improve schift generation

This commit is contained in:
Dobromir Popov
2024-05-26 11:54:22 +03:00
parent 7510c4c705
commit 870ab6fea4

View File

@ -682,23 +682,19 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
} }
else if (publishersNeeded > 0) { else if (publishersNeeded > 0) {
console.log("shift " + shift.name + " requires transport (" + transportCapable.length + " transport capable)"); console.log("shift " + shift.name + " requires transport (" + transportCapable.length + " transport capable)");
// let availablePublishers = availablePubsForTheDay.filter(p => !shift.assignments.some(a => a.publisher.id === p.id));
let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false); let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false);
// let availablePublishers = availablePubsForTheShift.filter(p =>
// (shift.transportIn && p.availabilities.some(avail => (avail.isWithTransportIn))
// || (shift.transportOut && p.availabilities.some(avail => (avail.isWithTransportOut))))
// && !shift.assignments.some(a => a.publisher.id === p.id));
let availablePublishers = availablePubsForTheShift.filter(p => { let availablePublishers = availablePubsForTheShift.filter(p => {
const hasTransportInAvailability = shift.transportIn && p.availabilities.some(avail => avail.isWithTransportIn); const hasTransportInAvailability = shift.transportIn && p.availabilities.some(avail => avail.isWithTransportIn);
const hasTransportOutAvailability = shift.transportOut && p.availabilities.some(avail => avail.isWithTransportOut); const hasTransportOutAvailability = shift.transportOut && p.availabilities.some(avail => avail.isWithTransportOut);
const isNotAssigned = !shift.assignments.some(a => a.publisher.id === p.id);
const isNotAssignedToday = !publishersToday.includes(p.id)
return (hasTransportInAvailability || hasTransportOutAvailability) && isNotAssigned && isNotAssignedToday; return (hasTransportInAvailability || hasTransportOutAvailability);
}); });
availablePublishers = await FilterInappropriatePublishers([...availablePublishers], publishersToday, shift);
// rank publishers based on different factors // rank publishers based on different factors
let rankedPublishersOld = await RankPublishersForShift(availablePublishers) let rankedPublishersOld = await RankPublishersForShift([...availablePublishers])
let rankedPublishers = await RankPublishersForShiftWeighted(availablePublishers) let rankedPublishers = await RankPublishersForShiftWeighted([...availablePublishers])
if (rankedPublishers.length > 0) { if (rankedPublishers.length > 0) {
const newAssignment = await prisma.assignment.create({ const newAssignment = await prisma.assignment.create({
data: { data: {
@ -768,21 +764,10 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
if (publishersNeeded > 0 && shift.assignments.length < goal) { if (publishersNeeded > 0 && shift.assignments.length < goal) {
let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false); let availablePubsForTheShift = await data.filterPublishersNew('id,firstName,lastName,email,isActive,desiredShiftsPerMonth,lastLogin,type', shift.startTime, true, false, false, true, false);
//ToDo: Optimization: store number of publishers, so we process the shifts from least to most available publishers later. let availablePublishers = await FilterInappropriatePublishers([...availablePubsForTheShift], publishersToday, shift);
let availablePublishers = availablePubsForTheShift.filter(p => {
const isNotAssigned = !shift.assignments.some(a => a.publisher?.id === p.id);
const isNotAssignedToday = !publishersToday.includes(p.id);
const isAssignedEnough = p.currentMonthAssignments >= p.desiredShiftsPerMonth;
//if (isAssignedEnough) console.log(p.firstName + " " + p.lastName + " is assigned enough: " + p.currentMonthAssignments + " >= " + p.desiredShiftsPerMonth);
return isNotAssigned && isNotAssignedToday && !isAssignedEnough;
});
shift.availablePublishers = availablePublishers.length; shift.availablePublishers = availablePublishers.length;
let rankedPublishers = await RankPublishersForShift(availablePublishers) let rankedPublishers = await RankPublishersForShift([...availablePublishers])
if (rankedPublishers.length == 0) { if (rankedPublishers.length == 0) {
console.log("No available publishers for shift " + shift.name); console.log("No available publishers for shift " + shift.name);
} else if (rankedPublishers.length > 0) { } else if (rankedPublishers.length > 0) {
@ -857,6 +842,19 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
} }
} }
async function FilterInappropriatePublishers(availablePublishers, pubsToExclude, shift) {
//ToDo: Optimization: store number of publishers, so we process the shifts from least to most available publishers later.
let goodPublishers = availablePublishers.filter(p => {
const isNotAssigned = !shift.assignments.some(a => a.publisher?.id === p.id);
const isNotAssignedToday = !pubsToExclude.includes(p.id);
const isAssignedEnough = p.currentMonthAssignments >= p.desiredShiftsPerMonth;
//if (isAssignedEnough) console.log(p.firstName + " " + p.lastName + " is assigned enough: " + p.currentMonthAssignments + " >= " + p.desiredShiftsPerMonth);
return isNotAssigned && isNotAssignedToday && !isAssignedEnough;
});
return goodPublishers;
}
//General guidelines affecting ranking of publishers for shift assignment //General guidelines affecting ranking of publishers for shift assignment
// 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.
@ -899,6 +897,7 @@ async function RankPublishersForShift(publishers) {
return ranked; return ranked;
} }
// ToDo: add negative weights for currentweekAssignments, so we avoid assigning the same publishers multiple times in a week. having in mind the days difference between shifts.
async function RankPublishersForShiftWeighted(publishers) { async function RankPublishersForShiftWeighted(publishers) {
// Define weights for each criterion // Define weights for each criterion
const weights = { const weights = {