01 · Context and task
The client is a wholesale distributor of motor oils, lubricants and filters. Every day, orders leave the warehouse and have to be delivered to customers. There are several trucks (GAZelle, KAMAZ, Lada VIS), each with its own cargo body and payload capacity. The packer's job is to distribute the orders so that everything fits and no truck runs half-empty.
Before, this was done by eye and in Excel: mistakes, overloading, extra trips. The task: a system that takes orders from 1C and calculates the optimal truck loads on its own — accounting for the weight, volume and dimensions of every item, box types and packing rules.
02 · What was hard
- This is an optimization problem, not CRUD. “Fit N items into M trucks so that everything fits, optimally” is the classic NP-hard bin packing problem. Brute force won't cut it: with dozens of line items, the number of combinations is astronomical. You need a real solver, not a pile of if-then rules.
- Real-world product geometry. A jerrycan of oil, a cylindrical tub of grease, a filter in its factory box — each has its own size and shape. Some items ship in the manufacturer's box, some are packed into the warehouse's corrugated cartons, some go unpacked. All of these rules had to be built into the calculation.
- The calculation has to be deterministic. If the system gives a different load plan every time on the same data, the packer won't trust it. The same order must always be packed the same way — and, where possible, into a single truck.
- 1C as the data source. Orders and products come from 1C, and 1C has no REST API — data is exchanged as XML files via the CommerceML protocol. We needed a receiver that parses the exports correctly, tells orders apart from service files and doesn't crash on malformed data.
There are thousands of simple admin panels out there. Systems that actually calculate optimal vehicle loading are rare. This is an engineering problem, not form layout.
03 · Solutions
A separate optimizer service on OR-Tools
We moved load planning into a separate FastAPI microservice built on Google OR-Tools — an industrial-grade solver for combinatorial optimization (the same one Google uses for its own logistics problems). The NestJS backend prepares the data, hands it to the optimizer, gets back the optimal load plan and saves it. The solver accounts for weight, volume, dimensions and packing rules all at once.
Manual adjustments on top of the calculation
Automation provides the starting point, but a person has the final say. The manager can drag an item from one truck to another, and the system recalculates the load. “Save manual edits” then locks in the final load plan. Machine calculation and human control work together.
Reference data with real geometry
Products are stored with their shape (a box L×W×H or a cylinder), weight and packing rule. Boxes have their own catalog with dimensions. Trucks are stored with cargo body dimensions and payload capacity. Some products are classified automatically by volume in liters. All of this is the data the optimizer runs on.


A 1C receiver via CommerceML
We built an endpoint that accepts 1C exports via CommerceML directly (no archives). Every upload is recorded in the import history: what arrived, how many orders, status (success/error), new and updated records. 1C service files are filtered out and flagged separately, so the manager sees only real orders.
Roles and audit
Two access levels: administrator (full access) and manager (orders, load planning and imports only). Every significant action is written to an audit log — who did what, and when. For a warehouse where several people work with orders, this is a basic necessity.
04 · Result
Phase 1 is delivered and running in production. The manager imports orders from 1C, clicks “Calculate” and within seconds gets a load plan for every truck, with the load percentage for each. You can see what fits, what doesn't, and which box each item travels in. The plan can be adjusted with the mouse and saved.
The calculation is deterministic: the same orders produce the same load plan, and the system tries to fit each order into a single truck. The business got a tool that eliminates overloading and extra trips — things that used to be estimated by eye.
05 · What's next
The project is developed in phases. Next up is pallet support (Euro, American and Chinese pallets), so truck capacity can be set in pallets, not just by weight and volume. This is the next layer of optimization on top of a core that already works.
The architecture is ready for it: the optimizer is a separate service, and its logic can be extended without touching the backend or the interface. Adding a new packaging type or rule means new data and solver parameters, not a rewrite of the system.