| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Sales (sale_management)
• Invoicing (account) • Purchase (purchase) • Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 8767 |
| Technical Name |
eh_log_transport |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Sales (sale_management)
• Invoicing (account) • Purchase (purchase) • Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 8767 |
| Technical Name |
eh_log_transport |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
Road Transport for Odoo 19
Trip dispatch, ePOD, and detention billing for the road leg, with a state machine that refuses to roll an unfit truck.
Why this module
Road Transport for Odoo 19
Dispatch is a gate, not a checkbox
A trip will not move to dispatched until a vehicle and a driver are assigned, both planned times are set, and the driver license is not expired. The check is one error listing every blocker at once, with code EHL-TRIP-001. State changes only go through the action buttons, direct writes are rejected with EHL-TRIP-002.
Proof of delivery that holds up
Each stop records recipient name and role, a signature image, an optional photo, GPS latitude and longitude, and a captured-at timestamp, with a status of captured, synced, disputed, or voided. ePOD records cascade with the trip and carry the company for isolation.
Detention computed, not argued
Free-time hours and a per-hour rate sit on the trip. The chargeable detention and amount compute automatically from planned versus actual times at both pickup and delivery, never go negative on early arrival, and stay zero until both ends of a stop are stamped.
Day in the life
A trip from board to closed file
A dispatcher opens a planned trip, assigns the tractor, trailer, and driver, and sets planned pickup and delivery. Dispatch is blocked because the driver license expired last week, so they swap drivers and the truck rolls. As the driver works the run, the trip moves at pickup (stamping actual pickup), in transit, at delivery (stamping actual delivery), then delivered. The driver captures an ePOD with the consignee signature and a photo. Pickup ran four hours late and delivery two, so beyond the four free-time hours the detention amount accrues by itself. The trip closes, every transition logged to the event ledger and the chatter.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
If the assigned driver license expiry date is in the past, dispatch is refused with the driver name and the expiry date named in the error, so an unfit driver never leaves the yard.
The trip enforces an explicit transition table. Trying to jump, for example, from planned straight to delivered raises a state-conflict error that lists exactly which transitions are allowed from the current state.
Writing the state field directly (import, script, or rules engine) is rejected with EHL-TRIP-002. The only legitimate path is the action buttons, which keeps the event log and chatter complete.
Detention can never go negative. Arriving before the planned time contributes zero, not a credit, so a long early leg cannot wash out a late one.
Detention stays zero for a stop until both its planned and actual datetimes exist, so half-entered data does not produce a phantom charge.
Trips, vehicles, drivers, and ePOD records each carry a company and a companies set with record rules, so one tenant cannot see or dispatch against another tenant's fleet.
Creating a driver without a linked contact auto-creates a res.partner from the name and phone, so contact and address data flows through the standard partner record from day one.
What is inside
Built to do the job, end to end.
- Trip spine and state machine. eh.log.transport.trip carries customer, pickup and delivery addresses and free-text locations, distance, tractor and trailer, driver, planned and actual datetimes, cargo description, package count, and gross weight. The state runs planned, dispatched, at pickup, in transit, at delivery, delivered, closed, plus cancelled, all guarded by an explicit transition table.
- Vehicle and driver masters. Vehicles carry a registration unique per company, a type (rigid, tractor, trailer, tipper, tanker, flatbed, reefer, low bed, van, and more), payload and volume capacity, and a home depot. Drivers carry license number, class, expiry, and issuing country, with an auto-computed expired flag.
- Electronic proof of delivery. Per-stop ePOD records recipient name and role, signature image, photo, GPS latitude and longitude, captured-at, notes, and a status of captured, synced, disputed, or voided. A stat button on the trip opens the linked ePOD list. The data model is built for an offline driver app to sync into.
- Demurrage and detention. Free-time hours default to four with a configurable per-hour rate. The engine sums time beyond plan at both pickup and delivery, subtracts free time, clamps at zero, and posts the chargeable hours and amount in the company currency. Four unit tests cover within-free-time, beyond, early arrival, and partial data.
- Audit and isolation. Every state transition is logged to the suite event ledger with from-state and to-state context, and the trip is on mail.thread so changes hit the chatter. Company and companies fields plus isolation record rules scope every model. Links to a sale order and a freight job are present for the suite, with restrict and set-null delete behavior.
Honest about the edges
What this does not do, so nothing surprises you.
- This is the road leg core. It records vehicle and driver masters, trips, ePOD, and detention. It does not include fuel, toll, or driver-settlement accounting, and it does not generate a PDF proof-of-delivery report in this module.
- Trips can be linked to a sale order and to a freight job through stored fields, but this module does not auto-spawn a trip on order confirmation and does not post revenue lines into the freight job ledger. That orchestration lives in the freight module.
- Vehicle telematics (gate-in, gate-out) and deeper fleet management (maintenance, fuel cards, hours-of-service, inspection scheduling) are not implemented here. The vehicle record is a lightweight master designed to bind to a dedicated fleet module when present.
- The dispatch guard checks driver license expiry, resource assignment, and planned times. It does not block on vehicle inspection due dates or on a captured ePOD, those are not enforced gates in this version.
- Customs declarations, HS codes, dangerous-goods classification, container and seal numbers, and EDI messaging are not part of this module. It is road dispatch, not customs or freight documentation.
- The ePOD signature and photo capture provides the data model. The offline driver application that captures and syncs them is a separate module and is not included here.
Odoo 19 road transport, Odoo trip dispatch, Odoo 19 Community logistics, electronic proof of delivery Odoo, ePOD Odoo 19, demurrage and detention Odoo, free time billing, driver license expiry check, truck dispatch board, vehicle and driver master, transport trip lifecycle, multi company transport, 3PL road leg, fleet dispatch Odoo Community, detention charge calculation
Please log in to comment on this module