xpeditis2.0/apps/backend/src/application/mappers/csv-rate.mapper.ts
2026-05-12 01:11:04 +02:00

122 lines
4.1 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import {
CsvRateResultDto,
CsvRateSearchResponseDto,
PriceBreakdownDto,
FobBreakdownDto,
} from '../dto/csv-rate-search.dto';
import {
CsvRateSearchOutput,
CsvRateSearchResult,
RateSearchFilters,
} from '@domain/ports/in/search-csv-rates.port';
import { RateSearchFiltersDto } from '../dto/rate-search-filters.dto';
import { CsvRateConfigDto } from '../dto/csv-rate-upload.dto';
import { CsvRateConfigOrmEntity } from '@infrastructure/persistence/typeorm/entities/csv-rate-config.orm-entity';
@Injectable()
export class CsvRateMapper {
mapFiltersDtoToDomain(dto?: RateSearchFiltersDto): RateSearchFilters | undefined {
if (!dto) return undefined;
return {
companies: dto.companies,
onlyDirect: dto.onlyDirect,
excludeNonDgRoutes: dto.excludeNonDgRoutes,
minPrice: dto.minPrice,
maxPrice: dto.maxPrice,
currency: dto.currency,
minTransitDays: dto.minTransitDays,
maxTransitDays: dto.maxTransitDays,
containerTypes: dto.containerTypes,
departureDate: dto.departureDate ? new Date(dto.departureDate) : undefined,
};
}
mapSearchResultToDto(result: CsvRateSearchResult): CsvRateResultDto {
const rate = result.rate;
const bd = result.priceBreakdown;
const fobBreakdown: FobBreakdownDto = {
documentation: bd.fobBreakdown.documentation,
isps: bd.fobBreakdown.isps,
handling: bd.fobBreakdown.handling,
solas: bd.fobBreakdown.solas,
customs: bd.fobBreakdown.customs,
ams_aci: bd.fobBreakdown.ams_aci,
isf5: bd.fobBreakdown.isf5,
dgAdmin: bd.fobBreakdown.dgAdmin,
};
const priceBreakdown: PriceBreakdownDto = {
freightCharge: bd.freightCharge,
freightCurrency: bd.freightCurrency,
fobFixed: bd.fobFixed,
fobHandling: bd.fobHandling,
fobDG: bd.fobDG,
fobCurrency: bd.fobCurrency,
fobBreakdown,
dgSurchargeAmount: bd.dgSurchargeAmount,
dgSurchargeCurrency: bd.dgSurchargeCurrency,
dgSurchargeStatus: bd.dgSurchargeStatus,
totalFreight: bd.totalFreight,
totalFob: bd.totalFob,
totalPriceForSorting: bd.totalPriceForSorting,
primaryCurrency: bd.primaryCurrency,
};
return {
companyName: rate.companyName,
companyEmail: rate.companyEmail,
originCFS: rate.originCFS,
origin: rate.originCode.getValue(),
portOfLoading: rate.portOfLoading,
routing: rate.routing,
destinationCFS: rate.destinationCFS,
destination: rate.destinationCode.getValue(),
destinationCountry: rate.destinationCountry,
containerType: rate.containerType.getValue(),
priceBreakdown,
frequency: rate.frequency,
transitDays: result.adjustedTransitDays ?? rate.transitDays,
validUntil: rate.validity.getEndDate().toISOString().split('T')[0],
dgAccepted: rate.isDgAccepted(),
dgSurchargeStatus: bd.dgSurchargeStatus,
remarks: rate.remarks,
source: result.source,
matchScore: result.matchScore,
serviceLevel: result.serviceLevel,
priceMultiplier: result.priceMultiplier,
originalTransitDays: result.originalTransitDays,
};
}
mapSearchOutputToResponseDto(output: CsvRateSearchOutput): CsvRateSearchResponseDto {
return {
results: output.results.map(r => this.mapSearchResultToDto(r)),
totalResults: output.totalResults,
searchedFiles: output.searchedFiles,
searchedAt: output.searchedAt,
appliedFilters: output.appliedFilters as any,
};
}
mapConfigEntityToDto(entity: CsvRateConfigOrmEntity): CsvRateConfigDto {
return {
id: entity.id,
companyName: entity.companyName,
csvFilePath: entity.csvFilePath,
type: entity.type,
hasApi: entity.hasApi,
apiConnector: entity.apiConnector,
isActive: entity.isActive,
uploadedAt: entity.uploadedAt,
rowCount: entity.rowCount,
metadata: entity.metadata,
};
}
mapConfigEntitiesToDtos(entities: CsvRateConfigOrmEntity[]): CsvRateConfigDto[] {
return entities.map(e => this.mapConfigEntityToDto(e));
}
}