From 792cb4be74848f55c73cc5fba5093097be070705 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Tue, 16 Jun 2026 15:09:09 +0700 Subject: [PATCH] fix: recalculate order price totals to prevent stale value usage during synchronous reward line replacement --- static/src/overrides/models/loyalty.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/static/src/overrides/models/loyalty.js b/static/src/overrides/models/loyalty.js index 436a2bc..714c9cb 100755 --- a/static/src/overrides/models/loyalty.js +++ b/static/src/overrides/models/loyalty.js @@ -175,8 +175,15 @@ patch(PosOrder.prototype, { let { discountable, discountablePerTax } = getDiscountable(reward); - // Use priceExcl instead of priceIncl for maximum limit comparison - discountable = Math.min(this.priceExcl, discountable); + // Compute real order totals to avoid stale values during synchronous reward line replacement. + // When _updateRewardLines deletes the old reward lines, order.triggerRecomputeAllPrices() + // queues a microtask. However, _applyReward runs synchronously right after line.delete(). + // Thus, this.priceExcl and this.priceIncl are stale and include the deleted reward lines. + const realPriceExcl = this.getOrderlines().reduce((sum, line) => sum + line.priceExcl, 0); + const realPriceIncl = this.getOrderlines().reduce((sum, line) => sum + line.priceIncl, 0); + + // Use realPriceExcl instead of priceIncl for maximum limit comparison + discountable = Math.min(realPriceExcl, discountable); if (Math.abs(discountable) < 0.0001) { return []; @@ -244,9 +251,9 @@ patch(PosOrder.prototype, { taxIds = this.pos.taxes.filter((tax) => taxIds.includes(tax.id)); } - var discount_amount = -(Math.min(this.priceIncl, entry[1]) * discountFactor); + var discount_amount = -(Math.min(realPriceIncl, entry[1]) * discountFactor); console.log("DEBUG LOYALTY:", { - discountable, maxDiscount, discountFactor, priceIncl: this.priceIncl, entry_1: entry[1], discount_amount + discountable, maxDiscount, discountFactor, priceIncl: realPriceIncl, entry_1: entry[1], discount_amount }); // OVERRIDE: Inject JSON variables (will be automatically assigned in Odoo 19 extraFields, we must make sure these properties are forwarded) lst.push({