Merge branch 'feature/IO-2776-cdk-fortellis' into feature/Reynolds-and-Reynolds-DMS-API-Integration
This commit is contained in:
346
Fortellis Notes.md
Normal file
346
Fortellis Notes.md
Normal file
@@ -0,0 +1,346 @@
|
||||
Fortellis Notes
|
||||
|
||||
Subscription ID
|
||||
|
||||
- Appears to give us a list of all dealerships we have access to, and `apiDmsInfo` contains the integrations that are enabled for that dealership.
|
||||
- Will likely need to filter based on the DMS ID or something?
|
||||
- Should store the whole subscription object. Contains department information needed in subsequent calls.
|
||||
|
||||
Department ID
|
||||
|
||||
- May have multiple departments. Appears that financial stuff goes to Accounting, History will go to Service.
|
||||
- TODO: How do we handle the multiple departments that may come up.
|
||||
|
||||
###Internal Questions
|
||||
|
||||
* Overview of the redis storing mechanism to cache this data.
|
||||
*
|
||||
|
||||
# GL Wip Posting
|
||||
|
||||
## Org Helper Return Data
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"acctgLgnID": "DEVWB-A",
|
||||
"applCode": "V",
|
||||
"coID": "77",
|
||||
"companyName": "TEST SYS C187092 DEVWB",
|
||||
"lgnDesc": "DEV WRITE BACK VMS",
|
||||
"logon": "DEVWB-V"
|
||||
},
|
||||
{
|
||||
"acctgLgnID": "DEVWB-A",
|
||||
"applCode": "F",
|
||||
"coID": "77",
|
||||
"companyName": "TEST SYS C187092 DEVWB",
|
||||
"lgnDesc": "DEV WRITE BACK F&I SALES",
|
||||
"logon": "DEVWB-FI"
|
||||
},
|
||||
{
|
||||
"acctgLgnID": "DEVWB-A",
|
||||
"applCode": "CS",
|
||||
"coID": "77",
|
||||
"companyName": "TEST SYS C187092 DEVWB",
|
||||
"lgnDesc": "DEV WRITE BACK SERVICE",
|
||||
"logon": "DEVWB-S"
|
||||
},
|
||||
{
|
||||
"acctgLgnID": "DEVWB-A",
|
||||
"applCode": "A",
|
||||
"coID": "77",
|
||||
"companyName": "TEST SYS C187092 DEVWB",
|
||||
"lgnDesc": "DEV WRITE BACK ACCTG",
|
||||
"logon": "DEVWB-A"
|
||||
},
|
||||
{
|
||||
"acctgLgnID": "DEVWB-A",
|
||||
"applCode": "SL",
|
||||
"coID": "77",
|
||||
"companyName": "TEST SYS C187092 DEVWB",
|
||||
"lgnDesc": "DEV WRTIE BACK SLS MGMT",
|
||||
"logon": "DEVWB-SL"
|
||||
},
|
||||
{
|
||||
"acctgLgnID": "DEVWB-A",
|
||||
"applCode": "O",
|
||||
"coID": "77",
|
||||
"companyName": "TEST SYS C187092 DEVWB",
|
||||
"lgnDesc": "DEV WRITE BACK PARTS",
|
||||
"logon": "DEVWB-I"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Journal Helper Return Data
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "32",
|
||||
"jrnlName": "PARTS SALES",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "4",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "92",
|
||||
"jrnlName": "YTD ADJUSTMENTS",
|
||||
"jrnlType": "Y",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "3",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "12",
|
||||
"jrnlName": "FLEET SALES",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "9",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "57",
|
||||
"jrnlName": "CASH RECEIPTS (OPEN-ITEM)",
|
||||
"jrnlType": "R",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "1",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "93",
|
||||
"jrnlName": "SET UP HISTORY",
|
||||
"jrnlType": "H",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "10",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "88",
|
||||
"jrnlName": "F/S STATISCAL DATA",
|
||||
"jrnlType": "F",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "10",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "58",
|
||||
"jrnlName": "WARRANTY CREDITS",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "3",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "FC",
|
||||
"jrnlName": "FINANCE CHARGE",
|
||||
"jrnlType": "A",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "12",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "94",
|
||||
"jrnlName": "SET UP SCHEDULES",
|
||||
"jrnlType": "C",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "3",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "95",
|
||||
"jrnlName": "SET UP GENERAL LEDGER",
|
||||
"jrnlType": "B",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "3",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "20",
|
||||
"jrnlName": "USED VEHICLE SALES",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "9",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "60",
|
||||
"jrnlName": "CASH DISBURSEMENTS",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "2",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "30",
|
||||
"jrnlName": "SERVICE SALES",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "7",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "40",
|
||||
"jrnlName": "PAYROLL",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "11",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "15",
|
||||
"jrnlName": "DEALER TRADES",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "9",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "70",
|
||||
"jrnlName": "NEW VEHICLE PURCHASES",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "8",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "25",
|
||||
"jrnlName": "USED WHOLESALE",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "9",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "75",
|
||||
"jrnlName": "GENERAL PURCHASES",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "5",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "10",
|
||||
"jrnlName": "NEW VEHICLE SALES",
|
||||
"jrnlType": "S",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "9",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "80",
|
||||
"jrnlName": "GENERAL JOURNAL",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "3",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "11",
|
||||
"jrnlName": "WORK IN PROGRESS",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "10",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "56",
|
||||
"jrnlName": "CASH RECEIPTS (BALANCE FWD)",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "1",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "81",
|
||||
"jrnlName": "STANDARD ENTRIES",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "6",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "51",
|
||||
"jrnlName": "CASH RECEIPTS JOURNAL - EFT",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "10",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "61",
|
||||
"jrnlName": "CASH DISBURSMENTS -EFT",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "10",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
},
|
||||
{
|
||||
"companyNo": "77",
|
||||
"jrnlID": "71",
|
||||
"jrnlName": "USED VEHICLE PURCHASES",
|
||||
"jrnlType": "G",
|
||||
"intercoFlag": "0",
|
||||
"defaultDocType": "8",
|
||||
"errCode": "",
|
||||
"errMsg": ""
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
# Feedback
|
||||
|
||||
- Receiving bad request errors, with no details. API errors page doesn't indicate what's wrong for certain types of error codes.
|
||||
- API Error page works on a several minute delay.
|
||||
47252
VendorsBulk.json
Normal file
47252
VendorsBulk.json
Normal file
File diff suppressed because it is too large
Load Diff
8504
_reference/Fortellis COA.json
Normal file
8504
_reference/Fortellis COA.json
Normal file
File diff suppressed because it is too large
Load Diff
5
_reference/Fortellis Feedback.md
Normal file
5
_reference/Fortellis Feedback.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Fortellis Feedback
|
||||
|
||||
Create Customer
|
||||
https://apidocs.fortellis.io/apis/c5cfb5b3-2013-4870-8645-0379c01ae56b
|
||||
Request Body compoennts do not show on website. Unable to determine which components are required.
|
||||
960
client/package-lock.json
generated
960
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -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("fortellis-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]);
|
||||
|
||||
@@ -76,8 +93,12 @@ export function DmsAllocationsSummary({ socket, bodyshop, jobId, title }) {
|
||||
extra={
|
||||
<Button
|
||||
onClick={() => {
|
||||
socket.emit("cdk-calculate-allocations", jobId, (ack) => setAllocationsSummary(ack));
|
||||
}}
|
||||
if (Fortellis.treatment === "on") {
|
||||
socket.emit("fortellis-calculate-allocations", jobId, (ack) => setAllocationsSummary(ack));
|
||||
} else {
|
||||
socket.emit("cdk-calculate-allocations", jobId, (ack) => setAllocationsSummary(ack));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SyncOutlined />
|
||||
</Button>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import { Button, Checkbox, Col, Table } from "antd";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { useSocket } from "../../contexts/SocketIO/useSocket";
|
||||
import { socket } from "../../pages/dms/dms.container";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
@@ -15,42 +17,125 @@ const mapDispatchToProps = () => ({
|
||||
});
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DmsCustomerSelector);
|
||||
|
||||
export function DmsCustomerSelector({ bodyshop }) {
|
||||
export function DmsCustomerSelector({ bodyshop, jobid }) {
|
||||
const { t } = useTranslation();
|
||||
const [customerList, setcustomerList] = useState([]);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selectedCustomer, setSelectedCustomer] = useState(null);
|
||||
const [dmsType, setDmsType] = useState("cdk");
|
||||
|
||||
socket.on("cdk-select-customer", (customerList) => {
|
||||
setOpen(true);
|
||||
setDmsType("cdk");
|
||||
setcustomerList(customerList);
|
||||
});
|
||||
socket.on("pbs-select-customer", (customerList) => {
|
||||
setOpen(true);
|
||||
setDmsType("pbs");
|
||||
setcustomerList(customerList);
|
||||
const {
|
||||
treatments: { Fortellis }
|
||||
} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["Fortellis"],
|
||||
splitKey: bodyshop.imexshopid
|
||||
});
|
||||
|
||||
const { socket: wsssocket } = useSocket();
|
||||
|
||||
useEffect(() => {
|
||||
if (Fortellis.treatment === "on") {
|
||||
const handleFortellisSelectCustomer = (customerList) => {
|
||||
setOpen(true);
|
||||
setDmsType("cdk");
|
||||
setcustomerList(customerList);
|
||||
};
|
||||
wsssocket.on("fortellis-select-customer", handleFortellisSelectCustomer);
|
||||
return () => {
|
||||
wsssocket.off("fortellis-select-customer", handleFortellisSelectCustomer);
|
||||
};
|
||||
} else {
|
||||
const handleCdkSelectCustomer = (customerList) => {
|
||||
setOpen(true);
|
||||
setDmsType("cdk");
|
||||
setcustomerList(customerList);
|
||||
};
|
||||
const handlePbsSelectCustomer = (customerList) => {
|
||||
setOpen(true);
|
||||
setDmsType("pbs");
|
||||
setcustomerList(customerList);
|
||||
};
|
||||
socket.on("cdk-select-customer", handleCdkSelectCustomer);
|
||||
socket.on("pbs-select-customer", handlePbsSelectCustomer);
|
||||
return () => {
|
||||
socket.off("cdk-select-customer", handleCdkSelectCustomer);
|
||||
socket.off("pbs-select-customer", handlePbsSelectCustomer);
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onUseSelected = () => {
|
||||
setOpen(false);
|
||||
socket.emit(`${dmsType}-selected-customer`, selectedCustomer);
|
||||
if (Fortellis.treatment === "on") {
|
||||
wsssocket.emit(`fortellis-selected-customer`, { selectedCustomerId: selectedCustomer, jobid });
|
||||
} else {
|
||||
socket.emit(`${dmsType}-selected-customer`, selectedCustomer);
|
||||
}
|
||||
setSelectedCustomer(null);
|
||||
};
|
||||
|
||||
const onUseGeneric = () => {
|
||||
setOpen(false);
|
||||
socket.emit(`${dmsType}-selected-customer`, bodyshop.cdk_configuration.generic_customer_number);
|
||||
|
||||
if (Fortellis.treatment === "on") {
|
||||
wsssocket.emit(`fortellis-selected-customer`, {
|
||||
selectedCustomerId: bodyshop.cdk_configuration.generic_customer_number,
|
||||
jobid
|
||||
});
|
||||
} else {
|
||||
socket.emit(`${dmsType}-selected-customer`, bodyshop.cdk_configuration.generic_customer_number);
|
||||
}
|
||||
setSelectedCustomer(null);
|
||||
};
|
||||
|
||||
const onCreateNew = () => {
|
||||
setOpen(false);
|
||||
socket.emit(`${dmsType}-selected-customer`, null);
|
||||
|
||||
if (Fortellis.treatment === "on") {
|
||||
wsssocket.emit(`fortellis-selected-customer`, { selectedCustomerId: null, jobid });
|
||||
} else {
|
||||
socket.emit(`${dmsType}-selected-customer`, null);
|
||||
}
|
||||
setSelectedCustomer(null);
|
||||
};
|
||||
|
||||
const fortellisColumns = [
|
||||
{
|
||||
title: t("jobs.fields.dms.id"),
|
||||
dataIndex: "customerId",
|
||||
key: "id"
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.dms.vinowner"),
|
||||
dataIndex: "vinOwner",
|
||||
key: "vinOwner",
|
||||
render: (text, record) => <Checkbox disabled checked={record.vinOwner} />
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.dms.name1"),
|
||||
dataIndex: ["customerName", "firstName"],
|
||||
key: "firstName",
|
||||
sorter: (a, b) => alphaSort(a.customerName?.firstName, b.customerName?.firstName)
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.dms.name1"),
|
||||
dataIndex: ["customerName", "lastName"],
|
||||
key: "lastName",
|
||||
sorter: (a, b) => alphaSort(a.customerName?.lastName, b.customerName?.lastName)
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.dms.address"),
|
||||
|
||||
key: "address",
|
||||
render: (record) =>
|
||||
`${record.postalAddress?.addressLine1} ${record.postalAddress?.addressLine2 ? `, ${record.postalAddress?.addressLine2}` : ""},
|
||||
${record.postalAddress?.city} ${record.postalAddress?.state} ${record.postalAddress?.postalCode} ${
|
||||
record.postalAddress?.country
|
||||
}`
|
||||
}
|
||||
];
|
||||
|
||||
const cdkColumns = [
|
||||
{
|
||||
title: t("jobs.fields.dms.id"),
|
||||
@@ -117,13 +202,13 @@ export function DmsCustomerSelector({ bodyshop }) {
|
||||
</div>
|
||||
)}
|
||||
pagination={{ position: "top" }}
|
||||
columns={dmsType === "cdk" ? cdkColumns : pbsColumns}
|
||||
rowKey={(record) => (dmsType === "cdk" ? record.id.value : record.ContactId)}
|
||||
columns={dmsType === "cdk" ? (Fortellis.treatment === "on" ? fortellisColumns : cdkColumns) : pbsColumns}
|
||||
rowKey={(record) => (dmsType === "cdk" ? record.id?.value || record.customerId : record.ContactId)}
|
||||
dataSource={customerList}
|
||||
//onChange={handleTableChange}
|
||||
rowSelection={{
|
||||
onSelect: (record) => {
|
||||
setSelectedCustomer(dmsType === "cdk" ? record.id.value : record.ContactId);
|
||||
setSelectedCustomer(dmsType === "cdk" ? record.id?.value || record.customerId : record.ContactId);
|
||||
},
|
||||
type: "radio",
|
||||
selectedRowKeys: [selectedCustomer]
|
||||
|
||||
@@ -26,6 +26,8 @@ import DmsCdkMakesRefetch from "../dms-cdk-makes/dms-cdk-makes.refetch.component
|
||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
import { useSocket } from "../../contexts/SocketIO/useSocket";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop
|
||||
@@ -36,8 +38,17 @@ const mapDispatchToProps = () => ({
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DmsPostForm);
|
||||
|
||||
export function DmsPostForm({ bodyshop, socket, job, logsRef }) {
|
||||
const {
|
||||
treatments: { Fortellis }
|
||||
} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["Fortellis"],
|
||||
splitKey: bodyshop.imexshopid
|
||||
});
|
||||
|
||||
const [form] = Form.useForm();
|
||||
const { t } = useTranslation();
|
||||
const { socket: wsssocket } = useSocket();
|
||||
|
||||
const handlePayerSelect = (value, index) => {
|
||||
form.setFieldsValue({
|
||||
@@ -58,10 +69,21 @@ export function DmsPostForm({ bodyshop, socket, job, logsRef }) {
|
||||
};
|
||||
|
||||
const handleFinish = (values) => {
|
||||
socket.emit(`${determineDmsType(bodyshop)}-export-job`, {
|
||||
jobid: job.id,
|
||||
txEnvelope: values
|
||||
});
|
||||
//TODO: Add this as a split instead.
|
||||
if (Fortellis.treatment === "on") {
|
||||
wsssocket.emit("fortellis-export-job", {
|
||||
jobid: job.id,
|
||||
txEnvelope: {
|
||||
...values,
|
||||
SubscriptionID: "5b527d7d-baf3-40bc-adae-e7a541e37363" //bodyshop.cdk_dealerid
|
||||
}
|
||||
});
|
||||
} else {
|
||||
socket.emit(`${determineDmsType(bodyshop)}-export-job`, {
|
||||
jobid: job.id,
|
||||
txEnvelope: values
|
||||
});
|
||||
}
|
||||
console.log(logsRef);
|
||||
if (logsRef) {
|
||||
console.log("executing", logsRef);
|
||||
@@ -74,6 +96,16 @@ export function DmsPostForm({ bodyshop, socket, job, logsRef }) {
|
||||
|
||||
return (
|
||||
<Card title={t("jobs.labels.dms.postingform")}>
|
||||
<Button
|
||||
onClick={() =>
|
||||
wsssocket.emit("fortellis-export-job", {
|
||||
txEnvelope: { test: 1, test2: 2, SubscriptionID: "5b527d7d-baf3-40bc-adae-e7a541e37363" },
|
||||
jobid: job.id
|
||||
})
|
||||
}
|
||||
>
|
||||
Test
|
||||
</Button>
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
@@ -151,7 +183,7 @@ export function DmsPostForm({ bodyshop, socket, job, logsRef }) {
|
||||
}
|
||||
]}
|
||||
>
|
||||
<Input disabled />
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="dms_model"
|
||||
@@ -162,14 +194,14 @@ export function DmsPostForm({ bodyshop, socket, job, logsRef }) {
|
||||
}
|
||||
]}
|
||||
>
|
||||
<Input disabled />
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name="inservicedate" label={t("jobs.fields.dms.inservicedate")}>
|
||||
<DateTimePicker isDateOnly />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
<Space>
|
||||
<DmsCdkMakes form={form} socket={socket} job={job} />
|
||||
<DmsCdkMakes form={form} job={job} />
|
||||
<DmsCdkMakesRefetch />
|
||||
<Form.Item name="dms_unsold" label={t("jobs.fields.dms.dms_unsold")} initialValue={false}>
|
||||
<Switch />
|
||||
|
||||
@@ -21,6 +21,8 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import { useSocket } from "../../contexts/SocketIO/useSocket.js";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop
|
||||
@@ -54,6 +56,14 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
||||
const search = queryString.parse(useLocation().search);
|
||||
const { jobId } = search;
|
||||
const notification = useNotification();
|
||||
const {
|
||||
treatments: { Fortellis }
|
||||
} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["Fortellis"],
|
||||
splitKey: bodyshop.imexshopid
|
||||
});
|
||||
const { socket: wsssocket } = useSocket();
|
||||
|
||||
const { loading, error, data } = useQuery(QUERY_JOB_EXPORT_DMS, {
|
||||
variables: { id: jobId },
|
||||
@@ -84,45 +94,75 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
||||
}, [t, setBreadcrumbs, setSelectedHeader]);
|
||||
|
||||
useEffect(() => {
|
||||
socket.on("connect", () => socket.emit("set-log-level", logLevel));
|
||||
socket.on("reconnect", () => {
|
||||
setLogs((logs) => {
|
||||
return [
|
||||
...logs,
|
||||
{
|
||||
timestamp: new Date(),
|
||||
level: "warn",
|
||||
message: "Reconnected to CDK Export Service"
|
||||
}
|
||||
];
|
||||
});
|
||||
});
|
||||
socket.on("connect_error", (err) => {
|
||||
console.log(`connect_error due to ${err}`, err);
|
||||
notification.error({ message: err.message });
|
||||
});
|
||||
socket.on("log-event", (payload) => {
|
||||
setLogs((logs) => {
|
||||
return [...logs, payload];
|
||||
});
|
||||
});
|
||||
socket.on("export-success", (payload) => {
|
||||
notification.success({
|
||||
message: t("jobs.successes.exported")
|
||||
});
|
||||
insertAuditTrail({
|
||||
jobid: payload,
|
||||
operation: AuditTrailMapping.jobexported(),
|
||||
type: "jobexported"
|
||||
});
|
||||
history("/manage/accounting/receivables");
|
||||
});
|
||||
if (Fortellis.treatment === "on") {
|
||||
wsssocket.emit("set-log-level", logLevel);
|
||||
|
||||
if (socket.disconnected) socket.connect();
|
||||
return () => {
|
||||
socket.removeAllListeners();
|
||||
socket.disconnect();
|
||||
};
|
||||
const handleLogEvent = (payload) => {
|
||||
setLogs((logs) => {
|
||||
return [...logs, payload];
|
||||
});
|
||||
};
|
||||
|
||||
const handleExportSuccess = (payload) => {
|
||||
notification.success({
|
||||
message: t("jobs.successes.exported")
|
||||
});
|
||||
insertAuditTrail({
|
||||
jobid: payload,
|
||||
operation: AuditTrailMapping.jobexported(),
|
||||
type: "jobexported"
|
||||
});
|
||||
history("/manage/accounting/receivables");
|
||||
};
|
||||
|
||||
wsssocket.on("fortellis-log-event", handleLogEvent);
|
||||
wsssocket.on("export-success", handleExportSuccess);
|
||||
|
||||
return () => {
|
||||
wsssocket.off("fortellis-log-event", handleLogEvent);
|
||||
wsssocket.off("export-success", handleExportSuccess);
|
||||
};
|
||||
} else {
|
||||
socket.on("connect", () => socket.emit("set-log-level", logLevel));
|
||||
socket.on("reconnect", () => {
|
||||
setLogs((logs) => {
|
||||
return [
|
||||
...logs,
|
||||
{
|
||||
timestamp: new Date(),
|
||||
level: "warn",
|
||||
message: "Reconnected to CDK Export Service"
|
||||
}
|
||||
];
|
||||
});
|
||||
});
|
||||
socket.on("connect_error", (err) => {
|
||||
console.log(`connect_error due to ${err}`, err);
|
||||
notification.error({ message: err.message });
|
||||
});
|
||||
socket.on("log-event", (payload) => {
|
||||
setLogs((logs) => {
|
||||
return [...logs, payload];
|
||||
});
|
||||
});
|
||||
socket.on("export-success", (payload) => {
|
||||
notification.success({
|
||||
message: t("jobs.successes.exported")
|
||||
});
|
||||
insertAuditTrail({
|
||||
jobid: payload,
|
||||
operation: AuditTrailMapping.jobexported(),
|
||||
type: "jobexported"
|
||||
});
|
||||
history("/manage/accounting/receivables");
|
||||
});
|
||||
|
||||
if (socket.disconnected) socket.connect();
|
||||
return () => {
|
||||
socket.removeAllListeners();
|
||||
socket.disconnect();
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
@@ -136,6 +176,9 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
||||
|
||||
return (
|
||||
<div>
|
||||
{Fortellis.treatment === "on" && (
|
||||
<AlertComponent message="Posting to Fortellis" type="warning" showIcon closable />
|
||||
)}
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col md={24} lg={10}>
|
||||
<DmsAllocationsSummary
|
||||
@@ -157,7 +200,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
||||
<DmsPostForm socket={socket} jobId={jobId} job={data && data.jobs_by_pk} logsRef={logsRef} />
|
||||
</Col>
|
||||
|
||||
<DmsCustomerSelector />
|
||||
<DmsCustomerSelector jobid={jobId} />
|
||||
|
||||
<Col span={24}>
|
||||
<div ref={logsRef}>
|
||||
|
||||
0
client/src/utils/determineDMSType.js
Normal file
0
client/src/utils/determineDMSType.js
Normal file
305
fortellis-scratch.js
Normal file
305
fortellis-scratch.js
Normal file
@@ -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();
|
||||
235
fortellis.js
Normal file
235
fortellis.js
Normal file
@@ -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();
|
||||
21
package.json
21
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",
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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}` })
|
||||
|
||||
@@ -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)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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: {}
|
||||
}
|
||||
]
|
||||
: [])
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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)}`);
|
||||
}
|
||||
}
|
||||
|
||||
373
server/fortellis/fortellis-helpers.js
Normal file
373
server/fortellis/fortellis-helpers.js
Normal file
@@ -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
|
||||
};
|
||||
9
server/fortellis/fortellis-logger.js
Normal file
9
server/fortellis/fortellis-logger.js
Normal file
@@ -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;
|
||||
1465
server/fortellis/fortellis.js
Normal file
1465
server/fortellis/fortellis.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
|
||||
116
server/web-sockets/createLogEvent.js
Normal file
116
server/web-sockets/createLogEvent.js
Normal file
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user