131 lines
4.1 KiB
TypeScript
131 lines
4.1 KiB
TypeScript
import { Inject, Injectable } from '@nestjs/common';
|
|
import { AdEntity } from './core/domain/ad.entity';
|
|
import {
|
|
AdWriteModel,
|
|
AdReadModel,
|
|
ScheduleItemModel,
|
|
AdWriteExtraModel,
|
|
} from './infrastructure/ad.repository';
|
|
import { v4 } from 'uuid';
|
|
import {
|
|
ScheduleItem,
|
|
ScheduleItemProps,
|
|
} from './core/domain/value-objects/schedule-item.value-object';
|
|
import { DirectionEncoderPort } from '@modules/geography/core/application/ports/direction-encoder.port';
|
|
import { AD_DIRECTION_ENCODER } from './ad.di-tokens';
|
|
import { ExtendedMapper } from '@mobicoop/ddd-library';
|
|
|
|
/**
|
|
* Mapper constructs objects that are used in different layers:
|
|
* Record is an object that is stored in a database,
|
|
* Entity is an object that is used in application domain layer,
|
|
* and a ResponseDTO is an object returned to a user (usually as json).
|
|
*/
|
|
|
|
@Injectable()
|
|
export class AdMapper
|
|
implements
|
|
ExtendedMapper<
|
|
AdEntity,
|
|
AdReadModel,
|
|
AdWriteModel,
|
|
AdWriteExtraModel,
|
|
undefined
|
|
>
|
|
{
|
|
constructor(
|
|
@Inject(AD_DIRECTION_ENCODER)
|
|
private readonly directionEncoder: DirectionEncoderPort,
|
|
) {}
|
|
|
|
toPersistence = (entity: AdEntity): AdWriteModel => {
|
|
const copy = entity.getProps();
|
|
const now = new Date();
|
|
const record: AdWriteModel = {
|
|
uuid: copy.id,
|
|
driver: copy.driver,
|
|
passenger: copy.passenger,
|
|
frequency: copy.frequency,
|
|
fromDate: new Date(copy.fromDate),
|
|
toDate: new Date(copy.toDate),
|
|
schedule: {
|
|
create: copy.schedule.map((scheduleItem: ScheduleItemProps) => ({
|
|
uuid: v4(),
|
|
day: scheduleItem.day,
|
|
time: new Date(
|
|
1970,
|
|
0,
|
|
1,
|
|
parseInt(scheduleItem.time.split(':')[0]),
|
|
parseInt(scheduleItem.time.split(':')[1]),
|
|
),
|
|
margin: scheduleItem.margin,
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
})),
|
|
},
|
|
seatsProposed: copy.seatsProposed,
|
|
seatsRequested: copy.seatsRequested,
|
|
strict: copy.strict,
|
|
driverDuration: copy.driverDuration,
|
|
driverDistance: copy.driverDistance,
|
|
passengerDuration: copy.passengerDuration,
|
|
passengerDistance: copy.passengerDistance,
|
|
fwdAzimuth: copy.fwdAzimuth,
|
|
backAzimuth: copy.backAzimuth,
|
|
createdAt: copy.createdAt,
|
|
updatedAt: copy.updatedAt,
|
|
};
|
|
return record;
|
|
};
|
|
|
|
toDomain = (record: AdReadModel): AdEntity =>
|
|
new AdEntity({
|
|
id: record.uuid,
|
|
createdAt: new Date(record.createdAt),
|
|
updatedAt: new Date(record.updatedAt),
|
|
props: {
|
|
seatsProposed: record.seatsProposed,
|
|
seatsRequested: record.seatsRequested,
|
|
strict: record.strict,
|
|
driverDuration: record.driverDuration,
|
|
driverDistance: record.driverDistance,
|
|
passengerDuration: record.passengerDuration,
|
|
passengerDistance: record.passengerDistance,
|
|
driver: record.driver,
|
|
passenger: record.passenger,
|
|
frequency: record.frequency,
|
|
fromDate: record.fromDate.toISOString().split('T')[0],
|
|
toDate: record.toDate.toISOString().split('T')[0],
|
|
schedule: record.schedule.map(
|
|
(scheduleItem: ScheduleItemModel) =>
|
|
new ScheduleItem({
|
|
day: scheduleItem.day,
|
|
time: `${scheduleItem.time
|
|
.getUTCHours()
|
|
.toString()
|
|
.padStart(2, '0')}:${scheduleItem.time
|
|
.getUTCMinutes()
|
|
.toString()
|
|
.padStart(2, '0')}`,
|
|
margin: scheduleItem.margin,
|
|
}),
|
|
),
|
|
waypoints: this.directionEncoder
|
|
.decode(record.waypoints)
|
|
.map((coordinates, index) => ({
|
|
position: index,
|
|
...coordinates,
|
|
})),
|
|
fwdAzimuth: record.fwdAzimuth,
|
|
backAzimuth: record.backAzimuth,
|
|
points: [],
|
|
},
|
|
});
|
|
|
|
toPersistenceExtra = (entity: AdEntity): AdWriteExtraModel => ({
|
|
waypoints: this.directionEncoder.encode(entity.getProps().waypoints),
|
|
direction: this.directionEncoder.encode(entity.getProps().points),
|
|
});
|
|
}
|