Customs paperwork generated instead of retyped
One shipment record generating the commercial invoice, packing list and customs declaration — removing a senior administrator's entire morning per consignment.
- Client
- Import and distribution companyNamed once permission is confirmed
- Year
- 2024
- Duration
- 10 weeks
- Stack
- OdooPythonPostgreSQLReact
4 hours → 20 min
Document preparation per consignment
80%
Fields populated automatically
Per shipment
Landed cost and margin, previously estimated
0
Border rejections from transposition errors since go-live
The situation
Every consignment required a commercial invoice, packing list, certificate of origin and customs declaration. All four contained largely the same data, retyped into separate templates by an administrator senior enough to know the rules. A single transposed figure meant a document set rejected at the border and a shipment held.
What we did
- 1Mapped every field on all four documents back to its source, and found that 80% came from data already held in the shipment record
- 2Built a document generation service on top of Odoo, producing all four from one record with the remaining exceptions flagged for human review
- 3Added validation against the rules that had previously lived in the administrator's head, with a review queue rather than silent auto-approval
- 4Allocated freight, duty, handling and demurrage to the consignment so landed cost and margin became reportable per shipment
We expected to save time. We did not expect to finally know what each shipment actually earned.
Why we did not fully automate it
The obvious build was a system that generates and submits the documents with no human in the loop. We chose not to.
The rules governing these documents change, and the consequence of a wrong submission is a held shipment, which is expensive and slow to unwind. So the system generates everything, flags what it is not confident about, and puts a person on the final approval.
Preparation went from four hours to twenty minutes. Full automation might have reached five, at the cost of a failure mode nobody would notice until the border.
The unexpected result
The valuable part turned out not to be the time saving.
To generate a customs declaration correctly you need every cost component allocated to the consignment: freight, duty, handling, demurrage. Once that data existed in a structured form, landed cost per shipment fell out of it. Then margin per shipment, and margin per customer.
The company had been estimating those numbers for years. Two of their apparently best accounts turned out to be their thinnest.
Validation as a review queue
The rules the administrator had internalised got written down and encoded, but as warnings routed to a queue, not as blocking errors.
A rule engine that silently rejects an unusual but legitimate consignment is worse than no rule engine, because people learn to work around it. Surfacing the doubt to a human keeps the knowledge in the system without removing judgement.
Services involved
More work
- Retail & FMCG
Stock counts from three days to one afternoon
Replacing a nightly POS-to-accounting export with one Odoo system, then fixing the habits that made the numbers wrong in the first place.
National retail chain · 2025Read - Manufacturing
Rebuilding a plant network without stopping the line
Segmenting plant and office traffic, fixing warehouse Wi-Fi that failed once the racking was loaded, and documenting an estate nobody had a diagram for.
FMCG manufacturer · 2025Read
Something like this, for your business?
We will say whether the same approach applies.
- A reply within one working dayFrom an engineer.
- We look before we quoteA call, and a site visit if needed.
- The recommendation is yoursYours to take elsewhere.
- Or call +20 109 777 8090


