212 lines
4.5 KiB
TypeScript
212 lines
4.5 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import {
|
|
IsNotEmpty,
|
|
IsString,
|
|
IsNumber,
|
|
Min,
|
|
IsOptional,
|
|
ValidateNested,
|
|
} from 'class-validator';
|
|
import { Type } from 'class-transformer';
|
|
import { RateSearchFiltersDto } from './rate-search-filters.dto';
|
|
|
|
/**
|
|
* CSV Rate Search Request DTO
|
|
*
|
|
* Request body for searching rates in CSV-based system
|
|
* Includes basic search parameters + optional advanced filters
|
|
*/
|
|
export class CsvRateSearchDto {
|
|
@ApiProperty({
|
|
description: 'Origin port code (UN/LOCODE format)',
|
|
example: 'NLRTM',
|
|
pattern: '^[A-Z]{2}[A-Z0-9]{3}$',
|
|
})
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
origin: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Destination port code (UN/LOCODE format)',
|
|
example: 'USNYC',
|
|
pattern: '^[A-Z]{2}[A-Z0-9]{3}$',
|
|
})
|
|
@IsNotEmpty()
|
|
@IsString()
|
|
destination: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Volume in cubic meters (CBM)',
|
|
minimum: 0.01,
|
|
example: 25.5,
|
|
})
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(0.01)
|
|
volumeCBM: number;
|
|
|
|
@ApiProperty({
|
|
description: 'Weight in kilograms',
|
|
minimum: 1,
|
|
example: 3500,
|
|
})
|
|
@IsNotEmpty()
|
|
@IsNumber()
|
|
@Min(1)
|
|
weightKG: number;
|
|
|
|
@ApiPropertyOptional({
|
|
description: 'Number of pallets (0 if no pallets)',
|
|
minimum: 0,
|
|
example: 10,
|
|
default: 0,
|
|
})
|
|
@IsOptional()
|
|
@IsNumber()
|
|
@Min(0)
|
|
palletCount?: number;
|
|
|
|
@ApiPropertyOptional({
|
|
description: 'Container type filter (e.g., LCL, 20DRY, 40HC)',
|
|
example: 'LCL',
|
|
})
|
|
@IsOptional()
|
|
@IsString()
|
|
containerType?: string;
|
|
|
|
@ApiPropertyOptional({
|
|
description: 'Advanced filters for narrowing results',
|
|
type: RateSearchFiltersDto,
|
|
})
|
|
@IsOptional()
|
|
@ValidateNested()
|
|
@Type(() => RateSearchFiltersDto)
|
|
filters?: RateSearchFiltersDto;
|
|
}
|
|
|
|
/**
|
|
* CSV Rate Search Response DTO
|
|
*
|
|
* Response containing matching rates with calculated prices
|
|
*/
|
|
export class CsvRateSearchResponseDto {
|
|
@ApiProperty({
|
|
description: 'Array of matching rate results',
|
|
type: [Object], // Will be replaced with RateResultDto
|
|
})
|
|
results: CsvRateResultDto[];
|
|
|
|
@ApiProperty({
|
|
description: 'Total number of results found',
|
|
example: 15,
|
|
})
|
|
totalResults: number;
|
|
|
|
@ApiProperty({
|
|
description: 'CSV files that were searched',
|
|
type: [String],
|
|
example: ['ssc-consolidation.csv', 'ecu-worldwide.csv'],
|
|
})
|
|
searchedFiles: string[];
|
|
|
|
@ApiProperty({
|
|
description: 'Timestamp when search was executed',
|
|
example: '2025-10-23T10:30:00Z',
|
|
})
|
|
searchedAt: Date;
|
|
|
|
@ApiProperty({
|
|
description: 'Filters that were applied to the search',
|
|
type: RateSearchFiltersDto,
|
|
})
|
|
appliedFilters: RateSearchFiltersDto;
|
|
}
|
|
|
|
/**
|
|
* Single CSV Rate Result DTO
|
|
*/
|
|
export class CsvRateResultDto {
|
|
@ApiProperty({
|
|
description: 'Company name',
|
|
example: 'SSC Consolidation',
|
|
})
|
|
companyName: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Origin port code',
|
|
example: 'NLRTM',
|
|
})
|
|
origin: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Destination port code',
|
|
example: 'USNYC',
|
|
})
|
|
destination: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Container type',
|
|
example: 'LCL',
|
|
})
|
|
containerType: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Calculated price in USD',
|
|
example: 1850.50,
|
|
})
|
|
priceUSD: number;
|
|
|
|
@ApiProperty({
|
|
description: 'Calculated price in EUR',
|
|
example: 1665.45,
|
|
})
|
|
priceEUR: number;
|
|
|
|
@ApiProperty({
|
|
description: 'Primary currency of the rate',
|
|
enum: ['USD', 'EUR'],
|
|
example: 'USD',
|
|
})
|
|
primaryCurrency: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Whether this rate has separate surcharges',
|
|
example: true,
|
|
})
|
|
hasSurcharges: boolean;
|
|
|
|
@ApiProperty({
|
|
description: 'Details of surcharges if any',
|
|
example: 'BAF+CAF included',
|
|
nullable: true,
|
|
})
|
|
surchargeDetails: string | null;
|
|
|
|
@ApiProperty({
|
|
description: 'Transit time in days',
|
|
example: 28,
|
|
})
|
|
transitDays: number;
|
|
|
|
@ApiProperty({
|
|
description: 'Rate validity end date',
|
|
example: '2025-12-31',
|
|
})
|
|
validUntil: string;
|
|
|
|
@ApiProperty({
|
|
description: 'Source of the rate',
|
|
enum: ['CSV', 'API'],
|
|
example: 'CSV',
|
|
})
|
|
source: 'CSV' | 'API';
|
|
|
|
@ApiProperty({
|
|
description: 'Match score (0-100) indicating how well this rate matches the search',
|
|
minimum: 0,
|
|
maximum: 100,
|
|
example: 95,
|
|
})
|
|
matchScore: number;
|
|
}
|