Files
bodyshop/server/notifications/scenarioBuilders.js

480 lines
15 KiB
JavaScript

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
};