This commit is contained in:
sbriat
2023-05-11 17:47:55 +02:00
parent 2a2cfa5c0f
commit da96f52c1e
69 changed files with 1700 additions and 492 deletions

View File

@@ -3,15 +3,17 @@ import {
ArrayMinSize,
IsArray,
IsBoolean,
IsDate,
IsEnum,
IsMilitaryTime,
IsNotEmpty,
IsNumber,
IsOptional,
IsString,
} from 'class-validator';
import { PointType } from '../../../geography/domain/types/point-type.enum';
import { Frequency } from '../types/frequency.enum';
import { Coordinates } from '../../../geography/domain/entities/coordinates';
import { Type } from 'class-transformer';
export class CreateAdRequest {
@IsString()
@@ -19,6 +21,11 @@ export class CreateAdRequest {
@AutoMap()
uuid: string;
@IsString()
@IsNotEmpty()
@AutoMap()
userUuid: string;
@IsBoolean()
@AutoMap()
driver: boolean;
@@ -27,53 +34,54 @@ export class CreateAdRequest {
@AutoMap()
passenger: boolean;
@IsNotEmpty()
@IsEnum(Frequency)
@AutoMap()
frequency: Frequency;
@IsString()
@Type(() => Date)
@IsDate()
@AutoMap()
fromDate: string;
fromDate: Date;
@IsString()
@Type(() => Date)
@IsDate()
@AutoMap()
toDate: string;
toDate: Date;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
monTime?: string | null;
monTime?: string;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
tueTime?: string | null;
tueTime?: string;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
wedTime?: string | null;
wedTime?: string;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
thuTime?: string | null;
thuTime?: string;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
friTime?: string | null;
friTime?: string;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
satTime?: string | null;
satTime?: string;
@IsOptional()
@IsString()
@IsMilitaryTime()
@AutoMap()
sunTime?: string | null;
sunTime?: string;
@IsNumber()
@AutoMap()
@@ -103,19 +111,33 @@ export class CreateAdRequest {
@AutoMap()
sunMargin: number;
@IsEnum(PointType)
@AutoMap()
originType: PointType;
@IsEnum(PointType)
@AutoMap()
destinationType: PointType;
@Type(() => Coordinates)
@IsArray()
@ArrayMinSize(2)
@AutoMap(() => [Coordinates])
waypoints: Coordinates[];
@AutoMap()
driverDuration?: number;
@AutoMap()
driverDistance?: number;
@AutoMap()
passengerDuration?: number;
@AutoMap()
passengerDistance?: number;
@AutoMap()
direction: string;
@AutoMap()
fwdAzimuth: number;
@AutoMap()
backAzimuth: number;
@IsNumber()
@AutoMap()
seatsDriver: number;
@@ -129,13 +151,9 @@ export class CreateAdRequest {
@AutoMap()
seatsUsed?: number;
@IsString()
@IsBoolean()
@AutoMap()
createdAt: string;
@IsString()
@AutoMap()
updatedAt: string;
strict: boolean;
timezone?: string;
}

View File

@@ -0,0 +1,7 @@
import { Ad } from './ad';
export class AdCompleter {
complete = async (ad: Ad): Promise<Ad> => {
return ad;
};
}

View File

@@ -1,6 +1,6 @@
import { AutoMap } from '@automapper/classes';
import { PointType } from '../../../geography/domain/types/point-type.enum';
import { Coordinates } from '../../../geography/domain/entities/coordinates';
import { Frequency } from '../types/frequency.enum';
export class Ad {
@AutoMap()
@@ -13,7 +13,7 @@ export class Ad {
passenger: boolean;
@AutoMap()
frequency: number;
frequency: Frequency;
@AutoMap()
fromDate: Date;
@@ -64,22 +64,16 @@ export class Ad {
sunMargin: number;
@AutoMap()
driverDuration: number;
driverDuration?: number;
@AutoMap()
driverDistance: number;
driverDistance?: number;
@AutoMap()
passengerDuration: number;
passengerDuration?: number;
@AutoMap()
passengerDistance: number;
@AutoMap()
originType: PointType;
@AutoMap()
destinationType: PointType;
passengerDistance?: number;
@AutoMap(() => [Coordinates])
waypoints: Coordinates[];
@@ -102,6 +96,9 @@ export class Ad {
@AutoMap()
seatsUsed: number;
@AutoMap()
strict: boolean;
@AutoMap()
createdAt: Date;

View File

@@ -0,0 +1,98 @@
import { Coordinates } from '../../../geography/domain/entities/coordinates';
import { Route } from '../../../geography/domain/entities/route';
import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface';
import { Role } from '../types/role.enum';
import { IGeorouter } from '../../../geography/domain/interfaces/georouter.interface';
import { Path } from '../../../geography/domain/types/path.type';
import { Timezoner } from '../../../geography/domain/types/timezoner';
export class Geography {
private points: Coordinates[];
timezones: string[];
driverRoute: Route;
passengerRoute: Route;
timezoneFinder: IFindTimezone;
constructor(points: Coordinates[], timezoner: Timezoner) {
this.points = points;
this.timezones = [timezoner.timezone];
this.timezoneFinder = timezoner.finder;
this.setTimezones();
}
createRoutes = async (
roles: Role[],
georouter: IGeorouter,
): Promise<void> => {
const paths: Path[] = [];
if (roles.includes(Role.DRIVER) && roles.includes(Role.PASSENGER)) {
if (this.points.length == 2) {
// 2 points => same route for driver and passenger
const commonPath: Path = {
key: RouteKey.COMMON,
points: this.points,
};
paths.push(commonPath);
} else {
const driverPath: Path = {
key: RouteKey.DRIVER,
points: this.points,
};
const passengerPath: Path = {
key: RouteKey.PASSENGER,
points: [this.points[0], this.points[this.points.length - 1]],
};
paths.push(driverPath, passengerPath);
}
} else if (roles.includes(Role.DRIVER)) {
const driverPath: Path = {
key: RouteKey.DRIVER,
points: this.points,
};
paths.push(driverPath);
} else if (roles.includes(Role.PASSENGER)) {
const passengerPath: Path = {
key: RouteKey.PASSENGER,
points: [this.points[0], this.points[this.points.length - 1]],
};
paths.push(passengerPath);
}
const routes = await georouter.route(paths, {
withDistance: false,
withPoints: false,
withTime: false,
});
if (routes.some((route) => route.key == RouteKey.COMMON)) {
this.driverRoute = routes.find(
(route) => route.key == RouteKey.COMMON,
).route;
this.passengerRoute = routes.find(
(route) => route.key == RouteKey.COMMON,
).route;
} else {
if (routes.some((route) => route.key == RouteKey.DRIVER)) {
this.driverRoute = routes.find(
(route) => route.key == RouteKey.DRIVER,
).route;
}
if (routes.some((route) => route.key == RouteKey.PASSENGER)) {
this.passengerRoute = routes.find(
(route) => route.key == RouteKey.PASSENGER,
).route;
}
}
};
private setTimezones = (): void => {
this.timezones = this.timezoneFinder.timezones(
this.points[0].lat,
this.points[0].lon,
);
};
}
export enum RouteKey {
COMMON = 'common',
DRIVER = 'driver',
PASSENGER = 'passenger',
}

View File

@@ -1,14 +1,14 @@
import { DateTime, TimeZone } from 'timezonecomplete';
export class TimeConverter {
static toUtcDatetime = (
date: string,
time: string,
timezone: string,
): Date => {
static toUtcDatetime = (date: Date, time: string, timezone: string): Date => {
try {
if (!date || !time || !timezone) throw new Error();
return new Date(
new DateTime(`${date}T${time}:00`, TimeZone.zone(timezone, false))
new DateTime(
`${date.toISOString().split('T')[0]}T${time}:00`,
TimeZone.zone(timezone, false),
)
.convert(TimeZone.zone('UTC'))
.toIsoString(),
);

View File

@@ -0,0 +1,5 @@
export type IDefaultParams = {
DEFAULT_TIMEZONE: string;
GEOROUTER_TYPE: string;
GEOROUTER_URL: string;
};

View File

@@ -1,4 +1,4 @@
export enum Frequency {
PUNCTUAL = 1,
RECURRENT = 2,
PUNCTUAL = 'PUNCTUAL',
RECURRENT = 'RECURRENT',
}

View File

@@ -0,0 +1,4 @@
export enum Role {
DRIVER = 'DRIVER',
PASSENGER = 'PASSENGER',
}

View File

@@ -20,6 +20,16 @@ export class CreateAdUseCase {
CreateAdRequest,
Ad,
);
adToCreate.driverDistance = command.geography.driverRoute?.distance;
adToCreate.driverDuration = command.geography.driverRoute?.duration;
adToCreate.passengerDistance = command.geography.passengerRoute?.distance;
adToCreate.passengerDuration = command.geography.passengerRoute?.duration;
adToCreate.fwdAzimuth = command.geography.driverRoute
? command.geography.driverRoute.fwdAzimuth
: command.geography.passengerRoute.fwdAzimuth;
adToCreate.backAzimuth = command.geography.driverRoute
? command.geography.driverRoute.backAzimuth
: command.geography.passengerRoute.backAzimuth;
return adToCreate;
// return await this.adRepository.createAd(adToCreate);
} catch (error) {