| data | ||
| models | ||
| security | ||
| views | ||
| wizards | ||
| __init__.py | ||
| __manifest__.py | ||
| .gitignore | ||
| README.md | ||
POS Loyalty Marketing Access & Approvals
A custom Odoo 19 module introducing comprehensive security permissions, double-approval validation states, hierarchy-aware routing, and automated accounting mapping for Point of Sale Loyalty, Promotions, and Vouchers.
🌟 Key Features
1. Granular Security Groups
- Marketing / User:
- Full Read / Create / Write access to loyalty programs, discount programs, gift cards, and eWallets.
- Restricted from deleting marketing programs.
- Restricted from generating vouchers (coupons) directly.
- Strict Read-only access to Point of Sale Orders, Order Lines, Payments, POS Reports, Loyalty History, and Loyalty Mail.
- Marketing / Manager:
- Full user capabilities.
- Exclusive access to Generate Vouchers directly via the standard generation wizard.
2. Double-Approval validation Flow
- All newly created
loyalty.programrecords (Loyalty, Discount, Promotion, Promo Code, Gift Card, eWallet) start in a Draft state. - Marketing Users can edit draft programs and click Submit for Approval to put them into the Pending Approval state.
- The designated company-level approver (or any user in the Marketing / Manager group if no specific approver is configured) can click Approve to move the program into the Active state.
- When an active program is modified, its state automatically resets to Draft to ensure all edits are explicitly reviewed and re-approved before they can be used at the POS register.
3. Staged Voucher Generation Queues
- Restricts immediate voucher code generation for non-managers.
- When a user submits a request to generate coupon/voucher codes, the module automatically intercepts it and creates a Voucher Generation Request (
loyalty.voucher.generation.request). - This request stores the desired program, code count, prefix, point values, and expiration dates.
- Managers review the request queues and approve them to execute code generation safely in the background.
4. Hierarchy-Aware Company-Level Approvers
- Designated approvers are configured directly on each Company record via the new Marketing Approvals notebook tab (Settings > Users & Companies > Companies).
- Form fields available:
- Marketing Program Approver
- Voucher Generation Approver
- Upward Tree Walking: When a marketing program set on the parent company OT is verified:
- The module walks upward in the company hierarchy tree (
parent_id) starting from the active/program company. - Branch companies automatically inherit and share parent-level (OT) approvers.
- Local overrides can be set on any child branch company if different personnel are desired.
- Fallback logic authorizes any Marketing / Manager user if no designated approver exists in the tree.
- The module walks upward in the company hierarchy tree (
5. Automated Discount Product Configuration
- When a marketing program is saved, Odoo standard generates an underlying service product used to represent the discount item in sales order lines.
- This module automatically intercepts that product's creation and:
- Assigns it to the product category
OT / Saleable / PoS / Discounts(with fallback to any category namedDiscounts). - Assigns both the Income Account and Expense Account to code
412201for the corresponding active company.
- Assigns it to the product category
🩹 Recent Fixes & Compatibility Updates
1. Odoo 19 Multi-Company Sharing Schema Compatibility
- Swapped deprecated
company_idfilters with the new standard Many2manycompany_idsdomain mapping when queryingaccount.accountinstances. This preventsValueError: Invalid field account.account.company_idbackend crashes when creating loyalty discount products.
2. Client Action Preprocessing Safety
- Added explicit view layout parameters (
'views': [[False, 'form']]) to the wizard action dictionaries. This prevents frontend JS crashes (TypeError: Cannot read properties of undefined (reading 'map')) when Odoo's web client pre-processes nested actions outside standard loaded actions.
3. Real-Time State Synchronization
- Chained a soft-reload client action (
'next': {'type': 'ir.actions.client', 'tag': 'reload'}) directly within the approval notification return payload. This ensures that the voucher request's state immediately updates to Approved in the UI and lists the newly generated voucher cards without requiring a manual page refresh.
📂 Technical Layout & Structure
pos_loyalty_marketing_access/
├── __init__.py
├── __manifest__.py
├── data/
│ └── ir_sequence_data.xml
├── models/
│ ├── __init__.py
│ ├── loyalty_program.py
│ ├── loyalty_reward.py
│ ├── loyalty_voucher_generation_request.py
│ ├── pos_config.py
│ └── sale_order.py
├── security/
│ ├── ir.model.access.csv
│ └── pos_loyalty_marketing_security.xml
├── views/
│ ├── loyalty_program_views.xml
│ ├── loyalty_voucher_generation_request_views.xml
│ ├── menu_views.xml
│ ├── pos_config_views.xml
│ └── res_company_views.xml
├── wizards/
│ ├── __init__.py
│ └── loyalty_generate_wizard.py
└── README.md
🛠️ Installation & Upgrades
- Place the
pos_loyalty_marketing_accessfolder inside your custom addons directory. - Restart the Odoo server.
- Update the module list in Odoo developer settings.
- Search for
POS Loyalty Marketing Access & Approvalsand click Install or Upgrade.
Alternatively, upgrade the database schema directly via the command line:
python3 odoo-bin -c odoo.conf -d mapangroup_o19_7 -u pos_loyalty_marketing_access --stop-after-init
📝 License & Copyright
- Author: Suherdy Yacob
- Version: 1.0
- Compatibility: Odoo 19.0 (Community & Enterprise Editions)