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 { 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]);

View File

@@ -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 = [] }) {

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 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 {

View File

@@ -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