Discount priorities
A line can be touched by several discount sources at once: the product's own discount, a multi-code row discount, quantity breaks, a Buy X Get X campaign, customer-specific prices and the customer's general (VIP) discount. They do not add up — the system follows a fixed priority ladder, identical in orders, invoices and the POS. Since the v2 pricing module the default is best-of: sources compete and the bigger discount wins.
The ladder — strongest first
1. Manual line discount — typed by a human; nothing overrides the
percentage, nothing re-prices a typed price
2. Locked row discount — the WINNING multi-code row has Lock discount
checked AND carries a discount:
its % replaces the product's own discount and
quantity tiers are skipped; customer pricing
and VIP still compete (bigger wins)
3. Row flags — Ignore quantity discounts / Ignore BXGX remove
a competitor from the line (they add no value)
4. BXGX free units — when the campaign wins the promotion axis it
stacks its free units on top of the paid line's
resolved percentage
5. Best-of percentage — the biggest single % among: the product's own
(unless a specific row replaced it), the winning
row's, the customer product price, the VIP %,
and the quantity tier (the tier only wins when
strictly bigger than every other candidate)
6. Price axis — independent of all percentages: customer fixed
price > winning row price > product list price
Steps 2 and 3 are blocking rules — they remove competitors rather than adding discount. Everything else competes flat, one winner per line, no compounding.
Rule by rule
1. Manual line discount
A percentage typed directly on the line by a human wins outright and keeps its value through every re-evaluation. A manually typed price is likewise never overwritten.
2. Locked row discount
When the winning multi-code row (see How the price row is chosen) has Lock discount checked and carries a discount:
- the row's discount replaces the product's own discount — even when smaller,
- quantity breaks are skipped for the line,
- customer pricing and the VIP discount are never blocked — the result is the biggest of the locked %, the customer product price and the VIP %.
A locked row with an empty discount does nothing by itself — only its price override applies and the ladder falls through to the normal best-of. To freeze a row's pricing completely, check Lock discount + Ignore quantity discounts + Ignore BXGX and give the row its discount.
3. Row flags (competitor removers)
- Ignore quantity discounts — quantity tiers do not apply on lines priced from the winning row, even tiers that would be bigger.
- Ignore BXGX — the product's Buy-X-Get-X campaign generates no free units on lines priced from the winning row.
4. Buy X Get X and the promotion axis
If the product has both Buy and Get quantities set (e.g. buy 2 get 1), every complete group of buy+get units produces free units as a separate negative line. When a quantity tier is also reached, the two campaigns are compared by their effective percentage at the current quantity:
- the bigger effective discount wins the line (ties go to BXGX),
- when BXGX wins, the quantity tier is removed from the competition and the paid line keeps its best non-tier percentage; the free units stack on top,
- when the tier wins, no free units are generated and the tier competes normally below.
5. Best-of percentage (the default)
When no lock applies, one flat comparison — the bigger discount wins, no stacking, no compounding:
- the product's own discount — excluded when a specific row (one bound to a warehouse and/or its own barcode) supplied the discount: a specific row's discount replaces it even when smaller. A fully-generic row's discount merely competes with it,
- the winning row's discount,
- the customer product price (per customer, per product — price or percentage),
- the customer's VIP percentage,
- the quantity tier — the highest reached tier, and it must be strictly bigger than every other candidate to win.
Quantity tiers are stored per line when it is added, but re-evaluated from the product's current tiers on every re-evaluation.
6. The price axis
Percentages never touch the price axis. The line's unit price resolves independently: customer fixed price (price-type customer pricing) > winning multi-code row price > product list price. This is why a row lock can never block a customer's fixed price.
The flag combinations
Fixed example: a specific winning row with discount 5 %, product discount 10 %, a quantity tier 20 % at qty 10, product Buy 2 Get 1, no customer pricing (when a customer source is present it still competes with — and beats — the 5 %, per rule 2):
| Lock | Ign. qty | Ign. BXGX | Paid-line % | Free units? |
|---|---|---|---|---|
| 5 % row (specific replaces product 10 %; tier 20 % beats BXGX on the promo axis → tier competes → 20 % tier) | no | |||
| ✓ | 20 % tier (BXGX eliminated; nothing else beats it) | no | ||
| ✓ | 5 % row; BXGX runs | yes | ||
| ✓ | ✓ | 5 % row | no | |
| ✓ | 5 % locked (tiers blocked) | yes (lock ≠ Ignore BXGX) | ||
| ✓ | ✓ | 5 % locked | no | |
| ✓ | ✓ | 5 % locked (Ignore qty redundant under lock) | yes | |
| ✓ | ✓ | ✓ | 5 % locked — the full freeze | no |
With a fully-generic winning row instead, the unlocked rows read 10 % product where the table shows 5 % row — a generic discount competes with the product's instead of replacing it. The lock rows come out identical either way.
Worked example
Product price 10.00 € net, product discount 10 %, quantity tiers 5 → 10 %, 10 → 20 %, customer with VIP 15 %:
| Situation | Result |
|---|---|
| Add 3 units | Product 10 % (tiers not reached) |
| Add 7 units, product has no own discount | Candidates VIP 15 % vs tier 10 % → 15 % VIP (tier must strictly exceed to win) |
| Add 10 units, product has no own discount | Tier 20 % strictly exceeds 15 % → 20 % tier |
| A specific winning row supplies 5 % (product still 10 %) | Row replaces the product's → 5 %, tiers still compete |
| That row has Lock checked, customer also has a 12 % product price | max(5 %, 12 %) → 12 % customer — customers are never blocked by a row |
| Product has Buy 2 Get 1, add 5 units (tier 10 % reached) | BXGX effective ≈ 33 % beats the tier → free units, tier removed, paid line keeps its best non-tier % |
Practical checklist
- Want a quantity break to win? Make sure no specific winning row discount and no lock is in the way, the row's Ignore quantity discounts is off, the tier beats BXGX on the promo axis, and the tier is strictly bigger than the product/row/customer percentages present.
- Want a campaign price only at one warehouse? Put it on a multi-code row limited to that warehouse — and remember a shop warehouse only prices on that shop's POS register; in orders and invoices the row needs its location marked Is main warehouse.
- Customer prices and VIP discounts can never be blocked by a row or a lock — plan campaign depth around them.
- Discounts never double-apply: the ladder always picks one winner per line (plus BXGX free units as separate lines).