Case study 01 · Replenishment & buyer tooling

Twenty buyers, twenty spreadsheets, one buy signal.

The ERP was generating reorder suggestions the buying team had learned to ignore — for good reasons. Fixing that meant rebuilding the logic, then rebuilding the interface, then automating the review nobody had time to do.

Company
PE-owned national distributor
Scope
8 DCs · 67k stocked SKUs
Users
20+ buyers and planners
Built in
Python, SQL, Streamlit, Anthropic API

The buying team was not the problem. Every buyer in that room could tell you, item by item, why the system's suggested quantity was wrong — and every one of them was right. That's the tell. When twenty experienced people all independently override the same system, the system is producing a number that doesn't describe the business.

What was actually broken

The reorder engine forecasted with a three-month rolling average. In a business with a hard seasonal peak, that does two specific and predictable things. Going into the peak it undershoots, because the trailing three months are all pre-season and the average lags the ramp — so the buy is short exactly when being short costs the most. Coming out of the peak it overshoots, because the trailing three months are all peak, and the signal persists for a full quarter after demand has collapsed. You buy too little in April and too much in August, every year, structurally.

Safety stock made it worse. A single hardcoded six-weeks-of-supply rule applied across the entire catalog, which means the item that sells steadily every week and the item that sells four times a year in unpredictable lumps were carrying proportionally identical cover. One of those is massively over-stocked. The other stocks out anyway, and the stockout is invisible in the data — the order that never gets placed doesn't appear anywhere.

So the buyers did the rational thing: each built a personal spreadsheet, pulled their own extract, applied their own judgment, and bought from that. Which produced a second-order problem worse than the first. There were now twenty versions of the buy signal, none reproducible, none auditable, and all of them walking out the door whenever a buyer left.

The failure wasn't that the number was wrong. It was that twenty people were each spending a day a week manufacturing a replacement for it.

What got built

1. Segmentation before logic

Every stocked SKU — roughly 67,000 of them — was classified on two axes: ABC by contribution, XYZ by demand variability. That grid is the input to a dynamic cycle stock target that replaced the flat six-weeks rule, with a seasonal adjustment layered on so cover expands ahead of the ramp instead of chasing it. A high-value, highly predictable item and a low-value, erratic one now get service targets and cover that reflect what they actually are.

This is the unglamorous half of the work and it's the half that determines whether the rest holds. Nothing downstream can be better than the segmentation underneath it.

2. A workbench, not a report

The planning interface was rebuilt around exceptions rather than rows. A buyer opening it does not get 67,000 items. They get inventory health across their SKU-locations, the vendor windows and MOQ fit across their buying horizon, and — the piece that changed behavior most — cross-warehouse transfer opportunities that avoid the buy entirely. In an eight-DC network, a meaningful share of "we need to order this" is actually "we already own this, it's in the wrong building."

An engineering note that mattered more than it sounds: the first version read live from SQL, and two people running sessions simultaneously produced a cache collision that corrupted both. The fix was architectural rather than defensive — move to batch-refreshed local Parquet files, so the multi-user collision stops being a thing to guard against and starts being structurally impossible. Multi-user tooling in an operating company has to survive people using it at the same time on a Monday morning.

3. An agent for the review nobody was doing

Even with good logic, someone has to look at the suggested lines before they become purchase orders. In practice nobody did, at volume, because there were more lines than hours. So the review got automated: an AI agent works a queue vendor by vendor, reviewing on the order of a hundred suggested PO lines per minute, and for each one approves, adjusts or rejects it — with its reasoning written to the record.

The reasoning being on the record is the point, not the throughput. An agent that silently approves lines is just a faster way to be wrong. An agent that says "rejected — this quantity assumes a lead time the vendor hasn't hit in six months" gives a buyer something to disagree with, which is what makes it usable in a room full of people who have been burned by a system before.

Adjacent to this build: a vendor stockout notification pipeline (an ERP flag query, a SharePoint enrichment layer, and a Power Automate distribution step) so that the buying team learns a vendor is out from a notification rather than from a customer, and a viability segmentation of 13,000+ special-order items that replaced item-by-item judgment calls on what to stock, drop or centralize.

What it produced

67k SKUsClassified ABC/XYZ, driving a seasonally adjusted statistical safety stock model in place of a flat six-weeks-of-supply rule.
20+Buyers moved off personal spreadsheets and onto one shared, reproducible buy signal.
100/minSuggested PO lines reviewed by the agent, with approve/adjust/reject reasoning on the record.
~$850kAnnual run-rate labor opportunity modeled from right-sizing the buying team once the manual work came out of it — about 100bps of budgeted SG&A from one function.

That last number deserves a caveat I'd give you on a call as well as here: it is a modeled run-rate opportunity that fed a long-range financial plan, not a realized savings figure I'm claiming credit for. The honest framing is that the manual work was measured, the automation removed a defined share of it, and the resulting headcount capacity was sized and defended in front of a sponsor. What a company then chooses to do with that capacity is a separate decision.

What transfers

Very little of this is distribution-specific. The pattern — a planning system whose output the experts have learned to override, replaced by segmentation, exception-driven tooling, and automation of the review step — applies wherever the supply signal is generated. In a co-man environment the same three layers produce a run schedule instead of a PO, with minimum run quantities and shelf life as the binding constraints instead of vendor lead times and MOQs. The interface changes. The failure mode doesn't.

What doesn't transfer is the specific logic, and that's deliberate. The segmentation thresholds, the seasonal shape, the service targets and the exception rules all have to be derived from your data. A product that ships those pre-configured is making assumptions about your business that it hasn't earned.

Next step

Tell me who decides what to buy.

If that answer takes more than one sentence, there's an engagement here.