Pricing rules and overrides

How Carbon resolves the price on a line, from base price through overrides and rules.

When you add an item to a line or a line, Carbon doesn't just copy the item's list price. It runs a resolution engine: it starts from a base price, applies any customer-specific override, then layers on discount and markup rules, and records the whole computation as a trace on the line. Two mechanisms feed that engine — (per-customer negotiated prices with quantity breaks) and (company-wide discount/markup logic). This page covers both, and exactly what wins when several apply.

Pricing rules

A pricing rule is a company-scoped rule that adjusts a price up or down. Each rule is a Discount or a Markup, expressed as either a Percentage or a Fixed amount, and it only fires when the line matches the rule's conditions.

FieldType
Discount (lowers the price) or Markup (raises it).
Percentage or Fixed. A percentage is stored as a fraction from 0 to 1 (10% is 0.10), so the form caps it at 100%.
The discount/markup value. For a percentage, the fraction of the running price; for fixed, an absolute amount.
Higher priority wins among discounts and orders the markup stack. Defaults to 0.
The line quantity range the rule applies to.
Restrict the rule to specific customers or customer types. Empty means all.
Restrict to specific items or an item posting group. Empty means all.
The date window the rule is active in. Empty bounds are open-ended.
Inactive rules are skipped without being deleted, preserving them for audit.

A rule matches a line only when every set condition holds: the quantity is within min/max, the date is inside the valid window, and the item and customer fall inside the item/customer restrictions (empty restriction means no restriction). Only matching, active rules go into the calculation.

NOTE

Percentages are fractions, not whole numbers

A Percentage amount is a fraction between 0 and 1 (0.10 for 10%). The rule form rejects anything above 1. If you enter 15 expecting 15%, that's a 1500% adjustment.

Price overrides

A price override pins a negotiated price for a specific item, optionally with quantity breaks. Unlike a rule, an override replaces the base price outright rather than adjusting it. Overrides are scoped one of three ways, and a single override targets exactly one scope:

  • Customer — this item, this customer.
  • Customer type — this item, everyone of this customer type.
  • All customers — this item, every customer (both customer and customer type left blank).

An override can't set both a customer and a customer type; the database enforces the exclusive scope. Each override carries a list of quantity breaks — rungs of quantityoverride price. For a given line quantity Carbon picks the highest break whose quantity is at or below the ordered quantity. Order eight when the rungs are 1, 5, and 10, and you get the price on the 5-rung.

FieldType
The item this override prices.
Scope to one customer. Mutually exclusive with customer type.
Scope to a customer type. Mutually exclusive with customer.
One or more quantityoverride price rungs. Duplicate quantities are rejected.
When on (the default), pricing rules still layer onto the override price. When off, the override price is final and rules are skipped.
The date window the override is active in.
Inactive overrides are skipped but retained for history.

You can seed one customer's or type's price list from another with Duplicate price list, choosing a skip or overwrite strategy for items the target already prices.

NOTE

An override is a price list, not a discount

An override sets the starting price directly. Whether rules then adjust it is governed by the override's Apply rules on top flag, per override — not a global setting.

How the engine picks a price

Resolution runs top to bottom. The result, plus every step, is stored on the line as a price trace, and the line records which pricing rule (if any) drove the final number.

Start from the base price. The item's unit sale price, or the cost-rollup price the quote already computed. Trace source: Base.

Apply the best-matching override, if any. Carbon checks the three scopes in strict precedence and commits to the first that yields a break: customer override, then customer-type override, then all-customers override. Once a scope matches, it never falls through to a lower one. If the ordered quantity is below the override's smallest break, that scope doesn't match and Carbon tries the next. The winning override sets the starting price. Trace source: Override, Type Override, or All Override.

Layer on pricing rules, unless the winning override set Apply rules on top to off. All matching active rules apply here, in the order below. Trace source: Rule.

Clamp and record. A negative result is floored at zero, and the final price is written to the line along with the full trace.

So the precedence is: customer override > customer-type override > all-customers override > base price, and then rules run on top of whichever starting price won.

What wins when rules collide

Discounts and markups combine differently, and this is the part that surprises people:

  • Discounts don't stack — the single highest-priority discount wins. When several discount rules match, Carbon ranks them by priority (ties broken by the larger effective amount) and applies only the top one. The rest are discarded. You never get two discounts on the same line.
  • Markups stack and compound. Every matching markup rule applies, in priority order, each computed against the already-adjusted running price. A 10% markup after a 20% markup compounds, it doesn't simply add.

Discounts are applied first, then the markup stack, then the zero floor.

HEADS UP

Two discounts never combine

If a customer qualifies for both a 10% and a 15% discount rule, they get 15% only — never 25%, and never both applied in sequence. Markups are the opposite: all of them apply, compounding.

NOTE

Price resolution is a value, not a lock

Resolution runs when the item or quantity changes on a line and fills in the unit price. It's a starting point you can still edit by hand; the trace records how the suggested number was reached.

Where it applies

The same engine prices both surfaces. On a quote line it runs during cost rollup and re-price. On a sales order line the line form calls the same resolution as you pick an item or change the quantity, filling the unit price and storing the trace. Both line types carry the resolved price and its provenance, so a price traces back to the exact override and rule that produced it.

There's no separate "price list" document in Carbon — the price list is simply the set of overrides scoped to a customer or customer type, and the resolution is computed in the application, not in the database.