refactor: dtos openapi

This commit is contained in:
Ahmed Bouhuolia
2025-03-22 23:21:52 +02:00
parent 2eb56e5850
commit 4c42515613
9 changed files with 357 additions and 14 deletions

View File

@@ -2,12 +2,14 @@ import { Type } from 'class-transformer';
import {
IsArray,
IsDate,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
ValidateNested,
} from 'class-validator';
import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto';
import { ApiProperty } from '@nestjs/swagger';
export class BillPaymentEntryDto {
@IsNumber()
@@ -19,48 +21,98 @@ export class BillPaymentEntryDto {
export class CommandBillPaymentDTO {
@IsNumber()
@IsNotEmpty()
@ApiProperty({
description: 'The id of the vendor',
example: 1,
})
vendorId: number;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The amount of the bill payment',
example: 100,
})
amount?: number;
@IsNumber()
@IsNotEmpty()
@ApiProperty({
description: 'The id of the payment account',
example: 1,
})
paymentAccountId: number;
@IsString()
@IsOptional()
@ApiProperty({
description: 'The payment number of the bill payment',
example: '123456',
})
paymentNumber?: string;
@IsDate()
@Type(() => Date)
@ApiProperty({
description: 'The payment date of the bill payment',
example: '2021-01-01',
})
paymentDate: Date | string;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The exchange rate of the bill payment',
example: 1,
})
exchangeRate?: number;
@IsString()
@IsOptional()
@ApiProperty({
description: 'The statement of the bill payment',
example: '123456',
})
statement?: string;
@IsString()
@IsOptional()
reference?: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => BillPaymentEntryDto)
@ApiProperty({
description: 'The entries of the bill payment',
example: [
{
billId: 1,
paymentAmount: 100,
},
],
})
entries: BillPaymentEntryDto[];
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The id of the branch',
example: 1,
})
branchId?: number;
@IsArray()
@IsOptional()
@ValidateNested({ each: true })
@Type(() => AttachmentLinkDto)
@ApiProperty({
description: 'The attachments of the bill payment',
example: [
{
id: 1,
type: 'bill',
},
],
})
attachments?: AttachmentLinkDto[];
}

View File

@@ -1,3 +1,4 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator';
import { IsDate } from 'class-validator';
import { IsNumber } from 'class-validator';
@@ -5,31 +6,59 @@ import { IsNumber } from 'class-validator';
export class CreditNoteRefundDto {
@IsNumber()
@IsNotEmpty()
@ApiProperty({
description: 'The id of the from account',
example: 1,
})
fromAccountId: number;
@IsNumber()
@IsPositive()
@IsNotEmpty()
@ApiProperty({
description: 'The amount of the credit note refund',
example: 100,
})
amount: number;
@IsNumber()
@IsOptional()
@IsPositive()
@ApiProperty({
description: 'The exchange rate of the credit note refund',
example: 1,
})
exchangeRate?: number;
@IsString()
@IsNotEmpty()
@ApiProperty({
description: 'The reference number of the credit note refund',
example: '123456',
})
referenceNo: string;
@IsString()
@IsNotEmpty()
@ApiProperty({
description: 'The description of the credit note refund',
example: 'Credit note refund',
})
description: string;
@IsDate()
@IsNotEmpty()
@ApiProperty({
description: 'The date of the credit note refund',
example: '2021-01-01',
})
date: Date;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The id of the branch',
example: 1,
})
branchId?: number;
}

View File

@@ -1,6 +1,7 @@
import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsArray, ValidateNested } from 'class-validator';
import { IsArray, IsNotEmpty, ValidateNested } from 'class-validator';
import { IsString } from 'class-validator';
import { IsDateString, IsNumber, IsOptional } from 'class-validator';
import { IsInt } from 'class-validator';
@@ -27,47 +28,95 @@ export class PaymentReceivedEntryDto {
export class CommandPaymentReceivedDto {
@IsInt()
@IsNotEmpty()
@ApiProperty({ description: 'The id of the customer', example: 1 })
customerId: number;
@IsDateString()
@ApiProperty({
description: 'The payment date of the payment received',
example: '2021-01-01',
})
paymentDate: Date | string;
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The amount of the payment received',
example: 100,
})
amount?: number;
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The exchange rate of the payment received',
example: 1,
})
exchangeRate?: number;
@IsOptional()
@IsString()
@ApiProperty({
description: 'The reference number of the payment received',
example: '123456',
})
referenceNo?: string;
@IsInt()
@IsNotEmpty()
@ApiProperty({
description: 'The id of the deposit account',
example: 1,
})
depositAccountId: number;
@IsOptional()
@IsString()
@ApiProperty({
description: 'The payment receive number of the payment received',
example: '123456',
})
paymentReceiveNo?: string;
@IsOptional()
@IsString()
@ApiProperty({
description: 'The statement of the payment received',
example: '123456',
})
statement?: string;
@IsArray()
@ValidateNested({ each: true })
@Type(() => PaymentReceivedEntryDto)
@ApiProperty({
description: 'The entries of the payment received',
example: [{ invoiceId: 1, paymentAmount: 100 }],
})
entries: PaymentReceivedEntryDto[];
@IsOptional()
@IsInt()
@ApiProperty({
description: 'The id of the branch',
example: 1,
})
branchId?: number;
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentLinkDto)
@ApiProperty({
description: 'The attachments of the payment received',
example: [
{
id: 1,
type: 'bill',
},
],
})
attachments?: AttachmentLinkDto[];
}

View File

@@ -1,10 +1,12 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsNotEmpty,
IsNumber,
IsOptional,
IsPositive,
@@ -27,72 +29,140 @@ class AttachmentDto {
export class CommandSaleReceiptDto {
@IsNumber()
@IsNotEmpty()
@ApiProperty({
description: 'The id of the customer',
example: 1,
})
customerId: number;
@IsOptional()
@IsNumber()
@IsPositive()
@ApiProperty({
description: 'The exchange rate of the sale receipt',
example: 1,
})
exchangeRate?: number;
@IsNumber()
@IsNotEmpty()
@ApiProperty({ description: 'The id of the deposit account', example: 1 })
depositAccountId: number;
@IsDate()
@IsNotEmpty()
@ApiProperty({
description: 'The date of the sale receipt',
example: '2021-01-01',
})
receiptDate: Date;
@IsOptional()
@IsString()
@ApiProperty({
description: 'The receipt number of the sale receipt',
example: '123456',
})
receiptNumber?: string;
@IsOptional()
@IsString()
@ApiProperty({
description: 'The reference number of the sale receipt',
example: '123456',
})
referenceNo?: string;
@IsBoolean()
@ApiProperty({
description: 'Whether the sale receipt is closed',
example: false,
})
closed: boolean = false;
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The id of the warehouse',
example: 1,
})
warehouseId?: number;
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The id of the branch',
example: 1,
})
branchId?: number;
@IsArray()
@ValidateNested({ each: true })
@Type(() => SaleReceiptEntryDto)
@Min(1)
@ApiProperty({
description: 'The entries of the sale receipt',
example: [{ key: '123456' }],
})
entries: SaleReceiptEntryDto[];
@IsOptional()
@IsString()
@ApiProperty({
description: 'The receipt message of the sale receipt',
example: '123456',
})
receiptMessage?: string;
@IsOptional()
@IsString()
@ApiProperty({
description: 'The statement of the sale receipt',
example: '123456',
})
statement?: string;
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
@ApiProperty({
description: 'The attachments of the sale receipt',
example: [{ key: '123456' }],
})
attachments?: AttachmentDto[];
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The id of the pdf template',
example: 1,
})
pdfTemplateId?: number;
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The discount of the sale receipt',
example: 1,
})
discount?: number;
@IsOptional()
@IsEnum(DiscountType)
@ApiProperty({
description: 'The discount type of the sale receipt',
example: DiscountType.Percentage,
})
discountType?: DiscountType;
@IsOptional()
@IsNumber()
@ApiProperty({
description: 'The adjustment of the sale receipt',
example: 1,
})
adjustment?: number;
}

View File

@@ -1,8 +1,10 @@
import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
IsArray,
IsEnum,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
@@ -23,59 +25,131 @@ class AttachmentDto {
export class CommandVendorCreditDto {
@IsNumber()
@IsNotEmpty()
@ApiProperty({
description: 'The id of the vendor',
example: 1,
})
vendorId: number;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The exchange rate of the vendor credit',
example: 1,
})
exchangeRate?: number;
@IsString()
@IsOptional()
@ApiProperty({
description: 'The vendor credit number',
example: '123456',
})
vendorCreditNumber?: string;
@IsString()
@IsOptional()
@ApiProperty({
description: 'The reference number of the vendor credit',
example: '123456',
})
referenceNo?: string;
@IsString() // ISO8601 date string
@IsString()
@IsNotEmpty()
@ApiProperty({
description: 'The date of the vendor credit',
example: '2021-01-01',
})
vendorCreditDate: string;
@IsString()
@IsOptional()
@ApiProperty({
description: 'The note of the vendor credit',
example: '123456',
})
note?: string;
@IsOptional()
@ApiProperty({
description: 'The open status of the vendor credit',
example: true,
})
open: boolean = false;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The warehouse id of the vendor credit',
example: 1,
})
warehouseId?: number;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The branch id of the vendor credit',
example: 1,
})
branchId?: number;
@IsArray()
@ValidateNested({ each: true })
@Type(() => VendorCreditEntryDto)
@ApiProperty({
description: 'The entries of the vendor credit',
example: [
{
itemId: 1,
quantity: 1,
unitPrice: 1,
discount: 1,
discountType: DiscountType.Percentage,
accountId: 1,
amount: 1,
},
],
})
entries: VendorCreditEntryDto[];
@IsArray()
@ValidateNested({ each: true })
@Type(() => AttachmentDto)
@IsOptional()
@ApiProperty({
description: 'The attachments of the vendor credit',
example: [
{
key: '123456',
},
],
})
attachments?: AttachmentDto[];
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The discount of the vendor credit',
example: 1,
})
discount?: number;
@IsEnum(DiscountType)
@IsOptional()
@ApiProperty({
description: 'The discount type of the vendor credit',
example: DiscountType.Percentage,
})
discountType?: DiscountType;
@IsNumber()
@IsOptional()
@ApiProperty({
description: 'The adjustment of the vendor credit',
example: 1,
})
adjustment?: number;
}

View File

@@ -3,6 +3,7 @@ import { DeleteRefundVendorCreditService } from './commands/DeleteRefundVendorCr
import { RefundVendorCredit } from './models/RefundVendorCredit';
import { CreateRefundVendorCredit } from './commands/CreateRefundVendorCredit.service';
import { IRefundVendorCreditDTO } from './types/VendorCreditRefund.types';
import { RefundVendorCreditDto } from './dtos/RefundVendorCredit.dto';
@Injectable()
export class VendorCreditsRefundApplication {
@@ -23,7 +24,7 @@ export class VendorCreditsRefundApplication {
*/
public async createRefundVendorCredit(
vendorCreditId: number,
refundVendorCreditDTO: IRefundVendorCreditDTO,
refundVendorCreditDTO: RefundVendorCreditDto,
): Promise<RefundVendorCredit> {
return this.createRefundVendorCreditService.createRefund(
vendorCreditId,

View File

@@ -6,6 +6,7 @@ import { IRefundVendorCreditDTO } from './types/VendorCreditRefund.types';
import { RefundVendorCredit } from './models/RefundVendorCredit';
import { PublicRoute } from '../Auth/Jwt.guard';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { RefundVendorCreditDto } from './dtos/RefundVendorCredit.dto';
@Controller('vendor-credits')
@ApiTags('vendor-credits-refunds')
@@ -25,7 +26,7 @@ export class VendorCreditsRefundController {
@ApiOperation({ summary: 'Create a refund for the given vendor credit.' })
public async createRefundVendorCredit(
@Param('vendorCreditId') vendorCreditId: string,
@Body() refundVendorCreditDTO: IRefundVendorCreditDTO,
@Body() refundVendorCreditDTO: RefundVendorCreditDto,
): Promise<RefundVendorCredit> {
return this.vendorCreditsRefundApplication.createRefundVendorCredit(
Number(vendorCreditId),

View File

@@ -5,7 +5,6 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
import {
IRefundVendorCreditCreatedPayload,
IRefundVendorCreditCreatingPayload,
IRefundVendorCreditDTO,
} from '../types/VendorCreditRefund.types';
import { Account } from '@/modules/Accounts/models/Account.model';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
@@ -17,9 +16,18 @@ import { events } from '@/common/events/events';
import { ServiceError } from '@/modules/Items/ServiceError';
import { ERRORS } from '../constants';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { RefundVendorCreditDto } from '../dtos/RefundVendorCredit.dto';
@Injectable()
export class CreateRefundVendorCredit {
/**
* @param {UnitOfWork} uow - Unit of work.
* @param {EventEmitter2} eventPublisher - Event emitter.
* @param {BranchTransactionDTOTransformer} branchDTOTransform - Branch transaction DTO transformer.
* @param {TenantModelProxy<typeof RefundVendorCredit>} refundVendorCreditModel - Refund vendor credit model.
* @param {TenantModelProxy<typeof Account>} accountModel - Account model.
* @param {TenantModelProxy<typeof VendorCredit>} vendorCreditModel - Vendor credit model.
*/
constructor(
private readonly uow: UnitOfWork,
private readonly eventPublisher: EventEmitter2,
@@ -40,12 +48,12 @@ export class CreateRefundVendorCredit {
/**
* Creates a refund vendor credit.
* @param {number} vendorCreditId
* @param {IRefundVendorCreditDTO} refundVendorCreditDTO
* @param {RefundVendorCreditDto} refundVendorCreditDTO
* @returns {Promise<IRefundVendorCredit>}
*/
public createRefund = async (
vendorCreditId: number,
refundVendorCreditDTO: IRefundVendorCreditDTO,
refundVendorCreditDTO: RefundVendorCreditDto,
): Promise<RefundVendorCredit> => {
// Retrieve the vendor credit or throw not found service error.
const vendorCredit = await this.vendorCreditModel()
@@ -107,13 +115,13 @@ export class CreateRefundVendorCredit {
/**
* Transformes the refund DTO to refund vendor credit model.
* @param {IVendorCredit} vendorCredit -
* @param {IRefundVendorCreditDTO} vendorCreditDTO
* @param {VendorCredit} vendorCredit -
* @param {RefundVendorCreditDto} vendorCreditDTO
* @returns {IRefundVendorCredit}
*/
public transformDTOToModel = (
vendorCredit: VendorCredit,
vendorCreditDTO: IRefundVendorCreditDTO,
vendorCreditDTO: RefundVendorCreditDto,
) => {
const initialDTO = {
vendorCreditId: vendorCredit.id,
@@ -126,7 +134,7 @@ export class CreateRefundVendorCredit {
/**
* Validate the deposit refund account type.
* @param {IAccount} account
* @param {Account} account
*/
public validateRefundDepositAccountType(account: Account) {
const supportedTypes = ['bank', 'cash', 'fixed-asset'];
@@ -138,7 +146,7 @@ export class CreateRefundVendorCredit {
/**
* Validate vendor credit has remaining credits.
* @param {IVendorCredit} vendorCredit
* @param {VendorCredit} vendorCredit
* @param {number} amount
*/
public validateVendorCreditRemainingCredit(

View File

@@ -0,0 +1,59 @@
import { ApiProperty } from '@nestjs/swagger';
import { Min } from 'class-validator';
import { IsString } from 'class-validator';
import { IsDate } from 'class-validator';
import { IsNotEmpty, IsNumber, IsOptional, IsPositive } from 'class-validator';
export class RefundVendorCreditDto {
@IsNumber()
@IsNotEmpty()
@Min(0)
@ApiProperty({
description: 'The amount of the refund',
example: 100,
})
amount: number;
@IsNumber()
@IsOptional()
@Min(0)
@ApiProperty({
description: 'The exchange rate of the refund',
example: 1,
})
exchangeRate?: number;
@IsNumber()
@IsNotEmpty()
@IsPositive()
@ApiProperty({
description: 'The id of the deposit account',
example: 1,
})
depositAccountId: number;
@IsString()
@IsNotEmpty()
@ApiProperty({
description: 'The description of the refund',
example: 'Refund for vendor credit',
})
description: string;
@IsDate()
@IsNotEmpty()
@ApiProperty({
description: 'The date of the refund',
example: '2021-01-01',
})
date: Date;
@IsNumber()
@IsOptional()
@IsPositive()
@ApiProperty({
description: 'The id of the branch',
example: 1,
})
branchId?: number;
}