A booking is routinely loaded in parts, and nothing told the customer which
containers boarded and which stayed behind. The carriage acceptance sheet was
the only record, and it both totalled up cargo still sitting in the yard and
lived inside a Warehouse documents bundle that direct truck-to-train cargo
has no business in.
The sheet now marks each wagon Loaded or Not loaded and totals only the loaded
ones. On load, the customer gets an in-app, SMS and email notice carrying the
train number, route, departure time and both container lists — capped to a
summary on SMS and email, complete in the inbox. Anything left behind also
raises a warehouse-desk notice so somebody owns finding it space.
That desk is addressed by a new warehouse_inventory:get_notification
permission: a recipient selector, not a route guard, so ops can assign who
gets pinged without granting access to anything.
The GRN notice went out over SMS alone, to whatever phone number the gate
clerk typed. Where the receive carries a booking it now resolves the company
and delivers in-app, SMS and email, skipping the typed phone so the customer
is not texted twice; manual and backlog receives keep the old path.
Direct truck-to-train export cargo skips the warehouse, so the existing
carriage acceptance sheet ready notice (fired on warehouse receive)
never reached these bookings. Their handover moment is the load itself.
Extract notifyCarriageAcceptanceReady into a shared notifications util
(was private to WarehouseInventoryService) and call it from
BookingJourneyService.loadBooking for EXPORT + DIRECT_TO_TRAIN bookings,
right after the GRN gate, before the load transaction proceeds.
Replaces the owner/general-manager/PoA trio with a single identity whose
subject is the PoA when the company declares one and the owner otherwise.
- Drop the general manager everywhere: entity columns, DTOs, required-field
list, self-service attributes, gm* identity handling.
- New explicit poaDeclared answer ("yes"/"no") replaces poaSameAsOwner. A
DARS delegation letter is required iff it is "yes"; a freight forwarder is
forced to "yes" server-side and gets no waiver.
- Owner name/email/phone become typeable and required, prefilled from the
eTrade lookup, never falling back to the authenticated account.
- Store eTrade's manager separately (etradeManagerName/Phone) and expose
ownerMatchesEtrade so backoffice compares the asserted owner against the
licence instead of against itself.
- Foreign companies satisfy the identity with Fayda or a passport number, on
whichever subject is verifying (poaPassportNumber added).
- Write companies.email/phone from the owner unconditionally, so a company
without a Fayda-verified owner still has a notification address.