const { getJobAssignmentType } = require("./stringHelpers"); /** * Populates the recipients for app, email, and FCM notifications based on scenario watchers. * * @param {Object} data - The data object containing scenarioWatchers and bodyShopId. * @param {Object} result - The result object to populate with recipients for app, email, and FCM notifications. */ const populateWatchers = (data, result) => { data.scenarioWatchers.forEach((recipients) => { const { user, app, fcm, email } = recipients; // Add user to app recipients with bodyShopId if app notification is enabled if (app === true) result.app.recipients.push({ user, bodyShopId: data.bodyShopId }); // Add user to FCM recipients if FCM notification is enabled if (fcm === true) result.fcm.recipients.push(user); // Add user to email recipients if email notification is enabled if (email === true) result.email.recipients.push({ user }); }); }; /** * Builds notification data for changes to alternate transport. * * @param {Object} data - The data object containing job details and alternate transport changes. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const alternateTransportChangedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.alternateTransportChanged", variables: { alternateTransport: data.data.alt_transport, oldAlternateTransport: data.changedFields.alt_transport?.old }, recipients: [] }, email: { subject: `Alternate transport for ${data?.jobRoNumber} (${data.bodyShopName}) changed to ${data.data.alt_transport || "None"}`, body: `The alternate transport status has been updated for job ${data?.jobRoNumber} in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for bill posted events. * * @param {Object} data - The data object containing job and billing details. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const billPostedHandler = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.billPosted", variables: { clmTotal: data.data.clm_total }, recipients: [] }, email: { subject: `Bill posted for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `A bill of $${data.data.clm_total} has been posted for job ${data?.jobRoNumber} in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for changes to critical parts status. * * @param {Object} data - The data object containing job details and critical parts status changes. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const criticalPartsStatusChangedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.criticalPartsStatusChanged", variables: { queuedForParts: data.data.queued_for_parts, oldQueuedForParts: data.changedFields.queued_for_parts?.old }, recipients: [] }, email: { subject: `Critical parts status for ${data?.jobRoNumber} (${data.bodyShopName}) updated`, body: `The critical parts status for job ${data?.jobRoNumber} in ${data.bodyShopName} has changed to ${data.data.queued_for_parts ? "queued" : "not queued"}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for completed intake or delivery checklists. * * @param {Object} data - The data object containing job details and checklist changes. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const intakeDeliveryChecklistCompletedBuilder = (data) => { // Determine checklist type based on which field was changed const checklistType = data.changedFields.intakechecklist ? "intake" : "delivery"; const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.checklistCompleted", variables: { checklistType, completed: true }, recipients: [] }, email: { subject: `${checklistType.charAt(0).toUpperCase() + checklistType.slice(1)} checklist completed for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `The ${checklistType} checklist for job ${data?.jobRoNumber} in ${data.bodyShopName} has been completed.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for job assignment events. * * @param {Object} data - The data object containing job details and scenario fields. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const jobAssignedToMeBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.assigned", variables: { type: data.scenarioFields?.[0] }, recipients: [] }, email: { subject: `You have been assigned to [${getJobAssignmentType(data.scenarioFields?.[0])}] on ${data?.jobRoNumber} in ${data.bodyShopName}`, body: `Hello, a new job has been assigned to you in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for jobs added to production. * * @param {Object} data - The data object containing job details. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const jobsAddedToProductionBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.addedToProduction", variables: {}, recipients: [] }, email: { subject: `Job ${data?.jobRoNumber} (${data.bodyShopName}) added to production`, body: `Job ${data?.jobRoNumber} in ${data.bodyShopName} has been added to production.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for job status changes. * * @param {Object} data - The data object containing job details and status changes. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const jobStatusChangeBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.statusChanged", variables: { status: data.data.status, oldStatus: data.changedFields.status.old }, recipients: [] }, email: { subject: `The status of ${data?.jobRoNumber} (${data.bodyShopName}) has changed from ${data.changedFields.status.old} to ${data.data.status}`, body: `...`, // Placeholder indicating email body may need further customization recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for new media added or reassigned events. * * @param {Object} data - The data object containing job details. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const newMediaAddedReassignedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.newMediaAdded", variables: {}, recipients: [] }, email: { subject: `New media added to ${data?.jobRoNumber} (${data.bodyShopName})`, body: `New media has been added to job ${data?.jobRoNumber} in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for new notes added to a job. * * @param {Object} data - The data object containing job details and note text. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const newNoteAddedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.newNoteAdded", variables: { text: data.data.text }, recipients: [] }, email: { subject: `New note added to ${data?.jobRoNumber} (${data.bodyShopName})`, body: `A new note has been added to job ${data?.jobRoNumber} in ${data.bodyShopName}: "${data.data.text}"`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for new time tickets posted. * * @param {Object} data - The data object containing job details. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const newTimeTicketPostedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.newTimeTicketPosted", variables: {}, recipients: [] }, email: { subject: `New time ticket posted for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `A new time ticket has been posted for job ${data?.jobRoNumber} in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for parts marked as back-ordered. * * @param {Object} data - The data object containing job details and parts status changes. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const partMarkedBackOrderedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.partBackOrdered", variables: { queuedForParts: data.data.queued_for_parts, oldQueuedForParts: data.changedFields.queued_for_parts?.old }, recipients: [] }, email: { subject: `Part marked back-ordered for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `A part for job ${data?.jobRoNumber} in ${data.bodyShopName} has been marked as back-ordered.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for payment collection events. * * @param {Object} data - The data object containing job and payment details. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const paymentCollectedCompletedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.paymentCollected", variables: { clmTotal: data.data.clm_total }, recipients: [] }, email: { subject: `Payment collected for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `Payment of $${data.data.clm_total} has been collected for job ${data?.jobRoNumber} in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for changes to scheduled dates. * * @param {Object} data - The data object containing job details and scheduling changes. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const scheduledDatesChangedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.scheduledDatesChanged", variables: { scheduledIn: data.data.scheduled_in, oldScheduledIn: data.changedFields.scheduled_in?.old, scheduledCompletion: data.data.scheduled_completion, oldScheduledCompletion: data.changedFields.scheduled_completion?.old, scheduledDelivery: data.data.scheduled_delivery, oldScheduledDelivery: data.changedFields.scheduled_delivery?.old }, recipients: [] }, email: { subject: `Scheduled dates updated for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `Scheduled dates for job ${data?.jobRoNumber} in ${data.bodyShopName} have been updated.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for supplement imported events. * * @param {Object} data - The data object containing job and supplement details. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const supplementImportedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: "notifications.job.supplementImported", variables: { suppAmt: data.data.cieca_ttl?.data?.supp_amt }, recipients: [] }, email: { subject: `Supplement imported for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `A supplement of $${data.data.cieca_ttl?.data?.supp_amt || 0} has been imported for job ${data?.jobRoNumber} in ${data.bodyShopName}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; /** * Builds notification data for tasks updated or created. * * @param {Object} data - The data object containing job details and task event type. * @returns {Object} Notification data structured for app, email, and FCM channels. */ const tasksUpdatedCreatedBuilder = (data) => { const result = { app: { jobId: data.jobId, bodyShopId: data.bodyShopId, key: data.isNew ? "notifications.job.taskCreated" : "notifications.job.taskUpdated", variables: { type: data.isNew ? "created" : "updated", roNumber: data.jobRoNumber }, recipients: [] }, email: { subject: `Tasks ${data.isNew ? "created" : "updated"} for ${data?.jobRoNumber} (${data.bodyShopName})`, body: `Tasks for job ${data?.jobRoNumber} in ${data.bodyShopName} have been ${data.isNew ? "created" : "updated"}.`, recipients: [] }, fcm: { recipients: [] } }; populateWatchers(data, result); return result; }; module.exports = { alternateTransportChangedBuilder, billPostedHandler, criticalPartsStatusChangedBuilder, intakeDeliveryChecklistCompletedBuilder, jobAssignedToMeBuilder, jobsAddedToProductionBuilder, jobStatusChangeBuilder, newMediaAddedReassignedBuilder, newNoteAddedBuilder, newTimeTicketPostedBuilder, partMarkedBackOrderedBuilder, paymentCollectedCompletedBuilder, scheduledDatesChangedBuilder, supplementImportedBuilder, tasksUpdatedCreatedBuilder };