# POS Loyalty Tax Mode Custom module for Odoo 19 that adds a **Before Tax / After Tax** option to the loyalty rule's "per money spent" reward point mode. ## Overview By default, Odoo calculates loyalty reward points based on the **total price including tax** when the rule is set to "per money spent". This module introduces a configurable dropdown that lets you choose whether points should be calculated on the price **before tax** or **after tax**. ## Features - Adds a **Tax Option** dropdown field on the `loyalty.rule` model - The dropdown only appears when the reward point mode is set to **"per money spent"** - Two options available: - **Before Tax** — points are calculated based on the subtotal (tax excluded) - **After Tax** — points are calculated based on the total (tax included, default behavior) - Fully integrated with the POS frontend — the setting syncs to the Point of Sale session automatically ## Dependencies | Module | Technical Name | |--------------|----------------| | POS Loyalty | `pos_loyalty` | | Loyalty | `loyalty` | ## Installation 1. Place the `pos_loyalty_tax_mode` folder into your `custom` addons directory 2. Restart the Odoo server 3. Go to **Apps** → Update Apps List 4. Search for **"POS Loyalty Tax Mode"** and click **Install** ## Configuration 1. Navigate to **Point of Sale** → **Configuration** → **Discount & Loyalty** 2. Open or create a loyalty program 3. In the **Rules** section, set the grant mode to **"per [currency] spent"** 4. A new **Tax Option** dropdown will appear — select either **Before Tax** or **After Tax** 5. Save and close/reopen your POS session to apply the changes ## Module Structure ``` pos_loyalty_tax_mode/ ├── __init__.py ├── __manifest__.py ├── readme.md ├── models/ │ ├── __init__.py │ └── loyalty_rule.py # Extends loyalty.rule with money_reward_point_mode field ├── views/ │ └── loyalty_rule_views.xml # Inherits form & kanban views to show the new field └── static/ └── src/ └── app/ └── pos_order_patch.js # Patches POS point calculation logic ``` ## Technical Details ### Backend (`models/loyalty_rule.py`) Adds a `money_reward_point_mode` selection field to `loyalty.rule`: | Value | Label | Description | |--------------|------------|------------------------------------------| | `before_tax` | Before Tax | Points based on price excluding tax | | `after_tax` | After Tax | Points based on price including tax (default) | The field is also registered in `_load_pos_data_fields` so it is available in the POS frontend. ### Frontend (`static/src/app/pos_order_patch.js`) Patches two methods on `PosOrder.prototype`: - **`pointsForPrograms(programs)`** — Modified to use `total_excluded` or `total_included` based on the rule's `money_reward_point_mode` when calculating `orderedProductPaid` and `pointsPerUnit` - **`_getPointsCorrection(program)`** — Modified to use the correct price (before/after tax) when computing point corrections for free-product rewards ## License LGPL-3