add export/inport number

This commit is contained in:
natib21
2026-07-17 08:47:52 +00:00
parent 2def8f9b0e
commit b4118e1bd4
5 changed files with 66 additions and 0 deletions

View File

@@ -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<void> {
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<void> {
await queryRunner.query(`
ALTER TABLE freight.wagons
DROP COLUMN IF EXISTS export_train_number,
DROP COLUMN IF EXISTS import_train_number;
`);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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: "",