From 136cc907bba8d39445066bf08d75de24c2eac1b0 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Thu, 20 Mar 2025 05:42:19 +0200 Subject: [PATCH] refactor: dtos validation --- .../src/modules/Accounts/CreateAccount.dto.ts | 4 +- .../modules/Accounts/CreateAccount.service.ts | 7 + .../server-nest/src/modules/App/App.module.ts | 3 +- .../Attachments/dtos/Attachment.dto.ts | 8 ++ .../modules/BankRules/BankRules.controller.ts | 6 +- .../modules/BankRules/BankRulesApplication.ts | 8 +- .../commands/CreateBankRule.service.ts | 8 +- .../commands/EditBankRule.service.ts | 8 +- .../modules/BankRules/dtos/BankRule.dto.ts | 81 ++++++++++++ .../src/modules/BankRules/models/BankRule.ts | 24 ++-- .../src/modules/BankRules/types.ts | 9 +- .../BankingMatching.controller.ts | 5 +- .../BankingMatchingApplication.ts | 17 ++- .../commands/MatchTransactions.ts | 4 +- .../dtos/MatchBankTransaction.dto.ts | 25 ++++ .../GetMatchedTransactionsByBills.service.ts | 4 +- .../BankingTransactions.controller.ts | 3 +- .../BankingTransactionsApplication.service.ts | 10 +- .../commands/CreateBankTransaction.service.ts | 3 +- .../dtos/CreateBankTransaction.dto.ts | 58 +++++++++ .../types/BankingTransactions.types.ts | 3 +- .../BillPayments/BillPayments.controller.ts | 9 +- .../BillPaymentsApplication.service.ts | 6 +- .../commands/BillPaymentBillSync.service.ts | 9 +- .../commands/BillPaymentValidators.service.ts | 16 +-- ...ommandBillPaymentDTOTransformer.service.ts | 7 +- .../commands/CreateBillPayment.service.ts | 4 +- .../commands/EditBillPayment.service.ts | 8 +- .../BillPayments/dtos/BillPayment.dto.ts | 68 ++++++++++ .../BillPayments/types/BillPayments.types.ts | 28 +--- .../src/modules/Bills/Bills.application.ts | 5 +- .../src/modules/Bills/Bills.controller.ts | 7 +- .../src/modules/Bills/Bills.types.ts | 13 +- .../commands/BillDTOTransformer.service.ts | 7 +- .../Bills/commands/BillsValidators.service.ts | 4 +- .../Bills/commands/CreateBill.service.ts | 3 +- .../Bills/commands/EditBill.service.ts | 3 +- .../src/modules/Bills/dtos/Bill.dto.ts | 106 +++++++++++++++ .../src/modules/Branches/dtos/Branch.dto.ts | 6 + .../CreditNoteRefunds.controller.ts | 3 +- .../CreditNotesRefundsApplication.service.ts | 5 +- .../CreateRefundCreditNote.service.ts | 12 +- .../dto/CreditNoteRefund.dto.ts | 35 +++++ .../types/CreditNoteRefunds.types.ts | 3 +- .../CreditNoteApplication.service.ts | 15 +-- .../CreditNotes/CreditNotes.controller.ts | 11 +- .../CommandCreditNoteDTOTransform.service.ts | 3 +- .../commands/CreateCreditNote.service.ts | 4 +- .../commands/EditCreditNote.service.ts | 5 +- .../CreditNotes/dtos/CreditNote.dto.ts | 98 ++++++++++++++ .../CreditNotes/dtos/RefundCreditNote.dto.ts | 12 ++ .../CreditNotes/types/CreditNotes.types.ts | 10 +- .../TrialBalanceSheetApplication.ts | 5 + .../InventoryAdjustments.controller.ts | 3 +- ...InventoryAdjustmentsApplication.service.ts | 3 +- .../CreateQuickInventoryAdjustment.service.ts | 3 +- .../CreateQuickInventoryAdjustment.dto.ts | 86 +++++++++++++ .../types/InventoryAdjustments.types.ts | 3 +- .../src/modules/Items/Item.controller.ts | 1 - .../src/modules/Items/ItemsEntries.service.ts | 17 +-- .../PaymentReceived.application.ts | 20 +-- .../commands/CreatePaymentReceived.serivce.ts | 3 +- .../commands/EditPaymentReceived.service.ts | 5 +- .../PaymentReceivedValidators.service.ts | 7 +- .../dtos/PaymentReceived.dto.ts | 75 +++++++++++ .../types/PaymentReceived.types.ts | 27 ++-- .../SaleEstimates.application.ts | 20 +-- .../SaleEstimates/SaleEstimates.controller.ts | 9 +- .../commands/CreateSaleEstimate.service.ts | 3 +- .../commands/EditSaleEstimate.service.ts | 3 +- .../SaleEstimateDTOTransformer.service.ts | 8 +- .../SaleEstimates/dtos/SaleEstimate.dto.ts | 104 +++++++++++++++ .../types/SaleEstimates.types.ts | 13 +- .../modules/SaleInvoices/SaleInvoice.types.ts | 16 +-- .../SaleInvoices/SaleInvoices.application.ts | 10 +- .../SaleInvoices/SaleInvoices.controller.ts | 10 +- ...ommandSaleInvoiceDTOTransformer.service.ts | 12 +- .../commands/CreateSaleInvoice.service.ts | 6 +- .../commands/EditSaleInvoice.service.ts | 7 +- .../SaleInvoices/dtos/SaleInvoice.dto.ts | 121 ++++++++++++++++++ .../SaleReceiptApplication.service.ts | 7 +- .../SaleReceipts/SaleReceipts.controller.ts | 9 +- .../commands/CreateSaleReceipt.service.ts | 3 +- .../commands/EditSaleReceipt.service.ts | 6 +- .../SaleReceiptDTOTransformer.service.ts | 4 +- .../SaleReceipts/dtos/SaleReceipt.dto.ts | 100 +++++++++++++++ .../CommandTaxRatesValidator.service.ts | 8 +- .../TransactionItemEntry/dto/ItemEntry.dto.ts | 76 +++++++++++ .../TransactionsLocking.controller.ts | 7 +- .../CommandTransactionsLockingService.ts | 14 +- .../dtos/TransactionsLocking.dto.ts | 25 ++++ .../VendorCredit/VendorCredits.controller.ts | 14 +- .../VendorCreditsApplication.service.ts | 9 +- .../commands/CreateVendorCredit.service.ts | 4 +- .../commands/EditVendorCredit.service.ts | 4 +- .../VendorCreditDTOTransform.service.ts | 12 +- .../VendorCredit/dtos/VendorCredit.dto.ts | 83 ++++++++++++ .../VendorCredit/types/VendorCredit.types.ts | 18 +-- .../Integrations/WarehousesDTOValidators.ts | 3 +- .../WarehouseTransferApplication.ts | 22 ++-- .../WarehouseTransfers.controller.ts | 15 +-- .../commands/CommandWarehouseTransfer.ts | 35 +++-- .../commands/CreateWarehouseTransfer.ts | 24 ++-- .../commands/EditWarehouseTransfer.ts | 10 +- .../dtos/WarehouseTransfer.dto.ts | 72 +++++++++++ 105 files changed, 1641 insertions(+), 366 deletions(-) create mode 100644 packages/server-nest/src/modules/Attachments/dtos/Attachment.dto.ts create mode 100644 packages/server-nest/src/modules/BankRules/dtos/BankRule.dto.ts create mode 100644 packages/server-nest/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts create mode 100644 packages/server-nest/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts create mode 100644 packages/server-nest/src/modules/BillPayments/dtos/BillPayment.dto.ts create mode 100644 packages/server-nest/src/modules/Bills/dtos/Bill.dto.ts create mode 100644 packages/server-nest/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts create mode 100644 packages/server-nest/src/modules/CreditNotes/dtos/CreditNote.dto.ts create mode 100644 packages/server-nest/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts create mode 100644 packages/server-nest/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts create mode 100644 packages/server-nest/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts create mode 100644 packages/server-nest/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts create mode 100644 packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts create mode 100644 packages/server-nest/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts create mode 100644 packages/server-nest/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts create mode 100644 packages/server-nest/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts create mode 100644 packages/server-nest/src/modules/VendorCredit/dtos/VendorCredit.dto.ts create mode 100644 packages/server-nest/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts diff --git a/packages/server-nest/src/modules/Accounts/CreateAccount.dto.ts b/packages/server-nest/src/modules/Accounts/CreateAccount.dto.ts index 0709e06a6..ffb80d2fd 100644 --- a/packages/server-nest/src/modules/Accounts/CreateAccount.dto.ts +++ b/packages/server-nest/src/modules/Accounts/CreateAccount.dto.ts @@ -25,12 +25,12 @@ export class CreateAccountDTO { @IsString() @MinLength(3) - @MaxLength(255) // Assuming DATATYPES_LENGTH.STRING is 255 + @MaxLength(255) accountType: string; @IsOptional() @IsString() - @MaxLength(65535) // Assuming DATATYPES_LENGTH.TEXT is 65535 + @MaxLength(65535) description?: string; @IsOptional() diff --git a/packages/server-nest/src/modules/Accounts/CreateAccount.service.ts b/packages/server-nest/src/modules/Accounts/CreateAccount.service.ts index 732bc64a5..c435bdbd4 100644 --- a/packages/server-nest/src/modules/Accounts/CreateAccount.service.ts +++ b/packages/server-nest/src/modules/Accounts/CreateAccount.service.ts @@ -18,6 +18,13 @@ import { TenantModelProxy } from '../System/models/TenantBaseModel'; @Injectable() export class CreateAccountService { + /** + * @param {TenantModelProxy} accountModel - The account model proxy. + * @param {EventEmitter2} eventEmitter - The event emitter. + * @param {UnitOfWork} uow - The unit of work. + * @param {CommandAccountValidators} validator - The command account validators. + * @param {TenancyContext} tenancyContext - The tenancy context. + */ constructor( @Inject(Account.name) private readonly accountModel: TenantModelProxy, diff --git a/packages/server-nest/src/modules/App/App.module.ts b/packages/server-nest/src/modules/App/App.module.ts index fca7c6d55..0b601f572 100644 --- a/packages/server-nest/src/modules/App/App.module.ts +++ b/packages/server-nest/src/modules/App/App.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from '@nestjs/config'; import { EventEmitterModule } from '@nestjs/event-emitter'; import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core'; import { join } from 'path'; +import { RedisModule } from '@liaoliaots/nestjs-redis'; import { AcceptLanguageResolver, CookieResolver, @@ -71,7 +72,7 @@ import { StripePaymentModule } from '../StripePayment/StripePayment.module'; import { FeaturesModule } from '../Features/Features.module'; import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; import { WarehousesTransfersModule } from '../WarehousesTransfers/WarehouseTransfers.module'; -import { RedisModule } from '@liaoliaots/nestjs-redis'; + @Module({ imports: [ diff --git a/packages/server-nest/src/modules/Attachments/dtos/Attachment.dto.ts b/packages/server-nest/src/modules/Attachments/dtos/Attachment.dto.ts new file mode 100644 index 000000000..ace202de4 --- /dev/null +++ b/packages/server-nest/src/modules/Attachments/dtos/Attachment.dto.ts @@ -0,0 +1,8 @@ +import { IsNotEmpty, IsString } from "class-validator"; + + +export class AttachmentLinkDto { + @IsString() + @IsNotEmpty() + key: string; +} diff --git a/packages/server-nest/src/modules/BankRules/BankRules.controller.ts b/packages/server-nest/src/modules/BankRules/BankRules.controller.ts index d0c4299cd..202c2b7f8 100644 --- a/packages/server-nest/src/modules/BankRules/BankRules.controller.ts +++ b/packages/server-nest/src/modules/BankRules/BankRules.controller.ts @@ -12,6 +12,8 @@ import { BankRulesApplication } from './BankRulesApplication'; import { ICreateBankRuleDTO, IEditBankRuleDTO } from './types'; import { PublicRoute } from '../Auth/Jwt.guard'; import { BankRule } from './models/BankRule'; +import { CreateBankRuleDto } from './dtos/BankRule.dto'; +import { EditBankRuleDto } from './dtos/BankRule.dto'; @Controller('banking/rules') @ApiTags('bank-rules') @@ -22,7 +24,7 @@ export class BankRulesController { @Post() @ApiOperation({ summary: 'Create a new bank rule.' }) async createBankRule( - @Body() createRuleDTO: ICreateBankRuleDTO, + @Body() createRuleDTO: CreateBankRuleDto, ): Promise { return this.bankRulesApplication.createBankRule(createRuleDTO); } @@ -31,7 +33,7 @@ export class BankRulesController { @ApiOperation({ summary: 'Edit the given bank rule.' }) async editBankRule( @Param('id') ruleId: number, - @Body() editRuleDTO: IEditBankRuleDTO, + @Body() editRuleDTO: EditBankRuleDto, ): Promise { return this.bankRulesApplication.editBankRule(ruleId, editRuleDTO); } diff --git a/packages/server-nest/src/modules/BankRules/BankRulesApplication.ts b/packages/server-nest/src/modules/BankRules/BankRulesApplication.ts index 44242013a..ba4e05e04 100644 --- a/packages/server-nest/src/modules/BankRules/BankRulesApplication.ts +++ b/packages/server-nest/src/modules/BankRules/BankRulesApplication.ts @@ -4,8 +4,8 @@ import { DeleteBankRuleService } from './commands/DeleteBankRule.service'; import { EditBankRuleService } from './commands/EditBankRule.service'; import { GetBankRuleService } from './queries/GetBankRule.service'; import { GetBankRulesService } from './queries/GetBankRules.service'; -import { ICreateBankRuleDTO, IEditBankRuleDTO } from './types'; import { BankRule } from './models/BankRule'; +import { CreateBankRuleDto, EditBankRuleDto } from './dtos/BankRule.dto'; @Injectable() export class BankRulesApplication { @@ -23,7 +23,7 @@ export class BankRulesApplication { * @returns {Promise} */ public createBankRule( - createRuleDTO: ICreateBankRuleDTO, + createRuleDTO: CreateBankRuleDto, ): Promise { return this.createBankRuleService.createBankRule(createRuleDTO); } @@ -31,12 +31,12 @@ export class BankRulesApplication { /** * Edits the given bank rule. * @param {number} ruleId - Bank rule identifier. - * @param {IEditBankRuleDTO} editRuleDTO - Bank rule data. + * @param {EditBankRuleDto} editRuleDTO - Bank rule data. * @returns {Promise} */ public editBankRule( ruleId: number, - editRuleDTO: IEditBankRuleDTO, + editRuleDTO: EditBankRuleDto, ): Promise { return this.editBankRuleService.editBankRule(ruleId, editRuleDTO); } diff --git a/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts b/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts index f770545e9..2ccbb103c 100644 --- a/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts +++ b/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts @@ -1,3 +1,4 @@ +import { ModelObject } from 'objection'; import { Knex } from 'knex'; import { Inject, Injectable } from '@nestjs/common'; import { @@ -9,6 +10,7 @@ import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { events } from '@/common/events/events'; import { BankRule } from '../models/BankRule'; +import { CreateBankRuleDto } from '../dtos/BankRule.dto'; @Injectable() export class CreateBankRuleService { @@ -23,10 +25,10 @@ export class CreateBankRuleService { * Transforms the DTO to model. * @param {ICreateBankRuleDTO} createDTO */ - private transformDTO(createDTO: ICreateBankRuleDTO) { + private transformDTO(createDTO: CreateBankRuleDto): ModelObject { return { ...createDTO, - }; + } as ModelObject; } /** @@ -35,7 +37,7 @@ export class CreateBankRuleService { * @returns {Promise} */ public async createBankRule( - createRuleDTO: ICreateBankRuleDTO, + createRuleDTO: CreateBankRuleDto, ): Promise { const transformDTO = this.transformDTO(createRuleDTO); diff --git a/packages/server-nest/src/modules/BankRules/commands/EditBankRule.service.ts b/packages/server-nest/src/modules/BankRules/commands/EditBankRule.service.ts index 1becf17d2..8f352cb24 100644 --- a/packages/server-nest/src/modules/BankRules/commands/EditBankRule.service.ts +++ b/packages/server-nest/src/modules/BankRules/commands/EditBankRule.service.ts @@ -9,6 +9,8 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditBankRuleDto } from '../dtos/BankRule.dto'; +import { ModelObject } from 'objection'; @Injectable() export class EditBankRuleService { @@ -25,10 +27,10 @@ export class EditBankRuleService { * @param createDTO * @returns */ - private transformDTO(createDTO: IEditBankRuleDTO) { + private transformDTO(createDTO: EditBankRuleDto): ModelObject { return { ...createDTO, - }; + } as ModelObject; } /** @@ -36,7 +38,7 @@ export class EditBankRuleService { * @param {number} ruleId - * @param {IEditBankRuleDTO} editBankDTO */ - public async editBankRule(ruleId: number, editRuleDTO: IEditBankRuleDTO) { + public async editBankRule(ruleId: number, editRuleDTO: EditBankRuleDto) { const oldBankRule = await this.bankRuleModel() .query() .findById(ruleId) diff --git a/packages/server-nest/src/modules/BankRules/dtos/BankRule.dto.ts b/packages/server-nest/src/modules/BankRules/dtos/BankRule.dto.ts new file mode 100644 index 000000000..90da54015 --- /dev/null +++ b/packages/server-nest/src/modules/BankRules/dtos/BankRule.dto.ts @@ -0,0 +1,81 @@ +import { Type } from 'class-transformer'; +import { + IsString, + IsInt, + Min, + IsOptional, + IsIn, + IsArray, + ValidateNested, + ArrayMinSize, + IsNotEmpty, +} from 'class-validator'; +import { BankRuleComparator } from '../types'; + +class BankRuleConditionDto { + @IsNotEmpty() + @IsIn(['description', 'amount']) + field: string; + + @IsNotEmpty() + @IsIn([ + 'equals', + 'equal', + 'contains', + 'not_contain', + 'bigger', + 'bigger_or_equal', + 'smaller', + 'smaller_or_equal', + ]) + comparator: BankRuleComparator = 'contains'; + + @IsNotEmpty() + value: string; +} + +export class CommandBankRuleDto { + @IsString() + @IsNotEmpty() + name: string; + + @IsInt() + @Min(0) + order: number; + + @IsOptional() + @IsInt() + @Min(0) + applyIfAccountId?: number; + + @IsIn(['deposit', 'withdrawal']) + applyIfTransactionType: 'deposit' | 'withdrawal'; + + @IsString() + @IsIn(['and', 'or']) + conditionsType: 'and' | 'or' = 'and'; + + @IsArray() + @ArrayMinSize(1) + @ValidateNested({ each: true }) + @Type(() => BankRuleConditionDto) + conditions: BankRuleConditionDto[]; + + @IsString() + assignCategory: string; + + @IsInt() + @Min(0) + assignAccountId: number; + + @IsOptional() + @IsString() + assignPayee?: string; + + @IsOptional() + @IsString() + assignMemo?: string; +} + +export class CreateBankRuleDto extends CommandBankRuleDto {} +export class EditBankRuleDto extends CommandBankRuleDto {} diff --git a/packages/server-nest/src/modules/BankRules/models/BankRule.ts b/packages/server-nest/src/modules/BankRules/models/BankRule.ts index d86c6183a..948dbeaac 100644 --- a/packages/server-nest/src/modules/BankRules/models/BankRule.ts +++ b/packages/server-nest/src/modules/BankRules/models/BankRule.ts @@ -4,18 +4,18 @@ import { BankRuleCondition } from './BankRuleCondition'; import { BankRuleAssignCategory, BankRuleConditionType } from '../types'; export class BankRule extends BaseModel { - public id!: number; - public name!: string; - public order!: number; - public applyIfAccountId!: number; - public applyIfTransactionType!: string; - public assignCategory!: BankRuleAssignCategory; - public assignAccountId!: number; - public assignPayee!: string; - public assignMemo!: string; - public conditionsType!: BankRuleConditionType; + public readonly id!: number; + public readonly name!: string; + public readonly order!: number; + public readonly applyIfAccountId!: number; + public readonly applyIfTransactionType!: string; + public readonly assignCategory!: BankRuleAssignCategory; + public readonly assignAccountId!: number; + public readonly assignPayee!: string; + public readonly assignMemo!: string; + public readonly conditionsType!: BankRuleConditionType; - conditions!: BankRuleCondition[]; + public readonly conditions!: BankRuleCondition[]; /** * Table name @@ -27,7 +27,7 @@ export class BankRule extends BaseModel { /** * Timestamps columns. */ - get timestamps() { + static get timestamps() { return ['created_at', 'updated_at']; } diff --git a/packages/server-nest/src/modules/BankRules/types.ts b/packages/server-nest/src/modules/BankRules/types.ts index 1d46945ac..dd7cb44f9 100644 --- a/packages/server-nest/src/modules/BankRules/types.ts +++ b/packages/server-nest/src/modules/BankRules/types.ts @@ -1,5 +1,6 @@ import { Knex } from 'knex'; import { BankRule } from './models/BankRule'; +import { CreateBankRuleDto, EditBankRuleDto } from './dtos/BankRule.dto'; export enum BankRuleConditionField { Amount = 'amount', @@ -94,11 +95,11 @@ export interface ICreateBankRuleDTO extends IBankRuleCommonDTO {} export interface IEditBankRuleDTO extends IBankRuleCommonDTO {} export interface IBankRuleEventCreatingPayload { - createRuleDTO: ICreateBankRuleDTO; + createRuleDTO: CreateBankRuleDto; trx?: Knex.Transaction; } export interface IBankRuleEventCreatedPayload { - createRuleDTO: ICreateBankRuleDTO; + createRuleDTO: CreateBankRuleDto; bankRule: BankRule; trx?: Knex.Transaction; } @@ -106,13 +107,13 @@ export interface IBankRuleEventCreatedPayload { export interface IBankRuleEventEditingPayload { ruleId: number; oldBankRule: any; - editRuleDTO: IEditBankRuleDTO; + editRuleDTO: EditBankRuleDto; trx?: Knex.Transaction; } export interface IBankRuleEventEditedPayload { oldBankRule: BankRule; bankRule: BankRule; - editRuleDTO: IEditBankRuleDTO; + editRuleDTO: EditBankRuleDto; trx?: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/BankingMatching/BankingMatching.controller.ts b/packages/server-nest/src/modules/BankingMatching/BankingMatching.controller.ts index 06e4c0f4e..1c01a53c9 100644 --- a/packages/server-nest/src/modules/BankingMatching/BankingMatching.controller.ts +++ b/packages/server-nest/src/modules/BankingMatching/BankingMatching.controller.ts @@ -1,7 +1,8 @@ +import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { Body, Controller, Get, Param, Post, Query } from '@nestjs/common'; import { BankingMatchingApplication } from './BankingMatchingApplication'; import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types'; -import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { MatchBankTransactionDto } from './dtos/MatchBankTransaction.dto'; @Controller('banking/matching') @ApiTags('banking-transactions-matching') @@ -26,7 +27,7 @@ export class BankingMatchingController { @ApiOperation({ summary: 'Match the given uncategorized transaction.' }) async matchTransaction( @Param('uncategorizedTransactionId') uncategorizedTransactionId: number | number[], - @Body() matchedTransactions: IMatchTransactionDTO[] + @Body() matchedTransactions: MatchBankTransactionDto ) { return this.bankingMatchingApplication.matchTransaction( uncategorizedTransactionId, diff --git a/packages/server-nest/src/modules/BankingMatching/BankingMatchingApplication.ts b/packages/server-nest/src/modules/BankingMatching/BankingMatchingApplication.ts index cb3662256..ade9aec83 100644 --- a/packages/server-nest/src/modules/BankingMatching/BankingMatchingApplication.ts +++ b/packages/server-nest/src/modules/BankingMatching/BankingMatchingApplication.ts @@ -3,13 +3,14 @@ import { GetMatchedTransactions } from './queries/GetMatchedTransactions.service import { MatchBankTransactions } from './commands/MatchTransactions'; import { UnmatchMatchedBankTransaction } from './commands/UnmatchMatchedTransaction.service'; import { GetMatchedTransactionsFilter, IMatchTransactionDTO } from './types'; +import { MatchBankTransactionDto } from './dtos/MatchBankTransaction.dto'; @Injectable() export class BankingMatchingApplication { constructor( private readonly getMatchedTransactionsService: GetMatchedTransactions, private readonly matchTransactionService: MatchBankTransactions, - private readonly unmatchMatchedTransactionService: UnmatchMatchedBankTransaction + private readonly unmatchMatchedTransactionService: UnmatchMatchedBankTransaction, ) {} /** @@ -20,11 +21,11 @@ export class BankingMatchingApplication { */ public getMatchedTransactions( uncategorizedTransactionsIds: Array, - filter: GetMatchedTransactionsFilter + filter: GetMatchedTransactionsFilter, ) { return this.getMatchedTransactionsService.getMatchedTransactions( uncategorizedTransactionsIds, - filter + filter, ); } @@ -36,11 +37,11 @@ export class BankingMatchingApplication { */ public matchTransaction( uncategorizedTransactionId: number | Array, - matchedTransactions: Array + matchedTransactions: MatchBankTransactionDto, ): Promise { return this.matchTransactionService.matchTransaction( uncategorizedTransactionId, - matchedTransactions + matchedTransactions, ); } @@ -49,11 +50,9 @@ export class BankingMatchingApplication { * @param {number} uncategorizedTransactionId - Uncategorized transaction id. * @returns {Promise} */ - public unmatchMatchedTransaction( - uncategorizedTransactionId: number - ) { + public unmatchMatchedTransaction(uncategorizedTransactionId: number) { return this.unmatchMatchedTransactionService.unmatchMatchedTransaction( - uncategorizedTransactionId + uncategorizedTransactionId, ); } } diff --git a/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactions.ts b/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactions.ts index 81ad5d19d..25339319b 100644 --- a/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactions.ts +++ b/packages/server-nest/src/modules/BankingMatching/commands/MatchTransactions.ts @@ -21,6 +21,7 @@ import { ServiceError } from '@/modules/Items/ServiceError'; import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { MatchBankTransactionDto } from '../dtos/MatchBankTransaction.dto'; @Injectable() export class MatchBankTransactions { @@ -112,9 +113,10 @@ export class MatchBankTransactions { */ public async matchTransaction( uncategorizedTransactionId: number | Array, - matchedTransactions: Array, + matchedTransactionsDto: MatchBankTransactionDto, ): Promise { const uncategorizedTransactionIds = castArray(uncategorizedTransactionId); + const matchedTransactions = matchedTransactionsDto.entries; // Validates the given matching transactions DTO. await this.validate(uncategorizedTransactionIds, matchedTransactions); diff --git a/packages/server-nest/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts b/packages/server-nest/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts new file mode 100644 index 000000000..f512128d6 --- /dev/null +++ b/packages/server-nest/src/modules/BankingMatching/dtos/MatchBankTransaction.dto.ts @@ -0,0 +1,25 @@ +import { + IsArray, + IsNotEmpty, + IsNumber, + IsString, + ValidateNested, +} from 'class-validator'; +import { Type } from 'class-transformer'; + +export class MatchTransactionEntryDto { + @IsString() + @IsNotEmpty() + referenceType: string; + + @IsNumber() + @IsNotEmpty() + referenceId: number; +} + +export class MatchBankTransactionDto { + @IsArray() + @ValidateNested({ each: true }) + @Type(() => MatchTransactionEntryDto) + entries: MatchTransactionEntryDto[]; +} diff --git a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts b/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts index 1a001a291..f5c022978 100644 --- a/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts +++ b/packages/server-nest/src/modules/BankingMatching/queries/GetMatchedTransactionsByBills.service.ts @@ -10,10 +10,10 @@ import { import { GetMatchedTransactionsByType } from './GetMatchedTransactionsByType'; import { CreateBillPaymentService } from '@/modules/BillPayments/commands/CreateBillPayment.service'; import { TransformerInjectable } from '@/modules/Transformer/TransformerInjectable.service'; -import { IBillPaymentDTO } from '@/modules/BillPayments/types/BillPayments.types'; import { Bill } from '@/modules/Bills/models/Bill'; import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateBillPaymentDto } from '@/modules/BillPayments/dtos/BillPayment.dto'; @Injectable() export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType { @@ -110,7 +110,7 @@ export class GetMatchedTransactionsByBills extends GetMatchedTransactionsByType .findById(matchTransactionDTO.referenceId) .throwIfNotFound(); - const createPaymentMadeDTO: IBillPaymentDTO = { + const createPaymentMadeDTO: CreateBillPaymentDto = { vendorId: bill.vendorId, paymentAccountId: uncategorizedTransaction.accountId, paymentDate: uncategorizedTransaction.date, diff --git a/packages/server-nest/src/modules/BankingTransactions/BankingTransactions.controller.ts b/packages/server-nest/src/modules/BankingTransactions/BankingTransactions.controller.ts index e6718ca85..4df126138 100644 --- a/packages/server-nest/src/modules/BankingTransactions/BankingTransactions.controller.ts +++ b/packages/server-nest/src/modules/BankingTransactions/BankingTransactions.controller.ts @@ -14,6 +14,7 @@ import { } from './types/BankingTransactions.types'; import { PublicRoute } from '../Auth/Jwt.guard'; import { ApiTags } from '@nestjs/swagger'; +import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto'; @Controller('banking/transactions') @ApiTags('banking-transactions') @@ -29,7 +30,7 @@ export class BankingTransactionsController { } @Post() - async createTransaction(@Body() transactionDTO: ICashflowNewCommandDTO) { + async createTransaction(@Body() transactionDTO: CreateBankTransactionDto) { return this.bankingTransactionsApplication.createTransaction( transactionDTO, ); diff --git a/packages/server-nest/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts b/packages/server-nest/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts index 5090e8d8f..16168675d 100644 --- a/packages/server-nest/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts +++ b/packages/server-nest/src/modules/BankingTransactions/BankingTransactionsApplication.service.ts @@ -1,10 +1,12 @@ -import { Knex } from 'knex'; +import { Injectable } from '@nestjs/common'; import { DeleteCashflowTransaction } from './commands/DeleteCashflowTransaction.service'; import { CreateBankTransactionService } from './commands/CreateBankTransaction.service'; import { GetBankTransactionService } from './queries/GetBankTransaction.service'; -import { IBankAccountsFilter, ICashflowNewCommandDTO } from './types/BankingTransactions.types'; -import { Injectable } from '@nestjs/common'; +import { + IBankAccountsFilter, +} from './types/BankingTransactions.types'; import { GetBankAccountsService } from './queries/GetBankAccounts.service'; +import { CreateBankTransactionDto } from './dtos/CreateBankTransaction.dto'; @Injectable() export class BankingTransactionsApplication { @@ -20,7 +22,7 @@ export class BankingTransactionsApplication { * @param {ICashflowNewCommandDTO} transactionDTO * @returns */ - public createTransaction(transactionDTO: ICashflowNewCommandDTO) { + public createTransaction(transactionDTO: CreateBankTransactionDto) { return this.createTransactionService.newCashflowTransaction(transactionDTO); } diff --git a/packages/server-nest/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts b/packages/server-nest/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts index d197e22a2..8c1bb19d6 100644 --- a/packages/server-nest/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts +++ b/packages/server-nest/src/modules/BankingTransactions/commands/CreateBankTransaction.service.ts @@ -18,6 +18,7 @@ import { ICommandCashflowCreatingPayload, } from '../types/BankingTransactions.types'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateBankTransactionDto } from '../dtos/CreateBankTransaction.dto'; @Injectable() export class CreateBankTransactionService { @@ -62,7 +63,7 @@ export class CreateBankTransactionService { * @returns {ICashflowTransactionInput} - Cashflow transaction object. */ private transformCashflowTransactionDTO = async ( - newCashflowTransactionDTO: ICashflowNewCommandDTO, + newCashflowTransactionDTO: CreateBankTransactionDto, cashflowAccount: Account, userId: number, ): Promise => { diff --git a/packages/server-nest/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts b/packages/server-nest/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts new file mode 100644 index 000000000..5195ca91c --- /dev/null +++ b/packages/server-nest/src/modules/BankingTransactions/dtos/CreateBankTransaction.dto.ts @@ -0,0 +1,58 @@ +import { + IsBoolean, + IsDate, + IsNumber, + IsOptional, + IsString, +} from 'class-validator'; + +export class CreateBankTransactionDto { + @IsDate() + date: Date; + + @IsString() + transactionNumber: string; + + @IsString() + referenceNo: string; + + @IsString() + transactionType: string; + + @IsString() + description: string; + + @IsNumber() + amount: number; + + @IsNumber() + exchangeRate: number; + + @IsString() + currencyCode: string; + + @IsNumber() + creditAccountId: number; + + @IsNumber() + cashflowAccountId: number; + + @IsBoolean() + publish: boolean; + + @IsOptional() + @IsNumber() + branchId?: number; + + @IsOptional() + @IsString() + plaidTransactionId?: string; + + @IsOptional() + @IsString() + plaidAccountId?: string; + + @IsOptional() + @IsNumber() + uncategorizedTransactionId?: number; +} diff --git a/packages/server-nest/src/modules/BankingTransactions/types/BankingTransactions.types.ts b/packages/server-nest/src/modules/BankingTransactions/types/BankingTransactions.types.ts index e9086ca3b..8be092c84 100644 --- a/packages/server-nest/src/modules/BankingTransactions/types/BankingTransactions.types.ts +++ b/packages/server-nest/src/modules/BankingTransactions/types/BankingTransactions.types.ts @@ -1,6 +1,7 @@ import { Knex } from 'knex'; import { UncategorizedBankTransaction } from '../models/UncategorizedBankTransaction'; import { BankTransaction } from '../models/BankTransaction'; +import { CreateBankTransactionDto } from '../dtos/CreateBankTransaction.dto'; export interface IPendingTransactionRemovingEventPayload { uncategorizedTransactionId: number; @@ -67,7 +68,7 @@ export interface ICommandCashflowCreatingPayload { } export interface ICommandCashflowCreatedPayload { - newTransactionDTO: ICashflowNewCommandDTO; + newTransactionDTO: CreateBankTransactionDto; cashflowTransaction: BankTransaction; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/BillPayments/BillPayments.controller.ts b/packages/server-nest/src/modules/BillPayments/BillPayments.controller.ts index 768633d1e..677b7d1e7 100644 --- a/packages/server-nest/src/modules/BillPayments/BillPayments.controller.ts +++ b/packages/server-nest/src/modules/BillPayments/BillPayments.controller.ts @@ -8,8 +8,11 @@ import { Put, } from '@nestjs/common'; import { BillPaymentsApplication } from './BillPaymentsApplication.service'; -import { IBillPaymentDTO } from './types/BillPayments.types'; import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; +import { + CreateBillPaymentDto, + EditBillPaymentDto, +} from './dtos/BillPayment.dto'; @Controller('bill-payments') @ApiTags('bill-payments') @@ -18,7 +21,7 @@ export class BillPaymentsController { @Post() @ApiOperation({ summary: 'Create a new bill payment.' }) - public createBillPayment(@Body() billPaymentDTO: IBillPaymentDTO) { + public createBillPayment(@Body() billPaymentDTO: CreateBillPaymentDto) { return this.billPaymentsApplication.createBillPayment(billPaymentDTO); } @@ -46,7 +49,7 @@ export class BillPaymentsController { }) public editBillPayment( @Param('billPaymentId') billPaymentId: string, - @Body() billPaymentDTO: IBillPaymentDTO, + @Body() billPaymentDTO: EditBillPaymentDto, ) { return this.billPaymentsApplication.editBillPayment( Number(billPaymentId), diff --git a/packages/server-nest/src/modules/BillPayments/BillPaymentsApplication.service.ts b/packages/server-nest/src/modules/BillPayments/BillPaymentsApplication.service.ts index a9cd939ad..59959244d 100644 --- a/packages/server-nest/src/modules/BillPayments/BillPaymentsApplication.service.ts +++ b/packages/server-nest/src/modules/BillPayments/BillPaymentsApplication.service.ts @@ -5,8 +5,8 @@ import { EditBillPayment } from './commands/EditBillPayment.service'; // import { GetBillPayments } from './GetBillPayments'; import { GetBillPayment } from './queries/GetBillPayment.service'; import { GetPaymentBills } from './queries/GetPaymentBills.service'; -import { IBillPaymentDTO } from './types/BillPayments.types'; import { GetBillPayments } from '../Bills/queries/GetBillPayments'; +import { CreateBillPaymentDto, EditBillPaymentDto } from './dtos/BillPayment.dto'; /** * Bill payments application. @@ -28,7 +28,7 @@ export class BillPaymentsApplication { * @param {IBillPaymentDTO} billPaymentDTO * @returns {Promise} */ - public createBillPayment(billPaymentDTO: IBillPaymentDTO) { + public createBillPayment(billPaymentDTO: CreateBillPaymentDto) { return this.createBillPaymentService.createBillPayment(billPaymentDTO); } @@ -48,7 +48,7 @@ export class BillPaymentsApplication { */ public editBillPayment( billPaymentId: number, - billPaymentDTO: IBillPaymentDTO, + billPaymentDTO: EditBillPaymentDto, ) { return this.editBillPaymentService.editBillPayment( billPaymentId, diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts b/packages/server-nest/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts index c526e492c..a58e8b62f 100644 --- a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts +++ b/packages/server-nest/src/modules/BillPayments/commands/BillPaymentBillSync.service.ts @@ -1,10 +1,11 @@ import { Inject, Injectable } from '@nestjs/common'; import { Knex } from 'knex'; import { Bill } from '../../Bills/models/Bill'; -import { IBillPaymentEntryDTO } from '../types/BillPayments.types'; import { entriesAmountDiff } from '@/utils/entries-amount-diff'; -import Objection from 'objection'; +import Objection, { ModelObject } from 'objection'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { BillPaymentEntryDto } from '../dtos/BillPayment.dto'; +import { BillPaymentEntry } from '../models/BillPaymentEntry'; @Injectable() export class BillPaymentBillSync { @@ -20,8 +21,8 @@ export class BillPaymentBillSync { * @param {IBillPaymentEntryDTO[]} oldPaymentMadeEntries - */ public async saveChangeBillsPaymentAmount( - paymentMadeEntries: IBillPaymentEntryDTO[], - oldPaymentMadeEntries?: IBillPaymentEntryDTO[], + paymentMadeEntries: BillPaymentEntryDto[], + oldPaymentMadeEntries?: ModelObject[], trx?: Knex.Transaction, ): Promise { const opers: Objection.QueryBuilder[] = []; diff --git a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentValidators.service.ts b/packages/server-nest/src/modules/BillPayments/commands/BillPaymentValidators.service.ts index 461b1ca54..868b0d767 100644 --- a/packages/server-nest/src/modules/BillPayments/commands/BillPaymentValidators.service.ts +++ b/packages/server-nest/src/modules/BillPayments/commands/BillPaymentValidators.service.ts @@ -1,9 +1,5 @@ import { Inject, Injectable } from '@nestjs/common'; import { sumBy, difference } from 'lodash'; -import { - IBillPaymentDTO, - IBillPaymentEntryDTO, -} from '../types/BillPayments.types'; import { ERRORS } from '../constants'; import { Bill } from '../../Bills/models/Bill'; import { BillPayment } from '../models/BillPayment'; @@ -12,6 +8,10 @@ import { ServiceError } from '../../Items/ServiceError'; import { ACCOUNT_TYPE } from '@/constants/accounts'; import { Account } from '../../Accounts/models/Account.model'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { + BillPaymentEntryDto, + EditBillPaymentDto, +} from '../dtos/BillPayment.dto'; @Injectable() export class BillPaymentValidators { @@ -141,11 +141,11 @@ export class BillPaymentValidators { * @return {void} */ public async validateBillsDueAmount( - billPaymentEntries: IBillPaymentEntryDTO[], + billPaymentEntries: BillPaymentEntryDto[], oldPaymentEntries: BillPaymentEntry[] = [], ) { const billsIds = billPaymentEntries.map( - (entry: IBillPaymentEntryDTO) => entry.billId, + (entry: BillPaymentEntryDto) => entry.billId, ); const storedBills = await this.billModel().query().whereIn('id', billsIds); @@ -168,7 +168,7 @@ export class BillPaymentValidators { } const hasWrongPaymentAmount: invalidPaymentAmountError[] = []; - billPaymentEntries.forEach((entry: IBillPaymentEntryDTO, index: number) => { + billPaymentEntries.forEach((entry: BillPaymentEntryDto, index: number) => { const entryBill = storedBillsMap.get(entry.billId); const { dueAmount } = entryBill; @@ -212,7 +212,7 @@ export class BillPaymentValidators { * @param {string} billPaymentNo */ public validateVendorNotModified( - billPaymentDTO: IBillPaymentDTO, + billPaymentDTO: EditBillPaymentDto, oldBillPayment: BillPayment, ) { if (billPaymentDTO.vendorId !== oldBillPayment.vendorId) { diff --git a/packages/server-nest/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts b/packages/server-nest/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts index 2c4dbf3c6..0feefd0f7 100644 --- a/packages/server-nest/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts +++ b/packages/server-nest/src/modules/BillPayments/commands/CommandBillPaymentDTOTransformer.service.ts @@ -2,11 +2,14 @@ import { Injectable } from '@nestjs/common'; import * as R from 'ramda'; import { omit, sumBy } from 'lodash'; import { formatDateFields } from '@/utils/format-date-fields'; -import { IBillPaymentDTO } from '../types/BillPayments.types'; import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index'; import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform'; import { Vendor } from '@/modules/Vendors/models/Vendor'; import { BillPayment } from '../models/BillPayment'; +import { + CreateBillPaymentDto, + EditBillPaymentDto, +} from '../dtos/BillPayment.dto'; @Injectable() export class CommandBillPaymentDTOTransformer { @@ -22,7 +25,7 @@ export class CommandBillPaymentDTOTransformer { * @return {Promise} */ public async transformDTOToModel( - billPaymentDTO: IBillPaymentDTO, + billPaymentDTO: CreateBillPaymentDto | EditBillPaymentDto, vendor: Vendor, oldBillPayment?: BillPayment, ): Promise { diff --git a/packages/server-nest/src/modules/BillPayments/commands/CreateBillPayment.service.ts b/packages/server-nest/src/modules/BillPayments/commands/CreateBillPayment.service.ts index a4c04c306..a521065e8 100644 --- a/packages/server-nest/src/modules/BillPayments/commands/CreateBillPayment.service.ts +++ b/packages/server-nest/src/modules/BillPayments/commands/CreateBillPayment.service.ts @@ -1,6 +1,5 @@ import { Knex } from 'knex'; import { - IBillPaymentDTO, IBillPaymentEventCreatedPayload, IBillPaymentCreatingPayload, } from '../types/BillPayments.types'; @@ -14,6 +13,7 @@ import { TenancyContext } from '../../Tenancy/TenancyContext.service'; import { BillPayment } from '../models/BillPayment'; import { Vendor } from '../../Vendors/models/Vendor'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateBillPaymentDto } from '../dtos/BillPayment.dto'; @Injectable() export class CreateBillPaymentService { @@ -56,7 +56,7 @@ export class CreateBillPaymentService { * @param {BillPaymentDTO} billPayment - Bill payment object. */ public async createBillPayment( - billPaymentDTO: IBillPaymentDTO, + billPaymentDTO: CreateBillPaymentDto, trx?: Knex.Transaction, ): Promise { const tenantMeta = await this.tenancyContext.getTenant(true); diff --git a/packages/server-nest/src/modules/BillPayments/commands/EditBillPayment.service.ts b/packages/server-nest/src/modules/BillPayments/commands/EditBillPayment.service.ts index 735291281..19116b71f 100644 --- a/packages/server-nest/src/modules/BillPayments/commands/EditBillPayment.service.ts +++ b/packages/server-nest/src/modules/BillPayments/commands/EditBillPayment.service.ts @@ -13,6 +13,7 @@ import { Vendor } from '@/modules/Vendors/models/Vendor'; import { events } from '@/common/events/events'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditBillPaymentDto } from '../dtos/BillPayment.dto'; @Injectable() export class EditBillPayment { @@ -43,14 +44,13 @@ export class EditBillPayment { * - Update the diff vendor balance. * - Update the diff bill payment amount. * ------ - * @param {number} tenantId - Tenant id * @param {Integer} billPaymentId - * @param {BillPaymentDTO} billPayment - * @param {IBillPayment} oldBillPayment + * @param {EditBillPaymentDto} billPayment + * @param {BillPayment} oldBillPayment */ public async editBillPayment( billPaymentId: number, - billPaymentDTO, + billPaymentDTO: EditBillPaymentDto, ): Promise { const tenantMeta = await this.tenancyContext.getTenant(true); diff --git a/packages/server-nest/src/modules/BillPayments/dtos/BillPayment.dto.ts b/packages/server-nest/src/modules/BillPayments/dtos/BillPayment.dto.ts new file mode 100644 index 000000000..9fc43b49e --- /dev/null +++ b/packages/server-nest/src/modules/BillPayments/dtos/BillPayment.dto.ts @@ -0,0 +1,68 @@ +import { Type } from 'class-transformer'; +import { + IsArray, + IsDate, + IsNumber, + IsOptional, + IsString, + ValidateNested, +} from 'class-validator'; +import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto'; + +export class BillPaymentEntryDto { + @IsNumber() + billId: number; + + @IsNumber() + paymentAmount: number; +} + +export class CommandBillPaymentDTO { + @IsNumber() + vendorId: number; + + @IsNumber() + @IsOptional() + amount?: number; + + @IsNumber() + paymentAccountId: number; + + @IsString() + @IsOptional() + paymentNumber?: string; + + @IsDate() + @Type(() => Date) + paymentDate: Date | string; + + @IsNumber() + @IsOptional() + exchangeRate?: number; + + @IsString() + @IsOptional() + statement?: string; + + @IsString() + @IsOptional() + reference?: string; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => BillPaymentEntryDto) + entries: BillPaymentEntryDto[]; + + @IsNumber() + @IsOptional() + branchId?: number; + + @IsArray() + @IsOptional() + @ValidateNested({ each: true }) + @Type(() => AttachmentLinkDto) + attachments?: AttachmentLinkDto[]; +} + +export class CreateBillPaymentDto extends CommandBillPaymentDTO {} +export class EditBillPaymentDto extends CommandBillPaymentDTO {} diff --git a/packages/server-nest/src/modules/BillPayments/types/BillPayments.types.ts b/packages/server-nest/src/modules/BillPayments/types/BillPayments.types.ts index f91c65cf6..bca7f222a 100644 --- a/packages/server-nest/src/modules/BillPayments/types/BillPayments.types.ts +++ b/packages/server-nest/src/modules/BillPayments/types/BillPayments.types.ts @@ -1,25 +1,7 @@ import { Knex } from 'knex'; import { BillPayment } from '../models/BillPayment'; import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types'; - -export interface IBillPaymentEntryDTO { - billId: number; - paymentAmount: number; -} - -export interface IBillPaymentDTO { - vendorId: number; - amount?: number; - paymentAccountId: number; - paymentNumber?: string; - paymentDate: Date | string; - exchangeRate?: number; - statement?: string; - reference?: string; - entries: IBillPaymentEntryDTO[]; - branchId?: number; - attachments?: AttachmentLinkDTO[]; -} +import { CreateBillPaymentDto, EditBillPaymentDto } from '../dtos/BillPayment.dto'; export interface IBillReceivePageEntry { billId: number; @@ -35,18 +17,18 @@ export interface IBillReceivePageEntry { export interface IBillPaymentEventCreatedPayload { billPayment: BillPayment; - billPaymentDTO: IBillPaymentDTO; + billPaymentDTO: CreateBillPaymentDto; billPaymentId: number; trx: Knex.Transaction; } export interface IBillPaymentCreatingPayload { - billPaymentDTO: IBillPaymentDTO; + billPaymentDTO: CreateBillPaymentDto; trx: Knex.Transaction; } export interface IBillPaymentEditingPayload { - billPaymentDTO: IBillPaymentDTO; + billPaymentDTO: EditBillPaymentDto; oldBillPayment: BillPayment; trx: Knex.Transaction; } @@ -54,7 +36,7 @@ export interface IBillPaymentEventEditedPayload { billPaymentId: number; billPayment: BillPayment; oldBillPayment: BillPayment; - billPaymentDTO: IBillPaymentDTO; + billPaymentDTO: EditBillPaymentDto; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/Bills/Bills.application.ts b/packages/server-nest/src/modules/Bills/Bills.application.ts index 2328a5e5c..5b8194cf3 100644 --- a/packages/server-nest/src/modules/Bills/Bills.application.ts +++ b/packages/server-nest/src/modules/Bills/Bills.application.ts @@ -7,6 +7,7 @@ import { GetDueBills } from './queries/GetDueBills.service'; import { OpenBillService } from './commands/OpenBill.service'; import { Injectable } from '@nestjs/common'; import { GetBillsService } from './queries/GetBills.service'; +import { CreateBillDto, EditBillDto } from './dtos/Bill.dto'; // import { GetBillPayments } from './queries/GetBillPayments'; // import { GetBills } from './queries/GetBills'; @@ -28,7 +29,7 @@ export class BillsApplication { * @param {IBillDTO} billDTO * @returns */ - public createBill(billDTO: IBillDTO) { + public createBill(billDTO: CreateBillDto) { return this.createBillService.createBill(billDTO); } @@ -38,7 +39,7 @@ export class BillsApplication { * @param {IBillEditDTO} billDTO * @returns */ - public editBill(billId: number, billDTO: IBillEditDTO) { + public editBill(billId: number, billDTO: EditBillDto) { return this.editBillService.editBill(billId, billDTO); } diff --git a/packages/server-nest/src/modules/Bills/Bills.controller.ts b/packages/server-nest/src/modules/Bills/Bills.controller.ts index 7f79a91a9..5abfb52a6 100644 --- a/packages/server-nest/src/modules/Bills/Bills.controller.ts +++ b/packages/server-nest/src/modules/Bills/Bills.controller.ts @@ -10,8 +10,9 @@ import { Query, } from '@nestjs/common'; import { BillsApplication } from './Bills.application'; -import { IBillDTO, IBillEditDTO, IBillsFilter } from './Bills.types'; +import { IBillsFilter } from './Bills.types'; import { PublicRoute } from '../Auth/Jwt.guard'; +import { CreateBillDto, EditBillDto } from './dtos/Bill.dto'; @Controller('bills') @ApiTags('bills') @@ -21,7 +22,7 @@ export class BillsController { @Post() @ApiOperation({ summary: 'Create a new bill.' }) - createBill(@Body() billDTO: IBillDTO) { + createBill(@Body() billDTO: CreateBillDto) { return this.billsApplication.createBill(billDTO); } @@ -33,7 +34,7 @@ export class BillsController { type: Number, description: 'The bill id', }) - editBill(@Param('id') billId: number, @Body() billDTO: IBillEditDTO) { + editBill(@Param('id') billId: number, @Body() billDTO: EditBillDto) { return this.billsApplication.editBill(billId, billDTO); } diff --git a/packages/server-nest/src/modules/Bills/Bills.types.ts b/packages/server-nest/src/modules/Bills/Bills.types.ts index dd57b14d9..586a6f27a 100644 --- a/packages/server-nest/src/modules/Bills/Bills.types.ts +++ b/packages/server-nest/src/modules/Bills/Bills.types.ts @@ -3,6 +3,7 @@ import { IItemEntryDTO } from '../TransactionItemEntry/ItemEntry.types'; import { AttachmentLinkDTO } from '../Attachments/Attachments.types'; import { Bill } from './models/Bill'; import { IDynamicListFilter } from '../DynamicListing/DynamicFilter/DynamicFilter.types'; +import { CreateBillDto, EditBillDto } from './dtos/Bill.dto'; export interface IBillDTO { vendorId: number; @@ -51,29 +52,25 @@ export interface IBillsFilter extends IDynamicListFilter { } export interface IBillCreatedPayload { - // tenantId: number; bill: Bill; - billDTO: IBillDTO; - // billId: number; + billDTO: CreateBillDto; trx?: Knex.Transaction; } export interface IBillCreatingPayload { - // tenantId: number; - billDTO: IBillDTO; + billDTO: CreateBillDto; trx: Knex.Transaction; } export interface IBillEditingPayload { - // tenantId: number; oldBill: Bill; - billDTO: IBillEditDTO; + billDTO: EditBillDto; trx: Knex.Transaction; } export interface IBillEditedPayload { oldBill: Bill; bill: Bill; - billDTO: IBillDTO; + billDTO: EditBillDto; trx?: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/Bills/commands/BillDTOTransformer.service.ts b/packages/server-nest/src/modules/Bills/commands/BillDTOTransformer.service.ts index a386170a2..3c416562e 100644 --- a/packages/server-nest/src/modules/Bills/commands/BillDTOTransformer.service.ts +++ b/packages/server-nest/src/modules/Bills/commands/BillDTOTransformer.service.ts @@ -15,6 +15,7 @@ import { Bill } from '../models/Bill'; import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateBillDto } from '../dtos/Bill.dto'; @Injectable() export class BillDTOTransformer { @@ -40,10 +41,10 @@ export class BillDTOTransformer { /** * Retrieve the bill landed cost amount. - * @param {IBillDTO} billDTO + * @param {CreateBillDto} billDTO * @returns {number} */ - private getBillLandedCostAmount(billDTO: IBillDTO): number { + private getBillLandedCostAmount(billDTO: CreateBillDto): number { const costEntries = billDTO.entries.filter((entry) => entry.landedCost); // return this.getBillEntriesTotal(costEntries); @@ -58,7 +59,7 @@ export class BillDTOTransformer { * @returns {IBill} */ public async billDTOToModel( - billDTO: IBillDTO, + billDTO: CreateBillDto, vendor: Vendor, oldBill?: Bill, ): Promise { diff --git a/packages/server-nest/src/modules/Bills/commands/BillsValidators.service.ts b/packages/server-nest/src/modules/Bills/commands/BillsValidators.service.ts index 072ab5fd1..86951d46a 100644 --- a/packages/server-nest/src/modules/Bills/commands/BillsValidators.service.ts +++ b/packages/server-nest/src/modules/Bills/commands/BillsValidators.service.ts @@ -9,6 +9,8 @@ import { BillLandedCost } from '@/modules/BillLandedCosts/models/BillLandedCost' import { VendorCreditAppliedBill } from '@/modules/VendorCreditsApplyBills/models/VendorCreditAppliedBill'; import { transformToMap } from '@/utils/transform-to-key'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { BillEntryDto } from '../dtos/Bill.dto'; @Injectable() export class BillsValidators { @@ -123,7 +125,7 @@ export class BillsValidators { * @param {IItemEntryDTO[]} newEntriesDTO - */ public async validateCostEntriesShouldBeInventoryItems( - newEntriesDTO: IItemEntryDTO[], + newEntriesDTO: BillEntryDto[], ) { const entriesItemsIds = newEntriesDTO.map((e) => e.itemId); const entriesItems = await this.itemModel() diff --git a/packages/server-nest/src/modules/Bills/commands/CreateBill.service.ts b/packages/server-nest/src/modules/Bills/commands/CreateBill.service.ts index ffa1cdbbd..61eee9fc2 100644 --- a/packages/server-nest/src/modules/Bills/commands/CreateBill.service.ts +++ b/packages/server-nest/src/modules/Bills/commands/CreateBill.service.ts @@ -14,6 +14,7 @@ import { Bill } from '../models/Bill'; import { Vendor } from '@/modules/Vendors/models/Vendor'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateBillDto } from '../dtos/Bill.dto'; @Injectable() export class CreateBill { @@ -46,7 +47,7 @@ export class CreateBill { * @return {Promise} */ public async createBill( - billDTO: IBillDTO, + billDTO: CreateBillDto, trx?: Knex.Transaction, ): Promise { // Retrieves the given bill vendor or throw not found error. diff --git a/packages/server-nest/src/modules/Bills/commands/EditBill.service.ts b/packages/server-nest/src/modules/Bills/commands/EditBill.service.ts index ca6300bed..7456c250c 100644 --- a/packages/server-nest/src/modules/Bills/commands/EditBill.service.ts +++ b/packages/server-nest/src/modules/Bills/commands/EditBill.service.ts @@ -15,6 +15,7 @@ import { Vendor } from '@/modules/Vendors/models/Vendor'; import { Knex } from 'knex'; import { TransactionLandedCostEntriesService } from '@/modules/BillLandedCosts/TransactionLandedCostEntries.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditBillDto } from '../dtos/Bill.dto'; @Injectable() export class EditBillService { @@ -46,7 +47,7 @@ export class EditBillService { * @param {IBillEditDTO} billDTO - The given new bill details. * @return {Promise} */ - public async editBill(billId: number, billDTO: IBillEditDTO): Promise { + public async editBill(billId: number, billDTO: EditBillDto): Promise { // Retrieve the given bill or throw not found error. const oldBill = await this.billModel() .query() diff --git a/packages/server-nest/src/modules/Bills/dtos/Bill.dto.ts b/packages/server-nest/src/modules/Bills/dtos/Bill.dto.ts new file mode 100644 index 000000000..a1f70ee9c --- /dev/null +++ b/packages/server-nest/src/modules/Bills/dtos/Bill.dto.ts @@ -0,0 +1,106 @@ +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsDate, + IsEnum, + IsInt, + IsNumber, + IsOptional, + IsPositive, + IsString, + Min, + MinLength, + ValidateNested, +} from 'class-validator'; + +enum DiscountType { + Percentage = 'percentage', + Amount = 'amount', +} + +export class BillEntryDto extends ItemEntryDto { + @IsOptional() + @IsBoolean() + landedCost?: boolean; +} + +class AttachmentDto { + @IsString() + key: string; +} + +export class CommandBillDto { + @IsString() + billNumber: string; + + @IsOptional() + @IsString() + referenceNo?: string; + + @IsDate() + @Type(() => Date) + billDate: Date; + + @IsOptional() + @IsDate() + @Type(() => Date) + dueDate?: Date; + + @IsInt() + vendorId: number; + + @IsOptional() + @IsNumber() + @IsPositive() + exchangeRate?: number; + + @IsOptional() + @IsInt() + warehouseId?: number; + + @IsOptional() + @IsInt() + branchId?: number; + + @IsOptional() + @IsInt() + projectId?: number; + + @IsOptional() + @IsString() + note?: string; + + @IsBoolean() + open: boolean = false; + + @IsBoolean() + isInclusiveTax: boolean = false; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => BillEntryDto) + @MinLength(1) + entries: BillEntryDto[]; + + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => AttachmentDto) + attachments?: AttachmentDto[]; + + @IsEnum(DiscountType) + discountType: DiscountType = DiscountType.Amount; + + @IsOptional() + @IsNumber() + discount?: number; + + @IsOptional() + @IsNumber() + adjustment?: number; +} + +export class CreateBillDto extends CommandBillDto {} +export class EditBillDto extends CommandBillDto {} diff --git a/packages/server-nest/src/modules/Branches/dtos/Branch.dto.ts b/packages/server-nest/src/modules/Branches/dtos/Branch.dto.ts index bb1e5ba43..648248fdc 100644 --- a/packages/server-nest/src/modules/Branches/dtos/Branch.dto.ts +++ b/packages/server-nest/src/modules/Branches/dtos/Branch.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { + IsBoolean, IsEmail, IsNotEmpty, IsOptional, @@ -13,6 +14,11 @@ class CommandBranchDto { @IsString() name: string; + @ApiPropertyOptional({ description: 'Branch code' }) + @IsOptional() + @IsBoolean() + primary?: boolean; + @ApiPropertyOptional({ description: 'Branch code' }) @IsOptional() @IsString() diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts b/packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts index ff2d0baab..6c307b41a 100644 --- a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts +++ b/packages/server-nest/src/modules/CreditNoteRefunds/CreditNoteRefunds.controller.ts @@ -3,6 +3,7 @@ import { Body, Controller, Delete, Param, Post } from '@nestjs/common'; import { ICreditNoteRefundDTO } from '../CreditNotes/types/CreditNotes.types'; import { CreditNotesRefundsApplication } from './CreditNotesRefundsApplication.service'; import { RefundCreditNote } from './models/RefundCreditNote'; +import { CreditNoteRefundDto } from './dto/CreditNoteRefund.dto'; @Controller('credit-notes') @ApiTags('credit-notes-refunds') @@ -21,7 +22,7 @@ export class CreditNoteRefundsController { @ApiOperation({ summary: 'Create a refund for the given credit note.' }) createRefundCreditNote( @Param('creditNoteId') creditNoteId: number, - @Body() creditNoteDTO: ICreditNoteRefundDTO, + @Body() creditNoteDTO: CreditNoteRefundDto, ): Promise { return this.creditNotesRefundsApplication.createRefundCreditNote( creditNoteId, diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts b/packages/server-nest/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts index 04db315dc..40c8917ca 100644 --- a/packages/server-nest/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts +++ b/packages/server-nest/src/modules/CreditNoteRefunds/CreditNotesRefundsApplication.service.ts @@ -4,6 +4,7 @@ import { CreateRefundCreditNoteService } from './commands/CreateRefundCreditNote import { DeleteRefundCreditNoteService } from './commands/DeleteRefundCreditNote.service'; import { RefundCreditNoteService } from './commands/RefundCreditNote.service'; import { RefundSyncCreditNoteBalanceService } from './commands/RefundSyncCreditNoteBalance'; +import { CreditNoteRefundDto } from './dto/CreditNoteRefund.dto'; @Injectable() export class CreditNotesRefundsApplication { @@ -17,12 +18,12 @@ export class CreditNotesRefundsApplication { /** * Create a refund credit note. * @param {number} creditNoteId - The credit note ID. - * @param {ICreditNoteRefundDTO} creditNoteDTO - The credit note DTO. + * @param {CreditNoteRefundDto} creditNoteDTO - The credit note DTO. * @returns {Promise} */ public createRefundCreditNote( creditNoteId: number, - creditNoteDTO: ICreditNoteRefundDTO, + creditNoteDTO: CreditNoteRefundDto, ) { return this.createRefundCreditNoteService.createCreditNoteRefund( creditNoteId, diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts b/packages/server-nest/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts index 0e61609b4..5d3c8098f 100644 --- a/packages/server-nest/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts +++ b/packages/server-nest/src/modules/CreditNoteRefunds/commands/CreateRefundCreditNote.service.ts @@ -13,6 +13,7 @@ import { CommandCreditNoteDTOTransform } from '@/modules/CreditNotes/commands/Co import { CreditNote } from '@/modules/CreditNotes/models/CreditNote'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreditNoteRefundDto } from '../dto/CreditNoteRefund.dto'; @Injectable() export class CreateRefundCreditNoteService { @@ -47,7 +48,7 @@ export class CreateRefundCreditNoteService { */ public async createCreditNoteRefund( creditNoteId: number, - newCreditNoteDTO: ICreditNoteRefundDTO, + newCreditNoteDTO: CreditNoteRefundDto, ): Promise { // Retrieve the credit note or throw not found service error. const creditNote = await this.creditNoteModel() @@ -85,7 +86,6 @@ export class CreateRefundCreditNoteService { .insertAndFetch({ ...this.transformDTOToModel(creditNote, newCreditNoteDTO), }); - // Triggers `onCreditNoteRefundCreated` event. await this.eventPublisher.emitAsync(events.creditNote.onRefundCreated, { trx, @@ -99,13 +99,13 @@ export class CreateRefundCreditNoteService { /** * Transformes the refund credit note DTO to model. - * @param {number} creditNoteId - * @param {ICreditNoteRefundDTO} creditNoteDTO - * @returns {ICreditNote} + * @param {CreditNote} creditNote - The credit note. + * @param {CreditNoteRefundDto} creditNoteDTO - The credit note refund DTO. + * @returns {Partial} */ private transformDTOToModel = ( creditNote: CreditNote, - creditNoteDTO: ICreditNoteRefundDTO, + creditNoteDTO: CreditNoteRefundDto, ): Partial => { return { creditNoteId: creditNote.id, diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts b/packages/server-nest/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts new file mode 100644 index 000000000..0c7bcbaed --- /dev/null +++ b/packages/server-nest/src/modules/CreditNoteRefunds/dto/CreditNoteRefund.dto.ts @@ -0,0 +1,35 @@ +import { IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator'; +import { IsDate } from 'class-validator'; +import { IsNumber } from 'class-validator'; + +export class CreditNoteRefundDto { + @IsNumber() + @IsNotEmpty() + fromAccountId: number; + + @IsNumber() + @IsPositive() + @IsNotEmpty() + amount: number; + + @IsNumber() + @IsOptional() + @IsPositive() + exchangeRate?: number; + + @IsString() + @IsNotEmpty() + referenceNo: string; + + @IsString() + @IsNotEmpty() + description: string; + + @IsDate() + @IsNotEmpty() + date: Date; + + @IsNumber() + @IsOptional() + branchId?: number; +} diff --git a/packages/server-nest/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts b/packages/server-nest/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts index 7b5df296a..610fad821 100644 --- a/packages/server-nest/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts +++ b/packages/server-nest/src/modules/CreditNoteRefunds/types/CreditNoteRefunds.types.ts @@ -1,6 +1,7 @@ import { Knex } from 'knex'; import { RefundCreditNote } from '../models/RefundCreditNote'; import { CreditNote } from '@/modules/CreditNotes/models/CreditNote'; +import { CreditNoteRefundDto } from '../dto/CreditNoteRefund.dto'; export interface ICreditNoteRefundDTO { fromAccountId: number; @@ -31,7 +32,7 @@ export interface IRefundCreditNoteDeletingPayload { export interface IRefundCreditNoteCreatingPayload { trx: Knex.Transaction; creditNote: CreditNote; - newCreditNoteDTO: ICreditNoteRefundDTO; + newCreditNoteDTO: CreditNoteRefundDto; } export interface IRefundCreditNoteCreatedPayload { diff --git a/packages/server-nest/src/modules/CreditNotes/CreditNoteApplication.service.ts b/packages/server-nest/src/modules/CreditNotes/CreditNoteApplication.service.ts index f2e530abc..74f298a29 100644 --- a/packages/server-nest/src/modules/CreditNotes/CreditNoteApplication.service.ts +++ b/packages/server-nest/src/modules/CreditNotes/CreditNoteApplication.service.ts @@ -4,12 +4,9 @@ import { DeleteCreditNoteService } from './commands/DeleteCreditNote.service'; import { EditCreditNoteService } from './commands/EditCreditNote.service'; import { OpenCreditNoteService } from './commands/OpenCreditNote.service'; import { GetCreditNotePdf } from './queries/GetCreditNotePdf.serivce'; -import { - ICreditNoteEditDTO, - ICreditNoteNewDTO, - ICreditNotesQueryDTO, -} from './types/CreditNotes.types'; +import { ICreditNotesQueryDTO } from './types/CreditNotes.types'; import { GetCreditNotesService } from './queries/GetCreditNotes.service'; +import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto'; @Injectable() export class CreditNoteApplication { @@ -24,20 +21,20 @@ export class CreditNoteApplication { /** * Creates a new credit note. - * @param {ICreditNoteNewDTO} creditNoteDTO + * @param {CreateCreditNoteDto} creditNoteDTO * @returns {Promise} */ - createCreditNote(creditNoteDTO: ICreditNoteNewDTO) { + createCreditNote(creditNoteDTO: CreateCreditNoteDto) { return this.createCreditNoteService.creditCreditNote(creditNoteDTO); } /** * Edits a credit note. * @param {number} creditNoteId - * @param {ICreditNoteEditDTO} creditNoteDTO + * @param {EditCreditNoteDto} creditNoteDTO * @returns {Promise} */ - editCreditNote(creditNoteId: number, creditNoteDTO: ICreditNoteEditDTO) { + editCreditNote(creditNoteId: number, creditNoteDTO: EditCreditNoteDto) { return this.editCreditNoteService.editCreditNote( creditNoteId, creditNoteDTO, diff --git a/packages/server-nest/src/modules/CreditNotes/CreditNotes.controller.ts b/packages/server-nest/src/modules/CreditNotes/CreditNotes.controller.ts index f4b11681c..ae9abd6c8 100644 --- a/packages/server-nest/src/modules/CreditNotes/CreditNotes.controller.ts +++ b/packages/server-nest/src/modules/CreditNotes/CreditNotes.controller.ts @@ -9,13 +9,10 @@ import { Query, } from '@nestjs/common'; import { CreditNoteApplication } from './CreditNoteApplication.service'; -import { - ICreditNoteEditDTO, - ICreditNoteNewDTO, - ICreditNotesQueryDTO, -} from './types/CreditNotes.types'; +import { ICreditNotesQueryDTO } from './types/CreditNotes.types'; import { PublicRoute } from '../Auth/Jwt.guard'; import { ApiTags } from '@nestjs/swagger'; +import { CreateCreditNoteDto, EditCreditNoteDto } from './dtos/CreditNote.dto'; @Controller('credit-notes') @ApiTags('credit-notes') @@ -27,7 +24,7 @@ export class CreditNotesController { constructor(private creditNoteApplication: CreditNoteApplication) {} @Post() - createCreditNote(@Body() creditNoteDTO: ICreditNoteNewDTO) { + createCreditNote(@Body() creditNoteDTO: CreateCreditNoteDto) { return this.creditNoteApplication.createCreditNote(creditNoteDTO); } @@ -39,7 +36,7 @@ export class CreditNotesController { @Put(':id') editCreditNote( @Param('id') creditNoteId: number, - @Body() creditNoteDTO: ICreditNoteEditDTO, + @Body() creditNoteDTO: EditCreditNoteDto, ) { return this.creditNoteApplication.editCreditNote( creditNoteId, diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts b/packages/server-nest/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts index b6eba29eb..0f66e0990 100644 --- a/packages/server-nest/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts +++ b/packages/server-nest/src/modules/CreditNotes/commands/CommandCreditNoteDTOTransform.service.ts @@ -17,6 +17,7 @@ import { BrandingTemplateDTOTransformer } from '../../PdfTemplate/BrandingTempla import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index'; import { CreditNoteAutoIncrementService } from './CreditNoteAutoIncrement.service'; import { CreditNote } from '../models/CreditNote'; +import { CreateCreditNoteDto, EditCreditNoteDto } from '../dtos/CreditNote.dto'; @Injectable() export class CommandCreditNoteDTOTransform { @@ -41,7 +42,7 @@ export class CommandCreditNoteDTOTransform { * @param {string} customerCurrencyCode - */ public transformCreateEditDTOToModel = async ( - creditNoteDTO: ICreditNoteNewDTO | ICreditNoteEditDTO, + creditNoteDTO: CreateCreditNoteDto | EditCreditNoteDto, customerCurrencyCode: string, oldCreditNote?: CreditNote, ): Promise => { diff --git a/packages/server-nest/src/modules/CreditNotes/commands/CreateCreditNote.service.ts b/packages/server-nest/src/modules/CreditNotes/commands/CreateCreditNote.service.ts index b82e72393..4968447bd 100644 --- a/packages/server-nest/src/modules/CreditNotes/commands/CreateCreditNote.service.ts +++ b/packages/server-nest/src/modules/CreditNotes/commands/CreateCreditNote.service.ts @@ -3,7 +3,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { ICreditNoteCreatedPayload, ICreditNoteCreatingPayload, - ICreditNoteNewDTO, } from '../types/CreditNotes.types'; import { CreditNote } from '../models/CreditNote'; import { Contact } from '../../Contacts/models/Contact'; @@ -13,6 +12,7 @@ import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateCreditNoteDto } from '../dtos/CreditNote.dto'; @Injectable() export class CreateCreditNoteService { @@ -42,7 +42,7 @@ export class CreateCreditNoteService { * @param creditNoteDTO */ public creditCreditNote = async ( - creditNoteDTO: ICreditNoteNewDTO, + creditNoteDTO: CreateCreditNoteDto, trx?: Knex.Transaction, ) => { // Triggers `onCreditNoteCreate` event. diff --git a/packages/server-nest/src/modules/CreditNotes/commands/EditCreditNote.service.ts b/packages/server-nest/src/modules/CreditNotes/commands/EditCreditNote.service.ts index d263d567f..11b1caee0 100644 --- a/packages/server-nest/src/modules/CreditNotes/commands/EditCreditNote.service.ts +++ b/packages/server-nest/src/modules/CreditNotes/commands/EditCreditNote.service.ts @@ -1,6 +1,5 @@ import { Inject, Injectable } from '@nestjs/common'; import { - ICreditNoteEditDTO, ICreditNoteEditedPayload, ICreditNoteEditingPayload, } from '../types/CreditNotes.types'; @@ -13,6 +12,7 @@ import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service'; import { events } from '@/common/events/events'; import { CommandCreditNoteDTOTransform } from './CommandCreditNoteDTOTransform.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditCreditNoteDto } from '../dtos/CreditNote.dto'; @Injectable() export class EditCreditNoteService { @@ -27,6 +27,7 @@ export class EditCreditNoteService { constructor( @Inject(CreditNote.name) private creditNoteModel: TenantModelProxy, + @Inject(Contact.name) private contactModel: TenantModelProxy, @@ -42,7 +43,7 @@ export class EditCreditNoteService { */ public async editCreditNote( creditNoteId: number, - creditNoteEditDTO: ICreditNoteEditDTO, + creditNoteEditDTO: EditCreditNoteDto, ) { // Retrieve the sale invoice or throw not found service error. const oldCreditNote = await this.creditNoteModel() diff --git a/packages/server-nest/src/modules/CreditNotes/dtos/CreditNote.dto.ts b/packages/server-nest/src/modules/CreditNotes/dtos/CreditNote.dto.ts new file mode 100644 index 000000000..251f6bc5a --- /dev/null +++ b/packages/server-nest/src/modules/CreditNotes/dtos/CreditNote.dto.ts @@ -0,0 +1,98 @@ +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsDate, + IsEnum, + IsInt, + IsNumber, + IsOptional, + IsPositive, + IsString, + Min, + ValidateNested, +} from 'class-validator'; + +enum DiscountType { + Percentage = 'percentage', + Amount = 'amount', +} + +class CreditNoteEntryDto extends ItemEntryDto {} + +class AttachmentDto { + @IsString() + key: string; +} + +export class CommandCreditNoteDto { + @IsInt() + customerId: number; + + @IsOptional() + @IsPositive() + exchangeRate?: number; + + @IsDate() + @Type(() => Date) + creditNoteDate: Date; + + @IsOptional() + @IsString() + referenceNo?: string; + + @IsOptional() + @IsString() + creditNoteNumber?: string; + + @IsOptional() + @IsString() + note?: string; + + @IsOptional() + @IsString() + termsConditions?: string; + + @IsBoolean() + open: boolean = false; + + @IsOptional() + @IsInt() + warehouseId?: number; + + @IsOptional() + @IsInt() + branchId?: number; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => CreditNoteEntryDto) + @Min(1) + entries: CreditNoteEntryDto[]; + + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => AttachmentDto) + attachments?: AttachmentDto[]; + + @IsOptional() + @IsInt() + pdfTemplateId?: number; + + @IsOptional() + @IsNumber() + discount?: number; + + @IsOptional() + @IsEnum(DiscountType) + discountType?: DiscountType; + + @IsOptional() + @IsNumber() + adjustment?: number; +} + +export class CreateCreditNoteDto extends CommandCreditNoteDto {} +export class EditCreditNoteDto extends CommandCreditNoteDto {} diff --git a/packages/server-nest/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts b/packages/server-nest/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts new file mode 100644 index 000000000..a78b986a3 --- /dev/null +++ b/packages/server-nest/src/modules/CreditNotes/dtos/RefundCreditNote.dto.ts @@ -0,0 +1,12 @@ +import { + IsDate, + IsInt, + IsNumber, + IsOptional, + IsPositive, + IsString, +} from 'class-validator'; + +export class RefundCreditNoteDto { + +} diff --git a/packages/server-nest/src/modules/CreditNotes/types/CreditNotes.types.ts b/packages/server-nest/src/modules/CreditNotes/types/CreditNotes.types.ts index 2362a001a..b133e868a 100644 --- a/packages/server-nest/src/modules/CreditNotes/types/CreditNotes.types.ts +++ b/packages/server-nest/src/modules/CreditNotes/types/CreditNotes.types.ts @@ -6,6 +6,7 @@ import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types'; import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model'; import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types'; import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types'; +import { EditCreditNoteDto } from '../dtos/CreditNote.dto'; export interface ICreditNoteEntryNewDTO extends IItemEntryDTO {} @@ -60,17 +61,16 @@ export interface ICreditNoteDeletedPayload { } export interface ICreditNoteEditingPayload { - trx: Knex.Transaction; oldCreditNote: CreditNote; - creditNoteEditDTO: ICreditNoteEditDTO; - tenantId: number; + creditNoteEditDTO: EditCreditNoteDto; + trx?: Knex.Transaction; } export interface ICreditNoteEditedPayload { - trx: Knex.Transaction; + trx?: Knex.Transaction; oldCreditNote: CreditNote; creditNote: CreditNote; - creditNoteEditDTO: ICreditNoteEditDTO; + creditNoteEditDTO: EditCreditNoteDto; } export interface ICreditNoteCreatedPayload { diff --git a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts b/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts index e658a7b23..168bb2fa8 100644 --- a/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts +++ b/packages/server-nest/src/modules/FinancialStatements/modules/TrialBalanceSheet/TrialBalanceSheetApplication.ts @@ -6,6 +6,11 @@ import { Injectable } from '@nestjs/common'; @Injectable() export class TrialBalanceSheetApplication { + /** + * @param {TrialBalanceSheetService} sheetService - The trial balance sheet service. + * @param {TrialBalanceSheetTableInjectable} tablable - The trial balance sheet table injectable. + * @param {TrialBalanceExportInjectable} exportable - The trial balance export injectable. + */ constructor( private readonly sheetService: TrialBalanceSheetService, private readonly tablable: TrialBalanceSheetTableInjectable, diff --git a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts b/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts index 8b251fbfb..1b6d8dac5 100644 --- a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts +++ b/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustments.controller.ts @@ -17,6 +17,7 @@ import { InventoryAdjustment } from './models/InventoryAdjustment'; import { PublicRoute } from '../Auth/Jwt.guard'; import { IPaginationMeta } from '@/interfaces/Model'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { CreateQuickInventoryAdjustmentDto } from './dtos/CreateQuickInventoryAdjustment.dto'; @Controller('inventory-adjustments') @ApiTags('inventory-adjustments') @@ -33,7 +34,7 @@ export class InventoryAdjustmentsController { description: 'The inventory adjustment has been successfully created.', }) public async createQuickInventoryAdjustment( - @Body() quickAdjustmentDTO: IQuickInventoryAdjustmentDTO, + @Body() quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto, ): Promise { return this.inventoryAdjustmentsApplicationService.createQuickInventoryAdjustment( quickAdjustmentDTO, diff --git a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts b/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts index 000bf0507..5d66ad8b8 100644 --- a/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts +++ b/packages/server-nest/src/modules/InventoryAdjutments/InventoryAdjustmentsApplication.service.ts @@ -10,6 +10,7 @@ import { InventoryAdjustment } from './models/InventoryAdjustment'; import { GetInventoryAdjustmentService } from './queries/GetInventoryAdjustment.service'; import { GetInventoryAdjustmentsService } from './queries/GetInventoryAdjustments.service'; import { IPaginationMeta } from '@/interfaces/Model'; +import { CreateQuickInventoryAdjustmentDto } from './dtos/CreateQuickInventoryAdjustment.dto'; @Injectable() export class InventoryAdjustmentsApplicationService { @@ -39,7 +40,7 @@ export class InventoryAdjustmentsApplicationService { * @param {IQuickInventoryAdjustmentDTO} quickAdjustmentDTO - Quick inventory adjustment DTO. */ public async createQuickInventoryAdjustment( - quickAdjustmentDTO: IQuickInventoryAdjustmentDTO, + quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto, ): Promise { return this.createQuickInventoryAdjustmentService.createQuickAdjustment( quickAdjustmentDTO, diff --git a/packages/server-nest/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts b/packages/server-nest/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts index d5c9bebb8..7d0d0da88 100644 --- a/packages/server-nest/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts +++ b/packages/server-nest/src/modules/InventoryAdjutments/commands/CreateQuickInventoryAdjustment.service.ts @@ -17,6 +17,7 @@ import { Item } from '@/modules/Items/models/Item'; import { Account } from '@/modules/Accounts/models/Account.model'; import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform'; import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform'; +import { CreateQuickInventoryAdjustmentDto } from '../dtos/CreateQuickInventoryAdjustment.dto'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { ERRORS } from '../constants/InventoryAdjustments.constants'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; @@ -89,7 +90,7 @@ export class CreateQuickInventoryAdjustmentService { * @param {IQuickInventoryAdjustmentDTO} quickAdjustmentDTO - qucik adjustment DTO. */ public async createQuickAdjustment( - quickAdjustmentDTO: IQuickInventoryAdjustmentDTO, + quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto, ): Promise { // Retrieve the adjustment account or throw not found error. const adjustmentAccount = await this.accountModel() diff --git a/packages/server-nest/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts b/packages/server-nest/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts new file mode 100644 index 000000000..c1f9950cc --- /dev/null +++ b/packages/server-nest/src/modules/InventoryAdjutments/dtos/CreateQuickInventoryAdjustment.dto.ts @@ -0,0 +1,86 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { + IsBoolean, + IsDate, + IsEnum, + IsNotEmpty, + IsNumber, + IsOptional, + IsPositive, + IsString, +} from 'class-validator'; +import { Type } from 'class-transformer'; + +enum IAdjustmentTypes { + INCREMENT = 'increment', + DECREMENT = 'decrement', +} + +export class CreateQuickInventoryAdjustmentDto { + @ApiProperty({ description: 'Date of the inventory adjustment' }) + @IsNotEmpty() + @IsDate() + @Type(() => Date) + date: Date; + + @ApiProperty({ description: 'Type of adjustment', enum: IAdjustmentTypes }) + @IsNotEmpty() + @IsEnum(IAdjustmentTypes) + type: 'increment' | 'decrement'; + + @ApiProperty({ description: 'ID of the adjustment account' }) + @IsNotEmpty() + @IsNumber() + @IsPositive() + adjustmentAccountId: number; + + @ApiProperty({ description: 'Reason for the adjustment' }) + @IsNotEmpty() + @IsString() + reason: string; + + @ApiProperty({ description: 'Description of the adjustment' }) + @IsNotEmpty() + @IsString() + description: string; + + @ApiProperty({ description: 'Reference number' }) + @IsNotEmpty() + @IsString() + referenceNo: string; + + @ApiProperty({ description: 'ID of the item being adjusted' }) + @IsNotEmpty() + @IsNumber() + @IsPositive() + itemId: number; + + @ApiProperty({ description: 'Quantity to adjust' }) + @IsNotEmpty() + @IsNumber() + @IsPositive() + quantity: number; + + @ApiProperty({ description: 'Cost of the item' }) + @IsNotEmpty() + @IsNumber() + @IsPositive() + cost: number; + + @ApiProperty({ description: 'Whether to publish the adjustment immediately' }) + @IsNotEmpty() + @IsBoolean() + publish: boolean; + + @ApiPropertyOptional({ description: 'ID of the warehouse (optional)' }) + @IsOptional() + @IsNumber() + @IsPositive() + warehouseId?: number; + + @ApiPropertyOptional({ description: 'ID of the branch (optional)' }) + @IsOptional() + @IsNumber() + @IsPositive() + branchId?: number; +} diff --git a/packages/server-nest/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts b/packages/server-nest/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts index 4e988a234..d2c475ac5 100644 --- a/packages/server-nest/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts +++ b/packages/server-nest/src/modules/InventoryAdjutments/types/InventoryAdjustments.types.ts @@ -1,5 +1,6 @@ import { Knex } from 'knex'; import { InventoryAdjustment } from '../models/InventoryAdjustment'; +import { CreateQuickInventoryAdjustmentDto } from '../dtos/CreateQuickInventoryAdjustment.dto'; type IAdjustmentTypes = 'increment' | 'decrement'; @@ -29,7 +30,7 @@ export interface IInventoryAdjustmentEventCreatedPayload { trx: Knex.Transaction; } export interface IInventoryAdjustmentCreatingPayload { - quickAdjustmentDTO: IQuickInventoryAdjustmentDTO; + quickAdjustmentDTO: CreateQuickInventoryAdjustmentDto; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/Items/Item.controller.ts b/packages/server-nest/src/modules/Items/Item.controller.ts index 160e00980..141f67cdf 100644 --- a/packages/server-nest/src/modules/Items/Item.controller.ts +++ b/packages/server-nest/src/modules/Items/Item.controller.ts @@ -118,7 +118,6 @@ export class ItemsController extends TenantController { description: 'The item has been successfully updated.', }) @ApiResponse({ status: 404, description: 'The item not found.' }) - // @UsePipes(new ZodValidationPipe(createItemSchema)) async editItem( @Param('id') id: string, @Body() editItemDto: EditItemDto, diff --git a/packages/server-nest/src/modules/Items/ItemsEntries.service.ts b/packages/server-nest/src/modules/Items/ItemsEntries.service.ts index 12d14ba8b..c6fa5a4ac 100644 --- a/packages/server-nest/src/modules/Items/ItemsEntries.service.ts +++ b/packages/server-nest/src/modules/Items/ItemsEntries.service.ts @@ -7,6 +7,7 @@ import { ServiceError } from './ServiceError'; import { IItemEntryDTO } from '../TransactionItemEntry/ItemEntry.types'; import { TenantModelProxy } from '../System/models/TenantBaseModel'; import { entriesAmountDiff } from '@/utils/entries-amount-diff'; +import { ItemEntryDto } from '../TransactionItemEntry/dto/ItemEntry.dto'; const ERRORS = { ITEMS_NOT_FOUND: 'ITEMS_NOT_FOUND', @@ -83,7 +84,7 @@ export class ItemsEntriesService { * @param {IItemEntryDTO[]} itemEntries - Items entries. * @returns {Promise} */ - public async validateItemsIdsExistance(itemEntries: IItemEntryDTO[]) { + public async validateItemsIdsExistance(itemEntries: Array<{ itemId: number }>) { const itemsIds = itemEntries.map((e) => e.itemId); const foundItems = await this.itemModel().query().whereIn('id', itemsIds); @@ -106,7 +107,7 @@ export class ItemsEntriesService { public async validateEntriesIdsExistance( referenceId: number, referenceType: string, - billEntries: IItemEntryDTO[], + billEntries: ItemEntryDto[], ) { const entriesIds = billEntries .filter((e: ItemEntry) => e.id) @@ -130,9 +131,9 @@ export class ItemsEntriesService { * @param {IItemEntryDTO[]} itemEntries - */ public async validateNonPurchasableEntriesItems( - itemEntries: IItemEntryDTO[], + itemEntries: ItemEntryDto[], ) { - const itemsIds = itemEntries.map((e: IItemEntryDTO) => e.itemId); + const itemsIds = itemEntries.map((e: ItemEntryDto) => e.itemId); const purchasbleItems = await this.itemModel() .query() .where('purchasable', true) @@ -150,8 +151,8 @@ export class ItemsEntriesService { * Validate the entries items that not sell-able. * @param {IItemEntryDTO[]} itemEntries - */ - public async validateNonSellableEntriesItems(itemEntries: IItemEntryDTO[]) { - const itemsIds = itemEntries.map((e: IItemEntryDTO) => e.itemId); + public async validateNonSellableEntriesItems(itemEntries: ItemEntryDto[]) { + const itemsIds = itemEntries.map((e: ItemEntryDto) => e.itemId); const sellableItems = await this.itemModel() .query() @@ -218,7 +219,7 @@ export class ItemsEntriesService { /** * Sets the cost/sell accounts to the invoice entries. */ - public setItemsEntriesDefaultAccounts = async (entries: IItemEntryDTO[]) => { + public setItemsEntriesDefaultAccounts = async (entries: ItemEntryDto[]) => { const entriesItemsIds = entries.map((e) => e.itemId); const items = await this.itemModel().query().whereIn('id', entriesItemsIds); @@ -240,7 +241,7 @@ export class ItemsEntriesService { * @param {ItemEntry[]} entries - Items entries. * @returns {number} */ - public getTotalItemsEntries(entries: IItemEntryDTO[]): number { + public getTotalItemsEntries(entries: ItemEntryDto[]): number { return sumBy(entries, (e) => ItemEntry.calcAmount(e)); } diff --git a/packages/server-nest/src/modules/PaymentReceived/PaymentReceived.application.ts b/packages/server-nest/src/modules/PaymentReceived/PaymentReceived.application.ts index 13a4de879..62151eb44 100644 --- a/packages/server-nest/src/modules/PaymentReceived/PaymentReceived.application.ts +++ b/packages/server-nest/src/modules/PaymentReceived/PaymentReceived.application.ts @@ -14,6 +14,10 @@ import { GetPaymentReceivedPdfService } from './queries/GetPaymentReceivedPdf.se import { GetPaymentReceivedStateService } from './queries/GetPaymentReceivedState.service'; import { GetPaymentsReceivedService } from './queries/GetPaymentsReceived.service'; import { SendPaymentReceiveMailNotification } from './commands/PaymentReceivedMailNotification'; +import { + CreatePaymentReceivedDto, + EditPaymentReceivedDto, +} from './dtos/PaymentReceived.dto'; @Injectable() export class PaymentReceivesApplication { @@ -31,10 +35,10 @@ export class PaymentReceivesApplication { /** * Creates a new payment receive. - * @param {IPaymentReceivedCreateDTO} paymentReceiveDTO + * @param {CreatePaymentReceivedDto} paymentReceiveDTO * @returns */ - public createPaymentReceived(paymentReceiveDTO: IPaymentReceivedCreateDTO) { + public createPaymentReceived(paymentReceiveDTO: CreatePaymentReceivedDto) { return this.createPaymentReceivedService.createPaymentReceived( paymentReceiveDTO, ); @@ -43,12 +47,12 @@ export class PaymentReceivesApplication { /** * Edit details the given payment receive with associated entries. * @param {number} paymentReceiveId - Payment receive id. - * @param {IPaymentReceivedEditDTO} paymentReceiveDTO - Payment receive data. + * @param {EditPaymentReceivedDto} paymentReceiveDTO - Payment receive data. * @returns */ public editPaymentReceive( paymentReceiveId: number, - paymentReceiveDTO: IPaymentReceivedEditDTO, + paymentReceiveDTO: EditPaymentReceivedDto, ) { return this.editPaymentReceivedService.editPaymentReceive( paymentReceiveId, @@ -130,17 +134,17 @@ export class PaymentReceivesApplication { * @param {PaymentReceive} paymentReceive * @returns */ - public getPaymentReceivePdf = (paymentReceiveId: number) => { + public getPaymentReceivePdf(paymentReceiveId: number) { return this.getPaymentReceivePdfService.getPaymentReceivePdf( paymentReceiveId, ); - }; + } /** * Retrieves the create/edit initial state of the payment received. * @returns {Promise} */ - public getPaymentReceivedState = () => { + public getPaymentReceivedState() { return this.getPaymentReceivedStateService.getPaymentReceivedState(); - }; + } } diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts b/packages/server-nest/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts index 9d94fc7a8..a15b39939 100644 --- a/packages/server-nest/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts +++ b/packages/server-nest/src/modules/PaymentReceived/commands/CreatePaymentReceived.serivce.ts @@ -14,6 +14,7 @@ import { Customer } from '@/modules/Customers/models/Customer'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { Inject, Injectable } from '@nestjs/common'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreatePaymentReceivedDto } from '../dtos/PaymentReceived.dto'; @Injectable() export class CreatePaymentReceivedService { @@ -38,7 +39,7 @@ export class CreatePaymentReceivedService { * @param {Knex.Transaction} trx - Database transaction. */ public async createPaymentReceived( - paymentReceiveDTO: IPaymentReceivedCreateDTO, + paymentReceiveDTO: CreatePaymentReceivedDto, trx?: Knex.Transaction, ) { const tenant = await this.tenancyContext.getTenant(true); diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts b/packages/server-nest/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts index 1546c87c2..f74ad6bd7 100644 --- a/packages/server-nest/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts +++ b/packages/server-nest/src/modules/PaymentReceived/commands/EditPaymentReceived.service.ts @@ -14,6 +14,7 @@ import { events } from '@/common/events/events'; import { Customer } from '@/modules/Customers/models/Customer'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditPaymentReceivedDto } from '../dtos/PaymentReceived.dto'; @Injectable() export class EditPaymentReceivedService { @@ -49,7 +50,7 @@ export class EditPaymentReceivedService { */ public async editPaymentReceive( paymentReceiveId: number, - paymentReceiveDTO: IPaymentReceivedEditDTO, + paymentReceiveDTO: EditPaymentReceivedDto, ) { const tenant = await this.tenancyContext.getTenant(true); @@ -151,7 +152,7 @@ export class EditPaymentReceivedService { */ private transformEditDTOToModel = async ( customer: Customer, - paymentReceiveDTO: IPaymentReceivedEditDTO, + paymentReceiveDTO: EditPaymentReceivedDto, oldPaymentReceive: PaymentReceived, ) => { return this.transformer.transformPaymentReceiveDTOToModel( diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts b/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts index 6c30e8514..e3942bd01 100644 --- a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts +++ b/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedValidators.service.ts @@ -12,6 +12,7 @@ import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice'; import { ServiceError } from '@/modules/Items/ServiceError'; import { ACCOUNT_TYPE } from '@/constants/accounts'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditPaymentReceivedDto } from '../dtos/PaymentReceived.dto'; @Injectable() export class PaymentReceivedValidators { @@ -191,11 +192,11 @@ export class PaymentReceivedValidators { /** * Validate the payment customer whether modified. - * @param {IPaymentReceivedEditDTO} paymentReceiveDTO - * @param {IPaymentReceived} oldPaymentReceive + * @param {EditPaymentReceivedDto} paymentReceiveDTO + * @param {PaymentReceived} oldPaymentReceive */ public validateCustomerNotModified( - paymentReceiveDTO: IPaymentReceivedEditDTO, + paymentReceiveDTO: EditPaymentReceivedDto, oldPaymentReceive: PaymentReceived, ) { if (paymentReceiveDTO.customerId !== oldPaymentReceive.customerId) { diff --git a/packages/server-nest/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts b/packages/server-nest/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts new file mode 100644 index 000000000..2f1ea95ae --- /dev/null +++ b/packages/server-nest/src/modules/PaymentReceived/dtos/PaymentReceived.dto.ts @@ -0,0 +1,75 @@ +import { AttachmentLinkDto } from '@/modules/Attachments/dtos/Attachment.dto'; +import { Type } from 'class-transformer'; +import { IsArray, ValidateNested } from 'class-validator'; +import { IsString } from 'class-validator'; +import { IsDateString, IsNumber, IsOptional } from 'class-validator'; +import { IsInt } from 'class-validator'; + +export class PaymentReceivedEntryDto { + @IsOptional() + @IsInt() + id?: number; + + @IsOptional() + @IsInt() + index?: number; + + @IsOptional() + @IsInt() + paymentReceiveId?: number; + + @IsInt() + invoiceId: number; + + @IsNumber() + paymentAmount: number; +} + +export class CommandPaymentReceivedDto { + @IsInt() + customerId: number; + + @IsDateString() + paymentDate: Date | string; + + @IsOptional() + @IsNumber() + amount?: number; + + @IsOptional() + @IsNumber() + exchangeRate?: number; + + @IsOptional() + @IsString() + referenceNo?: string; + + @IsInt() + depositAccountId: number; + + @IsOptional() + @IsString() + paymentReceiveNo?: string; + + @IsOptional() + @IsString() + statement?: string; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => PaymentReceivedEntryDto) + entries: PaymentReceivedEntryDto[]; + + @IsOptional() + @IsInt() + branchId?: number; + + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => AttachmentLinkDto) + attachments?: AttachmentLinkDto[]; +} + +export class CreatePaymentReceivedDto extends CommandPaymentReceivedDto {} +export class EditPaymentReceivedDto extends CommandPaymentReceivedDto {} diff --git a/packages/server-nest/src/modules/PaymentReceived/types/PaymentReceived.types.ts b/packages/server-nest/src/modules/PaymentReceived/types/PaymentReceived.types.ts index 12889242e..2b1b1a209 100644 --- a/packages/server-nest/src/modules/PaymentReceived/types/PaymentReceived.types.ts +++ b/packages/server-nest/src/modules/PaymentReceived/types/PaymentReceived.types.ts @@ -7,6 +7,17 @@ import { CommonMailOptionsDTO, } from '@/modules/MailNotification/MailNotification.types'; import { TenantJobPayload } from '@/interfaces/Tenant'; +import { EditPaymentReceivedDto } from '../dtos/PaymentReceived.dto'; + + +export interface IPaymentReceivedEntryDTO { + id?: number; + index?: number; + paymentReceiveId?: number; + invoiceId: number; + paymentAmount: number; +} + export interface IPaymentReceivedCreateDTO { customerId: number; @@ -37,14 +48,6 @@ export interface IPaymentReceivedEditDTO { attachments?: AttachmentLinkDTO[]; } -export interface IPaymentReceivedEntryDTO { - id?: number; - index?: number; - paymentReceiveId?: number; - invoiceId: number; - paymentAmount: number; -} - export interface IPaymentsReceivedFilter extends IDynamicListFilter { stringifiedFilterRoles?: string; filterQuery?: (trx: Knex.Transaction) => void; @@ -96,32 +99,26 @@ export interface IPaymentReceivedCreatedPayload { } export interface IPaymentReceivedEditedPayload { - // tenantId: number; paymentReceiveId: number; paymentReceive: PaymentReceived; oldPaymentReceive: PaymentReceived; - paymentReceiveDTO: IPaymentReceivedEditDTO; - // authorizedUser: ISystemUser; + paymentReceiveDTO: EditPaymentReceivedDto; trx: Knex.Transaction; } export interface IPaymentReceivedEditingPayload { - // tenantId: number; oldPaymentReceive: PaymentReceived; paymentReceiveDTO: IPaymentReceivedEditDTO; trx: Knex.Transaction; } export interface IPaymentReceivedDeletingPayload { - // tenantId: number; oldPaymentReceive: PaymentReceived; trx: Knex.Transaction; } export interface IPaymentReceivedDeletedPayload { - // tenantId: number; paymentReceiveId: number; oldPaymentReceive: PaymentReceived; - // authorizedUser: ISystemUser; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.application.ts b/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.application.ts index 0b9a36227..9ab18930a 100644 --- a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.application.ts +++ b/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.application.ts @@ -1,6 +1,6 @@ +import { Injectable } from '@nestjs/common'; import { CreateSaleEstimate } from './commands/CreateSaleEstimate.service'; import { - ISaleEstimateDTO, ISalesEstimatesFilter, SaleEstimateMailOptionsDTO, } from './types/SaleEstimates.types'; @@ -10,12 +10,14 @@ import { GetSaleEstimate } from './queries/GetSaleEstimate.service'; import { DeliverSaleEstimateService } from './commands/DeliverSaleEstimate.service'; import { ApproveSaleEstimateService } from './commands/ApproveSaleEstimate.service'; import { RejectSaleEstimateService } from './commands/RejectSaleEstimate.service'; -// import { SaleEstimateNotifyBySms } from './commands/SaleEstimateSmsNotify'; import { SendSaleEstimateMail } from './commands/SendSaleEstimateMail'; import { GetSaleEstimateState } from './queries/GetSaleEstimateState.service'; import { GetSaleEstimatesService } from './queries/GetSaleEstimates.service'; -import { Injectable } from '@nestjs/common'; import { GetSaleEstimatePdf } from './queries/GetSaleEstimatePdf'; +import { + CreateSaleEstimateDto, + EditSaleEstimateDto, +} from './dtos/SaleEstimate.dto'; @Injectable() export class SaleEstimatesApplication { @@ -31,25 +33,27 @@ export class SaleEstimatesApplication { private readonly sendEstimateMailService: SendSaleEstimateMail, private readonly getSaleEstimateStateService: GetSaleEstimateState, private readonly saleEstimatesPdfService: GetSaleEstimatePdf, - // private readonly saleEstimateNotifyBySmsService: SaleEstimateNotifyBySms, ) {} /** * Create a sale estimate. - * @param {EstimateDTO} estimate - Estimate DTO. + * @param {CreateSaleEstimateDto} estimate - Estimate DTO. * @return {Promise} */ - public createSaleEstimate(estimateDTO: ISaleEstimateDTO) { + public createSaleEstimate(estimateDTO: CreateSaleEstimateDto) { return this.createSaleEstimateService.createEstimate(estimateDTO); } /** * Edit the given sale estimate. * @param {number} estimateId - Sale estimate ID. - * @param {EstimateDTO} estimate - Estimate DTO. + * @param {EditSaleEstimateDto} estimate - Estimate DTO. * @return {Promise} */ - public editSaleEstimate(estimateId: number, estimateDTO: ISaleEstimateDTO) { + public editSaleEstimate( + estimateId: number, + estimateDTO: EditSaleEstimateDto, + ) { return this.editSaleEstimateService.editEstimate(estimateId, estimateDTO); } diff --git a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.controller.ts b/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.controller.ts index 34487759b..dea059596 100644 --- a/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.controller.ts +++ b/packages/server-nest/src/modules/SaleEstimates/SaleEstimates.controller.ts @@ -13,12 +13,15 @@ import { } from '@nestjs/common'; import { SaleEstimatesApplication } from './SaleEstimates.application'; import { - ISaleEstimateDTO, ISalesEstimatesFilter, SaleEstimateMailOptionsDTO, } from './types/SaleEstimates.types'; import { SaleEstimate } from './models/SaleEstimate'; import { PublicRoute } from '../Auth/Jwt.guard'; +import { + CreateSaleEstimateDto, + EditSaleEstimateDto, +} from './dtos/SaleEstimate.dto'; @Controller('sale-estimates') @ApiTags('sale-estimates') @@ -38,7 +41,7 @@ export class SaleEstimatesController { description: 'Sale estimate created successfully', }) public createSaleEstimate( - @Body() estimateDTO: ISaleEstimateDTO, + @Body() estimateDTO: CreateSaleEstimateDto, ): Promise { return this.saleEstimatesApplication.createSaleEstimate(estimateDTO); } @@ -61,7 +64,7 @@ export class SaleEstimatesController { }) public editSaleEstimate( @Param('id', ParseIntPipe) estimateId: number, - @Body() estimateDTO: ISaleEstimateDTO, + @Body() estimateDTO: EditSaleEstimateDto, ): Promise { return this.saleEstimatesApplication.editSaleEstimate( estimateId, diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts b/packages/server-nest/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts index d0329f050..b66cb6e1d 100644 --- a/packages/server-nest/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts +++ b/packages/server-nest/src/modules/SaleEstimates/commands/CreateSaleEstimate.service.ts @@ -14,6 +14,7 @@ import { events } from '@/common/events/events'; import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; import { Customer } from '@/modules/Customers/models/Customer'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateSaleEstimateDto } from '../dtos/SaleEstimate.dto'; @Injectable() export class CreateSaleEstimate { @@ -37,7 +38,7 @@ export class CreateSaleEstimate { * @return {Promise} */ public async createEstimate( - estimateDTO: ISaleEstimateDTO, + estimateDTO: CreateSaleEstimateDto, trx?: Knex.Transaction, ): Promise { // Retrieve the given customer or throw not found service error. diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts b/packages/server-nest/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts index fbbc1263b..16a9dd9cf 100644 --- a/packages/server-nest/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts +++ b/packages/server-nest/src/modules/SaleEstimates/commands/EditSaleEstimate.service.ts @@ -14,6 +14,7 @@ import { SaleEstimate } from '../models/SaleEstimate'; import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; import { Customer } from '@/modules/Customers/models/Customer'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditSaleEstimateDto } from '../dtos/SaleEstimate.dto'; @Injectable() export class EditSaleEstimate { @@ -40,7 +41,7 @@ export class EditSaleEstimate { */ public async editEstimate( estimateId: number, - estimateDTO: ISaleEstimateDTO, + estimateDTO: EditSaleEstimateDto, ): Promise { // Retrieve details of the given sale estimate id. const oldSaleEstimate = await this.saleEstimateModel() diff --git a/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts b/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts index 5ca633526..3a2600e8a 100644 --- a/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts +++ b/packages/server-nest/src/modules/SaleEstimates/commands/SaleEstimateDTOTransformer.service.ts @@ -2,10 +2,7 @@ import * as R from 'ramda'; import { Inject, Injectable } from '@nestjs/common'; import { omit, sumBy } from 'lodash'; import * as composeAsync from 'async/compose'; -// import { ICustomer, ISaleEstimate, ISaleEstimateDTO } from '../types/SaleEstimates.types'; import { SaleEstimateValidators } from './SaleEstimateValidators.service'; -// import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform'; -// import { WarehouseTransactionDTOTransform } from '@/services/Warehouses/Integrations/WarehouseTransactionDTOTransform'; import { formatDateFields } from '@/utils/format-date-fields'; import * as moment from 'moment'; import { SaleEstimateIncrement } from './SaleEstimateIncrement.service'; @@ -18,8 +15,7 @@ import { SaleEstimate } from '../models/SaleEstimate'; import { Customer } from '@/modules/Customers/models/Customer'; import { ISaleEstimateDTO } from '../types/SaleEstimates.types'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; -// import { assocItemEntriesDefaultIndex } from '@/services/Items/utils'; -// import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer'; +import { CommandSaleEstimateDto } from '../dtos/SaleEstimate.dto'; @Injectable() export class SaleEstimateDTOTransformer { @@ -42,7 +38,7 @@ export class SaleEstimateDTOTransformer { * @return {ISaleEstimate} */ async transformDTOToModel( - estimateDTO: ISaleEstimateDTO, + estimateDTO: CommandSaleEstimateDto, paymentCustomer: Customer, oldSaleEstimate?: SaleEstimate, ): Promise { diff --git a/packages/server-nest/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts b/packages/server-nest/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts new file mode 100644 index 000000000..4a374b770 --- /dev/null +++ b/packages/server-nest/src/modules/SaleEstimates/dtos/SaleEstimate.dto.ts @@ -0,0 +1,104 @@ +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsDate, + IsEnum, + IsNumber, + IsOptional, + IsString, + Min, + MinLength, + ValidateNested, +} from 'class-validator'; + +enum DiscountType { + Percentage = 'percentage', + Amount = 'amount', +} + +class SaleEstimateEntryDto extends ItemEntryDto {} + +class AttachmentDto { + @IsString() + key: string; +} +export class CommandSaleEstimateDto { + @IsNumber() + customerId: number; + + @IsDate() + @Type(() => Date) + estimateDate: Date; + + @IsDate() + @Type(() => Date) + expirationDate: Date; + + @IsString() + @IsOptional() + reference?: string; + + @IsString() + @IsOptional() + estimateNumber?: string; + + @IsBoolean() + delivered: boolean = false; + + @IsNumber() + @Min(0.01) + @IsOptional() + exchangeRate?: number; + + @IsNumber() + @IsOptional() + warehouseId?: number; + + @IsNumber() + @IsOptional() + branchId?: number; + + @IsArray() + @MinLength(1) + @ValidateNested({ each: true }) + @Type(() => SaleEstimateEntryDto) + entries: SaleEstimateEntryDto[]; + + @IsString() + @IsOptional() + note?: string; + + @IsString() + @IsOptional() + termsConditions?: string; + + @IsString() + @IsOptional() + sendToEmail?: string; + + @IsArray() + @IsOptional() + @ValidateNested({ each: true }) + @Type(() => AttachmentDto) + attachments?: AttachmentDto[]; + + @IsNumber() + @IsOptional() + pdfTemplateId?: number; + + @IsNumber() + @IsOptional() + discount?: number; + + @IsEnum(DiscountType) + discountType: DiscountType = DiscountType.Amount; + + @IsNumber() + @IsOptional() + adjustment?: number; +} + +export class CreateSaleEstimateDto extends CommandSaleEstimateDto {} +export class EditSaleEstimateDto extends CommandSaleEstimateDto {} diff --git a/packages/server-nest/src/modules/SaleEstimates/types/SaleEstimates.types.ts b/packages/server-nest/src/modules/SaleEstimates/types/SaleEstimates.types.ts index 5fa9690db..a32182f38 100644 --- a/packages/server-nest/src/modules/SaleEstimates/types/SaleEstimates.types.ts +++ b/packages/server-nest/src/modules/SaleEstimates/types/SaleEstimates.types.ts @@ -7,6 +7,7 @@ import { AttachmentLinkDTO } from '@/modules/Attachments/Attachments.types'; import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types'; import { CommonMailOptionsDTO } from '@/modules/MailNotification/MailNotification.types'; import { CommonMailOptions } from '@/modules/MailNotification/MailNotification.types'; +import { EditSaleEstimateDto } from '../dtos/SaleEstimate.dto'; export const SendSaleEstimateMailQueue = 'SendSaleEstimateMailProcessor'; export const SendSaleEstimateMailJob = 'SendSaleEstimateMailProcess'; @@ -34,7 +35,6 @@ export interface ISalesEstimatesFilter extends IDynamicListFilter { } export interface ISaleEstimateCreatedPayload { - // tenantId: number; saleEstimate: SaleEstimate; saleEstimateId: number; saleEstimateDTO: ISaleEstimateDTO; @@ -43,12 +43,10 @@ export interface ISaleEstimateCreatedPayload { export interface ISaleEstimateCreatingPayload { estimateDTO: ISaleEstimateDTO; - tenantId: number; trx: Knex.Transaction; } export interface ISaleEstimateEditedPayload { - // tenantId: number; estimateId: number; saleEstimate: SaleEstimate; oldSaleEstimate: SaleEstimate; @@ -57,33 +55,28 @@ export interface ISaleEstimateEditedPayload { } export interface ISaleEstimateEditingPayload { - // tenantId: number; oldSaleEstimate: SaleEstimate; - estimateDTO: ISaleEstimateDTO; + estimateDTO: EditSaleEstimateDto; trx: Knex.Transaction; } export interface ISaleEstimateDeletedPayload { - // tenantId: number; saleEstimateId: number; oldSaleEstimate: SaleEstimate; trx: Knex.Transaction; } export interface ISaleEstimateDeletingPayload { - // tenantId: number; oldSaleEstimate: SaleEstimate; trx: Knex.Transaction; } export interface ISaleEstimateEventDeliveredPayload { - // tenantId: number; saleEstimate: SaleEstimate; trx: Knex.Transaction; } export interface ISaleEstimateEventDeliveringPayload { - // tenantId: number; oldSaleEstimate: SaleEstimate; trx: Knex.Transaction; } @@ -97,13 +90,11 @@ export enum SaleEstimateAction { } export interface ISaleEstimateApprovingEvent { - // tenantId: number; oldSaleEstimate: SaleEstimate; trx: Knex.Transaction; } export interface ISaleEstimateApprovedEvent { - // tenantId: number; oldSaleEstimate: SaleEstimate; saleEstimate: SaleEstimate; trx: Knex.Transaction; diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoice.types.ts b/packages/server-nest/src/modules/SaleInvoices/SaleInvoice.types.ts index ff5c714b6..8f19536be 100644 --- a/packages/server-nest/src/modules/SaleInvoices/SaleInvoice.types.ts +++ b/packages/server-nest/src/modules/SaleInvoices/SaleInvoice.types.ts @@ -8,13 +8,7 @@ import { CommonMailOptionsDTO, } from '../MailNotification/MailNotification.types'; import { TenantJobPayload } from '@/interfaces/Tenant'; -// import SaleInvoice from './models/SaleInvoice'; -// import { SystemUser } from '../System/models/SystemUser'; -// import { ISystemUser, IAccount, ITaxTransaction } from '@/interfaces'; -// import { CommonMailOptions, CommonMailOptionsDTO } from './Mailable'; -// import { IDynamicListFilter } from '@/interfaces/DynamicFilter'; -// import { IItemEntry, IItemEntryDTO } from './ItemEntry'; -// import { AttachmentLinkDTO } from './Attachments'; +import { CreateSaleInvoiceDto, EditSaleInvoiceDto } from './dtos/SaleInvoice.dto'; export interface PaymentIntegrationTransactionLink { id: number; @@ -89,27 +83,27 @@ export type InvoiceNotificationType = 'details' | 'reminder'; export interface ISaleInvoiceCreatedPayload { saleInvoice: SaleInvoice; - saleInvoiceDTO: ISaleInvoiceCreateDTO; + saleInvoiceDTO: CreateSaleInvoiceDto; saleInvoiceId: number; trx: Knex.Transaction; } export interface ISaleInvoiceCreatingPaylaod { tenantId: number; - saleInvoiceDTO: ISaleInvoiceCreateDTO; + saleInvoiceDTO: CreateSaleInvoiceDto; trx: Knex.Transaction; } export interface ISaleInvoiceEditedPayload { saleInvoice: SaleInvoice; oldSaleInvoice: SaleInvoice; - saleInvoiceDTO: ISaleInvoiceEditDTO; + saleInvoiceDTO: EditSaleInvoiceDto; saleInvoiceId: number; trx: Knex.Transaction; } export interface ISaleInvoiceEditingPayload { - saleInvoiceDTO: ISaleInvoiceEditDTO; + saleInvoiceDTO: EditSaleInvoiceDto; oldSaleInvoice: SaleInvoice; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.application.ts b/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.application.ts index f6aa0857f..ba3d172a8 100644 --- a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.application.ts +++ b/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.application.ts @@ -11,8 +11,6 @@ import { GetInvoicePaymentsService } from './queries/GetInvoicePayments.service' import { GetSaleInvoiceState } from './queries/GetSaleInvoiceState.service'; import { GetSaleInvoiceMailState } from './queries/GetSaleInvoiceMailState.service'; import { - ISaleInvoiceCreateDTO, - ISaleInvoiceEditDTO, ISaleInvoiceWriteoffDTO, ISalesInvoicesFilter, SaleInvoiceMailState, @@ -20,6 +18,10 @@ import { } from './SaleInvoice.types'; import { GetSaleInvoicesService } from './queries/GetSaleInvoices'; import { SendSaleInvoiceMail } from './commands/SendSaleInvoiceMail'; +import { + CreateSaleInvoiceDto, + EditSaleInvoiceDto, +} from './dtos/SaleInvoice.dto'; @Injectable() export class SaleInvoiceApplication { @@ -44,7 +46,7 @@ export class SaleInvoiceApplication { * @param {ISaleInvoiceCreateDTO} saleInvoiceDTO * @returns {Promise} */ - public createSaleInvoice(saleInvoiceDTO: ISaleInvoiceCreateDTO) { + public createSaleInvoice(saleInvoiceDTO: CreateSaleInvoiceDto) { return this.createSaleInvoiceService.createSaleInvoice(saleInvoiceDTO); } @@ -55,7 +57,7 @@ export class SaleInvoiceApplication { */ public editSaleInvoice( saleInvoiceId: number, - saleInvoiceDTO: ISaleInvoiceEditDTO, + saleInvoiceDTO: EditSaleInvoiceDto, ) { return this.editSaleInvoiceService.editSaleInvoice( saleInvoiceId, diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts b/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts index 76746811e..fc9452f29 100644 --- a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts +++ b/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts @@ -11,8 +11,6 @@ import { Query, } from '@nestjs/common'; import { - ISaleInvoiceCreateDTO, - ISaleInvoiceEditDTO, ISaleInvoiceWriteoffDTO, ISalesInvoicesFilter, SaleInvoiceMailState, @@ -27,6 +25,10 @@ import { ApiResponse, ApiTags, } from '@nestjs/swagger'; +import { + CreateSaleInvoiceDto, + EditSaleInvoiceDto, +} from './dtos/SaleInvoice.dto'; @Controller('sale-invoices') @ApiTags('sale-invoices') @@ -50,7 +52,7 @@ export class SaleInvoicesController { status: 201, description: 'Sale invoice created successfully', }) - createSaleInvoice(@Body() saleInvoiceDTO: ISaleInvoiceCreateDTO) { + createSaleInvoice(@Body() saleInvoiceDTO: CreateSaleInvoiceDto) { return this.saleInvoiceApplication.createSaleInvoice(saleInvoiceDTO); } @@ -89,7 +91,7 @@ export class SaleInvoicesController { }) editSaleInvoice( @Param('id', ParseIntPipe) id: number, - @Body() saleInvoiceDTO: ISaleInvoiceEditDTO, + @Body() saleInvoiceDTO: EditSaleInvoiceDto, ) { return this.saleInvoiceApplication.editSaleInvoice(id, saleInvoiceDTO); } diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts b/packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts index fee92d1db..5aa4d2aab 100644 --- a/packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts +++ b/packages/server-nest/src/modules/SaleInvoices/commands/CommandSaleInvoiceDTOTransformer.service.ts @@ -4,10 +4,6 @@ import * as R from 'ramda'; import * as moment from 'moment'; import '../../../utils/moment-mysql'; import * as composeAsync from 'async/compose'; -import { - ISaleInvoiceCreateDTO, - ISaleInvoiceEditDTO, -} from '../SaleInvoice.types'; import { Customer } from '@/modules/Customers/models/Customer'; import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform'; import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform'; @@ -21,6 +17,10 @@ import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-ind import { formatDateFields } from '@/utils/format-date-fields'; import { ItemEntriesTaxTransactions } from '@/modules/TaxRates/ItemEntriesTaxTransactions.service'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; +import { + CreateSaleInvoiceDto, + EditSaleInvoiceDto, +} from '../dtos/SaleInvoice.dto'; @Injectable() export class CommandSaleInvoiceDTOTransformer { @@ -54,7 +54,7 @@ export class CommandSaleInvoiceDTOTransformer { */ public async transformDTOToModel( customer: Customer, - saleInvoiceDTO: ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO, + saleInvoiceDTO: CreateSaleInvoiceDto | EditSaleInvoiceDto, oldSaleInvoice?: SaleInvoice, ): Promise { const entriesModels = this.transformDTOEntriesToModels(saleInvoiceDTO); @@ -140,7 +140,7 @@ export class CommandSaleInvoiceDTOTransformer { * @returns {IItemEntry[]} */ private transformDTOEntriesToModels = ( - saleInvoiceDTO: ISaleInvoiceCreateDTO | ISaleInvoiceEditDTO, + saleInvoiceDTO: CreateSaleInvoiceDto | EditSaleInvoiceDto, ): ItemEntry[] => { return saleInvoiceDTO.entries.map((entry) => { return ItemEntry.fromJson({ diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts b/packages/server-nest/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts index ae505183f..175683a56 100644 --- a/packages/server-nest/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts +++ b/packages/server-nest/src/modules/SaleInvoices/commands/CreateSaleInvoice.service.ts @@ -16,6 +16,7 @@ import { SaleEstimate } from '@/modules/SaleEstimates/models/SaleEstimate'; import { Customer } from '@/modules/Customers/models/Customer'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateSaleInvoiceDto } from '../dtos/SaleInvoice.dto'; @Injectable() export class CreateSaleInvoice { @@ -57,8 +58,7 @@ export class CreateSaleInvoice { * @return {Promise} */ public createSaleInvoice = async ( - saleInvoiceDTO: ISaleInvoiceCreateDTO, - // authorizedUser: ITenantUser, + saleInvoiceDTO: CreateSaleInvoiceDto, trx?: Knex.Transaction, ): Promise => { // Validate customer existance. @@ -132,7 +132,7 @@ export class CreateSaleInvoice { */ private transformCreateDTOToModel = async ( customer: Customer, - saleInvoiceDTO: ISaleInvoiceCreateDTO, + saleInvoiceDTO: CreateSaleInvoiceDto, ) => { return this.transformerDTO.transformDTOToModel(customer, saleInvoiceDTO); }; diff --git a/packages/server-nest/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts b/packages/server-nest/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts index 82269cfe8..2d7b0629c 100644 --- a/packages/server-nest/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts +++ b/packages/server-nest/src/modules/SaleInvoices/commands/EditSaleInvoice.service.ts @@ -14,6 +14,7 @@ import { events } from '@/common/events/events'; import { SaleInvoice } from '../models/SaleInvoice'; import { Customer } from '@/modules/Customers/models/Customer'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditSaleInvoiceDto } from '../dtos/SaleInvoice.dto'; @Injectable() export class EditSaleInvoice { @@ -49,7 +50,7 @@ export class EditSaleInvoice { */ public async editSaleInvoice( saleInvoiceId: number, - saleInvoiceDTO: ISaleInvoiceEditDTO, + saleInvoiceDTO: EditSaleInvoiceDto, ): Promise { // Retrieve the sale invoice or throw not found service error. const oldSaleInvoice = await this.saleInvoiceModel() @@ -139,15 +140,13 @@ export class EditSaleInvoice { */ private tranformEditDTOToModel = async ( customer: Customer, - saleInvoiceDTO: ISaleInvoiceEditDTO, + saleInvoiceDTO: EditSaleInvoiceDto, oldSaleInvoice: SaleInvoice, - // authorizedUser: ITenantUser, ) => { return this.transformerDTO.transformDTOToModel( customer, saleInvoiceDTO, oldSaleInvoice, - // authorizedUser, ); }; } diff --git a/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts b/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts new file mode 100644 index 000000000..2713d4b21 --- /dev/null +++ b/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts @@ -0,0 +1,121 @@ +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsDate, + IsEnum, + IsInt, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, + Min, + MinLength, + ValidateNested, +} from 'class-validator'; + +enum DiscountType { + Percentage = 'percentage', + Amount = 'amount', +} + +class PaymentMethodDto { + @IsInt() + paymentIntegrationId: number; + + @IsBoolean() + enable: boolean; +} + +class CommandSaleInvoiceDto { + @IsInt() + @IsNotEmpty() + customerId: number; + + @IsDate() + @Type(() => Date) + @IsNotEmpty() + invoiceDate: Date; + + @IsDate() + @Type(() => Date) + @IsNotEmpty() + dueDate: Date; + + @IsOptional() + @IsString() + invoiceNo?: string; + + @IsOptional() + @IsString() + referenceNo?: string; + + @IsOptional() + @IsBoolean() + delivered: boolean = false; + + @IsOptional() + @IsString() + invoiceMessage?: string; + + @IsOptional() + @IsString() + termsConditions?: string; + + @IsOptional() + @IsNumber() + @Min(0) + exchangeRate?: number; + + @IsOptional() + @IsInt() + warehouseId?: number; + + @IsOptional() + @IsInt() + branchId?: number; + + @IsOptional() + @IsInt() + projectId?: number; + + @IsOptional() + @IsBoolean() + isInclusiveTax?: boolean; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => ItemEntryDto) + @MinLength(1) + entries: ItemEntryDto[]; + + @IsOptional() + @IsInt() + pdfTemplateId?: number; + + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => PaymentMethodDto) + paymentMethods?: PaymentMethodDto[]; + + @IsOptional() + @IsNumber() + discount?: number; + + @IsOptional() + @IsEnum(DiscountType) + discountType?: DiscountType; + + @IsOptional() + @IsNumber() + adjustment?: number; + + @IsOptional() + @IsInt() + fromEstimateId?: number; +} + +export class CreateSaleInvoiceDto extends CommandSaleInvoiceDto {} +export class EditSaleInvoiceDto extends CommandSaleInvoiceDto {} diff --git a/packages/server-nest/src/modules/SaleReceipts/SaleReceiptApplication.service.ts b/packages/server-nest/src/modules/SaleReceipts/SaleReceiptApplication.service.ts index 100df8b62..56d198a6e 100644 --- a/packages/server-nest/src/modules/SaleReceipts/SaleReceiptApplication.service.ts +++ b/packages/server-nest/src/modules/SaleReceipts/SaleReceiptApplication.service.ts @@ -4,12 +4,10 @@ import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service'; import { GetSaleReceiptState } from './queries/GetSaleReceiptState.service'; import { SaleReceiptsPdfService } from './queries/SaleReceiptsPdf.service'; import { CloseSaleReceipt } from './commands/CloseSaleReceipt.service'; -// import { GetSaleReceipts } from './queries/GetSaleReceipts'; import { DeleteSaleReceipt } from './commands/DeleteSaleReceipt.service'; import { GetSaleReceipt } from './queries/GetSaleReceipt.service'; import { EditSaleReceipt } from './commands/EditSaleReceipt.service'; import { - ISaleReceiptDTO, ISaleReceiptState, ISalesReceiptsFilter, SaleReceiptMailOpts, @@ -19,6 +17,7 @@ import { GetSaleReceiptsService } from './queries/GetSaleReceipts.service'; import { SaleReceipt } from './models/SaleReceipt'; import { IFilterMeta, IPaginationMeta } from '@/interfaces/Model'; import { SaleReceiptMailNotification } from './commands/SaleReceiptMailNotification'; +import { CreateSaleReceiptDto, EditSaleReceiptDto } from './dtos/SaleReceipt.dto'; @Injectable() export class SaleReceiptApplication { @@ -40,7 +39,7 @@ export class SaleReceiptApplication { * @returns {Promise} */ public async createSaleReceipt( - saleReceiptDTO: ISaleReceiptDTO, + saleReceiptDTO: CreateSaleReceiptDto, trx?: Knex.Transaction, ) { return this.createSaleReceiptService.createSaleReceipt(saleReceiptDTO, trx); @@ -55,7 +54,7 @@ export class SaleReceiptApplication { */ public async editSaleReceipt( saleReceiptId: number, - saleReceiptDTO: ISaleReceiptDTO, + saleReceiptDTO: EditSaleReceiptDto, ) { return this.editSaleReceiptService.editSaleReceipt( saleReceiptId, diff --git a/packages/server-nest/src/modules/SaleReceipts/SaleReceipts.controller.ts b/packages/server-nest/src/modules/SaleReceipts/SaleReceipts.controller.ts index fc6622886..07601171a 100644 --- a/packages/server-nest/src/modules/SaleReceipts/SaleReceipts.controller.ts +++ b/packages/server-nest/src/modules/SaleReceipts/SaleReceipts.controller.ts @@ -9,10 +9,13 @@ import { Post, Put, } from '@nestjs/common'; -import { ISaleReceiptDTO } from './types/SaleReceipts.types'; import { SaleReceiptApplication } from './SaleReceiptApplication.service'; import { PublicRoute } from '../Auth/Jwt.guard'; import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'; +import { + CreateSaleReceiptDto, + EditSaleReceiptDto, +} from './dtos/SaleReceipt.dto'; @Controller('sale-receipts') @ApiTags('sale-receipts') @@ -22,7 +25,7 @@ export class SaleReceiptsController { @Post() @ApiOperation({ summary: 'Create a new sale receipt.' }) - createSaleReceipt(@Body() saleReceiptDTO: ISaleReceiptDTO) { + createSaleReceipt(@Body() saleReceiptDTO: CreateSaleReceiptDto) { return this.saleReceiptApplication.createSaleReceipt(saleReceiptDTO); } @@ -62,7 +65,7 @@ export class SaleReceiptsController { }) editSaleReceipt( @Param('id', ParseIntPipe) id: number, - @Body() saleReceiptDTO: ISaleReceiptDTO, + @Body() saleReceiptDTO: EditSaleReceiptDto, ) { return this.saleReceiptApplication.editSaleReceipt(id, saleReceiptDTO); } diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts b/packages/server-nest/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts index 155939c49..b607fb9dd 100644 --- a/packages/server-nest/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts +++ b/packages/server-nest/src/modules/SaleReceipts/commands/CreateSaleReceipt.service.ts @@ -14,6 +14,7 @@ import { SaleReceipt } from '../models/SaleReceipt'; import { Customer } from '@/modules/Customers/models/Customer'; import { events } from '@/common/events/events'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateSaleReceiptDto } from '../dtos/SaleReceipt.dto'; @Injectable() export class CreateSaleReceipt { @@ -47,7 +48,7 @@ export class CreateSaleReceipt { * @return {Promise} */ public async createSaleReceipt( - saleReceiptDTO: ISaleReceiptDTO, + saleReceiptDTO: CreateSaleReceiptDto, trx?: Knex.Transaction, ): Promise { // Retrieves the payment customer model. diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts b/packages/server-nest/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts index 4c52f4900..87eaf19b7 100644 --- a/packages/server-nest/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts +++ b/packages/server-nest/src/modules/SaleReceipts/commands/EditSaleReceipt.service.ts @@ -14,6 +14,7 @@ import { Contact } from '@/modules/Contacts/models/Contact'; import { events } from '@/common/events/events'; import { Customer } from '@/modules/Customers/models/Customer'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditSaleReceiptDto } from '../dtos/SaleReceipt.dto'; @Injectable() export class EditSaleReceipt { @@ -37,7 +38,10 @@ export class EditSaleReceipt { * @param {ISaleReceipt} saleReceipt * @return {void} */ - public async editSaleReceipt(saleReceiptId: number, saleReceiptDTO: any) { + public async editSaleReceipt( + saleReceiptId: number, + saleReceiptDTO: EditSaleReceiptDto, + ) { // Retrieve sale receipt or throw not found service error. const oldSaleReceipt = await this.saleReceiptModel() .query() diff --git a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts b/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts index 96c52e685..820f44764 100644 --- a/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts +++ b/packages/server-nest/src/modules/SaleReceipts/commands/SaleReceiptDTOTransformer.service.ts @@ -13,9 +13,9 @@ import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry'; import { formatDateFields } from '@/utils/format-date-fields'; import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-index'; import { SaleReceipt } from '../models/SaleReceipt'; -import { ISaleReceiptDTO } from '../types/SaleReceipts.types'; import { Customer } from '@/modules/Customers/models/Customer'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateSaleReceiptDto, EditSaleReceiptDto } from '../dtos/SaleReceipt.dto'; @Injectable() export class SaleReceiptDTOTransformer { @@ -47,7 +47,7 @@ export class SaleReceiptDTOTransformer { * @returns {ISaleReceipt} */ async transformDTOToModel( - saleReceiptDTO: ISaleReceiptDTO, + saleReceiptDTO: CreateSaleReceiptDto | EditSaleReceiptDto, paymentCustomer: Customer, oldSaleReceipt?: SaleReceipt, ): Promise { diff --git a/packages/server-nest/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts b/packages/server-nest/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts new file mode 100644 index 000000000..daddee030 --- /dev/null +++ b/packages/server-nest/src/modules/SaleReceipts/dtos/SaleReceipt.dto.ts @@ -0,0 +1,100 @@ +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsDate, + IsEnum, + IsNumber, + IsOptional, + IsPositive, + IsString, + Min, + ValidateNested, +} from 'class-validator'; + +enum DiscountType { + Percentage = 'percentage', + Amount = 'amount', +} + +class SaleReceiptEntryDto extends ItemEntryDto {} + +class AttachmentDto { + @IsString() + key: string; +} + +export class CommandSaleReceiptDto { + @IsNumber() + customerId: number; + + @IsOptional() + @IsNumber() + @IsPositive() + exchangeRate?: number; + + @IsNumber() + depositAccountId: number; + + @IsDate() + receiptDate: Date; + + @IsOptional() + @IsString() + receiptNumber?: string; + + @IsOptional() + @IsString() + referenceNo?: string; + + @IsBoolean() + closed: boolean = false; + + @IsOptional() + @IsNumber() + warehouseId?: number; + + @IsOptional() + @IsNumber() + branchId?: number; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => SaleReceiptEntryDto) + @Min(1) + entries: SaleReceiptEntryDto[]; + + @IsOptional() + @IsString() + receiptMessage?: string; + + @IsOptional() + @IsString() + statement?: string; + + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @Type(() => AttachmentDto) + attachments?: AttachmentDto[]; + + @IsOptional() + @IsNumber() + pdfTemplateId?: number; + + @IsOptional() + @IsNumber() + discount?: number; + + @IsOptional() + @IsEnum(DiscountType) + discountType?: DiscountType; + + @IsOptional() + @IsNumber() + adjustment?: number; +} + +export class CreateSaleReceiptDto extends CommandSaleReceiptDto {} +export class EditSaleReceiptDto extends CommandSaleReceiptDto {} diff --git a/packages/server-nest/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts b/packages/server-nest/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts index 19c6473f3..a1dbc272f 100644 --- a/packages/server-nest/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts +++ b/packages/server-nest/src/modules/TaxRates/commands/CommandTaxRatesValidator.service.ts @@ -8,6 +8,7 @@ import { Injectable } from '@nestjs/common'; import { ServiceError } from '@/modules/Items/ServiceError'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types'; +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; @Injectable() export class CommandTaxRatesValidators { @@ -67,11 +68,10 @@ export class CommandTaxRatesValidators { /** * Validates the tax codes of the given item entries DTO. - * @param {number} tenantId * @param {IItemEntryDTO[]} itemEntriesDTO * @throws {ServiceError} */ - public async validateItemEntriesTaxCode(itemEntriesDTO: IItemEntryDTO[]) { + public async validateItemEntriesTaxCode(itemEntriesDTO: ItemEntryDto[]) { const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxCode); const taxCodes = filteredTaxEntries.map((e) => e.taxCode); @@ -92,10 +92,10 @@ export class CommandTaxRatesValidators { /** * Validates the tax rate id of the given item entries DTO. - * @param {IItemEntryDTO[]} itemEntriesDTO + * @param {ItemEntryDto[]} itemEntriesDTO * @throws {ServiceError} */ - public async validateItemEntriesTaxCodeId(itemEntriesDTO: IItemEntryDTO[]) { + public async validateItemEntriesTaxCodeId(itemEntriesDTO: ItemEntryDto[]) { const filteredTaxEntries = itemEntriesDTO.filter((e) => e.taxRateId); const taxRatesIds = filteredTaxEntries.map((e) => e.taxRateId); diff --git a/packages/server-nest/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts b/packages/server-nest/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts new file mode 100644 index 000000000..3b22aa955 --- /dev/null +++ b/packages/server-nest/src/modules/TransactionItemEntry/dto/ItemEntry.dto.ts @@ -0,0 +1,76 @@ +import { DiscountType } from '@/common/types/Discount'; +import { + IsEnum, + IsIn, + IsInt, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, +} from 'class-validator'; + +export class ItemEntryDto { + @IsInt() + index: number; + + @IsInt() + @IsNotEmpty() + itemId: number; + + @IsNumber() + @IsNotEmpty() + rate: number; + + @IsNumber() + @IsNotEmpty() + quantity: number; + + @IsOptional() + @IsNumber() + discount?: number; + + @IsOptional() + @IsEnum(DiscountType) + discountType?: DiscountType = DiscountType.Percentage; + + @IsOptional() + @IsString() + description?: string; + + @IsOptional() + @IsString() + taxCode?: string; + + @IsOptional() + @IsInt() + taxRateId?: number; + + @IsOptional() + @IsInt() + warehouseId?: number; + + @IsOptional() + @IsInt() + projectId?: number; + + @IsOptional() + @IsInt() + projectRefId?: number; + + @IsOptional() + @IsString() + @IsIn(['TASK', 'BILL', 'EXPENSE']) + projectRefType?: string; + + @IsOptional() + @IsNumber() + projectRefInvoicedAmount?: number; + + @IsOptional() + @IsInt() + sellAccountId?: number; + + @IsOptional() + @IsInt() + costAccountId?: number; +} diff --git a/packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.controller.ts b/packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.controller.ts index 40a55cdda..1390378c7 100644 --- a/packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.controller.ts +++ b/packages/server-nest/src/modules/TransactionsLocking/TransactionsLocking.controller.ts @@ -8,6 +8,7 @@ import { QueryTransactionsLocking } from './queries/QueryTransactionsLocking'; import { PublicRoute } from '../Auth/Jwt.guard'; import { ApiOperation } from '@nestjs/swagger'; import { ApiTags } from '@nestjs/swagger'; +import { CancelTransactionsLockingDto, TransactionsLockingDto, UnlockTransactionsLockingDto } from './dtos/TransactionsLocking.dto'; @Controller('transactions-locking') @ApiTags('Transactions Locking') @@ -22,7 +23,7 @@ export class TransactionsLockingController { @ApiOperation({ summary: 'Lock all transactions for a module or all modules' }) async commandTransactionsLocking( @Body('module') module: TransactionsLockingGroup, - @Body() transactionLockingDTO: ITransactionsLockingAllDTO, + @Body() transactionLockingDTO: TransactionsLockingDto, ) { const transactionMeta = await this.transactionsLockingService.commandTransactionsLocking( @@ -39,7 +40,7 @@ export class TransactionsLockingController { @ApiOperation({ summary: 'Cancel all transactions locking for a module or all modules' }) async cancelTransactionLocking( @Body('module') module: TransactionsLockingGroup, - @Body() cancelLockingDTO: ICancelTransactionsLockingDTO, + @Body() cancelLockingDTO: CancelTransactionsLockingDto, ) { const data = await this.transactionsLockingService.cancelTransactionLocking( module, @@ -55,7 +56,7 @@ export class TransactionsLockingController { @ApiOperation({ summary: 'Partial unlock all transactions locking for a module or all modules' }) async unlockTransactionsLockingBetweenPeriod( @Body('module') module: TransactionsLockingGroup, - @Body() unlockDTO: ITransactionLockingPartiallyDTO, + @Body() unlockDTO: UnlockTransactionsLockingDto, ) { const transactionMeta = await this.transactionsLockingService.unlockTransactionsLockingPartially( diff --git a/packages/server-nest/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts b/packages/server-nest/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts index 94e1e90fb..9321089a7 100644 --- a/packages/server-nest/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts +++ b/packages/server-nest/src/modules/TransactionsLocking/commands/CommandTransactionsLockingService.ts @@ -15,6 +15,7 @@ import { Injectable } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { events } from '@/common/events/events'; import { ServiceError } from '@/modules/Items/ServiceError'; +import { CancelTransactionsLockingDto, TransactionsLockingDto } from '../dtos/TransactionsLocking.dto'; const Modules = ['all', 'sales', 'purchases', 'financial']; @@ -33,7 +34,7 @@ export class TransactionsLockingService { */ public commandTransactionsLocking = async ( module: TransactionsLockingGroup = TransactionsLockingGroup.All, - transactionLockingDTO: Partial, + transactionLockingDTO: TransactionsLockingDto, ): Promise => { // Validate the transaction locking module. this.validateTransactionsLockingModule(module); @@ -70,7 +71,7 @@ export class TransactionsLockingService { */ public cancelTransactionLocking = async ( module: TransactionsLockingGroup = TransactionsLockingGroup.All, - cancelLockingDTO: ICancelTransactionsLockingDTO, + cancelLockingDTO: CancelTransactionsLockingDto, ): Promise => { // Validate the transaction locking module. this.validateTransactionsLockingModule(module); @@ -137,10 +138,11 @@ export class TransactionsLockingService { this.validateTransactionsLockingModule(module); // Saves transactions locking settings. - await this.transactionsLockingRepo.saveTransactionsLocking( - module, - { unlockFromDate: '', unlockToDate: '', partialUnlockReason: '' }, - ); + await this.transactionsLockingRepo.saveTransactionsLocking(module, { + unlockFromDate: '', + unlockToDate: '', + partialUnlockReason: '', + }); }; /** diff --git a/packages/server-nest/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts b/packages/server-nest/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts new file mode 100644 index 000000000..c42ef1515 --- /dev/null +++ b/packages/server-nest/src/modules/TransactionsLocking/dtos/TransactionsLocking.dto.ts @@ -0,0 +1,25 @@ +import { IsString } from 'class-validator'; +import { IsNotEmpty } from 'class-validator'; +import { IsDate } from 'class-validator'; + +export class TransactionsLockingDto { + @IsDate() + @IsNotEmpty() + lockToDate: Date; + + @IsString() + @IsNotEmpty() + reason: string; +} + +export class CancelTransactionsLockingDto { + @IsString() + @IsNotEmpty() + reason: string; +} + +export class UnlockTransactionsLockingDto { + @IsDate() + @IsNotEmpty() + unlockFromDate: Date; +} diff --git a/packages/server-nest/src/modules/VendorCredit/VendorCredits.controller.ts b/packages/server-nest/src/modules/VendorCredit/VendorCredits.controller.ts index d91db3410..df216971f 100644 --- a/packages/server-nest/src/modules/VendorCredit/VendorCredits.controller.ts +++ b/packages/server-nest/src/modules/VendorCredit/VendorCredits.controller.ts @@ -9,13 +9,13 @@ import { Query, } from '@nestjs/common'; import { VendorCreditsApplicationService } from './VendorCreditsApplication.service'; -import { - IVendorCreditCreateDTO, - IVendorCreditEditDTO, - IVendorCreditsQueryDTO, -} from './types/VendorCredit.types'; +import { IVendorCreditsQueryDTO } from './types/VendorCredit.types'; import { PublicRoute } from '../Auth/Jwt.guard'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; +import { + CreateVendorCreditDto, + EditVendorCreditDto, +} from './dtos/VendorCredit.dto'; @Controller('vendor-credits') @ApiTags('vendor-credits') @@ -27,7 +27,7 @@ export class VendorCreditsController { @Post() @ApiOperation({ summary: 'Create a new vendor credit.' }) - async createVendorCredit(@Body() dto: IVendorCreditCreateDTO) { + async createVendorCredit(@Body() dto: CreateVendorCreditDto) { return this.vendorCreditsApplication.createVendorCredit(dto); } @@ -47,7 +47,7 @@ export class VendorCreditsController { @ApiOperation({ summary: 'Edit the given vendor credit.' }) async editVendorCredit( @Param('id') vendorCreditId: number, - @Body() dto: IVendorCreditEditDTO, + @Body() dto: EditVendorCreditDto, ) { return this.vendorCreditsApplication.editVendorCredit(vendorCreditId, dto); } diff --git a/packages/server-nest/src/modules/VendorCredit/VendorCreditsApplication.service.ts b/packages/server-nest/src/modules/VendorCredit/VendorCreditsApplication.service.ts index f1c63bacb..47b709f2e 100644 --- a/packages/server-nest/src/modules/VendorCredit/VendorCreditsApplication.service.ts +++ b/packages/server-nest/src/modules/VendorCredit/VendorCreditsApplication.service.ts @@ -8,6 +8,7 @@ import { IVendorCreditCreateDTO } from './types/VendorCredit.types'; import { Injectable } from '@nestjs/common'; import { OpenVendorCreditService } from './commands/OpenVendorCredit.service'; import { GetVendorCreditsService } from './queries/GetVendorCredits.service'; +import { CreateVendorCreditDto, EditVendorCreditDto } from './dtos/VendorCredit.dto'; @Injectable() export class VendorCreditsApplicationService { @@ -28,11 +29,11 @@ export class VendorCreditsApplicationService { /** * Creates a new vendor credit. - * @param {IVendorCreditCreateDTO} dto - The vendor credit create DTO. + * @param {CreateVendorCreditDto} dto - The vendor credit create DTO. * @param {Knex.Transaction} trx - The transaction. * @returns {Promise} The created vendor credit. */ - createVendorCredit(dto: IVendorCreditCreateDTO, trx?: Knex.Transaction) { + createVendorCredit(dto: CreateVendorCreditDto, trx?: Knex.Transaction) { return this.createVendorCreditService.newVendorCredit(dto, trx); } @@ -48,13 +49,13 @@ export class VendorCreditsApplicationService { /** * Edits the given vendor credit. * @param {number} vendorCreditId - The vendor credit id. - * @param {IVendorCreditEditDTO} dto - The vendor credit edit DTO. + * @param {EditVendorCreditDto} dto - The vendor credit edit DTO. * @param {Knex.Transaction} trx - The transaction. * @returns {Promise} The edited vendor credit. */ editVendorCredit( vendorCreditId: number, - dto: IVendorCreditEditDTO, + dto: EditVendorCreditDto, trx?: Knex.Transaction, ) { return this.editVendorCreditService.editVendorCredit( diff --git a/packages/server-nest/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts b/packages/server-nest/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts index 9206008e3..e10ebd13f 100644 --- a/packages/server-nest/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts +++ b/packages/server-nest/src/modules/VendorCredit/commands/CreateVendorCredit.service.ts @@ -2,7 +2,6 @@ import { Inject, Injectable } from '@nestjs/common'; import { Knex } from 'knex'; import { IVendorCreditCreatedPayload, - IVendorCreditCreateDTO, IVendorCreditCreatingPayload, } from '@/modules/VendorCredit/types/VendorCredit.types'; import { VendorCredit } from '../models/VendorCredit'; @@ -13,6 +12,7 @@ import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service'; import { VendorCreditDTOTransformService } from './VendorCreditDTOTransform.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { CreateVendorCreditDto } from '../dtos/VendorCredit.dto'; @Injectable() export class CreateVendorCreditService { @@ -42,7 +42,7 @@ export class CreateVendorCreditService { * @param {Knex.Transaction} trx - */ public newVendorCredit = async ( - vendorCreditCreateDTO: IVendorCreditCreateDTO, + vendorCreditCreateDTO: CreateVendorCreditDto, trx?: Knex.Transaction, ) => { // Triggers `onVendorCreditCreate` event. diff --git a/packages/server-nest/src/modules/VendorCredit/commands/EditVendorCredit.service.ts b/packages/server-nest/src/modules/VendorCredit/commands/EditVendorCredit.service.ts index 9d9c38234..3aab9502c 100644 --- a/packages/server-nest/src/modules/VendorCredit/commands/EditVendorCredit.service.ts +++ b/packages/server-nest/src/modules/VendorCredit/commands/EditVendorCredit.service.ts @@ -13,6 +13,7 @@ import { events } from '@/common/events/events'; import { Knex } from 'knex'; import { VendorCreditDTOTransformService } from './VendorCreditDTOTransform.service'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { EditVendorCreditDto } from '../dtos/VendorCredit.dto'; @Injectable() export class EditVendorCreditService { @@ -39,10 +40,11 @@ export class EditVendorCreditService { /** * Deletes the given vendor credit. * @param {number} vendorCreditId - Vendor credit id. + * @param {EditVendorCreditDto} vendorCreditDto - */ public editVendorCredit = async ( vendorCreditId: number, - vendorCreditDTO: IVendorCreditEditDTO, + vendorCreditDTO: EditVendorCreditDto, trx?: Knex.Transaction, ) => { // Retrieve the vendor credit or throw not found service error. diff --git a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts b/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts index 584cf1adb..104b232ae 100644 --- a/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts +++ b/packages/server-nest/src/modules/VendorCredit/commands/VendorCreditDTOTransform.service.ts @@ -2,11 +2,7 @@ import * as moment from 'moment'; import { omit } from 'lodash'; import * as R from 'ramda'; import { ERRORS } from '../constants'; -import { - IVendorCreditCreateDTO, - IVendorCreditEditDTO, - IVendorCreditEntryDTO, -} from '../types/VendorCredit.types'; +import { IVendorCreditEntryDTO } from '../types/VendorCredit.types'; import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; import { BranchTransactionDTOTransformer } from '@/modules/Branches/integrations/BranchTransactionDTOTransform'; import { WarehouseTransactionDTOTransform } from '@/modules/Warehouses/Integrations/WarehouseTransactionDTOTransform'; @@ -15,6 +11,10 @@ import { assocItemEntriesDefaultIndex } from '@/utils/associate-item-entries-ind import { VendorCreditAutoIncrementService } from './VendorCreditAutoIncrement.service'; import { ServiceError } from '@/modules/Items/ServiceError'; import { Injectable } from '@nestjs/common'; +import { + CreateVendorCreditDto, + EditVendorCreditDto, +} from '../dtos/VendorCredit.dto'; @Injectable() export class VendorCreditDTOTransformService { @@ -39,7 +39,7 @@ export class VendorCreditDTOTransformService { * @returns {VendorCredit} */ public transformCreateEditDTOToModel = async ( - vendorCreditDTO: IVendorCreditCreateDTO | IVendorCreditEditDTO, + vendorCreditDTO: CreateVendorCreditDto | EditVendorCreditDto, vendorCurrencyCode: string, oldVendorCredit?: VendorCredit, ): Promise => { diff --git a/packages/server-nest/src/modules/VendorCredit/dtos/VendorCredit.dto.ts b/packages/server-nest/src/modules/VendorCredit/dtos/VendorCredit.dto.ts new file mode 100644 index 000000000..f9965c8d4 --- /dev/null +++ b/packages/server-nest/src/modules/VendorCredit/dtos/VendorCredit.dto.ts @@ -0,0 +1,83 @@ +import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsEnum, + IsNumber, + IsOptional, + IsString, + ValidateNested, +} from 'class-validator'; + +enum DiscountType { + Percentage = 'percentage', + Amount = 'amount', +} + +class VendorCreditEntryDto extends ItemEntryDto {} + +class AttachmentDto { + @IsString() + key: string; +} + +export class CommandVendorCreditDto { + @IsNumber() + vendorId: number; + + @IsNumber() + @IsOptional() + exchangeRate?: number; + + @IsString() + @IsOptional() + vendorCreditNumber?: string; + + @IsString() + @IsOptional() + referenceNo?: string; + + @IsString() // ISO8601 date string + vendorCreditDate: string; + + @IsString() + @IsOptional() + note?: string; + + @IsOptional() + open: boolean = false; + + @IsNumber() + @IsOptional() + warehouseId?: number; + + @IsNumber() + @IsOptional() + branchId?: number; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => VendorCreditEntryDto) + entries: VendorCreditEntryDto[]; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => AttachmentDto) + @IsOptional() + attachments?: AttachmentDto[]; + + @IsNumber() + @IsOptional() + discount?: number; + + @IsEnum(DiscountType) + @IsOptional() + discountType?: DiscountType; + + @IsNumber() + @IsOptional() + adjustment?: number; +} + +export class CreateVendorCreditDto extends CommandVendorCreditDto {} +export class EditVendorCreditDto extends CommandVendorCreditDto {} diff --git a/packages/server-nest/src/modules/VendorCredit/types/VendorCredit.types.ts b/packages/server-nest/src/modules/VendorCredit/types/VendorCredit.types.ts index 95b6bc3a0..ebabe1fcd 100644 --- a/packages/server-nest/src/modules/VendorCredit/types/VendorCredit.types.ts +++ b/packages/server-nest/src/modules/VendorCredit/types/VendorCredit.types.ts @@ -5,6 +5,10 @@ import { IRefundVendorCreditDTO } from '@/modules/VendorCreditsRefund/types/Vend import { IItemEntryDTO } from '@/modules/TransactionItemEntry/ItemEntry.types'; import { DiscountType } from '@/common/types/Discount'; import { IDynamicListFilter } from '@/modules/DynamicListing/DynamicFilter/DynamicFilter.types'; +import { + CreateVendorCreditDto, + EditVendorCreditDto, +} from '../dtos/VendorCredit.dto'; export enum VendorCreditAction { Create = 'Create', @@ -39,7 +43,7 @@ export interface IVendorCreditDTO { discount?: number; discountType?: DiscountType; - + adjustment?: number; } @@ -54,14 +58,13 @@ export interface IVendorCreditCreatePayload { export interface IVendorCreditCreatingPayload { vendorCredit: VendorCredit; vendorCreditId: number; - vendorCreditCreateDTO: IVendorCreditCreateDTO; + vendorCreditCreateDTO: CreateVendorCreditDto; trx: Knex.Transaction; } export interface IVendorCreditCreatedPayload { - // tenantId: number; vendorCredit: VendorCredit; - vendorCreditCreateDTO: IVendorCreditCreateDTO; + vendorCreditCreateDTO: CreateVendorCreditDto; trx: Knex.Transaction; } @@ -83,18 +86,15 @@ export interface IVendorCreditDeletingPayload { // Edit Vendor Credit Events // ------------------------ export interface IVendorCreditEditingPayload { - // tenantId: number; oldVendorCredit: VendorCredit; - vendorCreditDTO: IVendorCreditEditDTO; + vendorCreditDTO: EditVendorCreditDto; trx: Knex.Transaction; } export interface IVendorCreditEditedPayload { - // tenantId: number; oldVendorCredit: VendorCredit; vendorCredit: VendorCredit; - // vendorCreditId: number; - vendorCreditDTO: IVendorCreditEditDTO; + vendorCreditDTO: EditVendorCreditDto; trx: Knex.Transaction; } diff --git a/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts b/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts index 0b929f0a8..5d65ebb0a 100644 --- a/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts +++ b/packages/server-nest/src/modules/Warehouses/Integrations/WarehousesDTOValidators.ts @@ -41,8 +41,7 @@ export class WarehousesDTOValidators { /** * Validate the warehouse existance of - * @param {number} tenantId - * @param {IWarehouseTransactionDTO} saleInvoiceDTO + * @param {IWarehouseTransactionDTO} saleInvoiceDTO * @returns */ public validateDTOWarehouseWhenActive = async ( diff --git a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts b/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts index 3094c50fc..3b47668a4 100644 --- a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts +++ b/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransferApplication.ts @@ -1,8 +1,6 @@ -import { - ICreateWarehouseTransferDTO, - IEditWarehouseTransferDTO, - IGetWarehousesTransfersFilterDTO, -} from '@/modules/Warehouses/Warehouse.types'; +import { Injectable } from '@nestjs/common'; +import { ModelObject } from 'objection'; +import { IGetWarehousesTransfersFilterDTO } from '@/modules/Warehouses/Warehouse.types'; import { CreateWarehouseTransfer } from './commands/CreateWarehouseTransfer'; import { DeleteWarehouseTransfer } from './commands/DeleteWarehouseTransfer'; import { EditWarehouseTransfer } from './commands/EditWarehouseTransfer'; @@ -10,9 +8,11 @@ import { GetWarehouseTransfer } from './queries/GetWarehouseTransfer'; import { GetWarehouseTransfers } from './queries/GetWarehouseTransfers'; import { InitiateWarehouseTransfer } from './commands/InitiateWarehouseTransfer'; import { TransferredWarehouseTransfer } from './commands/TransferredWarehouseTransfer'; -import { Injectable } from '@nestjs/common'; import { WarehouseTransfer } from './models/WarehouseTransfer'; -import { ModelObject } from 'objection'; +import { + CreateWarehouseTransferDto, + EditWarehouseTransferDto, +} from './dtos/WarehouseTransfer.dto'; @Injectable() export class WarehouseTransferApplication { @@ -32,7 +32,7 @@ export class WarehouseTransferApplication { * @returns {Promise>} */ public createWarehouseTransfer = ( - createWarehouseTransferDTO: ICreateWarehouseTransferDTO, + createWarehouseTransferDTO: CreateWarehouseTransferDto, ): Promise> => { return this.createWarehouseTransferService.createWarehouseTransfer( createWarehouseTransferDTO, @@ -46,7 +46,7 @@ export class WarehouseTransferApplication { */ public editWarehouseTransfer = ( warehouseTransferId: number, - editWarehouseTransferDTO: IEditWarehouseTransferDTO, + editWarehouseTransferDTO: EditWarehouseTransferDto, ): Promise> => { return this.editWarehouseTransferService.editWarehouseTransfer( warehouseTransferId, @@ -69,8 +69,8 @@ export class WarehouseTransferApplication { /** * Retrieves warehouse transfer transaction. - * @param {number} warehouseTransferId - * @returns {Promise} + * @param {number} warehouseTransferId - Warehouse transfer id. + * @returns {Promise>} */ public getWarehouseTransfer = ( warehouseTransferId: number, diff --git a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts b/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts index 10089d29f..28f0d4822 100644 --- a/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts +++ b/packages/server-nest/src/modules/WarehousesTransfers/WarehouseTransfers.controller.ts @@ -9,13 +9,13 @@ import { Query, Inject, } from '@nestjs/common'; -import { WarehouseTransferApplication } from './WarehouseTransferApplication'; -import { - ICreateWarehouseTransferDTO, - IEditWarehouseTransferDTO, -} from '@/modules/Warehouses/Warehouse.types'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { WarehouseTransferApplication } from './WarehouseTransferApplication'; import { PublicRoute } from '../Auth/Jwt.guard'; +import { + CreateWarehouseTransferDto, + EditWarehouseTransferDto, +} from './dtos/WarehouseTransfer.dto'; @Controller('warehouse-transfers') @ApiTags('warehouse-transfers') @@ -40,7 +40,7 @@ export class WarehouseTransfersController { 'The warehouse transfer transaction has been created successfully.', }) async createWarehouseTransfer( - @Body() createWarehouseTransferDTO: ICreateWarehouseTransferDTO, + @Body() createWarehouseTransferDTO: CreateWarehouseTransferDto, ) { const warehouse = await this.warehouseTransferApplication.createWarehouseTransfer( @@ -66,14 +66,13 @@ export class WarehouseTransfersController { }) async editWarehouseTransfer( @Param('id') id: number, - @Body() editWarehouseTransferDTO: IEditWarehouseTransferDTO, + @Body() editWarehouseTransferDTO: EditWarehouseTransferDto, ) { const warehouseTransfer = await this.warehouseTransferApplication.editWarehouseTransfer( id, editWarehouseTransferDTO, ); - return { id: warehouseTransfer.id, message: diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts b/packages/server-nest/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts index 4b25bf557..8b1acb9ea 100644 --- a/packages/server-nest/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts +++ b/packages/server-nest/src/modules/WarehousesTransfers/commands/CommandWarehouseTransfer.ts @@ -1,16 +1,15 @@ +import { ModelObject } from 'objection'; +import { Inject, Injectable } from '@nestjs/common'; import { ERRORS } from '../constants'; import { WarehouseTransfer } from '../models/WarehouseTransfer'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; -import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; -import { Inject, Injectable } from '@nestjs/common'; import { ServiceError } from '@/modules/Items/ServiceError'; -import { ModelObject } from 'objection'; import { Item } from '@/modules/Items/models/Item'; -import { - ICreateWarehouseTransferDTO, - IEditWarehouseTransferDTO, -} from '@/modules/Warehouses/Warehouse.types'; import { Warehouse } from '@/modules/Warehouses/models/Warehouse.model'; +import { + CreateWarehouseTransferDto, + EditWarehouseTransferDto, +} from '../dtos/WarehouseTransfer.dto'; @Injectable() export class CommandWarehouseTransfer { @@ -25,7 +24,7 @@ export class CommandWarehouseTransfer { ) {} /** - * + * Throws error if warehouse transfer not found. * @param {WarehouseTransfer} warehouseTransfer */ throwIfTransferNotFound = (warehouseTransfer: WarehouseTransfer) => { @@ -35,9 +34,9 @@ export class CommandWarehouseTransfer { }; /** - * + * Retrieves the warehouse transfer or throw not found service error. * @param {number} branchId - * @returns + * @returns {Promise} */ async getWarehouseTransferOrThrowNotFound(branchId: number) { const foundTransfer = await this.warehouseTransferModel() @@ -55,9 +54,7 @@ export class CommandWarehouseTransfer { * @param {ICreateWarehouseTransferDTO|IEditWarehouseTransferDTO} warehouseTransferDTO */ validateWarehouseFromToNotSame( - warehouseTransferDTO: - | ICreateWarehouseTransferDTO - | IEditWarehouseTransferDTO, + warehouseTransferDTO: CreateWarehouseTransferDto | EditWarehouseTransferDto, ) { if ( warehouseTransferDTO.fromWarehouseId === @@ -69,12 +66,10 @@ export class CommandWarehouseTransfer { /** * Validates entries items should be inventory. - * @param {IItem[]} items + * @param {ModelObject[]} items - Items. * @returns {void} */ - validateItemsShouldBeInventory = ( - items: ModelObject[], - ): void => { + validateItemsShouldBeInventory = (items: ModelObject[]): void => { const nonInventoryItems = items.filter((item) => item.type !== 'inventory'); if (nonInventoryItems.length > 0) { @@ -85,9 +80,9 @@ export class CommandWarehouseTransfer { }; /** - * - * @param {number} fromWarehouseId - * @returns + * Retrieves the to warehouse or throw not found service error. + * @param {number} fromWarehouseId - From warehouse id. + * @returns {Promise} */ getToWarehouseOrThrow = async (fromWarehouseId: number) => { const warehouse = await this.warehouseModel() diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts b/packages/server-nest/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts index 52c77bd0f..8d32f4ab4 100644 --- a/packages/server-nest/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts +++ b/packages/server-nest/src/modules/WarehousesTransfers/commands/CreateWarehouseTransfer.ts @@ -20,6 +20,10 @@ import { events } from '@/common/events/events'; import { IInventoryItemCostMeta } from '@/modules/InventoryCost/types/InventoryCost.types'; import { ModelObject } from 'objection'; import { WarehouseTransferEntry } from '../models/WarehouseTransferEntry'; +import { + CreateWarehouseTransferDto, + WarehouseTransferEntryDto, +} from '../dtos/WarehouseTransfer.dto'; @Injectable() export class CreateWarehouseTransfer { @@ -48,11 +52,11 @@ export class CreateWarehouseTransfer { /** * Transformes the givne new warehouse transfer DTO to model. - * @param {ICreateWarehouseTransferDTO} warehouseTransferDTO + * @param {ICreateWarehouseTransferDTO} warehouseTransferDTO * @returns {IWarehouseTransfer} */ private transformDTOToModel = async ( - warehouseTransferDTO: ICreateWarehouseTransferDTO, + warehouseTransferDTO: CreateWarehouseTransferDto, ): Promise> => { const entries = await this.transformEntries( warehouseTransferDTO, @@ -91,8 +95,8 @@ export class CreateWarehouseTransfer { private transformEntryAssocAverageCost = R.curry( ( inventoryItemsCostMap: Map, - entry: IWarehouseTransferEntryDTO, - ): IWarehouseTransferEntryDTO => { + entry: WarehouseTransferEntryDto, + ): WarehouseTransferEntryDto => { const itemValuation = inventoryItemsCostMap.get(entry.itemId); const itemCost = get(itemValuation, 'average', 0); @@ -107,8 +111,8 @@ export class CreateWarehouseTransfer { * @returns {Promise} */ public transformEntries = async ( - warehouseTransferDTO: ICreateWarehouseTransferDTO, - entries: IWarehouseTransferEntryDTO[], + warehouseTransferDTO: CreateWarehouseTransferDto, + entries: WarehouseTransferEntryDto[], ): Promise[]> => { const inventoryItemsIds = warehouseTransferDTO.entries.map((e) => e.itemId); @@ -127,17 +131,15 @@ export class CreateWarehouseTransfer { /** * Authorize warehouse transfer before creating. - * @param {number} tenantId - * @param {ICreateWarehouseTransferDTO} warehouseTransferDTO + * @param {CreateWarehouseTransferDto} warehouseTransferDTO - Warehouse transfer DTO. */ public authorize = async ( - warehouseTransferDTO: ICreateWarehouseTransferDTO, + warehouseTransferDTO: CreateWarehouseTransferDto, ) => { // Validate warehouse from and to should not be the same. this.commandWarehouseTransfer.validateWarehouseFromToNotSame( warehouseTransferDTO, ); - // Retrieves the from warehouse or throw not found service error. const fromWarehouse = await this.commandWarehouseTransfer.getFromWarehouseOrThrow( @@ -162,7 +164,7 @@ export class CreateWarehouseTransfer { * @returns {Promise>} */ public createWarehouseTransfer = async ( - warehouseTransferDTO: ICreateWarehouseTransferDTO, + warehouseTransferDTO: CreateWarehouseTransferDto, ): Promise> => { // Authorize warehouse transfer before creating. await this.authorize(warehouseTransferDTO); diff --git a/packages/server-nest/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts b/packages/server-nest/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts index 075460553..9d98da189 100644 --- a/packages/server-nest/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts +++ b/packages/server-nest/src/modules/WarehousesTransfers/commands/EditWarehouseTransfer.ts @@ -13,9 +13,17 @@ import { events } from '@/common/events/events'; import { WarehouseTransfer } from '../models/WarehouseTransfer'; import { ItemsEntriesService } from '@/modules/Items/ItemsEntries.service'; import { ModelObject } from 'objection'; +import { EditWarehouseTransferDto } from '../dtos/WarehouseTransfer.dto'; @Injectable() export class EditWarehouseTransfer { + /** + * @param {UnitOfWork} uow - Unit of work service. + * @param {EventEmitter2} eventPublisher - Event emitter service. + * @param {CommandWarehouseTransfer} commandWarehouseTransfer - Command warehouse transfer service. + * @param {ItemsEntriesService} itemsEntries - Items entries service. + * @param {TenantModelProxy} warehouseTransferModel - Warehouse transfer model. + */ constructor( private readonly uow: UnitOfWork, private readonly eventPublisher: EventEmitter2, @@ -36,7 +44,7 @@ export class EditWarehouseTransfer { */ public editWarehouseTransfer = async ( warehouseTransferId: number, - editWarehouseDTO: IEditWarehouseTransferDTO, + editWarehouseDTO: EditWarehouseTransferDto, ): Promise> => { // Retrieves the old warehouse transfer transaction. const oldWarehouseTransfer = await this.warehouseTransferModel() diff --git a/packages/server-nest/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts b/packages/server-nest/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts new file mode 100644 index 000000000..a4f34bcbd --- /dev/null +++ b/packages/server-nest/src/modules/WarehousesTransfers/dtos/WarehouseTransfer.dto.ts @@ -0,0 +1,72 @@ +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsDate, + IsDecimal, + IsInt, + IsNotEmpty, + IsNumber, + IsOptional, + IsPositive, + IsString, + ValidateNested, + ArrayMinSize, +} from 'class-validator'; + +export class WarehouseTransferEntryDto { + @IsNotEmpty() + index: number; + + @IsNotEmpty() + @IsInt() + itemId: number; + + @IsOptional() + @IsString() + description?: string; + + @IsNotEmpty() + @IsInt() + @IsPositive() + quantity: number; + + @IsOptional() + @IsDecimal() + cost?: number; +} + +export class CommandWarehouseTransferDto { + @IsNotEmpty() + @IsInt() + fromWarehouseId: number; + + @IsNotEmpty() + @IsInt() + toWarehouseId: number; + + @IsNotEmpty() + @IsDate() + date: Date; + + @IsOptional() + @IsString() + transactionNumber?: string; + + @IsBoolean() + @IsOptional() + transferInitiated: boolean = false; + + @IsBoolean() + @IsOptional() + transferDelivered: boolean = false; + + @IsArray() + @ArrayMinSize(1) + @ValidateNested({ each: true }) + @Type(() => WarehouseTransferEntryDto) + entries: WarehouseTransferEntryDto[]; +} + +export class CreateWarehouseTransferDto extends CommandWarehouseTransferDto {} +export class EditWarehouseTransferDto extends CommandWarehouseTransferDto {}