A pricing matrix is a table of cost bands. Each band says: for a part that costs this much, mark it up by this percentage. Set it once in Settings → Pricing matrices and every part you buy is priced the same way, without anyone doing arithmetic on the counter.
What a pricing matrix is
Each band has a lower bound, an upper bound and a markup percentage. GarageFlow takes the part's cost, finds the band it falls in, and stores the result as the part's sell price:
sell price = cost × (1 + markup ÷ 100)
A part costing 85 in a 50–100 band at 60% sells at 136.00.
Bands are matched lowest bound first, and they are half-open: a band covers values from its minimum up to but not including its maximum. A band left with no upper bound runs to infinity. So 50–100 and 100–250 hand over cleanly at exactly 100 — that part lands in the second band.
Tip
Because the boundary is exclusive on top, write bands that touch (0–50, 50–100, 100–250) rather than the older 0–50 / 50.01–100 style. A part costing exactly 50 matches nothing in the second style.
Pricing matrix vs labor matrix
They are the same idea over two different inputs.
| Pricing matrix | Labor matrix | |
|---|---|---|
| Bands over | part cost | job hours |
| Each band holds | a markup percentage | a rate multiplier |
| Produces | the part's sell price | the effective hourly rate |
| Applies to | parts in inventory | labor lines on an order |
A labor matrix multiplies your posted door rate: a 3–6 hour band at ×1.30 turns a 120 base rate into 156 for that job. Everything below about matching, ordering and fall-through works identically for both.
Fall-through, the one to remember
If no band matches, nothing is applied. A part whose cost falls outside every band sells at cost — no markup, no error, no warning on the estimate. A labor line whose hours fall outside every band bills at the plain base rate.
That is the single biggest footgun in matrices, and it is invisible in the data: the part just quietly has a sell price equal to its cost, which looks like a deliberate zero-margin price rather than a hole in the table.
Warning
Give every matrix an open-ended top band (a minimum with no maximum). Without one, the expensive parts — the ones where margin matters most — are exactly the ones that sell at cost.
Gaps, overlaps and above-range
The matrix editor analyses coverage and flags three things:
Gap
A stretch of values no band covers. Anything landing there falls through unmodified.
Above range
Your highest band has an upper bound, so everything above it falls through. Fix it by clearing that band's maximum.
Overlap
Two bands claim the same values, so the band that wins is not the one you'd read off the table. The API refuses overlapping bands when you save, so an overlap always means older data — edit the bands and it clears.
A worked example
Drag the value and watch which band claims it. Push it past the top band to see fall-through happen.
| 0.00 – 20.00 | +100% |
| 20.00 – 50.00 | +80% |
| 50.00 – 100.00 | +60% |
| 100.00 – 250.00 | +45% |
| 250.00 – 500.00 | +35% |
- Matching band
- +60%
- Sell price
- 136.00
Bands stop at 500.00 — anything above it falls through and is billed unmodified.
What the customer sees
The customer never sees the matrix. On estimates, repair orders, invoices and the
customer portal, a labor line shows the effective rate — the matrix-adjusted
one — so that hours × rate equals the line total. Showing the base door rate
instead would print 1.00 h × 120 next to a total of 156.00, which reads as a
maths error.
Your base rate and the multipliers behind it stay shop-internal. Parts show their sell price; the cost and the markup that produced it are never printed.
Troubleshooting
"A part sold at cost." Its cost fell outside every band. Check for a gap around that cost, or a missing open-ended top band.
"The rate on the estimate isn't my posted rate." That is the labor matrix doing its job — the line shows the effective rate for those hours. Check the matching hour band.
"I changed the matrix and old orders didn't change." Saving a matrix recalculates the sell price of the parts attached to it, but a part that was already added to an order keeps the price it was added at. Re-add the line, or edit its price, to pick up the new one.
"Some parts didn't recalculate." A part uses its own assigned matrix if it has one, and the shop default otherwise. A part pinned to a different matrix is untouched when you edit this one.