This commit is contained in:
@@ -5,12 +5,13 @@ const path = require("path");
|
||||
const crypto = require("crypto");
|
||||
const moment = require("moment-timezone");
|
||||
const archiver = require("archiver");
|
||||
const { PDFDocument } = require("pdf-lib");
|
||||
const { PDFDocument, rgb } = require("pdf-lib");
|
||||
const fontkit = require("@pdf-lib/fontkit");
|
||||
const Report = db.report;
|
||||
const RoutePath = db.route_path;
|
||||
const Employee = db.employee;
|
||||
const Vehicle = db.vehicle;
|
||||
const Customer = db.customer;
|
||||
|
||||
const ROOT_DIR = path.resolve(__dirname, "../..");
|
||||
const TARGET_TIMEZONE = "America/New_York";
|
||||
@@ -105,6 +106,12 @@ const safeSetField = (form, fieldName, value, options = {}) => {
|
||||
if (typeof options.fontSize === "number") {
|
||||
field.setFontSize(options.fontSize);
|
||||
}
|
||||
if (options.center === true) {
|
||||
field.setAlignment(1);
|
||||
}
|
||||
if (options.blackText === true) {
|
||||
field.setTextColor(rgb(0, 0, 0));
|
||||
}
|
||||
field.setText(text);
|
||||
return;
|
||||
} catch (_textErr) {}
|
||||
@@ -181,7 +188,7 @@ const appendNoticeLine = (parts, text) => {
|
||||
}
|
||||
};
|
||||
|
||||
const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes) => {
|
||||
const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes, customerNotesById) => {
|
||||
const pdfDoc = await PDFDocument.load(templateBytes);
|
||||
pdfDoc.registerFontkit(fontkit);
|
||||
const unicodeFont = await pdfDoc.embedFont(unicodeFontBytes, { subset: true });
|
||||
@@ -209,7 +216,9 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
|
||||
safeSetField(form, `name_${row}`, customer?.customer_name || "");
|
||||
safeSetField(form, `addr_${row}`, customer?.customer_address || "");
|
||||
safeSetField(form, `phone_${row}`, customer?.customer_phone || "");
|
||||
const customerNoteText = resolveNoteFromCandidates(customer, relativeRouteCustomer, customerInOtherRoute);
|
||||
const customerId = toObjectIdText(customer?.customer_id);
|
||||
const profileNoteToDriver = (customerNotesById?.get(customerId) || "").toString().trim();
|
||||
const customerNoteText = profileNoteToDriver || resolveNoteFromCandidates(customer, relativeRouteCustomer, customerInOtherRoute);
|
||||
safeSetField(form, `note_${row}`, customerNoteText);
|
||||
|
||||
const pickupTime = formatUtcToLocalHm(
|
||||
@@ -229,14 +238,14 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
|
||||
if (enterCenterTime) {
|
||||
safeSetField(form, `arrive_${row}`, enterCenterTime);
|
||||
}
|
||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 11 });
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 12, center: true, blackText: true });
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 12, center: true, blackText: true });
|
||||
} else if (hasInCenterStatusByCandidate(customer, relativeRouteCustomer, customerInOtherRoute)) {
|
||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 11 });
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 12, center: true, blackText: true });
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 12, center: true, blackText: true });
|
||||
} else {
|
||||
safeSetField(form, `y_${row}`, "", { fontSize: 11 });
|
||||
safeSetField(form, `n_${row}`, "✕", { fontSize: 11 });
|
||||
safeSetField(form, `y_${row}`, "", { fontSize: 12, center: true, blackText: true });
|
||||
safeSetField(form, `n_${row}`, "✕", { fontSize: 12, center: true, blackText: true });
|
||||
}
|
||||
|
||||
const outboundStatus = findOutboundStatusByCustomerId(outboundCustomerStatuses, customer?.customer_id);
|
||||
@@ -440,10 +449,11 @@ exports.exportRouteReportZip = async (req, res) => {
|
||||
return res.status(500).send({ message: "Missing Unicode font file: NotoSansSC-Regular.ttf" });
|
||||
}
|
||||
|
||||
const [routes, drivers, vehicles] = await Promise.all([
|
||||
const [routes, drivers, vehicles, customers] = await Promise.all([
|
||||
RoutePath.find(splitSite.splitSiteGet(req, { schedule_date: date, status: { $ne: "disabled" } })),
|
||||
Employee.find(splitSite.splitSiteGet(req, {})),
|
||||
Vehicle.find(splitSite.splitSiteGet(req, { status: "active" }))
|
||||
Vehicle.find(splitSite.splitSiteGet(req, { status: "active" })),
|
||||
Customer.find(splitSite.splitSiteGet(req, {}))
|
||||
]);
|
||||
|
||||
const outboundRoutes = (routes || []).filter((route) => route?.type === "outbound");
|
||||
@@ -464,6 +474,12 @@ exports.exportRouteReportZip = async (req, res) => {
|
||||
vehicle
|
||||
])
|
||||
);
|
||||
const customerNotesById = new Map(
|
||||
(customers || []).map((customer) => [
|
||||
toObjectIdText(customer?._id || customer?.id),
|
||||
(customer?.notes_for_driver || "").toString().trim()
|
||||
])
|
||||
);
|
||||
const getRouteVehicleNumber = (route) => {
|
||||
const vehicleId = toObjectIdText(route?.vehicle);
|
||||
const vehicleNumberRaw = vehiclesMap.get(vehicleId)?.vehicle_number;
|
||||
@@ -511,7 +527,8 @@ exports.exportRouteReportZip = async (req, res) => {
|
||||
vehiclesMap,
|
||||
outboundCustomerStatuses,
|
||||
unicodeFontBytes,
|
||||
routes
|
||||
routes,
|
||||
customerNotesById
|
||||
);
|
||||
const base = sanitizeFileName(route?.name || `route_${i + 1}`) || `route_${i + 1}`;
|
||||
const existingCount = filenameCounter.get(base) || 0;
|
||||
|
||||
@@ -85,7 +85,8 @@ const RouteReportWithSignature = () => {
|
||||
(res?.data || []).forEach((customer) => {
|
||||
nextMap.set(customer?.id, {
|
||||
program_type: customer?.program_type || '',
|
||||
pay_source: customer?.pay_source || ''
|
||||
pay_source: customer?.pay_source || '',
|
||||
notes_for_driver: customer?.notes_for_driver || ''
|
||||
});
|
||||
});
|
||||
setCustomerMetaById(nextMap);
|
||||
@@ -183,7 +184,9 @@ const RouteReportWithSignature = () => {
|
||||
return { y: '', n: '✗' };
|
||||
};
|
||||
|
||||
const getRouteNoteToDriverText = (...customerCandidates) => {
|
||||
const getRouteNoteToDriverText = (customerId, ...customerCandidates) => {
|
||||
const profileNote = (customerMetaById.get(customerId)?.notes_for_driver || '').toString().trim();
|
||||
if (profileNote) return profileNote;
|
||||
for (const item of customerCandidates) {
|
||||
const noteText = (item?.customer_note || '').toString().trim();
|
||||
if (noteText) return noteText;
|
||||
@@ -317,7 +320,7 @@ const RouteReportWithSignature = () => {
|
||||
const customerInOtherRoute = otherRouteWithThisCustomer?.route_customer_list?.find(cust => cust?.customer_id === customer?.customer_id);
|
||||
const otherOutboundRoute = getOtherOutboundRouteWithThisCustomer(customer?.customer_id);
|
||||
const attendanceDisplay = getAttendanceDisplayByReportLogic(customer, relativeRouteCustomer, customerInOtherRoute);
|
||||
const routeNoteText = getRouteNoteToDriverText(customer, relativeRouteCustomer, customerInOtherRoute);
|
||||
const routeNoteText = getRouteNoteToDriverText(customer?.customer_id, customer, relativeRouteCustomer, customerInOtherRoute);
|
||||
|
||||
return (
|
||||
<tr key={index}>
|
||||
|
||||
Reference in New Issue
Block a user