Flow
Which rule sets the claim
1Promo with cost and rate
Cost x units x rate.
2Return with cost
Cost x units.
3Anything else
The register amount, marked as a fallback.
4Every row
Keeps the register amount, the rule label, and the rate next to the claim.
Wrong money sat in the main column of the discount report. It was the dollars the register took off the shelf price, sitting where you'd look for what a supplier owes the stores. The totals and the exports used it too.
The way I read a supplier-funded promo, the vendor pays a share of what they charged me, not a share of what I charged the customer. Say a jar sells for ten dollars and costs me four. A twenty percent promo takes two dollars off at the register. The vendor's share is eighty cents. The report said two dollars.
The old test even checked that quantity didn't change the total. I assume that's right for register dollars, since as I read it the register amount already covers every unit. It was just the wrong total.
Every row now works out its own claim
Each row now gets its own claim.
A promo row is cost times units times the rate, a return row is cost times units, and anything else keeps the register amount, marked as a fallback.
A return is priced at what I paid, cost times units. If the cost is missing, the row falls back. If the quantity is missing or bad, it counts as one unit, which can make a claim too small.
Where the rate comes from
The rate comes from text, not a number field. The code looks through the promo name and a few other text spots for something like "20%" or "20 percent", and takes the first one it finds. A name with two rates in it would give the first one, and I don't know how often that happens.
The register number stays, with a label on the guess
Each row keeps the old register amount next to the claim, plus a label for which rule made the claim and the rate it used. The grid shows both numbers side by side. The exports read the same data, so they match the grid.
The fallback is still the old number
When there's no cost or no rate, the claim is the register amount again, with the label on it. Rows waiting for review always end up there. The new test covers the promo math. I didn't see it touch a return, a fallback row, or a real promo name from the stores in this change.