Flow
How a stuck row gets its answer
Only rows stuck at zero ever take this path.
1Stuck at zero
Zero on the shelf, zero sold, zero ordered. Hand-picked groups and set starting amounts are skipped.
2Look at one earlier window
Same length, right before the current one, capped. Used only for a sales rate.
3It sold back then
Order from that rate, sized against today's empty shelf. The row says its rate was borrowed.
4It sat and did not sell
Keep the zero. Nobody bought it, so nothing gets ordered.
5It was never there
Hand off to the normal rules for new products.
Inside the ordering system was a loop that could keep a shelf empty for good. Every number it showed was correct, so nothing looked wrong. A product that sold fine and then ran out would just get a zero, every time.
The planner looks at each product group in each store. It checks how much sold lately, divides by the days the product was on the shelf, and orders enough to last a while. Counting only in-stock days is right. A product can't sell when it isn't there.
But if the product was gone the whole time, there are no in-stock days. No stock means no sales. No sales means the rate is zero, so the order is zero. Zero ordered means the shelf stays empty, so the following run repeats the identical calculation. The loop can't break itself.
It also mislabeled things. Some groups need a person to approve a first order, and that check fired on any group with no stock and no sales. So an old product that ran out would look like a new one.
Looking back only for rows stuck at zero
I didn't want to change rows that were fine. So the planner still does its normal math first. Then it picks out only the rows stuck at zero stock, zero sales, and zero ordered. Groups picked by hand, or with a starting amount someone set, are skipped. If my new code is wrong, it can only hurt rows that were already broken.
For those stuck rows, it looks at one earlier window of the same length, right before the current one. There's a cap on how long that window can be. It reads all the stuck groups at once, from data it already has. It uses that window only for a sales rate, never for stock.
What the earlier window can say about an empty shelf
The earlier window can say three things. If the product sold back then, the planner orders based on that rate. If it sat on the shelf and didn't sell, the zero stays. If it was never there at all, the normal rules for new products take over.
The approval check got fixed too, so an old product that just didn't sell isn't called new.
Every row now says where its number came from, and look-back rows show what the earlier window found. A buyer can see why an empty product got a big order.
Promotions and pulled products
A promotion in the earlier window gets copied forward. A product pulled on purpose might still get ordered. One that's been gone for two windows looks new. Those are the rows I'd check first.