Flow
What each policy answer does to a cart line
1Product can't be ordered
Skip the line with the product lookup's own reason.
2Policy gives an amount above zero
Write the line at that amount, with the cost based on it.
3Policy gives zero
Skip the line as below the minimum, with the policy's message.
4Policy wants a split
Skip the line as unsupported until the cart can store a split case.
5Someone reads the skips
A person reads the reasons and decides what to do with the demand nobody ordered.
The README for my cart described a rounding rule the code didn't have.
The doc said grouped products rounded by price, with a guard at the end. The code just rounded every share up to a full case, inside the loop that spreads units across products. No price check, no guard.
A group is a shelf slot that any of a few similar products can fill. The planner says how many units the group needs and which products are allowed. The cart deals those units out to the products one share at a time, checks each product can be ordered, and writes lines a buyer reviews.
Where it went wrong
The loop kept a running budget of units left to hand out. It took a share, rounded it up to a case, and then took the rounded amount off the budget. So the last share almost always rounded past what was left, and the group ended up a bit over the plan. The budget could also run out before every product got a turn. The old test even expected a line bigger than the plan.
The bigger problem: ordinary lines in the same cart got their quantities from the shared case policy, the code that knows what each supplier allows. Full cases only, half cases, a minimum order. The group lines ignored all of that. One cart, two rules, and a README describing a third.
Pulling the rounding out of the loop
I didn't write a better helper. I took the rounding out of the cart. The loop now hands out raw units and takes those same units off the budget, so it can't go over the plan. Then, after the product lookup gives the real case size and cost, the request goes through the same case policy ordinary lines use.
The request goes to the supplier's rules with the real case size and cost, and the rules decide what quantity, if any, gets written.
If a product gets several shares, they add up first and get rounded once. The supplier's rules load once per run, and only if there are group lines.
Each result has one clear ending:
- Too small to order: skip the line and say it's below the minimum.
- Needs a split the cart can't store: skip it as unsupported.
- Product can't be ordered: skip it with the lookup's reason.
- Anything else: write the line at the policy's quantity.
Nothing gets written as a fraction. The README now says group lines follow the same policy as the rest, which is true now.
The new test uses a supplier that sells half cases and expects a request between one and two cases to become a case and a half. That's the supplier's rule, not the cart's. Nothing I've found builds a grouped line and an ordinary line from the same facts and checks they match. If you copy this, write that test. I still owe it too.
What a reviewer will see
How many real carts were too big, or how many lines will now get skipped, I haven't checked. A shorter cart may look like a bug to whoever reviews it. If you copy this, watch the skip reasons as closely as the quantities.