diff --git a/src/Schedule/schedule.schema.ts b/src/Schedule/schedule.schema.ts index de488a2..058affe 100644 --- a/src/Schedule/schedule.schema.ts +++ b/src/Schedule/schedule.schema.ts @@ -437,6 +437,7 @@ d72a864e-2f41-45ab-9c9b-bf0512a31883,e9be51fd-2382-4e43-9988-74e76fde4b56,2024-1 throw new Error("User not found"); } Logger.log("args.schedule", args.schedule); + // reject schedule if start date is today or in the past if ( 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"); } + // generate preview and check if there is any overlapping with other schedules date in same service const previewSchedule = 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[], days: args.schedule.daysOfWeek as number[], }); + const existingScheduleDates = await this.prisma.scheduleDate.findMany( { 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 const isOverlapping = DateTimeUtils.isOverlaps( 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), })) ); + if (isOverlapping) { Logger.error("Overlapping schedule", "ScheduleSchema"); 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({ 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: { - AND: [ - { - participantIds: { - has: ctx.me?.id ?? "", - }, - orderId: { - not: null, - }, - dayOfWeek: { - in: Array.isArray(args.schedule.daysOfWeek) - ? args.schedule.daysOfWeek - : [], - }, - slot: { - in: Array.isArray(args.schedule.slots) - ? args.schedule.slots - : [], - }, - scheduleId: { - notIn: scheduleDatesInSchedule.map( - (scheduleDate) => scheduleDate.scheduleId - ), - }, - }, - ], - }, - }); - if (overlapSchedule) { - throw new Error("Overlapping schedule"); + + // First, generate the preview schedule dates + const previewScheduleDates = previewSchedule.slots.map((slot) => ({ + start: DateTimeUtils.fromIsoString(slot.start), + end: DateTimeUtils.fromIsoString(slot.end), + })); + + // Check if new schedule overlaps with any existing schedule dates for the user + const hasOverlap = existingUserScheduleDates.some((existingDate) => + previewScheduleDates.some((newScheduleDate) => + DateTimeUtils.isOverlap( + DateTimeUtils.fromDate(existingDate.start), + DateTimeUtils.fromDate(existingDate.end), + newScheduleDate.start, + newScheduleDate.end + ) + ) + ); + + if (hasOverlap) { + throw new Error( + "Schedule date has overlap with existing schedule dates" + ); } + const schedule = await this.prisma.schedule.create({ ...query, data: args.schedule, }); + // generate schedule dates based on data and config const scheduleDates = await this.scheduleService.generateScheduleDates(schedule); + // update schedule with schedule dates return await this.prisma.schedule.update({ ...query,