IO-3239 Add integration log statements on QBO.

This commit is contained in:
Patrick Fic
2025-05-19 11:10:02 -07:00
parent b8841e3ded
commit b014744940
6 changed files with 229 additions and 107 deletions

View File

@@ -14,7 +14,6 @@ const oauthClient = new OAuthClient({
clientSecret: process.env.QBO_SECRET, clientSecret: process.env.QBO_SECRET,
environment: process.env.NODE_ENV === "production" ? "production" : "sandbox", environment: process.env.NODE_ENV === "production" ? "production" : "sandbox",
redirectUri: process.env.QBO_REDIRECT_URI, redirectUri: process.env.QBO_REDIRECT_URI,
logging: true
}); });
//TODO:AIO Add in QBO callbacks. //TODO:AIO Add in QBO callbacks.

View File

@@ -20,7 +20,6 @@ exports.default = async (req, res) => {
clientSecret: process.env.QBO_SECRET, clientSecret: process.env.QBO_SECRET,
environment: process.env.NODE_ENV === "production" ? "production" : "sandbox", environment: process.env.NODE_ENV === "production" ? "production" : "sandbox",
redirectUri: process.env.QBO_REDIRECT_URI, redirectUri: process.env.QBO_REDIRECT_URI,
logging: true
}); });
try { try {
@@ -149,6 +148,15 @@ async function QueryVendorRecord(oauthClient, qbo_realmId, req, bill) {
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryVendorRecord",
billid: bill.id,
statusCode: result.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, result); setNewRefreshToken(req.user.email, result);
return ( return (
result.json && result.json &&
@@ -178,6 +186,15 @@ async function InsertVendorRecord(oauthClient, qbo_realmId, req, bill) {
}, },
body: JSON.stringify(Vendor) body: JSON.stringify(Vendor)
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "InsertVendorRecord",
billid: bill.id,
statusCode: result.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, result); setNewRefreshToken(req.user.email, result);
return result && result.json && result.json.Vendor; return result && result.json && result.json.Vendor;
} catch (error) { } catch (error) {
@@ -280,6 +297,15 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor, bodyshop)
}, },
body: JSON.stringify(billQbo) body: JSON.stringify(billQbo)
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "InsertBill",
billid: bill.id,
statusCode: result.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, result); setNewRefreshToken(req.user.email, result);
return result && result.json && result.json.Bill; return result && result.json && result.json.Bill;
} catch (error) { } catch (error) {
@@ -354,6 +380,14 @@ async function QueryMetaData(oauthClient, qbo_realmId, req) {
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryAccountType",
statusCode: accounts.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, accounts); setNewRefreshToken(req.user.email, accounts);
const taxCodes = await oauthClient.makeApiCall({ const taxCodes = await oauthClient.makeApiCall({
url: urlBuilder(qbo_realmId, "query", `select * From TaxCode`), url: urlBuilder(qbo_realmId, "query", `select * From TaxCode`),
@@ -362,7 +396,14 @@ async function QueryMetaData(oauthClient, qbo_realmId, req) {
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryTaxCode",
statusCode: taxCodes.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
const classes = await oauthClient.makeApiCall({ const classes = await oauthClient.makeApiCall({
url: urlBuilder(qbo_realmId, "query", `select * From Class`), url: urlBuilder(qbo_realmId, "query", `select * From Class`),
method: "POST", method: "POST",
@@ -370,7 +411,14 @@ async function QueryMetaData(oauthClient, qbo_realmId, req) {
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryClasses",
statusCode: classes.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
const taxCodeMapping = {}; const taxCodeMapping = {};
taxCodes.json && taxCodes.json &&

View File

@@ -29,7 +29,6 @@ exports.default = async (req, res) => {
clientSecret: process.env.QBO_SECRET, clientSecret: process.env.QBO_SECRET,
environment: process.env.NODE_ENV === "production" ? "production" : "sandbox", environment: process.env.NODE_ENV === "production" ? "production" : "sandbox",
redirectUri: process.env.QBO_REDIRECT_URI, redirectUri: process.env.QBO_REDIRECT_URI,
logging: true
}); });
try { try {
//Fetch the API Access Tokens & Set them for the session. //Fetch the API Access Tokens & Set them for the session.
@@ -255,6 +254,15 @@ async function InsertPayment(oauthClient, qbo_realmId, req, payment, parentRef,
}, },
body: JSON.stringify(paymentQbo) body: JSON.stringify(paymentQbo)
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "InsertPayment",
paymentid: payment.id,
statusCode: result.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, result); setNewRefreshToken(req.user.email, result);
return result && result.Bill; return result && result.Bill;
} catch (error) { } catch (error) {
@@ -274,7 +282,15 @@ async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number, isCreditM
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryInvoice",
statusCode: invoice.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
const paymentMethods = await oauthClient.makeApiCall({ const paymentMethods = await oauthClient.makeApiCall({
url: urlBuilder(qbo_realmId, "query", `select * From PaymentMethod`), url: urlBuilder(qbo_realmId, "query", `select * From PaymentMethod`),
method: "POST", method: "POST",
@@ -282,6 +298,14 @@ async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number, isCreditM
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryPaymentMethod",
statusCode: paymentMethods.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, paymentMethods); setNewRefreshToken(req.user.email, paymentMethods);
// const classes = await oauthClient.makeApiCall({ // const classes = await oauthClient.makeApiCall({
@@ -325,6 +349,15 @@ async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number, isCreditM
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryTaxCode",
statusCode: taxCodes.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
const items = await oauthClient.makeApiCall({ const items = await oauthClient.makeApiCall({
url: urlBuilder(qbo_realmId, "query", `select * From Item`), url: urlBuilder(qbo_realmId, "query", `select * From Item`),
method: "POST", method: "POST",
@@ -332,6 +365,14 @@ async function QueryMetaData(oauthClient, qbo_realmId, req, ro_number, isCreditM
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "QueryItems",
statusCode: items.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, items); setNewRefreshToken(req.user.email, items);
const itemMapping = {}; const itemMapping = {};
@@ -432,6 +473,15 @@ async function InsertCreditMemo(oauthClient, qbo_realmId, req, payment, parentRe
}, },
body: JSON.stringify(paymentQbo) body: JSON.stringify(paymentQbo)
}); });
logger.LogIntegrationCall({
platform: "QBO",
methodType: "POST",
methodName: "InsertCreditMemo",
paymentid: payment.id,
statusCode: result.status,
bodyshopid: req.user.bodyshopid,
email: req.user.email
})
setNewRefreshToken(req.user.email, result); setNewRefreshToken(req.user.email, result);
return result && result.Bill; return result && result.Bill;
} catch (error) { } catch (error) {

View File

@@ -22,8 +22,8 @@ exports.default = async (req, res) => {
clientSecret: process.env.QBO_SECRET, clientSecret: process.env.QBO_SECRET,
environment: process.env.NODE_ENV === "production" ? "production" : "sandbox", environment: process.env.NODE_ENV === "production" ? "production" : "sandbox",
redirectUri: process.env.QBO_REDIRECT_URI, redirectUri: process.env.QBO_REDIRECT_URI,
logging: true
}); });
try { try {
//Fetch the API Access Tokens & Set them for the session. //Fetch the API Access Tokens & Set them for the session.
const response = await apiGqlClient.request(queries.GET_QBO_AUTH, { const response = await apiGqlClient.request(queries.GET_QBO_AUTH, {
@@ -499,10 +499,8 @@ async function InsertInvoice(oauthClient, qbo_realmId, req, job, bodyshop, paren
DocNumber: job.ro_number, DocNumber: job.ro_number,
...(job.class ? { ClassRef: { value: classes[job.class] } } : {}), ...(job.class ? { ClassRef: { value: classes[job.class] } } : {}),
CustomerMemo: { CustomerMemo: {
value: `${job.clm_no ? `Claim No: ${job.clm_no}` : ``}${ value: `${job.clm_no ? `Claim No: ${job.clm_no}` : ``}${job.po_number ? `PO No: ${job.po_number}` : ``
job.po_number ? `PO No: ${job.po_number}` : `` } Vehicle:${job.v_model_yr || ""} ${job.v_make_desc || ""} ${job.v_model_desc || ""
} Vehicle:${job.v_model_yr || ""} ${job.v_make_desc || ""} ${
job.v_model_desc || ""
} ${job.v_vin || ""} ${job.plate_no || ""} `.trim() } ${job.v_vin || ""} ${job.plate_no || ""} `.trim()
}, },
CustomerRef: { CustomerRef: {
@@ -616,10 +614,8 @@ async function InsertInvoiceMultiPayerInvoice(
DocNumber: job.ro_number + suffix, DocNumber: job.ro_number + suffix,
...(job.class ? { ClassRef: { value: classes[job.class] } } : {}), ...(job.class ? { ClassRef: { value: classes[job.class] } } : {}),
CustomerMemo: { CustomerMemo: {
value: `${job.clm_no ? `Claim No: ${job.clm_no}` : ``}${ value: `${job.clm_no ? `Claim No: ${job.clm_no}` : ``}${job.po_number ? `PO No: ${job.po_number}` : ``
job.po_number ? `PO No: ${job.po_number}` : `` } Vehicle:${job.v_model_yr || ""} ${job.v_make_desc || ""} ${job.v_model_desc || ""
} Vehicle:${job.v_model_yr || ""} ${job.v_make_desc || ""} ${
job.v_model_desc || ""
} ${job.v_vin || ""} ${job.plate_no || ""} `.trim() } ${job.v_vin || ""} ${job.plate_no || ""} `.trim()
}, },
CustomerRef: { CustomerRef: {

View File

@@ -2968,3 +2968,11 @@ exports.GET_JOB_WATCHERS_MINIMAL = `
} }
} }
`; `;
exports.INSERT_INTEGRATION_LOG = `
mutation INSERT_INTEGRATION_LOG($log: integration_log_insert_input!) {
insert_integration_log_one(object: $log) {
id
}
}
`;

View File

@@ -12,6 +12,9 @@ const { uploadFileToS3 } = require("./s3");
const { v4 } = require("uuid"); const { v4 } = require("uuid");
const { InstanceRegion } = require("./instanceMgr"); const { InstanceRegion } = require("./instanceMgr");
const getHostNameOrIP = require("./getHostNameOrIP"); const getHostNameOrIP = require("./getHostNameOrIP");
const client = require("../graphql-client/graphql-client").client;
const queries = require("../graphql-client/queries");
const LOG_LEVELS = { const LOG_LEVELS = {
error: { level: 0, name: "error" }, error: { level: 0, name: "error" },
@@ -99,10 +102,8 @@ const createLogger = () => {
const labelColor = "\x1b[33m"; // Yellow const labelColor = "\x1b[33m"; // Yellow
const separatorColor = "\x1b[35m|\x1b[0m"; // Magenta for separators const separatorColor = "\x1b[35m|\x1b[0m"; // Magenta for separators
return `${timestampColor} [${hostnameColor}] [${level}]: ${message} ${ return `${timestampColor} [${hostnameColor}] [${level}]: ${message} ${user ? `${separatorColor} ${labelColor}user:\x1b[0m ${JSON.stringify(user)}` : ""
user ? `${separatorColor} ${labelColor}user:\x1b[0m ${JSON.stringify(user)}` : "" } ${record ? `${separatorColor} ${labelColor}record:\x1b[0m ${JSON.stringify(record)}` : ""}${meta
} ${record ? `${separatorColor} ${labelColor}record:\x1b[0m ${JSON.stringify(record)}` : ""}${
meta
? `\n${separatorColor} ${labelColor}meta:\x1b[0m ${JSON.stringify(meta, null, 2)} ${separatorColor}` ? `\n${separatorColor} ${labelColor}meta:\x1b[0m ${JSON.stringify(meta, null, 2)} ${separatorColor}`
: "" : ""
}`; }`;
@@ -194,9 +195,29 @@ const createLogger = () => {
winstonLogger.log(logEntry); winstonLogger.log(logEntry);
}; };
const LogIntegrationCall = async ({ platform, methodType, methodName, jobid, paymentid, billid, statusCode, bodyshopid, email }) => {
try {
//Insert the record.
await client.request(queries.INSERT_INTEGRATION_LOG, {
platform,
methodType,
methodName, jobid, paymentid, billid,
statusCode,
bodyshopid,
email
});
} catch (error) {
log("integration-log-error", "ERROR", email, null, {
error
});
}
};
return { return {
log, log,
logger: winstonLogger logger: winstonLogger,
LogIntegrationCall
}; };
} catch (e) { } catch (e) {
console.error("Error setting up enhanced Logger, defaulting to console.: " + e?.message || ""); console.error("Error setting up enhanced Logger, defaulting to console.: " + e?.message || "");