xpeditis2.0/apps/backend/src/infrastructure/carriers/maersk/maersk-request.mapper.ts
2025-10-27 20:54:01 +01:00

55 lines
1.6 KiB
TypeScript

/**
* 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 as 'FCL' | 'LCL') || 'FCL',
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 };
}
}