Freight Forwarder Management
by Odoo DevHouse https://apps.odoo.com/apps/modules/browse?author=Odoo%20DevHouse$ 599.47
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Inventory (stock) • Invoicing (account) • Sales (sale_management) |
| Lines of code | 3269 |
| Technical Name |
freight_forwarder_management |
| License | OPL-1 |
| Website | https://apps.odoo.com/apps/modules/browse?author=Odoo%20DevHouse |
Freight Forwarder Management
End-to-end freight forwarding inside Odoo 19 - Ports & Carriers, Trade Lane Routes, Cargo Templates, Shipments, Carrier Bookings, Charges & Profitability, Tracking Timeline, and a Customer Portal - all in one native app.
Freight forwarders arranging sea, air, land, and multimodal cargo for customers face a painful gap: standard Odoo handles Sales, Inventory, and Invoicing but has no concept of carrier bookings, Bills of Lading, cargo manifests, dangerous-goods compliance, or per-shipment profitability. Teams fall back on spreadsheets and email threads, lose traceability, and re-key the same cargo data every time a shipment repeats.
- No Carrier Booking record - vessel/flight, voyage, MBL/HBL tracked in email or Excel
- No Cargo Manifest - container counts, weights, volumes, HS codes computed by hand
- No Dangerous Goods (DG) compliance fields - UN numbers and DG classes not captured anywhere
- No Tracking Timeline - customers email "where is my shipment?" because there's no self-service view
- No Revenue vs. Cost split per shipment - profitability reconciled manually at month-end
- No one-click Invoice/Vendor Bill generation from shipment charges - double entry into Accounting
This module adds a full freight forwarding lifecycle as its own native Odoo 19 app. Configure Ports & Airports, Carriers, Shipping Methods, multi-leg Trade Lane Routes and 24 pre-loaded Charge Codes; reuse Cargo Templates - including full Dangerous Goods fields - instead of re-entering the same commodity lines; drive each Shipment through a 10-stage workflow from Draft to Done; place Carrier Bookings that pre-fill every field from the shipment; capture Revenue and Cost charges side by side with a live Gross Profit and Margin % footer; generate a customer invoice or vendor bill straight from those charge lines with a couple of clicks; keep a visible Tracking Timeline; and give both customers and internal users a self-service Portal page - all linked to Odoo's Sales, Inventory, and Accounting apps.
- Pre-loaded Master Data: sea ports & airports, global carriers, shipping methods, 24 charge codes (12 revenue/cost pairs), and 15 IMDG dangerous-goods classes
- Multi-leg Trade Lane Routes: origin/destination ports with ordered Route Legs, auto-computed total distance (km/mi), estimated trip time, and average speed
- Cargo Templates: reusable commodity/DG profiles loaded into any shipment via an add-or-replace wizard with a quantity multiplier
- 10-Stage Shipment Workflow: Draft -> Quotation Sent -> Confirmed -> Booking Placed -> In Transit -> Arrived -> Customs Clearance -> Delivered -> Done (+ Cancelled). Each transition is model-level guarded, not just button-hidden - illegal jumps and direct state writes are rejected with a clear error, skip-ahead over optional waypoints is allowed
- Carrier Bookings: "Place Booking" wizard pre-fills carrier/route/method/vessel/voyage/ports/schedule/B-L from the shipment, with an auto-confirm toggle
- Cargo Manifest: container/weight/volume rollups and a stored dangerous-goods flag on the shipment header, searchable from list/kanban filters
- Dangerous Goods Compliance: UN number, DG class (IMDG/IATA/ADR), packaging group, and flash point on both cargo templates and shipment cargo lines
- Charges & Profitability: Revenue and Cost charge lines per shipment with live Total Revenue, Total Cost, Gross Profit, and Margin % (all stored for reporting). Disbursement charge codes (duty/tax re-billed at cost) are invoiced normally but excluded from revenue/margin so pass-through amounts never distort profitability
- Chargeable Weight: auto-computed as max(actual, volumetric) per shipment, using the sea/road 1 CBM = 1000 kg ratio or the IATA 6000 cm³/kg divisor when the Shipping Method is Air
- Data-Integrity Guardrails: soft ISO 6346 container check-digit validation, a Shipper/Consignee-vs-Port country-mismatch warning, a hard Cut-off/ETD/ETA schedule-order check, and a per-company HBL/MBL uniqueness constraint
- Mass-advance Wizard: multi-select shipments from the list view and advance them all to a target state in one action - incompatible ones are skipped and reported, not blocking
- One-Click Invoicing: "Create Invoice" and "Create Vendor Bill" wizards post an
account.movefrom unbilled charge lines only, then flag them Invoiced/Billed - Tracking Timeline: canned status templates or free text, with a per-line "Visible to Customer" toggle
- Sales Order Integration: one-click "Create Shipment" button on confirmed orders, copying order lines into revenue charge lines
- Customer & Internal Portal: self-service tracking at
/my/shipments, with a Profitability panel shown to internal logins and hidden from true portal/customer users - PDF Reports: Booking Confirmation and Freight Shipment Order QWeb reports, downloadable from the backend or the portal
- Security Groups: Freight User and Freight Manager, plus a partner-scoped portal record rule
- Well Tested: 64 automated tests covering the state machine, wizards, rollups, guardrail constraints, and security rules
Set Up Master Data & Trade Lane Routes
Go to Freight -> Configuration -> Ports & Airports / Carriers / Shipping Methods - all pre-loaded and ready to use. Build a Route with one or more ordered Route Legs; total distance, estimated trip time, and average speed are computed automatically from the legs.
Create the Shipment & Load Cargo
Go to Operations -> Shipments -> New (or click Create Shipment on a confirmed Sales Order). Set POL/POD, route, main carrier, vessel/voyage, and schedule dates. On the Cargo tab, either add lines manually or click Load Cargo from Template to append or replace cargo from a saved template, scaled by a quantity multiplier.
Place the Carrier Booking
Once the shipment is Confirmed, click Place Booking. The
wizard pre-fills Carrier, Route, Shipping Method, Vessel/Voyage, Ports, Schedule, and B/L
references from the shipment. Toggle Auto-confirm Booking and submit - a
freight.booking record is created and the shipment advances to
Booking Placed.
Track the Shipment in Transit
Add lines to the Tracking Timeline tab as the shipment moves - pick a canned status template (e.g. "Cargo Received at Origin", "Customs Cleared", "Delivered to Consignee") or write a free-form note, set the location, and toggle Visible to Customer per line.
Capture Charges & Generate Invoice/Bill
On the Charges & Profitability tab, add Revenue and Cost lines by
charge code - the footer instantly computes Total Revenue,
Total Cost, Gross Profit, and Margin %.
Click Create Invoice to bill unbilled revenue lines, or
Create Vendor Bill to settle unbilled cost lines - each wizard posts an
account.move and flags the source lines Invoiced/Billed.
Let Customers Track from the Portal
Customers log into My Shipments (/my/shipments) and see a
stat-tile summary, the cargo table, and every tracking entry flagged
Visible to Customer - with a warning banner if the shipment contains dangerous
goods. Any internal user (salesperson, manager) additionally sees a
Profitability panel; true portal/customer logins never do.
Step 1 - Ports & Airports (Master Data)
26 pre-loaded sea ports and airports with UN/LOCODE, a Sea Port / Airport type badge, and country - ready to use in routes and shipments from day one.
Step 2 - Carriers (Master Data)
Global carriers spanning shipping lines, airlines, and multi-modal operators, each with a SCAC/IATA code, carrier type badge, and a live Bookings count smart column.
Step 3 - Trade Lane Route (Multi-leg)
Route form with origin/destination ports, default carrier, and frequency, plus computed Route Metrics - total distance (km/mi), estimated trip time, and average speed - rolled up from the Route Legs table.
Step 4 - Cargo Template (with Dangerous Goods)
Reusable cargo profile with cargo type, packing mode, country of origin, weights/volumes, HS code, import tax rate, and a full Dangerous Goods block - UN number, DG class, packaging group, flash point - plus per-line DG and individual-packing flags.
Step 5 - Shipment Form & Cargo Manifest
The core Shipment form - Route & Schedule, Bill of Lading/AWB, and Parties groups, with smart buttons for Bookings and Cargo. The Cargo tab shows rollup stat tiles (Containers, Total Weight, Volume, Dangerous Goods) above the manifest lines.
Step 6 - Load Cargo from Template (DG Warning + Preview)
Selecting a template that contains hazardous materials immediately shows a Contains Dangerous Goods flag and an orange warning banner, plus a live preview of the exact cargo lines that will be created - including the per-line DG toggle. The template's UN Number, DG Class, and Packaging Group are carried onto every DG-flagged line automatically (untick a line's DG toggle and those details clear again, so a line can never read "not dangerous" while still holding a UN number) - all visible in the preview before you commit.
Step 7 - Place Booking (Wizard)
Carrier, route, shipping method, vessel/voyage, ports, schedule, and B/L references pre-filled from the shipment, with an Auto-confirm Booking toggle and free-text booking instructions.
Step 8 - Booking Record (Confirmed)
The resulting freight.booking record in Confirmed state, with its own
Draft -> Confirmed -> In Transit -> Arrived statusbar, carrier booking reference, MBL/HBL, and a cargo
summary mirrored read-only from the parent shipment.
Step 9 - Bookings Tab on the Shipment
Every booking placed against the shipment is listed on its Bookings tab with carrier, ETA, and state - confirming the shipment and its booking(s) stay in sync.
Step 10 - Tracking Timeline Tab
Chronological tracking events - canned status template or free text, location, auto-stamped user, and a per-line "Visible To..." toggle that controls exactly what the portal shows.
Step 11 - Charges & Profitability Tab
Revenue and Cost (Buy) charge lines side by side, each with charge code, quantity, and unit price - footer computes Invoice Status, Total Revenue, Total Cost, Gross Profit, and Margin % in real time.
Step 12 - Create Customer Invoice (Wizard)
Shows only unbilled revenue charge lines, each removable with the x icon before confirming.
Header carries Bill To, Invoice Date, Currency, and Payment Terms; confirming posts an
account.move (customer invoice) and flags the selected lines Invoiced.
Step 13 - Create Vendor Bill (Wizard)
Mirror of the invoice wizard for unbilled cost charge lines. The Vendor field is left blank when neither the cost line's partner nor the main carrier has a linked vendor - by design, so the user picks one deliberately rather than the wizard guessing wrong.
Step 14 - Shipments Kanban (Grouped by Stage)
An operations board grouped by shipment stage, with a red "DG" badge on any card carrying dangerous goods - drag cards across stages or add a new shipment directly from a column.
Step 15 - Shipments List (Profitability Columns)
Multiple shipments at different stages side by side, with Dangerous Goods, Total Revenue, Gross Profit, and State columns visible at a glance - and a totals row summing the financial columns.
Every one of these checks is enforced at the model layer - not just hidden buttons in the UI - so the same rule holds whether the record is edited from the form, an import, or the API.
Shipper/Consignee Country Mismatch Warning
Re-selecting the Shipper (or Consignee) fires a soft warning the moment their registered country doesn't match the Port of Loading/Discharge's country - the #1 cause of a rejected customs declaration, caught before it gets that far. Note the new Chargeable Weight stat tile alongside Containers/Total Weight/Volume on the Cargo tab.
Schedule Order Validation
Saving a Cut-off Date after the ETD (or an ETD after the ETA) is rejected outright. The check compares every consecutive pair among whichever of Cut-off/ETD/ETA are actually set - not just fixed adjacent fields - so a Cut-off-after-ETA mistake is still caught even with ETD left blank.
HBL/MBL Uniqueness Per Company
Entering an MBL/MAWB (or HBL/HAWB) already used by another shipment in the same company is blocked, with the conflicting shipment named in the error. The comparison is trimmed and case-insensitive (carrier references get typed with inconsistent casing), excludes cancelled shipments so an abandoned draft never blocks a legitimate re-entry, and never conflicts across different companies.
Also enforced (no dedicated screenshot): a soft ISO 6346 container check-digit constraint on FCL cargo lines (11-character numbers only - free-form asset tags are left untouched), with a Manual Override escape hatch for verified exceptions.
Two dedicated QWeb PDF reports ship with the module - printable, shareable, and automatically pre-filled from your Odoo data. Both are downloadable from the backend and from the customer portal.
Carrier/method/vessel/voyage/MBL/HBL table, POL/cutoff/ETD/POD/ETA table, and cargo stat boxes -
generated straight from freight.booking via reports/freight_booking_report_templates.xml.
Full shipment document with Shipper/Consignee/Notify Party/Agent, Route/Schedule, Cargo Details
with DG/UN column, Charges table, and the Tracking Timeline - streamable from the portal via
?report_type=pdf using a secure access token.
/my/shipments gives customers and internal users a self-service tracking page - no backend
access needed and no more "where is my shipment?" emails to the ops team.
Sort by ETD or name, filter by All Active/All/In Transit/Delivered/Done, a red "DG" badge on
hazardous shipments, and a role-aware banner exposing the my_assignments=1 filter to
internal users.
DG warning banner, stat tiles, Shipment Info / Route & Schedule / Parties / Bookings panels, Cargo table with a per-line DG badge, Tracking Timeline, and the Profitability panel (Revenue/Cost/ Profit %) visible here because this session is an internal login.
Two backend groups plus a partner-scoped portal rule keep master data, operations, and customer visibility cleanly separated.
freight.shipment, scoped by an ir.rule to records where they are partner, shipper, consignee, notify party, or agent.base.group_user - any internal login sees it on the portal page, true customer logins never do.account.move - it feeds Accounting, it doesn't replace it.A confirmed Sales Order gets a Create Shipment header button the moment it doesn't have one yet - no need to jump into the Freight app and re-enter the customer or order lines by hand.
The new shipment opens in Draft, pre-filled with Customer, Salesperson, and a back-reference to the Sales Order shown right in the breadcrumb.
SMB Freight Forwarders
Run sea, air, and land shipments end-to-end without buying a dedicated TMS - quote, book, track, and invoice from one Odoo app.
Importers & Exporters
Track your own inbound/outbound shipments via the portal without needing to email your forwarder for status updates.
3PL / Logistics Providers
Manage multiple carriers and trade lanes per customer with clear revenue/cost separation across a high volume of concurrent shipments.
Chemical & Hazmat Shippers
Capture UN number and DG classification on every dangerous-goods cargo line before it ever leaves the warehouse.
Manufacturers with Repeat Shipments
Save a Cargo Template once per product line and reload it into every new shipment instead of re-entering commodity data.
Sales Teams Selling Freight
Spin up a shipment straight from a confirmed Sales Order with one click, then track margin per shipment from the Charges & Profitability tab.
| Field | Description | Calculation |
|---|---|---|
| total_revenue | Sum of (Quantity à Unit Price) for charge lines where Charge Type = Revenue | Σ(qty à price) revenue |
| total_cost | Sum of (Quantity à Unit Price) for charge lines where Charge Type = Cost | Σ(qty à price) cost |
| invoice_status | "To Invoice" while any revenue line has is_invoiced = False |
any(!is_invoiced) |
| gross_profit | total_revenue minus total_cost | revenue â cost |
| margin_pct | gross_profit as a percentage of total_revenue | profit / revenue à 100 |
All five fields are stored (store=True) so they can
be filtered, grouped, and pivoted in list/kanban/graph views.
Installation & First Setup
- Install: copy the module to your addons path -> Apps -> Update App List -> search "Freight Forwarder Management" -> Install
- Assign users: Settings -> Users -> assign the Freight User or Freight Manager group
- Review master data: Freight -> Configuration -> confirm Ports, Carriers, Shipping Methods, and Charge Codes match your trade lanes
- Build a route: Configuration -> Routes -> New -> set origin/destination, default carrier, and add route legs
- Save a cargo template: Configuration -> Cargo Templates -> New -> enter commodity, weights/volumes, DG data if applicable
- Create your first shipment: Operations -> Shipments -> New -> Load Cargo from Template -> Place Booking -> Create Invoice/Vendor Bill
Requires: Odoo 19 Community or Enterprise with modules: base, mail, portal, stock, account, sale_management.
No additional enterprise modules required. Demo data is opt-in - install with --with-demo to get one seeded route, cargo template, shipment, and booking.
Can I create a shipment directly from a Sales Order?
Yes. A "Create Shipment" button appears on confirmed orders that don't have one yet. It creates a shipment linked to the order and copies every non-section/note order line into a revenue charge line, using the first available revenue/both charge code.
Does the module calculate tax on charge lines?
Not yet. amount and amount_total are currently identical (quantity Ã
unit price, no tax engine wired in) - both fields are kept for report/UI parity and are ready for
a future tax computation to diverge them.
How is "Container Count" computed on a shipment?
It counts the number of distinct container numbers among FCL-typed cargo lines, falling back to a plain line count when no container numbers were entered - this avoids the nonsensical "sum of quantities" totals a naive rollup would produce.
Can a route have more than one leg (transshipment)?
Yes. Routes support multiple Route Legs, each with its own mode, from/to port, carrier, transit days, and distance. Total distance, transit time, and average speed on the route header are computed (and stored) from the legs.
Who can see the Profitability panel on the portal?
Any internal login (base.group_user) - salesperson, freight user, manager, admin.
True portal/customer logins never see it, and never see cost data anywhere in the module.
Does the module work with Odoo Community or only Enterprise?
Both. It depends only on standard Community modules (base, mail, portal, stock, account, sale_management). No enterprise-only modules are required.
Eliminate Spreadsheets & Email
Replace scattered spreadsheets and status-update emails with a structured, auditable shipment record and self-service portal.
Faster Billing Cycles
Generate invoices and vendor bills straight from charge lines in a couple of clicks - no re-keying charges into Accounting.
Built-In DG Compliance
UN number, DG class, and packaging group are captured at the cargo line - reducing regulatory and liability risk.
Real-Time Profitability
Revenue, cost, gross profit, and margin % are visible per shipment the moment charges are entered - no month-end reconciliation.
Need Help or Have a Feature Request?
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Inventory (stock) • Invoicing (account) • Sales (sale_management) |
| Lines of code | 3269 |
| Technical Name |
freight_forwarder_management |
| License | OPL-1 |
| Website | https://apps.odoo.com/apps/modules/browse?author=Odoo%20DevHouse |
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module