diff --git a/apps/edr-freight-api/src/migrations/2270000000000-AddWagonTrainNumbers.ts b/apps/edr-freight-api/src/migrations/2270000000000-AddWagonTrainNumbers.ts new file mode 100644 index 000000000..7050c1c40 --- /dev/null +++ b/apps/edr-freight-api/src/migrations/2270000000000-AddWagonTrainNumbers.ts @@ -0,0 +1,28 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +/** + * Per-wagon EXPORT/IMPORT run numbers, editable from the wagon form. + * + * Nullable with no default: a wagon is not on a run until an operator says so. + * Mirrors the width of trains.export_train_number / trains.import_train_number + * (varchar 20) so the two stay comparable. + */ +export class AddWagonTrainNumbers2270000000000 implements MigrationInterface { + name = 'AddWagonTrainNumbers2270000000000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE freight.wagons + ADD COLUMN IF NOT EXISTS export_train_number varchar(20), + ADD COLUMN IF NOT EXISTS import_train_number varchar(20); + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE freight.wagons + DROP COLUMN IF EXISTS export_train_number, + DROP COLUMN IF EXISTS import_train_number; + `); + } +} diff --git a/apps/edr-freight-api/src/modules/wagons/dto/create-wagon.dto.ts b/apps/edr-freight-api/src/modules/wagons/dto/create-wagon.dto.ts index d1939c9f5..408b13be5 100644 --- a/apps/edr-freight-api/src/modules/wagons/dto/create-wagon.dto.ts +++ b/apps/edr-freight-api/src/modules/wagons/dto/create-wagon.dto.ts @@ -20,6 +20,16 @@ export class CreateWagonDto { // Tare weight and payload capacity are not accepted here: they belong to the // wagon type and are resolved through wagonTypeId. + /** EXPORT run number — odd, Ethiopia → Djibouti (e.g. 8001). */ + @IsOptional() + @IsString() + exportTrainNumber?: string; + + /** IMPORT run number — even, Djibouti → Ethiopia (e.g. 8002). */ + @IsOptional() + @IsString() + importTrainNumber?: string; + @IsOptional() @IsEnum(WagonStatus) status?: WagonStatus; diff --git a/apps/edr-freight-api/src/modules/wagons/entities/wagon.entity.ts b/apps/edr-freight-api/src/modules/wagons/entities/wagon.entity.ts index b66fc3f9d..7bfb59e1d 100644 --- a/apps/edr-freight-api/src/modules/wagons/entities/wagon.entity.ts +++ b/apps/edr-freight-api/src/modules/wagons/entities/wagon.entity.ts @@ -43,6 +43,14 @@ export class Wagon extends BaseEntity { // Tare weight and payload capacity are properties of the wagon TYPE — read them // through `wagonType`, never off the individual wagon. + /** EXPORT run number — odd, Ethiopia → Djibouti (e.g. 8001). Null until set. */ + @Column({ name: 'export_train_number', type: 'varchar', length: 20, nullable: true }) + exportTrainNumber!: string | null; + + /** IMPORT run number — even, Djibouti → Ethiopia (e.g. 8002). Null until set. */ + @Column({ name: 'import_train_number', type: 'varchar', length: 20, nullable: true }) + importTrainNumber!: string | null; + @Column({ type: 'varchar', length: 20, default: WagonStatus.Available }) status!: WagonStatusType; diff --git a/apps/edr-freight-api/src/modules/wagons/wagons.service.ts b/apps/edr-freight-api/src/modules/wagons/wagons.service.ts index 8c5dd83c8..a43ff0e67 100644 --- a/apps/edr-freight-api/src/modules/wagons/wagons.service.ts +++ b/apps/edr-freight-api/src/modules/wagons/wagons.service.ts @@ -38,6 +38,8 @@ export class WagonsService { if (dto.trainId === undefined) wagon.trainId = null; if (dto.sequenceNumber === undefined) wagon.sequenceNumber = null; if (dto.currentYardId === undefined) wagon.currentYardId = null; + if (dto.exportTrainNumber === undefined) wagon.exportTrainNumber = null; + if (dto.importTrainNumber === undefined) wagon.importTrainNumber = null; return this.wagonRepo.save(wagon); } diff --git a/apps/edr-freight-web/backoffice/src/pages/fleet/config/resources.ts b/apps/edr-freight-web/backoffice/src/pages/fleet/config/resources.ts index 82c1eaa58..b5bc5d415 100644 --- a/apps/edr-freight-web/backoffice/src/pages/fleet/config/resources.ts +++ b/apps/edr-freight-web/backoffice/src/pages/fleet/config/resources.ts @@ -271,6 +271,22 @@ export const FLEET_RESOURCES: FleetResourceConfig[] = [ { id: "status", header: "Status", accessorKey: "status", format: "statusBadge" }, ], formFields: [ + // Run numbers are optional — a wagon sits in the fleet unassigned to any + // run until an operator fills these in. + { + name: "exportTrainNumber", + label: "Export train number", + type: "text", + description: "Odd — Ethiopia → Djibouti runs", + placeholder: "e.g. 8001", + }, + { + name: "importTrainNumber", + label: "Import train number", + type: "text", + description: "Even — Djibouti → Ethiopia runs", + placeholder: "e.g. 8002", + }, { name: "wagonNumber", label: "Wagon number", type: "text", required: true }, { name: "wagonTypeId", label: "Wagon type", type: "select", required: true, dynamicOptions: "wagonTypes" }, { name: "currentYardId", label: "Current Yard", type: "select", dynamicOptions: "yards" }, @@ -278,6 +294,8 @@ export const FLEET_RESOURCES: FleetResourceConfig[] = [ { name: "notes", label: "Notes", type: "textarea" }, ], emptyValues: { + exportTrainNumber: "", + importTrainNumber: "", wagonNumber: "", wagonTypeId: "", currentYardId: "",