feat(bookings): support multiple containers per booking via JSONB array

This commit is contained in:
marshal
2026-05-23 11:08:35 +03:00
parent 2064e6efda
commit ae317540c1
5 changed files with 88 additions and 85 deletions

View File

@@ -1,6 +1,7 @@
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { Transform } from "class-transformer";
import { Transform, Type } from "class-transformer";
import {
IsArray,
IsBoolean,
IsDateString,
IsIn,
@@ -10,6 +11,7 @@ import {
IsString,
IsUUID,
Min,
ValidateNested,
} from "class-validator";
const BOOKING_STATUSES = [
@@ -47,6 +49,24 @@ export {
CONTAINER_TYPES,
};
export class ContainerItem {
@ApiProperty({ enum: CONTAINER_TYPES, description: "Container type (20FT or 40FT)" })
@IsIn([...CONTAINER_TYPES])
type!: string;
@ApiProperty({ description: "Quantity of containers", minimum: 1 })
@IsInt()
@Min(1)
@Transform(({ value }) => Number(value))
qty!: number;
@ApiProperty({ description: "VGM per container in tons", minimum: 0 })
@IsNumber()
@Min(0)
@Transform(({ value }) => Number(value))
vgm!: number;
}
export class CreateBookingDto {
// ── core ─────────────────────────────────────────────────────────────
@ApiProperty({ description: "Unique booking reference" })
@@ -177,26 +197,16 @@ export class CreateBookingDto {
@IsString()
financialTerms?: string;
// ── container ────────────────────────────────────────────────────────
@ApiProperty({ enum: CONTAINER_TYPES })
@IsIn([...CONTAINER_TYPES])
containerType!: string;
@ApiProperty({ minimum: 1 })
@IsInt()
@Min(1)
@Transform(({ value }) => Number(value))
containerQuantity!: number;
@ApiProperty({ description: "VGM per container in tons", minimum: 0 })
@IsNumber()
@Min(0)
@Transform(({ value }) => Number(value))
containerVgmPerUnit!: number;
// ── containers ────────────────────────────────────────────────────────
@ApiProperty({ type: [ContainerItem], description: "Array of container specifications" })
@IsArray()
@ValidateNested({ each: true })
@Type(() => ContainerItem)
containers!: ContainerItem[];
@ApiPropertyOptional({
default: false,
description: "Auto-set to true when containerType=20FT and odd quantity. User may override.",
description: "Auto-set to true when any 20FT container has odd quantity. User may override.",
})
@IsOptional()
@IsBoolean()

View File

@@ -5,7 +5,6 @@ import { IsBoolean, IsIn, IsInt, IsOptional, IsString, IsUUID, Min } from "class
import {
BOOKING_STATUSES,
CONTRACT_TYPES,
CONTAINER_TYPES,
FREIGHT_TYPES,
PAYMENT_CURRENCIES,
SERVICE_TYPES,
@@ -48,11 +47,6 @@ export class FilterBookingDto {
@IsIn([...FREIGHT_TYPES])
freightType?: string;
@ApiPropertyOptional({ enum: CONTAINER_TYPES })
@IsOptional()
@IsIn([...CONTAINER_TYPES])
containerType?: string;
@ApiPropertyOptional({ description: "Filter consolidation-eligible bookings" })
@IsOptional()
@IsBoolean()