-- FLOW-TWO fixture — a SECOND export train, identical in shape to TRN-F2-EXP. -- -- Run AFTER seed-import-corridor.sql and seed-flow2-export-train.sql. -- Idempotent. -- -- The multi-train scenarios (TC-13, TC-14, TC-16) need two export trains on one -- day with the SAME pool structure, so that "which train did this booking land -- on" is the only variable. A second train with different pools would confound -- the overflow question with a capacity question. -- -- 35 × NW5 (CNT) + 20 × CW4 (BLK) + 5 × NW6 (FLT) = 60, at KALITY -- -- Its wagon numbers (WGN-F2Y-*) are distinct from TRN-F2-EXP's (WGN-F2X-*), so -- the two consists never compete for the same physical stock — a shared wagon -- pinned by the other train's schedule would make one consist silently short -- and the overflow arithmetic wrong. -- -- Length and pull are slack for the same reason as the first train (862.3 m of -- wagons behind 1000 m locos, ~5700 T behind 12000 T of pull): this suite tests -- SLOTS and TYPE, and a length rejection would masquerade as a pool rejection. -- 1. Its own locomotive pair at KALITY. INSERT INTO freight.locomotives (id, code, max_pull_weight_tons, max_train_length_meters, overage_tolerance_tons, current_yard_id) SELECT gen_random_uuid(), v.code, 12000, 1000, 0, y.id FROM (VALUES ('LOCO-F2Y-A'), ('LOCO-F2Y-B')) AS v(code) JOIN freight.yards y ON y.code = 'KALITY' WHERE NOT EXISTS (SELECT 1 FROM freight.locomotives l WHERE l.code = v.code); UPDATE freight.locomotives SET max_pull_weight_tons = 12000, max_train_length_meters = 1000, overage_tolerance_tons = 0, current_yard_id = (SELECT id FROM freight.yards WHERE code = 'KALITY') WHERE code IN ('LOCO-F2Y-A', 'LOCO-F2Y-B') AND (max_pull_weight_tons IS DISTINCT FROM 12000 OR max_train_length_meters IS DISTINCT FROM 1000 OR overage_tolerance_tons IS DISTINCT FROM 0); -- 2. The train. INSERT INTO freight.trains (id, code, train_name, capacity_tons, current_yard_id, import_train_number, export_train_number) SELECT gen_random_uuid(), 'TRN-F2-EXP2', 'E2E Flow-2 Export Three-Pool II', 4200, y.id, '9314', '9313' FROM freight.yards y WHERE y.code = 'KALITY' AND NOT EXISTS (SELECT 1 FROM freight.trains t WHERE t.code = 'TRN-F2-EXP2'); INSERT INTO freight.train_locomotives (id, train_id, locomotive_id, sequence_no) SELECT gen_random_uuid(), t.id, l.id, v.seq FROM (VALUES ('LOCO-F2Y-A', 0), ('LOCO-F2Y-B', 1)) AS v(loco_code, seq) JOIN freight.trains t ON t.code = 'TRN-F2-EXP2' JOIN freight.locomotives l ON l.code = v.loco_code WHERE NOT EXISTS ( SELECT 1 FROM freight.train_locomotives tl WHERE tl.train_id = t.id AND tl.locomotive_id = l.id ); -- 3. Its own three pools of rolling stock at KALITY. INSERT INTO freight.wagons (id, wagon_number, wagon_type_id, current_yard_id) SELECT gen_random_uuid(), 'WGN-F2Y-C' || lpad(g::text, 2, '0'), wt.id, y.id FROM generate_series(1, 35) AS g JOIN freight.wagon_types wt ON wt.code = 'NW5' JOIN freight.yards y ON y.code = 'KALITY' WHERE NOT EXISTS ( SELECT 1 FROM freight.wagons w WHERE w.wagon_number = 'WGN-F2Y-C' || lpad(g::text, 2, '0') ); INSERT INTO freight.wagons (id, wagon_number, wagon_type_id, current_yard_id) SELECT gen_random_uuid(), 'WGN-F2Y-B' || lpad(g::text, 2, '0'), wt.id, y.id FROM generate_series(1, 20) AS g JOIN freight.wagon_types wt ON wt.code = 'CW4' JOIN freight.yards y ON y.code = 'KALITY' WHERE NOT EXISTS ( SELECT 1 FROM freight.wagons w WHERE w.wagon_number = 'WGN-F2Y-B' || lpad(g::text, 2, '0') ); INSERT INTO freight.wagons (id, wagon_number, wagon_type_id, current_yard_id) SELECT gen_random_uuid(), 'WGN-F2Y-F' || lpad(g::text, 2, '0'), wt.id, y.id FROM generate_series(1, 5) AS g JOIN freight.wagon_types wt ON wt.code = 'NW6' JOIN freight.yards y ON y.code = 'KALITY' WHERE NOT EXISTS ( SELECT 1 FROM freight.wagons w WHERE w.wagon_number = 'WGN-F2Y-F' || lpad(g::text, 2, '0') ); -- 4. Couple all 60, same order as the first train. UPDATE freight.wagons w SET train_id = t.id, sequence_number = g.seq, status = 'ASSIGNED', current_yard_id = t.current_yard_id FROM freight.trains t, LATERAL ( SELECT ('WGN-F2Y-C' || lpad(s::text, 2, '0')) AS num, s AS seq FROM generate_series(1, 35) AS s UNION ALL SELECT ('WGN-F2Y-B' || lpad(s::text, 2, '0')), 35 + s FROM generate_series(1, 20) AS s UNION ALL SELECT ('WGN-F2Y-F' || lpad(s::text, 2, '0')), 55 + s FROM generate_series(1, 5) AS s ) g WHERE t.code = 'TRN-F2-EXP2' AND w.wagon_number = g.num AND (w.train_id IS DISTINCT FROM t.id OR w.sequence_number IS DISTINCT FROM g.seq OR w.status IS DISTINCT FROM 'ASSIGNED');