/** * SQL mirror of `bookingCargoTons()` (train-scheduling/train-capacity.util.ts). * * Three storage conventions share `bookings.cargo_total_weight_vgm`: * - BULK PER_TON — the column holds tons. * - BULK PER_ITEM — the column holds an ITEM COUNT; the tons are in * `bulk_total_weight_tons`. * - CONTAINER — the portal wizard captures VGM per line, not per booking, * and sends 0 (portal NewBookingPage: "containers carry NO weight at the * wizard"). The tons live in `booking_container.total_vgm_tons`. The * backoffice wizard does store a booking-level total, so both shapes exist * in the same table. * * Hence NULLIF on both columns: a plain * `COALESCE(bulk_total_weight_tons, cargo_total_weight_vgm)` stops at the * portal's 0 — COALESCE falls through on NULL, never on 0 — and every * portal-created container booking reads as 0 tons in exports and reports. */ export function bookingTonsSql(alias = 'b'): string { return `COALESCE( NULLIF(${alias}.bulk_total_weight_tons, 0), NULLIF(${alias}.cargo_total_weight_vgm, 0), (SELECT SUM(bc.total_vgm_tons) FROM freight.booking_container bc WHERE bc.booking_id = ${alias}.id AND bc.deleted_at IS NULL), 0)`; }