-
+
diff --git a/client/src/utils/determineDMSType.js b/client/src/utils/determineDMSType.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/fortellis-scratch.js b/fortellis-scratch.js
new file mode 100644
index 000000000..b37e6e87c
--- /dev/null
+++ b/fortellis-scratch.js
@@ -0,0 +1,305 @@
+const path = require('path');
+const Dinero = require('dinero.js');
+const { gql } = require('graphql-request');
+const queries = require('./server/graphql-client/queries');
+const GraphQLClient = require('graphql-request').GraphQLClient;
+const logger = require('./server/utils/logger');
+const AxiosLib = require('axios').default;
+const axios = AxiosLib.create();
+const uuid = require('uuid').v4;
+
+const FORTELLIS_KEY = 'X1FxzLyOk3kjHvMbzdPQXFZShkdbgzuo';
+const FORTELLIS_SECRET = '7Yvs0wpQeHcUS5r95ht8pqOaAvBq7dHV';
+const FORTELLIS_AUTH_URL = 'https://identity.fortellis.io/oauth2/aus1p1ixy7YL8cMq02p7/v1/token';
+const FORTELLIS_URL = 'https://api.fortellis.io';
+const SubscriptionID = '5b527d7d-baf3-40bc-adae-e7a541e37363';
+let SubscriptionMeta = null;
+//const SubscriptionID = "cb59fa04-e53e-4b57-b071-80a48ebc346c";
+
+function sleep(time, callback) {
+ var stop = new Date().getTime();
+ while (new Date().getTime() < stop + time) {}
+ callback();
+}
+async function GetAuthToken() {
+ const {
+ data: { access_token, expires_in, token_type },
+ } = await axios.post(
+ FORTELLIS_AUTH_URL,
+ {},
+ {
+ auth: {
+ username: FORTELLIS_KEY,
+ password: FORTELLIS_SECRET,
+ },
+ params: {
+ grant_type: 'client_credentials',
+ scope: 'anonymous',
+ },
+ },
+ );
+ return access_token;
+}
+
+async function FetchSubscriptions() {
+ const access_token = await GetAuthToken();
+ try {
+ const subscriptions = await axios.get(
+ `https://subscriptions.fortellis.io/v1/solution/subscriptions`,
+ {
+ headers: { Authorization: `Bearer ${access_token}` },
+ },
+ );
+
+ return subscriptions.data.subscriptions;
+ } catch (error) {
+ console.log('🚀 ~ FetchSubscriptions ~ error:', error);
+ }
+}
+async function GetBulkVendors() {
+ const departmentIds = (await FetchSubscriptions())
+ .find((s) => s.subscriptionId === SubscriptionID) //Get the subscription object.
+ ?.apiDmsInfo.find((info) => info.name === 'CDK Drive Async Vendors')?.departments; //Departments are categorized by API name and have an array of departments.
+
+ const access_token = await GetAuthToken();
+ const ReqId = uuid();
+ try {
+ //TODO: This is pointing towards the test environment. Need to carefully watch for the production switch.
+ const Vendors = await axios.get(`https://api.fortellis.io/cdk-test/drive/vendor/v2/bulk`, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': departmentIds[0].id,
+ },
+ });
+
+ //Returns a long poll. Need to wait specified seconds until checking.
+ console.log(
+ '🚀 ~ GetBulkVendors ~ Vendors - waiting to execute callback:',
+ Vendors.data.checkStatusAfterSeconds,
+ );
+ sleep(Vendors.data.checkStatusAfterSeconds * 1000, async () => {
+ const VendorsResult = await axios.get(Vendors.data._links.status.href, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': departmentIds[0].id,
+ },
+ });
+
+ //This may have to check again if it isn't ready.
+ const VendorsResult2 = await axios.get(VendorsResult.data._links.result.href, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': departmentIds[0].id,
+ },
+ });
+ console.log('🚀 ~ sleep ~ VendorsResult2:', VendorsResult2);
+ });
+
+ console.log('🚀 ~ GetBulkVendors ~ Vendors:', ReqId, Vendors.data);
+ } catch (error) {
+ console.log('🚀 ~ GetBulkVendors ~ error:', ReqId, error);
+ }
+}
+
+async function FetchVehicles({ SubscriptionID }) {
+ const access_token = await GetAuthToken();
+ try {
+ //This doesn't seem to work as it is for production only.
+ const Vehicles = await axios.get(`https://api.fortellis.io/cdkdrive/service/v1/vehicles/`, {
+ headers: { Authorization: `Bearer ${access_token}`, 'Subscription-Id': SubscriptionID },
+ });
+ console.log('🚀 ~ FetchVehicles ~ Vehicles:', Vehicles);
+
+ return Vehicles.data;
+ } catch (error) {
+ console.log('🚀 ~ FetchVehicles ~ error:', error);
+ }
+}
+
+async function PostVehicleServiceHistory() {
+ const access_token = await GetAuthToken();
+ const ReqId = uuid();
+ const departmentIds = (await FetchSubscriptions())
+ .find((s) => s.subscriptionId === SubscriptionID) //Get the subscription object.
+ ?.apiDmsInfo.find((info) => info.name === 'CDK Drive Async Vendors')?.departments; //Departments are categorized by API name and have an array of departments.
+
+ //Need to get a vehicle ID from somewhere.
+ const vehicles = await FetchVehicles({ SubscriptionID });
+ try {
+ //TODO: This is pointing towards the test environment. Need to carefully watch for the production switch.
+ const Vendors = await axios.post(
+ `https://api.fortellis.io/cdk-test/drive/post/service-vehicle-history-mgmt/v2/
+ `,
+ {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': departmentIds[0].id,
+ },
+ },
+ );
+ } catch (error) {
+ console.log('🚀 ~ PostVehicleServiceHistory ~ error:', ReqId, error);
+ }
+}
+
+//PostVehicleServiceHistory();
+//GetBulkVendors();
+
+async function GetDepartmentId() {
+ const departmentIds = await FetchSubscriptions();
+ console.log('🚀 ~ GetDepartmentId ~ departmentIds:', departmentIds);
+ const departmentIds2 = departmentIds
+ .find((s) => s.subscriptionId === SubscriptionID) //Get the subscription object.
+ ?.apiDmsInfo.find((info) => info.name === 'CDK Drive Async Vendors')?.departments; //Departments are categorized by API name and have an array of departments.
+
+ return departmentIds[0].id;
+}
+//////////////////GL WIP Section //////////////////////
+async function OrgHelpers() {
+ console.log('Executing Org Helpers');
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const DepartmentId = await GetDepartmentId();
+
+ try {
+ //This doesn't seem to work as it is for production only.
+ const OrgHelpers = await axios.get(
+ `https://api.fortellis.io/cdk-test/drive/businessofficeglwippost/orgHelper`,
+ {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': DepartmentId,
+ },
+ },
+ );
+ console.log('🚀 ~ OrgHelpers ~ Data:', OrgHelpers);
+
+ return OrgHelpers.data;
+ } catch (error) {
+ console.log('🚀 ~ OrgHelpers ~ error:', error);
+ }
+}
+async function JournalHelpers({ glCompanyNumber }) {
+ console.log('Executing Journal Helpers');
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const DepartmentId = await GetDepartmentId();
+
+ try {
+ //This doesn't seem to work as it is for production only.
+ const JournalHelpers = await axios.get(
+ `https://api.fortellis.io/cdk-test/drive/businessofficeglwippost/jrnlHelper/${glCompanyNumber}`,
+ {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': DepartmentId,
+ },
+ },
+ );
+ console.log('🚀 ~ JournalHelpers ~ Data:', JournalHelpers);
+ return JournalHelpers.data;
+ } catch (error) {
+ console.log('🚀 ~ JournalHelpers ~ error:', error);
+ }
+}
+
+async function GlSalesChain() {
+ console.log('Executing GL Sales Chain');
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const DepartmentId = await GetDepartmentId();
+
+ try {
+ //This doesn't seem to work as it is for production only.
+ const GlSalesChain = await axios.get(
+ `https://api.fortellis.io/cdk-test/drive/businessofficeglwippost/glSalesChain`,
+ {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': DepartmentId,
+ },
+ },
+ );
+ console.log('🚀 ~ GlSalesChain ~ Data:', GlSalesChain);
+ return GlSalesChain.data;
+ } catch (error) {
+ console.log('🚀 ~ GlSalesChain ~ error:', error);
+ }
+}
+async function GlExpenseAllocation() {
+ console.log('Executing GL Expense Allocation');
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const DepartmentId = await GetDepartmentId();
+
+ try {
+ //This doesn't seem to work as it is for production only.
+ const GlExpenseAllocation = await axios.get(
+ `https://api.fortellis.io/cdk-test/drive/businessofficeglwippost/glExpenseAllocation`,
+ {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': DepartmentId,
+ },
+ },
+ );
+ console.log('🚀 ~ GlExpenseAllocation ~ Data:', GlExpenseAllocation);
+ return GlExpenseAllocation.data;
+ } catch (error) {
+ console.log('🚀 ~ GlSalesChain ~ error:', error);
+ }
+}
+
+///EXEC FUNCTIONS
+async function PostAccountsGLWIP() {
+ //const orgHelpers = await OrgHelpers();
+ //const jrnlHelpers = await JournalHelpers({ glCompanyNumber: orgHelpers[0].coID });
+
+ //const glSalesChain = await GlSalesChain();
+ const glExpenseAllocation = await GlExpenseAllocation();
+}
+
+//PostAccountsGLWIP();
+
+async function GetCOA() {
+ console.log('Executing GetCOA');
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const DepartmentId = await GetDepartmentId();
+
+ try {
+ //This doesn't seem to work as it is for production only.
+ const GetCOA = await axios.get(
+ `https://api.fortellis.io/cdk-test/drive/chartofaccounts/v2/bulk`,
+ {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ 'Subscription-Id': SubscriptionID,
+ 'Request-Id': ReqId,
+ 'Department-Id': DepartmentId,
+ },
+ },
+ );
+ console.log('🚀 ~ GetCOA ~ Data:', GetCOA);
+ return GetCOA.data;
+ } catch (error) {
+ console.log('🚀 ~ GetCOA ~ error:', error);
+ }
+}
+GetCOA();
diff --git a/fortellis.js b/fortellis.js
new file mode 100644
index 000000000..4c6a7553a
--- /dev/null
+++ b/fortellis.js
@@ -0,0 +1,235 @@
+const path = require("path");
+const AxiosLib = require("axios").default;
+const axios = AxiosLib.create();
+const uuid = require("uuid").v4;
+
+const FORTELLIS_KEY = "X1FxzLyOk3kjHvMbzdPQXFZShkdbgzuo"; //TODO: Regenerate these keys after testing and move to env vars.
+const FORTELLIS_SECRET = "7Yvs0wpQeHcUS5r95ht8pqOaAvBq7dHV";
+const FORTELLIS_AUTH_URL = "https://identity.fortellis.io/oauth2/aus1p1ixy7YL8cMq02p7/v1/token";
+const FORTELLIS_URL = "https://api.fortellis.io";
+const ENVSubscriptionID = "5b527d7d-baf3-40bc-adae-e7a541e37363"; //TODO: Replace with the bodyshop.cdk_dealerid
+let SubscriptionMeta = null;
+//const ENVSubscriptionID = 'cb59fa04-e53e-4b57-b071-80a48ebc346c';
+
+async function GetAuthToken() {
+ //Done with Authorization Code Flow
+ //https://docs.fortellis.io/docs/tutorials/solution-integration/authorization-code-flow/
+ const {
+ data: { access_token, expires_in, token_type }
+ } = await axios.post(
+ FORTELLIS_AUTH_URL,
+ {},
+ {
+ auth: {
+ username: FORTELLIS_KEY,
+ password: FORTELLIS_SECRET
+ },
+ params: {
+ grant_type: "client_credentials",
+ scope: "anonymous"
+ }
+ }
+ );
+ return access_token;
+}
+
+async function FetchSubscriptions() {
+ const access_token = await GetAuthToken();
+ try {
+ const subscriptions = await axios.get(`https://subscriptions.fortellis.io/v1/solution/subscriptions`, {
+ headers: { Authorization: `Bearer ${access_token}` }
+ });
+ SubscriptionMeta = subscriptions.data.subscriptions.find((s) => s.subscriptionId === ENVSubscriptionID);
+ return SubscriptionMeta;
+ } catch (error) {
+ console.log("🚀 ~ FetchSubscriptions ~ error:", error);
+ }
+}
+
+async function GetDepartmentId({ apiName, debug = false }) {
+ if (!apiName) throw new Error("apiName not provided. Unable to get department without apiName.");
+ if (debug) {
+ console.log("API Names & Departments ");
+ console.log("===========");
+ console.log(
+ JSON.stringify(
+ SubscriptionMeta.apiDmsInfo.map((a) => ({
+ name: a.name,
+ departments: a.departments.map((d) => d.id)
+ })),
+ null,
+ 4
+ )
+ );
+ console.log("===========");
+ }
+ const departmentIds2 = SubscriptionMeta.apiDmsInfo //Get the subscription object.
+ .find((info) => info.name === apiName)?.departments; //Departments are categorized by API name and have an array of departments.
+
+ return departmentIds2[0].id; //TODO: This makes the assumption that there is only 1 department.
+}
+
+async function MakeFortellisCall({ apiName, url, headers = {}, body = {}, type = "post", debug = false }) {
+ if (debug) console.log(`Executing ${type} to ${url}`);
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const DepartmentId = await GetDepartmentId({ apiName, debug });
+
+ if (debug) {
+ console.log(
+ `ReqID: ${ReqId} | SubscriptionID: ${SubscriptionMeta.subscriptionId} | DepartmentId: ${DepartmentId}`
+ );
+ console.log(`Body Contents: ${JSON.stringify(body, null, 4)}`);
+ }
+
+ try {
+ let result;
+ switch (type) {
+ case "post":
+ default:
+ result = await axios.post(url, body, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionMeta.subscriptionId,
+ "Request-Id": ReqId,
+ "Department-Id": DepartmentId,
+ ...headers
+ }
+ });
+ break;
+ case "get":
+ result = await axios.get(url, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionMeta.subscriptionId,
+ "Request-Id": ReqId,
+ "Department-Id": DepartmentId,
+ ...headers
+ }
+ });
+ break;
+ }
+
+ if (debug) {
+ console.log(`ReqID: ${ReqId} Data`);
+ console.log(JSON.stringify(result.data, null, 4));
+ }
+
+ if (result.data.checkStatusAfterSeconds) {
+ return DelayedCallback({
+ delayMeta: result.data,
+ access_token,
+ SubscriptionID: SubscriptionMeta.subscriptionId,
+ ReqId,
+ departmentIds: DepartmentId
+ });
+ }
+ return result.data;
+ } catch (error) {
+ console.log(`ReqID: ${ReqId} Error`, error.response?.data);
+ //console.log(`ReqID: ${ReqId} Full Error`, JSON.stringify(error, null, 4));
+ }
+}
+//Get the status meta, then keep checking and return the result.
+async function DelayedCallback({ delayMeta, access_token, SubscriptionID, ReqId, departmentIds }) {
+ for (let index = 0; index < 5; index++) {
+ await sleep(delayMeta.checkStatusAfterSeconds * 1000);
+ //Check to see if the call is ready.
+ const statusResult = await axios.get(delayMeta._links.status.href, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionID,
+ "Request-Id": ReqId,
+ "Department-Id": departmentIds[0].id
+ }
+ });
+
+ //TODO: Add a check if the status result is not ready, to try again.
+ if (statusResult.data.status === "complete") {
+ //This may have to check again if it isn't ready.
+ const batchResult = await axios.get(statusResult.data._links.result.href, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionID,
+ "Request-Id": ReqId,
+ //"Department-Id": departmentIds[0].id
+ }
+ });
+ return batchResult;
+ } else {
+ return "Error!!! Still need to implement batch waiting.";
+ }
+ }
+}
+function sleep(ms) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+async function GetCOA() {
+ console.log("Executing GetCOA");
+ await MakeFortellisCall({
+ debug: true,
+ type: "get",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ url: `https://api.fortellis.io/cdk-test/drive/chartofaccounts/v2/bulk`,
+ waitForResult: true
+ });
+}
+
+async function StartWIP() {
+ const TransactionWip = MakeFortellisCall({
+ url: "https://api.fortellis.io/cdk-test/drive/glwippost/startWIP",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ body: {
+ acctgDate: "2023-09-26", //job.invoice
+ desc: "TEST TRANSACTION",
+ docType: "3", //pulled from Doc Type workbook
+ m13Flag: "0", // Is this a M13 entry. Presumanbly always 0
+ refer: "RO12345", //Supposed to be a doc reference number. Presumably the RO?
+ srcCo: "77",
+ srcJrnl: "80",
+ userID: "csr", //bodyshop user
+ userName: "PROGRAM, PARTNER*ADP" //Can leave blank to have this return to default.
+ },
+ debug: true
+ });
+
+ return TransactionWip;
+}
+
+async function InsertBatch({ transID }) {
+ const TransactionWip = MakeFortellisCall({
+ url: "https://api.fortellis.io/cdk-test/drive/glwippost/transWIP",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ body: [
+ {
+ acct: "",
+ cntl: "",
+ cntl2: null,
+ credtMemoNo: null,
+ postAmt: Math.round(payer.amount * 100),
+ postDesc: "", //Required if required by the DMS setup
+ prod: null, //Productivity Number
+ statCnt: 1, //Auto count, leave as 1.
+ transID: transID,
+ trgtCoID: "77" //Add this to read from the header
+ }
+ ],
+ debug: true
+ });
+}
+
+async function DoTheThings() {
+ await FetchSubscriptions();
+ //What do we have access to?
+ console.log("Sub Access : ", SubscriptionMeta.apiDmsInfo.map((i) => i.name).join(", "));
+ await GetCOA();
+
+ return;
+
+ //Insert Transactions
+ const TransactionHeader = await StartWIP();
+ const BatchResult = await InsertBatch({ transID: TransactionHeader.transID });
+}
+
+DoTheThings();
diff --git a/package.json b/package.json
index c66bdb8d2..62939ee0b 100644
--- a/package.json
+++ b/package.json
@@ -18,20 +18,21 @@
"job-totals-fixtures:local": "docker exec node-app /usr/bin/node /app/download-job-totals-fixtures.js"
},
"dependencies": {
- "@aws-sdk/client-cloudwatch-logs": "^3.887.0",
- "@aws-sdk/client-elasticache": "^3.887.0",
- "@aws-sdk/client-s3": "^3.887.0",
- "@aws-sdk/client-secrets-manager": "^3.887.0",
- "@aws-sdk/client-ses": "^3.887.0",
- "@aws-sdk/credential-provider-node": "^3.887.0",
- "@aws-sdk/lib-storage": "^3.887.0",
- "@aws-sdk/s3-request-presigner": "^3.887.0",
+ "@aws-sdk/client-cloudwatch-logs": "^3.882.0",
+ "@aws-sdk/client-elasticache": "^3.882.0",
+ "@aws-sdk/client-s3": "^3.882.0",
+ "@aws-sdk/client-secrets-manager": "^3.882.0",
+ "@aws-sdk/client-ses": "^3.882.0",
+ "@aws-sdk/credential-provider-node": "^3.882.0",
+ "@aws-sdk/lib-storage": "^3.882.0",
+ "@aws-sdk/s3-request-presigner": "^3.882.0",
"@opensearch-project/opensearch": "^2.13.0",
"@socket.io/admin-ui": "^0.5.1",
"@socket.io/redis-adapter": "^8.3.0",
"archiver": "^7.0.1",
"aws4": "^1.13.2",
- "axios": "^1.12.1",
+ "axios": "^1.11.0",
+ "axios-curlirize": "^2.0.0",
"better-queue": "^3.8.12",
"bullmq": "^5.58.5",
"chart.js": "^4.5.0",
@@ -40,7 +41,7 @@
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"crisp-status-reporter": "^1.2.2",
- "dd-trace": "^5.67.0",
+ "dd-trace": "^5.65.0",
"dinero.js": "^1.9.1",
"dotenv": "^17.2.2",
"express": "^4.21.1",
diff --git a/server.js b/server.js
index 2bb2bf5a8..1ddf2201a 100644
--- a/server.js
+++ b/server.js
@@ -38,7 +38,7 @@ const { registerCleanupTask, initializeCleanupManager } = require("./server/util
const { loadEmailQueue } = require("./server/notifications/queues/emailQueue");
const { loadAppQueue } = require("./server/notifications/queues/appQueue");
-
+const { SetLegacyWebsocketHandlers } = require("./server/web-sockets/web-socket");
const CLUSTER_RETRY_BASE_DELAY = 100;
const CLUSTER_RETRY_MAX_DELAY = 5000;
const CLUSTER_RETRY_JITTER = 100;
@@ -324,6 +324,9 @@ const applySocketIO = async ({ server, app }) => {
}
});
+ // Legacy Socket Events
+ SetLegacyWebsocketHandlers(io)
+
const api = {
pubClient,
io,
@@ -387,8 +390,6 @@ const main = async () => {
const redisHelpers = applyRedisHelpers({ pubClient, app, logger });
const ioHelpers = applyIOHelpers({ app, redisHelpers, ioRedis, logger });
- // Legacy Socket Events
- require("./server/web-sockets/web-socket");
// Initialize Queues
await loadQueues({ pubClient: pubClient, logger, redisHelpers, ioRedis });
diff --git a/server/accounting/pbs/pbs-ap-allocations.js b/server/accounting/pbs/pbs-ap-allocations.js
index f5092030c..f417d0d15 100644
--- a/server/accounting/pbs/pbs-ap-allocations.js
+++ b/server/accounting/pbs/pbs-ap-allocations.js
@@ -1,7 +1,7 @@
const GraphQLClient = require("graphql-request").GraphQLClient;
const queries = require("../../graphql-client/queries");
-const CdkBase = require("../../web-sockets/web-socket");
+const WsLogger = require("../../web-sockets/createLogEvent")
const moment = require("moment");
const Dinero = require("dinero.js");
const AxiosLib = require("axios").default;
@@ -18,12 +18,11 @@ axios.interceptors.request.use((x) => {
...x.headers
};
- const printable = `${new Date()} | Request: ${x.method.toUpperCase()} | ${
- x.url
- } | ${JSON.stringify(x.data)} | ${JSON.stringify(headers)}`;
+ const printable = `${new Date()} | Request: ${x.method.toUpperCase()} | ${x.url
+ } | ${JSON.stringify(x.data)} | ${JSON.stringify(headers)}`;
//console.log(printable);
- CdkBase.createJsonEvent(socket, "SILLY", `Raw Request: ${printable}`, x.data);
+ WsLogger.createJsonEvent(socket, "SILLY", `Raw Request: ${printable}`, x.data);
return x;
});
@@ -33,14 +32,14 @@ axios.interceptors.response.use((x) => {
const printable = `${new Date()} | Response: ${x.status} | ${JSON.stringify(x.data)}`;
//console.log(printable);
- CdkBase.createJsonEvent(socket, "SILLY", `Raw Response: ${printable}`, x.data);
+ WsLogger.createJsonEvent(socket, "SILLY", `Raw Response: ${printable}`, x.data);
return x;
});
async function PbsCalculateAllocationsAp(socket, billids) {
try {
- CdkBase.createLogEvent(socket, "DEBUG", `Received request to calculate allocations for ${billids}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Received request to calculate allocations for ${billids}`);
const { bills, bodyshops } = await QueryBillData(socket, billids);
const bodyshop = bodyshops[0];
socket.bodyshop = bodyshop;
@@ -50,7 +49,7 @@ async function PbsCalculateAllocationsAp(socket, billids) {
const transactionlist = [];
if (bills.length === 0) {
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"ERROR",
`No bills found for export. Ensure they have not already been exported and try again.`
@@ -166,19 +165,19 @@ async function PbsCalculateAllocationsAp(socket, billids) {
return transactionlist;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error encountered in PbsCalculateAllocationsAp. ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error encountered in PbsCalculateAllocationsAp. ${error}`);
}
}
exports.PbsCalculateAllocationsAp = PbsCalculateAllocationsAp;
async function QueryBillData(socket, billids) {
- CdkBase.createLogEvent(socket, "DEBUG", `Querying bill data for id(s) ${billids}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Querying bill data for id(s) ${billids}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
.request(queries.GET_PBS_AP_ALLOCATIONS, { billids: billids });
- CdkBase.createLogEvent(socket, "SILLY", `Bill data query result ${JSON.stringify(result, null, 2)}`);
+ WsLogger.createLogEvent(socket, "SILLY", `Bill data query result ${JSON.stringify(result, null, 2)}`);
return result;
}
@@ -193,7 +192,7 @@ function getCostAccount(billline, respcenters) {
}
exports.PbsExportAp = async function (socket, { billids, txEnvelope }) {
- CdkBase.createLogEvent(socket, "DEBUG", `Exporting selected AP.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Exporting selected AP.`);
//apAllocations has the same shap as the lines key for the accounting posting to PBS.
socket.apAllocations = await PbsCalculateAllocationsAp(socket, billids);
@@ -208,12 +207,12 @@ exports.PbsExportAp = async function (socket, { billids, txEnvelope }) {
CheckForErrors(socket, AccountPostingChange);
if (AccountPostingChange.WasSuccessful) {
- CdkBase.createLogEvent(socket, "DEBUG", `Marking bill as exported.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Marking bill as exported.`);
await MarkApExported(socket, [billid]);
socket.emit("ap-export-success", billid);
} else {
- CdkBase.createLogEvent(socket, "ERROR", `Export was not successful.`);
+ WsLogger.createLogEvent(socket, "ERROR", `Export was not successful.`);
socket.emit("ap-export-failure", {
billid,
error: AccountPostingChange.Message
@@ -224,7 +223,7 @@ exports.PbsExportAp = async function (socket, { billids, txEnvelope }) {
};
async function MarkApExported(socket, billids) {
- CdkBase.createLogEvent(socket, "DEBUG", `Marking bills as exported for id ${billids}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Marking bills as exported for id ${billids}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
diff --git a/server/accounting/pbs/pbs-job-export.js b/server/accounting/pbs/pbs-job-export.js
index 127c9d5e2..61f449e84 100644
--- a/server/accounting/pbs/pbs-job-export.js
+++ b/server/accounting/pbs/pbs-job-export.js
@@ -2,10 +2,10 @@ const GraphQLClient = require("graphql-request").GraphQLClient;
const AxiosLib = require("axios").default;
const queries = require("../../graphql-client/queries");
const { PBS_ENDPOINTS, PBS_CREDENTIALS } = require("./pbs-constants");
+const WsLogger = require("../../web-sockets/createLogEvent")
//const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
const CalculateAllocations = require("../../cdk/cdk-calculate-allocations").default;
-const CdkBase = require("../../web-sockets/web-socket");
const moment = require("moment-timezone");
const Dinero = require("dinero.js");
const InstanceManager = require("../../utils/instanceMgr").default;
@@ -19,12 +19,11 @@ axios.interceptors.request.use((x) => {
...x.headers[x.method],
...x.headers
};
- const printable = `${new Date()} | Request: ${x.method.toUpperCase()} | ${
- x.url
- } | ${JSON.stringify(x.data)} | ${JSON.stringify(headers)}`;
+ const printable = `${new Date()} | Request: ${x.method.toUpperCase()} | ${x.url
+ } | ${JSON.stringify(x.data)} | ${JSON.stringify(headers)}`;
//console.log(printable);
- CdkBase.createJsonEvent(socket, "SILLY", `Raw Request: ${printable}`, x.data);
+ WsLogger.createJsonEvent(socket, "SILLY", `Raw Request: ${printable}`, x.data);
return x;
});
@@ -34,7 +33,7 @@ axios.interceptors.response.use((x) => {
const printable = `${new Date()} | Response: ${x.status} | ${JSON.stringify(x.data)}`;
//console.log(printable);
- CdkBase.createJsonEvent(socket, "SILLY", `Raw Response: ${printable}`, x.data);
+ WsLogger.createJsonEvent(socket, "SILLY", `Raw Response: ${printable}`, x.data);
return x;
});
@@ -44,11 +43,11 @@ exports.default = async function (socket, { txEnvelope, jobid }) {
socket.recordid = jobid;
socket.txEnvelope = txEnvelope;
try {
- CdkBase.createLogEvent(socket, "DEBUG", `Received Job export request for id ${jobid}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Received Job export request for id ${jobid}`);
const JobData = await QueryJobData(socket, jobid);
socket.JobData = JobData;
- CdkBase.createLogEvent(socket, "DEBUG", `Querying the DMS for the Vehicle Record.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Querying the DMS for the Vehicle Record.`);
//Query for the Vehicle record to get the associated customer.
socket.DmsVeh = await QueryVehicleFromDms(socket);
//Todo: Need to validate the lines and methods below.
@@ -63,48 +62,47 @@ exports.default = async function (socket, { txEnvelope, jobid }) {
...socket.DMSCustList
]);
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error encountered in PbsJobExport. ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error encountered in PbsJobExport. ${error}`);
}
};
exports.PbsSelectedCustomer = async function PbsSelectedCustomer(socket, selectedCustomerId) {
try {
if (socket.JobData.bodyshop.pbs_configuration.disablecontactvehicle === false) {
- CdkBase.createLogEvent(socket, "DEBUG", `User selected customer ${selectedCustomerId || "NEW"}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `User selected customer ${selectedCustomerId || "NEW"}`);
//Upsert the contact information as per Wafaa's Email.
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
- `Upserting contact information to DMS for ${
- socket.JobData.ownr_fn || ""
+ `Upserting contact information to DMS for ${socket.JobData.ownr_fn || ""
} ${socket.JobData.ownr_ln || ""} ${socket.JobData.ownr_co_nm || ""}`
);
const ownerRef = await UpsertContactData(socket, selectedCustomerId);
- CdkBase.createLogEvent(socket, "DEBUG", `Upserting vehicle information to DMS for ${socket.JobData.v_vin}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Upserting vehicle information to DMS for ${socket.JobData.v_vin}`);
await UpsertVehicleData(socket, ownerRef.ReferenceId);
} else {
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`Contact and Vehicle updates disabled. Skipping to accounting data insert.`
);
}
- CdkBase.createLogEvent(socket, "DEBUG", `Inserting account data.`);
- CdkBase.createLogEvent(socket, "DEBUG", `Inserting accounting posting data..`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Inserting account data.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Inserting accounting posting data..`);
const insertResponse = await InsertAccountPostingData(socket);
if (insertResponse.WasSuccessful) {
- CdkBase.createLogEvent(socket, "DEBUG", `Marking job as exported.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Marking job as exported.`);
await MarkJobExported(socket, socket.JobData.id);
socket.emit("export-success", socket.JobData.id);
} else {
- CdkBase.createLogEvent(socket, "ERROR", `Export was not successful.`);
+ WsLogger.createLogEvent(socket, "ERROR", `Export was not successful.`);
}
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
await InsertFailedExportLog(socket, error);
}
};
@@ -112,22 +110,22 @@ exports.PbsSelectedCustomer = async function PbsSelectedCustomer(socket, selecte
// Was Successful
async function CheckForErrors(socket, response) {
if (response.WasSuccessful === undefined || response.WasSuccessful === true) {
- CdkBase.createLogEvent(socket, "DEBUG", `Successful response from DMS. ${response.Message || ""}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Successful response from DMS. ${response.Message || ""}`);
} else {
- CdkBase.createLogEvent(socket, "ERROR", `Error received from DMS: ${response.Message}`);
- CdkBase.createLogEvent(socket, "SILLY", `Error received from DMS: ${JSON.stringify(response)}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error received from DMS: ${response.Message}`);
+ WsLogger.createLogEvent(socket, "SILLY", `Error received from DMS: ${JSON.stringify(response)}`);
}
}
exports.CheckForErrors = CheckForErrors;
async function QueryJobData(socket, jobid) {
- CdkBase.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
.request(queries.QUERY_JOBS_FOR_PBS_EXPORT, { id: jobid });
- CdkBase.createLogEvent(socket, "SILLY", `Job data query result ${JSON.stringify(result, null, 2)}`);
+ WsLogger.createLogEvent(socket, "SILLY", `Job data query result ${JSON.stringify(result, null, 2)}`);
return result.jobs_by_pk;
}
@@ -166,7 +164,7 @@ async function QueryVehicleFromDms(socket) {
CheckForErrors(socket, VehicleGetResponse);
return VehicleGetResponse;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryVehicleFromDms - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryVehicleFromDms - ${error}`);
throw new Error(error);
}
}
@@ -197,7 +195,7 @@ async function QueryCustomersFromDms(socket) {
CheckForErrors(socket, CustomerGetResponse);
return CustomerGetResponse && CustomerGetResponse.Contacts;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryCustomersFromDms - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryCustomersFromDms - ${error}`);
throw new Error(error);
}
}
@@ -230,7 +228,7 @@ async function QueryCustomerBycodeFromDms(socket, CustomerRef) {
CheckForErrors(socket, CustomerGetResponse);
return CustomerGetResponse && CustomerGetResponse.Contacts;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryCustomersFromDms - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryCustomersFromDms - ${error}`);
throw new Error(error);
}
}
@@ -247,15 +245,15 @@ async function UpsertContactData(socket, selectedCustomerId) {
Code: socket.JobData.owner.accountingid,
...(socket.JobData.ownr_co_nm
? {
- //LastName: socket.JobData.ownr_ln,
- FirstName: socket.JobData.ownr_co_nm,
- IsBusiness: true
- }
+ //LastName: socket.JobData.ownr_ln,
+ FirstName: socket.JobData.ownr_co_nm,
+ IsBusiness: true
+ }
: {
- LastName: socket.JobData.ownr_ln,
- FirstName: socket.JobData.ownr_fn,
- IsBusiness: false
- }),
+ LastName: socket.JobData.ownr_ln,
+ FirstName: socket.JobData.ownr_fn,
+ IsBusiness: false
+ }),
//Salutation: "String",
//MiddleName: "String",
@@ -312,7 +310,7 @@ async function UpsertContactData(socket, selectedCustomerId) {
CheckForErrors(socket, ContactChangeResponse);
return ContactChangeResponse;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in UpsertContactData - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in UpsertContactData - ${error}`);
throw new Error(error);
}
}
@@ -465,7 +463,7 @@ async function UpsertVehicleData(socket, ownerRef) {
CheckForErrors(socket, VehicleChangeResponse);
return VehicleChangeResponse;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in UpsertVehicleData - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in UpsertVehicleData - ${error}`);
throw new Error(error);
}
}
@@ -566,13 +564,13 @@ async function InsertAccountPostingData(socket) {
CheckForErrors(socket, AccountPostingChange);
return AccountPostingChange;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertAccountPostingData - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertAccountPostingData - ${error}`);
throw new Error(error);
}
}
async function MarkJobExported(socket, jobid) {
- CdkBase.createLogEvent(socket, "DEBUG", `Marking job as exported for id ${jobid}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Marking job as exported for id ${jobid}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
@@ -615,6 +613,6 @@ async function InsertFailedExportLog(socket, error) {
return result;
} catch (error2) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertFailedExportLog - ${error} - ${JSON.stringify(error2)}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertFailedExportLog - ${error} - ${JSON.stringify(error2)}`);
}
}
diff --git a/server/cdk/cdk-calculate-allocations.js b/server/cdk/cdk-calculate-allocations.js
index 7c90aef20..c8de282db 100644
--- a/server/cdk/cdk-calculate-allocations.js
+++ b/server/cdk/cdk-calculate-allocations.js
@@ -1,10 +1,11 @@
const GraphQLClient = require("graphql-request").GraphQLClient;
const queries = require("../graphql-client/queries");
-const CdkBase = require("../web-sockets/web-socket");
-
+const CreateFortellisLogEvent = require("../fortellis/fortellis-logger");
const Dinero = require("dinero.js");
const _ = require("lodash");
+const WsLogger = require("../web-sockets/createLogEvent")
+
const InstanceManager = require("../utils/instanceMgr").default;
const { DiscountNotAlreadyCounted } = InstanceManager({
imex: require("../job/job-totals"),
@@ -13,37 +14,41 @@ const { DiscountNotAlreadyCounted } = InstanceManager({
exports.defaultRoute = async function (req, res) {
try {
- CdkBase.createLogEvent(req, "DEBUG", `Received request to calculate allocations for ${req.body.jobid}`);
+ //Fortellis TODO: determine when this is called and whether refactor is required.
+ WsLogger.createLogEvent(req, "DEBUG", `Received request to calculate allocations for ${req.body.jobid}`);
const jobData = await QueryJobData(req, req.BearerToken, req.body.jobid);
return res.status(200).json({ data: calculateAllocations(req, jobData) });
} catch (error) {
////console.log(error);
- CdkBase.createLogEvent(req, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
+ WsLogger.createLogEvent(req, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
res.status(500).json({ error: `Error encountered in CdkCalculateAllocations. ${error}` });
}
};
-exports.default = async function (socket, jobid) {
+exports.default = async function (socket, jobid, isFortellis = false) {
try {
- const jobData = await QueryJobData(socket, "Bearer " + socket.handshake.auth.token, jobid);
- return calculateAllocations(socket, jobData);
+ const jobData = await QueryJobData(socket, "Bearer " + socket.handshake.auth.token, jobid, isFortellis);
+ return calculateAllocations(socket, jobData, isFortellis);
} catch (error) {
////console.log(error);
- CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
+ const loggingFunction = isFortellis ? CreateFortellisLogEvent : WsLogger.createLogEvent;
+ loggingFunction(socket, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
}
};
-async function QueryJobData(connectionData, token, jobid) {
- CdkBase.createLogEvent(connectionData, "DEBUG", `Querying job data for id ${jobid}`);
+async function QueryJobData(connectionData, token, jobid, isFortellis) {
+ const loggingFunction = isFortellis ? CreateFortellisLogEvent : WsLogger.createLogEvent;
+
+ loggingFunction(connectionData, "DEBUG", `Querying job data for id ${jobid}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client.setHeaders({ Authorization: token }).request(queries.GET_CDK_ALLOCATIONS, { id: jobid });
- CdkBase.createLogEvent(connectionData, "SILLY", `Job data query result ${JSON.stringify(result, null, 2)}`);
+ loggingFunction(connectionData, "DEBUG", `Job data query result ${JSON.stringify(result, null, 2)}`);
return result.jobs_by_pk;
}
-function calculateAllocations(connectionData, job) {
+function calculateAllocations(connectionData, job, isFortellis) {
const { bodyshop } = job;
-
+ const loggingFunction = isFortellis ? CreateFortellisLogEvent : WsLogger.createLogEvent;
const taxAllocations = InstanceManager({
executeFunction: true,
deubg: true,
@@ -132,11 +137,11 @@ function calculateAllocations(connectionData, job) {
? val.prt_dsmk_m
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
: Dinero({
- amount: Math.round(val.act_price * 100)
- })
- .multiply(val.part_qty || 0)
- .percentage(Math.abs(val.prt_dsmk_p || 0))
- .multiply(val.prt_dsmk_p > 0 ? 1 : -1)
+ amount: Math.round(val.act_price * 100)
+ })
+ .multiply(val.part_qty || 0)
+ .percentage(Math.abs(val.prt_dsmk_p || 0))
+ .multiply(val.prt_dsmk_p > 0 ? 1 : -1)
: Dinero()
);
@@ -159,7 +164,7 @@ function calculateAllocations(connectionData, job) {
const selectedDmsAllocationConfig = bodyshop.md_responsibility_centers.dms_defaults.find(
(d) => d.name === job.dms_allocation
);
- CdkBase.createLogEvent(
+ loggingFunction(
connectionData,
"DEBUG",
`Using DMS Allocation ${selectedDmsAllocationConfig && selectedDmsAllocationConfig.name} for cost export.`
@@ -194,8 +199,8 @@ function calculateAllocations(connectionData, job) {
let TicketTotal = Dinero({
amount: Math.round(
ticket.rate *
- (ticket.employee && ticket.employee.flat_rate ? ticket.productivehrs || 0 : ticket.actualhrs || 0) *
- 100
+ (ticket.employee && ticket.employee.flat_rate ? ticket.productivehrs || 0 : ticket.actualhrs || 0) *
+ 100
)
});
//Add it to the right cost center.
@@ -360,10 +365,10 @@ function calculateAllocations(connectionData, job) {
Dinero(job.job_totals.parts.adjustments[key])
);
} else {
- CdkBase.createLogEvent(
+ loggingFunction(
connectionData,
"ERROR",
- `Error encountered in CdkCalculateAllocations. Unable to find adjustment account. ${error}`
+ `Error encountered in CdkCalculateAllocations. Unable to find adjustment account: ${accountName}`
);
}
});
@@ -383,10 +388,10 @@ function calculateAllocations(connectionData, job) {
Dinero(job.job_totals.rates[key].adjustments)
);
} else {
- CdkBase.createLogEvent(
+ loggingFunction(
connectionData,
"ERROR",
- `Error encountered in CdkCalculateAllocations. Unable to find adjustment account. ${error}`
+ `Error encountered in CdkCalculateAllocations. Unable to find adjustment account: ${accountName}`
);
}
}
@@ -427,37 +432,37 @@ function calculateAllocations(connectionData, job) {
...(job.job_totals.totals.ttl_adjustment
? [
- {
- center: "SUB ADJ",
- sale: Dinero(job.job_totals.totals.ttl_adjustment),
- cost: Dinero(),
- profitCenter: {
- name: "SUB ADJ",
- accountdesc: "SUB ADJ",
- accountitem: "SUB ADJ",
- accountname: "SUB ADJ",
- dms_acctnumber: bodyshop.md_responsibility_centers.ttl_adjustment.dms_acctnumber
- },
- costCenter: {}
- }
- ]
+ {
+ center: "SUB ADJ",
+ sale: Dinero(job.job_totals.totals.ttl_adjustment),
+ cost: Dinero(),
+ profitCenter: {
+ name: "SUB ADJ",
+ accountdesc: "SUB ADJ",
+ accountitem: "SUB ADJ",
+ accountname: "SUB ADJ",
+ dms_acctnumber: bodyshop.md_responsibility_centers.ttl_adjustment.dms_acctnumber
+ },
+ costCenter: {}
+ }
+ ]
: []),
...(job.job_totals.totals.ttl_tax_adjustment
? [
- {
- center: "TAX ADJ",
- sale: Dinero(job.job_totals.totals.ttl_tax_adjustment),
- cost: Dinero(),
- profitCenter: {
- name: "TAX ADJ",
- accountdesc: "TAX ADJ",
- accountitem: "TAX ADJ",
- accountname: "TAX ADJ",
- dms_acctnumber: bodyshop.md_responsibility_centers.ttl_tax_adjustment.dms_acctnumber
- },
- costCenter: {}
- }
- ]
+ {
+ center: "TAX ADJ",
+ sale: Dinero(job.job_totals.totals.ttl_tax_adjustment),
+ cost: Dinero(),
+ profitCenter: {
+ name: "TAX ADJ",
+ accountdesc: "TAX ADJ",
+ accountitem: "TAX ADJ",
+ accountname: "TAX ADJ",
+ dms_acctnumber: bodyshop.md_responsibility_centers.ttl_tax_adjustment.dms_acctnumber
+ },
+ costCenter: {}
+ }
+ ]
: [])
];
}
diff --git a/server/cdk/cdk-job-export.js b/server/cdk/cdk-job-export.js
index b93ee3637..619313c7b 100644
--- a/server/cdk/cdk-job-export.js
+++ b/server/cdk/cdk-job-export.js
@@ -1,33 +1,36 @@
const GraphQLClient = require("graphql-request").GraphQLClient;
const soap = require("soap");
const queries = require("../graphql-client/queries");
-const CdkBase = require("../web-sockets/web-socket");
const CdkWsdl = require("./cdk-wsdl").default;
const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
const CalcualteAllocations = require("./cdk-calculate-allocations").default;
const InstanceMgr = require("../utils/instanceMgr").default;
+const WsLogger = require("../web-sockets/createLogEvent")
const moment = require("moment-timezone");
const replaceSpecialRegex = /[^a-zA-Z0-9 .,\n #]+/g;
exports.default = async function (socket, { txEnvelope, jobid }) {
+ ////Store the following information into the redis store for this transaction.
socket.logEvents = [];
socket.recordid = jobid;
socket.txEnvelope = txEnvelope;
+ ////
+
try {
- CdkBase.createLogEvent(socket, "DEBUG", `Received Job export request for id ${jobid}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Received Job export request for id ${jobid}`);
const JobData = await QueryJobData(socket, jobid);
socket.JobData = JobData;
const DealerId = JobData.bodyshop.cdk_dealerid;
- CdkBase.createLogEvent(socket, "DEBUG", `Dealer ID detected: ${JSON.stringify(DealerId)}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Dealer ID detected: ${JSON.stringify(DealerId)}`);
- CdkBase.createLogEvent(socket, "DEBUG", `{1} Begin Calculate DMS Vehicle ID using VIN: ${JobData.v_vin}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{1} Begin Calculate DMS Vehicle ID using VIN: ${JobData.v_vin}`);
socket.DMSVid = await CalculateDmsVid(socket, JobData);
if (socket.DMSVid.newId === "N") {
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`{2.1} Querying the Vehicle using the DMSVid: ${socket.DMSVid.vehiclesVehId}`
@@ -38,7 +41,7 @@ exports.default = async function (socket, { txEnvelope, jobid }) {
socket.DMSVeh && socket.DMSVeh.owners && socket.DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
if (DMSVehCustomer && DMSVehCustomer.id && DMSVehCustomer.id.value) {
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`{2.2} Querying the Customer using the ID from DMSVeh: ${DMSVehCustomer.id.value}`
@@ -47,7 +50,7 @@ exports.default = async function (socket, { txEnvelope, jobid }) {
}
}
- CdkBase.createLogEvent(socket, "DEBUG", `{2.3} Querying the Customer using the name.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{2.3} Querying the Customer using the name.`);
socket.DMSCustList = await QueryDmsCustomerByName(socket, JobData);
@@ -56,7 +59,7 @@ exports.default = async function (socket, { txEnvelope, jobid }) {
...socket.DMSCustList
]);
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkJobExport. ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error encountered in CdkJobExport. ${error}`);
}
};
@@ -64,35 +67,35 @@ async function CdkSelectedCustomer(socket, selectedCustomerId) {
try {
socket.selectedCustomerId = selectedCustomerId;
if (selectedCustomerId) {
- CdkBase.createLogEvent(socket, "DEBUG", `{3.1} Querying the Customer using Customer ID: ${selectedCustomerId}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{3.1} Querying the Customer using Customer ID: ${selectedCustomerId}`);
socket.DMSCust = await QueryDmsCustomerById(socket, socket.JobData, selectedCustomerId);
} else {
- CdkBase.createLogEvent(socket, "DEBUG", `{3.2} Generating a new customer ID.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{3.2} Generating a new customer ID.`);
const newCustomerId = await GenerateDmsCustomerNumber(socket);
- CdkBase.createLogEvent(socket, "DEBUG", `{3.3} Inserting new customer with ID: ${newCustomerId}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{3.3} Inserting new customer with ID: ${newCustomerId}`);
socket.DMSCust = await InsertDmsCustomer(socket, newCustomerId);
}
if (socket.DMSVid.newId === "Y") {
- CdkBase.createLogEvent(socket, "DEBUG", `{4.1} Inserting new vehicle with ID: ID ${socket.DMSVid.vehiclesVehId}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{4.1} Inserting new vehicle with ID: ID ${socket.DMSVid.vehiclesVehId}`);
socket.DMSVeh = await InsertDmsVehicle(socket);
} else {
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`{4.2} Querying Existing Vehicle using ID ${socket.DMSVid.vehiclesVehId}`
);
socket.DMSVeh = await QueryDmsVehicleById(socket, socket.JobData, socket.DMSVid);
- CdkBase.createLogEvent(socket, "DEBUG", `{4.3} Updating Existing Vehicle to associate to owner.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{4.3} Updating Existing Vehicle to associate to owner.`);
socket.DMSVeh = await UpdateDmsVehicle(socket);
}
- CdkBase.createLogEvent(socket, "DEBUG", `{5} Creating Transaction header with Dms Start WIP`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{5} Creating Transaction header with Dms Start WIP`);
socket.DMSTransHeader = await InsertDmsStartWip(socket);
- CdkBase.createLogEvent(socket, "DEBUG", `{5.1} Creating Transaction with ID ${socket.DMSTransHeader.transID}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{5.1} Creating Transaction with ID ${socket.DMSTransHeader.transID}`);
socket.DMSBatchTxn = await InsertDmsBatchWip(socket);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`{6} Attempting to post Transaction with ID ${socket.DMSTransHeader.transID}`
@@ -100,23 +103,23 @@ async function CdkSelectedCustomer(socket, selectedCustomerId) {
socket.DmsBatchTxnPost = await PostDmsBatchWip(socket);
if (socket.DmsBatchTxnPost.code === "success") {
//something
- CdkBase.createLogEvent(socket, "DEBUG", `{6} Successfully posted sransaction to DMS.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{6} Successfully posted sransaction to DMS.`);
await MarkJobExported(socket, socket.JobData.id);
- CdkBase.createLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`);
socket.DMSVehHistory = await InsertServiceVehicleHistory(socket);
socket.emit("export-success", socket.JobData.id);
} else {
//Get the error code
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`{6.1} Getting errors for Transaction ID ${socket.DMSTransHeader.transID}`
);
socket.DmsError = await QueryDmsErrWip(socket);
//Delete the transaction
- CdkBase.createLogEvent(socket, "DEBUG", `{6.2} Deleting Transaction ID ${socket.DMSTransHeader.transID}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `{6.2} Deleting Transaction ID ${socket.DMSTransHeader.transID}`);
socket.DmsBatchTxnPost = await DeleteDmsWip(socket);
socket.DmsError.errMsg
@@ -125,29 +128,29 @@ async function CdkSelectedCustomer(socket, selectedCustomerId) {
(e) =>
e !== null &&
e !== "" &&
- CdkBase.createLogEvent(socket, "ERROR", `Error(s) encountered in posting transaction. ${e}`)
+ WsLogger.createLogEvent(socket, "ERROR", `Error(s) encountered in posting transaction. ${e}`)
);
}
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
await InsertFailedExportLog(socket, error);
} finally {
//Ensure we always insert logEvents
//GQL to insert logevents.
- CdkBase.createLogEvent(socket, "DEBUG", `Capturing log events to database.`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Capturing log events to database.`);
}
}
exports.CdkSelectedCustomer = CdkSelectedCustomer;
async function QueryJobData(socket, jobid) {
- CdkBase.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
.request(queries.QUERY_JOBS_FOR_CDK_EXPORT, { id: jobid });
- CdkBase.createLogEvent(socket, "SILLY", `Job data query result ${JSON.stringify(result, null, 2)}`);
+ WsLogger.createLogEvent(socket, "SILLY", `Job data query result ${JSON.stringify(result, null, 2)}`);
return result.jobs_by_pk;
}
@@ -161,11 +164,11 @@ async function CalculateDmsVid(socket, JobData) {
});
const [result, rawResponse, , rawRequest] = soapResponseVehicleInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.getVehIdsAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.getVehIdsAsync request.`);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.getVehIdsAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.getVehIdsAsync response.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientVehicleInsertUpdate.getVehIdsAsync Result ${JSON.stringify(result, null, 2)}`
@@ -178,15 +181,15 @@ async function CalculateDmsVid(socket, JobData) {
//return result && result.return && result.return[0];
} catch (error) {
- CdkBase.createXmlEvent(socket, error.request, `soapClientVehicleInsertUpdate.getVehIdsAsync request.`, true);
+ WsLogger.createXmlEvent(socket, error.request, `soapClientVehicleInsertUpdate.getVehIdsAsync request.`, true);
- CdkBase.createXmlEvent(
+ WsLogger.createXmlEvent(
socket,
error.response && error.response.data,
`soapClientVehicleInsertUpdate.getVehIdsAsync response.`,
true
);
- CdkBase.createLogEvent(socket, "ERROR", `{1} Error in CalculateDmsVid - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `{1} Error in CalculateDmsVid - ${error}`);
throw new Error(error);
}
}
@@ -206,19 +209,19 @@ async function QueryDmsVehicleById(socket, JobData, DMSVid) {
const [result, rawResponse, , rawRequest] = soapResponseVehicleInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.readAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.readAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientVehicleInsertUpdate.readAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.readAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.readAsync response.`);
CheckCdkResponseForError(socket, soapResponseVehicleInsertUpdate);
const VehicleFromDMS = result && result.return && result.return.vehicle;
return VehicleFromDMS;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryDmsVehicleById - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryDmsVehicleById - ${error}`);
throw new Error(error);
}
}
@@ -237,10 +240,10 @@ async function QueryDmsCustomerById(socket, JobData, CustomerId) {
const [result, rawResponse, , rawRequest] = soapResponseCustomerInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.readAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.readAsync request.`);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.readAsync response.`);
- CdkBase.createLogEvent(
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.readAsync response.`);
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientCustomerInsertUpdate.readAsync Result ${JSON.stringify(result, null, 2)}`
@@ -249,16 +252,16 @@ async function QueryDmsCustomerById(socket, JobData, CustomerId) {
const CustomersFromDms = result && result.return && result.return.customerParty;
return CustomersFromDms;
} catch (error) {
- CdkBase.createXmlEvent(socket, error.request, `soapClientCustomerInsertUpdate.readAsync request.`, true);
+ WsLogger.createXmlEvent(socket, error.request, `soapClientCustomerInsertUpdate.readAsync request.`, true);
- CdkBase.createXmlEvent(
+ WsLogger.createXmlEvent(
socket,
error.response && error.response.data,
`soapClientCustomerInsertUpdate.readAsync response.`,
true
);
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryDmsCustomerById - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryDmsCustomerById - ${error}`);
throw new Error(error);
}
}
@@ -270,7 +273,7 @@ async function QueryDmsCustomerByName(socket, JobData) {
: `${JobData.ownr_ln},${JobData.ownr_fn}`
).replace(replaceSpecialRegex, "");
- CdkBase.createLogEvent(socket, "DEBUG", `Begin Query DMS Customer by Name using: ${ownerName}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Begin Query DMS Customer by Name using: ${ownerName}`);
try {
const soapClientCustomerSearch = await soap.createClientAsync(CdkWsdl.CustomerSearch);
@@ -285,11 +288,11 @@ async function QueryDmsCustomerByName(socket, JobData) {
const [result, rawResponse, , rawRequest] = soapResponseCustomerSearch;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientCustomerSearch.executeSearchBulkAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientCustomerSearch.executeSearchBulkAsync request.`);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientCustomerSearch.executeSearchBulkAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientCustomerSearch.executeSearchBulkAsync response.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientCustomerSearch.executeSearchBulkAsync Result ${JSON.stringify(result, null, 2)}`
@@ -298,16 +301,16 @@ async function QueryDmsCustomerByName(socket, JobData) {
const CustomersFromDms = (result && result.return) || [];
return CustomersFromDms;
} catch (error) {
- CdkBase.createXmlEvent(socket, error.request, `soapClientCustomerSearch.executeSearchBulkAsync request.`, true);
+ WsLogger.createXmlEvent(socket, error.request, `soapClientCustomerSearch.executeSearchBulkAsync request.`, true);
- CdkBase.createXmlEvent(
+ WsLogger.createXmlEvent(
socket,
error.response && error.response.data,
`soapClientCustomerSearch.executeSearchBulkAsync response.`,
true
);
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryDmsCustomerByName - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryDmsCustomerByName - ${error}`);
throw new Error(error);
}
}
@@ -327,11 +330,11 @@ async function GenerateDmsCustomerNumber(socket) {
const [result, rawResponse, , rawRequest] = soapResponseCustomerInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.getCustomerNumberAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.getCustomerNumberAsync request.`);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.getCustomerNumberAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.getCustomerNumberAsync response.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientCustomerInsertUpdate.getCustomerNumberAsync Result ${JSON.stringify(result, null, 2)}`
@@ -340,20 +343,20 @@ async function GenerateDmsCustomerNumber(socket) {
const customerNumber = result && result.return && result.return.customerNumber;
return customerNumber;
} catch (error) {
- CdkBase.createXmlEvent(
+ WsLogger.createXmlEvent(
socket,
error.request,
`soapClientCustomerInsertUpdate.getCustomerNumberAsync request.`,
true
);
- CdkBase.createXmlEvent(
+ WsLogger.createXmlEvent(
socket,
error.response && error.response.data,
`soapClientCustomerInsertUpdate.getCustomerNumberAsync response.`,
true
);
- CdkBase.createLogEvent(socket, "ERROR", `Error in GenerateDmsCustomerNumber - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in GenerateDmsCustomerNumber - ${error}`);
throw new Error(error);
}
}
@@ -416,10 +419,10 @@ async function InsertDmsCustomer(socket, newCustomerNumber) {
);
const [result, rawResponse, , rawRequest] = soapResponseCustomerInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.insertAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.insertAsync request.`);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.insertAsync response.`);
- CdkBase.createLogEvent(
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.insertAsync response.`);
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientCustomerInsertUpdate.insertAsync Result ${JSON.stringify(result, null, 2)}`
@@ -428,15 +431,15 @@ async function InsertDmsCustomer(socket, newCustomerNumber) {
const customer = result && result.return && result.return.customerParty;
return customer;
} catch (error) {
- CdkBase.createXmlEvent(socket, error.request, `soapClientCustomerInsertUpdate.insertAsync request.`, true);
+ WsLogger.createXmlEvent(socket, error.request, `soapClientCustomerInsertUpdate.insertAsync request.`, true);
- CdkBase.createXmlEvent(
+ WsLogger.createXmlEvent(
socket,
error.response && error.response.data,
`soapClientCustomerInsertUpdate.insertAsync response.`,
true
);
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsCustomer - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertDmsCustomer - ${error}`);
throw new Error(error);
}
}
@@ -456,9 +459,9 @@ async function InsertDmsVehicle(socket) {
socket.txEnvelope.dms_unsold === true
? ""
: moment(socket.txEnvelope.inservicedate)
- //.tz(socket.JobData.bodyshop.timezone)
- .startOf("day")
- .toISOString()
+ //.tz(socket.JobData.bodyshop.timezone)
+ .startOf("day")
+ .toISOString()
}),
vehicleId: socket.DMSVid.vehiclesVehId
},
@@ -468,16 +471,16 @@ async function InsertDmsVehicle(socket) {
socket.txEnvelope.dms_unsold === true
? ""
: moment()
- // .tz(socket.JobData.bodyshop.timezone)
- .format("YYYYMMDD"),
+ // .tz(socket.JobData.bodyshop.timezone)
+ .format("YYYYMMDD"),
licensePlateNo:
socket.JobData.plate_no === null
? null
: String(socket.JobData.plate_no).replace(/([^\w]|_)/g, "").length === 0
? null
: String(socket.JobData.plate_no)
- .replace(/([^\w]|_)/g, "")
- .toUpperCase(),
+ .replace(/([^\w]|_)/g, "")
+ .toUpperCase(),
make: socket.txEnvelope.dms_make,
modelAbrev: socket.txEnvelope.dms_model,
modelYear: socket.JobData.v_model_yr,
@@ -497,19 +500,19 @@ async function InsertDmsVehicle(socket) {
const [result, rawResponse, , rawRequest] = soapResponseVehicleInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.insertAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.insertAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientVehicleInsertUpdate.insertAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.insertAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.insertAsync response.`);
CheckCdkResponseForError(socket, soapResponseVehicleInsertUpdate);
const VehicleFromDMS = result && result.return && result.return.vehicle;
return VehicleFromDMS;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsVehicle - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertDmsVehicle - ${error}`);
throw new Error(error);
}
}
@@ -554,13 +557,13 @@ async function UpdateDmsVehicle(socket) {
},
...(oldOwner
? [
- {
- id: {
- assigningPartyId: "PREVIOUS",
- value: oldOwner.id.value
- }
+ {
+ id: {
+ assigningPartyId: "PREVIOUS",
+ value: oldOwner.id.value
}
- ]
+ }
+ ]
: [])
];
}
@@ -578,24 +581,24 @@ async function UpdateDmsVehicle(socket) {
socket.txEnvelope.dms_unsold === true
? ""
: moment(socket.DMSVeh.dealer.inServiceDate || socket.txEnvelope.inservicedate)
- // .tz(socket.JobData.bodyshop.timezone)
- .toISOString()
+ // .tz(socket.JobData.bodyshop.timezone)
+ .toISOString()
})
},
vehicle: {
...socket.DMSVeh.vehicle,
...(socket.txEnvelope.dms_model_override
? {
- make: socket.txEnvelope.dms_make,
- modelAbrev: socket.txEnvelope.dms_model
- }
+ make: socket.txEnvelope.dms_make,
+ modelAbrev: socket.txEnvelope.dms_model
+ }
: {}),
deliveryDate:
socket.txEnvelope.dms_unsold === true
? ""
: moment(socket.DMSVeh.vehicle.deliveryDate)
- //.tz(socket.JobData.bodyshop.timezone)
- .toISOString()
+ //.tz(socket.JobData.bodyshop.timezone)
+ .toISOString()
},
owners: ids
},
@@ -603,19 +606,19 @@ async function UpdateDmsVehicle(socket) {
});
const [result, rawResponse, , rawRequest] = soapResponseVehicleInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.updateAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.updateAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`soapClientVehicleInsertUpdate.updateAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.updateAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.updateAsync response.`);
CheckCdkResponseForError(socket, soapResponseVehicleInsertUpdate);
const VehicleFromDMS = result && result.return && result.return.vehicle;
return VehicleFromDMS;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in UpdateDmsVehicle - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in UpdateDmsVehicle - ${error}`);
throw new Error(error);
}
}
@@ -642,18 +645,18 @@ async function InsertServiceVehicleHistory(socket) {
const [result, rawResponse, , rawRequest] = soapResponseServiceHistoryInsert;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientServiceHistoryInsert.serviceHistoryHeaderInsert Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert response.`);
CheckCdkResponseForError(socket, soapResponseServiceHistoryInsert);
return result && result.return;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertServiceVehicleHistory - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertServiceVehicleHistory - ${error}`);
throw new Error(error);
}
}
@@ -682,19 +685,19 @@ async function InsertDmsStartWip(socket) {
const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doStartWIPAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doStartWIPAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientAccountingGLInsertUpdate.doStartWIPAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doStartWIPAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doStartWIPAsync response.`);
CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
const TransactionHeader = result && result.return;
return TransactionHeader;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsStartWip - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertDmsStartWip - ${error}`);
throw new Error(error);
}
}
@@ -713,19 +716,19 @@ async function InsertDmsBatchWip(socket) {
const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync response.`);
CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
const BatchWipResult = result && result.return;
return BatchWipResult;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsBatchWip - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertDmsBatchWip - ${error}`);
throw new Error(error);
}
}
@@ -740,9 +743,9 @@ async function GenerateTransWips(socket) {
acct: alloc.profitCenter.dms_acctnumber,
cntl:
alloc.profitCenter.dms_control_override &&
- alloc.profitCenter.dms_control_override !== null &&
- alloc.profitCenter.dms_control_override !== undefined &&
- alloc.profitCenter.dms_control_override?.trim() !== ""
+ alloc.profitCenter.dms_control_override !== null &&
+ alloc.profitCenter.dms_control_override !== undefined &&
+ alloc.profitCenter.dms_control_override?.trim() !== ""
? alloc.profitCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
@@ -763,9 +766,9 @@ async function GenerateTransWips(socket) {
acct: alloc.costCenter.dms_acctnumber,
cntl:
alloc.costCenter.dms_control_override &&
- alloc.costCenter.dms_control_override !== null &&
- alloc.costCenter.dms_control_override !== undefined &&
- alloc.costCenter.dms_control_override?.trim() !== ""
+ alloc.costCenter.dms_control_override !== null &&
+ alloc.costCenter.dms_control_override !== undefined &&
+ alloc.costCenter.dms_control_override?.trim() !== ""
? alloc.costCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
@@ -783,9 +786,9 @@ async function GenerateTransWips(socket) {
acct: alloc.costCenter.dms_wip_acctnumber,
cntl:
alloc.costCenter.dms_control_override &&
- alloc.costCenter.dms_control_override !== null &&
- alloc.costCenter.dms_control_override !== undefined &&
- alloc.costCenter.dms_control_override?.trim() !== ""
+ alloc.costCenter.dms_control_override !== null &&
+ alloc.costCenter.dms_control_override !== undefined &&
+ alloc.costCenter.dms_control_override?.trim() !== ""
? alloc.costCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
@@ -824,9 +827,9 @@ async function GenerateTransWips(socket) {
acct: alloc.profitCenter.dms_acctnumber,
cntl:
alloc.profitCenter.dms_control_override &&
- alloc.profitCenter.dms_control_override !== null &&
- alloc.profitCenter.dms_control_override !== undefined &&
- alloc.profitCenter.dms_control_override?.trim() !== ""
+ alloc.profitCenter.dms_control_override !== null &&
+ alloc.profitCenter.dms_control_override !== undefined &&
+ alloc.profitCenter.dms_control_override?.trim() !== ""
? alloc.profitCenter.dms_control_override
: socket.JobData.ro_number,
cntl2: null,
@@ -877,19 +880,19 @@ async function PostDmsBatchWip(socket) {
const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync response.`);
// CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
const PostResult = result && result.return;
return PostResult;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`);
throw new Error(error);
}
}
@@ -906,19 +909,19 @@ async function QueryDmsErrWip(socket) {
const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doErrWIPAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doErrWIPAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"DEBUG",
`soapClientAccountingGLInsertUpdate.doErrWIPAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doErrWIPAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doErrWIPAsync response.`);
CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
const PostResult = result && result.return;
return PostResult;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in QueryDmsErrWip - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in QueryDmsErrWip - ${error}`);
throw new Error(error);
}
}
@@ -937,25 +940,25 @@ async function DeleteDmsWip(socket) {
const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
- CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync request.`);
+ WsLogger.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync request.`);
- CdkBase.createLogEvent(
+ WsLogger.createLogEvent(
socket,
"SILLY",
`soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync Result ${JSON.stringify(result, null, 2)}`
);
- CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync response.`);
+ WsLogger.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync response.`);
CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
const PostResult = result && result.return;
return PostResult;
} catch (error) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`);
throw new Error(error);
}
}
async function MarkJobExported(socket, jobid) {
- CdkBase.createLogEvent(socket, "DEBUG", `Marking job as exported for id ${jobid}`);
+ WsLogger.createLogEvent(socket, "DEBUG", `Marking job as exported for id ${jobid}`);
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
const result = await client
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
@@ -998,6 +1001,6 @@ async function InsertFailedExportLog(socket, error) {
return result;
} catch (error2) {
- CdkBase.createLogEvent(socket, "ERROR", `Error in InsertFailedExportLog - ${error} - ${JSON.stringify(error2)}`);
+ WsLogger.createLogEvent(socket, "ERROR", `Error in InsertFailedExportLog - ${error} - ${JSON.stringify(error2)}`);
}
}
diff --git a/server/fortellis/fortellis-helpers.js b/server/fortellis/fortellis-helpers.js
new file mode 100644
index 000000000..9eed6669c
--- /dev/null
+++ b/server/fortellis/fortellis-helpers.js
@@ -0,0 +1,373 @@
+const path = require("path");
+require("dotenv").config({
+ path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
+});
+
+const GraphQLClient = require("graphql-request").GraphQLClient;
+// const CalcualteAllocations = require("../cdk/cdk-calculate-allocations").default;
+const InstanceMgr = require("../utils/instanceMgr").default;
+const CreateFortellisLogEvent = require("./fortellis-logger");
+const queries = require("../graphql-client/queries");
+const logger = require("../utils/logger");
+const uuid = require("uuid").v4;
+const AxiosLib = require("axios").default;
+const axios = AxiosLib.create();
+const axiosCurlirize = require('axios-curlirize').default;
+
+axiosCurlirize(axios, (result, err) => {
+ const { command } = result;
+ console.log("*** ~ axiosCurlirize ~ command:", command);
+
+ // if (err) {
+ // use your logger here
+ // } else {
+ // }
+});
+
+const getTransactionType = (jobid) => `fortellis:${jobid}`;
+const defaultFortellisTTL = 60 * 60;
+
+async function GetAuthToken() {
+ //Done with Authorization Code Flow
+ //https://docs.fortellis.io/docs/tutorials/solution-integration/authorization-code-flow/
+
+ //TODO: This should get stored in the redis cache and only be refreshed when it expires.
+ const {
+ data: { access_token, expires_in, token_type }
+ } = await axios.post(
+ process.env.FORTELLIS_AUTH_URL,
+ {},
+ {
+ auth: {
+ username: process.env.FORTELLIS_KEY,
+ password: process.env.FORTELLIS_SECRET
+ },
+ params: {
+ grant_type: "client_credentials",
+ scope: "anonymous"
+ }
+ }
+ );
+ return access_token;
+}
+
+async function FetchSubscriptions({ redisHelpers, socket, jobid }) {
+ try {
+ const { setSessionTransactionData, getSessionTransactionData } = redisHelpers;
+
+ //Get Subscription ID from Transaction Envelope
+ const { SubscriptionID } = await getSessionTransactionData(socket.id, getTransactionType(jobid), `txEnvelope`);
+ if (!SubscriptionID) {
+ throw new Error("Subscription ID not found in transaction envelope.");
+ }
+
+ //Check to See if the subscription meta is in the Redis Cache.
+ const SubscriptionMetaFromCache = await getSessionTransactionData(
+ socket.id,
+ getTransactionType(jobid),
+ FortellisCacheEnums.SubscriptionMeta
+ );
+
+ // If it is, return it.
+ if (SubscriptionMetaFromCache) {
+ return SubscriptionMetaFromCache;
+ } else {
+ const access_token = await GetAuthToken();
+ const subscriptions = await axios.get(`https://subscriptions.fortellis.io/v1/solution/subscriptions`, {
+ headers: { Authorization: `Bearer ${access_token}` }
+ });
+ const SubscriptionMeta = subscriptions.data.subscriptions.find((s) => s.subscriptionId === SubscriptionID);
+ await setSessionTransactionData(
+ socket.id,
+ getTransactionType(jobid),
+ FortellisCacheEnums.SubscriptionMeta,
+ SubscriptionMeta,
+ defaultFortellisTTL
+ );
+ return SubscriptionMeta;
+ }
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error fetching subscription metadata.`, {
+ error: error.message,
+ stack: error.stack
+ });
+ }
+}
+
+async function GetDepartmentId({ apiName, debug = false, SubscriptionMeta }) {
+ if (!apiName) throw new Error("apiName not provided. Unable to get department without apiName.");
+ if (debug) {
+ console.log("API Names & Departments ");
+ console.log("===========");
+ console.log(
+ JSON.stringify(
+ SubscriptionMeta.apiDmsInfo.map((a) => ({
+ name: a.name,
+ departments: a.departments.map((d) => d.id)
+ })),
+ null,
+ 4
+ )
+ );
+ console.log("===========");
+ }
+ //TODO: Verify how to select the correct department.
+ const departmentIds2 = SubscriptionMeta.apiDmsInfo //Get the subscription object.
+ .find((info) => info.name === apiName)?.departments; //Departments are categorized by API name and have an array of departments.
+
+ return departmentIds2 && departmentIds2[0] && departmentIds2[0].id; //TODO: This makes the assumption that there is only 1 department.
+}
+
+//Highest level function call to make a call to fortellis. This should be the only call required, and it will handle all the logic for making the call.
+async function MakeFortellisCall({
+ apiName,
+ url,
+ headers = {},
+ body = {},
+ type = "post",
+ debug = true,
+ requestPathParams,
+ requestSearchParams = [], //Array of key/value strings like [["key", "value"]]
+ jobid,
+ redisHelpers,
+ socket,
+}) {
+ const { setSessionTransactionData, getSessionTransactionData } = redisHelpers;
+
+ const fullUrl = constructFullUrl({ url, pathParams: requestPathParams, requestSearchParams });
+
+ if (debug) logger.log(`Executing ${type} to ${fullUrl}`);
+ const ReqId = uuid();
+ const access_token = await GetAuthToken();
+ const SubscriptionMeta = await FetchSubscriptions({ redisHelpers, socket, jobid });
+ const DepartmentId = await GetDepartmentId({ apiName, debug, SubscriptionMeta });
+
+ if (debug) {
+ console.log(
+ `ReqID: ${ReqId} | SubscriptionID: ${SubscriptionMeta.subscriptionId} | DepartmentId: ${DepartmentId}`
+ );
+ console.log(`Body Contents: ${JSON.stringify(body, null, 4)}`);
+ }
+
+ try {
+ let result;
+ switch (type) {
+ case "post":
+ default:
+ result = await axios.post(fullUrl, body, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionMeta.subscriptionId,
+ "Request-Id": ReqId,
+ ...DepartmentId && { "Department-Id": DepartmentId },
+ ...headers
+ }
+ });
+ break;
+ case "get":
+ result = await axios.get(fullUrl, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionMeta.subscriptionId,
+ "Request-Id": ReqId,
+ "Department-Id": DepartmentId,
+ ...headers
+ }
+ });
+ break;
+ case "put":
+ result = await axios.put(fullUrl, body, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionMeta.subscriptionId,
+ "Request-Id": ReqId,
+ "Department-Id": DepartmentId,
+ ...headers
+ }
+ });
+ break;
+ }
+
+ if (debug) {
+ console.log(`ReqID: ${ReqId} Data`);
+ console.log(JSON.stringify(result.data, null, 4));
+ }
+
+ if (result.data.checkStatusAfterSeconds) {
+ return DelayedCallback({
+ delayMeta: result.data,
+ access_token,
+ SubscriptionID: SubscriptionMeta.subscriptionId,
+ ReqId,
+ departmentIds: DepartmentId
+ });
+ }
+ return result.data;
+ } catch (error) {
+ console.log(`ReqID: ${ReqId} Error`, error.response?.data);
+ //console.log(`ReqID: ${ReqId} Full Error`, JSON.stringify(error, null, 4));
+ }
+}
+
+//Some Fortellis calls return a batch result that isn't ready immediately.
+//This function will check the status of the call and wait until it is ready.
+//It will try 5 times before giving up.
+async function DelayedCallback({ delayMeta, access_token, SubscriptionID, ReqId, departmentIds }) {
+ for (let index = 0; index < 5; index++) {
+ await sleep(delayMeta.checkStatusAfterSeconds * 1000);
+ //Check to see if the call is ready.
+ const statusResult = await axios.get(delayMeta._links.status.href, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionID,
+ "Request-Id": ReqId,
+ "Department-Id": departmentIds[0].id
+ }
+ });
+
+ //TODO: Add a check if the status result is not ready, to try again.
+ if (statusResult.data.status === "complete") {
+ //This may have to check again if it isn't ready.
+ const batchResult = await axios.get(statusResult.data._links.result.href, {
+ headers: {
+ Authorization: `Bearer ${access_token}`,
+ "Subscription-Id": SubscriptionID,
+ "Request-Id": ReqId
+ //"Department-Id": departmentIds[0].id
+ }
+ });
+ return batchResult;
+ } else {
+ return "Error!!! Still need to implement batch waiting.";
+ }
+ }
+}
+function sleep(ms) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+}
+
+const isProduction = process.env.NODE_ENV === "production";
+
+const FortellisActions = {
+ QueryVehicles: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdkdrive/service/v1/vehicles/"
+ : "https://api.fortellis.io/cdk-test/cdkdrive/service/v1/vehicles/",
+ type: "get",
+ apiName: "Service Vehicle - Query Vehicles"
+ },
+ GetVehicleId: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/vehicle-ids/" //Request path params of vins
+ : "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/vehicle-ids/",
+ type: "get",
+ apiName: "CDK Drive Post Service Vehicle",
+ },
+ GetVehicleById: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/" //Request path params of vehicleId
+ : "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
+ type: "get",
+ apiName: "CDK Drive Post Service Vehicle",
+ },
+ QueryCustomerByName: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/customerpost/v1/search"
+ : "https://api.fortellis.io/cdk-test/drive/customerpost/v1/search",
+ type: "get",
+ apiName: "CDK Drive Post Customer",
+ },
+ ReadCustomer: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/customerpost/v1/" //Customer ID is request param.
+ : "https://api.fortellis.io/cdk-test/drive/customerpost/v1/",
+ type: "get",
+ apiName: "CDK Drive Post Customer",
+ },
+ CreateCustomer: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/customerpost/v1/"
+ : "https://api.fortellis.io/cdk-test/drive/customerpost/v1/",
+ type: "post",
+ apiName: "CDK Drive Post Customer",
+ },
+ InsertVehicle: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/"
+ : "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
+ type: "post",
+ apiName: "CDK Drive Post Service Vehicle",
+ },
+ UpdateVehicle: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/"
+ : "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
+ type: "put",
+ apiName: "CDK Drive Post Service Vehicle",
+ },
+ GetCOA: {
+ type: "get",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ url: `https://api.fortellis.io/cdk-test/drive/chartofaccounts/v2/bulk/`,
+ waitForResult: true
+ },
+ StartWip: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/glpost/startWIP"
+ : "https://api.fortellis.io/cdk-test/drive/glpost/startWIP",
+ type: "post",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ },
+ TranBatchWip: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/glpost/transBatchWIP"
+ : "https://api.fortellis.io/cdk-test/drive/glpost/transBatchWIP",
+ type: "post",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ },
+ PostBatchWip: {
+ url: isProduction
+ ? "https://api.fortellis.io/cdk/drive/glpost/postBatchWIP"
+ : "https://api.fortellis.io/cdk-test/drive/glpost/postBatchWIP",
+ type: "post",
+ apiName: "CDK Drive Post Accounts GL WIP",
+ },
+
+};
+
+const FortellisCacheEnums = {
+ txEnvelope: "txEnvelope",
+ DMSBatchTxn: "DMSBatchTxn",
+ SubscriptionMeta: "SubscriptionMeta",
+ DepartmentId: "DepartmentId",
+ JobData: "JobData",
+ DMSVid: "DMSVid",
+ DMSVeh: "DMSVeh",
+ DMSVehCustomer: "DMSVehCustomer",
+ DMSCustList: "DMSCustList",
+ DMSCust: "DMSCust",
+ selectedCustomerId: "selectedCustomerId",
+ DMSTransHeader: "DMSTransHeader",
+ transWips: "transWips",
+ DmsBatchTxnPost: "DmsBatchTxnPost"
+};
+
+function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) {
+ // Ensure the base URL ends with a single "/"
+ url = url.replace(/\/+$/, "/");
+ const fullPath = pathParams ? `${url}${pathParams}` : url;
+ const searchParams = new URLSearchParams(requestSearchParams).toString();
+ const fullUrl = searchParams ? `${fullPath}?${searchParams}` : fullPath;
+ return fullUrl;
+}
+
+
+
+module.exports = {
+ GetAuthToken,
+ FortellisCacheEnums,
+ MakeFortellisCall,
+ FortellisActions,
+ getTransactionType,
+ defaultFortellisTTL
+};
diff --git a/server/fortellis/fortellis-logger.js b/server/fortellis/fortellis-logger.js
new file mode 100644
index 000000000..9cf296634
--- /dev/null
+++ b/server/fortellis/fortellis-logger.js
@@ -0,0 +1,9 @@
+const logger = require("../utils/logger");
+
+const CreateFortellisLogEvent = (socket, level, message, txnDetails) => {
+ //TODO: Add detaisl to track the whole transaction between Fortellis and the server.
+ logger.log("fortellis-log-event", level, socket?.user?.email, null, { wsmessage: message, txnDetails });
+ socket.emit("fortellis-log-event", { level, message, txnDetails });
+};
+
+module.exports = CreateFortellisLogEvent;
diff --git a/server/fortellis/fortellis.js b/server/fortellis/fortellis.js
new file mode 100644
index 000000000..587d6d52f
--- /dev/null
+++ b/server/fortellis/fortellis.js
@@ -0,0 +1,1465 @@
+const GraphQLClient = require("graphql-request").GraphQLClient;
+const CalculateAllocations = require("../cdk/cdk-calculate-allocations").default;
+const InstanceMgr = require("../utils/instanceMgr").default;
+const CreateFortellisLogEvent = require("./fortellis-logger");
+const queries = require("../graphql-client/queries");
+const {
+ MakeFortellisCall,
+ FortellisActions,
+ getTransactionType,
+ defaultFortellisTTL,
+ FortellisCacheEnums
+} = require("./fortellis-helpers");
+const _ = require("lodash");
+const moment = require("moment-timezone");
+
+const replaceSpecialRegex = /[^a-zA-Z0-9 .,\n #]+/g;
+
+async function FortellisJobExport({
+ socket,
+ redisHelpers,
+ ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom },
+ txEnvelope,
+ jobid
+}) {
+ const {
+ // setSessionData,
+ // getSessionData,
+ // addUserSocketMapping,
+ // removeUserSocketMapping,
+ // refreshUserSocketTTL,
+ // getUserSocketMappingByBodyshop,
+ setSessionTransactionData,
+ // getSessionTransactionData,
+ // clearSessionTransactionData
+ } = redisHelpers;
+ try {
+ CreateFortellisLogEvent(socket, "debug", `Received Job export request for id ${jobid}`);
+ await setSessionTransactionData(
+ socket.id,
+ getTransactionType(jobid),
+ FortellisCacheEnums.txEnvelope,
+ txEnvelope,
+ defaultFortellisTTL
+ );
+
+ const JobData = await QueryJobData({ socket, jobid }); //TODO: Need to remove unnecessary stuff here to reduce the payload.
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.JobData, JobData, defaultFortellisTTL);
+
+ CreateFortellisLogEvent(socket, "DEBUG", `{1} Begin Calculate DMS Vehicle ID using VIN: ${JobData.v_vin}`);
+ const DMSVid = (await CalculateDmsVid({ socket, JobData, redisHelpers }))[0];
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSVid, DMSVid, defaultFortellisTTL);
+
+ let DMSVehCustomer;
+ if (!DMSVid.newId) {
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{2.1} Querying the Vehicle using the DMSVid: ${DMSVid.vehiclesVehId}`
+ );
+ const DMSVeh = await QueryDmsVehicleById({ socket, redisHelpers, JobData, DMSVid });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSVeh, DMSVeh, defaultFortellisTTL);
+
+ const DMSVehCustomerFromVehicle =
+ DMSVeh && DMSVeh.owners && DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
+
+ if (DMSVehCustomerFromVehicle && DMSVehCustomerFromVehicle.id && DMSVehCustomerFromVehicle.id.value) {
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{2.2} Querying the Customer using the ID from DMSVeh: ${DMSVehCustomerFromVehicle.id.value}`
+ );
+ DMSVehCustomer = await QueryDmsCustomerById({ socket, redisHelpers, JobData, CustomerId: DMSVehCustomerFromVehicle.id.value });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSVehCustomer, DMSVehCustomer, defaultFortellisTTL);
+ }
+ }
+ CreateFortellisLogEvent(socket, "DEBUG", `{2.3} Querying the Customer using the name.`);
+
+ const DMSCustList = await QueryDmsCustomerByName({ socket, redisHelpers, JobData });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSCustList, DMSCustList, defaultFortellisTTL);
+
+
+ socket.emit("fortellis-select-customer", [
+ ...(DMSVehCustomer ? [{ ...DMSVehCustomer, vinOwner: true }] : []),
+ ...DMSCustList
+ ]);
+
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in FortellisJobExport - ${error}`, {
+ error: error.message,
+ stack: error.stack
+ });
+ }
+}
+
+
+
+async function FortellisSelectedCustomer({ socket, redisHelpers, ioHelpers, selectedCustomerId, jobid }) {
+
+ const {
+ // setSessionData,
+ // getSessionData,
+ // addUserSocketMapping,
+ // removeUserSocketMapping,
+ // refreshUserSocketTTL,
+ // getUserSocketMappingByBodyshop,
+ setSessionTransactionData,
+ getSessionTransactionData,
+ //clearSessionTransactionData
+ } = redisHelpers;
+
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.selectedCustomerId, selectedCustomerId, defaultFortellisTTL);
+ const JobData = await getSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.JobData);
+ const txEnvelope = await getSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.txEnvelope);
+ const DMSVid = await redisHelpers.getSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.DMSVid);
+ try {
+
+
+ let DMSCust;
+ if (selectedCustomerId) {
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{3.1} Querying the Customer using Customer ID: ${selectedCustomerId}`
+ );
+ DMSCust = await QueryDmsCustomerById({ socket, redisHelpers, JobData, CustomerId: selectedCustomerId }); //TODO: Optimize here - if selected ID, we already have the customer information. Prevent an extra call to Fortellis.
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSCust, DMSCust, defaultFortellisTTL);
+ } else {
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{3.2} Creating new customer.`
+ );
+ const DMSCustomerInsertResponse = await InsertDmsCustomer({ socket, redisHelpers, JobData });
+ DMSCust = { customerId: DMSCustomerInsertResponse.data }
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSCust, DMSCust, defaultFortellisTTL);
+ }
+
+ let DMSVeh;
+ if (DMSVid.newId) {
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{4.1} Inserting new vehicle with ID: ID ${DMSVid.vehiclesVehId}`
+ );
+ DMSVeh = await InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMSVid, DMSCust });
+ } else {
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{4.2} Querying Existing Vehicle using ID ${DMSVid.vehiclesVehId}`
+ );
+ DMSVeh = await QueryDmsVehicleById({ socket, redisHelpers, JobData, DMSVid });
+
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{4.3} Updating Existing Vehicle to associate to owner.`
+ );
+ DMSVeh = await UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust, selectedCustomerId, txEnvelope });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSVeh, DMSVeh, defaultFortellisTTL);//TODO: This should be immutable probably.F
+
+ }
+
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{5} Creating Transaction header with Dms Start WIP`
+ );
+ const DMSTransHeader = await InsertDmsStartWip({ socket, redisHelpers, JobData });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSTransHeader, DMSTransHeader, defaultFortellisTTL);
+
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{5.1} Creating Transaction with ID ${DMSTransHeader.transID}`
+ );
+
+ const DMSBatchTxn = await InsertDmsBatchWip({ socket, redisHelpers, JobData });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSBatchTxn, DMSBatchTxn, defaultFortellisTTL);
+
+
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{6} Attempting to post Transaction with ID ${DMSTransHeader.transID}`
+ );
+
+ const DmsBatchTxnPost = await PostDmsBatchWip({ socket, redisHelpers, JobData });
+ await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DmsBatchTxnPost, DmsBatchTxnPost, defaultFortellisTTL);
+
+ if (DmsBatchTxnPost.rtnCode === "0") { //TODO: Validate this is a string and not #
+ //something
+ CreateFortellisLogEvent(socket, "DEBUG", `{6} Successfully posted sransaction to DMS.`);
+
+ await MarkJobExported({ socket, jobid: JobData.id });
+
+ CreateFortellisLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`);
+ socket.DMSVehHistory = await InsertServiceVehicleHistory(socket);
+ socket.emit("export-success", JobData.id);
+ } else {
+ //Get the error code
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `{6.1} Getting errors for Transaction ID ${DMSTransHeader.transID}`
+ );
+ // socket.DmsError = await QueryDmsErrWip(socket);
+ // //Delete the transaction
+ // CdkBase.createLogEvent(socket, "DEBUG", `{6.2} Deleting Transaction ID ${socket.DMSTransHeader.transID}`);
+ // socket.DmsBatchTxnPost = await DeleteDmsWip(socket);
+
+ // socket.DmsError.errMsg
+ // .split("|")
+ // .map(
+ // (e) =>
+ // e !== null &&
+ // e !== "" &&
+ // CdkBase.createLogEvent(socket, "ERROR", `Error(s) encountered in posting transaction. ${e}`)
+ // );
+ }
+ } catch (error) {
+ // CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
+ CreateFortellisLogEvent(socket, "ERROR", `Error in FortellisSelectedCustomer - ${error}`, {
+ error: error.message,
+ stack: error.stack
+ });
+ await InsertFailedExportLog({ socket, JobData, error });
+ } finally {
+ //Ensure we always insert logEvents
+ //GQL to insert logevents.
+
+ //CdkBase.createLogEvent(socket, "DEBUG", `Capturing log events to database.`);
+ }
+}
+
+exports.FortellisSelectedCustomer = FortellisSelectedCustomer;
+
+async function QueryJobData({ socket, jobid }) {
+ const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
+ const result = await client
+ .setHeaders({ Authorization: `Bearer ${socket.handshake?.auth?.token}` })
+ .request(queries.QUERY_JOBS_FOR_CDK_EXPORT, { id: jobid });
+ return result.jobs_by_pk;
+}
+
+async function CalculateDmsVid({ socket, JobData, redisHelpers }) {
+ try {
+ const result = await MakeFortellisCall({
+ ...FortellisActions.GetVehicleId,
+ requestPathParams: JobData.v_vin,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {},
+
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in CalculateDmsVid - ${error}`, { request: error.request });
+ }
+}
+
+async function QueryDmsVehicleById({ socket, redisHelpers, JobData, DMSVid }) {
+ try {
+ const result = await MakeFortellisCall({
+ ...FortellisActions.GetVehicleById,
+ requestPathParams: DMSVid.vehiclesVehId,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {},
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in QueryDmsVehicleById - ${error}`, { request: error.request });
+ }
+}
+
+async function QueryDmsCustomerById({ socket, redisHelpers, JobData, CustomerId }) {
+ try {
+ const result = await MakeFortellisCall({
+ ...FortellisActions.ReadCustomer,
+ requestPathParams: CustomerId,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {},
+
+ });
+ return result.data;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in QueryDmsCustomerById - ${error}`, { request: error.request });
+ }
+}
+
+async function QueryDmsCustomerByName({ socket, redisHelpers, JobData }) {
+ const ownerName =
+ JobData.ownr_co_nm && JobData.ownr_co_nm.trim() !== ""
+ ? [["lastName", JobData.ownr_co_nm.replace(replaceSpecialRegex, "")]]
+ : [["firstName", JobData.ownr_fn.replace(replaceSpecialRegex, "")], ["lastName", JobData.ownr_ln.replace(replaceSpecialRegex, "")]];
+
+ CreateFortellisLogEvent(
+ socket,
+ "DEBUG",
+ `Begin query DMS Customer by Name using ${JSON.stringify(ownerName)}`
+ );
+
+ try {
+ const result = await MakeFortellisCall({
+ ...FortellisActions.QueryCustomerByName,
+ requestSearchParams: ownerName,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {},
+
+ });
+ return result.data;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in QueryDmsCustomerByName - ${error}`, { request: error.request });
+ }
+}
+
+async function InsertDmsCustomer({ socket, redisHelpers, JobData }) {
+ try {
+ const result = await MakeFortellisCall({
+ ...FortellisActions.CreateCustomer,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {
+ "customerType": "INDIVIDUAL",
+ "customerName": {
+ //"suffix": "Mr.",
+ "firstName": JobData.ownr_fn && JobData.ownr_fn.replace(replaceSpecialRegex, "").toUpperCase(),
+ //"middleName": "",
+ "lastName": JobData.ownr_ln && JobData.ownr_ln.replace(replaceSpecialRegex, "").toUpperCase(),
+ //"title": "",
+ //"nickName": ""
+ },
+ "companyName": JobData.ownr_co_nm && JobData.ownr_co_nm.replace(replaceSpecialRegex, "").toUpperCase(),
+ "postalAddress": {
+ "addressLine1": JobData.ownr_addr1?.replace(replaceSpecialRegex, "").trim(),
+ "addressLine2": JobData.ownr_addr2?.replace(replaceSpecialRegex, "").trim(),
+ "city": JobData.ownr_city?.replace(replaceSpecialRegex, "").trim(),
+ "state": JobData.ownr_state?.replace(replaceSpecialRegex, "").trim(),
+ "postalCode": InstanceMgr({
+ imex:
+ JobData.ownr_zip &&
+ JobData.ownr_zip
+ .toUpperCase()
+ .replace(/\W/g, "")
+ .replace(/(...)/, "$1 "),
+ rome: JobData.ownr_zip
+ }),
+ //"county": JobData.ownr_county?.trim(),
+ "country": JobData.ownr_ctry?.replace(replaceSpecialRegex, "").trim(),
+ "province": JobData.ownr_st?.replace(replaceSpecialRegex, "").trim(),
+ //"territory": ""
+ },
+ // "birthDate": {
+ // "day": "15",
+ // "month": "07",
+ // "year": "1979"
+ // },
+ //"gender": "M",
+ //"language": "English",
+ "contactMethods": {
+ "phones": [
+ {
+ //"uuid": "",
+ "number": JobData.ownr_ph1?.replace(replaceSpecialRegex, ""),
+ "type": "HOME",
+ // "doNotCallIndicator": true,
+ // "doNotCallIndicatorDate": `null,
+ // "doNotCallRegistrySource": "",
+ // "isOnDoNotCallRegistry": false,
+ // "isPrimary": false,
+ // "isPreferred": false,
+ // "isTextMessageAllowed": false,
+ // "textMessageCarrier": "",
+ // "optInDate": null,
+ // "optInRequestedDate": null,
+ // "preferredDay": "",
+ // "preferredTime": ""
+ },
+ // {
+ // "uuid": "",
+ // "number": "6666666666",
+ // "type": "MOBILE",
+ // "doNotCallIndicator": true,
+ // "doNotCallIndicatorDate": null,
+ // "doNotCallRegistrySource": "",
+ // "isOnDoNotCallRegistry": false,
+ // "isPrimary": true,
+ // "isPreferred": true,
+ // "isTextMessageAllowed": false,
+ // "textMessageCarrier": "",
+ // "optInDate": null,
+ // "optInRequestedDate": null,
+ // "preferredDay": "",
+ // "preferredTime": ""
+ // }
+ ],
+ "emailAddresses": [
+
+ ...!_.isEmpty(JobData.ownr_ea) ?
+ [{
+ //"uuid": "",
+ "address": JobData.ownr_ea,
+ "type": "PERSONAL",
+ // "doNotEmailSource": "",
+ // "doNotEmail": false,
+ // "isPreferred": true,
+ // "transactionEmailNotificationOptIn": false,
+ // "optInRequestDate": null,
+ // "optInDate": null
+ }] : [],
+ // {
+ // "uuid": "",
+ // "address": "jilldoe@test.com",
+ // "type": "WORK",
+ // "doNotEmailSource": "",
+ // "doNotEmail": false,
+ // "isPreferred": false,
+ // "transactionEmailNotificationOptIn": false,
+ // "optInRequestDate": null,
+ // "optInDate": null
+ // }
+ ]
+ },
+ // // "doNotContact": false,
+ // // "optOutDate": "",
+ // // "optOutTime": "",
+ // // "optOutFlag": false,
+ // // "isDeleteDataFlag": false,
+ // // "deleteDataDate": "",
+ // // "deleteDataTime": "",
+ // // "blockMailFlag": true,
+ // // "dateAdded": "",
+ // // "employer": "employer",
+ // "insurance": {
+ // "policy": {
+ // "effectiveDate": "2022-01-01",
+ // "expirationDate": "2023-01-01",
+ // "number": "12345",
+ // "verifiedBy": "Agent",
+ // "verifiedDate": "2023-01-01",
+ // "insPolicyCollisionDed": "",
+ // "insPolicyComprehensiveDed": "",
+ // "insPolicyFireTheftDed": ""
+ // },
+ // "insuranceAgency": {
+ // "agencyName": "InsAgency",
+ // "agentName": "agent",
+ // "phoneNumber": "9999999999",
+ // "postalAddress": {
+ // "addressLine1": "999 Main St",
+ // "addressLine2": "Suite 999",
+ // "city": "Austin",
+ // "state": "TX",
+ // "postalCode": "78750",
+ // "county": "Travis",
+ // "country": "USA"
+ // }
+ // },
+ // "insuranceCompany": {
+ // "name": "InsCompany",
+ // "phoneNumber": "8888888888",
+ // "postalAddress": {
+ // "addressLine1": "888 Main St",
+ // "addressLine2": "Suite 888",
+ // "city": "Austin",
+ // "state": "TX",
+ // "postalCode": "78750",
+ // "county": "Travis",
+ // "country": "USA"
+ // }
+ // }
+ // },
+ // "specialInstructions": [
+ // {
+ // "lineNuber": "1",
+ // "specialInstruction": "specialInstruction1"
+ // },
+ // {
+ // "lineNuber": "2",
+ // "specialInstruction": "specialInstruction2"
+ // }
+ // ],
+ // "groupCode": "PT",
+ // "priceCode": "5",
+ // "roPriceCode": "5",
+ // "taxCode": "3145",
+ // "dealerLoyaltyIndicator": "PN612345",
+ // "delCdeServiceNames": "99",
+ // "deleteCode": "9999",
+ // "fleetFlag": "1",
+ // "dealerFields": [
+ // {
+ // "lineNumber": null,
+ // "dealerField": "Custom dealer field value 1"
+ // },
+ // {
+ // "lineNumber": null,
+ // "dealerField": "Custom dealer field value 2"
+ // },
+ // {
+ // "lineNumber": null,
+ // "dealerField": "Custom dealer field value 3"
+ // }
+ // ]
+ },
+
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in InsertDmsCustomer - ${error}`, { request: error.request });
+ }
+
+ // try {
+ // const soapClientCustomerInsertUpdate = await soap.createClientAsync(CdkWsdl.CustomerInsertUpdate);
+ // const soapResponseCustomerInsertUpdate = await soapClientCustomerInsertUpdate.insertAsync(
+ // {
+ // arg0: CDK_CREDENTIALS,
+ // arg1: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+ // arg2: { userId: null },
+ // arg3: {
+ // //Copied the required fields from the other integration.
+ // //TODO: Verify whether we need to bring more information in.
+ // id: { value: newCustomerNumber },
+ // address: {
+ // addressLine: socket.JobData.ownr_addr1 && socket.JobData.ownr_addr1.replace(replaceSpecialRegex, ""),
+ // city: socket.JobData.ownr_city && socket.JobData.ownr_city.replace(replaceSpecialRegex, ""),
+ // country: socket.JobData.ownr_ctry && socket.JobData.ownr_ctry.replace(replaceSpecialRegex, ""),
+ // postalCode: InstanceMgr({
+ // imex:
+ // socket.JobData.ownr_zip &&
+ // socket.JobData.ownr_zip //TODO Need to remove for US Based customers.
+ // .toUpperCase()
+ // .replace(/\W/g, "")
+ // .replace(/(...)/, "$1 "),
+ // rome: socket.JobData.ownr_zip
+ // }),
+ // stateOrProvince: socket.JobData.ownr_st && socket.JobData.ownr_st.replace(replaceSpecialRegex, "")
+ // },
+ // contactInfo: {
+ // mainTelephoneNumber: {
+ // main: true,
+ // value: socket.JobData.ownr_ph1 && socket.JobData.ownr_ph1.replace(replaceSpecialRegex, "")
+ // },
+ // email: {
+ // desc: socket.JobData.ownr_ea ? "Other" : "CustomerDeclined",
+ // value: socket.JobData.ownr_ea ? socket.JobData.ownr_ea : null
+ // }
+ // },
+ // demographics: null,
+ // name1: {
+ // companyName:
+ // socket.JobData.ownr_co_nm && socket.JobData.ownr_co_nm.replace(replaceSpecialRegex, "").toUpperCase(),
+
+ // firstName: socket.JobData.ownr_fn && socket.JobData.ownr_fn.replace(replaceSpecialRegex, "").toUpperCase(),
+ // fullname: null,
+ // lastName: socket.JobData.ownr_ln && socket.JobData.ownr_ln.replace(replaceSpecialRegex, "").toUpperCase(),
+ // middleName: null,
+ // nameType:
+ // socket.JobData.ownr_co_nm && String(socket.JobData.ownr_co_nm).trim() !== "" ? "Business" : "Person",
+ // suffix: null,
+ // title: null
+ // }
+ // }
+ // },
+
+ // {}
+ // );
+
+ // const [result, rawResponse, , rawRequest] = soapResponseCustomerInsertUpdate;
+ // CdkBase.createXmlEvent(socket, rawRequest, `soapClientCustomerInsertUpdate.insertAsync request.`);
+
+ // CdkBase.createXmlEvent(socket, rawResponse, `soapClientCustomerInsertUpdate.insertAsync response.`);
+ // CdkBase.createLogEvent(
+ // socket,
+ // "SILLY",
+ // `soapClientCustomerInsertUpdate.insertAsync Result ${JSON.stringify(result, null, 2)}`
+ // );
+ // CheckCdkResponseForError(socket, soapResponseCustomerInsertUpdate);
+ // const customer = result && result.return && result.return.customerParty;
+ // return customer;
+ // } catch (error) {
+ // CdkBase.createXmlEvent(socket, error.request, `soapClientCustomerInsertUpdate.insertAsync request.`, true);
+
+ // CdkBase.createXmlEvent(
+ // socket,
+ // error.response && error.response.data,
+ // `soapClientCustomerInsertUpdate.insertAsync response.`,
+ // true
+ // );
+ // CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsCustomer - ${error}`);
+ // throw new Error(error);
+ // }
+}
+
+async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMSVid, DMSCust }) {
+ try {
+
+ const result = await MakeFortellisCall({
+ ...FortellisActions.InsertVehicle,
+ requestSearchParams: {},
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {
+ "dealer": {
+ "company": JobData.bodyshop.cdk_configuration.srcco || "77",
+ // "dealNumber": "",
+ // "dealerAssignedNumber": "82268",
+ // "dealerDefined1": "2WDSP",
+ // "dealerDefined2": "33732.71",
+ // "dealerDefined3": "",
+ // "dealerDefined4": "G0901",
+ // "dealerDefined5": "",
+ // "dealerDefined6": "",
+ // "dealerDefined7": "",
+ // "dealerDefined8": "",
+ // "dealerNumber": "",
+ ...(txEnvelope.inservicedate && {
+ inServiceDate:
+ txEnvelope.dms_unsold === true
+ ? ""
+ : moment(txEnvelope.inservicedate)
+ //.tz(JobData.bodyshop.timezone)
+ .startOf("day")
+ .toISOString()
+ }),
+ //"lastServiceDate": "2011-11-23",
+ "vehicleId": DMSVid.vehiclesVehId,
+ // "vehicleLocation": "",
+ // "vehicleSoldDate": "2021-04-06",
+ // "wholesaleVehicleInd": false
+ },
+ // "manufacturer": {
+ // "name": "",
+ // "plant": "",
+ // "productionNumber": "PZPKM6",
+ // "vehicleProductionDate": "2020-04-06"
+ // },
+ // "invoice": {
+ // "entryDate": "2012-01-19",
+ // "freight": {
+ // "freightInCharge": 995.95,
+ // "freightOutCharge": 95.95,
+ // "freightTaxCharge": 5.95
+ // },
+ // "vehicleAcquisitionDate": "2012-01-18",
+ // "vehicleOrderDate": "2012-01-12",
+ // "vehicleOrderNumber": "",
+ // "vehicleOrderPriority": "",
+ // "vehicleOrderType": "TRE RETAIL - STOCK"
+ // },
+ "vehicle": {
+ // "axleCode": "GU6/3.42 REAR AXLE RATIO",
+ // "axleCount": 2,
+ // "bodyStyle": "PU",
+ // "brakeSystem": "",
+ // "cabType": "",
+ // "certifiedPreownedInd": false,
+ // "certifiedPreownedNumber": "",
+ // "chassis": "",
+ // "color": "",
+ // "dealerBodyStyle": "",
+ deliveryDate:
+ txEnvelope.dms_unsold === true
+ ? ""
+ : moment()
+ // .tz(JobData.bodyshop.timezone)
+ .format("YYYY-MM-DD"),
+ // "deliveryMileage": 4,
+ // "doorsQuantity": 4,
+ // "engineNumber": "",
+ // "engineType": "LMG/VORTEC 5.3L VVT V8 SFI FLEXFUEL",
+ // "exteriorColor": "",
+ // "fleetVehicleId": "",
+ // "frontTireCode": "",
+ // "gmRPOCode": "",
+ // "ignitionKeyNumber": "",
+ // "interiorColor": "EBONY",
+ licensePlateNo:
+ JobData.plate_no === null
+ ? null
+ : String(JobData.plate_no).replace(/([^\w]|_)/g, "").length === 0
+ ? null
+ : String(JobData.plate_no)
+ .replace(/([^\w]|_)/g, "")
+ .toUpperCase(),
+ make: txEnvelope.dms_make,
+ // "model": "CC10753",
+ modelAbrev: txEnvelope.dms_model,
+ // "modelDescription": "SILVERADO 1500 2WD EXT CAB LT",
+ // "modelType": "T",
+ modelYear: JobData.v_model_yr,
+ // "numberOfEngineCylinders": 4,
+ odometerStatus: txEnvelope.kmout,
+ // "options": [
+ // {
+ // "optionCategory": "SS",
+ // "optionCode": "A95",
+ // "optionCost": 875.6,
+ // "optionDescription": "FRONT BUCKET SEATS INCLUDING: PWR SEAT ADJUST DRIVER 6-WAY",
+ // "optionPrices": [
+ // {
+ // "optionPricingType": "RETAIL",
+ // "price": 995
+ // },
+ // {
+ // "optionPricingType": "INVOICE",
+ // "price": 875.6
+ // }
+ // ]
+ // },
+ // {
+ // "optionCategory": "E",
+ // "optionCode": "LMG",
+ // "optionCost": 0,
+ // "optionDescription": "VORTEC 5.3L V8 SFI ENGINE W/ACTIVE FUEL MANAGEMENT",
+ // "optionPrices": [
+ // {
+ // "optionPricingType": "RETAIL",
+ // "price": 0
+ // },
+ // {
+ // "optionPricingType": "INVOICE",
+ // "price": 0
+ // }
+ // ]
+ // }
+ // ],
+ // "rearTireCode": "",
+ // "restraintSystem": "",
+ saleClassValue: "MISC",
+ // "sourceCodeValue": "",
+ // "sourceDescription": "",
+ // "standardEquipment": "",
+ // "stickerNumber": "",
+ // "transmissionType": "A",
+ // "transmissionNo": "MYC/ELECTRONIC 6-SPEED AUTOMATIC W/OD",
+ // "trimCode": "",
+ // "vehicleNote": "",
+ // "vehiclePrices": [
+ // {
+ // "price": 35894,
+ // "vehiclePricingType": "SELLINGPRICE"
+ // },
+ // {
+ // "price": 33749.87,
+ // "vehiclePricingType": "INVOICE"
+ // },
+ // {
+ // "price": 36472,
+ // "vehiclePricingType": "RETAIL"
+ // },
+ // {
+ // "price": 28276.66,
+ // "vehiclePricingType": "BASEINVOICE"
+ // },
+ // {
+ // "price": 30405,
+ // "vehiclePricingType": "BASERETAIL"
+ // },
+ // {
+ // "price": 33749.87,
+ // "vehiclePricingType": "COMMISSIONPRICE"
+ // },
+ // {
+ // "price": 32702.9,
+ // "vehiclePricingType": "DRAFTAMOUNT"
+ // }
+ // ],
+ // "vehicleStatus": "G",
+ // "vehicleStock": "82268",
+ // "vehicleWeight": "6800",
+ vin: JobData.v_vin
+ // "warrantyExpDate": "2015-01-12",
+ // "wheelbase": ""
+ },
+ "owners": [
+ {
+ "id": {
+ assigningPartyId: "CURRENT",
+ value: DMSCust.customerId
+ },
+
+ }
+ ],
+ //"inventoryAccount": "237"
+ },
+
+ });
+ return result.data;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in InsertDmsVehicle - ${error}`, { request: error.request });
+ }
+}
+
+async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust, selectedCustomerId, txEnvelope }) {
+ try {
+
+ let ids = [];
+
+ //if it's a generic customer, don't update the vehicle owners.
+
+ if (selectedCustomerId === JobData.bodyshop.cdk_configuration.generic_customer_number) {
+ ids = DMSVeh && DMSVeh.owners && DMSVeh.owners;
+ } else {
+ const existingOwnerinVeh =
+ DMSVeh &&
+ DMSVeh.owners &&
+ DMSVeh.owners.find((o) => o.id.value === DMSCust.customerId);
+
+ if (existingOwnerinVeh) {
+ ids = DMSVeh.owners.map((o) => {
+ return {
+ id: {
+ assigningPartyId: o.id.value === DMSCust.customerId ? "CURRENT" : "PREVIOUS",
+ value: o.id.value
+ }
+ };
+ });
+ } else {
+ const oldOwner =
+ DMSVeh &&
+ DMSVeh.owners &&
+ DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
+
+ ids = [
+ {
+ id: {
+ assigningPartyId: "CURRENT",
+ value: DMSCust.customerId
+ }
+ },
+ ...(oldOwner
+ ? [
+ {
+ id: {
+ assigningPartyId: "PREVIOUS",
+ value: oldOwner.id
+ }
+ }
+ ]
+ : [])
+ ];
+ }
+ }
+
+ const DMSVehToSend = _.cloneDeep(DMSVeh);
+ //Remove unsupported fields on the post API.
+ delete DMSVehToSend.dealer.lastActivityDate;
+ delete DMSVehToSend.manufacturer;
+ delete DMSVehToSend.invoice;
+ delete DMSVehToSend.inventoryAccount;
+
+
+ const result = await MakeFortellisCall({
+ ...FortellisActions.UpdateVehicle,
+ requestSearchParams: {},
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {
+ ...DMSVehToSend,
+ dealer: {
+ ...DMSVehToSend.dealer, //TODO: Check why company is blank on a queried record.
+ company: "77",
+ ...((txEnvelope.inservicedate || DMSVehToSend.dealer.inServiceDate) && {
+ inServiceDate:
+ txEnvelope.dms_unsold === true
+ ? ""
+ : moment(DMSVehToSend.dealer.inServiceDate || txEnvelope.inservicedate)
+ // .tz(JobData.bodyshop.timezone)
+ .toISOString()
+ })
+ },
+ vehicle: {
+ ...DMSVehToSend.vehicle,
+ ...(txEnvelope.dms_model_override
+ ? {
+ make: txEnvelope.dms_make,
+ modelAbrev: txEnvelope.dms_model
+ }
+ : {}),
+ deliveryDate:
+ txEnvelope.dms_unsold === true
+ ? ""
+ : moment(DMSVehToSend.vehicle.deliveryDate)
+ //.tz(JobData.bodyshop.timezone)
+ .toISOString()
+ },
+ owners: ids
+ },
+
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in UpdateDmsVehicle - ${error}`, { request: error.request });
+ }
+
+ //
+
+ // try {
+ // const soapClientVehicleInsertUpdate = await soap.createClientAsync(CdkWsdl.VehicleInsertUpdate);
+
+ // let ids = [];
+
+ // //if it's a generic customer, don't update the vehicle owners.
+
+ // if (socket.selectedCustomerId === socket.JobData.bodyshop.cdk_configuration.generic_customer_number) {
+ // ids = socket.DMSVeh && socket.DMSVeh.owners && socket.DMSVeh.owners;
+ // } else {
+ // const existingOwnerinVeh =
+ // socket.DMSVeh &&
+ // socket.DMSVeh.owners &&
+ // socket.DMSVeh.owners.find((o) => o.id.value === socket.DMSCust.id.value);
+
+ // if (existingOwnerinVeh) {
+ // ids = socket.DMSVeh.owners.map((o) => {
+ // return {
+ // id: {
+ // assigningPartyId: o.id.value === socket.DMSCust.id.value ? "CURRENT" : "PREVIOUS",
+ // value: o.id.value
+ // }
+ // };
+ // });
+ // } else {
+ // const oldOwner =
+ // socket.DMSVeh &&
+ // socket.DMSVeh.owners &&
+ // socket.DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
+
+ // ids = [
+ // {
+ // id: {
+ // assigningPartyId: "CURRENT",
+ // value: socket.DMSCust.id.value
+ // }
+ // },
+ // ...(oldOwner
+ // ? [
+ // {
+ // id: {
+ // assigningPartyId: "PREVIOUS",
+ // value: oldOwner.id.value
+ // }
+ // }
+ // ]
+ // : [])
+ // ];
+ // }
+ // }
+
+ // const soapResponseVehicleInsertUpdate = await soapClientVehicleInsertUpdate.updateAsync({
+ // arg0: CDK_CREDENTIALS,
+ // arg1: { id: socket.JobData.bodyshop.cdk_dealerid },
+ // arg2: {
+ // ...socket.DMSVeh,
+ // dealer: {
+ // ...socket.DMSVeh.dealer,
+ // ...((socket.txEnvelope.inservicedate || socket.DMSVeh.dealer.inServiceDate) && {
+ // inServiceDate:
+ // socket.txEnvelope.dms_unsold === true
+ // ? ""
+ // : moment(socket.DMSVeh.dealer.inServiceDate || socket.txEnvelope.inservicedate)
+ // // .tz(socket.JobData.bodyshop.timezone)
+ // .toISOString()
+ // })
+ // },
+ // vehicle: {
+ // ...socket.DMSVeh.vehicle,
+ // ...(socket.txEnvelope.dms_model_override
+ // ? {
+ // make: socket.txEnvelope.dms_make,
+ // modelAbrev: socket.txEnvelope.dms_model
+ // }
+ // : {}),
+ // deliveryDate:
+ // socket.txEnvelope.dms_unsold === true
+ // ? ""
+ // : moment(socket.DMSVeh.vehicle.deliveryDate)
+ // //.tz(socket.JobData.bodyshop.timezone)
+ // .toISOString()
+ // },
+ // owners: ids
+ // },
+ // arg3: "VEHICLES"
+ // });
+ // const [result, rawResponse, , rawRequest] = soapResponseVehicleInsertUpdate;
+
+ // CdkBase.createXmlEvent(socket, rawRequest, `soapClientVehicleInsertUpdate.updateAsync request.`);
+
+ // CdkBase.createLogEvent(
+ // socket,
+ // "DEBUG",
+ // `soapClientVehicleInsertUpdate.updateAsync Result ${JSON.stringify(result, null, 2)}`
+ // );
+ // CdkBase.createXmlEvent(socket, rawResponse, `soapClientVehicleInsertUpdate.updateAsync response.`);
+ // CheckCdkResponseForError(socket, soapResponseVehicleInsertUpdate);
+ // const VehicleFromDMS = result && result.return && result.return.vehicle;
+ // return VehicleFromDMS;
+ // } catch (error) {
+ // CdkBase.createLogEvent(socket, "ERROR", `Error in UpdateDmsVehicle - ${error}`);
+ // throw new Error(error);
+ // }
+}
+
+// async function InsertServiceVehicleHistory(socket) {
+// try {
+// const soapClientServiceHistoryInsert = await soap.createClientAsync(CdkWsdl.ServiceHistoryInsert);
+
+// const soapResponseServiceHistoryInsert = await soapClientServiceHistoryInsert.serviceHistoryHeaderInsertAsync({
+// authToken: CDK_CREDENTIALS,
+// dealerId: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+// serviceHistoryHeader: {
+// vehID: socket.DMSVid.vehiclesVehId,
+// roNumber: socket.JobData.ro_number.match(/\d+/g),
+// mileage: socket.txEnvelope.kmout,
+// openDate: moment(socket.JobData.actual_in).tz(socket.JobData.bodyshop.timezone).format("YYYY-MM-DD"),
+// openTime: moment(socket.JobData.actual_in).tz(socket.JobData.bodyshop.timezone).format("HH:mm:ss"),
+// closeDate: moment(socket.JobData.invoice_date).tz(socket.JobData.bodyshop.timezone).format("YYYY-MM-DD"),
+// closeTime: moment(socket.JobData.invoice_date).tz(socket.JobData.bodyshop.timezone).format("HH:mm:ss"),
+// comments: socket.txEnvelope.story,
+// cashierID: socket.JobData.bodyshop.cdk_configuration.cashierid
+// }
+// });
+
+// const [result, rawResponse, , rawRequest] = soapResponseServiceHistoryInsert;
+
+// CdkBase.createXmlEvent(socket, rawRequest, `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert request.`);
+
+// CdkBase.createLogEvent(
+// socket,
+// "SILLY",
+// `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert Result ${JSON.stringify(result, null, 2)}`
+// );
+// CdkBase.createXmlEvent(socket, rawResponse, `soapClientServiceHistoryInsert.serviceHistoryHeaderInsert response.`);
+// CheckCdkResponseForError(socket, soapResponseServiceHistoryInsert);
+// return result && result.return;
+// } catch (error) {
+// CdkBase.createLogEvent(socket, "ERROR", `Error in InsertServiceVehicleHistory - ${error}`);
+// throw new Error(error);
+// }
+// }
+
+// async function InsertDmsStartWip(socket) {
+// try {
+// const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate);
+
+// const soapResponseAccountingGLInsertUpdate = await soapClientAccountingGLInsertUpdate.doStartWIPAsync({
+// arg0: CDK_CREDENTIALS,
+// arg1: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+// arg2: {
+// acctgDate: moment().tz(socket.JobData.bodyshop.timezone).format("YYYY-MM-DD"),
+// //socket.JobData.invoice_date
+// desc: socket.txEnvelope.story && socket.txEnvelope.story.replace(replaceSpecialRegex, ""),
+// docType: 10 || 7, //Need to check what this usually would be? Apparently it is almost always 10 or 7.
+// //1 Cash Receipt , 2 Check, 3 Journal Voucher, 4 Parts invoice, 5 Payable Invoice, 6 Recurring Entry, 7 Repair Order Invoice, 8 Vehicle Purchase Invoice, 9 Vehicle Sale Invoice, 10 Other, 11 Payroll, 12 Finance Charge, 13 FMLR Invoice, 14 Parts Credit Memo, 15 Manufacturer Document, 16 FMLR Credit Memo
+// m13Flag: 0,
+// refer: socket.JobData.ro_number,
+// srcCo: socket.JobData.bodyshop.cdk_configuration.srcco,
+// srcJrnl: socket.txEnvelope.journal,
+// userID: socket.JobData.bodyshop.cdk_configuration.cashierid //Where is this coming from?
+// //userName: "IMEX",
+// }
+// });
+
+// const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
+
+// CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doStartWIPAsync request.`);
+
+// CdkBase.createLogEvent(
+// socket,
+// "SILLY",
+// `soapClientAccountingGLInsertUpdate.doStartWIPAsync Result ${JSON.stringify(result, null, 2)}`
+// );
+// CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doStartWIPAsync response.`);
+// CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
+// const TransactionHeader = result && result.return;
+// return TransactionHeader;
+// } catch (error) {
+// CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsStartWip - ${error}`);
+// throw new Error(error);
+// }
+// }
+
+
+async function InsertDmsStartWip({ socket, redisHelpers, JobData }) {
+ try {
+ const txEnvelope = await redisHelpers.getSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.txEnvelope);
+
+ const result = await MakeFortellisCall({
+ ...FortellisActions.StartWip,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {
+ "acctgDate": moment().tz(JobData.bodyshop.timezone).format("YYYY-MM-DD"),
+ "desc": txEnvelope.story && txEnvelope.story.replace(replaceSpecialRegex, ""),
+ "docType": "10",
+ "m13Flag": "0",
+ "refer": JobData.ro_number,
+ // "rtnCode": "",
+ // "sendline": "",
+ // "groupName": "",
+ "srcCo": JobData.bodyshop.cdk_configuration.srcco,
+ "srcJrnl": txEnvelope.journal,
+ "transID": "",
+ "userID": JobData.bodyshop.cdk_configuration.cashierid,
+ "userName": "BSMS"
+ },
+
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in InsertDmsStartWip - ${error}`, { request: error.request });
+ }
+}
+
+async function InsertDmsBatchWip({ socket, redisHelpers, JobData }) {
+ try {
+ const result = await MakeFortellisCall({
+ ...FortellisActions.TranBatchWip,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: await GenerateTransWips({ socket, redisHelpers, JobData })
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in InsertDmsBatchWip - ${error}`, { request: error.request, stack: error.stack });
+ }
+}
+
+// async function InsertDmsBatchWip(socket) {
+// try {
+// const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate);
+
+// const soapResponseAccountingGLInsertUpdate = await soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync({
+// arg0: CDK_CREDENTIALS,
+// arg1: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+// arg2: {
+// transWIPs: await GenerateTransWips(socket)
+// }
+// });
+
+// const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
+
+// CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync request.`);
+
+// CdkBase.createLogEvent(
+// socket,
+// "SILLY",
+// `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync Result ${JSON.stringify(result, null, 2)}`
+// );
+// CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doTransBatchWIPAsync response.`);
+// CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
+// const BatchWipResult = result && result.return;
+// return BatchWipResult;
+// } catch (error) {
+// CdkBase.createLogEvent(socket, "ERROR", `Error in InsertDmsBatchWip - ${error}`);
+// throw new Error(error);
+// }
+// }
+
+async function GenerateTransWips({ socket, redisHelpers, JobData }) {
+ const allocations = await CalculateAllocations(socket, JobData.id, true); //3rd prop sets fortellis to true to maintain logging.
+ const wips = [];
+ const DMSTransHeader = await redisHelpers.getSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.DMSTransHeader);
+
+ allocations.forEach((alloc) => {
+ //Add the sale item from each allocation.
+ if (alloc.sale.getAmount() > 0 && !alloc.tax) {
+ const item = {
+ acct: alloc.profitCenter.dms_acctnumber,
+ cntl:
+ alloc.profitCenter.dms_control_override &&
+ alloc.profitCenter.dms_control_override !== null &&
+ alloc.profitCenter.dms_control_override !== undefined &&
+ alloc.profitCenter.dms_control_override?.trim() !== ""
+ ? alloc.profitCenter.dms_control_override
+ : JobData.ro_number,
+ cntl2: null,
+ credtMemoNo: null,
+ postAmt: alloc.sale.multiply(-1).getAmount(),
+ postDesc: null,
+ prod: null,
+ statCnt: 1,
+ transID: DMSTransHeader.transID,
+ trgtCoID: JobData.bodyshop.cdk_configuration.srcco
+ };
+ wips.push(item);
+ }
+
+ //Add the cost Item.
+ if (alloc.cost.getAmount() > 0 && !alloc.tax) {
+ const item = {
+ acct: alloc.costCenter.dms_acctnumber,
+ cntl:
+ alloc.costCenter.dms_control_override &&
+ alloc.costCenter.dms_control_override !== null &&
+ alloc.costCenter.dms_control_override !== undefined &&
+ alloc.costCenter.dms_control_override?.trim() !== ""
+ ? alloc.costCenter.dms_control_override
+ : JobData.ro_number,
+ cntl2: null,
+ credtMemoNo: null,
+ postAmt: alloc.cost.getAmount(),
+ postDesc: null,
+ prod: null,
+ statCnt: 1,
+ transID: DMSTransHeader.transID,
+ trgtCoID: JobData.bodyshop.cdk_configuration.srcco
+ };
+ wips.push(item);
+
+ const itemWip = {
+ acct: alloc.costCenter.dms_wip_acctnumber,
+ cntl:
+ alloc.costCenter.dms_control_override &&
+ alloc.costCenter.dms_control_override !== null &&
+ alloc.costCenter.dms_control_override !== undefined &&
+ alloc.costCenter.dms_control_override?.trim() !== ""
+ ? alloc.costCenter.dms_control_override
+ : JobData.ro_number,
+ cntl2: null,
+ credtMemoNo: null,
+ postAmt: alloc.cost.multiply(-1).getAmount(),
+ postDesc: null,
+ prod: null,
+ statCnt: 1,
+ transID: DMSTransHeader.transID,
+ trgtCoID: JobData.bodyshop.cdk_configuration.srcco
+ };
+ wips.push(itemWip);
+ //Add to the WIP account.
+ }
+
+ if (alloc.tax) {
+
+ if (alloc.sale.getAmount() > 0) {
+ const item2 = {
+ acct: alloc.profitCenter.dms_acctnumber,
+ cntl:
+ alloc.profitCenter.dms_control_override &&
+ alloc.profitCenter.dms_control_override !== null &&
+ alloc.profitCenter.dms_control_override !== undefined &&
+ alloc.profitCenter.dms_control_override?.trim() !== ""
+ ? alloc.profitCenter.dms_control_override
+ : JobData.ro_number,
+ cntl2: null,
+ credtMemoNo: null,
+ postAmt: alloc.sale.multiply(-1).getAmount(),
+ postDesc: null,
+ prod: null,
+ statCnt: 1,
+ transID: DMSTransHeader.transID,
+ trgtCoID: JobData.bodyshop.cdk_configuration.srcco
+ };
+ wips.push(item2);
+ }
+ }
+ });
+ const txEnvelope = await redisHelpers.getSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.txEnvelope);
+
+ txEnvelope.payers.forEach((payer) => {
+ const item = {
+ acct: payer.dms_acctnumber,
+ cntl: payer.controlnumber,
+ cntl2: null,
+ credtMemoNo: null,
+ postAmt: Math.round(payer.amount * 100),
+ postDesc: null,
+ prod: null,
+ statCnt: 1,
+ transID: DMSTransHeader.transID,
+ trgtCoID: JobData.bodyshop.cdk_configuration.srcco
+ };
+
+ wips.push(item);
+ });
+ await redisHelpers.setSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.transWips, wips, defaultFortellisTTL);
+
+ return wips;
+}
+
+async function PostDmsBatchWip({ socket, redisHelpers, JobData }) {
+ try {
+ const DMSTransHeader = await redisHelpers.getSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.DMSTransHeader);
+
+
+ const result = await MakeFortellisCall({
+ ...FortellisActions.PostBatchWip,
+ headers: {},
+ redisHelpers,
+ socket,
+ jobid: JobData.id,
+ body: {
+ "opCode": "P",
+ "transID": DMSTransHeader.transID
+ }
+ });
+ return result;
+ } catch (error) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`, { request: error.request });
+ }
+}
+
+// async function PostDmsBatchWip(socket) {
+// try {
+// const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate);
+
+// const soapResponseAccountingGLInsertUpdate = await soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync({
+// arg0: CDK_CREDENTIALS,
+// arg1: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+// arg2: {
+// postWIP: { opCode: "P", transID: socket.DMSTransHeader.transID }
+// }
+// });
+
+// const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
+
+// CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync request.`);
+
+// CdkBase.createLogEvent(
+// socket,
+// "SILLY",
+// `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync Result ${JSON.stringify(result, null, 2)}`
+// );
+// CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync response.`);
+// // CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
+// const PostResult = result && result.return;
+// return PostResult;
+// } catch (error) {
+// CdkBase.createLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`);
+// throw new Error(error);
+// }
+// }
+
+// async function QueryDmsErrWip(socket) {
+// try {
+// const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate);
+
+// const soapResponseAccountingGLInsertUpdate = await soapClientAccountingGLInsertUpdate.doErrWIPAsync({
+// arg0: CDK_CREDENTIALS,
+// arg1: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+// arg2: socket.DMSTransHeader.transID
+// });
+
+// const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
+
+// CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doErrWIPAsync request.`);
+
+// CdkBase.createLogEvent(
+// socket,
+// "DEBUG",
+// `soapClientAccountingGLInsertUpdate.doErrWIPAsync Result ${JSON.stringify(result, null, 2)}`
+// );
+// CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doErrWIPAsync response.`);
+// CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
+// const PostResult = result && result.return;
+// return PostResult;
+// } catch (error) {
+// CdkBase.createLogEvent(socket, "ERROR", `Error in QueryDmsErrWip - ${error}`);
+// throw new Error(error);
+// }
+// }
+
+// async function DeleteDmsWip(socket) {
+// try {
+// const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate);
+
+// const soapResponseAccountingGLInsertUpdate = await soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync({
+// arg0: CDK_CREDENTIALS,
+// arg1: { dealerId: socket.JobData.bodyshop.cdk_dealerid },
+// arg2: {
+// postWIP: { opCode: "D", transID: socket.DMSTransHeader.transID }
+// }
+// });
+
+// const [result, rawResponse, , rawRequest] = soapResponseAccountingGLInsertUpdate;
+
+// CdkBase.createXmlEvent(socket, rawRequest, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync request.`);
+
+// CdkBase.createLogEvent(
+// socket,
+// "SILLY",
+// `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync Result ${JSON.stringify(result, null, 2)}`
+// );
+// CdkBase.createXmlEvent(socket, rawResponse, `soapClientAccountingGLInsertUpdate.doPostBatchWIPAsync response.`);
+// CheckCdkResponseForError(socket, soapResponseAccountingGLInsertUpdate);
+// const PostResult = result && result.return;
+// return PostResult;
+// } catch (error) {
+// CdkBase.createLogEvent(socket, "ERROR", `Error in PostDmsBatchWip - ${error}`);
+// throw new Error(error);
+// }
+// }
+
+async function MarkJobExported({ socket, jobid }) {
+
+ CreateFortellisLogEvent(socket, "ERROR", `Marking job as exported for id ${jobid}`);
+ const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
+ const result = await client
+ .setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
+ .request(queries.MARK_JOB_EXPORTED, {
+ jobId: jobid,
+ job: {
+ status: socket.JobData.bodyshop.md_ro_statuses.default_exported || "Exported*",
+ date_exported: new Date()
+ },
+ log: {
+ bodyshopid: socket.JobData.bodyshop.id,
+ jobid: jobid,
+ successful: true,
+ useremail: socket.user.email,
+ metadata: socket.transWips
+ },
+ bill: {
+ exported: true,
+ exported_at: new Date()
+ }
+ });
+
+ return result;
+}
+
+async function InsertFailedExportLog({ socket, JobData, error }) {
+ try {
+ const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
+ const result = await client
+ .setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
+ .request(queries.INSERT_EXPORT_LOG, {
+ log: {
+ bodyshopid: JobData.bodyshop.id,
+ jobid: JobData.id,
+ successful: false,
+ message: JSON.stringify(error),
+ useremail: socket.user.email
+ }
+ });
+
+ return result;
+ } catch (error2) {
+ CreateFortellisLogEvent(socket, "ERROR", `Error in InsertFailedExportLog - ${error}`, { message: error2.message, stack: error2.stack });
+ }
+}
+
+exports.getTransactionType = getTransactionType;
+exports.FortellisJobExport = FortellisJobExport;
diff --git a/server/utils/redisHelpers.js b/server/utils/redisHelpers.js
index 593ce13a6..7ce1066d2 100644
--- a/server/utils/redisHelpers.js
+++ b/server/utils/redisHelpers.js
@@ -19,6 +19,7 @@ const getBodyshopCacheKey = (bodyshopId) => `bodyshop-cache:${bodyshopId}`;
const getUserSocketMappingKey = (email) =>
`user:${process.env?.NODE_ENV === "production" ? "prod" : "dev"}:${email}:socketMapping`;
+const getSocketTransactionkey = ({ socketId, transactionType }) => `socket:${socketId}:${transactionType}`;
/**
* Fetch bodyshop data from the database
* @param bodyshopId
@@ -51,9 +52,12 @@ const fetchBodyshopFromDB = async (bodyshopId, logger) => {
*/
const applyRedisHelpers = ({ pubClient, app, logger }) => {
// Store session data in Redis
- const setSessionData = async (socketId, key, value) => {
+ const setSessionData = async (socketId, key, value, ttl) => {
try {
- await pubClient.hset(`socket:${socketId}`, key, JSON.stringify(value)); // Use Redis pubClient
+ await pubClient.hset(`socket:${socketId}`, key, JSON.stringify(value), ttl); // Use Redis pubClient
+ if (ttl && typeof ttl === "number") {
+ await pubClient.expire(`socket:${socketId}`, ttl);
+ }
} catch (error) {
logger.log(`Error Setting Session Data for socket ${socketId}: ${error}`, "ERROR", "redis");
}
@@ -69,6 +73,35 @@ const applyRedisHelpers = ({ pubClient, app, logger }) => {
}
};
+ const setSessionTransactionData = async (socketId, transactionType, key, value, ttl) => {
+ try {
+ await pubClient.hset(getSocketTransactionkey({ socketId, transactionType }), key, JSON.stringify(value)); // Use Redis pubClient
+ if (ttl && typeof ttl === "number") {
+ await pubClient.expire(getSocketTransactionkey({ socketId, transactionType }), ttl);
+ }
+ } catch (error) {
+ logger.log(
+ `Error Setting Session Data for socket transaction ${socketId}:${transactionType}: ${error}`,
+ "ERROR",
+ "redis"
+ );
+ }
+ };
+
+ // Retrieve session transaction data from Redis
+ const getSessionTransactionData = async (socketId, transactionType, key) => {
+ try {
+ const data = await pubClient.hget(getSocketTransactionkey({ socketId, transactionType }), key);
+ return data ? JSON.parse(data) : null;
+ } catch (error) {
+ logger.log(
+ `Error Getting Session Data for socket transaction ${socketId}:${transactionType}: ${error}`,
+ "ERROR",
+ "redis"
+ );
+ }
+ };
+
// Clear session data from Redis
const clearSessionData = async (socketId) => {
try {
@@ -77,6 +110,18 @@ const applyRedisHelpers = ({ pubClient, app, logger }) => {
logger.log(`Error Clearing Session Data for socket ${socketId}: ${error}`, "ERROR", "redis");
}
};
+ // Clear session data from Redis
+ const clearSessionTransactionData = async (socketId, transactionType) => {
+ try {
+ await pubClient.del(getSocketTransactionkey({ socketId, transactionType }));
+ } catch (error) {
+ logger.log(
+ `Error Clearing Session Transaction Data for socket ${socketId}:${transactionType}: ${error}`,
+ "ERROR",
+ "redis"
+ );
+ }
+ };
/**
* Add a socket mapping for a user
@@ -394,7 +439,10 @@ const applyRedisHelpers = ({ pubClient, app, logger }) => {
getUserSocketMapping,
refreshUserSocketTTL,
getBodyshopFromRedis,
- updateOrInvalidateBodyshopFromRedis
+ updateOrInvalidateBodyshopFromRedis,
+ setSessionTransactionData,
+ getSessionTransactionData,
+ clearSessionTransactionData
// setMultipleSessionData,
// getMultipleSessionData,
// setMultipleFromArraySessionData,
diff --git a/server/web-sockets/createLogEvent.js b/server/web-sockets/createLogEvent.js
new file mode 100644
index 000000000..0e0d52cbc
--- /dev/null
+++ b/server/web-sockets/createLogEvent.js
@@ -0,0 +1,116 @@
+const { isArray } = require("lodash");
+const logger = require("../utils/logger");
+
+
+function createLogEvent(socket, level, message) {
+ if (LogLevelHierarchy(socket.log_level) >= LogLevelHierarchy(level)) {
+ // console.log(`[WS LOG EVENT] ${level} - ${new Date()} - ${socket.user.email} - ${socket.id} - ${message}`);
+ socket.emit("log-event", {
+ timestamp: new Date(),
+ level,
+ message
+ });
+
+ logger.log("ws-log-event", level, socket.user.email, socket.recordid, {
+ wsmessage: message
+ });
+
+ if (socket.logEvents && isArray(socket.logEvents)) {
+ socket.logEvents.push({
+ timestamp: new Date(),
+ level,
+ message
+ });
+ }
+ // if (level === "ERROR") {
+ // throw new Error(message);
+ // }
+ }
+}
+
+function createJsonEvent(socket, level, message, json) {
+ if (LogLevelHierarchy(socket.log_level) >= LogLevelHierarchy(level)) {
+ //console.log(`[WS LOG EVENT] ${level} - ${new Date()} - ${socket.user.email} - ${socket.id} - ${message}`);
+ socket.emit("log-event", {
+ timestamp: new Date(),
+ level,
+ message
+ });
+ }
+ logger.log(
+ "ws-log-event-json",
+ level,
+ socket.user.email,
+ socket.recordid,
+ {
+ wsmessage: message,
+ json
+ },
+ true
+ );
+
+ if (socket.logEvents && isArray(socket.logEvents)) {
+ socket.logEvents.push({
+ timestamp: new Date(),
+ level,
+ message
+ });
+ }
+ // if (level === "ERROR") {
+ // throw new Error(message);
+ // }
+}
+
+function createXmlEvent(socket, xml, message, isError = false) {
+ if (LogLevelHierarchy(socket.log_level) >= LogLevelHierarchy("SILLY")) {
+ socket.emit("log-event", {
+ timestamp: new Date(),
+ level: isError ? "ERROR" : "SILLY",
+ message: `${message}: ${xml}`
+ });
+ }
+
+ logger.log(
+ isError ? "ws-log-event-xml-error" : "ws-log-event-xml",
+ isError ? "ERROR" : "SILLY",
+ socket.user.email,
+ socket.recordid,
+ {
+ wsmessage: message,
+ xml
+ },
+ true
+ );
+
+ if (socket.logEvents && isArray(socket.logEvents)) {
+ socket.logEvents.push({
+ timestamp: new Date(),
+ level: isError ? "ERROR" : "SILLY",
+ message,
+ xml
+ });
+ }
+}
+
+function LogLevelHierarchy(level) {
+ switch (level) {
+ case "XML":
+ return 5;
+ case "SILLY":
+ return 5;
+ case "DEBUG":
+ return 4;
+ case "INFO":
+ return 3;
+ case "WARN":
+ return 2;
+ case "ERROR":
+ return 1;
+ default:
+ return 3;
+ }
+}
+
+exports.createLogEvent = createLogEvent;
+exports.createXmlEvent = createXmlEvent;
+exports.createJsonEvent = createJsonEvent;
diff --git a/server/web-sockets/redisSocketEvents.js b/server/web-sockets/redisSocketEvents.js
index dd279e7d6..68a19fd19 100644
--- a/server/web-sockets/redisSocketEvents.js
+++ b/server/web-sockets/redisSocketEvents.js
@@ -1,8 +1,20 @@
const { admin } = require("../firebase/firebase-handler");
-
+const { FortellisJobExport, FortellisSelectedCustomer } = require("../fortellis/fortellis");
+const FortellisLogger = require("../fortellis/fortellis-logger");
+const CdkCalculateAllocations = require("../cdk/cdk-calculate-allocations").default;
const redisSocketEvents = ({
io,
- redisHelpers: { addUserSocketMapping, removeUserSocketMapping, refreshUserSocketTTL, getUserSocketMappingByBodyshop },
+ redisHelpers: {
+ setSessionData,
+ getSessionData,
+ addUserSocketMapping,
+ removeUserSocketMapping,
+ refreshUserSocketTTL,
+ getUserSocketMappingByBodyshop,
+ setSessionTransactionData,
+ getSessionTransactionData,
+ clearSessionTransactionData
+ },
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom },
logger
}) => {
@@ -217,6 +229,76 @@ const redisSocketEvents = ({
});
};
+ //Fortellis/CDK Handlers
+ const registerFortellisEvents = (socket) => {
+ socket.on("fortellis-export-job", async ({ jobid, txEnvelope }) => {
+ try {
+ await FortellisJobExport({
+ socket,
+ redisHelpers: {
+ setSessionData,
+ getSessionData,
+ addUserSocketMapping,
+ removeUserSocketMapping,
+ refreshUserSocketTTL,
+ getUserSocketMappingByBodyshop,
+ setSessionTransactionData,
+ getSessionTransactionData,
+ clearSessionTransactionData
+ },
+ ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom },
+ jobid,
+ txEnvelope
+ });
+ } catch (error) {
+ FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
+ logger.log("fortellis-job-export-error", "error", null, null, {
+ message: error.message,
+ stack: error.stack
+ });
+ }
+ });
+ socket.on("fortellis-selected-customer", async ({ jobid, selectedCustomerId }) => {
+ try {
+ await FortellisSelectedCustomer({
+ socket,
+ redisHelpers: {
+ setSessionData,
+ getSessionData,
+ addUserSocketMapping,
+ removeUserSocketMapping,
+ refreshUserSocketTTL,
+ getUserSocketMappingByBodyshop,
+ setSessionTransactionData,
+ getSessionTransactionData,
+ clearSessionTransactionData
+ },
+ ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom },
+ jobid,
+ selectedCustomerId
+ });
+ } catch (error) {
+ FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
+ logger.log("fortellis-selectd-customer-error", "error", null, null, {
+ message: error.message,
+ stack: error.stack
+ });
+ }
+ });
+ socket.on("fortellis-calculate-allocations", async (jobid, callback) => {
+ try {
+ const allocations = await CdkCalculateAllocations(socket, jobid);
+ callback(allocations);
+ } catch (error) {
+ FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
+ logger.log("fortellis-selectd-customer-error", "error", null, null, {
+ message: error.message,
+ stack: error.stack
+ });
+ }
+ });
+ };
+
// Task Events
const registerTaskEvents = (socket) => {
socket.on("task-created", (payload) => {
@@ -245,6 +327,7 @@ const redisSocketEvents = ({
registerDisconnectEvents(socket);
registerSyncEvents(socket);
registerTaskEvents(socket);
+ registerFortellisEvents(socket);
};
// Associate Middleware and Handlers
diff --git a/server/web-sockets/web-socket.js b/server/web-sockets/web-socket.js
index c55313a86..b2e94909b 100644
--- a/server/web-sockets/web-socket.js
+++ b/server/web-sockets/web-socket.js
@@ -1,231 +1,122 @@
-const path = require("path");
-
-const { io } = require("../../server");
const { admin } = require("../firebase/firebase-handler");
const { default: CdkJobExport, CdkSelectedCustomer } = require("../cdk/cdk-job-export");
const CdkGetMakes = require("../cdk/cdk-get-makes").default;
const CdkCalculateAllocations = require("../cdk/cdk-calculate-allocations").default;
-const { isArray } = require("lodash");
const logger = require("../utils/logger");
const { default: PbsExportJob, PbsSelectedCustomer } = require("../accounting/pbs/pbs-job-export");
const { PbsCalculateAllocationsAp, PbsExportAp } = require("../accounting/pbs/pbs-ap-allocations");
+const { createLogEvent } = require("./createLogEvent");
-io.use(function (socket, next) {
- try {
- if (socket.handshake.auth.token) {
- admin
- .auth()
- .verifyIdToken(socket.handshake.auth.token)
- .then((user) => {
- socket.user = user;
- next();
- })
- .catch((error) => {
- next(new Error("Authentication error", JSON.stringify(error)));
- });
- } else {
- next(new Error("Authentication error - no authorization token."));
- }
- } catch (error) {
- //console.log("Uncaught connection error:::", error);
- logger.log("websocket-connection-error", "error", null, null, {
- token: socket.handshake.auth.token,
- ...error
- });
- next(new Error(`Authentication error ${error}`));
- }
-});
+function SetLegacyWebsocketHandlers(io) {
-io.on("connection", (socket) => {
- socket.log_level = "DEBUG";
- createLogEvent(socket, "DEBUG", `Connected and Authenticated.`);
-
- socket.on("set-log-level", (level) => {
- socket.log_level = level;
- socket.emit("log-event", {
- timestamp: new Date(),
- level: "INFO",
- message: `Updated log level to ${level}`
- });
- });
-
- ///CDK
- socket.on("cdk-export-job", (jobid) => {
- CdkJobExport(socket, jobid);
- });
- socket.on("cdk-selected-customer", (selectedCustomerId) => {
- createLogEvent(socket, "DEBUG", `User selected customer ID ${selectedCustomerId}`);
- socket.selectedCustomerId = selectedCustomerId;
- CdkSelectedCustomer(socket, selectedCustomerId);
- });
-
- socket.on("cdk-get-makes", async (cdk_dealerid, callback) => {
+ io.use(function (socket, next) {
try {
- const makes = await CdkGetMakes(socket, cdk_dealerid);
- callback(makes);
+ if (socket.handshake.auth.token) {
+ admin
+ .auth()
+ .verifyIdToken(socket.handshake.auth.token)
+ .then((user) => {
+ socket.user = user;
+ next();
+ })
+ .catch((error) => {
+ next(new Error("Authentication error", JSON.stringify(error)));
+ });
+ } else {
+ next(new Error("Authentication error - no authorization token."));
+ }
} catch (error) {
- createLogEvent(socket, "ERROR", `Error in cdk-get-makes WS call. ${JSON.stringify(error, null, 2)}`);
- }
- });
-
- socket.on("cdk-calculate-allocations", async (jobid, callback) => {
- const allocations = await CdkCalculateAllocations(socket, jobid);
- createLogEvent(socket, "DEBUG", `Allocations calculated.`);
- createLogEvent(socket, "SILLY", `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`);
-
- callback(allocations);
- });
- //END CDK
-
- //PBS AR
- socket.on("pbs-calculate-allocations", async (jobid, callback) => {
- const allocations = await CdkCalculateAllocations(socket, jobid);
- createLogEvent(socket, "DEBUG", `Allocations calculated.`);
- createLogEvent(socket, "SILLY", `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`);
-
- callback(allocations);
- });
- socket.on("pbs-export-job", (jobid) => {
- PbsExportJob(socket, jobid);
- });
- socket.on("pbs-selected-customer", (selectedCustomerId) => {
- createLogEvent(socket, "DEBUG", `User selected customer ID ${selectedCustomerId}`);
- socket.selectedCustomerId = selectedCustomerId;
- PbsSelectedCustomer(socket, selectedCustomerId);
- });
- //End PBS AR
-
- //PBS AP
- socket.on("pbs-calculate-allocations-ap", async (billids, callback) => {
- const allocations = await PbsCalculateAllocationsAp(socket, billids);
- createLogEvent(socket, "DEBUG", `AP Allocations calculated.`);
- createLogEvent(socket, "DEBUG", `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`);
- socket.apAllocations = allocations;
- callback(allocations);
- });
-
- socket.on("pbs-export-ap", ({ billids, txEnvelope }) => {
- socket.txEnvelope = txEnvelope;
- PbsExportAp(socket, { billids, txEnvelope });
- });
-
- //END PBS AP
-
- socket.on("disconnect", () => {
- createLogEvent(socket, "DEBUG", `User disconnected.`);
- });
-});
-
-function createLogEvent(socket, level, message) {
- if (LogLevelHierarchy(socket.log_level) >= LogLevelHierarchy(level)) {
- // console.log(`[WS LOG EVENT] ${level} - ${new Date()} - ${socket.user.email} - ${socket.id} - ${message}`);
- socket.emit("log-event", {
- timestamp: new Date(),
- level,
- message
- });
-
- logger.log("ws-log-event", level, socket.user.email, socket.recordid, {
- wsmessage: message
- });
-
- if (socket.logEvents && isArray(socket.logEvents)) {
- socket.logEvents.push({
- timestamp: new Date(),
- level,
- message
+ //console.log("Uncaught connection error:::", error);
+ logger.log("websocket-connection-error", "error", null, null, {
+ token: socket.handshake.auth.token,
+ ...error
});
+ next(new Error(`Authentication error ${error}`));
}
- // if (level === "ERROR") {
- // throw new Error(message);
- // }
- }
+ });
+
+ io.on("connection", (socket) => {
+ socket.log_level = "DEBUG";
+ createLogEvent(socket, "DEBUG", `Connected and Authenticated.`);
+
+ socket.on("set-log-level", (level) => {
+ socket.log_level = level;
+ socket.emit("log-event", {
+ timestamp: new Date(),
+ level: "INFO",
+ message: `Updated log level to ${level}`
+ });
+ });
+
+ ///CDK
+ socket.on("cdk-export-job", (jobid) => {
+ CdkJobExport(socket, jobid);
+ });
+ socket.on("cdk-selected-customer", (selectedCustomerId) => {
+ createLogEvent(socket, "DEBUG", `User selected customer ID ${selectedCustomerId}`);
+ socket.selectedCustomerId = selectedCustomerId;
+ CdkSelectedCustomer(socket, selectedCustomerId);
+ });
+
+ socket.on("cdk-get-makes", async (cdk_dealerid, callback) => {
+ try {
+ const makes = await CdkGetMakes(socket, cdk_dealerid);
+ callback(makes);
+ } catch (error) {
+ createLogEvent(socket, "ERROR", `Error in cdk-get-makes WS call. ${JSON.stringify(error, null, 2)}`);
+ }
+ });
+
+ socket.on("cdk-calculate-allocations", async (jobid, callback) => {
+ console.log("cdk-calculate-allocations called", typeof CdkCalculateAllocations);
+ const allocations = await CdkCalculateAllocations(socket, jobid);
+ createLogEvent(socket, "DEBUG", `Allocations calculated.`);
+ createLogEvent(socket, "SILLY", `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`);
+
+ callback(allocations);
+ });
+ //END CDK
+
+ //PBS AR
+ socket.on("pbs-calculate-allocations", async (jobid, callback) => {
+ const allocations = await CdkCalculateAllocations(socket, jobid);
+ createLogEvent(socket, "DEBUG", `Allocations calculated.`);
+ createLogEvent(socket, "SILLY", `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`);
+
+ callback(allocations);
+ });
+ socket.on("pbs-export-job", (jobid) => {
+ PbsExportJob(socket, jobid);
+ });
+ socket.on("pbs-selected-customer", (selectedCustomerId) => {
+ createLogEvent(socket, "DEBUG", `User selected customer ID ${selectedCustomerId}`);
+ socket.selectedCustomerId = selectedCustomerId;
+ PbsSelectedCustomer(socket, selectedCustomerId);
+ });
+ //End PBS AR
+
+ //PBS AP
+ socket.on("pbs-calculate-allocations-ap", async (billids, callback) => {
+ const allocations = await PbsCalculateAllocationsAp(socket, billids);
+ createLogEvent(socket, "DEBUG", `AP Allocations calculated.`);
+ createLogEvent(socket, "DEBUG", `Allocations calculated. ${JSON.stringify(allocations, null, 2)}`);
+ socket.apAllocations = allocations;
+ callback(allocations);
+ });
+
+ socket.on("pbs-export-ap", ({ billids, txEnvelope }) => {
+ socket.txEnvelope = txEnvelope;
+ PbsExportAp(socket, { billids, txEnvelope });
+ });
+
+ //END PBS AP
+
+ socket.on("disconnect", () => {
+ createLogEvent(socket, "DEBUG", `User disconnected.`);
+ });
+ });
+
}
-function createJsonEvent(socket, level, message, json) {
- if (LogLevelHierarchy(socket.log_level) >= LogLevelHierarchy(level)) {
- //console.log(`[WS LOG EVENT] ${level} - ${new Date()} - ${socket.user.email} - ${socket.id} - ${message}`);
- socket.emit("log-event", {
- timestamp: new Date(),
- level,
- message
- });
- }
- logger.log(
- "ws-log-event-json",
- level,
- socket.user.email,
- socket.recordid,
- {
- wsmessage: message,
- json
- },
- true
- );
-
- if (socket.logEvents && isArray(socket.logEvents)) {
- socket.logEvents.push({
- timestamp: new Date(),
- level,
- message
- });
- }
- // if (level === "ERROR") {
- // throw new Error(message);
- // }
-}
-
-function createXmlEvent(socket, xml, message, isError = false) {
- if (LogLevelHierarchy(socket.log_level) >= LogLevelHierarchy("SILLY")) {
- socket.emit("log-event", {
- timestamp: new Date(),
- level: isError ? "ERROR" : "SILLY",
- message: `${message}: ${xml}`
- });
- }
-
- logger.log(
- isError ? "ws-log-event-xml-error" : "ws-log-event-xml",
- isError ? "ERROR" : "SILLY",
- socket.user.email,
- socket.recordid,
- {
- wsmessage: message,
- xml
- },
- true
- );
-
- if (socket.logEvents && isArray(socket.logEvents)) {
- socket.logEvents.push({
- timestamp: new Date(),
- level: isError ? "ERROR" : "SILLY",
- message,
- xml
- });
- }
-}
-
-function LogLevelHierarchy(level) {
- switch (level) {
- case "XML":
- return 5;
- case "SILLY":
- return 5;
- case "DEBUG":
- return 4;
- case "INFO":
- return 3;
- case "WARN":
- return 2;
- case "ERROR":
- return 1;
- default:
- return 3;
- }
-}
-
-exports.createLogEvent = createLogEvent;
-exports.createXmlEvent = createXmlEvent;
-exports.createJsonEvent = createJsonEvent;
+exports.SetLegacyWebsocketHandlers = SetLegacyWebsocketHandlers;
\ No newline at end of file