/** * Maersk Response Mapper * * Maps Maersk API response to domain entities */ import { v4 as uuidv4 } from 'uuid'; import { RateQuote } from '@domain/entities/rate-quote.entity'; import { MaerskRateSearchResponse, MaerskRateResult, MaerskRouteSegment } from './maersk.types'; export class MaerskResponseMapper { /** * Map Maersk API response to domain RateQuote entities */ static toRateQuotes( response: MaerskRateSearchResponse, originCode: string, destinationCode: string ): RateQuote[] { return response.results.map(result => this.toRateQuote(result, originCode, destinationCode)); } /** * Map single Maersk rate result to RateQuote domain entity */ private static toRateQuote( result: MaerskRateResult, originCode: string, destinationCode: string ): RateQuote { const surcharges = result.pricing.charges.map(charge => ({ type: charge.chargeCode, description: charge.chargeName, amount: charge.amount, currency: charge.currency, })); const route = result.schedule.routeSchedule.map(segment => this.mapRouteSegment(segment)); return RateQuote.create({ id: uuidv4(), carrierId: 'maersk-carrier-id', // TODO: Get from carrier repository carrierName: 'Maersk Line', carrierCode: 'MAERSK', origin: { code: result.routeDetails.origin.unlocCode, name: result.routeDetails.origin.cityName, country: result.routeDetails.origin.countryName, }, destination: { code: result.routeDetails.destination.unlocCode, name: result.routeDetails.destination.cityName, country: result.routeDetails.destination.countryName, }, pricing: { baseFreight: result.pricing.oceanFreight, surcharges, totalAmount: result.pricing.totalAmount, currency: result.pricing.currency, }, containerType: this.mapContainerType(result.equipment.type), mode: 'FCL', // Maersk typically handles FCL etd: new Date(result.routeDetails.departureDate), eta: new Date(result.routeDetails.arrivalDate), transitDays: result.routeDetails.transitTime, route, availability: result.bookingDetails.equipmentAvailability, frequency: result.schedule.frequency, vesselType: result.vesselInfo?.type, co2EmissionsKg: result.sustainability?.co2Emissions, }); } /** * Map Maersk route segment to domain format */ private static mapRouteSegment(segment: MaerskRouteSegment): any { return { portCode: segment.portCode, portName: segment.portName, arrival: segment.arrivalDate ? new Date(segment.arrivalDate) : undefined, departure: segment.departureDate ? new Date(segment.departureDate) : undefined, vesselName: segment.vesselName, voyageNumber: segment.voyageNumber, }; } /** * Map Maersk container type to internal format */ private static mapContainerType(maerskType: string): string { // Map Maersk container types to standard format const typeMap: { [key: string]: string } = { '20DRY': '20DRY', '40DRY': '40DRY', '40HC': '40HC', '45HC': '45HC', '20REEFER': '20REEFER', '40REEFER': '40REEFER', '40HCREEFER': '40HCREEFER', '20OT': '20OT', '40OT': '40OT', '20FR': '20FR', '40FR': '40FR', }; return typeMap[maerskType] || maerskType; } }