🚚 Delivery trips
Updated
Plan a delivery trip from routes, vehicles and schedules, then compare the plan with the real departure, completion, stop times and stop pins.
User steps: work with a trip on screen. Mechanics: developer notes.
How the process works#
A delivery trip is the logistics layer around already approved sales orders. The dispatcher creates a DeliveryTrip, chooses a route, vehicle and driver, fills stops from the route, dispatches the trip, then completes it.
The trip has three states:
| State | What it means |
|---|---|
| Draft | The trip can still be edited. Fill from route can add stops. |
| Dispatched | Dispatch trip was pressed. The trip stores Actual departure. |
| Completed | Complete trip was pressed. The trip stores Actual completion and becomes read-only. |
A state is not changed by editing the state field. It changes only through the command buttons. The completion command also calls the sales fulfilment service: normal and partial stops move their sales orders forward, refused stops cancel confirmed orders.
Settings#
Delivery route#
Where: Ribbon → Sales → Dictionaries → Delivery routes. Object: DeliveryRoute.
| Field | Values | Default | Behaviour |
|---|---|---|---|
| Name | Text | Required by the card | Names the route in trip and schedule selectors. |
| Depot | A store | Empty | When a trip on this route has empty Depot, save fills it from the route. |
| Default vehicle | A vehicle | Empty | When the trip has empty Vehicle, save fills it from the route unless the schedule gives one first. |
| Default driver | A sales person / driver | Empty | When the trip has empty Driver, save fills it from the route unless the schedule gives one first. |
| Disabled | On / off | Off | A disabled route refuses dispatch and completion. |
| Arrive radius, m | Integer metres; 0 or empty means no distance check | 0 | On completion, planned and actual stop pins farther than this radius are named in the message. The trip still completes. |
A blank default field means "do not stamp this value". It does not clear a value already selected on the trip.
Route stops#
Where: Ribbon → Sales → Dictionaries → Route stops. Object: DeliveryRouteStop.
Each stop belongs to a route and names one outlet.
| Field | Values | Default | Behaviour |
|---|---|---|---|
| Sequence | Integer | Required | Defines the order copied to the trip. The system does not optimise it. |
| Outlet | Customer outlet | Required | Fill from route takes confirmed sales orders for this outlet on the trip date. |
| Window from, min / Window to, min | Minutes from midnight; empty side means no bound on that side | Empty | Copied to trip lines. Arrival before Window from or after Window to gets a verdict. Late stops are named on completion. |
| Dwell, min | Integer minutes | Empty | Copied to trip lines as planned dwell time. It is information only; it does not block completion. |
| Latitude / Longitude | Decimal degrees; both 0 means no planned pin | 0 / 0 | Copied to trip lines. A half-filled pair or out-of-range coordinate refuses dispatch or completion. |
| Disabled | On / off | Off | A disabled stop is not used by Fill from route. |
Delivery schedule#
Where: Ribbon → Sales → Dictionaries → Delivery schedules. Object: DeliverySchedule.
| Field | Values | Default | Behaviour |
|---|---|---|---|
| Route | Delivery route | Required | The schedule applies only to this route. |
| Weekday | Monday through Sunday | Required | Dispatch trip finds the schedule whose weekday matches Delivery date. |
| Depart hour | 0–23 | 0 when empty | The hour used for Planned departure. |
| Depart minute | 0–59 | 0 when empty | The minute used for Planned departure. |
| Vehicle / Driver | Vehicle and driver | Empty | Used as trip defaults when the trip and route defaults are empty. |
| Disabled | On / off | Off | Disabled schedules are ignored. With no schedule, Planned departure stays empty. |
Vehicle capacity#
Where: Ribbon → Sales → Dictionaries → Vehicles. Object: Vehicle.
| Field | Values | Default | Behaviour |
|---|---|---|---|
| Capacity qty | Decimal quantity; 0 means no capacity check | 0 | Dispatch and completion sum the order quantities on trip stops. If demand is greater, the command refuses the trip. |
| Capacity kg | Decimal kg | 0 | Stored on the vehicle, but current trip validation does not calculate weight. |
| Disabled | On / off | Off | Disabled vehicles refuse dispatch and completion. |
Example with numbers#
A route has two stops:
| Stop | Window | Planned pin |
|---|---|---|
| 1 | 09:00–10:00, written as 540–600 | 50.450100, 30.523400 |
| 2 | 11:00–12:00, written as 660–720 | no pin |
The route Arrive radius, m is 300. The Wednesday schedule says Depart hour 6 and Depart minute 30. A Wednesday trip is dispatched on 16 September.
| Action | What changes |
|---|---|
| Save the draft trip with this route | Empty Vehicle, Driver and Depot are filled from route or schedule defaults. |
| Press Fill from route | Confirmed orders for the route outlets and 16 September are copied as stops; the windows and planned pin are copied too. |
| Press Dispatch trip | Planned departure becomes 16 September 06:30. Actual departure becomes the current time. |
| Stop 1 arrives at 11:30 | 11:30 is minute 690, which is 90 minutes after 600. |
| Stop 1 actual pin is 50.459100, 30.523400 | The great-circle distance is about 1001 m, which is greater than 300 m. |
| Press Complete trip | The trip closes and the message names stop 1 as 90 minutes late and about 1001 m from plan. |
If Arrive radius, m is 0, the same actual pin is not checked. If Arrived at is empty, the window verdict is not calculated; empty means "not marked", not midnight.
Optimise stop order#
Optimise stop order sits on the draft trip only: once the trip is dispatched, the order is what the driver left with, and rewriting it from the office is a divergence from reality, not an improvement.
The button rearranges the stops by distance — nearest neighbour from the first stop — and rewrites Stop sequence 1…N. It reports the outcome in metres, so the figure can be checked rather than believed.
| The case | What happens |
|---|---|
| Any stop has a time window | Refused, naming the stop. The window is a promise, and an order chosen purely by distance would break it silently |
| Fewer than three stops with coordinates | Nothing to rearrange, and the message says so |
| A stop has no planned pin | It keeps its relative order and moves to the end; it is not counted in the saving |
| The order is already the shortest this method finds | Rewritten the same, message says the route did not get shorter |
The first stop stays first. The depot (Store) carries no coordinates, so
the system does not know where the van leaves from and will not invent it: the
stop that is first today anchors the chain, and the rest are arranged after it.
Example with numbers#
Four stops on one latitude, 716 m apart in longitude, entered as A → B → C → D where B is the farthest:
| Order | Route |
|---|---|
| As entered: A, B, C, D | 2,147 + 1,431 + 716 = 4,294 m |
| After the button: A, C, D, B | 716 × 3 = 2,147 m |
The message names the saving — 2,147 m. Press it again and it answers that the route did not get shorter — the method has nothing left to improve.
Boundaries and edge cases#
- Route sequence is copied as-is; Optimise stop order is the one thing that rewrites it, and only on a draft.
- The optimiser is nearest-neighbour, not a shortest-path solver: it improves the order, it does not promise the best one.
- Late arrival and a far actual pin are facts. They are reported but do not block completion.
- Impossible facts do block: Departed at without Arrived at, departure earlier than arrival, half-filled coordinate pairs, and latitude / longitude outside their ranges.
- Both planned coordinate fields equal to zero means "no pin". One zero coordinate by itself is allowed when the other coordinate is real.
- Capacity kg is stored for the vehicle but is not used by trip validation yet.
- Only orders in the route outlets are accepted for a routed trip.
What is posted#
DeliveryTrip itself has no register movements and no general-ledger entry. The trip is an operational document.
On Complete trip the sales fulfilment service walks the trip stops:
| Stop outcome | Effect |
|---|---|
| Normal | The linked SalesOrder is moved forward to delivery. |
| Partial with one order line and positive Shipped qty | The order line's delivered quantity is updated before delivery. |
| Refused | A confirmed order is moved to Cancelled. |
Money, tax, receivables and cost are still posted by the sales realization when it reaches Issued, not by the trip. Payment is still a separate document.
What's not there yet#
- Stop-order optimisation ignores time windows: a trip where any stop has one is refused rather than resequenced, because a shorter route that misses a promise is worse than a longer one that keeps it.
- The optimiser starts from the first stop, not from the depot:
Storecarries no coordinates, so there is no origin to leave from. - It is nearest-neighbour, not a shortest route: it improves the order, it does not promise the best one.
- Late or far-away stops do not calculate penalties and do not block the trip.
- Capacity kg is not checked against item weights.
- There is no automatic rescheduling when a trip misses a window.
Same topic for other readers: User · Developer