This commit is contained in:
@@ -5,7 +5,7 @@ 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;
|
||||
@@ -162,6 +162,24 @@ const hasEnterCenterTimeByCandidate = (...candidates) =>
|
||||
const hasInCenterStatusByCandidate = (...candidates) =>
|
||||
candidates.some((item) => (item?.customer_route_status || "").toString() === "inCenter");
|
||||
|
||||
const drawCenteredMarkInField = (pdfDoc, form, fieldName, mark, font) => {
|
||||
if (!mark) return;
|
||||
try {
|
||||
const field = form.getTextField(fieldName);
|
||||
const widgets = field?.acroField?.getWidgets?.() || [];
|
||||
if (!widgets.length) return;
|
||||
const page = pdfDoc.getPage(0);
|
||||
widgets.forEach((widget) => {
|
||||
const rect = widget.getRectangle();
|
||||
const fontSize = Math.min(Math.max(rect.height * 0.75, 10), 16);
|
||||
const markWidth = font.widthOfTextAtSize(mark, fontSize);
|
||||
const x = rect.x + Math.max((rect.width - markWidth) / 2, 1);
|
||||
const y = rect.y + Math.max((rect.height - fontSize) / 2, 1);
|
||||
page.drawText(mark, { x, y, size: fontSize, font, color: rgb(0, 0, 0) });
|
||||
});
|
||||
} catch (_err) {}
|
||||
};
|
||||
|
||||
const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes) => {
|
||||
const pdfDoc = await PDFDocument.load(templateBytes);
|
||||
pdfDoc.registerFontkit(fontkit);
|
||||
@@ -210,14 +228,17 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
|
||||
if (enterCenterTime) {
|
||||
safeSetField(form, `arrive_${row}`, enterCenterTime);
|
||||
}
|
||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 11 });
|
||||
safeSetField(form, `y_${row}`, "");
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||
drawCenteredMarkInField(pdfDoc, form, `y_${row}`, "✓", unicodeFont);
|
||||
} else if (hasInCenterStatusByCandidate(customer, relativeRouteCustomer, customerInOtherRoute)) {
|
||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 11 });
|
||||
safeSetField(form, `y_${row}`, "");
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||
drawCenteredMarkInField(pdfDoc, form, `y_${row}`, "✓", unicodeFont);
|
||||
} else {
|
||||
safeSetField(form, `y_${row}`, "", { fontSize: 11 });
|
||||
safeSetField(form, `n_${row}`, "✕", { fontSize: 11 });
|
||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||
drawCenteredMarkInField(pdfDoc, form, `n_${row}`, "✕", unicodeFont);
|
||||
}
|
||||
|
||||
const outboundStatus = findOutboundStatusByCustomerId(outboundCustomerStatuses, customer?.customer_id);
|
||||
@@ -370,7 +391,6 @@ exports.exportRouteReportZip = async (req, res) => {
|
||||
Vehicle.find(splitSite.splitSiteGet(req, { status: "active" }))
|
||||
]);
|
||||
|
||||
const inboundRoutes = (routes || []).filter((route) => route?.type === "inbound");
|
||||
const outboundRoutes = (routes || []).filter((route) => route?.type === "outbound");
|
||||
const outboundCustomerStatuses = outboundRoutes.reduce((acc, route) => {
|
||||
const list = Array.isArray(route?.route_customer_list) ? route.route_customer_list : [];
|
||||
@@ -389,6 +409,25 @@ exports.exportRouteReportZip = async (req, res) => {
|
||||
vehicle
|
||||
])
|
||||
);
|
||||
const getRouteVehicleNumber = (route) => {
|
||||
const vehicleId = toObjectIdText(route?.vehicle);
|
||||
const vehicleNumberRaw = vehiclesMap.get(vehicleId)?.vehicle_number;
|
||||
if (vehicleNumberRaw === undefined || vehicleNumberRaw === null || vehicleNumberRaw === "") {
|
||||
return Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
const numeric = Number(vehicleNumberRaw);
|
||||
if (!Number.isNaN(numeric)) return numeric;
|
||||
return Number.MAX_SAFE_INTEGER;
|
||||
};
|
||||
|
||||
const inboundRoutes = (routes || [])
|
||||
.filter((route) => route?.type === "inbound")
|
||||
.sort((a, b) => {
|
||||
const numberA = getRouteVehicleNumber(a);
|
||||
const numberB = getRouteVehicleNumber(b);
|
||||
if (numberA !== numberB) return numberA - numberB;
|
||||
return (a?.name || "").localeCompare(b?.name || "");
|
||||
});
|
||||
const templateBytes = fs.readFileSync(templatePath);
|
||||
const unicodeFontBytes = fs.readFileSync(unicodeFontPath);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user