feat(warehouses): prefill receive-to-warehouse from existing booking data

The receive form now arrives filled with everything the booking already knows,
instead of the operator re-typing it:

- container numbers come from the per-unit records (booking_container_units)
  entered at booking time, falling back to the line-level aggregate
- customs seal number prefilled from the units' seal numbers
- net weight prefilled from the booking's declared cargo weight (tonnes)
- driver signatory defaults to the arriving driver's name

Existing prefills (owner, TIN, phone, booking ref, cargo, packaging, unit
count, first-mile / customer truck + driver) unchanged; all fields stay
editable where they were editable before.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Hagernesh
2026-07-10 06:42:20 +00:00
parent 0a88e2bb1d
commit fc2366f9e0
3 changed files with 20 additions and 1 deletions

View File

@@ -207,6 +207,7 @@ export interface EligibleBookingRow {
customerTin: string | null;
customerPhone: string | null;
containerNumber: string | null;
sealNumbers: string | null;
containerQuantity: number | null;
containerPackagingType: string | null;
cargoDescription: string | null;
@@ -774,7 +775,8 @@ export class WarehouseInventoryService {
company.name AS "customer",
company.tin AS "customerTin",
COALESCE(company.contact_person_phone, company.phone, company.general_manager_phone, company.etrade_phone) AS "customerPhone",
bc.container_numbers AS "containerNumber",
COALESCE(bcu.unit_numbers, bc.container_numbers) AS "containerNumber",
bcu.seal_numbers AS "sealNumbers",
bc.container_quantity AS "containerQuantity",
bc.container_packaging_type AS "containerPackagingType",
(NULLIF(TRIM(COALESCE(b.last_mile_delivery_address, '')), '') IS NOT NULL
@@ -831,6 +833,14 @@ export class WarehouseInventoryService {
LEFT JOIN freight.container_types container_type ON container_type.id = booking_container.container_type_id
WHERE booking_container.booking_id = b.id AND booking_container.deleted_at IS NULL
) bc ON true
LEFT JOIN LATERAL (
SELECT string_agg(NULLIF(unit.container_number, ''), ', ' ORDER BY unit.container_number) AS unit_numbers,
string_agg(DISTINCT NULLIF(unit.seal_number, ''), ', ') AS seal_numbers
FROM freight.booking_container_units unit
JOIN freight.booking_container line
ON line.id = unit.booking_container_id AND line.deleted_at IS NULL
WHERE line.booking_id = b.id AND unit.deleted_at IS NULL
) bcu ON true
LEFT JOIN LATERAL (
SELECT first_mile.id, first_mile.status, first_mile.vehicle_id
FROM freight.first_mile first_mile

View File

@@ -296,6 +296,10 @@ const truckEntranceFromBookings = (bookings: EligibleBooking[]): {
const truckType = commonNonEmptyValue(
bookings.map((booking) => booking.firstMileTruckType || booking.customerTruckType),
);
const customsSealNumber = commonNonEmptyValue(bookings.map((booking) => booking.sealNumbers));
// Booking's declared cargo weight (tonnes) — the receive-time net until re-weighed.
const bookingWeight = bookings.length === 1 ? Number(bookings[0]?.weight ?? '') : NaN;
const netWeightKg: number | '' = Number.isFinite(bookingWeight) && bookingWeight > 0 ? bookingWeight : '';
const edrDigitalBookingId =
bookings.length === 1
? bookings[0]?.reference ?? bookings[0]?.id ?? ''
@@ -321,9 +325,11 @@ const truckEntranceFromBookings = (bookings: EligibleBooking[]): {
customerPhone,
edrDigitalBookingId,
assignedEquipmentNumber,
customsSealNumber,
itemDescription,
packagingType,
unitCount,
netWeightKg,
grossWeightKg: '',
truckPlateNumber,
trailerPlateNumber,
@@ -331,6 +337,7 @@ const truckEntranceFromBookings = (bookings: EligibleBooking[]): {
driverPhone,
driverLicenseNumber,
truckType,
driverSignatoryName: driverName,
},
lockedFields: {
ownerName: Boolean(ownerName),

View File

@@ -388,6 +388,8 @@ export interface EligibleBooking {
customerTin: string | null;
customerPhone: string | null;
containerNumber: string | null;
/** Distinct seal numbers from the booking's container units, comma-joined. */
sealNumbers: string | null;
containerQuantity: number | null;
containerPackagingType: string | null;
cargoDescription: string | null;