Merge branch 'master-AIO' into feature/IO-3092-imgproxy

This commit is contained in:
Patrick Fic
2025-02-21 13:03:37 -08:00
16 changed files with 11819 additions and 11418 deletions

View File

@@ -55,7 +55,7 @@ exports.default = async (req, res) => {
const csv = converter.json2csv(shopList, { emptyFieldValue: "" });
emailer
.sendTaskEmail({
to: ["patrick.fic@convenient-brands.com", "bradley.rhoades@convenient-brands.com"],
to: ["patrick.fic@convenient-brands.com", "bradley.rhoades@convenient-brands.com", "jrome@rometech.com"],
subject: `RO Usage Report - ${moment().format("MM/DD/YYYY")}`,
text: `
Usage Report for ${moment().format("MM/DD/YYYY")} for Rome Online Customers.

View File

@@ -55,7 +55,7 @@ const sendServerEmail = async ({ subject, text }) => {
imex: `ImEX Online API - ${process.env.NODE_ENV} <noreply@imex.online>`,
rome: `Rome Online API - ${process.env.NODE_ENV} <noreply@romeonline.io>`
}),
to: ["patrick@imexsystems.ca", "support@thinkimex.com"],
to: ["support@thinkimex.com"],
subject: subject,
text: text,
ses: {
@@ -92,7 +92,7 @@ const sendTaskEmail = async ({ to, subject, type = "text", html, text, attachmen
},
(err, info) => {
// (message, type, user, record, meta
logger.log("server-email", err ? "error" : "debug", null, null, { message: err || info });
logger.log("server-email", err ? "error" : "debug", null, null, { message: err ? err?.message : info });
}
);
} catch (error) {
@@ -239,24 +239,24 @@ const emailBounce = async (req, res) => {
return;
}
//If it's bounced, log it as bounced in audit log. Send an email to the user.
const result = await client.request(queries.UPDATE_EMAIL_AUDIT, {
await client.request(queries.UPDATE_EMAIL_AUDIT, {
sesid: messageId,
status: "Bounced",
context: message.bounce?.bouncedRecipients
});
mailer.sendMail(
{
from: InstanceMgr({
from: InstanceManager({
imex: `ImEX Online <noreply@imex.online>`,
rome: `Rome Online <noreply@romeonline.io>`
}),
to: replyTo,
//bcc: "patrick@snapt.ca",
subject: `${InstanceMgr({
subject: `${InstanceManager({
imex: "ImEX Online",
rome: "Rome Online"
})} Bounced Email - RE: ${subject}`,
text: `${InstanceMgr({
text: `${InstanceManager({
imex: "ImEX Online",
rome: "Rome Online"
})} has tried to deliver an email with the subject: ${subject} to the intended recipients but encountered an error.
@@ -270,7 +270,7 @@ ${body.bounce?.bouncedRecipients.map(
},
(err, info) => {
logger.log("sns-error", err ? "error" : "debug", "api", null, {
message: err ? JSON.stringify(error) : info
message: err ? err?.message : info
});
}
);

View File

@@ -2241,6 +2241,7 @@ exports.QUERY_PARTS_SCAN = `query QUERY_PARTS_SCAN ($id: uuid!) {
mod_lb_hrs
oem_partno
alt_partno
op_code_desc
}
}
}`;
@@ -2252,7 +2253,7 @@ exports.UPDATE_PARTS_CRITICAL = `mutation UPDATE_PARTS_CRITICAL ($IdsToMarkCriti
notcritical: update_joblines(where: {id: {_nin: $IdsToMarkCritical}, jobid: {_eq: $jobid}}, _set: {critical: false}) {
affected_rows
}
}`;
}`;;
exports.ACTIVE_SHOP_BY_USER = `query ACTIVE_SHOP_BY_USER($user: String) {
associations(where: {active: {_eq: true}, useremail: {_eq: $user}}) {
@@ -2690,6 +2691,23 @@ exports.STATUS_UPDATE = `query STATUS_UPDATE($period: timestamptz!, $today: time
}
`;
exports.INSERT_AUDIT_TRAIL = `
mutation INSERT_AUDIT_TRAIL($auditObj: audit_trail_insert_input!) {
insert_audit_trail_one(object: $auditObj) {
id
jobid
billid
bodyshopid
created
operation
type
useremail
}
}
`;
exports.GET_DOCUMENTS_BY_JOB = `
query GET_DOCUMENTS_BY_JOB($jobId: uuid!) {
jobs_by_pk(id: $jobId) {

View File

@@ -99,6 +99,7 @@ async function OpenSearchUpdateHandler(req, res) {
break;
case "payments":
//Query to get the job and RO number
const payment = await client.request(
`query ADMIN_GET_PAYMENT_BY_ID($paymentId: uuid!) {
payments_by_pk(id: $paymentId) {
@@ -147,11 +148,25 @@ async function OpenSearchUpdateHandler(req, res) {
body: document
};
logger.log("os-handler", "DEBUG", null, null, {
id: req.body.event.data.new.id,
index: req.body.table.name,
bodyshopid: payload.body.bodyshopid
// body: document
});
const response = await osClient.index(payload);
//console.log(response.body);
res.status(200).json(response.body);
}
} catch (error) {
logger.log("os-handler-error", "ERROR", null, null, {
id: req.body.event.data.new.id,
index: req.body.table.name,
message: error.message,
stack: error.stack
// body: document
});
res.status(400).json(JSON.stringify(error));
}
}
@@ -166,7 +181,9 @@ async function OpenSearchSearchHandler(req, res) {
}
logger.log("os-search", "DEBUG", req.user.email, null, {
search
search,
index,
bodyshopid
});
const BearerToken = req.BearerToken;

View File

@@ -1,16 +1,25 @@
const queries = require("../graphql-client/queries");
const logger = require("../utils/logger");
const predefinedPartTypes = [
"PAN", "PAC", "PAR", "PAL", "PAA", "PAM", "PAP", "PAS", "PASL", "PAG",
];
const predefinedPartTypes = ["PAN", "PAC", "PAR", "PAL", "PAA", "PAM", "PAP", "PAS", "PASL", "PAG"];
const predefinedModLbrTypes = [
"LAA", "LAB", "LAD", "LAE", "LAF", "LAG", "LAM", "LAR", "LAS", "LAU",
"LA1", "LA2", "LA3", "LA4",
"LAA",
"LAB",
"LAD",
"LAE",
"LAF",
"LAG",
"LAM",
"LAR",
"LAS",
"LAU",
"LA1",
"LA2",
"LA3",
"LA4"
];
exports.partsScan = async function (req, res) {
console.log('hello')
const { jobid } = req.body;
const BearerToken = req.BearerToken;
const client = req.userGraphQLClient;
@@ -18,10 +27,9 @@ exports.partsScan = async function (req, res) {
logger.log("job-parts-scan", "DEBUG", req.user?.email, jobid, null);
try {
const data = await client.setHeaders({ Authorization: BearerToken }).request(
queries.QUERY_PARTS_SCAN,
{ id: jobid }
);
const data = await client
.setHeaders({ Authorization: BearerToken })
.request(queries.QUERY_PARTS_SCAN, { id: jobid });
const rules = data.jobs_by_pk.bodyshop.md_parts_scan || [];
if (!Array.isArray(rules)) {
@@ -36,21 +44,22 @@ exports.partsScan = async function (req, res) {
? new RegExp(rule.value, "i")
: typeof rule.value === "string"
? new RegExp(rule.value)
: null,
: null
}));
const criticalIds = new Set();
for (const jobline of data.jobs_by_pk.joblines) {
for (const { field, regex, operation, value } of compiledRules) {
if (criticalIds.has(jobline.id)) break; // Skip further evaluation if already critical
for (const { field, regex, operation, value, mark_critical, update_field, update_value } of compiledRules) {
// IO-3077 - Remove skip as this is extended to include line updates.
// if (criticalIds.has(jobline.id)) break; // Skip further evaluation if already critical
let jobValue = jobline[field];
let match = false;
if (field === "part_number") {
match = regex
? regex.test(jobline.oem_partno || '') || regex.test(jobline.alt_partno || '')
? regex.test(jobline.oem_partno || "") || regex.test(jobline.alt_partno || "")
: jobline.oem_partno === value || jobline.alt_partno === value;
} else if (field === "part_type") {
match = predefinedPartTypes.includes(value) && value === jobValue;
@@ -68,22 +77,44 @@ exports.partsScan = async function (req, res) {
}
if (match) {
criticalIds.add(jobline.id);
break; // No need to evaluate further rules for this jobline
if (mark_critical) {
//Could technically lead to duplicates, but they'd only be n positives, ultimately leading a positive.
criticalIds.add(jobline.id);
}
if (update_field && update_value) {
const result = await client.setHeaders({ Authorization: BearerToken }).request(queries.UPDATE_JOB_LINE, {
lineId: jobline.id,
line: { [update_field]: update_value, manual_line: true }
});
const auditResult = await client
.setHeaders({ Authorization: BearerToken })
.request(queries.INSERT_AUDIT_TRAIL, {
auditObj: {
bodyshopid: data.jobs_by_pk.bodyshop.id,
jobid,
operation: `Jobline (#${jobline.line_no} ${jobline.line_desc}/${jobline.id}) ${update_field} updated from ${jobline[update_field]} to ${update_value}. Lined marked as manual line.`,
type: "partscanupdate",
useremail: req.user.email
}
});
}
//break; // No need to evaluate further rules for this jobline
}
}
}
const result = await client.setHeaders({ Authorization: BearerToken }).request(
queries.UPDATE_PARTS_CRITICAL,
{ IdsToMarkCritical: Array.from(criticalIds), jobid }
);
const result = await client
.setHeaders({ Authorization: BearerToken })
.request(queries.UPDATE_PARTS_CRITICAL, { IdsToMarkCritical: Array.from(criticalIds), jobid });
res.status(200).json(result);
} catch (error) {
logger.log("job-parts-scan-error", "ERROR", req.user?.email, jobid, {
jobid,
error: error.message,
stack: error.stack
});
res.status(400).json(JSON.stringify({ message: error?.message }));
}