Files
mwitnessing/pages/api/schedule.ts
2024-12-02 16:14:28 +02:00

262 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// pages/api/shifts.ts
import axiosServer from '../../src/axiosServer';
import { getToken } from "next-auth/jwt";
import type { NextApiRequest, NextApiResponse } from "next";
import { Prisma, PrismaClient, DayOfWeek, Publisher, Shift } from "@prisma/client";
import { levenshteinEditDistance } from "levenshtein-edit-distance";
import { filterPublishers, /* other functions */ } from './index';
import CAL from "../../src/helpers/calendar";
//const common = require("@common");
import common from "../../src/helpers/common";
import { Axios } from 'axios';
const path = require("path");
const fs = require("fs");
const generateTemplateFile = async (data, templateSrc) => {
const handlebars = require("handlebars");
const htmlDocx = require("html-docx-js");
// Compile the Handlebars template
const template = handlebars.compile(templateSrc);
// Generate the HTML output using the template and the events data
const html = template(data);
return html;
}
function splitNotes(notes) {
if (!notes) {
return { notes: '', notes_bold: '' };
}
// Combine both dash types into a single pattern for the regex
const dashPattern = /[-]/g;
// Find all occurrences of either dash
let allDashes = [...notes.matchAll(dashPattern)];
if (allDashes.length === 0) {
// No dash found, return the original notes in both parts
return { notes: notes, notes_bold: '' };
}
// Get the index of the first and last dash
const firstDashIndex = allDashes[0].index;
const lastDashIndex = allDashes[allDashes.length - 1].index;
// Extract parts before the first dash and after the last dash
const notesBeforeFirstDash = notes.substring(0, firstDashIndex + 1);
const notesAfterLastDash = notes.substring(lastDashIndex + 1);
return {
notes: notesBeforeFirstDash,
notes_bold: notesAfterLastDash
};
}
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
console.log(req.url);
console.log(req.query);
const prisma = common.getPrismaClient();
// If you don't have the NEXTAUTH_SECRET environment variable set,
// you will have to pass your secret as `secret` to `getToken`
const axios = await axiosServer({ req: req, res: res });
const token = await getToken({ req: req });
if (!token) {
// If no token or invalid token, return unauthorized status
return res.status(401).json({ message: "Unauthorized" });
}
if (req.method === 'GET') {
const { year, month } = req.query;
//ToDo: maybe we don't need that anymore as we are publishing the shifts and show all published shifts
let fromDate = new Date();
fromDate.setDate(fromDate.getDate() - 1);
fromDate.setHours(0, 0, 0, 0);
if (year && month) {
fromDate = new Date(parseInt(year as string), parseInt(month as string) - 1, 1);
}
const monthInfo = common.getMonthDatesInfo(fromDate);
//let toDate = new Date(monthInfo.lastSunday);
if (year && month) {
fromDate = monthInfo.firstMonday;
}
try {
const shifts = await prisma.shift.findMany({
where: {
isActive: true,
isPublished: true,
// OR: [
// { isPublished: true },
// { user: { role: 'admin' } } // Todo: example. fix this
// ],
startTime: {
gte: fromDate,
//lt: toDate,
},
},
orderBy: {
startTime: 'asc',
},
include: {
assignments: {
where: {},
include: {
publisher: true,
},
},
cartEvent: {
include: {
location: true,
},
},
},
});
let json = JSON.stringify(shifts);
const groupedShifts = {};
const startDate = new Date(shifts[0].startTime);
let i = 0;
try {
for (const shift of shifts) {
i++;
const date = new Date(shift.startTime);
const day = common.getISODateOnly(date)
const time = common.getTimeRange(shift.startTime, shift.endTime); //common.getLocalTime(date);
if (!groupedShifts[day]) {
groupedShifts[day] = {};
}
if (!groupedShifts[day][time]) {
groupedShifts[day][time] = [];
}
// let { notes, notes_bold } = splitNotes(shift.notes);//.substring(Math.max(shift.notes.lastIndexOf("-"), shift.notes.lastIndexOf("")) + 1).trim() || "";
let notes = "", notes_bold = "";
if (shift.assignments.some(a => a.isWithTransport)) {
if (shift.requiresTransport) {
notes = "Транспорт: ";
notes_bold = " " + shift.assignments.filter(a => a.isWithTransport).map(a => common.getInitials(a.publisher.firstName + " " + a.publisher.lastName)).join(", ");
}
}
let shiftSchedule = {
date: date,
placeOfEvent: shift.cartEvent.location.name,
time: time,
requiresTransport: shift.requiresTransport,
//bold the text after - in the notes
notes: notes,
notes_bold: notes_bold,
names: shift.assignments.length > 0
? shift.assignments
.map((assignment) => {
return (
assignment.publisher.firstName +
" " +
assignment.publisher.lastName
);
})
.join(", ")
: shift.name,
};
if (shiftSchedule.names.length > 0) {
groupedShifts[day][time].push(shiftSchedule);
}
}
} catch (err) {
console.log(err + " " + JSON.stringify(shifts[i]));
}
for (const day in groupedShifts) {
const times = Object.keys(groupedShifts[day]);
for (const time of times) {
const shift = groupedShifts[day][time][0];
if (shift) {
// Determine the first shift of the day if it requires transport
if (time === times[0] && shift.requiresTransport) { // Check if this is the first time slot of the day
shift.notes = "Докарва количка от Склад Сердика -"; // Update the first shift in the first time slot
}
// Determine the last shift of the day if it requires transport
if (time === times[times.length - 1] && shift.requiresTransport) { // Check if this is the last time slot of the day
shift.notes = "Прибира количка в Склад Сердика -"; // Update the last shift in the last time slot
}
}
}
}
// Create the output object in the format of the second JSON file
const monthlySchedule = {
month: common.getMonthName(shifts[0].startTime.getMonth()),
year: startDate.getFullYear(),
events: [],
};
for (const day in groupedShifts) {
var dayEvent = null;
for (const time in groupedShifts[day]) {
if (dayEvent == null) {
const shift = groupedShifts[day][time][0];
if (!shift) {
console.log("shift is null");
continue;
}
let weekday = common.getDayOfWeekName(shift.date);
let monthName = common.getMonthName(shift.date.getMonth());
weekday = weekday.charAt(0).toUpperCase() + weekday.slice(1);
let weekNr = common.getWeekNumber(shift.date);
console.log("weekday = " + weekday, " weekNr = " + weekNr);
dayEvent = {
week: weekNr,
dayOfWeek: weekday,
dayOfMonth: shift.date.getDate(),
placeOfEvent: shift.placeOfEvent,
shifts: [],
transport: shift.notes,
monthName: monthName,
};
}
dayEvent.shifts.push(...groupedShifts[day][time]);
}
if (dayEvent) {
monthlySchedule.events.push(dayEvent);
}
}
const outputPath = path.join(process.cwd(), 'public', 'content', 'output');
if (!fs.existsSync(outputPath)) {
fs.mkdirSync(outputPath, { recursive: true });
}
//fs.writeFileSync(path.join(outputPath, `shifts ${year}.${month}.json`), JSON.stringify(monthlySchedule), 'utf8');
// Load the Handlebars template from a file
const template = fs.readFileSync("./src/templates/schedule.hbs", "utf8");
generateTemplateFile(monthlySchedule, template).then((result) => {
const filename = path.join(outputPath, `schedule.html`)
//fs.writeFileSync(filename, result, "utf8");
res.end(result);
}
);
}
catch (error) {
console.log(error);
res.status(500).json({ error: "Internal Server Error" });
}
} else {
res.setHeader('Allow', ['GET']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}