Process automation
Process automation for a steel trader: the 18:30 line
How a 33-person staalhandel in Mechelen reconciles 5,400 inkoop-bevestigingen across AS/400 and SQL Server 2008 before the 18:30 DESADV cutoff.

It is 17:45 on a Tuesday in a warehouse office on the edge of Mechelen. Karim, the senior inkoper, has 47 inkoop-bevestigingen still open on his second monitor. The VAN-provider ships the day's EDIFACT DESADV file at 18:30. Every coil that goes out without a reconciled weight is an invoice dispute three weeks from now, and a phone call with a Romanian mill four weeks from now.
The company is a 33-person staalhandel — a B2B steel trader that warehouses cold-rolled coils, slits them, and ships to fabricators across Belgium and the southern Netherlands. They handle roughly 5,400 inkoop-bevestigingen a week. Every one of those confirmations carries a nominal weight from the mill, a tolerance band, and, if the coil has already crossed the dock, an actual weighbridge reading from the warehouse. Reconciling those three numbers against each other, every day, on the way to the 18:30 cutoff, is the process the trader hired us to automate.
The mismatch between those numbers is the entire business.
What follows is the process-automation engagement that turned the weekly scramble around that mismatch into a twelve-minute loop, without anyone in Mechelen having to touch either system of record.
Two systems that never spoke
The voorraadsysteem is a 16-year-old AS/400 — IBM i, in its current name. Sales orders, customer master, ledgers, all of it sits in DB2/400. The team writes screens in 5250 green-on-black and nobody on the floor finds that strange. IBM is still shipping new releases of the OS, so this is not a doomed platform. It is a platform with a thirty-five-year vocabulary and no concept of a coil.
The coil traceability is a homegrown SQL Server 2008 database, built by a Vlaams consultant in 2011 and quietly extended every year since. Each coil has a heat number, a producer, a charge analysis, a roll route, and a chain of weighbridge readings. The traceability database knows which coil came off which charge from which mill, which is what European mill safety regulations require. The AS/400 doesn't, and never will.
Microsoft ended extended support for SQL Server 2008 in July 2019. The traceability server still runs because nothing else in the building is allowed to touch it. We agreed in the first scoping call that we would not touch it either.
The 1.8 percent line
European mills typically guarantee plus-or-minus 2 percent on cold-rolled coil weight. The tolerance is real — a 12-tonne coil can arrive 200 kg light without any party being at fault. The trader's contract with its mill says they accept the nominal weight as the basis for the bevestiging; the customer's contract with the trader says the customer pays for the weighbridge weight at the moment the slit material leaves the dock.
Between those two contracts is a 1.8 percent threshold — a number their controlling team picked in 2017 because below it, the paperwork to recover the difference costs more than the difference itself. Above it, somebody on the floor has to look.
Before we built the agent, "somebody on the floor" meant Karim, three colleagues, and a shared Excel sheet called weegafwijking_2025_v3_FINAL.xlsx. By Friday at lunch the file would have 70 tabs, four people would have its memory mapped, and the 18:30 cutoff would slip to 19:15 at least twice a week.
The reconciliation loop
The agent is a small Python service. It runs every twelve minutes during the working day and does seven things, in order:
- Pulls new bevestigingen from the EDI VAN inbox (CONTRL acknowledgements, ORDRSP, IFTMIN).
- Matches each line to a sales order in DB2/400 using the customer reference and the mill's order number.
- Pulls the corresponding heat numbers and weighbridge readings from SQL Server.
- Computes the gewicht-afwijking against the nominal.
- If the absolute deviation is under 1.8 percent, writes the reconciliation back to DB2/400 and marks the line clean.
- If the absolute deviation is at or above 1.8 percent, parks the line in the inkoper queue with all three sources attached.
- At 18:25, generates the DESADV envelope for all clean lines and hands it to the VAN.
The hard parts are not the LLM calls. The hard parts are the boundaries. The classifier itself is twenty lines:
THRESHOLD = 0.018 # 1.8% — controlling memo, 2017
def classify(line, coil):
if coil is None or coil.weighbridge_kg is None:
return "park:no_weighbridge_yet"
nominal = line.nominal_kg
deviation = abs(coil.weighbridge_kg - nominal) / nominal
if deviation < THRESHOLD:
return "auto"
return f"park:deviation_{deviation:.3%}"
The boundaries are where the work lives.
Reading from DB2/400 in a way the IBM i operators trust. We use the IBM i Access ODBC driver against a read-only profile, and write back only through a single insert/update stored procedure that the in-house developer wrote and signed off on. No direct table mutation. Ever.
Translating the SQL Server schema, which has accumulated four generations of conventions, into a single canonical coil-event view. This is two hundred lines of SQL and one very patient afternoon with the consultant who built it.
Parsing the inbound EDIFACT. Each mill has its own dialect. The Romanian mill sends ORDRSP with weights in the QTY+12 segment; the Italian mill sends them in QTY+47; the German mill sends a separate IFTMIN. We did not write a generic EDIFACT parser. We wrote three mill-specific parsers and a router. Generic parsers in this domain are how projects die.
Logging every parse decision into a versioned audit table from day one. The controlling team has a long memory and a strict habit of asking "show me the decision" months after the fact. The audit table sits in the same SQL Server 2008 box we promised not to touch — we negotiated one new table for it, and it pays for itself every quarter-end.
The 18:25 cutoff window. The VAN-provider's UN/EDIFACT DESADV envelope has to be on their server by 18:30 with a margin. Five minutes of margin is what we agreed; in twenty-two weeks of running, the agent has missed the window twice, both because the SQL Server box was in the middle of its 18:00 backup. We pushed the backup to 19:00.
The purchaser queue
The interesting design question was not how to reconcile the easy cases. It was what to do with the deviations.
We built a small queue interface in the same internal portal the team already used for ploeg-planning. Each parked line shows up as a card with three panels: the bevestiging from the mill, the sales order from the AS/400, and the weighbridge events from the traceability database. The purchaser sees the same three numbers the agent saw, and the same delta, and decides one of four things: accept the deviation against the mill's account, accept it against the customer's account, request a recount on the dock, or escalate to the mill rep.
The queue does not let the purchaser change the underlying numbers. It only records a decision. The decision is what flows back to DB2/400 — through that same stored procedure, with the user's badge ID attached, so that two months from now somebody can ask "who accepted the 2.4 percent deviation on charge 81-44109" and get an answer in twelve seconds.
This sounds obvious. It was not obvious the first time we built it. The first version of the queue had an "edit weight" field that we removed in week three after the controlling team realised they could not reconstruct any of the previous month's decisions.
In an industrial reconciliation flow, never let the human edit the numbers. Let them choose a decision against the numbers. The audit trail you do not write in week one is the audit trail you cannot reconstruct in month six.
A week in shape
Roughly, what comes in and what gets parked each week:
- 5,400 inkoop-bevestigingen received.
- About 4,950 reconcile cleanly under 1.8 percent.
- About 370 land in the queue between 0.8 and 1.8 percent because of a known mill-specific calibration drift — we flag these and they auto-pass when the mill's monthly correction file arrives.
- About 80 are real deviations that need a purchaser decision.
- Two to four are flagged as data-integrity errors (a heat number on the bevestiging that does not exist in traceability) and route to the developer who maintains the SQL Server box.
The 80 a week that need a human are the entire reason the team kept their four inkopers. The 4,950 a week that flow without a human are the reason those inkopers now go home at 17:30 instead of 19:15.
Five months in
The system has been running since mid-January. As of last Friday:
- The 18:30 DESADV cutoff has slipped twice, both for the backup reason above.
- The Excel sheet has not been opened since week four.
- Karim's team logs about 6 hours a week in the queue, down from an estimated 22 hours a week of reconciliation work before. We did not measure this rigorously beforehand — we asked them to log a week of work in mid-December as a baseline.
- Two invoice disputes that did go to dispute were settled in the trader's favour faster than any prior dispute the controlling team could remember, because the parked-line record gave the customer's bookkeeper the same three numbers the agent saw.
We did not replace the AS/400, and we did not replace the SQL Server 2008 box. Both remain operationally critical. The agent is glue, not a replacement, and that was the engagement contract.
The job of process automation in a legacy industrial setting is rarely to remove the old system. It is to mediate between the old system and the business event that the old system was never asked to understand.
That shape — keep the systems of record, build the missing event layer — is what makes process automation in steel, food, and the parts of logistics still running on what they ran on in 2008, work at all. The systems are not broken. They are mute on the events the business actually argues about, and the agent is what gives those events a voice the systems can hear.
Three things we would do differently
First, we would scope the EDIFACT dialect work before quoting. We spent four working days longer than we expected on the three mill-specific parsers because the German mill changed its IFTMIN structure in February without notice and we wrote our discovery tooling in production. Next time, the first two weeks are a parse-and-log-only mode against live traffic, with no reconciliation logic running yet.
Second, we would push the SQL Server backup window in week one, not week ten. The 18:00 backup was an unwritten convention that nobody surfaced until we tripped over it. A "what runs on a cron, anywhere" audit on day one would have caught it.
Third, we would build the queue card before we built the reconciliation loop. The shape of the card forces every difficult question: what does the purchaser need to see, what decisions are legal, what gets written back, who signs off. Answering those first would have changed our DB2/400 stored-procedure design.
The small thing you can do today
If you run an operation with two systems that have never agreed on the same number, write down the threshold above which a human looks. Not the average deviation. Not the worst case. The line. If the line does not exist on paper, the queue you eventually build will get redesigned three times. When we built this process-automation agent for the Mechelen trader, the line — 1.8 percent — was the only number we did not have to debate. The team had picked it in 2017 and it was sitting in a controlling memo nobody had read in five years. That memo saved us two weeks.
Key takeaway
In legacy industrial automation, the agent is glue between two systems that never agreed on a number. Its job is to find the disagreement and route it to a human.
FAQ
What is a DESADV in EDIFACT?
DESADV (Despatch Advice) is the EDIFACT message a supplier sends to a customer to announce a shipment. It carries pack data, weights, and references back to the related order.
Why not just replace the AS/400?
For a 33-person trader running stable green-screen workflows, an AS/400 replacement is a multi-year programme. The agent solved the reconciliation problem in four months without that risk.
How does the 1.8 percent threshold actually work?
Any absolute weight deviation between the mill confirmation and the weighbridge reading at or above 1.8 percent parks the line for a purchaser decision before EDI dispatch. Below 1.8 percent, the reconciliation auto-commits.
What is the SQL Server 2008 box for?
It stores coil traceability: heat numbers, charge analysis, weighbridge events. The AS/400 has no concept of these, but European mill safety regulations require them to be tracked end-to-end.
What happens if a coil has no weighbridge reading yet?
The line is parked with a no-weighbridge tag and stays out of the 18:30 DESADV envelope until the coil crosses the dock. It does not auto-pass on the nominal weight.