backend/lib/seed/helpers/Utils.dates.intervals.ts
2025-05-14 21:45:16 +02:00

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 })));
}
}