feat: patch PosOrder to exclude temporary loyalty cards from applicability and rewards calculations
This commit is contained in:
parent
ccdc2f95df
commit
c71acbf7cb
@ -23,6 +23,10 @@ This custom Odoo module enhances the POS Loyalty interface and partner creation
|
|||||||
- Solves a core Odoo 19 multi-company operational bug where cashiers in branch companies encounter "Access Errors" when validating orders for customers whose loyalty cards belong to the parent company.
|
- Solves a core Odoo 19 multi-company operational bug where cashiers in branch companies encounter "Access Errors" when validating orders for customers whose loyalty cards belong to the parent company.
|
||||||
- Bypasses company-specific record rules during POS loyalty audit logging using standard and safe `sudo` environment execution.
|
- Bypasses company-specific record rules during POS loyalty audit logging using standard and safe `sudo` environment execution.
|
||||||
|
|
||||||
|
5. **Loyalty Reward and Point Access Control:**
|
||||||
|
- Restricts loyalty program reward eligibility, point balance displays, and program applicability in the POS UI strictly to customers who have a persisted, active card in the database for that specific program.
|
||||||
|
- Prevents unauthorized claim/access to zero-point rewards (e.g., 100% discount rewards in executive/exclusive programs) by non-enrolled members.
|
||||||
|
|
||||||
## Technical Details
|
## Technical Details
|
||||||
- **JS OWL Patching:** Overrides POS frontend partner management safely using clean, standard owl-level class overrides.
|
- **JS OWL Patching:** Overrides POS frontend partner management and order processing (`PosOrder`) safely using clean, standard owl-level class overrides to filter program eligibility, claimable rewards, and loyalty point lists based on card status.
|
||||||
- **Python Inheritance:** Customizes backend models (`res.partner`, `pos.order`) to clean loading domains and securely provision cross-company data.
|
- **Python Inheritance:** Customizes backend models (`res.partner`, `pos.order`) to clean loading domains and securely provision cross-company data.
|
||||||
|
|||||||
@ -24,6 +24,7 @@ Custom POS Loyalty and Membership management features:
|
|||||||
'assets': {
|
'assets': {
|
||||||
'point_of_sale._assets_pos': [
|
'point_of_sale._assets_pos': [
|
||||||
'pos_loyalty_member_custom/static/src/app/screens/partner_list_patch.js',
|
'pos_loyalty_member_custom/static/src/app/screens/partner_list_patch.js',
|
||||||
|
'pos_loyalty_member_custom/static/src/app/models/pos_order_patch.js',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
'installable': True,
|
'installable': True,
|
||||||
|
|||||||
51
static/src/app/models/pos_order_patch.js
Normal file
51
static/src/app/models/pos_order_patch.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/** @odoo-module **/
|
||||||
|
|
||||||
|
import { PosOrder } from "@point_of_sale/app/models/pos_order";
|
||||||
|
import { patch } from "@web/core/utils/patch";
|
||||||
|
|
||||||
|
patch(PosOrder.prototype, {
|
||||||
|
_programIsApplicable(program) {
|
||||||
|
const isApplicable = super._programIsApplicable(...arguments);
|
||||||
|
if (!isApplicable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (program.program_type === 'loyalty') {
|
||||||
|
const partner = this.getPartner();
|
||||||
|
if (partner) {
|
||||||
|
// Check if a card exists in cache for this program and partner
|
||||||
|
const card = this.models['loyalty.card'].find(
|
||||||
|
(c) => c.partner_id?.id === partner.id && c.program_id?.id === program.id
|
||||||
|
);
|
||||||
|
// If a card exists and is temporary (ID < 0), the program is not applicable
|
||||||
|
if (card && card.id < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
getClaimableRewards(coupon_id = false, program_id = false, auto = false) {
|
||||||
|
const claimable = super.getClaimableRewards(...arguments);
|
||||||
|
return claimable.filter((item) => {
|
||||||
|
const card = this.models['loyalty.card'].get(item.coupon_id);
|
||||||
|
if (card && card.program_id?.program_type === 'loyalty' && card.id < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getLoyaltyPoints() {
|
||||||
|
const points = super.getLoyaltyPoints(...arguments);
|
||||||
|
return points.filter((item) => {
|
||||||
|
const couponId = parseInt(item.couponId);
|
||||||
|
if (couponId < 0 && item.program?.program_type === 'loyalty') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user