import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsBoolean, IsEnum, IsInt, IsOptional, IsString, IsUUID, Max, MaxLength, Min } from 'class-validator'; import { DEFAULT_MAX_STACK_HEIGHT, WAREHOUSE_ZONE_STACK_STATUSES, WarehouseZoneStackStatus, } from '../entities/warehouse-zone-stack.entity'; import { WAREHOUSE_ZONE_SLOT_STATUSES, WarehouseZoneSlotStatus, } from '../entities/warehouse-zone-slot.entity'; /** Nobody stacks boxes this high; the cap is here to catch a typo'd 30. */ const MAX_SUPPORTED_STACK_HEIGHT = 10; export class CreateWarehouseZoneStackDto { @ApiPropertyOptional({ format: 'uuid', description: 'Optional — taken from the route param when omitted' }) @IsOptional() @IsUUID() zoneId?: string; @ApiProperty({ example: 'ZA-001' }) @IsString() @MaxLength(40) code!: string; @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(160) name?: string; @ApiPropertyOptional({ description: 'Physical row label' }) @IsOptional() @IsString() @MaxLength(20) row?: string; @ApiPropertyOptional({ description: 'Physical bay label' }) @IsOptional() @IsString() @MaxLength(20) bay?: string; @ApiPropertyOptional({ description: 'Physical position label' }) @IsOptional() @IsString() @MaxLength(20) position?: string; @ApiPropertyOptional({ default: DEFAULT_MAX_STACK_HEIGHT, description: 'One slot is generated per level, 1 to this height.', }) @IsOptional() @IsInt() @Min(1) @Max(MAX_SUPPORTED_STACK_HEIGHT) maxStackHeight?: number; } export class UpdateWarehouseZoneStackDto { @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(40) code?: string; @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(160) name?: string; @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(20) row?: string; @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(20) bay?: string; @ApiPropertyOptional() @IsOptional() @IsString() @MaxLength(20) position?: string; @ApiPropertyOptional({ description: 'Raising it adds slots; lowering it removes the empty top levels.' }) @IsOptional() @IsInt() @Min(1) @Max(MAX_SUPPORTED_STACK_HEIGHT) maxStackHeight?: number; @ApiPropertyOptional({ enum: WAREHOUSE_ZONE_STACK_STATUSES }) @IsOptional() @IsEnum(WAREHOUSE_ZONE_STACK_STATUSES) status?: WarehouseZoneStackStatus; } export class UpdateWarehouseZoneSlotDto { @ApiPropertyOptional({ enum: WAREHOUSE_ZONE_SLOT_STATUSES, description: 'Operator intent only. OCCUPIED is derived from inventory and cannot be set here.', }) @IsOptional() @IsEnum(WAREHOUSE_ZONE_SLOT_STATUSES) status?: WarehouseZoneSlotStatus; @ApiPropertyOptional() @IsOptional() @IsBoolean() isActive?: boolean; }