This commit is contained in:
@@ -5,7 +5,7 @@ const path = require("path");
|
|||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const moment = require("moment-timezone");
|
const moment = require("moment-timezone");
|
||||||
const archiver = require("archiver");
|
const archiver = require("archiver");
|
||||||
const { PDFDocument } = require("pdf-lib");
|
const { PDFDocument, rgb } = require("pdf-lib");
|
||||||
const fontkit = require("@pdf-lib/fontkit");
|
const fontkit = require("@pdf-lib/fontkit");
|
||||||
const Report = db.report;
|
const Report = db.report;
|
||||||
const RoutePath = db.route_path;
|
const RoutePath = db.route_path;
|
||||||
@@ -162,6 +162,24 @@ const hasEnterCenterTimeByCandidate = (...candidates) =>
|
|||||||
const hasInCenterStatusByCandidate = (...candidates) =>
|
const hasInCenterStatusByCandidate = (...candidates) =>
|
||||||
candidates.some((item) => (item?.customer_route_status || "").toString() === "inCenter");
|
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 buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes) => {
|
||||||
const pdfDoc = await PDFDocument.load(templateBytes);
|
const pdfDoc = await PDFDocument.load(templateBytes);
|
||||||
pdfDoc.registerFontkit(fontkit);
|
pdfDoc.registerFontkit(fontkit);
|
||||||
@@ -210,14 +228,17 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh
|
|||||||
if (enterCenterTime) {
|
if (enterCenterTime) {
|
||||||
safeSetField(form, `arrive_${row}`, enterCenterTime);
|
safeSetField(form, `arrive_${row}`, enterCenterTime);
|
||||||
}
|
}
|
||||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 11 });
|
safeSetField(form, `y_${row}`, "");
|
||||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||||
|
drawCenteredMarkInField(pdfDoc, form, `y_${row}`, "✓", unicodeFont);
|
||||||
} else if (hasInCenterStatusByCandidate(customer, relativeRouteCustomer, customerInOtherRoute)) {
|
} else if (hasInCenterStatusByCandidate(customer, relativeRouteCustomer, customerInOtherRoute)) {
|
||||||
safeSetField(form, `y_${row}`, "✓", { fontSize: 11 });
|
safeSetField(form, `y_${row}`, "");
|
||||||
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
safeSetField(form, `n_${row}`, "", { fontSize: 11 });
|
||||||
|
drawCenteredMarkInField(pdfDoc, form, `y_${row}`, "✓", unicodeFont);
|
||||||
} else {
|
} else {
|
||||||
safeSetField(form, `y_${row}`, "", { fontSize: 11 });
|
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);
|
const outboundStatus = findOutboundStatusByCustomerId(outboundCustomerStatuses, customer?.customer_id);
|
||||||
@@ -370,7 +391,6 @@ exports.exportRouteReportZip = async (req, res) => {
|
|||||||
Vehicle.find(splitSite.splitSiteGet(req, { status: "active" }))
|
Vehicle.find(splitSite.splitSiteGet(req, { status: "active" }))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const inboundRoutes = (routes || []).filter((route) => route?.type === "inbound");
|
|
||||||
const outboundRoutes = (routes || []).filter((route) => route?.type === "outbound");
|
const outboundRoutes = (routes || []).filter((route) => route?.type === "outbound");
|
||||||
const outboundCustomerStatuses = outboundRoutes.reduce((acc, route) => {
|
const outboundCustomerStatuses = outboundRoutes.reduce((acc, route) => {
|
||||||
const list = Array.isArray(route?.route_customer_list) ? route.route_customer_list : [];
|
const list = Array.isArray(route?.route_customer_list) ? route.route_customer_list : [];
|
||||||
@@ -389,6 +409,25 @@ exports.exportRouteReportZip = async (req, res) => {
|
|||||||
vehicle
|
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 templateBytes = fs.readFileSync(templatePath);
|
||||||
const unicodeFontBytes = fs.readFileSync(unicodeFontPath);
|
const unicodeFontBytes = fs.readFileSync(unicodeFontPath);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user