fix
All checks were successful
Build And Deploy Main / build-and-deploy (push) Successful in 33s

This commit is contained in:
2026-03-12 14:47:37 -04:00
parent d107bb4a3e
commit d21bf201f9
2 changed files with 61 additions and 4 deletions

View File

@@ -28,6 +28,7 @@ const toObjectIdText = (value) => {
if (typeof value === "object" && value._id) return `${value._id}`;
return `${value}`;
};
const normalizeCustomerName = (name) => (name || "").toString().trim().toLowerCase().replace(/\s+/g, " ");
const findTemplatePathBySite = (site) => {
const safeSite = [1, 2, 3].includes(Number(site)) ? Number(site) : 1;
@@ -180,11 +181,22 @@ const appendNoticeLine = (parts, text) => {
}
};
const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes, customerNotesById, debugRows) => {
const collectFieldRects = (form, fieldName) => {
try {
const field = form.getTextField(fieldName);
const widgets = field?.acroField?.getWidgets?.() || [];
return widgets.map((widget) => widget.getRectangle());
} catch (_err) {
return [];
}
};
const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes, customerNotesById, customerNotesByName, debugRows) => {
const pdfDoc = await PDFDocument.load(templateBytes);
pdfDoc.registerFontkit(fontkit);
const unicodeFont = await pdfDoc.embedFont(unicodeFontBytes, { subset: true });
const form = pdfDoc.getForm();
const markDrawQueue = [];
const routeName = route?.name || "";
const scheduleDate = route?.schedule_date || "";
const driverId = toObjectIdText(route?.driver);
@@ -209,7 +221,11 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
safeSetField(form, `addr_${row}`, customer?.customer_address || "");
safeSetField(form, `phone_${row}`, customer?.customer_phone || "");
const customerId = toObjectIdText(customer?.customer_id);
const profileNoteToDriver = (customerNotesById?.get(customerId) || "").toString().trim();
const profileNoteToDriver = (
customerNotesById?.get(customerId) ||
customerNotesByName?.get(normalizeCustomerName(customer?.customer_name || "")) ||
""
).toString().trim();
const customerNoteText = profileNoteToDriver;
safeSetField(form, `note_${row}`, customerNoteText);
@@ -236,16 +252,22 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
nValue = "";
safeSetField(form, `y_${row}`, yValue, { fontSize: 12, center: true, blackText: true });
safeSetField(form, `n_${row}`, nValue, { fontSize: 12, center: true, blackText: true });
const yRects = collectFieldRects(form, `y_${row}`);
yRects.forEach((rect) => markDrawQueue.push({ rect, text: "Y" }));
} else if (hasInCenterStatusByCandidate(customer, relativeRouteCustomer, customerInOtherRoute)) {
yValue = "Y";
nValue = "";
safeSetField(form, `y_${row}`, yValue, { fontSize: 12, center: true, blackText: true });
safeSetField(form, `n_${row}`, nValue, { fontSize: 12, center: true, blackText: true });
const yRects = collectFieldRects(form, `y_${row}`);
yRects.forEach((rect) => markDrawQueue.push({ rect, text: "Y" }));
} else {
yValue = "";
nValue = "N";
safeSetField(form, `y_${row}`, yValue, { fontSize: 12, center: true, blackText: true });
safeSetField(form, `n_${row}`, nValue, { fontSize: 12, center: true, blackText: true });
const nRects = collectFieldRects(form, `n_${row}`);
nRects.forEach((rect) => markDrawQueue.push({ rect, text: "N" }));
}
const outboundStatus = findOutboundStatusByCustomerId(outboundCustomerStatuses, customer?.customer_id);
@@ -328,6 +350,14 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
// Rebuild form appearances with a Unicode font so UTF-8 (e.g., Chinese) renders correctly.
form.updateFieldAppearances(unicodeFont);
form.flatten();
const firstPage = pdfDoc.getPage(0);
markDrawQueue.forEach(({ rect, text }) => {
const fontSize = Math.min(Math.max(rect.height * 0.72, 9), 14);
const textWidth = unicodeFont.widthOfTextAtSize(text, fontSize);
const x = rect.x + Math.max((rect.width - textWidth) / 2, 1);
const y = rect.y + Math.max((rect.height - fontSize) / 2, 1);
firstPage.drawText(text, { x, y, size: fontSize, font: unicodeFont, color: rgb(0, 0, 0) });
});
return pdfDoc.save();
};
exports.createReport = (req, res) => {
@@ -494,6 +524,17 @@ exports.exportRouteReportZip = async (req, res) => {
(customer?.notes_for_driver || "").toString().trim()
])
);
const customerNotesByName = new Map();
(customers || []).forEach((customer) => {
const note = (customer?.notes_for_driver || "").toString().trim();
if (!note) return;
const key = normalizeCustomerName(customer?.name || customer?.name_cn || `${customer?.firstname || ""} ${customer?.lastname || ""}`);
if (!key) return;
const previous = customerNotesByName.get(key);
if (!previous || (customer?.status || "").toString().toLowerCase() === "active") {
customerNotesByName.set(key, note);
}
});
const getRouteVehicleNumber = (route) => {
const vehicleId = toObjectIdText(route?.vehicle);
const vehicleNumberRaw = vehiclesMap.get(vehicleId)?.vehicle_number;
@@ -544,6 +585,7 @@ exports.exportRouteReportZip = async (req, res) => {
unicodeFontBytes,
routes,
customerNotesById,
customerNotesByName,
debugMode ? debugRows : null
);
const base = sanitizeFileName(route?.name || `route_${i + 1}`) || `route_${i + 1}`;