diff --git a/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx b/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx index 966cadf13..bfc14f9d6 100644 --- a/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx +++ b/client/src/components/dms-allocations-summary/dms-allocations-summary.component.jsx @@ -7,6 +7,8 @@ import { selectBodyshop } from "../../redux/user/user.selectors"; import Dinero from "dinero.js"; import { SyncOutlined } from "@ant-design/icons"; import { pageLimit } from "../../utils/config"; +import { useSplitTreatments } from "@splitsoftware/splitio-react"; +import { useSocket } from "../../contexts/SocketIO/useSocket"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -22,13 +24,28 @@ export default connect(mapStateToProps, mapDispatchToProps)(DmsAllocationsSummar export function DmsAllocationsSummary({ socket, bodyshop, jobId, title }) { const { t } = useTranslation(); const [allocationsSummary, setAllocationsSummary] = useState([]); + const { + treatments: { Fortellis } + } = useSplitTreatments({ + attributes: {}, + names: ["Fortellis"], + splitKey: bodyshop.imexshopid + }); + const { socket: wsssocket } = useSocket(); useEffect(() => { - if (socket.connected) { - socket.emit("cdk-calculate-allocations", jobId, (ack) => { + if (Fortellis.treatment === "on") { + wsssocket.emit("cdk-calculate-allocations", jobId, (ack) => { setAllocationsSummary(ack); socket.allocationsSummary = ack; }); + } else { + if (socket.connected) { + socket.emit("cdk-calculate-allocations", jobId, (ack) => { + setAllocationsSummary(ack); + socket.allocationsSummary = ack; + }); + } } }, [socket, socket.connected, jobId]); diff --git a/server/fortellis/fortellis-helpers.js b/server/fortellis/fortellis-helpers.js index 229c4ecc2..64c590fdc 100644 --- a/server/fortellis/fortellis-helpers.js +++ b/server/fortellis/fortellis-helpers.js @@ -310,11 +310,34 @@ const FortellisActions = { 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: "put", + apiName: "CDK Drive Post Accounting GL", + }, + TranBatchWip: { + url: isProduction + ? "https://api.fortellis.io/cdk/drive/glpost/transBatchWIP" + : "https://api.fortellis.io/cdk-test/drive/glpost/transBatchWIP", + type: "put", + apiName: "CDK Drive Post Accounting GL", + }, + PostBatchWip: { + url: isProduction + ? "https://api.fortellis.io/cdk/drive/glpost/transBatchWIP" + : "https://api.fortellis.io/cdk-test/drive/glpost/postBatchWIP", + type: "put", + apiName: "CDK Drive Post Accounting GL", + }, + }; const FortellisCacheEnums = { txEnvelope: "txEnvelope", + DMSBatchTxn: "DMSBatchTxn", SubscriptionMeta: "SubscriptionMeta", DepartmentId: "DepartmentId", JobData: "JobData", @@ -324,6 +347,9 @@ const FortellisCacheEnums = { DMSCustList: "DMSCustList", DMSCust: "DMSCust", selectedCustomerId: "selectedCustomerId", + DMSTransHeader: "DMSTransHeader", + transWips: "transWips", + DmsBatchTxnPost: "DmsBatchTxnPost" }; function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) { diff --git a/server/fortellis/fortellis.js b/server/fortellis/fortellis.js index ab57ec634..ed0cbe165 100644 --- a/server/fortellis/fortellis.js +++ b/server/fortellis/fortellis.js @@ -1,9 +1,5 @@ -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 CalculateAllocations = require("../cdk/cdk-calculate-allocations").default; const InstanceMgr = require("../utils/instanceMgr").default; const CreateFortellisLogEvent = require("./fortellis-logger"); const queries = require("../graphql-client/queries"); @@ -160,53 +156,67 @@ async function FortellisSelectedCustomer({ socket, redisHelpers, ioHelpers, sele `{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 + } - ////New code above. - /// Old code below. + + 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); - console.log(DMSVeh) - // CdkBase.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}`); + CreateFortellisLogEvent( + socket, + "DEBUG", + `{6} Attempting to post Transaction with ID ${socket.DMSTransHeader.transID}` + ); - // socket.DMSBatchTxn = await InsertDmsBatchWip(socket); - // CdkBase.createLogEvent( - // socket, - // "DEBUG", - // `{6} Attempting to post Transaction with ID ${socket.DMSTransHeader.transID}` - // ); - // socket.DmsBatchTxnPost = await PostDmsBatchWip(socket); - // if (socket.DmsBatchTxnPost.code === "success") { - // //something - // CdkBase.createLogEvent(socket, "DEBUG", `{6} Successfully posted sransaction to DMS.`); + const DmsBatchTxnPost = await PostDmsBatchWip({ socket, redisHelpers, JobData }); + await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DmsBatchTxnPost, DmsBatchTxnPost, defaultFortellisTTL); - // await MarkJobExported(socket, socket.JobData.id); + if (DmsBatchTxnPost.rtnCode === "0") { //TODO: Validate this is a string and not # + //something + CreateFortellisLogEvent(socket, "DEBUG", `{6} Successfully posted sransaction to DMS.`); - // CdkBase.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( - // 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}`); - // socket.DmsBatchTxnPost = await DeleteDmsWip(socket); + await MarkJobExported(socket, socket.JobData.id); - // socket.DmsError.errMsg - // .split("|") - // .map( - // (e) => - // e !== null && - // e !== "" && - // CdkBase.createLogEvent(socket, "ERROR", `Error(s) encountered in posting transaction. ${e}`) - // ); - // } + CreateFortellisLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`); + socket.DMSVehHistory = await InsertServiceVehicleHistory(socket); + socket.emit("export-success", socket.JobData.id); + } else { + //Get the error code + CreateFortellisLogEvent( + 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}`); + // 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}`); // await InsertFailedExportLog(socket, error); @@ -311,7 +321,6 @@ async function QueryDmsCustomerByName({ socket, redisHelpers, JobData }) { } async function InsertDmsCustomer({ socket, redisHelpers, JobData }) { - try { const result = await MakeFortellisCall({ ...FortellisActions.CreateCustomer, @@ -1083,6 +1092,54 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust // } // } + +async function InsertDmsStartWip({ socket, redisHelpers, JobData }) { + try { + const result = await MakeFortellisCall({ + ...FortellisActions.StartWip, + headers: {}, + redisHelpers, + socket, + jobid: JobData.id, + body: { + "acctgDate": moment().tz(socket.JobData.bodyshop.timezone).format("YYYY-MM-DD"), + "desc": socket.txEnvelope.story && socket.txEnvelope.story.replace(replaceSpecialRegex, ""), + "docType": "10", + "m13Flag": "0", + "refer": socket.JobData.ro_number, + // "rtnCode": "", + // "sendline": "", + // "groupName": "", + "srcCo": socket.JobData.bodyshop.cdk_configuration.srcco, + "srcJrnl": socket.txEnvelope.journal, + "transID": "", + "userID": socket.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 }); + } +} + // async function InsertDmsBatchWip(socket) { // try { // const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate); @@ -1114,138 +1171,164 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust // } // } -// async function GenerateTransWips(socket) { -// const allocations = await CalcualteAllocations(socket, socket.JobData.id); -// const wips = []; -// 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 -// : socket.JobData.ro_number, -// cntl2: null, -// credtMemoNo: null, -// postAmt: alloc.sale.multiply(-1).getAmount(), -// postDesc: null, -// prod: null, -// statCnt: 1, -// transID: socket.DMSTransHeader.transID, -// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco -// }; -// wips.push(item); -// } +async function GenerateTransWips({ socket, redisHelpers, JobData }) { + const allocations = await CalculateAllocations(socket, 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); -// //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 -// : socket.JobData.ro_number, -// cntl2: null, -// credtMemoNo: null, -// postAmt: alloc.cost.getAmount(), -// postDesc: null, -// prod: null, -// statCnt: 1, -// transID: socket.DMSTransHeader.transID, -// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco -// }; -// wips.push(item); + 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); + } -// 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 -// : socket.JobData.ro_number, -// cntl2: null, -// credtMemoNo: null, -// postAmt: alloc.cost.multiply(-1).getAmount(), -// postDesc: null, -// prod: null, -// statCnt: 1, -// transID: socket.DMSTransHeader.transID, -// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco -// }; -// wips.push(itemWip); -// //Add to the WIP account. -// } + //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); -// if (alloc.tax) { -// // if (alloc.cost.getAmount() > 0) { -// // const item = { -// // acct: alloc.costCenter.dms_acctnumber, -// // cntl: socket.JobData.ro_number, -// // cntl2: null, -// // credtMemoNo: null, -// // postAmt: alloc.cost.getAmount(), -// // postDesc: null, -// // prod: null, -// // statCnt: 1, -// // transID: socket.DMSTransHeader.transID, -// // trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco, -// // }; + 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. + } -// // wips.push(item); -// // } + if (alloc.tax) { + // if (alloc.cost.getAmount() > 0) { + // const item = { + // acct: alloc.costCenter.dms_acctnumber, + // cntl: 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, + // }; -// 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 -// : socket.JobData.ro_number, -// cntl2: null, -// credtMemoNo: null, -// postAmt: alloc.sale.multiply(-1).getAmount(), -// postDesc: null, -// prod: null, -// statCnt: 1, -// transID: socket.DMSTransHeader.transID, -// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco -// }; -// wips.push(item2); -// } -// } -// }); + // wips.push(item); + // } -// socket.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: socket.DMSTransHeader.transID, -// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco -// }; + 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); -// wips.push(item); -// }); -// socket.transWips = wips; -// return wips; -// } + 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 { diff --git a/server/web-sockets/redisSocketEvents.js b/server/web-sockets/redisSocketEvents.js index 6710c2bed..68a19fd19 100644 --- a/server/web-sockets/redisSocketEvents.js +++ b/server/web-sockets/redisSocketEvents.js @@ -1,7 +1,7 @@ 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: { @@ -285,6 +285,18 @@ const redisSocketEvents = ({ }); } }); + 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