From e229c11b7017f0c8892db68a51da171108772407 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 8 Jun 2026 12:01:23 +0700 Subject: [PATCH] refactor: improve loyalty card membership validation and manual program exclusion logic --- static/src/app/models/pos_order.js | 37 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/static/src/app/models/pos_order.js b/static/src/app/models/pos_order.js index e8750fb..a9ae400 100644 --- a/static/src/app/models/pos_order.js +++ b/static/src/app/models/pos_order.js @@ -49,24 +49,45 @@ patch(PosOrder.prototype, { // an add-on subscription (e.g. Makan Pagi Gratis). if (program.manual_membership) { if (!partner) return false; - const allCards = this.models['loyalty.card']?.getAll() || []; - return allCards.some((card) => { - const cardPartnerId = resolveManyToOneId(card.partner_id); - const cardProgramId = resolveManyToOneId(card.program_id); - return cardPartnerId === partner.id && cardProgramId === program.id && card.id > 0; - }); + const card = this.models["loyalty.card"].find( + (c) => (c.partner_id?.id === partner.id || resolveManyToOneId(c.partner_id) === partner.id) && + (c.program_id?.id === program.id || resolveManyToOneId(c.program_id) === program.id) + ); + + // If the card is not in the cache yet, return true to trigger fetching from the server + if (!card) { + return true; + } + + // Once in cache, it must be a real card (positive ID) and active + return card.id > 0 && card.active; } // ── Case 2: Auto-tier program (Silver / Gold / Platinum) ── // If the partner holds a manual membership level (e.g. Direksi), // block all auto-tier rewards — they use their own program's rewards. + let hasManualMembership = false; if (membershipId) { const allPrograms = this.models['loyalty.program'].getAll(); const memberProgram = allPrograms.find((p) => p.id === membershipId); - if (memberProgram && memberProgram.manual_membership) { - return false; + if (memberProgram && memberProgram.manual_membership && memberProgram.program_type === 'loyalty') { + hasManualMembership = true; } } + if (!hasManualMembership && partner) { + hasManualMembership = this.models['loyalty.card'].some((card) => { + const cardPartnerId = card.partner_id?.id || resolveManyToOneId(card.partner_id); + if (cardPartnerId !== partner.id || card.id < 0 || !card.active) { + return false; + } + const cardProgramId = card.program_id?.id || resolveManyToOneId(card.program_id); + const prog = this.models['loyalty.program'].get(cardProgramId); + return prog && prog.manual_membership && prog.program_type === 'loyalty'; + }); + } + if (hasManualMembership) { + return false; + } // Retrieve all loyalty programs const allPrograms = this.models['loyalty.program'].getAll();