Merge branch 'main' into production
This commit is contained in:
@ -10,7 +10,7 @@ import { bgBG } from '../x-date-pickers/locales/bgBG';
|
|||||||
import { ToastContainer } from 'react-toastify';
|
import { ToastContainer } from 'react-toastify';
|
||||||
const common = require('src/helpers/common');
|
const common = require('src/helpers/common');
|
||||||
//todo import Availability type from prisma schema
|
//todo import Availability type from prisma schema
|
||||||
import { isBefore, addMinutes, isAfter, isEqual, set, getHours, getMinutes, getSeconds } from 'date-fns'; //ToDo obsolete
|
import { isBefore, addMinutes, isAfter, isEqual, set, getHours, getMinutes, getSeconds } from 'date-fns'; //ToDo obsolete?
|
||||||
import { stat } from 'fs';
|
import { stat } from 'fs';
|
||||||
|
|
||||||
const { DateTime, FixedOffsetZone } = require('luxon');
|
const { DateTime, FixedOffsetZone } = require('luxon');
|
||||||
|
@ -46,7 +46,8 @@ const ProtectedRoute = ({ children, allowedRoles, deniedMessage, bypass = false,
|
|||||||
<div className="flex items-center justify-center min-h-screen">
|
<div className="flex items-center justify-center min-h-screen">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<h1 className="text-2xl font-bold mb-4 text-blue-500">{session?.user?.email},</h1>
|
<h1 className="text-2xl font-bold mb-4 text-blue-500">{session?.user?.email},</h1>
|
||||||
<p className="mb-6">{`Нямате достъп до тази страница. Ако мислите, че това е грешка, моля, свържете се с администраторите`}</p>
|
<p className="mb-6">{`Нямате достъп до тази страница.`}</p>
|
||||||
|
<p className="mb-6">{`Ако мислите, че това е грешка, моля, свържете се с администраторите`}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>);
|
</>);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -723,6 +723,9 @@ export default function CalendarPage({ initialEvents, initialShifts }) {
|
|||||||
<button className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center" onClick={() => generateShifts("genDay", true, true, null, 1)}>
|
<button className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center" onClick={() => generateShifts("genDay", true, true, null, 1)}>
|
||||||
{isLoading('genDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-cogs mr-2"></i>)}
|
{isLoading('genDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-cogs mr-2"></i>)}
|
||||||
Генерирай смени 2 </button>
|
Генерирай смени 2 </button>
|
||||||
|
<button className="block w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 flex items-center" onClick={() => generateShifts("genDay", true, true, null, 2)}>
|
||||||
|
{isLoading('genDay') ? (<i className="fas fa-sync-alt fa-spin mr-2"></i>) : (<i className="fas fa-cogs mr-2"></i>)}
|
||||||
|
Генерирай смени 3 </button>
|
||||||
<button className="block px-4 py-2 text-sm text-red-500 hover:bg-gray-100"
|
<button className="block px-4 py-2 text-sm text-red-500 hover:bg-gray-100"
|
||||||
onClick={() => openConfirmModal(
|
onClick={() => openConfirmModal(
|
||||||
'Сигурни ли сте че искате да изтриете ВСИЧКИ смени и назначения за месеца?',
|
'Сигурни ли сте че искате да изтриете ВСИЧКИ смени и назначения за месеца?',
|
||||||
|
@ -836,246 +836,302 @@ async function getCoverMePublisherEmails(shiftId) {
|
|||||||
return { shift, availablePublishers: availablePublishers, subscribedPublishers };
|
return { shift, availablePublishers: availablePublishers, subscribedPublishers };
|
||||||
}
|
}
|
||||||
|
|
||||||
// ### COPIED TO shift api (++) ###
|
// ### COPIED TO shift api (/shiftgenerate.ts) (++) ###
|
||||||
|
|
||||||
/** JSDoc
|
// /** JSDoc
|
||||||
* Generates a schedule.
|
// * Generates a schedule.
|
||||||
*
|
// *
|
||||||
0. generate shifts and assign publishers from the previous month if still available
|
// 0. generate shifts and assign publishers from the previous month if still available
|
||||||
1. Make sure we always put people only when they are available.
|
// 1. Make sure we always put people only when they are available.
|
||||||
2. First provision one male or two females that are available for transport in the first and last shifts.
|
// 2. First provision one male or two females that are available for transport in the first and last shifts.
|
||||||
3, Then gradually fill all other shifts with day by day troughout the whole month (monthInfo.firstMonday to .lastSunday) with first one, then two, then 3 and wherever possible more (up to CartEvent.numberOfPublishers number)
|
// 3, Then gradually fill all other shifts with day by day troughout the whole month (monthInfo.firstMonday to .lastSunday) with first one, then two, then 3 and wherever possible more (up to CartEvent.numberOfPublishers number)
|
||||||
4. Some publishers are available only at specific time (somoetimes only once) and other are more available. if people are available only for this time, prioritize them so they are not left behind.
|
// 4. Some publishers are available only at specific time (somoetimes only once) and other are more available. if people are available only for this time, prioritize them so they are not left behind.
|
||||||
5. prioritize based on publisher's desiredShiftsPerMonth and previous months assignments.
|
// 5. prioritize based on publisher's desiredShiftsPerMonth and previous months assignments.
|
||||||
6. Idealy noone should be more than once a week. disqualify publishers already on a shift this week. only assign them if there are no other options and we have less than 3 publishers on a specific shift.
|
// 6. Idealy noone should be more than once a week. disqualify publishers already on a shift this week. only assign them if there are no other options and we have less than 3 publishers on a specific shift.
|
||||||
*
|
// *
|
||||||
* @param {Axios} axios Axios instance for making requests.
|
// * @param {Axios} axios Axios instance for making requests.
|
||||||
* @param {string} date The date for the schedule.
|
// * @param {string} date The date for the schedule.
|
||||||
* @param {boolean} [copyFromPreviousMonth=false] Whether to copy from the previous month.
|
// * @param {boolean} [copyFromPreviousMonth=false] Whether to copy from the previous month.
|
||||||
* @param {boolean} [autoFill=false] Whether to autofill data.
|
// * @param {boolean} [autoFill=false] Whether to autofill data.
|
||||||
* @param {boolean} forDay Specific day flag.
|
// * @param {boolean} forDay Specific day flag.
|
||||||
*/
|
// */
|
||||||
async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, autoFill = false, forDay) {
|
// async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, autoFill = false, forDay) {
|
||||||
let missingPublishers = [];
|
// let missingPublishers = [];
|
||||||
let publishersWithChangedPref = [];
|
// let publishersWithChangedPref = [];
|
||||||
|
|
||||||
const prisma = common.getPrismaClient();
|
// const prisma = common.getPrismaClient();
|
||||||
try {
|
// try {
|
||||||
const monthInfo = common.getMonthDatesInfo(new Date(date));
|
// const monthInfo = common.getMonthDatesInfo(new Date(date));
|
||||||
const lastMonthInfo = common.getMonthDatesInfo(new Date(monthInfo.date.getFullYear(), monthInfo.date.getMonth() - 1, 1));
|
// const lastMonthInfo = common.getMonthDatesInfo(new Date(monthInfo.date.getFullYear(), monthInfo.date.getMonth() - 1, 1));
|
||||||
|
|
||||||
if (forDay) {
|
// if (forDay) {
|
||||||
await DeleteShiftsForDay(monthInfo.date);
|
// await DeleteShiftsForDay(monthInfo.date);
|
||||||
} else {
|
// } else {
|
||||||
await DeleteShiftsForMonth(monthInfo);
|
// await DeleteShiftsForMonth(monthInfo);
|
||||||
}
|
// }
|
||||||
|
|
||||||
const events = await prisma.cartEvent.findMany({
|
// const events = await prisma.cartEvent.findMany({
|
||||||
where: {
|
// where: {
|
||||||
isActive: true
|
// isActive: true
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
let shiftsLastMonth = await getShiftsFromLastMonth(lastMonthInfo);
|
// let shiftsLastMonth = await getShiftsFromLastMonth(lastMonthInfo);
|
||||||
let publishers = await getAllPublishersWithStatisticsMonth('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', date, false, true, false, true, true);
|
// let publishers = await getAllPublishersWithStatisticsMonth('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', date, false, true, false, true, true);
|
||||||
|
|
||||||
let shiftAssignments = [];
|
// let shiftAssignments = [];
|
||||||
let day = new Date(monthInfo.firstMonday);
|
// let day = new Date(monthInfo.firstMonday);
|
||||||
let endDate = monthInfo.lastSunday;
|
// let endDate = monthInfo.lastSunday;
|
||||||
let dayNr = 1;
|
// let dayNr = 1;
|
||||||
let weekNr = 1;
|
// let weekNr = 1;
|
||||||
|
|
||||||
if (forDay) {
|
// if (forDay) {
|
||||||
day = monthInfo.date;
|
// day = monthInfo.date;
|
||||||
endDate.setDate(monthInfo.date.getDate() + 1);
|
// endDate.setDate(monthInfo.date.getDate() + 1);
|
||||||
dayNr = monthInfo.date.getDate();
|
// dayNr = monthInfo.date.getDate();
|
||||||
weekNr = common.getWeekNumber(monthInfo.date);
|
// weekNr = common.getWeekNumber(monthInfo.date);
|
||||||
}
|
// }
|
||||||
|
|
||||||
let publishersThisWeek = [];
|
// let publishersThisWeek = [];
|
||||||
|
|
||||||
// 0. generate shifts and assign publishers from the previous month if still available
|
// // 0. generate shifts and assign publishers from the previous month if still available
|
||||||
while (day < endDate) {
|
// while (day < endDate) {
|
||||||
let availablePubsForTheDay = await filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, true);
|
// let availablePubsForTheDay = await filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, true);
|
||||||
console.log("passing schedule generation for " + day.toLocaleDateString());
|
// console.log("passing schedule generation for " + day.toLocaleDateString());
|
||||||
const dayOfM = day.getDate();
|
// const dayOfM = day.getDate();
|
||||||
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
// let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
||||||
let dayName = common.DaysOfWeekArray[day.getDayEuropean()];
|
// let dayName = common.DaysOfWeekArray[day.getDayEuropean()];
|
||||||
const event = events.find((event) => event.dayofweek == dayName && (event.dayOfMonth == null || event.dayOfMonth == dayOfM));
|
// const event = events.find((event) => event.dayofweek == dayName && (event.dayOfMonth == null || event.dayOfMonth == dayOfM));
|
||||||
|
|
||||||
if (!event) {
|
// if (!event) {
|
||||||
day.setDate(day.getDate() + 1);
|
// day.setDate(day.getDate() + 1);
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
event.startTime = new Date(event.startTime);
|
// event.startTime = new Date(event.startTime);
|
||||||
event.endTime = new Date(event.endTime);
|
// event.endTime = new Date(event.endTime);
|
||||||
|
|
||||||
let startTime = new Date(day);
|
// let startTime = new Date(day);
|
||||||
startTime.setHours(event.startTime.getHours());
|
// startTime.setHours(event.startTime.getHours());
|
||||||
startTime.setMinutes(event.startTime.getMinutes());
|
// startTime.setMinutes(event.startTime.getMinutes());
|
||||||
let endTime = new Date(day);
|
// let endTime = new Date(day);
|
||||||
endTime.setHours(event.endTime.getHours());
|
// endTime.setHours(event.endTime.getHours());
|
||||||
endTime.setMinutes(event.endTime.getMinutes());
|
// endTime.setMinutes(event.endTime.getMinutes());
|
||||||
|
|
||||||
let shiftStart = new Date(startTime);
|
// let shiftStart = new Date(startTime);
|
||||||
let shiftEnd = new Date(startTime);
|
// let shiftEnd = new Date(startTime);
|
||||||
shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration);
|
// shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration);
|
||||||
|
|
||||||
let shiftNr = 0;
|
// let shiftNr = 0;
|
||||||
while (shiftEnd <= endTime) {
|
// while (shiftEnd <= endTime) {
|
||||||
shiftNr++;
|
// shiftNr++;
|
||||||
const __shiftName = String(shiftStart.getHours()).padStart(2, "0") + ":" + String(shiftStart.getMinutes()).padStart(2, "0") + " - " + String(shiftEnd.getHours()).padStart(2, "0") + ":" + String(shiftEnd.getMinutes()).padStart(2, "0");
|
// const __shiftName = String(shiftStart.getHours()).padStart(2, "0") + ":" + String(shiftStart.getMinutes()).padStart(2, "0") + " - " + String(shiftEnd.getHours()).padStart(2, "0") + ":" + String(shiftEnd.getMinutes()).padStart(2, "0");
|
||||||
shiftAssignments = [];
|
// shiftAssignments = [];
|
||||||
let isTransportRequired = shiftNr == 1 || shiftEnd.getTime() == endTime.getTime();
|
// let isTransportRequired = shiftNr == 1 || shiftEnd.getTime() == endTime.getTime();
|
||||||
|
|
||||||
const shiftLastMonthSameDay = findTheSameShiftFromLastMonth(shiftsLastMonth, day, weekNr, shiftNr);
|
// const shiftLastMonthSameDay = findTheSameShiftFromLastMonth(shiftsLastMonth, day, weekNr, shiftNr);
|
||||||
|
|
||||||
if (shiftLastMonthSameDay) {
|
// if (shiftLastMonthSameDay) {
|
||||||
for (let assignment of shiftLastMonthSameDay.assignments) {
|
// for (let assignment of shiftLastMonthSameDay.assignments) {
|
||||||
let publisher = assignment.publisher;
|
// let publisher = assignment.publisher;
|
||||||
console.log("found publisher from last month: " + publisher.firstName + " " + publisher.lastName);
|
// console.log("found publisher from last month: " + publisher.firstName + " " + publisher.lastName);
|
||||||
let availability = await FindPublisherAvailability(publisher.id, shiftStart, shiftEnd, dayOfWeekEnum, weekNr);
|
// let availability = await FindPublisherAvailability(publisher.id, shiftStart, shiftEnd, dayOfWeekEnum, weekNr);
|
||||||
console.log("availability " + availability?.id + ": " + common.getDateFormattedShort(availability?.startTime) + " " + common.getTimeFormatted(availability?.startTime) + " - " + common.getTimeFormatted(availability?.endTime));
|
// console.log("availability " + availability?.id + ": " + common.getDateFormattedShort(availability?.startTime) + " " + common.getTimeFormatted(availability?.startTime) + " - " + common.getTimeFormatted(availability?.endTime));
|
||||||
|
|
||||||
if (availability && copyFromPreviousMonth && !publishersThisWeek.includes(publisher.id)) {
|
// if (availability && copyFromPreviousMonth && !publishersThisWeek.includes(publisher.id)) {
|
||||||
shiftAssignments.push({
|
// shiftAssignments.push({
|
||||||
publisherId: publisher.id,
|
// publisherId: publisher.id,
|
||||||
isConfirmed: true,
|
// isConfirmed: true,
|
||||||
isWithTransportIn: availability.isWithTransportIn,
|
// isWithTransportIn: availability.isWithTransportIn,
|
||||||
isWithTransportOut: availability.isWithTransportOut
|
// isWithTransportOut: availability.isWithTransportOut
|
||||||
});
|
// });
|
||||||
publishersThisWeek.push(publisher.id);
|
// publishersThisWeek.push(publisher.id);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
let publishersNeeded = event.numberOfPublishers - shiftAssignments.length;
|
// let publishersNeeded = event.numberOfPublishers - shiftAssignments.length;
|
||||||
//ToDo: check if getAvailablePublishersForShift is working correctly
|
// //ToDo: check if getAvailablePublishersForShift is working correctly
|
||||||
let availablePublishers = await getAvailablePublishersForShift(shiftStart, shiftEnd, publishers, publishersThisWeek);
|
// let availablePublishers = await getAvailablePublishersForShift(shiftStart, shiftEnd, publishers, publishersThisWeek);
|
||||||
|
|
||||||
console.log("shift " + __shiftName + " needs " + publishersNeeded + " publishers, available: " + availablePublishers.length + " for the day: " + availablePubsForTheDay.length);
|
// console.log("shift " + __shiftName + " needs " + publishersNeeded + " publishers, available: " + availablePublishers.length + " for the day: " + availablePubsForTheDay.length);
|
||||||
|
|
||||||
// Prioritize publishers with minimal availability
|
// // Prioritize publishers with minimal availability
|
||||||
// SKIP ADDING PUBLISHERS FOR NOW
|
// // SKIP ADDING PUBLISHERS FOR NOW
|
||||||
// availablePublishers = availablePublishers.sort((a, b) => a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount);
|
// // availablePublishers = availablePublishers.sort((a, b) => a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount);
|
||||||
|
|
||||||
// for (let i = 0; i < publishersNeeded; i++) {
|
// // for (let i = 0; i < publishersNeeded; i++) {
|
||||||
// if (availablePublishers[i]) {
|
// // if (availablePublishers[i]) {
|
||||||
// shiftAssignments.push({ publisherId: availablePublishers[i].id });
|
// // shiftAssignments.push({ publisherId: availablePublishers[i].id });
|
||||||
// publishersThisWeek.push(availablePublishers[i].id);
|
// // publishersThisWeek.push(availablePublishers[i].id);
|
||||||
// }
|
// // }
|
||||||
// }
|
// // }
|
||||||
|
|
||||||
const createdShift = await prisma.shift.create({
|
// const createdShift = await prisma.shift.create({
|
||||||
data: {
|
// data: {
|
||||||
startTime: shiftStart,
|
// startTime: shiftStart,
|
||||||
endTime: shiftEnd,
|
// endTime: shiftEnd,
|
||||||
name: event.dayofweek + " " + shiftStart.toLocaleTimeString() + " - " + shiftEnd.toLocaleTimeString(),
|
// name: event.dayofweek + " " + shiftStart.toLocaleTimeString() + " - " + shiftEnd.toLocaleTimeString(),
|
||||||
requiresTransport: isTransportRequired,
|
// requiresTransport: isTransportRequired,
|
||||||
cartEvent: {
|
// cartEvent: {
|
||||||
connect: {
|
// connect: {
|
||||||
id: event.id,
|
// id: event.id,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
assignments: {
|
// assignments: {
|
||||||
create: shiftAssignments.map((a) => {
|
// create: shiftAssignments.map((a) => {
|
||||||
return {
|
// return {
|
||||||
publisher: {
|
// publisher: {
|
||||||
connect: { id: a.publisherId }
|
// connect: { id: a.publisherId }
|
||||||
},
|
// },
|
||||||
isConfirmed: a.isConfirmed,
|
// isConfirmed: a.isConfirmed,
|
||||||
isBySystem: true,
|
// isBySystem: true,
|
||||||
};
|
// };
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
shiftStart = new Date(shiftEnd);
|
// shiftStart = new Date(shiftEnd);
|
||||||
shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration);
|
// shiftEnd.setMinutes(shiftStart.getMinutes() + event.shiftDuration);
|
||||||
}
|
// }
|
||||||
|
|
||||||
day.setDate(day.getDate() + 1);
|
// day.setDate(day.getDate() + 1);
|
||||||
dayNr++;
|
// dayNr++;
|
||||||
if (common.DaysOfWeekArray[day.getDayEuropean()] === DayOfWeek.Sunday) {
|
// if (common.DaysOfWeekArray[day.getDayEuropean()] === DayOfWeek.Sunday) {
|
||||||
weekNr++;
|
// weekNr++;
|
||||||
publishersThisWeek = [];
|
// publishersThisWeek = [];
|
||||||
publishers.forEach(p => p.currentWeekAssignments = 0);
|
// publishers.forEach(p => p.currentWeekAssignments = 0);
|
||||||
}
|
// }
|
||||||
if (forDay) break;
|
// if (forDay) break;
|
||||||
}
|
// }
|
||||||
|
|
||||||
let allShifts = await prisma.shift.findMany({
|
// let allShifts = await prisma.shift.findMany({
|
||||||
where: {
|
// where: {
|
||||||
startTime: {
|
// startTime: {
|
||||||
gte: monthInfo.firstMonday,
|
// gte: monthInfo.firstMonday,
|
||||||
lt: monthInfo.lastSunday,
|
// lt: monthInfo.lastSunday,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
include: {
|
// include: {
|
||||||
assignments: {
|
// assignments: {
|
||||||
include: {
|
// include: {
|
||||||
publisher: true,
|
// publisher: true,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
console.log(" second pass " + monthInfo.monthName + " " + monthInfo.year);
|
// console.log(" second pass " + monthInfo.monthName + " " + monthInfo.year);
|
||||||
// 2. First pass - prioritize shifts with transport where it is needed
|
// // 2. First pass - prioritize shifts with transport where it is needed
|
||||||
day = monthInfo.firstMonday;
|
// day = monthInfo.firstMonday;
|
||||||
dayNr = 1;
|
// dayNr = 1;
|
||||||
weekNr = 1;
|
// weekNr = 1;
|
||||||
while (day < endDate) {
|
// while (day < endDate) {
|
||||||
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
// let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(day);
|
||||||
let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]);
|
// let event = events.find((event) => event.dayofweek == common.DaysOfWeekArray[day.getDayEuropean()]);
|
||||||
if (event) {
|
// if (event) {
|
||||||
let availablePubsForTheDay = await filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, true);
|
// let availablePubsForTheDay = await filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', day, false, false, false, true, true);
|
||||||
|
|
||||||
let shifts = allShifts.filter(s => common.getISODateOnly(s.startTime) === common.getISODateOnly(day));
|
// let shifts = allShifts.filter(s => common.getISODateOnly(s.startTime) === common.getISODateOnly(day));
|
||||||
let transportShifts = shifts.filter(s => s.requiresTransport);
|
// let transportShifts = shifts.filter(s => s.requiresTransport);
|
||||||
transportShifts.forEach(shift => {
|
// transportShifts.forEach(shift => {
|
||||||
let availablePublishers = availablePubsForTheDay.filter(p => !shift.assignments.some(a => a.publisher.id === p.id));
|
// let availablePublishers = availablePubsForTheDay.filter(p => !shift.assignments.some(a => a.publisher.id === p.id));
|
||||||
availablePublishers = availablePublishers.sort((a, b) => a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount);
|
// availablePublishers = availablePublishers.sort((a, b) => a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount);
|
||||||
let publishersNeeded = event.numberOfPublishers - shift.assignments.length;
|
// let publishersNeeded = event.numberOfPublishers - shift.assignments.length;
|
||||||
if (publishersNeeded > 0) {//get the beset match
|
// if (publishersNeeded > 0) {//get the beset match
|
||||||
if (availablePublishers[0]) {
|
// if (availablePublishers[0]) {
|
||||||
shift.assignments.push({ publisherId: availablePublishers[i].id });
|
// shift.assignments.push({ publisherId: availablePublishers[i].id });
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
// 3. Second pass - fill the rest of the shifts
|
// // 3. Second pass - fill the rest of the shifts
|
||||||
let shiftsToFill = shifts.filter(s => !s.requiresTransport);
|
// let shiftsToFill = shifts.filter(s => !s.requiresTransport);
|
||||||
shiftsToFill.forEach(shift => {
|
// shiftsToFill.forEach(shift => {
|
||||||
let availablePublishers = availablePubsForTheDay.filter(p => !shift.assignments.some(a => a.publisher.id === p.id));
|
// let availablePublishers = availablePubsForTheDay.filter(p => !shift.assignments.some(a => a.publisher.id === p.id));
|
||||||
availablePublishers = availablePublishers.sort((a, b) => a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount);
|
// availablePublishers = availablePublishers.sort((a, b) => a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount);
|
||||||
let publishersNeeded = event.numberOfPublishers - shift.assignments.length;
|
// let publishersNeeded = event.numberOfPublishers - shift.assignments.length;
|
||||||
if (publishersNeeded > 0) {//get the beset match
|
// if (publishersNeeded > 0) {//get the beset match
|
||||||
if (availablePublishers[0]) {
|
// if (availablePublishers[0]) {
|
||||||
shift.assignments.push({ publisherId: availablePublishers[i].id });
|
// shift.assignments.push({ publisherId: availablePublishers[i].id });
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
day.setDate(day.getDate() + 1);
|
// day.setDate(day.getDate() + 1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!forDay) {
|
// if (!forDay) {
|
||||||
console.log("###############################################");
|
// console.log("###############################################");
|
||||||
console.log(" DONE CREATING SCHEDULE FOR " + monthInfo.monthName + " " + monthInfo.year);
|
// console.log(" DONE CREATING SCHEDULE FOR " + monthInfo.monthName + " " + monthInfo.year);
|
||||||
console.log("###############################################");
|
// console.log("###############################################");
|
||||||
}
|
// }
|
||||||
|
|
||||||
return {};
|
// return {};
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
console.log(error);
|
// console.log(error);
|
||||||
return { error: error };
|
// return { error: error };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// async function getShiftsFromLastMonth(monthInfo) {
|
||||||
|
// const prisma = common.getPrismaClient();
|
||||||
|
// // Fetch shifts for the month
|
||||||
|
// const rawShifts = await prisma.shift.findMany({
|
||||||
|
// where: {
|
||||||
|
// startTime: {
|
||||||
|
// gte: monthInfo.firstMonday,
|
||||||
|
// lte: monthInfo.lastSunday,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// include: {
|
||||||
|
// assignments: {
|
||||||
|
// include: {
|
||||||
|
// publisher: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Process shifts to add weekNr and shiftNr
|
||||||
|
// return rawShifts.map(shift => ({
|
||||||
|
// ...shift,
|
||||||
|
// weekNr: common.getWeekNumber(new Date(shift.startTime)),
|
||||||
|
// shiftNr: rawShifts.filter(s => common.getISODateOnly(s.startTime) === common.getISODateOnly(shift.startTime)).indexOf(shift) + 1,
|
||||||
|
// weekDay: common.DaysOfWeekArray[new Date(shift.startTime).getDayEuropean()],
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
// function findTheSameShiftFromLastMonth(shiftsLastMonth, day, weekNr, shiftNr) {
|
||||||
|
// let weekDay = common.DaysOfWeekArray[day.getDayEuropean()];
|
||||||
|
// return shiftsLastMonth.find(s => {
|
||||||
|
// return s.weekNr === weekNr &&
|
||||||
|
// s.shiftNr === shiftNr &&
|
||||||
|
// s.weekDay === weekDay;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //ToDo use bulk find instead of loop
|
||||||
|
// async function getAvailablePublishersForShift(startTime, endTime, allPublishers, publishersThisWeek) {
|
||||||
|
// let availablePublishers = [];
|
||||||
|
|
||||||
|
// for (let publisher of allPublishers) {
|
||||||
|
// let availability = await FindPublisherAvailability(publisher.id, startTime, endTime);
|
||||||
|
|
||||||
|
// if (availability && !publishersThisWeek.includes(publisher.id)) {
|
||||||
|
// availablePublishers.push(publisher);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return availablePublishers;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// ### COPIED TO shift api (--) ###
|
||||||
|
|
||||||
async function DeleteShiftsForMonth(monthInfo) {
|
async function DeleteShiftsForMonth(monthInfo) {
|
||||||
try {
|
try {
|
||||||
@ -1110,57 +1166,6 @@ async function DeleteShiftsForDay(date) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getShiftsFromLastMonth(monthInfo) {
|
|
||||||
const prisma = common.getPrismaClient();
|
|
||||||
// Fetch shifts for the month
|
|
||||||
const rawShifts = await prisma.shift.findMany({
|
|
||||||
where: {
|
|
||||||
startTime: {
|
|
||||||
gte: monthInfo.firstMonday,
|
|
||||||
lte: monthInfo.lastSunday,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
include: {
|
|
||||||
assignments: {
|
|
||||||
include: {
|
|
||||||
publisher: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Process shifts to add weekNr and shiftNr
|
|
||||||
return rawShifts.map(shift => ({
|
|
||||||
...shift,
|
|
||||||
weekNr: common.getWeekNumber(new Date(shift.startTime)),
|
|
||||||
shiftNr: rawShifts.filter(s => common.getISODateOnly(s.startTime) === common.getISODateOnly(shift.startTime)).indexOf(shift) + 1,
|
|
||||||
weekDay: common.DaysOfWeekArray[new Date(shift.startTime).getDayEuropean()],
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
function findTheSameShiftFromLastMonth(shiftsLastMonth, day, weekNr, shiftNr) {
|
|
||||||
let weekDay = common.DaysOfWeekArray[day.getDayEuropean()];
|
|
||||||
return shiftsLastMonth.find(s => {
|
|
||||||
return s.weekNr === weekNr &&
|
|
||||||
s.shiftNr === shiftNr &&
|
|
||||||
s.weekDay === weekDay;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//ToDo use bulk find instead of loop
|
|
||||||
async function getAvailablePublishersForShift(startTime, endTime, allPublishers, publishersThisWeek) {
|
|
||||||
let availablePublishers = [];
|
|
||||||
|
|
||||||
for (let publisher of allPublishers) {
|
|
||||||
let availability = await FindPublisherAvailability(publisher.id, startTime, endTime);
|
|
||||||
|
|
||||||
if (availability && !publishersThisWeek.includes(publisher.id)) {
|
|
||||||
availablePublishers.push(publisher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return availablePublishers;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function FindPublisherAvailability(publisherId, startDate, endDate, dayOfWeekEnum, weekNr) {
|
async function FindPublisherAvailability(publisherId, startDate, endDate, dayOfWeekEnum, weekNr) {
|
||||||
const prisma = common.getPrismaClient();
|
const prisma = common.getPrismaClient();
|
||||||
const start = new Date(startDate);
|
const start = new Date(startDate);
|
||||||
@ -1220,9 +1225,6 @@ async function FindPublisherAvailability(publisherId, startDate, endDate, dayOfW
|
|||||||
return exactAvailabilities.length > 0 ? exactAvailabilities[0] : repeatingAvailabilities.length > 0 ? repeatingAvailabilities[0] : null;
|
return exactAvailabilities.length > 0 ? exactAvailabilities[0] : repeatingAvailabilities.length > 0 ? repeatingAvailabilities[0] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ### COPIED TO shift api (--) ###
|
|
||||||
|
|
||||||
|
|
||||||
// function matchesAvailability(avail, filterDate) {
|
// function matchesAvailability(avail, filterDate) {
|
||||||
// // Setting the start and end time of the filterDate
|
// // Setting the start and end time of the filterDate
|
||||||
// filterDate.setHours(0, 0, 0, 0);
|
// filterDate.setHours(0, 0, 0, 0);
|
||||||
@ -1268,7 +1270,7 @@ module.exports = {
|
|||||||
getCoverMePublisherEmails,
|
getCoverMePublisherEmails,
|
||||||
getAllPublishersWithStatisticsMonth,
|
getAllPublishersWithStatisticsMonth,
|
||||||
getCalendarEvents,
|
getCalendarEvents,
|
||||||
GenerateSchedule,
|
// GenerateSchedule,
|
||||||
DeleteShiftsForMonth,
|
DeleteShiftsForMonth,
|
||||||
DeleteShiftsForDay,
|
DeleteShiftsForDay,
|
||||||
};
|
};
|
Reference in New Issue
Block a user