diff --git a/models/baseModels/AppliedCouponCodes/AppliedCouponCodes.ts b/models/baseModels/AppliedCouponCodes/AppliedCouponCodes.ts index 318ec9f4..9a4b7490 100644 --- a/models/baseModels/AppliedCouponCodes/AppliedCouponCodes.ts +++ b/models/baseModels/AppliedCouponCodes/AppliedCouponCodes.ts @@ -23,10 +23,18 @@ export class AppliedCouponCodes extends InvoiceItem { 'pricingRule', 'validFrom', 'validTo', + 'maximumUse', + 'used', ], filters: { name: value as string }, }); + if ((coupon[0]?.maximumUse as number) <= (coupon[0]?.used as number)) { + throw new ValidationError( + 'Coupon code has been used maximum number of times' + ); + } + const applicableCouponCodesNames = await getApplicableCouponCodesName( value as string, this.parentdoc as SalesInvoice diff --git a/models/baseModels/Invoice/Invoice.ts b/models/baseModels/Invoice/Invoice.ts index c1862544..7452696e 100644 --- a/models/baseModels/Invoice/Invoice.ts +++ b/models/baseModels/Invoice/Invoice.ts @@ -236,6 +236,10 @@ export abstract class Invoice extends Transactional { await this._updateIsItemsReturned(); await this._createLoyaltyPointEntry(); + + if (this.schemaName === ModelNameEnum.SalesInvoice) { + this.updateUsedCountOfCoupons(); + } } async afterCancel() { @@ -553,6 +557,17 @@ export abstract class Invoice extends Transactional { return newReturnDoc; } + updateUsedCountOfCoupons() { + this.coupons?.map(async (coupon) => { + const couponDoc = await this.fyo.doc.getDoc( + ModelNameEnum.CouponCode, + coupon.coupons + ); + + await couponDoc.setAndSync({ used: (couponDoc.used as number) + 1 }); + }); + } + async _updateIsItemsReturned() { if (!this.isReturn || !this.returnAgainst || this.isQuote) { return;