From 75b98c39d82033b91ef04f5621e61075761087b5 Mon Sep 17 00:00:00 2001 From: Yong ke Weng Date: Sat, 21 Feb 2026 09:50:39 -0500 Subject: [PATCH] fix: validate credit note per-entry amount against each invoice due amount The `validateInvoicesRemainingAmount` method was incorrectly comparing the total credit amount (sum of all entries) against each individual invoice's due amount. This caused valid credit note applications to be rejected when applying to multiple invoices where the total exceeded any single invoice's due amount. Changed the validation to compare each invoice's due amount against only the specific entry amount being applied to that invoice. Co-Authored-By: Claude Opus 4.6 --- .../CreditNoteApplyToInvoices.service.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts index c58254bc7..eb4162d86 100644 --- a/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts +++ b/packages/server/src/modules/CreditNotesApplyInvoice/commands/CreditNoteApplyToInvoices.service.ts @@ -2,6 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { Knex } from 'knex'; import { sumBy } from 'lodash'; import { + ICreditNoteAppliedToInvoice, ICreditNoteAppliedToInvoiceModel, IApplyCreditToInvoicesDTO, IApplyCreditToInvoicesCreatedPayload, @@ -71,7 +72,7 @@ export class CreditNoteApplyToInvoices { // Validate invoices has remaining amount to apply. this.validateInvoicesRemainingAmount( appliedInvoicesEntries, - creditNoteAppliedModel.amount, + creditNoteAppliedModel.entries, ); // Validate the credit note remaining amount. this.creditNoteDTOTransform.validateCreditRemainingAmount( @@ -122,17 +123,18 @@ export class CreditNoteApplyToInvoices { }; /** - * Validate the invoice remaining amount. + * Validate each invoice has sufficient remaining amount for the applied credit. * @param {ISaleInvoice[]} invoices - * @param {number} amount + * @param {ICreditNoteAppliedToInvoice[]} entries */ private validateInvoicesRemainingAmount = ( invoices: SaleInvoice[], - amount: number, + entries: ICreditNoteAppliedToInvoice[], ) => { - const invalidInvoices = invoices.filter( - (invoice) => invoice.dueAmount < amount, - ); + const invalidInvoices = invoices.filter((invoice) => { + const entry = entries.find((e) => e.invoiceId === invoice.id); + return entry && invoice.dueAmount < entry.amount; + }); if (invalidInvoices.length > 0) { throw new ServiceError(ERRORS.INVOICES_HAS_NO_REMAINING_AMOUNT); }