151 lines
5.4 KiB
TypeScript
151 lines
5.4 KiB
TypeScript
import { CommandHandler } from '@nestjs/cqrs';
|
|
import { CreateAdCommand } from '../../commands/create-ad.command';
|
|
import { Ad } from '../entities/ad';
|
|
import { AdRepository } from '../../adapters/secondaries/ad.repository';
|
|
import { InjectMapper } from '@automapper/nestjs';
|
|
import { Mapper } from '@automapper/core';
|
|
import { CreateAdRequest } from '../dtos/create-ad.request';
|
|
import { Inject } from '@nestjs/common';
|
|
import { IProvideParams } from '../interfaces/params-provider.interface';
|
|
import { ICreateGeorouter } from '../../../geography/domain/interfaces/georouter-creator.interface';
|
|
import { IFindTimezone } from '../../../geography/domain/interfaces/timezone-finder.interface';
|
|
import { IGeorouter } from '../../../geography/domain/interfaces/georouter.interface';
|
|
import { DefaultParams } from '../types/default-params.type';
|
|
import { Role } from '../types/role.enum';
|
|
import { Geography } from '../entities/geography';
|
|
import { IEncodeDirection } from '../../../geography/domain/interfaces/direction-encoder.interface';
|
|
import { TimeConverter } from '../entities/time-converter';
|
|
import { Coordinate } from '../../../geography/domain/entities/coordinate';
|
|
import {
|
|
DIRECTION_ENCODER,
|
|
GEOROUTER_CREATOR,
|
|
PARAMS_PROVIDER,
|
|
TIMEZONE_FINDER,
|
|
} from '../../ad.constants';
|
|
|
|
@CommandHandler(CreateAdCommand)
|
|
export class CreateAdUseCase {
|
|
private readonly georouter: IGeorouter;
|
|
private readonly defaultParams: DefaultParams;
|
|
private timezone: string;
|
|
private roles: Role[];
|
|
private geography: Geography;
|
|
private ad: Ad;
|
|
|
|
constructor(
|
|
@InjectMapper() private readonly mapper: Mapper,
|
|
private readonly adRepository: AdRepository,
|
|
@Inject(PARAMS_PROVIDER)
|
|
private readonly defaultParamsProvider: IProvideParams,
|
|
@Inject(GEOROUTER_CREATOR)
|
|
private readonly georouterCreator: ICreateGeorouter,
|
|
@Inject(TIMEZONE_FINDER)
|
|
private readonly timezoneFinder: IFindTimezone,
|
|
@Inject(DIRECTION_ENCODER)
|
|
private readonly directionEncoder: IEncodeDirection,
|
|
) {
|
|
this.defaultParams = defaultParamsProvider.getParams();
|
|
this.georouter = georouterCreator.create(
|
|
this.defaultParams.GEOROUTER_TYPE,
|
|
this.defaultParams.GEOROUTER_URL,
|
|
);
|
|
}
|
|
|
|
async execute(command: CreateAdCommand): Promise<Ad> {
|
|
try {
|
|
this.ad = this.mapper.map(command.createAdRequest, CreateAdRequest, Ad);
|
|
this.setTimezone(command.createAdRequest.addresses);
|
|
this.setGeography(command.createAdRequest.addresses);
|
|
this.setRoles(command.createAdRequest);
|
|
await this.geography.createRoutes(this.roles, this.georouter, {
|
|
withDistance: false,
|
|
withPoints: true,
|
|
withTime: false,
|
|
});
|
|
this.setAdGeography(command);
|
|
this.setAdSchedule(command);
|
|
return await this.adRepository.createAd(this.ad);
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
private setTimezone = (coordinates: Coordinate[]): void => {
|
|
this.timezone = this.defaultParams.DEFAULT_TIMEZONE;
|
|
try {
|
|
const timezones = this.timezoneFinder.timezones(
|
|
coordinates[0].lon,
|
|
coordinates[0].lat,
|
|
);
|
|
if (timezones.length > 0) this.timezone = timezones[0];
|
|
} catch (e) {}
|
|
};
|
|
|
|
private setRoles = (createAdRequest: CreateAdRequest): void => {
|
|
this.roles = [];
|
|
if (createAdRequest.driver) this.roles.push(Role.DRIVER);
|
|
if (createAdRequest.passenger) this.roles.push(Role.PASSENGER);
|
|
};
|
|
|
|
private setGeography = (coordinates: Coordinate[]): void => {
|
|
this.geography = new Geography(coordinates);
|
|
};
|
|
|
|
private setAdGeography = (command: CreateAdCommand): void => {
|
|
this.ad.driverDistance = this.geography.driverRoute?.distance;
|
|
this.ad.driverDuration = this.geography.driverRoute?.duration;
|
|
this.ad.passengerDistance = this.geography.passengerRoute?.distance;
|
|
this.ad.passengerDuration = this.geography.passengerRoute?.duration;
|
|
this.ad.fwdAzimuth = this.geography.driverRoute
|
|
? this.geography.driverRoute.fwdAzimuth
|
|
: this.geography.passengerRoute.fwdAzimuth;
|
|
this.ad.backAzimuth = this.geography.driverRoute
|
|
? this.geography.driverRoute.backAzimuth
|
|
: this.geography.passengerRoute.backAzimuth;
|
|
this.ad.waypoints = this.directionEncoder.encode(
|
|
command.createAdRequest.addresses,
|
|
);
|
|
this.ad.direction = this.geography.driverRoute
|
|
? this.directionEncoder.encode(this.geography.driverRoute.points)
|
|
: undefined;
|
|
};
|
|
|
|
private setAdSchedule = (command: CreateAdCommand): void => {
|
|
this.ad.monTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.monTime,
|
|
this.timezone,
|
|
);
|
|
this.ad.tueTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.tueTime,
|
|
this.timezone,
|
|
);
|
|
this.ad.wedTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.wedTime,
|
|
this.timezone,
|
|
);
|
|
this.ad.thuTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.thuTime,
|
|
this.timezone,
|
|
);
|
|
this.ad.friTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.friTime,
|
|
this.timezone,
|
|
);
|
|
this.ad.satTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.satTime,
|
|
this.timezone,
|
|
);
|
|
this.ad.sunTime = TimeConverter.toUtcDatetime(
|
|
this.ad.fromDate,
|
|
command.createAdRequest.sunTime,
|
|
this.timezone,
|
|
);
|
|
};
|
|
}
|