diff --git a/apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/schedules.controller.e2e-spec.ts b/apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/schedules.controller.e2e-spec.ts index 4c40fab807..e12d7598fb 100644 --- a/apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/schedules.controller.e2e-spec.ts +++ b/apps/api/v2/src/ee/schedules/schedules_2024_06_11/controllers/schedules.controller.e2e-spec.ts @@ -121,11 +121,13 @@ describe("Schedules Endpoints", () => { expect(outputSchedule?.isDefault).toEqual(expected.isDefault); expect(outputSchedule?.availability.length).toEqual(expectedAvailabilityLength); - const outputScheduleAvailability = outputSchedule?.availability[0]; - expect(outputScheduleAvailability).toBeDefined(); - expect(outputScheduleAvailability?.days).toEqual(expected.availability?.[0].days); - expect(outputScheduleAvailability?.startTime).toEqual(expected.availability?.[0].startTime); - expect(outputScheduleAvailability?.endTime).toEqual(expected.availability?.[0].endTime); + if (expectedAvailabilityLength) { + const outputScheduleAvailability = outputSchedule?.availability[0]; + expect(outputScheduleAvailability).toBeDefined(); + expect(outputScheduleAvailability?.days).toEqual(expected.availability?.[0].days); + expect(outputScheduleAvailability?.startTime).toEqual(expected.availability?.[0].startTime); + expect(outputScheduleAvailability?.endTime).toEqual(expected.availability?.[0].endTime); + } expect(JSON.stringify(outputSchedule?.overrides)).toEqual(JSON.stringify(expected.overrides)); } @@ -222,6 +224,33 @@ describe("Schedules Endpoints", () => { }); }); + it("should empty availabilities and overrides", async () => { + const body: UpdateScheduleInput_2024_06_11 = { + availability: [], + overrides: [], + }; + + return request(app.getHttpServer()) + .patch(`/api/v2/schedules/${createdSchedule.id}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_06_11) + .send(body) + .expect(200) + .then((response: any) => { + const responseData: UpdateScheduleOutput_2024_06_11 = response.body; + expect(responseData.status).toEqual(SUCCESS_STATUS); + const responseSchedule = responseData.data; + + const expectedSchedule = { + ...createdSchedule, + overrides: body.overrides, + availability: body.availability, + }; + outputScheduleMatchesExpected(responseSchedule, expectedSchedule, 0); + + createdSchedule = responseSchedule; + }); + }); + it("should delete schedule", async () => { return request(app.getHttpServer()).delete(`/api/v2/schedules/${createdSchedule.id}`).expect(200); }); diff --git a/apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts b/apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts index 55480185eb..92d05bc871 100644 --- a/apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts +++ b/apps/api/v2/src/ee/schedules/schedules_2024_06_11/schedules.repository.ts @@ -119,14 +119,17 @@ export class SchedulesRepository_2024_06_11 { timeZone: schedule.timeZone, }; - const availabilitiesAndOverrides: Prisma.AvailabilityCreateManyInput[] = []; + const createAvailabilityStatements: Prisma.AvailabilityCreateManyInput[] = []; + const createOverridesStatements: Prisma.AvailabilityCreateManyInput[] = []; + + const deleteAvailabilityStatements: Prisma.AvailabilityWhereInput[] = []; + const deleteOverridesStatements: Prisma.AvailabilityWhereInput[] = []; - const deleteConditions = []; if (availability) { // note(Lauris): availabilities and overrides are stored in the same "Availability" table, // but availabilities have "date" field as null, while overrides have it as not null, so delete // condition below results in deleting only rows from Availability table that are availabilities. - deleteConditions.push({ + deleteAvailabilityStatements.push({ scheduleId: { equals: scheduleId }, date: null, }); @@ -136,7 +139,7 @@ export class SchedulesRepository_2024_06_11 { // note(Lauris): availabilities and overrides are stored in the same "Availability" table, // but overrides have "date" field as not-null, while availabilities have it as null, so delete // condition below results in deleting only rows from Availability table that are overrides. - deleteConditions.push({ + deleteOverridesStatements.push({ scheduleId: { equals: scheduleId }, NOT: { date: null }, }); @@ -144,7 +147,7 @@ export class SchedulesRepository_2024_06_11 { if (availability && availability.length > 0) { availability.forEach((availability) => { - availabilitiesAndOverrides.push({ + createAvailabilityStatements.push({ days: availability.days, startTime: availability.startTime, endTime: availability.endTime, @@ -155,7 +158,7 @@ export class SchedulesRepository_2024_06_11 { if (overrides && overrides.length > 0) { overrides.forEach((override) => { - availabilitiesAndOverrides.push({ + createOverridesStatements.push({ date: override.date, startTime: override.startTime, endTime: override.endTime, @@ -164,11 +167,21 @@ export class SchedulesRepository_2024_06_11 { }); } - if (availabilitiesAndOverrides.length > 0) { + const deleteStatements = [...deleteAvailabilityStatements, ...deleteOverridesStatements]; + const createStatements = [...createAvailabilityStatements, ...createOverridesStatements]; + + if (deleteStatements.length > 0) { updateScheduleData.availability = { - deleteMany: deleteConditions, + deleteMany: deleteStatements, + }; + } + + if (createStatements.length > 0) { + updateScheduleData.availability = { + // note(Lauris): keep deleteMany statements + ...(updateScheduleData.availability || {}), createMany: { - data: availabilitiesAndOverrides, + data: createStatements, }, }; }