From 99a9bbc2918a7a8ba69065da506410a7ce549c24 Mon Sep 17 00:00:00 2001 From: Hagernesh Date: Wed, 8 Jul 2026 19:56:34 +0000 Subject: [PATCH] unload export --- .../dto/create-booking-under-contract.dto.ts | 7 ++++++- .../portal/src/pages/contracts/NewShipmentPage.tsx | 2 ++ .../pages/contracts/new-shipment-form/schema.ts | 14 +++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/edr-freight-api/src/modules/contracts/dto/create-booking-under-contract.dto.ts b/apps/edr-freight-api/src/modules/contracts/dto/create-booking-under-contract.dto.ts index e3130da95..f220cae0d 100644 --- a/apps/edr-freight-api/src/modules/contracts/dto/create-booking-under-contract.dto.ts +++ b/apps/edr-freight-api/src/modules/contracts/dto/create-booking-under-contract.dto.ts @@ -9,14 +9,19 @@ import { IsOptional, IsString, IsUUID, + Matches, Min, ValidateNested, } from 'class-validator'; /** One physical container under a booking line — entered at booking time. */ export class CreateContainerUnitDto { - @ApiProperty() + @ApiProperty({ description: 'ISO 6346 container number, e.g. ABCD1234567' }) @IsString() + @Transform(({ value }) => (typeof value === 'string' ? value.trim().toUpperCase() : value)) + @Matches(/^[A-Z]{4}\d{7}$/, { + message: 'containerNumber must match ISO container format, e.g. ABCD1234567', + }) containerNumber!: string; @ApiPropertyOptional() diff --git a/apps/edr-freight-web/portal/src/pages/contracts/NewShipmentPage.tsx b/apps/edr-freight-web/portal/src/pages/contracts/NewShipmentPage.tsx index e2c7bffcc..c2dc8f0bf 100644 --- a/apps/edr-freight-web/portal/src/pages/contracts/NewShipmentPage.tsx +++ b/apps/edr-freight-web/portal/src/pages/contracts/NewShipmentPage.tsx @@ -1151,6 +1151,8 @@ function ContainerLineEditor({ render={({ field, fieldState }) => ( field.onChange(e.currentTarget.value.toUpperCase())} + maxLength={11} label={u === 0 ? "Container number *" : undefined} placeholder="e.g. MSCU1234567" error={fieldState.error?.message} diff --git a/apps/edr-freight-web/portal/src/pages/contracts/new-shipment-form/schema.ts b/apps/edr-freight-web/portal/src/pages/contracts/new-shipment-form/schema.ts index 1403cf1b5..4fab3457d 100644 --- a/apps/edr-freight-web/portal/src/pages/contracts/new-shipment-form/schema.ts +++ b/apps/edr-freight-web/portal/src/pages/contracts/new-shipment-form/schema.ts @@ -26,8 +26,20 @@ export interface ShipmentValidationContext { requiresDate?: boolean; } +// ISO 6346: 4 letters (owner + category) + 6 serial digits + 1 check digit. +// Enforced at booking input so the number stays a clean reference in the warehouse. +const ISO_CONTAINER_RE = /^[A-Z]{4}\d{7}$/; + const containerUnitSchema = z.object({ - containerNumber: z.string().min(1, "Container number is required."), + containerNumber: z + .string() + .transform((v) => v.trim().toUpperCase()) + .pipe( + z + .string() + .min(1, "Container number is required.") + .regex(ISO_CONTAINER_RE, "Use ISO format: 4 letters + 7 digits, e.g. ABCU1234567."), + ), sealNumber: z.string().default(""), vgmTons: z .string()