diff --git a/static/src/app/models/pos_order.js b/static/src/app/models/pos_order.js index defc633..0e0442e 100644 --- a/static/src/app/models/pos_order.js +++ b/static/src/app/models/pos_order.js @@ -31,31 +31,47 @@ patch(PosOrder.prototype, { return false; } - const allCards = this.models['loyalty.card']?.getAll() || []; - const card = allCards.find((c) => { - const cardPartnerId = resolveManyToOneId(c.partner_id); - const cardProgramId = resolveManyToOneId(c.program_id); - return cardPartnerId === partner.id && cardProgramId === program.id; - }); + 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 so that updatePrograms + // will trigger fetching the card from the server via couponForProgram. if (!card) { return true; } + // Once the card is in cache, if it is a mock card (negative ID) or inactive, + // the partner is not a valid member of this subscription program. if (card.id < 0 || !card.active) { return false; } + const parseDate = (d) => { + if (!d) return null; + if (d.isLuxonDateTime) { + return d.startOf('day'); + } + if (typeof d === 'string') { + return DateTime.fromISO(d).startOf('day'); + } + if (d instanceof Date) { + return DateTime.fromJSDate(d).startOf('day'); + } + return null; + }; + const today = DateTime.now().startOf('day'); if (card.subscription_start_date) { - const startDate = DateTime.fromISO(card.subscription_start_date).startOf('day'); - if (today < startDate) { + const startDate = parseDate(card.subscription_start_date); + if (startDate && startDate.isValid && today < startDate) { return false; } } if (card.subscription_end_date) { - const endDate = DateTime.fromISO(card.subscription_end_date).startOf('day'); - if (today > endDate) { + const endDate = parseDate(card.subscription_end_date); + if (endDate && endDate.isValid && today > endDate) { return false; } } @@ -66,10 +82,22 @@ patch(PosOrder.prototype, { _getRealCouponPoints(coupon_id) { const dbCoupon = this.models['loyalty.card'].get(coupon_id); - const programId = dbCoupon ? resolveManyToOneId(dbCoupon.program_id) : null; + let programId = dbCoupon ? resolveManyToOneId(dbCoupon.program_id) : null; + if (!programId) { + const pe = this.uiState.couponPointChanges[coupon_id]; + if (pe) { + programId = pe.program_id; + } + } const program = programId ? this.models['loyalty.program'].get(programId) : null; if (program && program.program_type === 'subscription') { + if (!dbCoupon || dbCoupon.id < 0 || !dbCoupon.active) { + return 0; + } + if (!this._canGenerateRewards(program, this.priceIncl, this.priceExcl)) { + return 0; + } // Subscription program rewards cost points, but they are free for the customer. // We return enough points to cover the reward cost, limited by 1 claim per day. const rewardPoints = (program.reward_ids || []).reduce((max, r) => Math.max(max, r.required_points || 0), 1); @@ -89,7 +117,7 @@ patch(PosOrder.prototype, { if (order === this) { continue; } - if (!order.is_paid && order.state !== 'paid' && order.state !== 'done' && order.state !== 'invoiced' && !order.finalized) { + if (!order.isPaid() && order.state !== 'paid' && order.state !== 'done' && order.state !== 'invoiced' && !order.finalized) { continue; } for (const line of order._get_reward_lines() || []) {