-
Notifications
You must be signed in to change notification settings - Fork 2
Transport Order Leg Implementation Documentation
The Transport Order Leg feature enables multi-leg transport orders by allowing users to define multiple pickup and drop-off locations within a single Transport Order. Each leg represents a segment of the transport journey, from one facility to another, with specific pick and drop modes, addresses, and transport requirements.
Transport Order Legs were implemented to support complex transport scenarios where:
- A single transport order requires multiple stops (e.g., pick up from multiple locations, deliver to multiple destinations)
- Different legs may have different vehicle types, transport job types, or scheduled dates
- Each leg may require different pick/drop modes (e.g., curbside, dock, warehouse)
- Legs need to be individually tracked and managed through the transport workflow
The Transport Order Legs is a child table (istable: 1) that belongs to the Transport Order doctype. It contains the following key fields:
- facility_type_from: Link to DocType (Shipper, Consignee, Container Yard, Container Depot, Container Freight Station, Storage Facility, Sorting Hub, Truck Park, Transport Terminal)
-
facility_from: Dynamic Link based on
facility_type_from -
facility_type_to: Link to DocType (same options as
facility_type_from) -
facility_to: Dynamic Link based on
facility_type_to
- pick_address: Link to Address (auto-filled from facility's primary address)
- pick_address_html: Read-only text field displaying formatted address
- drop_address: Link to Address (auto-filled from facility's primary address)
- drop_address_html: Read-only text field displaying formatted address
-
pick_mode: Link to Pick and Drop Mode (filtered to modes where
allow_in_pick = 1) -
drop_mode: Link to Pick and Drop Mode (filtered to modes where
allow_in_drop = 1)
- scheduled_date: Date field for leg-specific scheduling
- vehicle_type: Link to Vehicle Type
- transport_job_type: Select field (Container, Non-Container, Special, Oversized, Multimodal, Heavy Haul)
File: logistics/transport/doctype/transport_order_legs/transport_order_legs.json
- Created: 2025-09-10
- Type: Child Table (
istable: 1) - Editable Grid: Yes (
editable_grid: 1) - Grid Page Length: 50 rows
File: logistics/transport/doctype/transport_order_legs/transport_order_legs.py
Automatically calls auto_fill_addresses() during validation to ensure addresses are populated from facility primary addresses.
Auto-fills pick_address and drop_address based on facility primary addresses:
- First attempts to use facility-specific primary address fields (e.g.,
shipper_primary_address,consignee_primary_address) - Falls back to querying Address records linked via Dynamic Links
- Prioritizes addresses marked as
is_primary_addressoris_shipping_address
Helper method that retrieves the primary address for a given facility:
- Maps facility types to their primary address field names
- Handles facility types without dedicated primary address fields
- Returns the most appropriate address based on priority flags
Returns all addresses linked to a facility via Dynamic Links. Used by frontend query filters to populate address dropdowns.
Returns the primary address for a facility. Used by frontend to auto-fill address fields when a facility is selected.
File: logistics/transport/doctype/transport_order/transport_order.js
The frontend implements several event handlers for the Transport Order Legs child table:
- Auto-populates
vehicle_typeandtransport_job_typefrom parent Transport Order when a new leg is added - Only sets values if they're not already present in the leg
- Clears
vehicle_typewhentransport_job_typechanges (to force re-selection with updated filters)
- Validates vehicle type compatibility when changed
- Auto-fills pick address when facility is selected
- Clears pick address if facility is cleared
- Calls
auto_fill_pick_address()which uses theget_primary_addressAPI
- Auto-fills drop address when facility is selected
- Clears drop address if facility is cleared
- Calls
auto_fill_drop_address()which uses theget_primary_addressAPI
-
auto_fill_pick_address(frm, cdt, cdn): Fetches and sets primary address for pick location -
auto_fill_drop_address(frm, cdt, cdn): Fetches and sets primary address for drop location -
render_pick_address_html(frm, cdt, cdn): Renders formatted HTML for pick address -
render_drop_address_html(frm, cdt, cdn): Renders formatted HTML for drop address
File: logistics/transport/doctype/transport_order/transport_order.py
Called during before_submit() to ensure:
- At least one leg exists
- Each leg has required fields:
-
facility_type_from,facility_from -
facility_type_to,facility_to vehicle_typetransport_job_type
-
- If
scheduled_dateis set on a leg, it must be valid
Validates that:
- Pick and drop facilities cannot be the same unless different addresses are specified
- Pick and drop addresses cannot be the same
Populates Transport Order legs from a selected Transport Template:
- Fetches legs from the template
- Maps template leg fields to Transport Order Legs
- Calculates
scheduled_datebased onday_offsetfrom template - Auto-fills
transport_job_typefrom parent Transport Order - Can replace existing legs or append to them
When creating a Transport Job from a Transport Order, this function:
- Iterates through each Transport Order Leg
- Validates
pick_modeanddrop_modeare valid Pick and Drop Mode records - Creates a new
Transport Legdocument for each order leg - Copies fields from order leg to transport leg:
- Facility information (from/to)
- Pick/drop modes and addresses
- Vehicle type and transport job type
- Links the Transport Leg to the Transport Job
- Creates a denormalized entry in
Transport Job Legschild table for quick viewing/filtering
Key Field Mapping:
Transport Order Leg → Transport Leg
- facility_type_from → facility_type_from
- facility_from → facility_from
- pick_mode → pick_mode (validated)
- pick_address → pick_address
- facility_type_to → facility_type_to
- facility_to → facility_to
- drop_mode → drop_mode (validated)
- drop_address → drop_address
- vehicle_type → vehicle_type
- transport_job_type → transport_job_type
- scheduled_date (from order) → date
- Automatically populates pick and drop addresses from facility primary addresses
- Supports multiple facility types with different primary address field names
- Falls back to Dynamic Link-based address lookup for facility types without dedicated primary address fields
- Links to Pick and Drop Mode records (not literal strings)
- Validates modes are appropriate for pick or drop operations
- Filters available modes based on
allow_in_pickandallow_in_dropflags
- Each leg can have its own
scheduled_date - Defaults to parent Transport Order's
scheduled_dateif not specified - Supports day offsets when populated from templates
- Each leg can specify its own
vehicle_typeandtransport_job_type - Defaults to parent Transport Order values when leg is created
- Validates vehicle type compatibility
- Can populate legs from Transport Templates
- Supports day offsets for multi-day transport plans
- Preserves facility and address information from templates
- Minimum Legs: Transport Order must have at least one leg before submission
-
Required Fields: Each leg must have:
- Facility type and facility for both pick and drop locations
- Vehicle type
- Transport job type
-
Facility Validation:
- Pick and drop facilities cannot be the same unless different addresses are specified
- Pick and drop addresses cannot be the same
-
Mode Validation:
-
pick_modemust be a valid Pick and Drop Mode withallow_in_pick = 1 -
drop_modemust be a valid Pick and Drop Mode withallow_in_drop = 1
-
-
Date Validation: If
scheduled_dateis set on a leg, it must be a valid date
Manual Creation:
- User creates or opens a Transport Order
- Navigates to "Leg Plan" tab
- Adds rows to the
legschild table - Selects facility types and facilities for pick and drop locations
- Addresses are auto-filled from facility primary addresses
- Optionally sets pick/drop modes, vehicle type, transport job type, and scheduled date
Template-Based Creation:
- User selects a Transport Template on the Transport Order
- Clicks "Leg Plan" → "Create" button
- System calls
action_get_leg_plan()which:- Fetches legs from the template
- Maps template fields to Transport Order Legs
- Calculates scheduled dates based on day offsets
- Populates the legs table
- User fills in required leg information
- System validates legs during
validate():- Auto-fills addresses if missing
- Validates facility compatibility
- Before submission,
before_submit()validates:- At least one leg exists
- All required fields are present
- Facilities and addresses are valid
- User submits Transport Order
- User creates Transport Job from Transport Order
- System calls
_create_and_attach_job_legs_from_order_legs():- Creates a Transport Leg document for each Transport Order Leg
- Validates pick/drop modes
- Copies all relevant fields
- Links Transport Legs to Transport Job
- Creates denormalized entries in Transport Job Legs table
- User creates Run Sheet from Transport Job
- System can group all legs in one Run Sheet or create separate Run Sheets per leg
- Transport Legs are added to Run Sheet for execution
logistics/transport/doctype/
├── transport_order_legs/
│ ├── transport_order_legs.json # Doctype definition
│ ├── transport_order_legs.py # Python class and API methods
│ └── __pycache__/ # Python bytecode
├── transport_order/
│ ├── transport_order.json # Parent doctype (references legs table)
│ ├── transport_order.py # Validation, job creation logic
│ └── transport_order.js # Frontend event handlers
└── transport_leg/
└── transport_leg.py # Target doctype created from order legs
-
ORDER_LEGS_FIELDNAME_FALLBACKS: List of possible field names for the legs child table (e.g.,["legs", "transport_order_legs"])
-
_find_child_table_fieldname(): Discovers the actual field name for the legs child table -
_safe_set(): Sets a field value only if the field exists on the document -
_copy_child_rows_by_common_fields(): Copies child table rows between documents based on common fields -
_map_template_row_to_order_row(): Maps template leg data to Transport Order Leg format
The address auto-fill uses a two-tier approach:
- Primary Address Fields: For facility types with dedicated primary address fields (Shipper, Consignee, Container Yard, etc.), directly accesses the field
-
Dynamic Link Fallback: For facility types without dedicated fields or when primary address is not set, queries Address records linked via Dynamic Links, prioritizing:
is_primary_address = 1is_shipping_address = 1- First created address
Pick and Drop Modes are validated at two points:
-
Frontend: Link filters restrict available modes based on
allow_in_pickandallow_in_dropflags - Backend: When creating Transport Legs from Order Legs, validates that selected modes exist and are appropriate
When creating Transport Legs from Order Legs, the system creates:
- Transport Leg Document: Full document with all details (source of truth)
- Transport Job Legs Entry: Denormalized snapshot in child table for quick viewing/filtering
This allows efficient querying and filtering while maintaining a single source of truth in the Transport Leg document.
Potential areas for future development:
- Leg Sequencing: Visual ordering and sequencing of legs
- Leg Dependencies: Define dependencies between legs (e.g., leg 2 must start after leg 1 completes)
- Leg Status Tracking: Individual status tracking per leg
- Leg Costing: Per-leg cost calculation and allocation
- Leg Optimization: Route optimization across multiple legs
- Leg Templates: Reusable leg configurations
- Transport Order: Main parent document
- Transport Job: Created from Transport Order, contains Transport Legs
- Transport Leg: Executable leg created from Transport Order Leg
- Transport Template: Template for populating legs
- Pick and Drop Mode: Defines pick/drop operation types
- Facility Types: Shipper, Consignee, Container Yard, etc.
Getting Started
- Getting Started
- Recent Platform Updates
- CargoNext v1 — Release Notes
- CargoNext v1 — Astraea Press Release
- Document Management
- Milestone Tracking
- Customer Portal
Setup and Settings
- Logistics Settings
- Credit Management
- Default Details and Relationships
- Sea Freight Settings
- Air Freight Settings
- Transport Settings
- Warehouse Settings
- Customs Settings
Sea Freight
- Sea Freight Module
- Sea Booking
- Sea Shipment
- Sea Consolidation
- Master Bill
- Shipper
- Consignee
- Container Type
- Container Management
Air Freight
Transport
- Transport Module
- Transport Order
- Transport Job
- Transport Consolidation
- Transport Leg
- Transport Plan
- Run Sheet
- Proof of Delivery
- Transport Template
- Load Type
- Transport Order — Inter-module Field Copy
Customs
Warehousing
- Warehousing Module
- Inbound Order
- Release Order
- Transfer Order
- VAS Order
- Stocktake Order
- Warehouse Job
- Warehouse Contract
- Gate Pass
- Periodic Billing
- Storage Location
- Handling Unit Type
Pricing Center
- Sales Quote
- Sales Quote — Separate Billings and Internal Job
- Change Request
- Sales Quote – Calculation Method
Job Management
- Job Management Module
- Revenue Recognition Policy — Accounts, Dates, and Charges
- Proforma GL Entries
- WIP and Accrual Reversal on Invoicing
Sustainability
Intercompany
Special Projects
Pages
Features
Reports
Glossary