get cached matching
This commit is contained in:
parent
09efe313ba
commit
b810bc86e6
|
@ -60,6 +60,44 @@ export class MatchQueryHandler implements IQueryHandler {
|
||||||
perPage: this._defaultParams.PER_PAGE,
|
perPage: this._defaultParams.PER_PAGE,
|
||||||
})
|
})
|
||||||
.setDatesAndSchedule(this.datetimeTransformer);
|
.setDatesAndSchedule(this.datetimeTransformer);
|
||||||
|
let matchingEntity: MatchingEntity | undefined = await this._cachedMatching(
|
||||||
|
query.id,
|
||||||
|
);
|
||||||
|
if (!matchingEntity)
|
||||||
|
matchingEntity = (await this._createMatching(query)) as MatchingEntity;
|
||||||
|
const perPage: number = query.perPage as number;
|
||||||
|
const page: number = Paginator.pageNumber(
|
||||||
|
matchingEntity.getProps().matches.length,
|
||||||
|
perPage,
|
||||||
|
query.page as number,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
id: matchingEntity.id,
|
||||||
|
matches: Paginator.pageItems(
|
||||||
|
matchingEntity.getProps().matches,
|
||||||
|
page,
|
||||||
|
perPage,
|
||||||
|
),
|
||||||
|
total: matchingEntity.getProps().matches.length,
|
||||||
|
page,
|
||||||
|
perPage,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
private _cachedMatching = async (
|
||||||
|
id?: string,
|
||||||
|
): Promise<MatchingEntity | undefined> => {
|
||||||
|
if (!id) return undefined;
|
||||||
|
try {
|
||||||
|
return await this.matchingRepository.get(id);
|
||||||
|
} catch (e: any) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private _createMatching = async (
|
||||||
|
query: MatchQuery,
|
||||||
|
): Promise<MatchingEntity> => {
|
||||||
await query.setRoutes();
|
await query.setRoutes();
|
||||||
|
|
||||||
let algorithm: Algorithm;
|
let algorithm: Algorithm;
|
||||||
|
@ -70,30 +108,8 @@ export class MatchQueryHandler implements IQueryHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
const matches: MatchEntity[] = await algorithm.match();
|
const matches: MatchEntity[] = await algorithm.match();
|
||||||
const perPage: number = query.perPage as number;
|
const matchingEntity = MatchingEntity.create({
|
||||||
const page: number = Paginator.pageNumber(
|
matches,
|
||||||
matches.length,
|
|
||||||
perPage,
|
|
||||||
query.page as number,
|
|
||||||
);
|
|
||||||
// create Matching Entity for persistence
|
|
||||||
const matchingEntity: MatchingEntity = MatchingEntity.create({
|
|
||||||
matches: matches.map((matchEntity: MatchEntity) => ({
|
|
||||||
adId: matchEntity.getProps().adId,
|
|
||||||
role: matchEntity.getProps().role,
|
|
||||||
frequency: matchEntity.getProps().frequency,
|
|
||||||
distance: matchEntity.getProps().distance,
|
|
||||||
duration: matchEntity.getProps().duration,
|
|
||||||
initialDistance: matchEntity.getProps().initialDistance,
|
|
||||||
initialDuration: matchEntity.getProps().initialDuration,
|
|
||||||
distanceDetour: matchEntity.getProps().distanceDetour,
|
|
||||||
durationDetour: matchEntity.getProps().durationDetour,
|
|
||||||
distanceDetourPercentage:
|
|
||||||
matchEntity.getProps().distanceDetourPercentage,
|
|
||||||
durationDetourPercentage:
|
|
||||||
matchEntity.getProps().durationDetourPercentage,
|
|
||||||
journeys: matchEntity.getProps().journeys,
|
|
||||||
})),
|
|
||||||
query: {
|
query: {
|
||||||
driver: query.driver as boolean,
|
driver: query.driver as boolean,
|
||||||
passenger: query.passenger as boolean,
|
passenger: query.passenger as boolean,
|
||||||
|
@ -120,13 +136,7 @@ export class MatchQueryHandler implements IQueryHandler {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await this.matchingRepository.save(matchingEntity);
|
await this.matchingRepository.save(matchingEntity);
|
||||||
return {
|
return matchingEntity;
|
||||||
id: matchingEntity.id,
|
|
||||||
matches: Paginator.pageItems(matches, page, perPage),
|
|
||||||
total: matches.length,
|
|
||||||
page,
|
|
||||||
perPage,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { Point } from '@modules/ad/core/domain/value-objects/point.value-object'
|
||||||
import { Route } from '../../types/route.type';
|
import { Route } from '../../types/route.type';
|
||||||
|
|
||||||
export class MatchQuery extends QueryBase {
|
export class MatchQuery extends QueryBase {
|
||||||
|
id?: string;
|
||||||
driver?: boolean;
|
driver?: boolean;
|
||||||
passenger?: boolean;
|
passenger?: boolean;
|
||||||
readonly frequency: Frequency;
|
readonly frequency: Frequency;
|
||||||
|
@ -43,6 +44,7 @@ export class MatchQuery extends QueryBase {
|
||||||
|
|
||||||
constructor(props: MatchRequestDto, routeProvider: RouteProviderPort) {
|
constructor(props: MatchRequestDto, routeProvider: RouteProviderPort) {
|
||||||
super();
|
super();
|
||||||
|
this.id = props.id;
|
||||||
this.driver = props.driver;
|
this.driver = props.driver;
|
||||||
this.passenger = props.passenger;
|
this.passenger = props.passenger;
|
||||||
this.frequency = props.frequency;
|
this.frequency = props.frequency;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { MatchProps } from './match.types';
|
import { MatchEntity } from './match.entity';
|
||||||
import { MatchQueryProps } from './value-objects/match-query.value-object';
|
import { MatchQueryProps } from './value-objects/match-query.value-object';
|
||||||
|
|
||||||
// All properties that a Matching has
|
// All properties that a Matching has
|
||||||
export interface MatchingProps {
|
export interface MatchingProps {
|
||||||
query: MatchQueryProps; // the query that induced the matches
|
query: MatchQueryProps; // the query that induced the matches
|
||||||
matches: MatchProps[];
|
matches: MatchEntity[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties that are needed for a Matching creation
|
// Properties that are needed for a Matching creation
|
||||||
export interface CreateMatchingProps {
|
export interface CreateMatchingProps {
|
||||||
query: MatchQueryProps;
|
query: MatchQueryProps;
|
||||||
matches: MatchProps[];
|
matches: MatchEntity[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
IsISO8601,
|
IsISO8601,
|
||||||
IsInt,
|
IsInt,
|
||||||
IsOptional,
|
IsOptional,
|
||||||
|
IsUUID,
|
||||||
Max,
|
Max,
|
||||||
Min,
|
Min,
|
||||||
ValidateNested,
|
ValidateNested,
|
||||||
|
@ -21,6 +22,10 @@ import { Frequency } from '@modules/ad/core/domain/ad.types';
|
||||||
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
||||||
|
|
||||||
export class MatchRequestDto {
|
export class MatchRequestDto {
|
||||||
|
@IsUUID()
|
||||||
|
@IsOptional()
|
||||||
|
id?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsBoolean()
|
@IsBoolean()
|
||||||
driver?: boolean;
|
driver?: boolean;
|
||||||
|
|
|
@ -7,25 +7,26 @@ service MatcherService {
|
||||||
}
|
}
|
||||||
|
|
||||||
message MatchRequest {
|
message MatchRequest {
|
||||||
bool driver = 1;
|
string id = 1;
|
||||||
bool passenger = 2;
|
bool driver = 2;
|
||||||
Frequency frequency = 3;
|
bool passenger = 3;
|
||||||
string fromDate = 4;
|
Frequency frequency = 4;
|
||||||
string toDate = 5;
|
string fromDate = 5;
|
||||||
repeated ScheduleItem schedule = 6;
|
string toDate = 6;
|
||||||
bool strict = 7;
|
repeated ScheduleItem schedule = 7;
|
||||||
repeated Waypoint waypoints = 8;
|
bool strict = 8;
|
||||||
AlgorithmType algorithmType = 9;
|
repeated Waypoint waypoints = 9;
|
||||||
int32 remoteness = 10;
|
AlgorithmType algorithmType = 10;
|
||||||
bool useProportion = 11;
|
int32 remoteness = 11;
|
||||||
int32 proportion = 12;
|
bool useProportion = 12;
|
||||||
bool useAzimuth = 13;
|
int32 proportion = 13;
|
||||||
int32 azimuthMargin = 14;
|
bool useAzimuth = 14;
|
||||||
float maxDetourDistanceRatio = 15;
|
int32 azimuthMargin = 15;
|
||||||
float maxDetourDurationRatio = 16;
|
float maxDetourDistanceRatio = 16;
|
||||||
int32 identifier = 22;
|
float maxDetourDurationRatio = 17;
|
||||||
optional int32 page = 23;
|
int32 identifier = 18;
|
||||||
optional int32 perPage = 24;
|
optional int32 page = 19;
|
||||||
|
optional int32 perPage = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ScheduleItem {
|
message ScheduleItem {
|
||||||
|
|
|
@ -15,22 +15,32 @@ export class MatchMapper {
|
||||||
private readonly outputDatetimeTransformer: DateTimeTransformerPort,
|
private readonly outputDatetimeTransformer: DateTimeTransformerPort,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
toResponse = (match: MatchEntity): MatchResponseDto => ({
|
toResponse = (match: MatchEntity): MatchResponseDto => {
|
||||||
...new ResponseBase(match),
|
return {
|
||||||
adId: match.getProps().adId,
|
...new ResponseBase(match),
|
||||||
role: match.getProps().role,
|
adId: match.getProps().adId,
|
||||||
frequency: match.getProps().frequency,
|
role: match.getProps().role,
|
||||||
distance: match.getProps().distance,
|
frequency: match.getProps().frequency,
|
||||||
duration: match.getProps().duration,
|
distance: match.getProps().distance,
|
||||||
initialDistance: match.getProps().initialDistance,
|
duration: match.getProps().duration,
|
||||||
initialDuration: match.getProps().initialDuration,
|
initialDistance: match.getProps().initialDistance,
|
||||||
distanceDetour: match.getProps().distanceDetour,
|
initialDuration: match.getProps().initialDuration,
|
||||||
durationDetour: match.getProps().durationDetour,
|
distanceDetour: match.getProps().distanceDetour,
|
||||||
distanceDetourPercentage: match.getProps().distanceDetourPercentage,
|
durationDetour: match.getProps().durationDetour,
|
||||||
durationDetourPercentage: match.getProps().durationDetourPercentage,
|
distanceDetourPercentage: match.getProps().distanceDetourPercentage,
|
||||||
journeys: match.getProps().journeys.map((journey: Journey) => ({
|
durationDetourPercentage: match.getProps().durationDetourPercentage,
|
||||||
day: new Date(
|
journeys: match.getProps().journeys.map((journey: Journey) => ({
|
||||||
this.outputDatetimeTransformer.fromDate(
|
day: new Date(
|
||||||
|
this.outputDatetimeTransformer.fromDate(
|
||||||
|
{
|
||||||
|
date: journey.firstDate.toISOString().split('T')[0],
|
||||||
|
time: journey.firstDriverDepartureTime(),
|
||||||
|
coordinates: journey.driverOrigin(),
|
||||||
|
},
|
||||||
|
match.getProps().frequency,
|
||||||
|
),
|
||||||
|
).getDay(),
|
||||||
|
firstDate: this.outputDatetimeTransformer.fromDate(
|
||||||
{
|
{
|
||||||
date: journey.firstDate.toISOString().split('T')[0],
|
date: journey.firstDate.toISOString().split('T')[0],
|
||||||
time: journey.firstDriverDepartureTime(),
|
time: journey.firstDriverDepartureTime(),
|
||||||
|
@ -38,41 +48,33 @@ export class MatchMapper {
|
||||||
},
|
},
|
||||||
match.getProps().frequency,
|
match.getProps().frequency,
|
||||||
),
|
),
|
||||||
).getDay(),
|
lastDate: this.outputDatetimeTransformer.fromDate(
|
||||||
firstDate: this.outputDatetimeTransformer.fromDate(
|
|
||||||
{
|
|
||||||
date: journey.firstDate.toISOString().split('T')[0],
|
|
||||||
time: journey.firstDriverDepartureTime(),
|
|
||||||
coordinates: journey.driverOrigin(),
|
|
||||||
},
|
|
||||||
match.getProps().frequency,
|
|
||||||
),
|
|
||||||
lastDate: this.outputDatetimeTransformer.fromDate(
|
|
||||||
{
|
|
||||||
date: journey.lastDate.toISOString().split('T')[0],
|
|
||||||
time: journey.firstDriverDepartureTime(),
|
|
||||||
coordinates: journey.driverOrigin(),
|
|
||||||
},
|
|
||||||
match.getProps().frequency,
|
|
||||||
),
|
|
||||||
steps: journey.journeyItems.map((journeyItem: JourneyItem) => ({
|
|
||||||
duration: journeyItem.duration,
|
|
||||||
distance: journeyItem.distance as number,
|
|
||||||
lon: journeyItem.lon,
|
|
||||||
lat: journeyItem.lat,
|
|
||||||
time: this.outputDatetimeTransformer.time(
|
|
||||||
{
|
{
|
||||||
date: journey.firstDate.toISOString().split('T')[0],
|
date: journey.lastDate.toISOString().split('T')[0],
|
||||||
time: journeyItem.driverTime(),
|
time: journey.firstDriverDepartureTime(),
|
||||||
coordinates: journey.driverOrigin(),
|
coordinates: journey.driverOrigin(),
|
||||||
},
|
},
|
||||||
match.getProps().frequency,
|
match.getProps().frequency,
|
||||||
),
|
),
|
||||||
actors: journeyItem.actorTimes.map((actorTime: ActorTime) => ({
|
steps: journey.journeyItems.map((journeyItem: JourneyItem) => ({
|
||||||
role: actorTime.role,
|
duration: journeyItem.duration,
|
||||||
target: actorTime.target,
|
distance: journeyItem.distance as number,
|
||||||
|
lon: journeyItem.lon,
|
||||||
|
lat: journeyItem.lat,
|
||||||
|
time: this.outputDatetimeTransformer.time(
|
||||||
|
{
|
||||||
|
date: journey.firstDate.toISOString().split('T')[0],
|
||||||
|
time: journeyItem.driverTime(),
|
||||||
|
coordinates: journey.driverOrigin(),
|
||||||
|
},
|
||||||
|
match.getProps().frequency,
|
||||||
|
),
|
||||||
|
actors: journeyItem.actorTimes.map((actorTime: ActorTime) => ({
|
||||||
|
role: actorTime.role,
|
||||||
|
target: actorTime.target,
|
||||||
|
})),
|
||||||
})),
|
})),
|
||||||
})),
|
})),
|
||||||
})),
|
};
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,234 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Mapper } from '@mobicoop/ddd-library';
|
import { Mapper } from '@mobicoop/ddd-library';
|
||||||
import { MatchingEntity } from './core/domain/matching.entity';
|
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()
|
@Injectable()
|
||||||
export class MatchingMapper
|
export class MatchingMapper
|
||||||
implements Mapper<MatchingEntity, string, string, undefined>
|
implements Mapper<MatchingEntity, string, string, undefined>
|
||||||
{
|
{
|
||||||
toPersistence = (entity: MatchingEntity): string => JSON.stringify(entity);
|
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 =>
|
toDomain = (record: string): MatchingEntity => {
|
||||||
new MatchingEntity(JSON.parse(record));
|
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;
|
||||||
|
};
|
||||||
|
|
|
@ -16,6 +16,8 @@ import {
|
||||||
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
import { AlgorithmType } from '@modules/ad/core/application/types/algorithm.types';
|
||||||
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
|
import { Waypoint } from '@modules/ad/core/application/types/waypoint.type';
|
||||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||||
|
import { Target } from '@modules/ad/core/domain/candidate.types';
|
||||||
|
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||||
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
@ -76,7 +78,156 @@ const mockAdRepository = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockMatchingRepository: MatchingRepositoryPort = {
|
const mockMatchingRepository: MatchingRepositoryPort = {
|
||||||
get: jest.fn(),
|
get: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementationOnce(
|
||||||
|
() =>
|
||||||
|
new MatchingEntity({
|
||||||
|
id: 'a3b10efb-121e-4d08-9198-9f57afdb5e2d',
|
||||||
|
createdAt: new Date('2023-08-20T09:48:00Z'),
|
||||||
|
updatedAt: new Date('2023-08-20T09:48:00Z'),
|
||||||
|
props: {
|
||||||
|
matches: [
|
||||||
|
new MatchEntity({
|
||||||
|
id: '4bd4e90b-ffba-4f5f-b904-48ad0667a1d7',
|
||||||
|
createdAt: new Date('2023-08-30T08:45:00Z'),
|
||||||
|
updatedAt: new Date('2023-08-30T08:45:00Z'),
|
||||||
|
props: {
|
||||||
|
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||||
|
role: Role.DRIVER,
|
||||||
|
frequency: Frequency.PUNCTUAL,
|
||||||
|
distance: 356041,
|
||||||
|
duration: 12647,
|
||||||
|
initialDistance: 348745,
|
||||||
|
initialDuration: 12105,
|
||||||
|
distanceDetour: 7296,
|
||||||
|
durationDetour: 542,
|
||||||
|
distanceDetourPercentage: 4.1,
|
||||||
|
durationDetourPercentage: 3.8,
|
||||||
|
journeys: [
|
||||||
|
{
|
||||||
|
firstDate: new Date('2023-08-28'),
|
||||||
|
lastDate: new Date('2023-08-28'),
|
||||||
|
journeyItems: [
|
||||||
|
{
|
||||||
|
lon: 6.389745,
|
||||||
|
lat: 48.32644,
|
||||||
|
duration: 0,
|
||||||
|
distance: 0,
|
||||||
|
actorTimes: [
|
||||||
|
{
|
||||||
|
role: Role.DRIVER,
|
||||||
|
target: Target.START,
|
||||||
|
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date(
|
||||||
|
'2023-08-28T06:45:00Z',
|
||||||
|
),
|
||||||
|
firstMaxDatetime: new Date(
|
||||||
|
'2023-08-28T07:15:00Z',
|
||||||
|
),
|
||||||
|
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: Role.PASSENGER,
|
||||||
|
target: Target.START,
|
||||||
|
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date(
|
||||||
|
'2023-08-28T06:45:00Z',
|
||||||
|
),
|
||||||
|
firstMaxDatetime: new Date(
|
||||||
|
'2023-08-28T07:15:00Z',
|
||||||
|
),
|
||||||
|
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 6.984567,
|
||||||
|
lat: 48.021548,
|
||||||
|
distance: 356041,
|
||||||
|
duration: 12647,
|
||||||
|
actorTimes: [
|
||||||
|
{
|
||||||
|
role: Role.DRIVER,
|
||||||
|
target: Target.FINISH,
|
||||||
|
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date(
|
||||||
|
'2023-08-28T06:45:00Z',
|
||||||
|
),
|
||||||
|
firstMaxDatetime: new Date(
|
||||||
|
'2023-08-28T07:15:00Z',
|
||||||
|
),
|
||||||
|
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: Role.PASSENGER,
|
||||||
|
target: Target.FINISH,
|
||||||
|
firstDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date(
|
||||||
|
'2023-08-28T06:45:00Z',
|
||||||
|
),
|
||||||
|
firstMaxDatetime: new Date(
|
||||||
|
'2023-08-28T07:15:00Z',
|
||||||
|
),
|
||||||
|
lastDatetime: new Date('2023-08-28T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-08-28T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-08-28T07:15:00Z'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
query: {
|
||||||
|
driver: false,
|
||||||
|
passenger: true,
|
||||||
|
frequency: Frequency.PUNCTUAL,
|
||||||
|
fromDate: '2023-08-28',
|
||||||
|
toDate: '2023-08-28',
|
||||||
|
schedule: [
|
||||||
|
{
|
||||||
|
day: 1,
|
||||||
|
time: '06:40',
|
||||||
|
margin: 900,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
seatsProposed: 3,
|
||||||
|
seatsRequested: 1,
|
||||||
|
strict: true,
|
||||||
|
waypoints: [
|
||||||
|
{
|
||||||
|
lon: 6.389745,
|
||||||
|
lat: 48.32644,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 6.984567,
|
||||||
|
lat: 48.021548,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
algorithmType: 'PASSENGER_ORIENTED',
|
||||||
|
remoteness: 15000,
|
||||||
|
useProportion: true,
|
||||||
|
proportion: 0.3,
|
||||||
|
useAzimuth: true,
|
||||||
|
azimuthMargin: 10,
|
||||||
|
maxDetourDistanceRatio: 0.3,
|
||||||
|
maxDetourDurationRatio: 0.3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error();
|
||||||
|
}),
|
||||||
save: jest.fn(),
|
save: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -151,6 +302,10 @@ describe('Match Query Handler', () => {
|
||||||
matchQueryHandler = module.get<MatchQueryHandler>(MatchQueryHandler);
|
matchQueryHandler = module.get<MatchQueryHandler>(MatchQueryHandler);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
it('should be defined', () => {
|
it('should be defined', () => {
|
||||||
expect(matchQueryHandler).toBeDefined();
|
expect(matchQueryHandler).toBeDefined();
|
||||||
});
|
});
|
||||||
|
@ -183,4 +338,64 @@ describe('Match Query Handler', () => {
|
||||||
expect(matching.id).toHaveLength(36);
|
expect(matching.id).toHaveLength(36);
|
||||||
expect(MatchingEntity.create).toHaveBeenCalledTimes(1);
|
expect(MatchingEntity.create).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return a valid saved Matching', async () => {
|
||||||
|
jest.spyOn(MatchingEntity, 'create');
|
||||||
|
const matchQuery = new MatchQuery(
|
||||||
|
{
|
||||||
|
id: 'a3b10efb-121e-4d08-9198-9f57afdb5e2d',
|
||||||
|
algorithmType: AlgorithmType.PASSENGER_ORIENTED,
|
||||||
|
driver: false,
|
||||||
|
passenger: true,
|
||||||
|
frequency: Frequency.PUNCTUAL,
|
||||||
|
fromDate: '2023-08-28',
|
||||||
|
toDate: '2023-08-28',
|
||||||
|
schedule: [
|
||||||
|
{
|
||||||
|
time: '07:05',
|
||||||
|
day: 1,
|
||||||
|
margin: 900,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
strict: false,
|
||||||
|
waypoints: [originWaypoint, destinationWaypoint],
|
||||||
|
},
|
||||||
|
mockRouteProvider,
|
||||||
|
);
|
||||||
|
const matching: MatchingResult = await matchQueryHandler.execute(
|
||||||
|
matchQuery,
|
||||||
|
);
|
||||||
|
expect(matching.id).toBe('a3b10efb-121e-4d08-9198-9f57afdb5e2d');
|
||||||
|
expect(MatchingEntity.create).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a new matching if saved Matching is not found', async () => {
|
||||||
|
jest.spyOn(MatchingEntity, 'create');
|
||||||
|
const matchQuery = new MatchQuery(
|
||||||
|
{
|
||||||
|
id: 'a3b10efb-121e-4d08-9198-9f57afdb5e2d',
|
||||||
|
algorithmType: AlgorithmType.PASSENGER_ORIENTED,
|
||||||
|
driver: false,
|
||||||
|
passenger: true,
|
||||||
|
frequency: Frequency.PUNCTUAL,
|
||||||
|
fromDate: '2023-08-28',
|
||||||
|
toDate: '2023-08-28',
|
||||||
|
schedule: [
|
||||||
|
{
|
||||||
|
time: '07:05',
|
||||||
|
day: 1,
|
||||||
|
margin: 900,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
strict: false,
|
||||||
|
waypoints: [originWaypoint, destinationWaypoint],
|
||||||
|
},
|
||||||
|
mockRouteProvider,
|
||||||
|
);
|
||||||
|
const matching: MatchingResult = await matchQueryHandler.execute(
|
||||||
|
matchQuery,
|
||||||
|
);
|
||||||
|
expect(matching.id).toHaveLength(36);
|
||||||
|
expect(MatchingEntity.create).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { getRedisToken } from '@liaoliaots/nestjs-redis';
|
import { getRedisToken } from '@liaoliaots/nestjs-redis';
|
||||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||||
import { Target } from '@modules/ad/core/domain/candidate.types';
|
import { Target } from '@modules/ad/core/domain/candidate.types';
|
||||||
|
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||||
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
||||||
import { MatchingNotFoundException } from '@modules/ad/core/domain/matching.errors';
|
import { MatchingNotFoundException } from '@modules/ad/core/domain/matching.errors';
|
||||||
import { MatchingRepository } from '@modules/ad/infrastructure/matching.repository';
|
import { MatchingRepository } from '@modules/ad/infrastructure/matching.repository';
|
||||||
|
@ -52,7 +53,7 @@ const matchingEntity: MatchingEntity = new MatchingEntity({
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
props: {
|
props: {
|
||||||
matches: [
|
matches: [
|
||||||
{
|
MatchEntity.create({
|
||||||
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||||
role: Role.DRIVER,
|
role: Role.DRIVER,
|
||||||
frequency: Frequency.PUNCTUAL,
|
frequency: Frequency.PUNCTUAL,
|
||||||
|
@ -60,10 +61,6 @@ const matchingEntity: MatchingEntity = new MatchingEntity({
|
||||||
duration: 12647,
|
duration: 12647,
|
||||||
initialDistance: 348745,
|
initialDistance: 348745,
|
||||||
initialDuration: 12105,
|
initialDuration: 12105,
|
||||||
distanceDetour: 7296,
|
|
||||||
durationDetour: 542,
|
|
||||||
distanceDetourPercentage: 4.1,
|
|
||||||
durationDetourPercentage: 3.8,
|
|
||||||
journeys: [
|
journeys: [
|
||||||
{
|
{
|
||||||
firstDate: new Date('2023-09-01'),
|
firstDate: new Date('2023-09-01'),
|
||||||
|
@ -91,7 +88,7 @@ const matchingEntity: MatchingEntity = new MatchingEntity({
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// ...
|
// ...
|
||||||
},
|
}),
|
||||||
],
|
],
|
||||||
query: {
|
query: {
|
||||||
driver: false,
|
driver: false,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
|
||||||
import { Target } from '@modules/ad/core/domain/candidate.types';
|
import { Target } from '@modules/ad/core/domain/candidate.types';
|
||||||
|
import { MatchEntity } from '@modules/ad/core/domain/match.entity';
|
||||||
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
import { MatchingEntity } from '@modules/ad/core/domain/matching.entity';
|
||||||
import { MatchingMapper } from '@modules/ad/matching.mapper';
|
import { MatchingMapper } from '@modules/ad/matching.mapper';
|
||||||
import { Test } from '@nestjs/testing';
|
import { Test } from '@nestjs/testing';
|
||||||
|
@ -25,46 +26,88 @@ describe('Matching Mapper', () => {
|
||||||
updatedAt: new Date('2023-08-20T09:48:00Z'),
|
updatedAt: new Date('2023-08-20T09:48:00Z'),
|
||||||
props: {
|
props: {
|
||||||
matches: [
|
matches: [
|
||||||
{
|
new MatchEntity({
|
||||||
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
id: '4bd4e90b-ffba-4f5f-b904-48ad0667a1d7',
|
||||||
role: Role.DRIVER,
|
createdAt: new Date('2023-08-30T08:45:00Z'),
|
||||||
frequency: Frequency.PUNCTUAL,
|
updatedAt: new Date('2023-08-30T08:45:00Z'),
|
||||||
distance: 356041,
|
props: {
|
||||||
duration: 12647,
|
adId: 'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||||
initialDistance: 348745,
|
role: Role.DRIVER,
|
||||||
initialDuration: 12105,
|
frequency: Frequency.PUNCTUAL,
|
||||||
distanceDetour: 7296,
|
distance: 356041,
|
||||||
durationDetour: 542,
|
duration: 12647,
|
||||||
distanceDetourPercentage: 4.1,
|
initialDistance: 348745,
|
||||||
durationDetourPercentage: 3.8,
|
initialDuration: 12105,
|
||||||
journeys: [
|
distanceDetour: 7296,
|
||||||
{
|
durationDetour: 542,
|
||||||
firstDate: new Date('2023-09-01'),
|
distanceDetourPercentage: 4.1,
|
||||||
lastDate: new Date('2023-09-01'),
|
durationDetourPercentage: 3.8,
|
||||||
journeyItems: [
|
journeys: [
|
||||||
{
|
{
|
||||||
lon: 6.35484,
|
firstDate: new Date('2023-09-01'),
|
||||||
lat: 48.26587,
|
lastDate: new Date('2023-09-01'),
|
||||||
duration: 0,
|
journeyItems: [
|
||||||
distance: 0,
|
{
|
||||||
actorTimes: [
|
lon: 6.389745,
|
||||||
{
|
lat: 48.32644,
|
||||||
role: Role.DRIVER,
|
duration: 0,
|
||||||
target: Target.START,
|
distance: 0,
|
||||||
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
actorTimes: [
|
||||||
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
{
|
||||||
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
role: Role.DRIVER,
|
||||||
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
target: Target.START,
|
||||||
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
},
|
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
],
|
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
},
|
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
],
|
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
// ...
|
role: Role.PASSENGER,
|
||||||
},
|
target: Target.START,
|
||||||
|
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
|
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
|
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lon: 6.984567,
|
||||||
|
lat: 48.021548,
|
||||||
|
distance: 356041,
|
||||||
|
duration: 12647,
|
||||||
|
actorTimes: [
|
||||||
|
{
|
||||||
|
role: Role.DRIVER,
|
||||||
|
target: Target.FINISH,
|
||||||
|
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
|
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
|
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: Role.PASSENGER,
|
||||||
|
target: Target.FINISH,
|
||||||
|
firstDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
|
firstMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
|
firstMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
|
lastDatetime: new Date('2023-09-01T07:00:00Z'),
|
||||||
|
lastMinDatetime: new Date('2023-09-01T06:45:00Z'),
|
||||||
|
lastMaxDatetime: new Date('2023-09-01T07:15:00Z'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
query: {
|
query: {
|
||||||
driver: false,
|
driver: false,
|
||||||
|
@ -105,14 +148,17 @@ describe('Matching Mapper', () => {
|
||||||
});
|
});
|
||||||
const mapped: string = matchingMapper.toPersistence(matchingEntity);
|
const mapped: string = matchingMapper.toPersistence(matchingEntity);
|
||||||
expect(mapped).toBe(
|
expect(mapped).toBe(
|
||||||
'{"_id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","_createdAt":"2023-08-20T09:48:00.000Z","_updatedAt":"2023-08-20T09:48:00.000Z","props":{"matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.35484,"lat":48.26587,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}},"_domainEvents":[]}',
|
'{"id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","createdAt":"2023-08-20T09:48:00.000Z","updatedAt":"2023-08-20T09:48:00.000Z","matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.389745,"lat":48.32644,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]},{"lon":6.984567,"lat":48.021548,"duration":12647,"distance":356041,"actorTimes":[{"role":"DRIVER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}}',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should map persisted string to domain entity', async () => {
|
it('should map persisted string to domain entity', async () => {
|
||||||
const matchingEntity: MatchingEntity = matchingMapper.toDomain(
|
const matchingEntity: MatchingEntity = matchingMapper.toDomain(
|
||||||
'{"_id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","_createdAt":"2023-08-20T09:48:00.000Z","_updatedAt":"2023-08-20T09:48:00.000Z","props":{"matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.35484,"lat":48.26587,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}},"_domainEvents":[]}',
|
'{"id":"644a7cb3-6436-4db5-850d-b4c7421d4b97","createdAt":"2023-08-20T09:48:00.000Z","updatedAt":"2023-08-20T09:48:00.000Z","matches":[{"adId":"dd937edf-1264-4868-b073-d1952abe30b1","role":"DRIVER","frequency":"PUNCTUAL","distance":356041,"duration":12647,"initialDistance":348745,"initialDuration":12105,"distanceDetour":7296,"durationDetour":542,"distanceDetourPercentage":4.1,"durationDetourPercentage":3.8,"journeys":[{"firstDate":"2023-09-01T00:00:00.000Z","lastDate":"2023-09-01T00:00:00.000Z","journeyItems":[{"lon":6.389745,"lat":48.32644,"duration":0,"distance":0,"actorTimes":[{"role":"DRIVER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"START","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]},{"lon":6.984567,"lat":48.021548,"duration":12647,"distance":356041,"actorTimes":[{"role":"DRIVER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"},{"role":"PASSENGER","target":"FINISH","firstDatetime":"2023-09-01T07:00:00.000Z","firstMinDatetime":"2023-09-01T06:45:00.000Z","firstMaxDatetime":"2023-09-01T07:15:00.000Z","lastDatetime":"2023-09-01T07:00:00.000Z","lastMinDatetime":"2023-09-01T06:45:00.000Z","lastMaxDatetime":"2023-09-01T07:15:00.000Z"}]}]}]}],"query":{"driver":false,"passenger":true,"frequency":"PUNCTUAL","fromDate":"2023-09-01","toDate":"2023-09-01","schedule":[{"day":5,"time":"06:40","margin":900}],"seatsProposed":3,"seatsRequested":1,"strict":true,"waypoints":[{"lon":6.389745,"lat":48.32644},{"lon":6.984567,"lat":48.021548}],"algorithmType":"PASSENGER_ORIENTED","remoteness":15000,"useProportion":true,"proportion":0.3,"useAzimuth":true,"azimuthMargin":10,"maxDetourDistanceRatio":0.3,"maxDetourDurationRatio":0.3}}',
|
||||||
);
|
);
|
||||||
expect(matchingEntity.getProps().query.fromDate).toBe('2023-09-01');
|
expect(matchingEntity.getProps().query.fromDate).toBe('2023-09-01');
|
||||||
|
expect(matchingEntity.getProps().matches[0].getProps().adId).toBe(
|
||||||
|
'dd937edf-1264-4868-b073-d1952abe30b1',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue