refactor: remove temporary coupon_id patching in favor of filtering orphaned reward lines in _get_reward_lines
This commit is contained in:
parent
4c01b4a5e0
commit
047f8a0987
@ -74,25 +74,6 @@ patch(PosOrder.prototype, {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* getLoyaltyPoints reads coupon_id.id — guard undefined coupon_id.
|
|
||||||
*/
|
|
||||||
getLoyaltyPoints() {
|
|
||||||
const undefinedCouponLines = [];
|
|
||||||
for (const line of this._get_reward_lines()) {
|
|
||||||
if (!line.coupon_id) {
|
|
||||||
line.coupon_id = { id: 0 };
|
|
||||||
undefinedCouponLines.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return super.getLoyaltyPoints(...arguments);
|
|
||||||
} finally {
|
|
||||||
for (const line of undefinedCouponLines) {
|
|
||||||
line.coupon_id = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _updateRewardLines — purge orphans before core re-processes them.
|
* _updateRewardLines — purge orphans before core re-processes them.
|
||||||
@ -104,7 +85,7 @@ patch(PosOrder.prototype, {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* _validForPointsCorrection — core accesses reward.program_id.id without null check.
|
* _validForPointsCorrection — core accesses reward.program_id.id without null check.
|
||||||
* Guard it here.
|
* Guard it here. This also guards the lines accessed in _getPointsCorrection.
|
||||||
*/
|
*/
|
||||||
_validForPointsCorrection(reward, line, rule) {
|
_validForPointsCorrection(reward, line, rule) {
|
||||||
if (!reward || !reward.program_id || !rule.program_id) {
|
if (!reward || !reward.program_id || !rule.program_id) {
|
||||||
@ -113,28 +94,21 @@ patch(PosOrder.prototype, {
|
|||||||
return super._validForPointsCorrection(...arguments);
|
return super._validForPointsCorrection(...arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPointsCorrection(program) {
|
/**
|
||||||
if (!program || !program.rule_ids) {
|
* _get_reward_lines — exclude orphaned reward lines (no valid reward_id.program_id).
|
||||||
return 0;
|
* This also protects _getPointsCorrection which iterates this.lines.filter(is_reward_line).
|
||||||
}
|
* NOTE: Do NOT reassign this.lines — that goes through the ORM setter and permanently
|
||||||
const originalLines = this.lines;
|
* mutates/destroys lines. Instead, filter at the method level.
|
||||||
this.lines = this.lines.filter(
|
*/
|
||||||
(line) => !(line.is_reward_line && (!line.reward_id || !line.reward_id.program_id))
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
return super._getPointsCorrection(...arguments);
|
|
||||||
} finally {
|
|
||||||
this.lines = originalLines;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_get_reward_lines() {
|
_get_reward_lines() {
|
||||||
const rewardLines = super._get_reward_lines(...arguments);
|
const rewardLines = super._get_reward_lines(...arguments);
|
||||||
if (!rewardLines) {
|
if (!rewardLines) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
// Exclude orphaned lines with missing reward_id.program_id OR missing coupon_id.
|
||||||
|
// getLoyaltyPoints accesses line.coupon_id.id which crashes if coupon_id is undefined.
|
||||||
return rewardLines.filter(
|
return rewardLines.filter(
|
||||||
(line) => line.reward_id && line.reward_id.program_id
|
(line) => line.reward_id && line.reward_id.program_id && line.coupon_id
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -169,20 +143,12 @@ patch(PosOrder.prototype, {
|
|||||||
|
|
||||||
patch(OrderPaymentValidation.prototype, {
|
patch(OrderPaymentValidation.prototype, {
|
||||||
async validateOrder(isForceValidate) {
|
async validateOrder(isForceValidate) {
|
||||||
const undefinedCouponLines = [];
|
// Purge any orphaned reward lines before validation to prevent crashes
|
||||||
for (const line of this.order._get_reward_lines()) {
|
// in confirm_coupon_programs when it iterates reward lines.
|
||||||
if (!line.coupon_id) {
|
if (this.order) {
|
||||||
line.coupon_id = { id: 0 };
|
purgeOrphanedRewardLines(this.order);
|
||||||
undefinedCouponLines.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return await super.validateOrder(...arguments);
|
|
||||||
} finally {
|
|
||||||
for (const line of undefinedCouponLines) {
|
|
||||||
line.coupon_id = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return await super.validateOrder(...arguments);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -237,14 +203,6 @@ patch(PosStore.prototype, {
|
|||||||
async postProcessLoyalty(order) {
|
async postProcessLoyalty(order) {
|
||||||
purgeOrphanedRewardLines(order);
|
purgeOrphanedRewardLines(order);
|
||||||
|
|
||||||
const undefinedCouponLines = [];
|
|
||||||
for (const line of order._get_reward_lines()) {
|
|
||||||
if (!line.coupon_id) {
|
|
||||||
line.coupon_id = { id: 0 };
|
|
||||||
undefinedCouponLines.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const originalCall = this.data.call;
|
const originalCall = this.data.call;
|
||||||
this.data.call = function (model, method, args) {
|
this.data.call = function (model, method, args) {
|
||||||
if (model === "pos.order" && method === "confirm_coupon_programs") {
|
if (model === "pos.order" && method === "confirm_coupon_programs") {
|
||||||
@ -260,9 +218,6 @@ patch(PosStore.prototype, {
|
|||||||
return await super.postProcessLoyalty(...arguments);
|
return await super.postProcessLoyalty(...arguments);
|
||||||
} finally {
|
} finally {
|
||||||
this.data.call = originalCall;
|
this.data.call = originalCall;
|
||||||
for (const line of undefinedCouponLines) {
|
|
||||||
line.coupon_id = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user