Requiring a GRN before loading only works if every path into the warehouse
issues one. Two did not: autoUnloadArrived and unloadBooking created RECEIVED
inventory with a null grn_number, so cargo that genuinely arrived — by first
mile or self haul — would have been stuck un-loadable behind the new gate.
Both now stamp a GRN, derived from the booking's trade direction, matching
receive/bulkReceive/autoUnloadArrivedBookings. unloadBooking keeps an
already-issued GRN when it re-unloads an existing row rather than reissuing one.
Every path that creates warehouse inventory now issues a GRN, so the chain is
seamless: booking arrives (first mile or self haul) -> received -> GRN -> loadable
onto its allocated wagon.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>