6d8b6b3e59
Implemented DeliveryTask, Payment, and Sale entities with full CRUD, business logic, and API endpoints. Updated Order/OrderItem for sale linkage and fulfillment tracking. Registered new DbSets and DI services. Revised documentation for delivery, sale, and payment workflows.
5.3 KiB
5.3 KiB
05 — Delivery Ride Execution
Status: Planning Depends On: 04 — Loading Event
Goal
Fulfill pending orders against an active Delivery ride. The driver visits each store on the route, delivers the ordered items, gets customer confirmation, and the system creates the stock movement, updates the order, and completes the sale.
Background / Context
- A Delivery ride goes
Activeafter the loading event is confirmed. - Orders are linked to a ride implicitly through route:
Ride → Route → Stores → Pending Orders. QuantityFulfilledonOrderItemtracks what was actually delivered (added in pre-planning).- No separate backorder entity — partially fulfilled orders stay
PartiallyFulfilledand get picked up by the next delivery ride on the same route. - Customer confirmation in v1 is a boolean flag (
CustomerConfirmed). Full signature/OTP deferred to Step 09 (Fraud Controls).
Data Model Changes
New Entity — DeliveryTask
Extends Template (adds IsActive, CreatedAt — consistent with all other entities).
| Column | Type | Notes |
|---|---|---|
| Id | Guid | PK (from Template) |
| FK_RideId | Guid | FK → DeliveryRun |
| FK_OrderId | Guid | FK → Order |
| Sequence | int | Visit order on the route |
| Status | DeliveryTaskStatus | State machine below |
| CustomerConfirmed | bool | Set to true at confirm time |
| ConfirmedAt | DateTime? | Timestamp of customer confirmation |
| Note | string? | Driver note on failure or partial delivery |
| IsActive | bool | From Template (soft delete) |
| CreatedAt | DateTime | From Template |
New Enum — DeliveryTaskStatus
public enum DeliveryTaskStatus
{
Pending,
Delivered,
PartiallyDelivered,
Failed
}
No new columns on OrderItem
QuantityFulfilled already added in pre-planning. No further model changes needed.
State Machine
Pending → Delivered (all lines fully delivered + customer confirmed)
Pending → PartiallyDelivered (some lines short + customer confirmed)
Pending → Failed (driver could not deliver, no stock movement)
Stock Movements
Created on Delivered or PartiallyDelivered after customer confirmation. One movement per item:
- Debit vehicle:
-QuantityFulfilledatLocationType.Vehicle,FK_LocationId = VehicleId VehicleIdis resolved fromDeliveryTask.FK_RideId → DeliveryRun.FK_VehicleIdMovementType.SaleReferenceId = OrderId
No movement on Failed.
Order and Sale Status Transitions (triggered internally)
| Condition | Order | Sale |
|---|---|---|
| All OrderItem lines: QuantityFulfilled == Quantity | → Fulfilled | → Completed |
| Any OrderItem line: QuantityFulfilled < Quantity | → PartiallyFulfilled | stays Pending |
| Task Failed | stays Pending | stays Pending |
API Endpoints
Base routes: /api/rides/{rideId}/tasks and /api/delivery-tasks
| Method | Route | Who | Description |
|---|---|---|---|
| POST | /api/rides/{rideId}/tasks/generate |
Driver/System | Auto-create tasks from all Pending/PartiallyFulfilled orders for stores on ride's route |
| GET | /api/rides/{rideId}/tasks |
Driver | List all tasks for this ride with current status |
| GET | /api/delivery-tasks/{id} |
Driver | Task detail with order items and quantities |
| PUT | /api/delivery-tasks/{id}/quantities |
Driver | Set QuantityFulfilled per order item before confirming |
| POST | /api/delivery-tasks/{id}/confirm |
Driver | Customer confirmed — creates stock movements, transitions order/sale |
| POST | /api/delivery-tasks/{id}/fail |
Driver | Mark task as failed with a note |
Business Rules
- Delivery tasks can only be created for a ride in
Activestatus and of typeDelivery. - One task per order per ride — cannot create a second task for the same order on the same ride.
QuantityFulfilledmust be set on all order items before calling confirm.QuantityFulfilledcannot exceedQuantityon any line.CustomerConfirmedmust be true before the task can move toDeliveredorPartiallyDelivered.- Stock movement is created only once — at confirm. Never on fail.
- A failed task does not change the order or sale status — the order stays available for the next ride.
- Partial delivery: the unfulfilled quantity (
Quantity - QuantityFulfilled) remains on the same order. The next delivery ride on the same route will pick it up automatically viagenerate.
Implementation Build Order
- Enum — add
DeliveryTaskStatustoModels/Enums.cs - Entity —
DeliveryTaskinModels/ AppDBContext— new DbSet + Fluent config (Restrict on Ride, Order FKs)- Migration
- DTOs —
DeliveryTaskDTOs.csinFeatures/DeliveryRide/ - Repository —
IDeliveryTaskRepository,DeliveryTaskRepository - Service —
DeliveryTaskService - Controller —
DeliveryTaskController - DI registration in
Program.cs
Feature folder: Features/DeliveryRide/
Open Questions — Resolved
- ✅ Customer confirmation — boolean flag in v1, full signature/OTP in Step 09
- ✅ Backorder — no separate entity; same order stays PartiallyFulfilled for next ride
- ✅ Task generation — on-demand via
generateendpoint, not automatic on ride activation - ✅ Failed task — order stays Pending, available for next ride, no stock movement