booking operations and trains scheduling also allocations

This commit is contained in:
marshal
2026-06-10 00:48:32 +03:00
parent 675975bc08
commit 5774d7db9d
180 changed files with 13423 additions and 3877 deletions

View File

@@ -0,0 +1,86 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
ArrayMinSize,
IsArray,
IsBoolean,
IsInt,
IsNumber,
IsOptional,
IsString,
IsUUID,
Min,
ValidateNested,
} from 'class-validator';
export class ContainerPlacementDto {
@ApiProperty({ format: 'uuid' })
@IsUUID()
bookingContainerId!: string;
@ApiProperty({ minimum: 0 })
@IsInt()
@Min(0)
unitIndex!: number;
@ApiProperty({ minimum: 1 })
@IsInt()
@Min(1)
sequenceNo!: number;
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID()
containerId?: string;
@ApiPropertyOptional()
@IsOptional()
@IsString()
containerNumber?: string;
@ApiPropertyOptional()
@IsOptional()
@IsString()
sealNumber?: string;
}
export class AssignBookingsDto {
@ApiProperty({ type: [String] })
@IsArray()
@ArrayMinSize(1)
@IsUUID('4', { each: true })
bookingIds!: string[];
@ApiPropertyOptional({ description: 'Bypass soft hold and overweight warnings' })
@IsOptional()
@IsBoolean()
forceAssign?: boolean;
@ApiPropertyOptional({ type: [ContainerPlacementDto] })
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => ContainerPlacementDto)
containerPlacements?: ContainerPlacementDto[];
@ApiPropertyOptional({ description: 'Maximum total booking weight allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainWeightTons?: number;
@ApiPropertyOptional({ description: 'Maximum total wagon length allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainLengthMeters?: number;
@ApiPropertyOptional({ description: 'Maximum wagons allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
maxWagonsPerTrain?: number;
}

View File

@@ -1,5 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsDateString, IsUUID } from 'class-validator';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsDateString, IsInt, IsNumber, IsOptional, IsUUID, Min } from 'class-validator';
export class CreateContainerTrainScheduleDto {
@ApiProperty({ format: 'uuid' })
@@ -13,4 +14,25 @@ export class CreateContainerTrainScheduleDto {
@ApiProperty({ format: 'uuid' })
@IsUUID()
locomotiveId!: string;
@ApiPropertyOptional({ description: 'Maximum total booking weight allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainWeightTons?: number;
@ApiPropertyOptional({ description: 'Maximum total wagon length allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainLengthMeters?: number;
@ApiPropertyOptional({ description: 'Maximum wagons allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
maxWagonsPerTrain?: number;
}

View File

@@ -0,0 +1,23 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsIn, IsOptional, IsUUID } from 'class-validator';
export class GetEligibleBookingsDto {
@ApiPropertyOptional({ enum: ['CONTAINER', 'BULK'] })
@IsOptional()
@IsIn(['CONTAINER', 'BULK'])
freightType?: 'CONTAINER' | 'BULK';
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID()
originStationId?: string;
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID()
destinationStationId?: string;
@ApiPropertyOptional()
@IsOptional()
schedulingStatus?: string;
}

View File

@@ -0,0 +1,18 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsOptional, IsUUID } from 'class-validator';
export class GetEligibleBulkBookingsDto {
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID()
originStationId?: string;
@ApiPropertyOptional({ format: 'uuid' })
@IsOptional()
@IsUUID()
destinationStationId?: string;
@ApiPropertyOptional({ example: 'HOLDING' })
@IsOptional()
schedulingStatus?: string;
}

View File

@@ -1,5 +1,5 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { IsDateString, IsOptional, IsUUID } from 'class-validator';
import { IsOptional, IsUUID } from 'class-validator';
export class GetEligibleContainerBookingsDto {
@ApiPropertyOptional({ format: 'uuid' })
@@ -12,8 +12,7 @@ export class GetEligibleContainerBookingsDto {
@IsUUID()
destinationStationId?: string;
@ApiPropertyOptional({ example: '2026-06-20T08:00:00.000Z' })
@ApiPropertyOptional({ example: 'HOLDING' })
@IsOptional()
@IsDateString()
scheduleDate?: string;
schedulingStatus?: string;
}

View File

@@ -0,0 +1,22 @@
import { ApiProperty } from '@nestjs/swagger';
import { ArrayMinSize, IsArray, IsUUID, ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';
export class PinWagonAssignmentDto {
@ApiProperty({ format: 'uuid' })
@IsUUID()
trainSetWagonId!: string;
@ApiProperty({ format: 'uuid' })
@IsUUID()
physicalWagonId!: string;
}
export class PinWagonsDto {
@ApiProperty({ type: [PinWagonAssignmentDto] })
@IsArray()
@ArrayMinSize(1)
@ValidateNested({ each: true })
@Type(() => PinWagonAssignmentDto)
assignments!: PinWagonAssignmentDto[];
}

View File

@@ -0,0 +1,3 @@
import { PreviewTrainScheduleDto } from './preview-train-schedule.dto';
export class PreviewBulkTrainScheduleDto extends PreviewTrainScheduleDto {}

View File

@@ -1,22 +1,3 @@
import { ApiProperty } from '@nestjs/swagger';
import { ArrayMinSize, IsArray, IsDateString, IsUUID } from 'class-validator';
import { PreviewTrainScheduleDto } from './preview-train-schedule.dto';
export class PreviewContainerTrainScheduleDto {
@ApiProperty({ type: [String] })
@IsArray()
@ArrayMinSize(1)
@IsUUID('4', { each: true })
bookingIds!: string[];
@ApiProperty({ example: '2026-06-20T08:00:00.000Z' })
@IsDateString()
scheduleDate!: string;
@ApiProperty({ format: 'uuid' })
@IsUUID()
originStationId!: string;
@ApiProperty({ format: 'uuid' })
@IsUUID()
destinationStationId!: string;
}
export class PreviewContainerTrainScheduleDto extends PreviewTrainScheduleDto {}

View File

@@ -0,0 +1,61 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import {
ArrayMinSize,
IsArray,
IsDateString,
IsInt,
IsNumber,
IsOptional,
IsUUID,
Min,
} from 'class-validator';
export class PreviewTrainScheduleDto {
@ApiProperty({ type: [String] })
@IsArray()
@ArrayMinSize(1)
@IsUUID('4', { each: true })
bookingIds!: string[];
@ApiProperty({ example: '2026-06-20T08:00:00.000Z' })
@IsDateString()
scheduleDate!: string;
@ApiProperty({ format: 'uuid' })
@IsUUID()
originStationId!: string;
@ApiProperty({ format: 'uuid' })
@IsUUID()
destinationStationId!: string;
@ApiPropertyOptional({
format: 'uuid',
description: 'Allow bookings already assigned to this schedule (re-assign / reschedule)',
})
@IsOptional()
@IsUUID()
targetScheduleId?: string;
@ApiPropertyOptional({ description: 'Maximum total booking weight allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainWeightTons?: number;
@ApiPropertyOptional({ description: 'Maximum total wagon length allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainLengthMeters?: number;
@ApiPropertyOptional({ description: 'Maximum wagons allowed on this train' })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
maxWagonsPerTrain?: number;
}

View File

@@ -0,0 +1,40 @@
import { ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsInt, IsNumber, IsOptional, Min } from 'class-validator';
export class UpdateTrainSchedulingGlobalRulesDto {
@ApiPropertyOptional({ example: 760 })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainLengthMeters?: number;
@ApiPropertyOptional({ example: 3500 })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
maxTrainWeightTons?: number;
@ApiPropertyOptional({ example: 53 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
maxWagonsPerTrain?: number;
@ApiPropertyOptional({ example: 30 })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0.001)
max20ftContainerWeightTons?: number;
@ApiPropertyOptional({ example: 10 })
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
max20ftPairWeightDiffTons?: number;
}