(wip) schedle generation;

added confirmations on schedule  DELETE!!!
better reports page;
log every delete over API, more logging;
This commit is contained in:
Dobromir Popov
2024-05-24 12:53:17 +03:00
parent 73ac798a6d
commit 2202e8b1b4
9 changed files with 166 additions and 64 deletions

View File

@ -10,7 +10,7 @@ import { filterPublishers, /* other functions */ } from './index';
import CAL from "../../src/helpers/calendar";
//const common = require("@common");
import common from "../../src/helpers/common";
import common, { logger } from "../../src/helpers/common";
import data from "../../src/helpers/data";
import { Axios } from 'axios';
@ -59,6 +59,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
break;
case "delete":
result = await DeleteSchedule(axios, req.query.date, common.parseBool(req.query.forDay));
let msg = "Deleted schedule for " + (req.query.forDay ? req.query.date : "the entire month of ") + req.query.date + ". Action requested by " + token.email;
logger.warn(msg);
console.log(msg);
res.send("deleted"); // JSON.stringify(result, null, 2)
break;
case "createcalendarevent":
@ -694,7 +697,8 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
return (hasTransportInAvailability || hasTransportOutAvailability) && isNotAssigned && isNotAssignedToday;
});
// rank publishers based on different factors
let rankedPublishers = await RankPublishersForShift(availablePublishers)
let rankedPublishersOld = await RankPublishersForShift(availablePublishers)
let rankedPublishers = await RankPublishersForShiftWeighted(availablePublishers)
if (rankedPublishers.length > 0) {
const newAssignment = await prisma.assignment.create({
data: {
@ -801,36 +805,36 @@ async function GenerateSchedule(axios, date, copyFromPreviousMonth = false, auto
});
shift.assignments.push(newAssignment);
publishersToday.push(rankedPublishers[0].id);
}
//check if publisher.familyMembers are also available and add them to the shift. ToDo: test case
let familyMembers = availablePubsForTheShift.filter(p => p.familyHeadId && p.familyHeadId === rankedPublishers[0].familyHeadId);
if (familyMembers.length > 0) {
familyMembers.forEach(async familyMember => {
if (shift.assignments.length < event.numberOfPublishers) {
console.log("Assigning " + familyMember.firstName + " " + familyMember.lastName + " to " + shift.startDate.getDate() + " " + shift.name);
const newAssignment = await prisma.assignment.create({
data: {
shift: {
connect: {
id: shift.id,
//check if publisher.familyMembers are also available and add them to the shift. ToDo: test case
let familyMembers = availablePubsForTheShift.filter(p => p.familyHeadId && p.familyHeadId === rankedPublishers[0].familyHeadId);
if (familyMembers.length > 0) {
familyMembers.forEach(async familyMember => {
if (shift.assignments.length < event.numberOfPublishers) {
console.log("Assigning " + familyMember.firstName + " " + familyMember.lastName + " to " + shift.startDate.getDate() + " " + shift.name);
const newAssignment = await prisma.assignment.create({
data: {
shift: {
connect: {
id: shift.id,
},
},
},
publisher: {
connect: {
id: familyMember.id,
publisher: {
connect: {
id: familyMember.id,
},
},
isConfirmed: true,
isBySystem: false,
},
isConfirmed: true,
isBySystem: false,
},
});
shift.assignments.push(newAssignment);
publishersToday.push(familyMember.id);
}
});
});
shift.assignments.push(newAssignment);
publishersToday.push(familyMember.id);
}
});
}
}
}
};
}
@ -887,9 +891,6 @@ async function RankPublishersForShift(publishers) {
const availabilityDifference = a.currentMonthAvailabilityHoursCount - b.currentMonthAvailabilityHoursCount;
if (availabilityDifference !== 0) return availabilityDifference;
// biggest difference between desired and current assignments first (descending)
const desiredCurrentDifference = b.DesiredMinusCurrent - a.DesiredMinusCurrent;
if (desiredCurrentDifference !== 0) return desiredCurrentDifference;
// less assigned first (ascending)
return a.currentMonthAssignments - b.currentMonthAssignments;
@ -897,6 +898,52 @@ async function RankPublishersForShift(publishers) {
return ranked;
}
async function RankPublishersForShiftWeighted(publishers) {
// Define weights for each criterion
const weights = {
gender: 2,
desiredCompletion: 3,
availability: 2,
lastMonthCompletion: 3,
currentAssignments: 1
};
// Normalize weights to ensure they sum to 1
const totalWeight = Object.values(weights).reduce((acc, val) => acc + val, 0);
Object.keys(weights).forEach(key => {
weights[key] /= totalWeight;
});
publishers.forEach(p => {
p.lastMonthCompletion = p.previousMonthAssignments / p.currentMonthAssignments;
p.desiredCompletion = p.currentMonthAssignments / p.desiredShiftsPerMonth;
});
let ranked = publishers.sort((a, b) => {
// Calculate weighted score for each publisher
const scoreA = (a.isMale ? weights.gender : 0) -
(a.desiredCompletion * weights.desiredCompletion) +
((1 - a.currentMonthAvailabilityHoursCount / 24) * weights.availability) +
(a.currentMonthAssignments * weights.lastMonthCompletion) -
(a.currentMonthAssignments * weights.currentAssignments);
const scoreB = (b.isMale ? weights.gender : 0) -
(b.desiredCompletion * weights.desiredCompletion) +
((1 - b.currentMonthAvailabilityHoursCount / 24) * weights.availability) +
(b.currentMonthAssignments * weights.lastMonthCompletion) -
(b.currentMonthAssignments * weights.currentAssignments);
return scoreB - scoreA; // Sort descending by score
});
return ranked;
}
async function DeleteShiftsForMonth(monthInfo) {
try {
const prisma = common.getPrismaClient();