diff --git a/app/controllers/report.controller.js b/app/controllers/report.controller.js index 928b27b..da6601b 100644 --- a/app/controllers/report.controller.js +++ b/app/controllers/report.controller.js @@ -123,7 +123,46 @@ const findOutboundStatusByCustomerId = (outboundCustomerStatuses, customerId) => return outboundCustomerStatuses.find((item) => toObjectIdText(item?.customer_id) === targetId) || {}; }; -const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes) => { +const normalizeRouteName = (name) => (name || "").toString().toLowerCase().replace(/\s+/g, ""); + +const findRelatedCustomersForReport = (route, customer, allRoutes) => { + const customerId = toObjectIdText(customer?.customer_id); + const oppositeType = route?.type === "inbound" ? "outbound" : "inbound"; + const sameDateOppositeRoutes = (allRoutes || []).filter( + (item) => item?.type === oppositeType && item?.schedule_date === route?.schedule_date + ); + const relativeRoute = sameDateOppositeRoutes.find( + (item) => normalizeRouteName(item?.name) === normalizeRouteName(route?.name) + ); + const relativeRouteCustomer = (relativeRoute?.route_customer_list || []).find( + (item) => toObjectIdText(item?.customer_id) === customerId + ); + const otherRoute = sameDateOppositeRoutes.find( + (item) => + normalizeRouteName(item?.name) !== normalizeRouteName(route?.name) && + (item?.route_customer_list || []).some((itemCustomer) => toObjectIdText(itemCustomer?.customer_id) === customerId) + ); + const customerInOtherRoute = (otherRoute?.route_customer_list || []).find( + (item) => toObjectIdText(item?.customer_id) === customerId + ); + return { relativeRouteCustomer, customerInOtherRoute }; +}; + +const resolveNoteFromCandidates = (...candidates) => { + for (const candidate of candidates) { + const note = (candidate?.customer_note || candidate?.customer_special_needs || "").toString().trim(); + if (note) return note; + } + return ""; +}; + +const hasEnterCenterTimeByCandidate = (...candidates) => + candidates.some((item) => item?.customer_enter_center_time !== undefined && item?.customer_enter_center_time !== null && item?.customer_enter_center_time !== ""); + +const hasInCenterStatusByCandidate = (...candidates) => + candidates.some((item) => (item?.customer_route_status || "").toString() === "inCenter"); + +const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, vehiclesMap, outboundCustomerStatuses, unicodeFontBytes, allRoutes) => { const pdfDoc = await PDFDocument.load(templateBytes); pdfDoc.registerFontkit(fontkit); const unicodeFont = await pdfDoc.embedFont(unicodeFontBytes, { subset: true }); @@ -147,24 +186,33 @@ const buildRoutePdfBuffer = async (templateBytes, route, seqNum, driversMap, veh const customers = Array.isArray(route?.route_customer_list) ? route.route_customer_list : []; customers.forEach((customer, index) => { const row = index + 1; + const { relativeRouteCustomer, customerInOtherRoute } = findRelatedCustomersForReport(route, customer, allRoutes); safeSetField(form, `name_${row}`, customer?.customer_name || ""); safeSetField(form, `addr_${row}`, customer?.customer_address || ""); safeSetField(form, `phone_${row}`, customer?.customer_phone || ""); - const customerNoteText = customer?.customer_note || customer?.customer_special_needs || ""; + const customerNoteText = resolveNoteFromCandidates(customer, relativeRouteCustomer, customerInOtherRoute); safeSetField(form, `note_${row}`, customerNoteText); - const pickupTime = formatUtcToLocalHm(customer?.customer_pickup_time); + const pickupTime = formatUtcToLocalHm( + customer?.customer_pickup_time || + relativeRouteCustomer?.customer_pickup_time || + customerInOtherRoute?.customer_pickup_time + ); if (pickupTime) safeSetField(form, `pick_${row}`, pickupTime); - const hasEnterCenterTime = customer?.customer_enter_center_time !== undefined && customer?.customer_enter_center_time !== null; + const hasEnterCenterTime = hasEnterCenterTimeByCandidate(customer, relativeRouteCustomer, customerInOtherRoute); if (hasEnterCenterTime) { - const enterCenterTime = formatUtcToLocalHm(customer?.customer_enter_center_time); + const enterCenterTime = formatUtcToLocalHm( + customer?.customer_enter_center_time || + relativeRouteCustomer?.customer_enter_center_time || + customerInOtherRoute?.customer_enter_center_time + ); if (enterCenterTime) { safeSetField(form, `arrive_${row}`, enterCenterTime); } safeSetField(form, `y_${row}`, "✓", { fontSize: 11 }); safeSetField(form, `n_${row}`, "", { fontSize: 11 }); - } else if (customer?.customer_route_status === "inCenter") { + } else if (hasInCenterStatusByCandidate(customer, relativeRouteCustomer, customerInOtherRoute)) { safeSetField(form, `y_${row}`, "✓", { fontSize: 11 }); safeSetField(form, `n_${row}`, "", { fontSize: 11 }); } else { @@ -368,7 +416,8 @@ exports.exportRouteReportZip = async (req, res) => { driversMap, vehiclesMap, outboundCustomerStatuses, - unicodeFontBytes + unicodeFontBytes, + routes ); const base = sanitizeFileName(route?.name || `route_${i + 1}`) || `route_${i + 1}`; const existingCount = filenameCounter.get(base) || 0;