matcher/src/modules/ad/matching.mapper.ts

235 lines
8.4 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { Mapper } from '@mobicoop/ddd-library';
import { MatchingEntity } from './core/domain/matching.entity';
import { Frequency, Role } from './core/domain/ad.types';
import { MatchEntity } from './core/domain/match.entity';
import { Target } from './core/domain/candidate.types';
import { Waypoint } from './core/application/types/waypoint.type';
import { ScheduleItem } from './core/application/types/schedule-item.type';
import { Journey } from './core/domain/value-objects/journey.value-object';
import { JourneyItem } from './core/domain/value-objects/journey-item.value-object';
import { ActorTime } from './core/domain/value-objects/actor-time.value-object';
@Injectable()
export class MatchingMapper
implements Mapper<MatchingEntity, string, string, undefined>
{
toPersistence = (entity: MatchingEntity): string =>
JSON.stringify(<PersistedMatching>{
id: entity.id,
createdAt: entity.createdAt.toISOString(),
updatedAt: entity.updatedAt.toISOString(),
matches: entity.getProps().matches.map((match: MatchEntity) => ({
adId: match.getProps().adId,
role: match.getProps().role,
frequency: match.getProps().frequency,
distance: match.getProps().distance,
duration: match.getProps().duration,
initialDistance: match.getProps().initialDistance,
initialDuration: match.getProps().initialDuration,
distanceDetour: match.getProps().distanceDetour,
durationDetour: match.getProps().durationDetour,
distanceDetourPercentage: match.getProps().distanceDetourPercentage,
durationDetourPercentage: match.getProps().durationDetourPercentage,
journeys: match.getProps().journeys.map((journey: Journey) => ({
firstDate: journey.firstDate.toISOString(),
lastDate: journey.lastDate.toISOString(),
journeyItems: journey.journeyItems.map(
(journeyItem: JourneyItem) => ({
lon: journeyItem.lon,
lat: journeyItem.lat,
duration: journeyItem.duration,
distance: journeyItem.distance,
actorTimes: journeyItem.actorTimes.map(
(actorTime: ActorTime) => ({
role: actorTime.role,
target: actorTime.target,
firstDatetime: actorTime.firstDatetime.toISOString(),
firstMinDatetime: actorTime.firstMinDatetime.toISOString(),
firstMaxDatetime: actorTime.firstMaxDatetime.toISOString(),
lastDatetime: actorTime.lastDatetime.toISOString(),
lastMinDatetime: actorTime.lastMinDatetime.toISOString(),
lastMaxDatetime: actorTime.lastMaxDatetime.toISOString(),
}),
),
}),
),
})),
})),
query: {
driver: entity.getProps().query.driver,
passenger: entity.getProps().query.passenger,
frequency: entity.getProps().query.frequency,
fromDate: entity.getProps().query.fromDate,
toDate: entity.getProps().query.toDate,
schedule: entity
.getProps()
.query.schedule?.map((scheduleItem: ScheduleItem) => ({
day: scheduleItem.day,
time: scheduleItem.time,
margin: scheduleItem.margin,
})),
seatsProposed: entity.getProps().query.seatsProposed,
seatsRequested: entity.getProps().query.seatsRequested,
strict: entity.getProps().query.strict,
waypoints: entity
.getProps()
.query.waypoints.map((waypoint: Waypoint) => ({
lon: waypoint.lon,
lat: waypoint.lat,
position: waypoint.position,
houseNumber: waypoint.houseNumber,
street: waypoint.street,
postalCode: waypoint.postalCode,
locality: waypoint.locality,
country: waypoint.country,
})),
algorithmType: entity.getProps().query.algorithmType,
remoteness: entity.getProps().query.remoteness,
useProportion: entity.getProps().query.useProportion,
proportion: entity.getProps().query.proportion,
useAzimuth: entity.getProps().query.useAzimuth,
azimuthMargin: entity.getProps().query.azimuthMargin,
maxDetourDistanceRatio: entity.getProps().query.maxDetourDistanceRatio,
maxDetourDurationRatio: entity.getProps().query.maxDetourDurationRatio,
},
});
toDomain = (record: string): MatchingEntity => {
const parsedRecord: PersistedMatching = JSON.parse(record);
const matchingEntity: MatchingEntity = new MatchingEntity({
id: parsedRecord.id,
createdAt: new Date(parsedRecord.createdAt),
updatedAt: new Date(parsedRecord.updatedAt),
props: {
query: parsedRecord.query,
matches: parsedRecord.matches.map((match: PersistedMatch) =>
MatchEntity.create({
adId: match.adId,
role: match.role,
frequency: match.frequency,
distance: match.distance,
duration: match.duration,
initialDistance: match.initialDistance,
initialDuration: match.initialDuration,
journeys: match.journeys.map(
(journey: PersistedJourney) =>
new Journey({
firstDate: new Date(journey.firstDate),
lastDate: new Date(journey.lastDate),
journeyItems: journey.journeyItems.map(
(journeyItem: PersistedJourneyItem) =>
new JourneyItem({
lon: journeyItem.lon,
lat: journeyItem.lat,
duration: journeyItem.duration,
distance: journeyItem.distance,
actorTimes: journeyItem.actorTimes.map(
(actorTime: PersistedActorTime) =>
new ActorTime({
role: actorTime.role,
target: actorTime.target,
firstDatetime: new Date(actorTime.firstDatetime),
firstMinDatetime: new Date(
actorTime.firstMinDatetime,
),
firstMaxDatetime: new Date(
actorTime.firstMaxDatetime,
),
lastDatetime: new Date(actorTime.lastDatetime),
lastMinDatetime: new Date(
actorTime.lastMinDatetime,
),
lastMaxDatetime: new Date(
actorTime.lastMaxDatetime,
),
}),
),
}),
),
}),
),
}),
),
},
});
return matchingEntity;
};
}
type PersistedMatching = {
id: string;
createdAt: string;
updatedAt: string;
matches: PersistedMatch[];
query: {
driver: boolean;
passenger: boolean;
frequency: Frequency;
fromDate: string;
toDate: string;
schedule: {
day: number;
time: string;
margin: number;
}[];
seatsProposed: number;
seatsRequested: number;
strict: boolean;
waypoints: {
houseNumber: string;
street: string;
postalCode: string;
locality: string;
lon: number;
lat: number;
country: string;
position: number;
}[];
algorithmType: string;
remoteness: number;
useProportion: boolean;
proportion: number;
useAzimuth: boolean;
azimuthMargin: number;
maxDetourDistanceRatio: number;
maxDetourDurationRatio: number;
};
};
type PersistedMatch = {
adId: string;
role: Role;
frequency: Frequency;
distance: number;
duration: number;
initialDistance: number;
initialDuration: number;
journeys: PersistedJourney[];
};
type PersistedJourney = {
firstDate: string;
lastDate: string;
journeyItems: PersistedJourneyItem[];
};
type PersistedJourneyItem = {
lon: number;
lat: number;
duration: number;
distance: number;
actorTimes: PersistedActorTime[];
};
type PersistedActorTime = {
role: Role;
target: Target;
firstDatetime: string;
firstMinDatetime: string;
firstMaxDatetime: string;
lastDatetime: string;
lastMinDatetime: string;
lastMaxDatetime: string;
};