Go to file
2026-05-28 12:14:32 +07:00
data first commit 2026-05-28 10:07:53 +07:00
models fix: trigger client reload, specify view type, and update account company search criteria 2026-05-28 12:14:32 +07:00
security first commit 2026-05-28 10:07:53 +07:00
views first commit 2026-05-28 10:07:53 +07:00
wizards fix: trigger client reload, specify view type, and update account company search criteria 2026-05-28 12:14:32 +07:00
__init__.py first commit 2026-05-28 10:07:53 +07:00
__manifest__.py first commit 2026-05-28 10:07:53 +07:00
.gitignore first commit 2026-05-28 10:07:53 +07:00
README.md fix: trigger client reload, specify view type, and update account company search criteria 2026-05-28 12:14:32 +07:00

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.program records (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.

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 named Discounts).
    • Assigns both the Income Account and Expense Account to code 412201 for the corresponding active company.

🩹 Recent Fixes & Compatibility Updates

1. Odoo 19 Multi-Company Sharing Schema Compatibility

  • Swapped deprecated company_id filters with the new standard Many2many company_ids domain mapping when querying account.account instances. This prevents ValueError: Invalid field account.account.company_id backend 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

  1. Place the pos_loyalty_marketing_access folder inside your custom addons directory.
  2. Restart the Odoo server.
  3. Update the module list in Odoo developer settings.
  4. Search for POS Loyalty Marketing Access & Approvals and 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

  • Author: Suherdy Yacob
  • Version: 1.0
  • Compatibility: Odoo 19.0 (Community & Enterprise Editions)