new coverMe routine; refactoring

This commit is contained in:
Dobromir Popov
2024-04-13 18:27:19 +03:00
parent 1b06e70734
commit af87b7d51b
7 changed files with 503 additions and 300 deletions

View File

@ -347,6 +347,43 @@ export default async function handler(req, res) {
res.status(200).json({ "message": "ok" });
break;
case "getPossibleShiftPublisherEmails":
const subscribedPublishers = await prisma.publisher.findMany({
where: {
isSubscribedToCoverMe: true
},
select: {
id: true,
firstName: true,
lastName: true,
email: true
}
}).then(pubs => {
return pubs.map(pub => {
return {
id: pub.id,
name: pub.firstName + " " + pub.lastName,
email: pub.email
}
});
});
let shift = await prisma.shift.findUnique({
where: {
id: parseInt(req.query.shiftId)
}
});
let availablePublishers = await filterPublishersNew_Available("id,firstName,lastName,email", new Date(shift.startTime), true, false);
//return names and email info only
availablePublishers = availablePublishers.map(pub => {
return {
id: pub.id,
name: pub.firstName + " " + pub.lastName,
email: pub.email
}
});
res.status(200).json({ shift, availablePublishers: availablePublishers, subscribedPublishers });
break;
default:
res.status(200).json({
@ -425,254 +462,7 @@ export async function getMonthlyStatistics(selectFields, filterDate) {
export async function filterPublishersNew_Available(selectFields, filterDate, isExactTime = false, isForTheMonth = false, isWithStats = true) {
// Only attempt to split if selectFields is a string; otherwise, use it as it is.
selectFields = typeof selectFields === 'string' ? selectFields.split(",") : selectFields;
let selectBase = selectFields.reduce((acc, curr) => {
acc[curr] = true;
return acc;
}, {});
selectBase.assignments = {
select: {
id: true,
shift: {
select: {
id: true,
startTime: true,
endTime: true
}
}
},
where: {
shift: {
startTime: {
gte: filterDate,
}
}
}
};
var monthInfo = common.getMonthDatesInfo(filterDate);
var weekNr = common.getWeekOfMonth(filterDate); //getWeekNumber
let dayOfWeekEnum = common.getDayOfWeekNameEnEnumForDate(filterDate);
if (!isExactTime) {
filterDate.setHours(0, 0, 0, 0); // Set to midnight
}
const filterDateEnd = new Date(filterDate);
filterDateEnd.setHours(23, 59, 59, 999);
let whereClause = {};
//if full day, match by date only
if (!isExactTime) { // Check only by date without considering time ( Assignments on specific days without time)
whereClause["availabilities"] = {
some: {
OR: [
{
startTime: { gte: filterDate },
endTime: { lte: filterDateEnd },
}
,
// Check if dayOfMonth is null and match by day of week using the enum (Assigments every week)
// This includes availabilities from previous assignments but not with preference
{
dayOfMonth: null, // includes monthly and weekly repeats
dayofweek: dayOfWeekEnum,
// ToDo: and weekOfMonth
startTime: { lte: filterDate },
AND: [
{
OR: [ // OR condition for repeatUntil to handle events that either end after filterDate or repeat forever
{ endDate: { gte: filterDate } },
{ endDate: null }
]
}
]
}
]
}
};
}
//if not full day, match by date and time
else {
//match exact time (should be same as data.findPublisherAvailability())
whereClause["availabilities"] = {
some: {
OR: [
// Check if dayOfMonth is set and filterDate is between start and end dates (Assignments on specific days AND time)
{
// dayOfMonth: filterDate.getDate(),
startTime: { lte: filterDate },
endTime: { gte: filterDate }
},
// Check if dayOfMonth is null and match by day of week using the enum (Assigments every week)
{
dayOfMonth: null,
dayofweek: dayOfWeekEnum,
startTime: { gte: filterDate },
AND: [
{
OR: [ // OR condition for repeatUntil to handle events that either end after filterDate or repeat forever
{ endDate: { gte: filterDate } },
{ endDate: null }
]
}
]
}
]
}
};
}
if (isForTheMonth) {
// If no filter date, return all publishers's availabilities for currentMonthStart
whereClause["availabilities"] = {
some: {
OR: [
// Check if dayOfMonth is not null and startTime is after currentMonthStart (Assignments on specific days AND time)
{
dayOfMonth: { not: null },
startTime: { gte: currentMonthStart },
endTime: { lte: currentMonthEnd }
},
// Check if dayOfMonth is null and match by day of week using the enum (Assigments every week)
{
dayOfMonth: null,
AND: [
{
OR: [ // OR condition for repeatUntil to handle events that either end after filterDate or repeat forever
{ endDate: { gte: filterDate } },
{ endDate: null }
]
}
]
}
]
}
};
}
console.log(`getting publishers for date: ${filterDate}, isExactTime: ${isExactTime}, isForTheMonth: ${isForTheMonth}`);
//include availabilities if flag is true
const prisma = common.getPrismaClient(); //why we need to get it again?
let publishers = await prisma.publisher.findMany({
where: whereClause,
select: {
...selectBase,
availabilities: true
}
});
console.log(`publishers: ${publishers.length}, WhereClause: ${JSON.stringify(whereClause)}`);
// convert matching weekly availabilities to availabilities for the day to make furter processing easier on the client.
// we trust that the filtering was OK, so we use the dateFilter as date.
publishers.forEach(pub => {
pub.availabilities = pub.availabilities.map(avail => {
if (avail.dayOfMonth == null) {
let newStart = new Date(filterDate);
newStart.setHours(avail.startTime.getHours(), avail.startTime.getMinutes(), 0, 0);
let newEnd = new Date(filterDate);
newEnd.setHours(avail.endTime.getHours(), avail.endTime.getMinutes(), 0, 0);
return {
...avail,
startTime: newStart,
endTime: newEnd
}
}
return avail;
});
});
let currentWeekStart: Date, currentWeekEnd: Date,
currentMonthStart: Date, currentMonthEnd: Date,
previousMonthStart: Date, previousMonthEnd: Date;
if (isWithStats) {
currentWeekStart = common.getStartOfWeek(filterDate);
currentWeekEnd = common.getEndOfWeek(filterDate);
currentMonthStart = monthInfo.firstMonday;
currentMonthEnd = monthInfo.lastSunday;
let prevMnt = new Date(filterDate)
prevMnt.setMonth(prevMnt.getMonth() - 1);
monthInfo = common.getMonthDatesInfo(prevMnt);
previousMonthStart = monthInfo.firstMonday;
previousMonthEnd = monthInfo.lastSunday;
//get if publisher has assignments for current weekday, week, current month, previous month
publishers.forEach(pub => {
// Filter assignments for current day
pub.currentDayAssignments = pub.assignments?.filter(assignment => {
return assignment.shift.startTime >= filterDate && assignment.shift.startTime <= filterDateEnd;
}).length;
// Filter assignments for current week
pub.currentWeekAssignments = pub.assignments?.filter(assignment => {
return assignment.shift.startTime >= currentWeekStart && assignment.shift.startTime <= currentWeekEnd;
}).length;
// Filter assignments for current month
pub.currentMonthAssignments = pub.assignments?.filter(assignment => {
return assignment.shift.startTime >= currentMonthStart && assignment.shift.startTime <= currentMonthEnd;
}).length;
// Filter assignments for previous month
pub.previousMonthAssignments = pub.assignments?.filter(assignment => {
return assignment.shift.startTime >= previousMonthStart && assignment.shift.startTime <= previousMonthEnd;
}).length;
});
}
//get the availabilities for the day. Calcullate:
//1. how many days the publisher is available for the current month - only with dayOfMonth
//2. how many days the publisher is available without dayOfMonth (previous months count)
//3. how many hours in total the publisher is available for the current month
publishers.forEach(pub => {
if (isWithStats) {
pub.currentMonthAvailability = pub.availabilities?.filter(avail => {
// return avail.dayOfMonth != null && avail.startTime >= currentMonthStart && avail.startTime <= currentMonthEnd;
return avail.startTime >= currentMonthStart && avail.startTime <= currentMonthEnd;
})
pub.currentMonthAvailabilityDaysCount = pub.currentMonthAvailability.length || 0;
// pub.currentMonthAvailabilityDaysCount += pub.availabilities.filter(avail => {
// return avail.dayOfMonth == null;
// }).length;
pub.currentMonthAvailabilityHoursCount = pub.currentMonthAvailability.reduce((acc, curr) => {
return acc + (curr.endTime.getTime() - curr.startTime.getTime()) / (1000 * 60 * 60);
}, 0);
//if pub has up-to-date availabilities (with dayOfMonth) for the current month
pub.hasUpToDateAvailabilities = pub.availabilities?.some(avail => {
return avail.dayOfMonth != null && avail.startTime >= currentMonthStart; // && avail.startTime <= currentMonthEnd;
});
}
//if pub has ever filled the form - if has availabilities which are not from previous assignments
pub.hasEverFilledForm = pub.availabilities?.some(avail => {
return avail.isFromPreviousAssignments == false;
});
//if pub has availabilities for the current day
pub.hasAvailabilityForCurrentDay = pub.availabilities?.some(avail => {
return avail.startTime >= filterDate && avail.startTime <= filterDateEnd;
});
});
if (isExactTime) {
// Post filter for time if dayOfMonth is null as we can't only by time for multiple dates in SQL
// Modify the availabilities array of the filtered publishers
publishers.forEach(pub => {
pub.availabilities = pub.availabilities?.filter(avail => matchesAvailability(avail, filterDate));
});
}
return publishers;
return data.filterPublishersNew(selectFields, filterDate, isExactTime, isForTheMonth, isWithStats);
}
// availabilites filter: