203 lines
5.7 KiB
TypeScript
203 lines
5.7 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import {
|
|
IsNotEmpty,
|
|
IsString,
|
|
IsNumber,
|
|
Min,
|
|
IsOptional,
|
|
ValidateNested,
|
|
IsBoolean,
|
|
} from 'class-validator';
|
|
import { Type } from 'class-transformer';
|
|
import { RateSearchFiltersDto } from './rate-search-filters.dto';
|
|
|
|
export class CsvRateSearchDto {
|
|
@ApiProperty({ description: 'Origin UN/LOCODE', example: 'FRFOS' })
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
origin: string;
|
|
|
|
@ApiProperty({ description: 'Destination UN/LOCODE', example: 'CNSHA' })
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
destination: string;
|
|
|
|
@ApiProperty({ description: 'Volume in cubic meters (CBM)', minimum: 0.01, example: 10.5 })
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(0.01)
|
|
volumeCBM: number;
|
|
|
|
@ApiProperty({ description: 'Weight in kilograms', minimum: 1, example: 2500 })
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
weightKG: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Container type filter', example: 'LCL' })
|
|
@IsOptional()
|
|
@IsString()
|
|
containerType?: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Cargo contains dangerous goods', example: false })
|
|
@IsOptional()
|
|
@IsBoolean()
|
|
hasDangerousGoods?: boolean;
|
|
|
|
@ApiPropertyOptional({ description: 'Advanced filters', type: RateSearchFiltersDto })
|
|
@IsOptional()
|
|
@ValidateNested()
|
|
@Type(() => RateSearchFiltersDto)
|
|
filters?: RateSearchFiltersDto;
|
|
}
|
|
|
|
export class CsvRateSearchResponseDto {
|
|
@ApiProperty({ description: 'Array of matching rate results', type: [Object] })
|
|
results: CsvRateResultDto[];
|
|
|
|
@ApiProperty({ description: 'Total number of results', example: 12 })
|
|
totalResults: number;
|
|
|
|
@ApiProperty({ description: 'CSV files searched', type: [String] })
|
|
searchedFiles: string[];
|
|
|
|
@ApiProperty({ description: 'Timestamp of search', example: '2026-05-11T10:30:00Z' })
|
|
searchedAt: Date;
|
|
|
|
@ApiProperty({ description: 'Applied filters' })
|
|
appliedFilters: RateSearchFiltersDto;
|
|
}
|
|
|
|
export class FobBreakdownDto {
|
|
documentation: number;
|
|
isps: number;
|
|
handling: number;
|
|
solas: number;
|
|
customs: number;
|
|
ams_aci: number;
|
|
isf5: number;
|
|
dgAdmin: number;
|
|
}
|
|
|
|
export class PriceBreakdownDto {
|
|
@ApiProperty({ description: 'Freight charge', example: 420.0 })
|
|
freightCharge: number;
|
|
|
|
@ApiProperty({ description: 'Freight currency', example: 'USD' })
|
|
freightCurrency: string;
|
|
|
|
@ApiProperty({ description: 'Fixed FOB charges (doc+ISPS+solas+customs+AMS+ISF5)', example: 185 })
|
|
fobFixed: number;
|
|
|
|
@ApiProperty({ description: 'FOB handling charge', example: 60 })
|
|
fobHandling: number;
|
|
|
|
@ApiProperty({ description: 'DG admin fee (FOB currency, 0 if non-DG)', example: 0 })
|
|
fobDG: number;
|
|
|
|
@ApiProperty({ description: 'FOB currency', example: 'EUR' })
|
|
fobCurrency: string;
|
|
|
|
@ApiProperty({ description: 'Itemized FOB breakdown', type: FobBreakdownDto })
|
|
fobBreakdown: FobBreakdownDto;
|
|
|
|
@ApiPropertyOptional({
|
|
description: 'DG surcharge amount (null if on_request/not_accepted)',
|
|
example: null,
|
|
})
|
|
dgSurchargeAmount: number | null;
|
|
|
|
@ApiProperty({ description: 'DG surcharge currency', example: 'EUR' })
|
|
dgSurchargeCurrency: string;
|
|
|
|
@ApiProperty({
|
|
description: 'DG surcharge status',
|
|
enum: ['computed', 'on_request', 'not_accepted'],
|
|
example: 'computed',
|
|
})
|
|
dgSurchargeStatus: string;
|
|
|
|
@ApiProperty({ description: 'Total freight in freightCurrency', example: 420.0 })
|
|
totalFreight: number;
|
|
|
|
@ApiProperty({ description: 'Total FOB in fobCurrency', example: 245 })
|
|
totalFob: number;
|
|
|
|
@ApiProperty({ description: 'Sum for sorting (currency-naive)', example: 665.0 })
|
|
totalPriceForSorting: number;
|
|
|
|
@ApiProperty({ description: 'Primary currency', example: 'USD' })
|
|
primaryCurrency: string;
|
|
}
|
|
|
|
export class CsvRateResultDto {
|
|
@ApiProperty({ example: 'SSC Consolidation' })
|
|
companyName: string;
|
|
|
|
@ApiProperty({ example: 'bookings@ssc.com' })
|
|
companyEmail: string;
|
|
|
|
@ApiProperty({ description: 'Origin CFS name', example: 'Fos Sur Mer' })
|
|
originCFS: string;
|
|
|
|
@ApiProperty({ description: 'Origin UN/LOCODE', example: 'FRFOS' })
|
|
origin: string;
|
|
|
|
@ApiProperty({ description: 'Port of loading', example: 'FOS SUR MER' })
|
|
portOfLoading: string;
|
|
|
|
@ApiProperty({ description: 'Routing type', example: 'Direct' })
|
|
routing: string;
|
|
|
|
@ApiProperty({ description: 'Destination CFS name', example: 'Shanghai' })
|
|
destinationCFS: string;
|
|
|
|
@ApiProperty({ description: 'Destination UN/LOCODE', example: 'CNSHA' })
|
|
destination: string;
|
|
|
|
@ApiProperty({ description: 'Destination country', example: 'China' })
|
|
destinationCountry: string;
|
|
|
|
@ApiProperty({ example: 'LCL' })
|
|
containerType: string;
|
|
|
|
@ApiProperty({ description: 'Detailed price breakdown', type: PriceBreakdownDto })
|
|
priceBreakdown: PriceBreakdownDto;
|
|
|
|
@ApiProperty({ description: 'Departure frequency', example: 'Weekly' })
|
|
frequency: string;
|
|
|
|
@ApiProperty({ description: 'Transit time (adjusted if service level)', example: 28 })
|
|
transitDays: number;
|
|
|
|
@ApiProperty({ description: 'Rate validity end date', example: '2026-12-31' })
|
|
validUntil: string;
|
|
|
|
@ApiProperty({ description: 'Whether DG cargo is accepted', example: true })
|
|
dgAccepted: boolean;
|
|
|
|
@ApiProperty({ description: 'DG surcharge status', example: 'computed' })
|
|
dgSurchargeStatus: string;
|
|
|
|
@ApiProperty({ description: 'Internal remarks', example: 'GR1/GR2' })
|
|
remarks: string;
|
|
|
|
@ApiProperty({ example: 'CSV' })
|
|
source: 'CSV';
|
|
|
|
@ApiProperty({ description: 'Match score 0-100', example: 95 })
|
|
matchScore: number;
|
|
|
|
@ApiPropertyOptional({ enum: ['RAPID', 'STANDARD', 'ECONOMIC'] })
|
|
serviceLevel?: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Price multiplier for service level', example: 1.0 })
|
|
priceMultiplier?: number;
|
|
|
|
@ApiPropertyOptional({
|
|
description: 'Original transit days before service level adjustment',
|
|
example: 28,
|
|
})
|
|
originalTransitDays?: number;
|
|
}
|