Files
edr-platform/apps/edr-freight-api/src/modules/bookings/booking-tons.sql.ts
Nathnael 0e9cfbce66 fix(reports): count container tonnage in exports and reports
Every SQL tonnage in the export datasets and report definitions used
`COALESCE(b.bulk_total_weight_tons, b.cargo_total_weight_vgm)`. COALESCE
falls through on NULL, never on 0 — and the portal booking wizard stores
`cargo_total_weight_vgm = 0` for container freight on purpose, because VGM
is captured per container line, not as a booking-level figure. So every
portal-created container booking reported as weighing nothing. The
backoffice wizard does store a booking-level total, so the same table holds
both shapes and the numbers looked erratic rather than uniformly zero.

Extract the resolver the TypeScript side already has three copies of
(bookingCargoTons, cargoTonsAndItems, totalVgmTons) into one SQL helper:
NULLIF both booking-level columns, then fall back to
SUM(booking_container.total_vgm_tons). Applied to the bookings and
train-schedules export datasets, the cargo-summary, contract-utilization and
booking-status-breakdown reports, and the intercity booking list.

On dev data this recovers 116 of 154 zero-weight container bookings and
raises live booking tonnage from 42,973 t to 61,424 t.
2026-08-28 09:20:46 +00:00

27 lines
1.2 KiB
TypeScript

/**
* 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)`;
}