The discount system supports item-level and check-level discounts with configurable presets, manual entry, comps (100% discount), role-based access control, and manager override for restricted users.Documentation Index
Fetch the complete documentation index at: https://docs.laportenard.com/llms.txt
Use this file to discover all available pages before exploring further.
Discount types
Presets are configured in the Odoo backend (nu.pos.discount.preset):
| Type | Behavior |
|---|---|
fixed_percent | Fixed percentage (e.g., “10% Off”) — value pre-filled, not editable |
fixed_amount | Fixed dollar amount (e.g., “$5 Off”) — value pre-filled, not editable |
open_percent | Opens percentage entry with the preset as default — user can change |
open_amount | Opens amount entry with the preset as default — user can change |
applies_to field: item, check, or both.
Comp
A comp is a 100% discount applied directly (no modal). Triggered from the “Comp Item” tile in the item detail panel. If the user’smax_discount is below 100, a manager override is required.
Access control
Permission check
User clicks discount/comp. System checks
canPerformAction(role, "discount", permissions).Max discount enforcement
Each user has amax_discount value from their PosUser record:
0= unlimited (no cap)> 0= maximum percentage this user can apply
DiscountModal clamps input to maxDiscount. When a manager approves via override, their own max_discount is used. In the override modal, managers with insufficient max_discount are shown grayed out.
Data flow
Item discount
Check discount
Stacking
Item and check discounts compose multiplicatively: 10% item + 20% check = 28% total, not 30%.Reducer actions
| Action | Payload | Effect |
|---|---|---|
APPLY_ITEM_DISCOUNT | { itemId, discount, discountState } | Sets item.discount (%) and item.discountState |
REMOVE_ITEM_DISCOUNT | { itemId } | Clears discount to 0 |
APPLY_CHECK_DISCOUNT | { checkDiscount, itemDiscounts } | Sets order.checkDiscount and per-item discount % |
REMOVE_CHECK_DISCOUNT | — | Clears all discounts |
Audit trail
BothItemDiscountState and CheckDiscountState store:
appliedByUserId/appliedByName— who applied the discountapprovedByUserId/approvedByName— manager who approved (if override was needed)presetId/presetName— which preset was used (if any)
Hub sync
discountState and checkDiscount flow through the snapshot pipeline:
buildSnapshot()includes them on items and ordersrebuildOrderFromSnapshot()restores them
Backend addon
nu_pos_discounts/ — Odoo 12 addon. Extends _get_bootstrap_extra() to include discount_presets array:
i18n
Translations in thediscounts namespace (src/i18n/locales/{en,es}.json).
| Key | EN | ES |
|---|---|---|
discountItem | Discount Item | Descuento a Ítem |
discountCheck | Discount Check | Descuento a Cuenta |
removeDiscount | Remove Discount | Quitar Descuento |
maxDiscountExceeded | Maximum discount is % | Descuento máximo es % |
Testing
models.test.ts— Parsing, preset filteringservices.test.ts—computeDiscountPct,distributeCheckDiscount,composeDiscountPct