/** * Maersk Request Mapper * * Maps internal domain format to Maersk API format */ import { CarrierRateSearchInput } from '../../../domain/ports/out/carrier-connector.port'; import { MaerskRateSearchRequest } from './maersk.types'; export class MaerskRequestMapper { /** * Map domain rate search input to Maersk API request */ static toMaerskRateSearchRequest(input: CarrierRateSearchInput): MaerskRateSearchRequest { const { size, type } = this.parseContainerType(input.containerType); return { originPortCode: input.origin, destinationPortCode: input.destination, containerSize: size, containerType: type, cargoMode: input.mode, estimatedDepartureDate: input.departureDate.toISOString(), numberOfContainers: input.quantity || 1, cargoWeight: input.weight, cargoVolume: input.volume, isDangerousGoods: input.isHazmat || false, imoClass: input.imoClass, }; } /** * Parse container type (e.g., '40HC' -> { size: '40', type: 'DRY' }) */ private static parseContainerType(containerType: string): { size: string; type: string } { // Extract size (first 2 digits) const sizeMatch = containerType.match(/^(\d{2})/); const size = sizeMatch ? sizeMatch[1] : '40'; // Determine type let type = 'DRY'; if (containerType.includes('REEFER')) { type = 'REEFER'; } else if (containerType.includes('OT')) { type = 'OPEN_TOP'; } else if (containerType.includes('FR')) { type = 'FLAT_RACK'; } else if (containerType.includes('TANK')) { type = 'TANK'; } return { size, type }; } }