The problem
At a cocoa processor, everything is decided at intake. The truck crosses the weighbridge, a weight is recorded, a sample is drawn, the laboratory measures moisture and refractions — foreign matter, broken beans, waste — and those figures determine both the price paid to the farmer and whether the load is accepted or turned away.
Every one of those steps existed, but none of them spoke to the next. Weighing lived in one place, lab analysis in another, the processing order somewhere else again. Nothing tied an incoming lot to an outgoing one. Between the group's two companies, documents were retyped by hand. And electronic invoice certification, now mandatory in Côte d'Ivoire, happened outside the ERP entirely.
The approach
One principle held from start to finish: do not replace what the standard already does well. Purchasing, stock, manufacturing, accounting and point of sale stay native Odoo. Business restrictions — who may create a product, who may confirm a sale, who sees a validated analysis — are expressed as groups and record rules, not as control code.
Custom development begins only where the cocoa trade has no standard equivalent. Weighing, quality analysis and lot splitting are genuinely new models; everything else is added by inheritance onto the existing flows, without diverting them.
One example of that mindset: toll-processing manufacturing orders had to resolve their principal. The first version looked the partner up by name — except two partners shared that name, one of them archived. Resolution now runs off the actual flow history, and deliberately abstains when the answer is ambiguous rather than pointing at the wrong client.
The solution
Nineteen custom modules on a single Odoo 18 Enterprise instance shared by both companies in the group.
The business core connects the full chain: the weighing ticket carries the inbound, outbound and net weights, moisture, refractions and the acceptance decision; the lab analysis is attached to the stock receipt and then to the manufacturing order it feeds; lot splitting tracks material beyond native traceability. Tickets can be pushed in from the weighing station through a dedicated HTTP endpoint behind a token — with the server recomputing the ticket state itself rather than trusting what it is handed.
Tax compliance is handled inside the ERP: invoices, credit notes and farmer purchase slips are FNE-certified straight from accounting and from the till.
Business intelligence runs in both directions. Odoo exposes its data to Power BI through a governed API — access key, call quota, IP allow-list, logging — instead of opening the database for reading. And the other way round, posting an invoice triggers a Power BI report refresh, authenticated through OAuth2 on Azure AD.
The rest of the scope covers access rights down to the field, the button and the menu — far finer than standard groups — traced document duplication between the two companies, a generic audit trail, and a trial-balance export in the format the accounting firm expects.
The result
The intake → analysis → processing → export chain sits in a single system, and a lot can be followed end to end. Weighings enter the ERP as structured records instead of being retyped. Documents crossing from one company to the other leave a trail instead of being copied. Invoices come out certified. And management dashboards refresh when accounting moves, not on a fixed schedule.
Stack
- Odoo
- Odoo 18 Enterprise
- Modules
- PurchaseManufacturingInventorySalesAccountingPoint of SaleHRApprovals
- Tech
- PythonPostgreSQLOWLPower BI
- Protocoles
- RESTJSONOAuth2