Fix weekly restriction bug in LayerUtil

This commit is contained in:
Simon Larsen 2023-12-05 18:56:01 +00:00
parent 91691a05d6
commit 161536fb5b
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
3 changed files with 147 additions and 10 deletions

View File

@ -1,5 +1,5 @@
import InBetween from './Database/InBetween';
import DayOfWeek from './Day/DayOfWeek';
import DayOfWeek, { DayOfWeekUtil } from './Day/DayOfWeek';
import BadDataException from './Exception/BadDataException';
import { JSONObject, ObjectType } from './JSON';
import PositiveNumber from './PositiveNumber';
@ -8,6 +8,39 @@ import moment from 'moment-timezone';
export const Moment: typeof moment = moment;
export default class OneUptimeDate {
public static moveDateToTheDayOfWeek(
date: Date,
moveToWeek: Date,
dayOfWeek: DayOfWeek
): Date {
// date will be moved to the week of "moveToWeek" and then to the day of week "dayOfWeek"
date = this.fromString(date);
date = this.keepTimeButMoveDay(date, moveToWeek);
// now move the date to the day of week
const dateDayOfWeek: DayOfWeek = this.getDayOfWeek(date);
if (dateDayOfWeek === dayOfWeek) {
return date;
}
const numberOfDayOfWeek: number =
DayOfWeekUtil.getNumberOfDayOfWeek(dayOfWeek);
const dateDayOfWeekNumber: number =
DayOfWeekUtil.getNumberOfDayOfWeek(dateDayOfWeek);
const difference: number = numberOfDayOfWeek - dateDayOfWeekNumber;
if (difference === 0) {
return date;
}
return this.addRemoveDays(date, difference);
}
public static isOverlapping(
start: Date,
end: Date,

View File

@ -8,4 +8,25 @@ enum DayOfWeek {
Saturday = 'Saturday',
}
export class DayOfWeekUtil {
public static getNumberOfDayOfWeek(dayOfWeek: DayOfWeek): number {
switch (dayOfWeek) {
case DayOfWeek.Sunday:
return 0;
case DayOfWeek.Monday:
return 1;
case DayOfWeek.Tuesday:
return 2;
case DayOfWeek.Wednesday:
return 3;
case DayOfWeek.Thursday:
return 4;
case DayOfWeek.Friday:
return 5;
case DayOfWeek.Saturday:
return 6;
}
}
}
export default DayOfWeek;

View File

@ -9,6 +9,7 @@ import OneUptimeDate from '../Date';
import EventInterval from '../Events/EventInterval';
import StartAndEndTime from '../Time/StartAndEndTime';
import Typeof from '../Typeof';
import DayOfWeek from '../Day/DayOfWeek';
export interface LayerProps {
users: Array<UserModel>;
@ -517,8 +518,19 @@ export default class LayerUtil {
];
}
if (restrictionTimes.restictionType === RestrictionType.Daily) {
return LayerUtil.getEventsByDailyRestriction(data);
if (
restrictionTimes.restictionType === RestrictionType.Daily &&
restrictionTimes.dayRestrictionTimes
) {
return LayerUtil.getEventsByDailyRestriction({
eventStartTime: data.eventStartTime,
eventEndTime: data.eventEndTime,
restrictionStartAndEndTime:
restrictionTimes.dayRestrictionTimes,
props: {
intervalType: EventInterval.Day,
},
});
}
if (restrictionTimes.restictionType === RestrictionType.Weekly) {
@ -538,7 +550,7 @@ export default class LayerUtil {
// if there are no weekly restriction times, we dont have any restrictions and we can return the event start and end times
const trimmedStartAndEndTimes: Array<StartAndEndTime> = [];
let trimmedStartAndEndTimes: Array<StartAndEndTime> = [];
if (!weeklyRestrictionTimes || weeklyRestrictionTimes.length === 0) {
return [
@ -549,19 +561,90 @@ export default class LayerUtil {
];
}
// const eventStartTime: Date = data.eventStartTime;
// const eventStartDayOfWeek: DayOfWeek = OneUptimeDate.getDayOfWeek(eventStartTime);
const restrictionStartAndEndTimes: Array<StartAndEndTime> =
LayerUtil.getWeeklyRestrictionTimesForWeek(data);
for (const restrictionStartAndEndTime of restrictionStartAndEndTimes) {
const trimmedStartAndEndTimesForRestriction: Array<StartAndEndTime> =
LayerUtil.getEventsByDailyRestriction({
eventStartTime: restrictionStartAndEndTime.startTime,
eventEndTime: restrictionStartAndEndTime.endTime,
restrictionStartAndEndTime: restrictionStartAndEndTime,
props: {
intervalType: EventInterval.Week,
},
});
trimmedStartAndEndTimes = [
...trimmedStartAndEndTimes,
...trimmedStartAndEndTimesForRestriction,
];
}
return trimmedStartAndEndTimes;
}
public static getWeeklyRestrictionTimesForWeek(data: {
eventStartTime: Date;
eventEndTime: Date;
restrictionTimes: RestrictionTimes;
}): Array<StartAndEndTime> {
const weeklyRestrictionTimes: Array<WeeklyResctriction> =
data.restrictionTimes.weeklyRestrictionTimes;
const eventStartTime: Date = data.eventStartTime;
const startAndEndTimesOfWeeklyRestrictions: Array<StartAndEndTime> = [];
for (const weeklyRestriction of weeklyRestrictionTimes) {
// move all of these to the week of the event start time
const startDayOfWeek: DayOfWeek = weeklyRestriction.startDay;
const endDayOfWeek: DayOfWeek = weeklyRestriction.endDay;
let startTime: Date = weeklyRestriction.startTime;
let endTime: Date = weeklyRestriction.endTime;
// move start and end times to the week of the event start time
startTime = OneUptimeDate.moveDateToTheDayOfWeek(
startTime,
eventStartTime,
startDayOfWeek
);
endTime = OneUptimeDate.moveDateToTheDayOfWeek(
endTime,
eventStartTime,
endDayOfWeek
);
// now we have true start and end times of the weekly restriction
// if start time is after end time, we need to add one week to the end time
if (OneUptimeDate.isAfter(startTime, endTime)) {
endTime = OneUptimeDate.addRemoveWeeks(endTime, 1);
}
startAndEndTimesOfWeeklyRestrictions.push({
startTime,
endTime,
});
}
return startAndEndTimesOfWeeklyRestrictions;
}
public static getEventsByDailyRestriction(data: {
eventStartTime: Date;
eventEndTime: Date;
restrictionTimes: RestrictionTimes;
restrictionStartAndEndTime: StartAndEndTime;
props: {
intervalType: EventInterval;
};
}): Array<StartAndEndTime> {
const dayRestrictionTimes: StartAndEndTime | null =
data.restrictionTimes.dayRestrictionTimes;
data.restrictionStartAndEndTime;
// if there are no day restriction times, we dont have any restrictions and we can return the event start and end times
@ -697,11 +780,11 @@ export default class LayerUtil {
restrictionStartTime = OneUptimeDate.addRemoveDays(
restrictionStartTime,
1
data.props.intervalType === EventInterval.Day ? 1 : 7 // daily or weekly
);
restrictionEndTime = OneUptimeDate.addRemoveDays(
restrictionEndTime,
1
data.props.intervalType === EventInterval.Day ? 1 : 7 // daily or weekly
);
}
}