89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
import { DateTimeRangeComponent, AvailabilityComponent, DateRangeComponent, HourComponent } from '@seed/interfaces/components.dates';
|
|
import _ from 'lodash';
|
|
import { Interval, DateTime } from 'luxon';
|
|
|
|
export function checkIfDatesAreInAvailabilities(
|
|
dates: DateTimeRangeComponent[],
|
|
availabilities: AvailabilityComponent,
|
|
options?: { zone: string },
|
|
): boolean {
|
|
const zone = options?.zone || process.env.TIMEZONE || 'utc';
|
|
const intervalsExceptions = getExceptionsIntervalFromAvailabilities(availabilities, zone);
|
|
let isInException = false;
|
|
|
|
if (intervalsExceptions.length > 0) {
|
|
isInException = _.some(dates, (d) => {
|
|
return checkIfDateRangeIsInIntervals(d, intervalsExceptions);
|
|
});
|
|
}
|
|
|
|
const intervalDates = getDatesIntervalFromAvailabilities(availabilities, zone);
|
|
let isInDates = true;
|
|
|
|
if (intervalDates.length > 0) {
|
|
isInDates = _.every(dates, (d) => {
|
|
return checkIfDateRangeIsInIntervals(d, intervalDates);
|
|
});
|
|
}
|
|
|
|
return !isInException && isInDates;
|
|
}
|
|
|
|
function checkIfDateRangeIsInIntervals(dateR: DateTimeRangeComponent, intervals: Interval[]): boolean {
|
|
const interval = Interval.fromDateTimes(dateR.startDate, dateR.endDate);
|
|
return _.some(intervals, (i) => i.overlaps(interval));
|
|
}
|
|
|
|
function getExceptionsIntervalFromAvailabilities(availabilities: AvailabilityComponent, zone: string): Interval[] {
|
|
const exceptions = availabilities.exceptions;
|
|
const intervalsExceptions: Interval[] = [];
|
|
|
|
// Create all ezxceptions intervals
|
|
if (exceptions) {
|
|
exceptions.forEach((e) => {
|
|
createIntervalFromDatesAndHours(e.dates, zone, e.hours, intervalsExceptions);
|
|
});
|
|
}
|
|
|
|
return intervalsExceptions;
|
|
}
|
|
|
|
function getDatesIntervalFromAvailabilities(availabilities: AvailabilityComponent, zone: string): Interval[] {
|
|
const dates = availabilities.dates;
|
|
const hours = availabilities.hours;
|
|
const datesExceptions: Interval[] = [];
|
|
|
|
// Create all ezxceptions dates
|
|
if (dates) {
|
|
createIntervalFromDatesAndHours(dates, zone, hours, datesExceptions);
|
|
}
|
|
|
|
return datesExceptions;
|
|
}
|
|
|
|
function createIntervalFromDatesAndHours(dates: DateRangeComponent, zone: string, hours: HourComponent[] | undefined, datesExceptions: Interval[]) {
|
|
let dateStart = DateTime.fromJSDate(dates.startDate, { zone });
|
|
const dateEnd = DateTime.fromJSDate(dates.endDate, { zone });
|
|
|
|
if (hours) {
|
|
while (dateStart < dateEnd) {
|
|
hours.forEach((h) => {
|
|
const hStart = parseInt(h.from.split(':')[0]);
|
|
const mStart = parseInt(h.from.split(':')[1]);
|
|
|
|
const hEnd = parseInt(h.to.split(':')[0]);
|
|
const mEnd = parseInt(h.to.split(':')[1]);
|
|
|
|
datesExceptions.push(
|
|
Interval.fromDateTimes(dateStart.set({ hour: hStart, minute: mStart }), dateStart.set({ hour: hEnd, minute: mEnd })),
|
|
);
|
|
});
|
|
dateStart = dateStart.plus({ day: 1 });
|
|
}
|
|
|
|
// if all day
|
|
} else {
|
|
datesExceptions.push(Interval.fromDateTimes(DateTime.fromJSDate(dates.startDate, { zone }), DateTime.fromJSDate(dates.endDate, { zone })));
|
|
}
|
|
}
|