|
|
|
|
@@ -1,4 +1,6 @@
|
|
|
|
|
const { getJobAssignmentType } = require("./stringHelpers");
|
|
|
|
|
const { getJobAssignmentType, formatTaskPriority } = require("./stringHelpers");
|
|
|
|
|
const moment = require("moment-timezone");
|
|
|
|
|
const { startCase } = require("lodash");
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Populates the recipients for app, email, and FCM notifications based on scenario watchers.
|
|
|
|
|
@@ -26,17 +28,17 @@ const populateWatchers = (data, result) => {
|
|
|
|
|
*/
|
|
|
|
|
// Verified
|
|
|
|
|
const alternateTransportChangedBuilder = (data) => {
|
|
|
|
|
const body = `The Alternate Transport status has been updated to ${data?.data?.alt_transport}.`;
|
|
|
|
|
const body = `The Alternate Transport status has been updated from ${data.changedFields.alt_transport?.old || "unset"} to ${data?.changedFields?.alt_transport?.new || "unset"}.`;
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
bodyShopId: data.bodyShopId,
|
|
|
|
|
jobRoNumber: data.jobRoNumber,
|
|
|
|
|
key: "notifications.job.alternateTransportChanged",
|
|
|
|
|
body, // Same as email body
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
alternateTransport: data.changedFields.alt_transport?.new,
|
|
|
|
|
oldAlternateTransport: data.changedFields.alt_transport?.old
|
|
|
|
|
alternateTransport: data?.changedFields?.alt_transport?.new,
|
|
|
|
|
oldAlternateTransport: data?.changedFields?.alt_transport?.old
|
|
|
|
|
},
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
@@ -60,7 +62,6 @@ const alternateTransportChangedBuilder = (data) => {
|
|
|
|
|
//verified
|
|
|
|
|
const billPostedHandler = (data) => {
|
|
|
|
|
const facing = data?.data?.isinhouse ? "In-House" : "External";
|
|
|
|
|
|
|
|
|
|
const body = `An ${facing} Bill has been posted${data?.data?.is_credit_memo ? " (Credit Memo)" : ""}.`.trim();
|
|
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
|
@@ -71,8 +72,8 @@ const billPostedHandler = (data) => {
|
|
|
|
|
key: "notifications.job.billPosted",
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
facing,
|
|
|
|
|
is_credit_memo: data?.data?.is_credit_memo
|
|
|
|
|
isInHouse: data?.data?.isinhouse,
|
|
|
|
|
isCreditMemo: data?.data?.is_credit_memo
|
|
|
|
|
},
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
@@ -95,7 +96,7 @@ const billPostedHandler = (data) => {
|
|
|
|
|
*/
|
|
|
|
|
// TODO: Needs change
|
|
|
|
|
const criticalPartsStatusChangedBuilder = (data) => {
|
|
|
|
|
const body = `The critical parts status has changed to ${data.data.queued_for_parts ? "queued" : "not queued"}.`;
|
|
|
|
|
const body = `The critical parts status has changed to ${data?.data?.queued_for_parts ? "queued" : "not queued"}.`;
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
@@ -104,8 +105,8 @@ const criticalPartsStatusChangedBuilder = (data) => {
|
|
|
|
|
key: "notifications.job.criticalPartsStatusChanged",
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
queuedForParts: data.data.queued_for_parts,
|
|
|
|
|
oldQueuedForParts: data.changedFields.queued_for_parts?.old
|
|
|
|
|
queuedForParts: data?.data?.queued_for_parts,
|
|
|
|
|
oldQueuedForParts: data?.changedFields?.queued_for_parts?.old
|
|
|
|
|
},
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
@@ -162,7 +163,7 @@ const intakeDeliveryChecklistCompletedBuilder = (data) => {
|
|
|
|
|
*/
|
|
|
|
|
// Verified
|
|
|
|
|
const jobAssignedToMeBuilder = (data) => {
|
|
|
|
|
const body = `You have been assigned to ${getJobAssignmentType(data.scenarioFields?.[0])}`;
|
|
|
|
|
const body = `You have been assigned to ${getJobAssignmentType(data.scenarioFields?.[0])}.`;
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
@@ -224,7 +225,7 @@ const jobsAddedToProductionBuilder = (data) => {
|
|
|
|
|
*/
|
|
|
|
|
// Verified
|
|
|
|
|
const jobStatusChangeBuilder = (data) => {
|
|
|
|
|
const body = `The status has changed from ${data.changedFields.status.old} to ${data.changedFields.status.new}`;
|
|
|
|
|
const body = `The status has changed from ${data?.changedFields?.status?.old || "unset"} to ${data?.changedFields?.status?.new || "unset"}`;
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
@@ -294,8 +295,19 @@ const newMediaAddedReassignedBuilder = (data) => {
|
|
|
|
|
/**
|
|
|
|
|
* Builds notification data for new notes added to a job.
|
|
|
|
|
*/
|
|
|
|
|
// verified
|
|
|
|
|
const newNoteAddedBuilder = (data) => {
|
|
|
|
|
const body = `An Note has been added: "${data.data.text}"`;
|
|
|
|
|
const body = [
|
|
|
|
|
"A",
|
|
|
|
|
data?.data?.critical && "critical",
|
|
|
|
|
data?.data?.private && "private",
|
|
|
|
|
data?.data?.type,
|
|
|
|
|
"Note has been added by",
|
|
|
|
|
`${data.data.created_by}`
|
|
|
|
|
]
|
|
|
|
|
.filter(Boolean)
|
|
|
|
|
.join(" ");
|
|
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
@@ -304,7 +316,10 @@ const newNoteAddedBuilder = (data) => {
|
|
|
|
|
key: "notifications.job.newNoteAdded",
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
text: data.data.text
|
|
|
|
|
createdBy: data?.data?.created_by,
|
|
|
|
|
critical: data?.data?.critical,
|
|
|
|
|
type: data?.data?.type,
|
|
|
|
|
private: data?.data?.private
|
|
|
|
|
},
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
@@ -325,9 +340,11 @@ const newNoteAddedBuilder = (data) => {
|
|
|
|
|
/**
|
|
|
|
|
* Builds notification data for new time tickets posted.
|
|
|
|
|
*/
|
|
|
|
|
// Verified
|
|
|
|
|
const newTimeTicketPostedBuilder = (data) => {
|
|
|
|
|
const type = data?.data?.cost_center;
|
|
|
|
|
const body = `An ${type} time ticket has been posted${data?.data?.flat_rate ? " (Flat Rate)" : ""}.`.trim();
|
|
|
|
|
const body =
|
|
|
|
|
`A ${startCase(type.toLowerCase())} Time Ticket for ${data?.data?.date} has been posted${data?.data?.flat_rate ? " (Flat Rate)" : ""}.`.trim();
|
|
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
@@ -337,7 +354,9 @@ const newTimeTicketPostedBuilder = (data) => {
|
|
|
|
|
key: "notifications.job.newTimeTicketPosted",
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
type
|
|
|
|
|
type,
|
|
|
|
|
date: data?.data?.date,
|
|
|
|
|
flatRate: data?.data?.flat_rate
|
|
|
|
|
},
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
@@ -419,7 +438,27 @@ const paymentCollectedCompletedBuilder = (data) => {
|
|
|
|
|
* Builds notification data for changes to scheduled dates.
|
|
|
|
|
*/
|
|
|
|
|
const scheduledDatesChangedBuilder = (data) => {
|
|
|
|
|
const body = `Scheduled dates have been updated.`;
|
|
|
|
|
const momentFormat = "MM/DD/YYYY hh:mm a";
|
|
|
|
|
const changedFields = data.changedFields;
|
|
|
|
|
|
|
|
|
|
// Define field configurations
|
|
|
|
|
const fieldConfigs = {
|
|
|
|
|
scheduled_in: "Scheduled In",
|
|
|
|
|
scheduled_completion: "Scheduled Completion",
|
|
|
|
|
scheduled_delivery: "Scheduled Delivery"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Build field messages dynamically
|
|
|
|
|
const fieldMessages = Object.entries(fieldConfigs)
|
|
|
|
|
.filter(([field]) => changedFields[field]) // Only include changed fields
|
|
|
|
|
.map(([field, label]) => {
|
|
|
|
|
const { old, new: newValue } = changedFields[field];
|
|
|
|
|
const formatDate = (date) => (date ? moment(date).tz(data.bodyShopTimezone).format(momentFormat) : "unset");
|
|
|
|
|
return `${label} changed from ${formatDate(old)} to ${formatDate(newValue)}`;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const body = fieldMessages.length > 0 ? fieldMessages.join(", ") + "." : "Scheduled dates have been updated.";
|
|
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
@@ -428,12 +467,12 @@ const scheduledDatesChangedBuilder = (data) => {
|
|
|
|
|
key: "notifications.job.scheduledDatesChanged",
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
scheduledIn: data.changedFields.scheduled_in?.new,
|
|
|
|
|
oldScheduledIn: data.changedFields.scheduled_in?.old,
|
|
|
|
|
scheduledCompletion: data.changedFields.scheduled_completion?.new,
|
|
|
|
|
oldScheduledCompletion: data.changedFields.scheduled_completion?.old,
|
|
|
|
|
scheduledDelivery: data.changedFields.scheduled_delivery?.new,
|
|
|
|
|
oldScheduledDelivery: data.changedFields.scheduled_delivery?.old
|
|
|
|
|
scheduledIn: changedFields.scheduled_in?.new,
|
|
|
|
|
oldScheduledIn: changedFields.scheduled_in?.old,
|
|
|
|
|
scheduledCompletion: changedFields.scheduled_completion?.new,
|
|
|
|
|
oldScheduledCompletion: changedFields.scheduled_completion?.old,
|
|
|
|
|
scheduledDelivery: changedFields.scheduled_delivery?.new,
|
|
|
|
|
oldScheduledDelivery: changedFields.scheduled_delivery?.old
|
|
|
|
|
},
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
@@ -486,7 +525,75 @@ const supplementImportedBuilder = (data) => {
|
|
|
|
|
* Builds notification data for tasks updated or created.
|
|
|
|
|
*/
|
|
|
|
|
const tasksUpdatedCreatedBuilder = (data) => {
|
|
|
|
|
const body = `Tasks have been ${data.isNew ? "created" : "updated"}.`;
|
|
|
|
|
const momentFormat = "MM/DD/YYYY hh:mm a";
|
|
|
|
|
const timezone = data.bodyShopTimezone;
|
|
|
|
|
const taskTitle = data?.data?.title;
|
|
|
|
|
|
|
|
|
|
let body;
|
|
|
|
|
let variables;
|
|
|
|
|
|
|
|
|
|
if (data.isNew) {
|
|
|
|
|
// Created case
|
|
|
|
|
const priority = formatTaskPriority(data?.data?.priority);
|
|
|
|
|
const createdBy = data?.data?.created_by;
|
|
|
|
|
const dueDate = data.data.due_date ? ` due on ${moment(data.data.due_date).tz(timezone).format(momentFormat)}` : "";
|
|
|
|
|
const completedOnCreation = data.data.completed === true;
|
|
|
|
|
body = `A ${priority} Task ${taskTitle} has been created${completedOnCreation ? " and marked completed" : ""} by ${createdBy}${dueDate}`;
|
|
|
|
|
variables = {
|
|
|
|
|
isNew: data.isNew,
|
|
|
|
|
roNumber: data.jobRoNumber,
|
|
|
|
|
title: data?.data?.title,
|
|
|
|
|
priority: data?.data?.priority,
|
|
|
|
|
createdBy: data?.data?.created_by,
|
|
|
|
|
dueDate: data?.data?.due_date,
|
|
|
|
|
completed: completedOnCreation ? data?.data?.completed : undefined // Only include if true
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
// Updated case
|
|
|
|
|
const changedFields = data.changedFields;
|
|
|
|
|
const fieldNames = Object.keys(changedFields);
|
|
|
|
|
|
|
|
|
|
// Special case: Only 'completed' changed
|
|
|
|
|
if (fieldNames.length === 1 && changedFields.completed) {
|
|
|
|
|
body = `Task ${taskTitle} was marked ${changedFields.completed.new ? "complete" : "incomplete"}`;
|
|
|
|
|
variables = {
|
|
|
|
|
isNew: data.isNew,
|
|
|
|
|
roNumber: data.jobRoNumber,
|
|
|
|
|
title: data?.data?.title,
|
|
|
|
|
changedCompleted: data?.changedFields?.completed?.new
|
|
|
|
|
};
|
|
|
|
|
} else {
|
|
|
|
|
// General update case
|
|
|
|
|
const fieldMessages = [];
|
|
|
|
|
|
|
|
|
|
if (changedFields.description) {
|
|
|
|
|
fieldMessages.push("Description Updated");
|
|
|
|
|
}
|
|
|
|
|
if (changedFields.priority) {
|
|
|
|
|
fieldMessages.push(`Priority changed to ${formatTaskPriority(changedFields.priority.new)}`);
|
|
|
|
|
}
|
|
|
|
|
if (changedFields.due_date) {
|
|
|
|
|
fieldMessages.push(`Due date set to ${moment(changedFields.due_date.new).tz(timezone).format(momentFormat)}`);
|
|
|
|
|
}
|
|
|
|
|
if (changedFields.completed) {
|
|
|
|
|
fieldMessages.push(`Status changed to ${changedFields.completed.new ? "complete" : "incomplete"}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
body =
|
|
|
|
|
fieldMessages.length > 0
|
|
|
|
|
? `Task ${taskTitle} updated: ${fieldMessages.join(", ")}`
|
|
|
|
|
: `Task ${taskTitle} has been updated.`;
|
|
|
|
|
variables = {
|
|
|
|
|
isNew: data.isNew,
|
|
|
|
|
roNumber: data.jobRoNumber,
|
|
|
|
|
title: data?.data?.title,
|
|
|
|
|
changedPriority: data?.changedFields?.priority?.new,
|
|
|
|
|
changedDueDate: data?.changedFields?.due_date?.new,
|
|
|
|
|
changedCompleted: data?.changedFields?.completed?.new
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
|
app: {
|
|
|
|
|
jobId: data.jobId,
|
|
|
|
|
@@ -494,10 +601,7 @@ const tasksUpdatedCreatedBuilder = (data) => {
|
|
|
|
|
bodyShopId: data.bodyShopId,
|
|
|
|
|
key: data.isNew ? "notifications.job.taskCreated" : "notifications.job.taskUpdated",
|
|
|
|
|
body,
|
|
|
|
|
variables: {
|
|
|
|
|
isNew: data.isNew,
|
|
|
|
|
roNumber: data.jobRoNumber
|
|
|
|
|
},
|
|
|
|
|
variables,
|
|
|
|
|
recipients: []
|
|
|
|
|
},
|
|
|
|
|
email: {
|
|
|
|
|
|