From 95ac760447a0759c997d17ea89d5988167db6cb5 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Fri, 5 Apr 2024 14:49:15 +0300 Subject: [PATCH] fix repeating availability dayofmonh problem --- components/availability/AvailabilityForm.js | 116 +++++++++++++----- .../AvailabilityFormDatePicker.js | 2 +- pages/api/index.ts | 5 +- pages/cart/publishers/import.tsx | 2 +- .../fix_availability_dayofweek.sql | 28 +++++ src/helpers/common.js | 33 ++--- src/helpers/excel.js | 6 +- 7 files changed, 140 insertions(+), 52 deletions(-) create mode 100644 prisma/administrative_scripts/fix_availability_dayofweek.sql diff --git a/components/availability/AvailabilityForm.js b/components/availability/AvailabilityForm.js index a24f2af..9fb1b65 100644 --- a/components/availability/AvailabilityForm.js +++ b/components/availability/AvailabilityForm.js @@ -90,9 +90,9 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o let avs = availabilities.filter(av => av.type !== "assignment"); // Determine if we need to delete and recreate, or just update let shouldRecreate = avs.length > 0 && avs.length !== groupedTimeSlots.length || avs.some(av => !av.id); - shouldRecreate = shouldRecreate || ( avs.length == 0 && availabilities.length > 0); + shouldRecreate = shouldRecreate || (avs.length == 0 && availabilities.length > 0); //create availability if we open a form with assignment without availability - + if (shouldRecreate) { // Delete existing availabilities if they have an ID console.log("Recreating availabilities"); @@ -173,52 +173,106 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o return groupedIntervals; } - // const firstSlotWithTransport = timeSlots[0].checked && timeSlots[0]?.isWithTransport; - // const lastSlotWithTransport = timeSlots[timeSlots.length - 1].checked && timeSlots[timeSlots.length - 1]?.isWithTransport; - function createAvailabilityFromGroup(group) { - let startTime = new Date(day); + // // const firstSlotWithTransport = timeSlots[0].checked && timeSlots[0]?.isWithTransport; + // // const lastSlotWithTransport = timeSlots[timeSlots.length - 1].checked && timeSlots[timeSlots.length - 1]?.isWithTransport; + // function createAvailabilityFromGroup(group) { + // let startTime = new Date(day); + // startTime.setHours(group[0].startTime.getHours(), group[0].startTime.getMinutes(), group[0].startTime.getSeconds(), 0); + + // let endTime = new Date(day); + // endTime.setHours(group[group.length - 1].endTime.getHours(), group[group.length - 1].endTime.getMinutes(), group[group.length - 1].endTime.getSeconds(), 0); + + + // return { + // name: common.getTimeFomatted(startTime) + "-" + common.getTimeFomatted(endTime), + // publisherId: publisher.id, + // startTime: startTime, + // endTime: endTime, + // isWithTransportIn: group[0].isFirst && timeSlots[0].isWithTransport, + // isWithTransportOut: group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport, + // dayofweek: common.getDayOfWeekNameEnEnumForDate(day.getDay()), + // repeatWeekly: doRepeat, + // dayOfMonth: doRepeat ? null : startTime.getDate(), + // endDate: doRepeat ? repeatUntil : null, + // dateOfEntry: new Date(), + // }; + // } + + // function updateAvailabilityFromGroup(availability, group) { + // availability.startTime.setTime(group[0].startTime); + // availability.endTime.setTime(group[group.length - 1].endTime); + // availability.name = common.getTimeFomatted(availability.startTime) + "-" + common.getTimeFomatted(availability.endTime); + + // availability.isWithTransportIn = group[0].isFirst && timeSlots[0].isWithTransport; + // availability.isWithTransportOut = group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport; + + // delete availability.weekOfMonth; + // if (doRepeat) { + // availability.repeatWeekly = true; + // availability.dayOfMonth = null; + // availability.weekOfMonth = 0; + // availability.endDate = repeatUntil; + // } else { + // availability.repeatWeekly = false; + // availability.dayOfMonth = availability.startTime.getDate(); + // availability.endDate = null; + // } + + // availability.dateOfEntry = new Date(); + // if (availability.parentAvailabilityId) { + // availability.parentAvailability = { connect: { id: parentAvailabilityId } }; + // } + // delete availability.parentAvailabilityId; + + // return availability; + // } + // Common function to set shared properties + function setSharedAvailabilityProperties(availability, group, timeSlots) { + let startTime = new Date(availability.startTime || day); startTime.setHours(group[0].startTime.getHours(), group[0].startTime.getMinutes(), group[0].startTime.getSeconds(), 0); - let endTime = new Date(day); + let endTime = new Date(availability.endTime || day); endTime.setHours(group[group.length - 1].endTime.getHours(), group[group.length - 1].endTime.getMinutes(), group[group.length - 1].endTime.getSeconds(), 0); - - return { - name: common.getTimeFomatted(startTime) + "-" + common.getTimeFomatted(endTime), - publisherId: publisher.id, - startTime: startTime, - endTime: endTime, - isWithTransportIn: group[0].isFirst && timeSlots[0].isWithTransport, - isWithTransportOut: group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport, - dayofweek: common.getDayOfWeekNameEnEnum(day.getDay()), - repeatWeekly: doRepeat, - dayOfMonth: doRepeat ? null : startTime.getDate(), - endDate: doRepeat ? repeatUntil : null, - dateOfEntry: new Date(), - }; - } - - function updateAvailabilityFromGroup(availability, group) { - availability.startTime.setTime(group[0].startTime); - availability.endTime.setTime(group[group.length - 1].endTime); - availability.name = common.getTimeFomatted(availability.startTime) + "-" + common.getTimeFomatted(availability.endTime); + availability.startTime = startTime; + availability.endTime = endTime; + availability.name = common.getTimeFomatted(startTime) + "-" + common.getTimeFomatted(endTime); availability.isWithTransportIn = group[0].isFirst && timeSlots[0].isWithTransport; availability.isWithTransportOut = group[group.length - 1].isLast && timeSlots[timeSlots.length - 1].isWithTransport; - delete availability.weekOfMonth; + // Adjustments for repeating settings if (doRepeat) { availability.repeatWeekly = true; availability.dayOfMonth = null; - availability.weekOfMonth = 0; availability.endDate = repeatUntil; } else { availability.repeatWeekly = false; - availability.dayOfMonth = availability.startTime.getDate(); + availability.dayOfMonth = startTime.getDate(); availability.endDate = null; } availability.dateOfEntry = new Date(); + } + + function createAvailabilityFromGroup(group) { + let availability = { + publisherId: publisher.id, + dayofweek: common.getDayOfWeekNameEnEnumForDate(day), + }; + + setSharedAvailabilityProperties(availability, group, timeSlots); + + return availability; + } + + function updateAvailabilityFromGroup(availability, group) { + setSharedAvailabilityProperties(availability, group, timeSlots); + + delete availability.weekOfMonth; + if (doRepeat) { + availability.weekOfMonth = 0; + } if (availability.parentAvailabilityId) { availability.parentAvailability = { connect: { id: parentAvailabilityId } }; } @@ -227,6 +281,8 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o return availability; } + + const handleDelete = async (e) => { e.preventDefault(); try { diff --git a/components/availability/AvailabilityFormDatePicker.js b/components/availability/AvailabilityFormDatePicker.js index 80c6faa..979975b 100644 --- a/components/availability/AvailabilityFormDatePicker.js +++ b/components/availability/AvailabilityFormDatePicker.js @@ -170,7 +170,7 @@ export default function AvailabilityForm({ publisherId, existingItem, inline, on availability.name = common.getTimeFomatted(availability.startTime) + "-" + common.getTimeFomatted(availability.endTime); } - availability.dayofweek = common.getDayOfWeekNameEnEnum(availability.startTime); + availability.dayofweek = common.getDayOfWeekNameEnEnumForDate(availability.startTime); if (availability.repeatWeekly) { availability.dayOfMonth = null; availability.weekOfMonth = 0; //weekly recurrance - no need for week of month. special value 0 diff --git a/pages/api/index.ts b/pages/api/index.ts index 42f47c6..7e45d0d 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -264,7 +264,7 @@ export default async function handler(req, res) { let data = { publisherId: pub.id, dayOfMonth: null, - dayofweek: avail.dayofweek || common.getDayOfWeekNameEnEnum(avail.startTime), + dayofweek: avail.dayofweek || common.getDayOfWeekNameEnEnumForDate(avail.startTime), weekOfMonth: avail.weekofMonth || common.getWeekOfMonth(avail.startTime), // null for auto generated availabilities //dateOfEntry: new Date(), //avail.dateOfEntry || avail.startTime, @@ -535,7 +535,7 @@ export async function filterPublishers(selectFields, searchText, filterDate, fet let dayOfWeekEnum: DayOfWeek if (filterDate) { // Determine day of week using common function - dayOfWeekEnum = common.getDayOfWeekNameEnEnum(filterDate); + dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(filterDate); if (filterDate.getHours() > 21 || filterDate.getHours() < 6) { filterDate.setHours(0, 0, 0, 0); // Set to midnight } @@ -603,6 +603,7 @@ export async function filterPublishers(selectFields, searchText, filterDate, fet }; } else { + //match exact time (should be same as data.findPublisherAvailability()) whereClause["availabilities"] = { some: { OR: [ diff --git a/pages/cart/publishers/import.tsx b/pages/cart/publishers/import.tsx index 7e10eb7..5acedd8 100644 --- a/pages/cart/publishers/import.tsx +++ b/pages/cart/publishers/import.tsx @@ -383,7 +383,7 @@ export default function ImportPage() { common.logger.debug("processing availabilities for " + day.toLocaleDateString()); // Output: Sun Apr 17 2022 14:07:11 GMT+0300 (Eastern European Summer Time) common.logger.debug("parsing availability input: " + shifts); // Output: 0 (Sunday) - const dayOfWeekName = common.getDayOfWeekNameEnEnum(day); + const dayOfWeekName = common.getDayOfWeekNameEnEnumForDate(day); let dayOfMonth = day.getDate(); const name = `${names[0]} ${names[1]}`; diff --git a/prisma/administrative_scripts/fix_availability_dayofweek.sql b/prisma/administrative_scripts/fix_availability_dayofweek.sql new file mode 100644 index 0000000..3d87f75 --- /dev/null +++ b/prisma/administrative_scripts/fix_availability_dayofweek.sql @@ -0,0 +1,28 @@ +-- find +SELECT * +FROM availability +WHERE dayofweek = "Thursday" +AND DAYOFWEEK(startTime) <> 5; + + +--fix + +UPDATE availability +SET dayofweek = CASE DAYOFWEEK(startTime) + WHEN 1 THEN 'Sunday' + WHEN 2 THEN 'Monday' + WHEN 3 THEN 'Tuesday' + WHEN 4 THEN 'Wednesday' + WHEN 5 THEN 'Thursday' + WHEN 6 THEN 'Friday' + WHEN 7 THEN 'Saturday' +END +WHERE dayofweek != CASE DAYOFWEEK(startTime) + WHEN 1 THEN 'Sunday' + WHEN 2 THEN 'Monday' + WHEN 3 THEN 'Tuesday' + WHEN 4 THEN 'Wednesday' + WHEN 5 THEN 'Thursday' + WHEN 6 THEN 'Friday' + WHEN 7 THEN 'Saturday' +END; \ No newline at end of file diff --git a/src/helpers/common.js b/src/helpers/common.js index e580a4b..fdac13e 100644 --- a/src/helpers/common.js +++ b/src/helpers/common.js @@ -151,24 +151,27 @@ exports.getDayOfWeekName = function (date) { return exports.dayOfWeekNames[dayOfWeekIndex]; }; -exports.getDayOfWeekNameEnEnum = function (date) { +exports.getDayOfWeekNameEnEnumForDate = function (date) { date = new Date(date); const dayOfWeekIndex = date.getDayEuropean(); - const dayOfWeekNames = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; - - //return enum instead of string - // const dayOfWeekNames: Record = { - // 0: DayOfWeek.Monday, - // 1: DayOfWeek.Tuesday, - // 2: DayOfWeek.Wednesday, - // 3: DayOfWeek.Thursday, - // 4: DayOfWeek.Friday, - // 5: DayOfWeek.Saturday, - // 6: DayOfWeek.Sunday - // }; - - return dayOfWeekNames[dayOfWeekIndex]; + return exports.DaysOfWeekArray[dayOfWeekIndex]; } + +//obsolete: we want to ensure getDayEuropean() is used, hense we will not use this function +// exports.getDayOfWeekNameEnEnum = function (dayOfWeekIndex) { +// //return enum instead of string +// // const dayOfWeekNames: Record = { +// // 0: DayOfWeek.Monday, +// // 1: DayOfWeek.Tuesday, +// // 2: DayOfWeek.Wednesday, +// // 3: DayOfWeek.Thursday, +// // 4: DayOfWeek.Friday, +// // 5: DayOfWeek.Saturday, +// // 6: DayOfWeek.Sunday +// // }; +// return exports.DaysOfWeekArray[dayOfWeekIndex]; + +// } exports.getPubTypeEnum = function (text) { const input = text.trim(); const mapping = { diff --git a/src/helpers/excel.js b/src/helpers/excel.js index 4b18578..4bba712 100644 --- a/src/helpers/excel.js +++ b/src/helpers/excel.js @@ -388,7 +388,7 @@ exports.processEvents = async function (events, year, monthNumber, progressCallb } - var dayofWeek = common.getDayOfWeekNameEnEnum(date); + var dayofWeek = common.getDayOfWeekNameEnEnumForDate(date); const cartEvent = cartEvents.find( (ce) => ce.locationId === location.id && @@ -482,7 +482,7 @@ exports.processEvents = async function (events, year, monthNumber, progressCallb // create availability with the same date as the event. //ToDo: add parameter to control if we want to create availability for each event. can be done whe we import previous shifts. // if (createAvailabilities) { - // const dayofWeek = common.getDayOfWeekNameEnEnum(date); + // const dayofWeek = common.getDayOfWeekNameEnEnumForDate(date); // const availability = await prisma.availability.create({ // data: { // publisherId: publisher.id, @@ -536,7 +536,7 @@ exports.processEvents = async function (events, year, monthNumber, progressCallb //ToDo: check if that works // const availability = await data.findPublisherAvailability(publisher.id, start); // if (!availability && createAvailabilities) { - // const dayofWeek = common.getDayOfWeekNameEnEnum(date); + // const dayofWeek = common.getDayOfWeekNameEnEnumForDate(date); // const availability = await prisma.availability.create({ // data: { // publisherId: publisher.id,