IO-2776 Add posting transactions for Fortellis.

This commit is contained in:
Patrick Fic
2025-08-27 16:37:31 -07:00
parent 3d691568ff
commit 8296d914c5
4 changed files with 313 additions and 175 deletions

View File

@@ -7,6 +7,8 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
import Dinero from "dinero.js"; import Dinero from "dinero.js";
import { SyncOutlined } from "@ant-design/icons"; import { SyncOutlined } from "@ant-design/icons";
import { pageLimit } from "../../utils/config"; import { pageLimit } from "../../utils/config";
import { useSplitTreatments } from "@splitsoftware/splitio-react";
import { useSocket } from "../../contexts/SocketIO/useSocket";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser //currentUser: selectCurrentUser
@@ -22,13 +24,28 @@ export default connect(mapStateToProps, mapDispatchToProps)(DmsAllocationsSummar
export function DmsAllocationsSummary({ socket, bodyshop, jobId, title }) { export function DmsAllocationsSummary({ socket, bodyshop, jobId, title }) {
const { t } = useTranslation(); const { t } = useTranslation();
const [allocationsSummary, setAllocationsSummary] = useState([]); const [allocationsSummary, setAllocationsSummary] = useState([]);
const {
treatments: { Fortellis }
} = useSplitTreatments({
attributes: {},
names: ["Fortellis"],
splitKey: bodyshop.imexshopid
});
const { socket: wsssocket } = useSocket();
useEffect(() => { useEffect(() => {
if (socket.connected) { if (Fortellis.treatment === "on") {
socket.emit("cdk-calculate-allocations", jobId, (ack) => { wsssocket.emit("cdk-calculate-allocations", jobId, (ack) => {
setAllocationsSummary(ack); setAllocationsSummary(ack);
socket.allocationsSummary = ack; socket.allocationsSummary = ack;
}); });
} else {
if (socket.connected) {
socket.emit("cdk-calculate-allocations", jobId, (ack) => {
setAllocationsSummary(ack);
socket.allocationsSummary = ack;
});
}
} }
}, [socket, socket.connected, jobId]); }, [socket, socket.connected, jobId]);

View File

@@ -310,11 +310,34 @@ const FortellisActions = {
apiName: "CDK Drive Post Accounts GL WIP", apiName: "CDK Drive Post Accounts GL WIP",
url: `https://api.fortellis.io/cdk-test/drive/chartofaccounts/v2/bulk/`, url: `https://api.fortellis.io/cdk-test/drive/chartofaccounts/v2/bulk/`,
waitForResult: true 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 = { const FortellisCacheEnums = {
txEnvelope: "txEnvelope", txEnvelope: "txEnvelope",
DMSBatchTxn: "DMSBatchTxn",
SubscriptionMeta: "SubscriptionMeta", SubscriptionMeta: "SubscriptionMeta",
DepartmentId: "DepartmentId", DepartmentId: "DepartmentId",
JobData: "JobData", JobData: "JobData",
@@ -324,6 +347,9 @@ const FortellisCacheEnums = {
DMSCustList: "DMSCustList", DMSCustList: "DMSCustList",
DMSCust: "DMSCust", DMSCust: "DMSCust",
selectedCustomerId: "selectedCustomerId", selectedCustomerId: "selectedCustomerId",
DMSTransHeader: "DMSTransHeader",
transWips: "transWips",
DmsBatchTxnPost: "DmsBatchTxnPost"
}; };
function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) { function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) {

View File

@@ -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 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 InstanceMgr = require("../utils/instanceMgr").default;
const CreateFortellisLogEvent = require("./fortellis-logger"); const CreateFortellisLogEvent = require("./fortellis-logger");
const queries = require("../graphql-client/queries"); 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.` `{4.3} Updating Existing Vehicle to associate to owner.`
); );
DMSVeh = await UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust, selectedCustomerId, txEnvelope }); 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) CreateFortellisLogEvent(
// CdkBase.createLogEvent(socket, "DEBUG", `{5} Creating Transaction header with Dms Start WIP`); socket,
// socket.DMSTransHeader = await InsertDmsStartWip(socket); "DEBUG",
// CdkBase.createLogEvent(socket, "DEBUG", `{5.1} Creating Transaction with ID ${socket.DMSTransHeader.transID}`); `{6} Attempting to post Transaction with ID ${socket.DMSTransHeader.transID}`
);
// socket.DMSBatchTxn = await InsertDmsBatchWip(socket); const DmsBatchTxnPost = await PostDmsBatchWip({ socket, redisHelpers, JobData });
// CdkBase.createLogEvent( await setSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DmsBatchTxnPost, DmsBatchTxnPost, defaultFortellisTTL);
// 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.`);
// 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.`); await MarkJobExported(socket, socket.JobData.id);
// 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);
// socket.DmsError.errMsg CreateFortellisLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`);
// .split("|") socket.DMSVehHistory = await InsertServiceVehicleHistory(socket);
// .map( socket.emit("export-success", socket.JobData.id);
// (e) => } else {
// e !== null && //Get the error code
// e !== "" && CreateFortellisLogEvent(
// CdkBase.createLogEvent(socket, "ERROR", `Error(s) encountered in posting transaction. ${e}`) 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) { } catch (error) {
// CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`); // CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
// await InsertFailedExportLog(socket, error); // await InsertFailedExportLog(socket, error);
@@ -311,7 +321,6 @@ async function QueryDmsCustomerByName({ socket, redisHelpers, JobData }) {
} }
async function InsertDmsCustomer({ socket, redisHelpers, JobData }) { async function InsertDmsCustomer({ socket, redisHelpers, JobData }) {
try { try {
const result = await MakeFortellisCall({ const result = await MakeFortellisCall({
...FortellisActions.CreateCustomer, ...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) { // async function InsertDmsBatchWip(socket) {
// try { // try {
// const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate); // const soapClientAccountingGLInsertUpdate = await soap.createClientAsync(CdkWsdl.AccountingGLInsertUpdate);
@@ -1114,138 +1171,164 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust
// } // }
// } // }
// async function GenerateTransWips(socket) { async function GenerateTransWips({ socket, redisHelpers, JobData }) {
// const allocations = await CalcualteAllocations(socket, socket.JobData.id); const allocations = await CalculateAllocations(socket, socket.JobData.id, true); //3rd prop sets fortellis to true to maintain logging.
// const wips = []; const wips = [];
// allocations.forEach((alloc) => { const DMSTransHeader = await redisHelpers.getSessionTransactionData(socket.id, getTransactionType(JobData.id), FortellisCacheEnums.DMSTransHeader);
// //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);
// }
// //Add the cost Item. allocations.forEach((alloc) => {
// if (alloc.cost.getAmount() > 0 && !alloc.tax) { //Add the sale item from each allocation.
// const item = { if (alloc.sale.getAmount() > 0 && !alloc.tax) {
// acct: alloc.costCenter.dms_acctnumber, const item = {
// cntl: acct: alloc.profitCenter.dms_acctnumber,
// alloc.costCenter.dms_control_override && cntl:
// alloc.costCenter.dms_control_override !== null && alloc.profitCenter.dms_control_override &&
// alloc.costCenter.dms_control_override !== undefined && alloc.profitCenter.dms_control_override !== null &&
// alloc.costCenter.dms_control_override?.trim() !== "" alloc.profitCenter.dms_control_override !== undefined &&
// ? alloc.costCenter.dms_control_override alloc.profitCenter.dms_control_override?.trim() !== ""
// : socket.JobData.ro_number, ? alloc.profitCenter.dms_control_override
// cntl2: null, : JobData.ro_number,
// credtMemoNo: null, cntl2: null,
// postAmt: alloc.cost.getAmount(), credtMemoNo: null,
// postDesc: null, postAmt: alloc.sale.multiply(-1).getAmount(),
// prod: null, postDesc: null,
// statCnt: 1, prod: null,
// transID: socket.DMSTransHeader.transID, statCnt: 1,
// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco transID: DMSTransHeader.transID,
// }; trgtCoID: JobData.bodyshop.cdk_configuration.srcco
// wips.push(item); };
wips.push(item);
}
// const itemWip = { //Add the cost Item.
// acct: alloc.costCenter.dms_wip_acctnumber, if (alloc.cost.getAmount() > 0 && !alloc.tax) {
// cntl: const item = {
// alloc.costCenter.dms_control_override && acct: alloc.costCenter.dms_acctnumber,
// alloc.costCenter.dms_control_override !== null && cntl:
// alloc.costCenter.dms_control_override !== undefined && alloc.costCenter.dms_control_override &&
// alloc.costCenter.dms_control_override?.trim() !== "" alloc.costCenter.dms_control_override !== null &&
// ? alloc.costCenter.dms_control_override alloc.costCenter.dms_control_override !== undefined &&
// : socket.JobData.ro_number, alloc.costCenter.dms_control_override?.trim() !== ""
// cntl2: null, ? alloc.costCenter.dms_control_override
// credtMemoNo: null, : JobData.ro_number,
// postAmt: alloc.cost.multiply(-1).getAmount(), cntl2: null,
// postDesc: null, credtMemoNo: null,
// prod: null, postAmt: alloc.cost.getAmount(),
// statCnt: 1, postDesc: null,
// transID: socket.DMSTransHeader.transID, prod: null,
// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco statCnt: 1,
// }; transID: DMSTransHeader.transID,
// wips.push(itemWip); trgtCoID: JobData.bodyshop.cdk_configuration.srcco
// //Add to the WIP account. };
// } wips.push(item);
// if (alloc.tax) { const itemWip = {
// // if (alloc.cost.getAmount() > 0) { acct: alloc.costCenter.dms_wip_acctnumber,
// // const item = { cntl:
// // acct: alloc.costCenter.dms_acctnumber, alloc.costCenter.dms_control_override &&
// // cntl: socket.JobData.ro_number, alloc.costCenter.dms_control_override !== null &&
// // cntl2: null, alloc.costCenter.dms_control_override !== undefined &&
// // credtMemoNo: null, alloc.costCenter.dms_control_override?.trim() !== ""
// // postAmt: alloc.cost.getAmount(), ? alloc.costCenter.dms_control_override
// // postDesc: null, : JobData.ro_number,
// // prod: null, cntl2: null,
// // statCnt: 1, credtMemoNo: null,
// // transID: socket.DMSTransHeader.transID, postAmt: alloc.cost.multiply(-1).getAmount(),
// // trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco, 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) { // wips.push(item);
// 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);
// }
// }
// });
// socket.txEnvelope.payers.forEach((payer) => { if (alloc.sale.getAmount() > 0) {
// const item = { const item2 = {
// acct: payer.dms_acctnumber, acct: alloc.profitCenter.dms_acctnumber,
// cntl: payer.controlnumber, cntl:
// cntl2: null, alloc.profitCenter.dms_control_override &&
// credtMemoNo: null, alloc.profitCenter.dms_control_override !== null &&
// postAmt: Math.round(payer.amount * 100), alloc.profitCenter.dms_control_override !== undefined &&
// postDesc: null, alloc.profitCenter.dms_control_override?.trim() !== ""
// prod: null, ? alloc.profitCenter.dms_control_override
// statCnt: 1, : JobData.ro_number,
// transID: socket.DMSTransHeader.transID, cntl2: null,
// trgtCoID: socket.JobData.bodyshop.cdk_configuration.srcco 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); txEnvelope.payers.forEach((payer) => {
// }); const item = {
// socket.transWips = wips; acct: payer.dms_acctnumber,
// return wips; 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) { // async function PostDmsBatchWip(socket) {
// try { // try {

View File

@@ -1,7 +1,7 @@
const { admin } = require("../firebase/firebase-handler"); const { admin } = require("../firebase/firebase-handler");
const { FortellisJobExport, FortellisSelectedCustomer } = require("../fortellis/fortellis"); const { FortellisJobExport, FortellisSelectedCustomer } = require("../fortellis/fortellis");
const FortellisLogger = require("../fortellis/fortellis-logger"); const FortellisLogger = require("../fortellis/fortellis-logger");
const CdkCalculateAllocations = require("../cdk/cdk-calculate-allocations").default;
const redisSocketEvents = ({ const redisSocketEvents = ({
io, io,
redisHelpers: { 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 // Task Events