const { Client } = require('pg'); const q = async (db, label, sql) => { const { rows } = await db.query(sql); console.log(`\n== ${label}`); console.table(rows); }; (async () => { const db = new Client({ host: 'localhost', port: 5433, user: 'nati', password: 'password', database: 'nati_wt_opsreport', }); await db.connect(); await q(db, 'TEU by hand (40ft = 2)', ` SELECT COUNT(*) items, COUNT(*) FILTER (WHERE cty.size_ft = 20) c20, COUNT(*) FILTER (WHERE cty.size_ft >= 40) c40, SUM(CASE WHEN cty.size_ft >= 40 THEN 2 ELSE 1 END) teu FROM freight.wagon_allocation_container_items ci LEFT JOIN freight.container_types cty ON cty.id = ci.container_type_id JOIN freight.wagon_booking_allocations wba ON wba.id = ci.wagon_booking_allocation_id AND wba.deleted_at IS NULL JOIN freight.train_set_wagons tsw ON tsw.id = wba.train_set_wagon_id AND tsw.deleted_at IS NULL JOIN freight.train_schedules ts ON ts.train_set_id = tsw.train_set_id AND ts.deleted_at IS NULL AND ts.status NOT IN ('DRAFT','CANCELLED') WHERE ci.deleted_at IS NULL`); await q(db, 'actual tons by hand', ` SELECT ROUND(SUM(wba.allocated_weight_tons), 1) actual_tons, COUNT(*) allocations, COUNT(DISTINCT tsw.id) wagons FROM freight.wagon_booking_allocations wba JOIN freight.train_set_wagons tsw ON tsw.id = wba.train_set_wagon_id AND tsw.deleted_at IS NULL JOIN freight.train_schedules ts ON ts.train_set_id = tsw.train_set_id AND ts.deleted_at IS NULL AND ts.status NOT IN ('DRAFT','CANCELLED') WHERE wba.deleted_at IS NULL`); await q(db, 'charged by hand: containers 20/40 laden + bulk wagons', ` WITH led AS ( SELECT wba.id, tsw.id AS wagon_id, wba.load_type, b.equipment_return, ct.code AS cargo_code, (SELECT COUNT(*) FROM freight.wagon_allocation_container_items ci LEFT JOIN freight.container_types cty ON cty.id = ci.container_type_id WHERE ci.wagon_booking_allocation_id = wba.id AND ci.deleted_at IS NULL AND cty.size_ft = 20) c20, (SELECT COUNT(*) FROM freight.wagon_allocation_container_items ci LEFT JOIN freight.container_types cty ON cty.id = ci.container_type_id WHERE ci.wagon_booking_allocation_id = wba.id AND ci.deleted_at IS NULL AND cty.size_ft >= 40) c40 FROM freight.wagon_booking_allocations wba JOIN freight.train_set_wagons tsw ON tsw.id = wba.train_set_wagon_id AND tsw.deleted_at IS NULL JOIN freight.train_schedules ts ON ts.train_set_id = tsw.train_set_id AND ts.deleted_at IS NULL AND ts.status NOT IN ('DRAFT','CANCELLED') LEFT JOIN freight.bookings b ON b.id = wba.booking_id AND b.deleted_at IS NULL LEFT JOIN freight.cargo_types ct ON ct.id = b.cargo_type_id WHERE wba.deleted_at IS NULL) SELECT SUM(CASE WHEN load_type = 'CONTAINER' THEN c20 * CASE WHEN equipment_return = 'RETURN' THEN 2.24 ELSE 20 END + c40 * CASE WHEN equipment_return = 'RETURN' THEN 3.88 ELSE 40 END ELSE 0 END) AS container_charged, COUNT(DISTINCT wagon_id) FILTER (WHERE load_type <> 'CONTAINER' AND COALESCE(cargo_code,'') IN ('PERISHABLE','LIVESTOCK')) * 38 AS perishable_charged, COUNT(DISTINCT wagon_id) FILTER (WHERE load_type <> 'CONTAINER' AND COALESCE(cargo_code,'') NOT IN ('PERISHABLE','LIVESTOCK')) * 70 AS bulk_charged FROM led`); await q(db, 'schedules with both actual timestamps', ` SELECT ts.train_number, ts.direction, ts.actual_departure_at, ts.actual_arrival_at, ROUND(EXTRACT(EPOCH FROM (ts.actual_arrival_at - ts.actual_departure_at))::numeric/3600, 2) hours FROM freight.train_schedules ts WHERE ts.deleted_at IS NULL AND ts.actual_departure_at IS NOT NULL AND ts.actual_arrival_at IS NOT NULL`); await q(db, 'checkpoints', ` SELECT e.kind, y.label, e.occurred_at, e.train_schedule_id FROM freight.train_checkpoint_events e JOIN freight.yards y ON y.id = e.yard_id WHERE e.deleted_at IS NULL ORDER BY e.train_schedule_id, e.sequence_no`); await q(db, 'standards row', `SELECT station_standard_hours_ethiopia eth, station_standard_hours_djibouti dj, cycle_standard_hours_container cyc, default_leg_standard_hours leg, delay_tolerance_minutes tol, charged_tons_full_20ft f20, charged_tons_full_40ft f40, default_full_trainset_wagons dfl FROM freight.operations_standards`); await db.end(); })().catch((e) => { console.error('FAIL', e.message); process.exit(1); });