fix: improve schedule overlap validation in ScheduleSchema
- Enhanced the validation logic to check for overlapping schedules by incorporating checks against existing user schedule dates. - Added comprehensive overlap detection for new schedules, ensuring they do not conflict with any existing schedules for the user. - This update aims to improve the integrity of scheduling operations and provide clearer error messages for users regarding scheduling conflicts.
This commit is contained in:
@@ -437,6 +437,7 @@ d72a864e-2f41-45ab-9c9b-bf0512a31883,e9be51fd-2382-4e43-9988-74e76fde4b56,2024-1
|
|||||||
throw new Error("User not found");
|
throw new Error("User not found");
|
||||||
}
|
}
|
||||||
Logger.log("args.schedule", args.schedule);
|
Logger.log("args.schedule", args.schedule);
|
||||||
|
|
||||||
// reject schedule if start date is today or in the past
|
// reject schedule if start date is today or in the past
|
||||||
if (
|
if (
|
||||||
DateTimeUtils.fromDate(args.schedule.scheduleStart as Date).day <=
|
DateTimeUtils.fromDate(args.schedule.scheduleStart as Date).day <=
|
||||||
@@ -444,6 +445,7 @@ d72a864e-2f41-45ab-9c9b-bf0512a31883,e9be51fd-2382-4e43-9988-74e76fde4b56,2024-1
|
|||||||
) {
|
) {
|
||||||
throw new Error("Start date is in the past or today");
|
throw new Error("Start date is in the past or today");
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate preview and check if there is any overlapping with other schedules date in same service
|
// generate preview and check if there is any overlapping with other schedules date in same service
|
||||||
const previewSchedule =
|
const previewSchedule =
|
||||||
await this.scheduleService.createSchedulePreviewForCenter({
|
await this.scheduleService.createSchedulePreviewForCenter({
|
||||||
@@ -452,6 +454,7 @@ d72a864e-2f41-45ab-9c9b-bf0512a31883,e9be51fd-2382-4e43-9988-74e76fde4b56,2024-1
|
|||||||
slots: args.schedule.slots as number[],
|
slots: args.schedule.slots as number[],
|
||||||
days: args.schedule.daysOfWeek as number[],
|
days: args.schedule.daysOfWeek as number[],
|
||||||
});
|
});
|
||||||
|
|
||||||
const existingScheduleDates = await this.prisma.scheduleDate.findMany(
|
const existingScheduleDates = await this.prisma.scheduleDate.findMany(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
@@ -471,6 +474,7 @@ d72a864e-2f41-45ab-9c9b-bf0512a31883,e9be51fd-2382-4e43-9988-74e76fde4b56,2024-1
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// check if there is any overlapping with existing schedule dates in same service using DateTimeUtils
|
// check if there is any overlapping with existing schedule dates in same service using DateTimeUtils
|
||||||
const isOverlapping = DateTimeUtils.isOverlaps(
|
const isOverlapping = DateTimeUtils.isOverlaps(
|
||||||
previewSchedule.slots.map((slot) => ({
|
previewSchedule.slots.map((slot) => ({
|
||||||
@@ -482,55 +486,72 @@ d72a864e-2f41-45ab-9c9b-bf0512a31883,e9be51fd-2382-4e43-9988-74e76fde4b56,2024-1
|
|||||||
end: DateTimeUtils.fromDate(date.end),
|
end: DateTimeUtils.fromDate(date.end),
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isOverlapping) {
|
if (isOverlapping) {
|
||||||
Logger.error("Overlapping schedule", "ScheduleSchema");
|
Logger.error("Overlapping schedule", "ScheduleSchema");
|
||||||
throw new Error("Overlapping schedule");
|
throw new Error("Overlapping schedule");
|
||||||
}
|
}
|
||||||
const scheduleDatesInSchedule =
|
|
||||||
|
// check if scheduleDate have overlap with other scheduleDate of same user
|
||||||
|
const existingUserScheduleDates =
|
||||||
await this.prisma.scheduleDate.findMany({
|
await this.prisma.scheduleDate.findMany({
|
||||||
where: {
|
where: {
|
||||||
scheduleId: args.schedule.id,
|
AND: [
|
||||||
|
{
|
||||||
|
participantIds: {
|
||||||
|
has: ctx.me?.id ?? "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: {
|
||||||
|
notIn: [
|
||||||
|
ScheduleDateStatus.COMPLETED,
|
||||||
|
ScheduleDateStatus.EXPIRED,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
end: {
|
||||||
|
gte: DateTimeUtils.now().toJSDate(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const overlapSchedule = await this.prisma.scheduleDate.findFirst({
|
|
||||||
where: {
|
// First, generate the preview schedule dates
|
||||||
AND: [
|
const previewScheduleDates = previewSchedule.slots.map((slot) => ({
|
||||||
{
|
start: DateTimeUtils.fromIsoString(slot.start),
|
||||||
participantIds: {
|
end: DateTimeUtils.fromIsoString(slot.end),
|
||||||
has: ctx.me?.id ?? "",
|
}));
|
||||||
},
|
|
||||||
orderId: {
|
// Check if new schedule overlaps with any existing schedule dates for the user
|
||||||
not: null,
|
const hasOverlap = existingUserScheduleDates.some((existingDate) =>
|
||||||
},
|
previewScheduleDates.some((newScheduleDate) =>
|
||||||
dayOfWeek: {
|
DateTimeUtils.isOverlap(
|
||||||
in: Array.isArray(args.schedule.daysOfWeek)
|
DateTimeUtils.fromDate(existingDate.start),
|
||||||
? args.schedule.daysOfWeek
|
DateTimeUtils.fromDate(existingDate.end),
|
||||||
: [],
|
newScheduleDate.start,
|
||||||
},
|
newScheduleDate.end
|
||||||
slot: {
|
)
|
||||||
in: Array.isArray(args.schedule.slots)
|
)
|
||||||
? args.schedule.slots
|
);
|
||||||
: [],
|
|
||||||
},
|
if (hasOverlap) {
|
||||||
scheduleId: {
|
throw new Error(
|
||||||
notIn: scheduleDatesInSchedule.map(
|
"Schedule date has overlap with existing schedule dates"
|
||||||
(scheduleDate) => scheduleDate.scheduleId
|
);
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (overlapSchedule) {
|
|
||||||
throw new Error("Overlapping schedule");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const schedule = await this.prisma.schedule.create({
|
const schedule = await this.prisma.schedule.create({
|
||||||
...query,
|
...query,
|
||||||
data: args.schedule,
|
data: args.schedule,
|
||||||
});
|
});
|
||||||
|
|
||||||
// generate schedule dates based on data and config
|
// generate schedule dates based on data and config
|
||||||
const scheduleDates =
|
const scheduleDates =
|
||||||
await this.scheduleService.generateScheduleDates(schedule);
|
await this.scheduleService.generateScheduleDates(schedule);
|
||||||
|
|
||||||
// update schedule with schedule dates
|
// update schedule with schedule dates
|
||||||
return await this.prisma.schedule.update({
|
return await this.prisma.schedule.update({
|
||||||
...query,
|
...query,
|
||||||
|
|||||||
Reference in New Issue
Block a user