DRY the pax/driver schedule adjustment logic
This commit is contained in:
parent
104559d03d
commit
01ebac7e74
|
@ -2,12 +2,14 @@ import {
|
||||||
AggregateID,
|
AggregateID,
|
||||||
AggregateRoot,
|
AggregateRoot,
|
||||||
ArgumentInvalidException,
|
ArgumentInvalidException,
|
||||||
|
ValueObject,
|
||||||
} from '@mobicoop/ddd-library';
|
} from '@mobicoop/ddd-library';
|
||||||
import { Role } from './ad.types';
|
import { Role } from './ad.types';
|
||||||
import { CalendarTools } from './calendar-tools.service';
|
import { CalendarTools } from './calendar-tools.service';
|
||||||
import {
|
import {
|
||||||
CandidateProps,
|
CandidateProps,
|
||||||
CreateCandidateProps,
|
CreateCandidateProps,
|
||||||
|
DateInterval,
|
||||||
Target,
|
Target,
|
||||||
} from './candidate.types';
|
} from './candidate.types';
|
||||||
import { ActorTime } from './value-objects/actor-time.value-object';
|
import { ActorTime } from './value-objects/actor-time.value-object';
|
||||||
|
@ -101,57 +103,13 @@ export class CandidateEntity extends AggregateRoot<CandidateProps> {
|
||||||
* Create the driver schedule based on the passenger schedule
|
* Create the driver schedule based on the passenger schedule
|
||||||
*/
|
*/
|
||||||
private _createDriverSchedule = (): void => {
|
private _createDriverSchedule = (): void => {
|
||||||
let driverSchedule: Array<ScheduleItemProps | undefined> =
|
const passengerSchedule = new Schedule(
|
||||||
this.props.passengerSchedule!.map(
|
this.props.passengerSchedule!,
|
||||||
(scheduleItemProps: ScheduleItemProps) => ({
|
|
||||||
day: scheduleItemProps.day,
|
|
||||||
time: scheduleItemProps.time,
|
|
||||||
margin: scheduleItemProps.margin,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
// adjust the driver theoretical schedule :
|
|
||||||
// we guess the ideal driver departure time based on the duration to
|
|
||||||
// reach the passenger starting point from the driver starting point
|
|
||||||
driverSchedule = driverSchedule
|
|
||||||
.map((scheduleItemProps: ScheduleItemProps) => {
|
|
||||||
try {
|
|
||||||
const driverDate: Date = CalendarTools.firstDate(
|
|
||||||
scheduleItemProps.day,
|
|
||||||
this.props.dateInterval,
|
this.props.dateInterval,
|
||||||
);
|
);
|
||||||
const driverStartDatetime: Date = CalendarTools.datetimeWithSeconds(
|
this.props.driverSchedule = passengerSchedule
|
||||||
driverDate,
|
.adjust(-this._passengerStartDuration())
|
||||||
scheduleItemProps.time,
|
.unpack().items;
|
||||||
-this._passengerStartDuration(),
|
|
||||||
);
|
|
||||||
return <ScheduleItemProps>{
|
|
||||||
day: driverDate.getUTCDay(),
|
|
||||||
margin: scheduleItemProps.margin,
|
|
||||||
time: `${driverStartDatetime
|
|
||||||
.getUTCHours()
|
|
||||||
.toString()
|
|
||||||
.padStart(2, '0')}:${driverStartDatetime
|
|
||||||
.getUTCMinutes()
|
|
||||||
.toString()
|
|
||||||
.padStart(2, '0')}`,
|
|
||||||
};
|
|
||||||
} catch (e) {
|
|
||||||
// no possible driver date or time
|
|
||||||
// TODO : find a test case !
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(
|
|
||||||
(scheduleItemProps: ScheduleItemProps | undefined) =>
|
|
||||||
scheduleItemProps !== undefined,
|
|
||||||
);
|
|
||||||
this.props.driverSchedule = driverSchedule.map(
|
|
||||||
(scheduleItemProps: ScheduleItemProps) => ({
|
|
||||||
day: scheduleItemProps.day,
|
|
||||||
time: scheduleItemProps.time,
|
|
||||||
margin: scheduleItemProps.margin,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -174,57 +132,14 @@ export class CandidateEntity extends AggregateRoot<CandidateProps> {
|
||||||
* Create the passenger schedule based on the driver schedule
|
* Create the passenger schedule based on the driver schedule
|
||||||
*/
|
*/
|
||||||
private _createPassengerSchedule = (): void => {
|
private _createPassengerSchedule = (): void => {
|
||||||
let passengerSchedule: Array<ScheduleItemProps | undefined> =
|
const driverSchedule = new Schedule(
|
||||||
this.props.driverSchedule!.map(
|
this.props.driverSchedule!,
|
||||||
(scheduleItemProps: ScheduleItemProps) => ({
|
|
||||||
day: scheduleItemProps.day,
|
|
||||||
time: scheduleItemProps.time,
|
|
||||||
margin: scheduleItemProps.margin,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
// adjust the passenger theoretical schedule :
|
|
||||||
// we guess the ideal passenger departure time based on the duration to
|
|
||||||
// reach the passenger starting point from the driver starting point
|
|
||||||
passengerSchedule = passengerSchedule
|
|
||||||
.map((scheduleItemProps: ScheduleItemProps) => {
|
|
||||||
try {
|
|
||||||
const passengerDate: Date = CalendarTools.firstDate(
|
|
||||||
scheduleItemProps.day,
|
|
||||||
this.props.dateInterval,
|
this.props.dateInterval,
|
||||||
);
|
);
|
||||||
const passengeStartDatetime: Date = CalendarTools.datetimeWithSeconds(
|
|
||||||
passengerDate,
|
this.props.passengerSchedule = driverSchedule
|
||||||
scheduleItemProps.time,
|
.adjust(this._passengerStartDuration())
|
||||||
this._passengerStartDuration(),
|
.unpack().items;
|
||||||
);
|
|
||||||
return {
|
|
||||||
day: passengerDate.getUTCDay(),
|
|
||||||
margin: scheduleItemProps.margin,
|
|
||||||
time: `${passengeStartDatetime
|
|
||||||
.getUTCHours()
|
|
||||||
.toString()
|
|
||||||
.padStart(2, '0')}:${passengeStartDatetime
|
|
||||||
.getUTCMinutes()
|
|
||||||
.toString()
|
|
||||||
.padStart(2, '0')}`,
|
|
||||||
};
|
|
||||||
} catch (e) {
|
|
||||||
// no possible passenger date or time
|
|
||||||
// TODO : find a test case !
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.filter(
|
|
||||||
(scheduleItemProps: ScheduleItemProps | undefined) =>
|
|
||||||
scheduleItemProps !== undefined,
|
|
||||||
);
|
|
||||||
this.props.passengerSchedule = passengerSchedule.map(
|
|
||||||
(scheduleItemProps: ScheduleItemProps) => ({
|
|
||||||
day: scheduleItemProps.day,
|
|
||||||
time: scheduleItemProps.time,
|
|
||||||
margin: scheduleItemProps.margin,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private _createJourney = (driverScheduleItem: ScheduleItem): Journey =>
|
private _createJourney = (driverScheduleItem: ScheduleItem): Journey =>
|
||||||
|
@ -407,6 +322,60 @@ export class CandidateEntity extends AggregateRoot<CandidateProps> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO Use this class as part of the CandidateEntity aggregate
|
||||||
|
class Schedule extends ValueObject<{
|
||||||
|
items: ScheduleItemProps[];
|
||||||
|
dateInterval: DateInterval;
|
||||||
|
}> {
|
||||||
|
constructor(items: ScheduleItemProps[], dateInterval: DateInterval) {
|
||||||
|
super({ items, dateInterval });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected validate(): void {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given duration to each schedule item
|
||||||
|
* unless the expected new datetime is not possible,
|
||||||
|
* in which case the item is removed from the adjusted schedule
|
||||||
|
* @param duration time increment in seconds (can be negative)
|
||||||
|
* @returns the new adjusted schedule
|
||||||
|
*/
|
||||||
|
adjust(duration: number): Schedule {
|
||||||
|
const newItems = this.props.items.reduce((acc, scheduleItemProps) => {
|
||||||
|
try {
|
||||||
|
const itemDate: Date = CalendarTools.firstDate(
|
||||||
|
scheduleItemProps.day,
|
||||||
|
this.props.dateInterval,
|
||||||
|
);
|
||||||
|
const driverStartDatetime: Date = CalendarTools.datetimeWithSeconds(
|
||||||
|
itemDate,
|
||||||
|
scheduleItemProps.time,
|
||||||
|
duration,
|
||||||
|
);
|
||||||
|
acc.push({
|
||||||
|
day: itemDate.getUTCDay(),
|
||||||
|
margin: scheduleItemProps.margin,
|
||||||
|
time: this._formatTime(driverStartDatetime),
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
// no possible driver date or time
|
||||||
|
// TODO : find a test case !
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, new Array<ScheduleItemProps>());
|
||||||
|
|
||||||
|
return new Schedule(newItems, this.props.dateInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _formatTime(dateTime: Date) {
|
||||||
|
return (
|
||||||
|
dateTime.getUTCHours().toString().padStart(2, '0') +
|
||||||
|
':' +
|
||||||
|
dateTime.getUTCMinutes().toString().padStart(2, '0')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type ScheduleItemRange = {
|
type ScheduleItemRange = {
|
||||||
scheduleItem: ScheduleItem;
|
scheduleItem: ScheduleItem;
|
||||||
range: Date[];
|
range: Date[];
|
||||||
|
|
Loading…
Reference in New Issue