Merge remote-tracking branch 'origin/feature/IO-2776-cdk-fortellis' into feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration
This commit is contained in:
47252
VendorsBulk.json
47252
VendorsBulk.json
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
|||||||
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.
|
|
||||||
@@ -5,6 +5,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||||
|
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
currentUser: selectCurrentUser,
|
currentUser: selectCurrentUser,
|
||||||
@@ -18,15 +19,26 @@ export default connect(mapStateToProps, mapDispatchToProps)(DmsCdkMakesRefetch);
|
|||||||
export function DmsCdkMakesRefetch({ currentUser, bodyshop }) {
|
export function DmsCdkMakesRefetch({ currentUser, bodyshop }) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const {
|
||||||
|
treatments: { Fortellis }
|
||||||
|
} = useSplitTreatments({
|
||||||
|
attributes: {},
|
||||||
|
names: ["Fortellis"],
|
||||||
|
splitKey: bodyshop.imexshopid
|
||||||
|
});
|
||||||
|
|
||||||
if (!currentUser.email.includes("@imex.")) return null;
|
if (!currentUser.email.includes("@imex.")) return null;
|
||||||
|
|
||||||
const handleRefetch = async () => {
|
const handleRefetch = async () => {
|
||||||
setLoading(true);
|
try {
|
||||||
await axios.post("/cdk/getvehicles", {
|
setLoading(true);
|
||||||
cdk_dealerid: bodyshop.cdk_dealerid,
|
await axios.post(`cdk${Fortellis.treatment === "on" ? "/fortellis" : ""}/getvehicles`, {
|
||||||
bodyshopid: bodyshop.id
|
cdk_dealerid: bodyshop.cdk_dealerid,
|
||||||
});
|
bodyshopid: bodyshop.id
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -162,12 +162,12 @@ export default function CdkLikePostForm({ bodyshop, socket, job, logsRef, mode }
|
|||||||
<Row gutter={[16, 12]}>
|
<Row gutter={[16, 12]}>
|
||||||
<Col xs={24} sm={12} md={8}>
|
<Col xs={24} sm={12} md={8}>
|
||||||
<Form.Item name="dms_make" label={t("jobs.fields.dms.dms_make")} rules={[{ required: true }]}>
|
<Form.Item name="dms_make" label={t("jobs.fields.dms.dms_make")} rules={[{ required: true }]}>
|
||||||
<Input />
|
<Input disabled />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={12} md={8}>
|
<Col xs={24} sm={12} md={8}>
|
||||||
<Form.Item name="dms_model" label={t("jobs.fields.dms.dms_model")} rules={[{ required: true }]}>
|
<Form.Item name="dms_model" label={t("jobs.fields.dms.dms_model")} rules={[{ required: true }]}>
|
||||||
<Input />
|
<Input disabled />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={12} md={8}>
|
<Col xs={24} sm={12} md={8}>
|
||||||
|
|||||||
@@ -424,10 +424,9 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
|||||||
setLogs([]);
|
setLogs([]);
|
||||||
if (isWssMode(mode)) {
|
if (isWssMode(mode)) {
|
||||||
setActiveLogLevel(logLevel);
|
setActiveLogLevel(logLevel);
|
||||||
} else {
|
|
||||||
activeSocket.disconnect();
|
|
||||||
activeSocket.connect();
|
|
||||||
}
|
}
|
||||||
|
activeSocket.disconnect();
|
||||||
|
activeSocket.connect();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Reconnect
|
Reconnect
|
||||||
|
|||||||
@@ -1,305 +0,0 @@
|
|||||||
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
235
fortellis.js
@@ -1,235 +0,0 @@
|
|||||||
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();
|
|
||||||
@@ -157,7 +157,7 @@ async function QueryJobData(socket, jobid) {
|
|||||||
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
|
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
|
||||||
.request(queries.QUERY_JOBS_FOR_PBS_EXPORT, { id: jobid });
|
.request(queries.QUERY_JOBS_FOR_PBS_EXPORT, { id: jobid });
|
||||||
|
|
||||||
WsLogger.createLogEvent(socket, "DEBUG", `Job data query result ${JSON.stringify(result, null, 2)}`);
|
//WsLogger.createLogEvent(socket, "DEBUG", `Job data query result ${JSON.stringify(result, null, 2)}`);
|
||||||
return result.jobs_by_pk;
|
return result.jobs_by_pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,13 +687,13 @@ async function InsertFailedExportLog(socket, error) {
|
|||||||
const result = await client
|
const result = await client
|
||||||
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
|
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
|
||||||
.request(queries.INSERT_EXPORT_LOG, {
|
.request(queries.INSERT_EXPORT_LOG, {
|
||||||
log: {
|
logs: [{
|
||||||
bodyshopid: socket.JobData.bodyshop.id,
|
bodyshopid: socket.JobData.bodyshop.id,
|
||||||
jobid: socket.JobData.id,
|
jobid: socket.JobData.id,
|
||||||
successful: false,
|
successful: false,
|
||||||
message: JSON.stringify(error),
|
message: JSON.stringify(error),
|
||||||
useremail: socket.user.email
|
useremail: socket.user.email
|
||||||
}
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const queries = require("../graphql-client/queries");
|
|||||||
const CreateFortellisLogEvent = require("../fortellis/fortellis-logger");
|
const CreateFortellisLogEvent = require("../fortellis/fortellis-logger");
|
||||||
const Dinero = require("dinero.js");
|
const Dinero = require("dinero.js");
|
||||||
const _ = require("lodash");
|
const _ = require("lodash");
|
||||||
const WsLogger = require("../web-sockets/createLogEvent")
|
const WsLogger = require("../web-sockets/createLogEvent");
|
||||||
|
|
||||||
const InstanceManager = require("../utils/instanceMgr").default;
|
const InstanceManager = require("../utils/instanceMgr").default;
|
||||||
const { DiscountNotAlreadyCounted } = InstanceManager({
|
const { DiscountNotAlreadyCounted } = InstanceManager({
|
||||||
@@ -14,13 +14,12 @@ const { DiscountNotAlreadyCounted } = InstanceManager({
|
|||||||
|
|
||||||
exports.defaultRoute = async function (req, res) {
|
exports.defaultRoute = async function (req, res) {
|
||||||
try {
|
try {
|
||||||
//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}`);
|
WsLogger.createLogEvent(req, "DEBUG", `Received request to calculate allocations for ${req.body.jobid}`);
|
||||||
const jobData = await QueryJobData(req, req.BearerToken, req.body.jobid);
|
const jobData = await QueryJobData(req, req.BearerToken, req.body.jobid);
|
||||||
return res.status(200).json({ data: calculateAllocations(req, jobData) });
|
return res.status(200).json({ data: calculateAllocations(req, jobData) });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
////console.log(error);
|
|
||||||
WsLogger.createLogEvent(req, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
|
WsLogger.createLogEvent(req, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
|
||||||
|
WsLogger.createLogEvent(req, "ERROR", `Error encountered in CdkCalculateAllocations. ${error.stack}`);
|
||||||
res.status(500).json({ error: `Error encountered in CdkCalculateAllocations. ${error}` });
|
res.status(500).json({ error: `Error encountered in CdkCalculateAllocations. ${error}` });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -30,9 +29,9 @@ exports.default = async function (socket, jobid, isFortellis = false) {
|
|||||||
const jobData = await QueryJobData(socket, "Bearer " + socket.handshake.auth.token, jobid, isFortellis);
|
const jobData = await QueryJobData(socket, "Bearer " + socket.handshake.auth.token, jobid, isFortellis);
|
||||||
return calculateAllocations(socket, jobData, isFortellis);
|
return calculateAllocations(socket, jobData, isFortellis);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
////console.log(error);
|
|
||||||
const loggingFunction = isFortellis ? CreateFortellisLogEvent : WsLogger.createLogEvent;
|
const loggingFunction = isFortellis ? CreateFortellisLogEvent : WsLogger.createLogEvent;
|
||||||
loggingFunction(socket, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
|
loggingFunction(socket, "ERROR", `Error encountered in CdkCalculateAllocations. ${error}`);
|
||||||
|
loggingFunction(socket, "ERROR", `Error encountered in CdkCalculateAllocations. ${error.stack}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ async function QueryJobData(connectionData, token, jobid, isFortellis) {
|
|||||||
loggingFunction(connectionData, "DEBUG", `Querying job data for id ${jobid}`);
|
loggingFunction(connectionData, "DEBUG", `Querying job data for id ${jobid}`);
|
||||||
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
||||||
const result = await client.setHeaders({ Authorization: token }).request(queries.GET_CDK_ALLOCATIONS, { id: jobid });
|
const result = await client.setHeaders({ Authorization: token }).request(queries.GET_CDK_ALLOCATIONS, { id: jobid });
|
||||||
loggingFunction(connectionData, "DEBUG", `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;
|
return result.jobs_by_pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,11 +136,11 @@ function calculateAllocations(connectionData, job, isFortellis) {
|
|||||||
? val.prt_dsmk_m
|
? val.prt_dsmk_m
|
||||||
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
||||||
: Dinero({
|
: Dinero({
|
||||||
amount: Math.round(val.act_price * 100)
|
amount: Math.round(val.act_price * 100)
|
||||||
})
|
})
|
||||||
.multiply(val.part_qty || 0)
|
.multiply(val.part_qty || 0)
|
||||||
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
||||||
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
||||||
: Dinero()
|
: Dinero()
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -199,8 +198,8 @@ function calculateAllocations(connectionData, job, isFortellis) {
|
|||||||
let TicketTotal = Dinero({
|
let TicketTotal = Dinero({
|
||||||
amount: Math.round(
|
amount: Math.round(
|
||||||
ticket.rate *
|
ticket.rate *
|
||||||
(ticket.employee && ticket.employee.flat_rate ? ticket.productivehrs || 0 : ticket.actualhrs || 0) *
|
(ticket.employee && ticket.employee.flat_rate ? ticket.productivehrs || 0 : ticket.actualhrs || 0) *
|
||||||
100
|
100
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
//Add it to the right cost center.
|
//Add it to the right cost center.
|
||||||
@@ -432,37 +431,37 @@ function calculateAllocations(connectionData, job, isFortellis) {
|
|||||||
|
|
||||||
...(job.job_totals.totals.ttl_adjustment
|
...(job.job_totals.totals.ttl_adjustment
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
center: "SUB ADJ",
|
center: "SUB ADJ",
|
||||||
sale: Dinero(job.job_totals.totals.ttl_adjustment),
|
sale: Dinero(job.job_totals.totals.ttl_adjustment),
|
||||||
cost: Dinero(),
|
cost: Dinero(),
|
||||||
profitCenter: {
|
profitCenter: {
|
||||||
name: "SUB ADJ",
|
name: "SUB ADJ",
|
||||||
accountdesc: "SUB ADJ",
|
accountdesc: "SUB ADJ",
|
||||||
accountitem: "SUB ADJ",
|
accountitem: "SUB ADJ",
|
||||||
accountname: "SUB ADJ",
|
accountname: "SUB ADJ",
|
||||||
dms_acctnumber: bodyshop.md_responsibility_centers.ttl_adjustment.dms_acctnumber
|
dms_acctnumber: bodyshop.md_responsibility_centers.ttl_adjustment.dms_acctnumber
|
||||||
},
|
},
|
||||||
costCenter: {}
|
costCenter: {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
...(job.job_totals.totals.ttl_tax_adjustment
|
...(job.job_totals.totals.ttl_tax_adjustment
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
center: "TAX ADJ",
|
center: "TAX ADJ",
|
||||||
sale: Dinero(job.job_totals.totals.ttl_tax_adjustment),
|
sale: Dinero(job.job_totals.totals.ttl_tax_adjustment),
|
||||||
cost: Dinero(),
|
cost: Dinero(),
|
||||||
profitCenter: {
|
profitCenter: {
|
||||||
name: "TAX ADJ",
|
name: "TAX ADJ",
|
||||||
accountdesc: "TAX ADJ",
|
accountdesc: "TAX ADJ",
|
||||||
accountitem: "TAX ADJ",
|
accountitem: "TAX ADJ",
|
||||||
accountname: "TAX ADJ",
|
accountname: "TAX ADJ",
|
||||||
dms_acctnumber: bodyshop.md_responsibility_centers.ttl_tax_adjustment.dms_acctnumber
|
dms_acctnumber: bodyshop.md_responsibility_centers.ttl_tax_adjustment.dms_acctnumber
|
||||||
},
|
},
|
||||||
costCenter: {}
|
costCenter: {}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: [])
|
: [])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ const CdkWsdl = require("./cdk-wsdl").default;
|
|||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
|
|
||||||
const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
|
const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
|
||||||
|
const {
|
||||||
|
MakeFortellisCall,
|
||||||
|
FortellisActions,
|
||||||
|
GetAuthToken,
|
||||||
|
GetDepartmentId
|
||||||
|
} = require("../fortellis/fortellis-helpers");
|
||||||
|
|
||||||
// exports.default = async function (socket, cdk_dealerid) {
|
// exports.default = async function (socket, cdk_dealerid) {
|
||||||
// try {
|
// try {
|
||||||
@@ -105,3 +111,85 @@ async function GetCdkMakes(req, cdk_dealerid) {
|
|||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function GetFortellisMakes(req, cdk_dealerid) {
|
||||||
|
logger.log("fortellis-replace-makes-models", "DEBUG", req.user.email, null, {
|
||||||
|
cdk_dealerid
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
const result = await MakeFortellisCall({
|
||||||
|
...FortellisActions.GetMakeModel,
|
||||||
|
headers: {},
|
||||||
|
redisHelpers: {
|
||||||
|
setSessionTransactionData: () => {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
getSessionTransactionData: () => {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
socket: { emit: () => null },
|
||||||
|
jobid: null,
|
||||||
|
body: {},
|
||||||
|
SubscriptionObject: {
|
||||||
|
SubscriptionID: cdk_dealerid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("fortellis-replace-makes-models-response", "ERROR", req.user.email, null, {
|
||||||
|
cdk_dealerid,
|
||||||
|
xml: result
|
||||||
|
});
|
||||||
|
return result.data;
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("fortellis-replace-makes-models-error", "ERROR", req.user.email, null, {
|
||||||
|
cdk_dealerid,
|
||||||
|
error
|
||||||
|
});
|
||||||
|
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.fortellis = async function ReloadFortellisMakes(req, res) {
|
||||||
|
const { bodyshopid, cdk_dealerid } = req.body;
|
||||||
|
try {
|
||||||
|
//Query all CDK Models
|
||||||
|
const newList = await GetFortellisMakes(req, cdk_dealerid);
|
||||||
|
|
||||||
|
const BearerToken = req.BearerToken;
|
||||||
|
const client = req.userGraphQLClient;
|
||||||
|
|
||||||
|
const deleteResult = await client
|
||||||
|
.setHeaders({ Authorization: BearerToken })
|
||||||
|
.request(queries.DELETE_ALL_DMS_VEHICLES, {});
|
||||||
|
|
||||||
|
//Insert the new ones.
|
||||||
|
|
||||||
|
const insertResult = await client.setHeaders({ Authorization: BearerToken }).request(queries.INSERT_DMS_VEHICLES, {
|
||||||
|
vehicles: newList.map((i) => {
|
||||||
|
return {
|
||||||
|
bodyshopid,
|
||||||
|
makecode: i.makeCode,
|
||||||
|
modelcode: i.modelCode,
|
||||||
|
make: i.makeFullName,
|
||||||
|
model: i.modelFullName
|
||||||
|
};
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.log("fortellis-replace-makes-models-success", "DEBUG", req.user.email, null, {
|
||||||
|
cdk_dealerid,
|
||||||
|
count: newList.length
|
||||||
|
});
|
||||||
|
|
||||||
|
res.sendStatus(200);
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("fortellis-replace-makes-models-error", "ERROR", req.user.email, null, {
|
||||||
|
cdk_dealerid,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
res.status(500).json(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ async function QueryJobData(socket, jobid) {
|
|||||||
.setHeaders({ Authorization: `Bearer ${currentToken}` })
|
.setHeaders({ Authorization: `Bearer ${currentToken}` })
|
||||||
.request(queries.QUERY_JOBS_FOR_CDK_EXPORT, { id: jobid });
|
.request(queries.QUERY_JOBS_FOR_CDK_EXPORT, { id: jobid });
|
||||||
|
|
||||||
WsLogger.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;
|
return result.jobs_by_pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -993,13 +993,13 @@ async function InsertFailedExportLog(socket, error) {
|
|||||||
const result = await client
|
const result = await client
|
||||||
.setHeaders({ Authorization: `Bearer ${currentToken}` })
|
.setHeaders({ Authorization: `Bearer ${currentToken}` })
|
||||||
.request(queries.INSERT_EXPORT_LOG, {
|
.request(queries.INSERT_EXPORT_LOG, {
|
||||||
log: {
|
logs: [{
|
||||||
bodyshopid: socket.JobData.bodyshop.id,
|
bodyshopid: socket.JobData.bodyshop.id,
|
||||||
jobid: socket.JobData.id,
|
jobid: socket.JobData.id,
|
||||||
successful: false,
|
successful: false,
|
||||||
message: JSON.stringify(error),
|
message: JSON.stringify(error),
|
||||||
useremail: socket.user.email
|
useremail: socket.user.email
|
||||||
}
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ const logger = require("../utils/logger");
|
|||||||
const uuid = require("uuid").v4;
|
const uuid = require("uuid").v4;
|
||||||
const AxiosLib = require("axios").default;
|
const AxiosLib = require("axios").default;
|
||||||
const axios = AxiosLib.create();
|
const axios = AxiosLib.create();
|
||||||
const axiosCurlirize = require('axios-curlirize').default;
|
const axiosCurlirize = require("axios-curlirize").default;
|
||||||
|
|
||||||
// Custom error class for Fortellis API errors
|
// Custom error class for Fortellis API errors
|
||||||
class FortellisApiError extends Error {
|
class FortellisApiError extends Error {
|
||||||
constructor(message, details) {
|
constructor(message, details) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = 'FortellisApiError';
|
this.name = "FortellisApiError";
|
||||||
this.reqId = details.reqId;
|
this.reqId = details.reqId;
|
||||||
this.url = details.url;
|
this.url = details.url;
|
||||||
this.apiName = details.apiName;
|
this.apiName = details.apiName;
|
||||||
@@ -26,14 +26,8 @@ class FortellisApiError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
axiosCurlirize(axios, (result, err) => {
|
axiosCurlirize(axios, (_result, _err) => {
|
||||||
const { command } = result;
|
//Left intentionally blank. We don't want to console.log. We handle logging the cURL in MakeFortellisCall once completed.
|
||||||
console.log("*** ~ axiosCurlirize ~ command:", command);
|
|
||||||
|
|
||||||
// if (err) {
|
|
||||||
// use your logger here
|
|
||||||
// } else {
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const getTransactionType = (jobid) => `fortellis:${jobid}`;
|
const getTransactionType = (jobid) => `fortellis:${jobid}`;
|
||||||
@@ -63,12 +57,14 @@ async function GetAuthToken() {
|
|||||||
return access_token;
|
return access_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function FetchSubscriptions({ redisHelpers, socket, jobid }) {
|
async function FetchSubscriptions({ redisHelpers, socket, jobid, SubscriptionObject }) {
|
||||||
try {
|
try {
|
||||||
const { setSessionTransactionData, getSessionTransactionData } = redisHelpers;
|
const { setSessionTransactionData, getSessionTransactionData } = redisHelpers;
|
||||||
|
|
||||||
//Get Subscription ID from Transaction Envelope
|
//Get Subscription ID from Transaction Envelope
|
||||||
const { SubscriptionID } = await getSessionTransactionData(socket.id, getTransactionType(jobid), `txEnvelope`);
|
const { SubscriptionID } = SubscriptionObject
|
||||||
|
? SubscriptionObject
|
||||||
|
: await getSessionTransactionData(socket.id, getTransactionType(jobid), `txEnvelope`);
|
||||||
if (!SubscriptionID) {
|
if (!SubscriptionID) {
|
||||||
throw new Error("Subscription ID not found in transaction envelope.");
|
throw new Error("Subscription ID not found in transaction envelope.");
|
||||||
}
|
}
|
||||||
@@ -85,17 +81,20 @@ async function FetchSubscriptions({ redisHelpers, socket, jobid }) {
|
|||||||
return SubscriptionMetaFromCache;
|
return SubscriptionMetaFromCache;
|
||||||
} else {
|
} else {
|
||||||
const access_token = await GetAuthToken();
|
const access_token = await GetAuthToken();
|
||||||
const subscriptions = await axios.get(`https://subscriptions.fortellis.io/v1/solution/subscriptions`, {
|
const subscriptions = await axios.get(FortellisActions.GetSubscription.url, {
|
||||||
headers: { Authorization: `Bearer ${access_token}` }
|
headers: { Authorization: `Bearer ${access_token}` },
|
||||||
|
logRequest: false
|
||||||
});
|
});
|
||||||
const SubscriptionMeta = subscriptions.data.subscriptions.find((s) => s.subscriptionId === SubscriptionID);
|
const SubscriptionMeta = subscriptions.data.subscriptions.find((s) => s.subscriptionId === SubscriptionID);
|
||||||
await setSessionTransactionData(
|
if (setSessionTransactionData) {
|
||||||
socket.id,
|
await setSessionTransactionData(
|
||||||
getTransactionType(jobid),
|
socket.id,
|
||||||
FortellisCacheEnums.SubscriptionMeta,
|
getTransactionType(jobid),
|
||||||
SubscriptionMeta,
|
FortellisCacheEnums.SubscriptionMeta,
|
||||||
defaultFortellisTTL
|
SubscriptionMeta,
|
||||||
);
|
defaultFortellisTTL
|
||||||
|
);
|
||||||
|
}
|
||||||
return SubscriptionMeta;
|
return SubscriptionMeta;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -106,25 +105,24 @@ async function FetchSubscriptions({ redisHelpers, socket, jobid }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function GetDepartmentId({ apiName, debug = false, SubscriptionMeta }) {
|
async function GetDepartmentId({ apiName, debug = false, SubscriptionMeta, overrideDepartmentId }) {
|
||||||
if (!apiName) throw new Error("apiName not provided. Unable to get department without apiName.");
|
if (!apiName) throw new Error("apiName not provided. Unable to get department without apiName.");
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log("API Names & Departments ");
|
console.log("API Names & Departments ");
|
||||||
console.log("===========");
|
console.log("===========");
|
||||||
console.log(
|
console.log(JSON.stringify(SubscriptionMeta.apiDmsInfo, null, 4));
|
||||||
JSON.stringify(
|
|
||||||
SubscriptionMeta.apiDmsInfo,
|
|
||||||
null,
|
|
||||||
4
|
|
||||||
)
|
|
||||||
);
|
|
||||||
console.log("===========");
|
console.log("===========");
|
||||||
}
|
}
|
||||||
//TODO: Verify how to select the correct department.
|
|
||||||
const departmentIds2 = SubscriptionMeta.apiDmsInfo //Get the subscription object.
|
const departmentIds = SubscriptionMeta.apiDmsInfo //Get the subscription object.
|
||||||
.find((info) => info.name === apiName)?.departments; //Departments are categorized by API name and have an array of departments.
|
.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.
|
if (overrideDepartmentId) {
|
||||||
|
return departmentIds && departmentIds.find(d => d.id === overrideDepartmentId)?.id
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return departmentIds && departmentIds[0] && departmentIds[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.
|
//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.
|
||||||
@@ -134,22 +132,23 @@ async function MakeFortellisCall({
|
|||||||
headers = {},
|
headers = {},
|
||||||
body = {},
|
body = {},
|
||||||
type = "post",
|
type = "post",
|
||||||
debug = true,
|
debug = false,
|
||||||
requestPathParams,
|
requestPathParams,
|
||||||
requestSearchParams = [], //Array of key/value strings like [["key", "value"]]
|
requestSearchParams = [], //Array of key/value strings like [["key", "value"]]
|
||||||
jobid,
|
jobid,
|
||||||
redisHelpers,
|
redisHelpers,
|
||||||
socket,
|
socket,
|
||||||
|
SubscriptionObject, //This is used because of the get make models to bypass all of the redis calls.
|
||||||
|
overrideDepartmentId
|
||||||
}) {
|
}) {
|
||||||
const { setSessionTransactionData, getSessionTransactionData } = redisHelpers;
|
//const { setSessionTransactionData, getSessionTransactionData } = redisHelpers;
|
||||||
|
|
||||||
const fullUrl = constructFullUrl({ url, pathParams: requestPathParams, requestSearchParams });
|
const fullUrl = constructFullUrl({ url, pathParams: requestPathParams, requestSearchParams });
|
||||||
|
if (debug) console.log(`Executing ${type} to ${fullUrl}`);
|
||||||
if (debug) logger.log(`Executing ${type} to ${fullUrl}`);
|
|
||||||
const ReqId = uuid();
|
const ReqId = uuid();
|
||||||
const access_token = await GetAuthToken();
|
const access_token = await GetAuthToken();
|
||||||
const SubscriptionMeta = await FetchSubscriptions({ redisHelpers, socket, jobid });
|
const SubscriptionMeta = await FetchSubscriptions({ redisHelpers, socket, jobid, SubscriptionObject });
|
||||||
const DepartmentId = await GetDepartmentId({ apiName, debug, SubscriptionMeta });
|
const DepartmentId = await GetDepartmentId({ apiName, debug, SubscriptionMeta, overrideDepartmentId });
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
console.log(
|
console.log(
|
||||||
@@ -168,7 +167,9 @@ async function MakeFortellisCall({
|
|||||||
Authorization: `Bearer ${access_token}`,
|
Authorization: `Bearer ${access_token}`,
|
||||||
"Subscription-Id": SubscriptionMeta.subscriptionId,
|
"Subscription-Id": SubscriptionMeta.subscriptionId,
|
||||||
"Request-Id": ReqId,
|
"Request-Id": ReqId,
|
||||||
...DepartmentId && { "Department-Id": DepartmentId },
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
...(DepartmentId && { "Department-Id": DepartmentId }),
|
||||||
...headers
|
...headers
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -179,6 +180,7 @@ async function MakeFortellisCall({
|
|||||||
Authorization: `Bearer ${access_token}`,
|
Authorization: `Bearer ${access_token}`,
|
||||||
"Subscription-Id": SubscriptionMeta.subscriptionId,
|
"Subscription-Id": SubscriptionMeta.subscriptionId,
|
||||||
"Request-Id": ReqId,
|
"Request-Id": ReqId,
|
||||||
|
Accept: "application/json",
|
||||||
"Department-Id": DepartmentId,
|
"Department-Id": DepartmentId,
|
||||||
...headers
|
...headers
|
||||||
}
|
}
|
||||||
@@ -190,6 +192,8 @@ async function MakeFortellisCall({
|
|||||||
Authorization: `Bearer ${access_token}`,
|
Authorization: `Bearer ${access_token}`,
|
||||||
"Subscription-Id": SubscriptionMeta.subscriptionId,
|
"Subscription-Id": SubscriptionMeta.subscriptionId,
|
||||||
"Request-Id": ReqId,
|
"Request-Id": ReqId,
|
||||||
|
Accept: "application/json",
|
||||||
|
"Content-Type": "application/json",
|
||||||
"Department-Id": DepartmentId,
|
"Department-Id": DepartmentId,
|
||||||
...headers
|
...headers
|
||||||
}
|
}
|
||||||
@@ -211,11 +215,23 @@ async function MakeFortellisCall({
|
|||||||
departmentIds: DepartmentId
|
departmentIds: DepartmentId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.log(
|
||||||
|
"fortellis-log-event-json",
|
||||||
|
"DEBUG",
|
||||||
|
socket?.user?.email,
|
||||||
|
jobid,
|
||||||
|
{
|
||||||
|
requestcurl: result.config.curlCommand,
|
||||||
|
reqid: result.config.headers["Request-Id"] || null,
|
||||||
|
subscriptionId: result.config.headers["Subscription-Id"] || null,
|
||||||
|
resultdata: result.data,
|
||||||
|
resultStatus: result.status
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return result.data;
|
return result.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`ReqID: ${ReqId} Error`, error.response?.data);
|
|
||||||
//console.log(`ReqID: ${ReqId} Full Error`, JSON.stringify(error, null, 4));
|
|
||||||
|
|
||||||
const errorDetails = {
|
const errorDetails = {
|
||||||
reqId: ReqId,
|
reqId: ReqId,
|
||||||
url: fullUrl,
|
url: fullUrl,
|
||||||
@@ -226,12 +242,20 @@ async function MakeFortellisCall({
|
|||||||
originalError: error
|
originalError: error
|
||||||
};
|
};
|
||||||
|
|
||||||
// CreateFortellisLogEvent(socket, "ERROR", `Error in MakeFortellisCall for ${apiName}: ${error.message}`, {
|
logger.log(
|
||||||
// ...errorDetails,
|
"fortellis-log-event-error",
|
||||||
// errorStack: error.stack
|
"ERROR",
|
||||||
// });
|
socket?.user?.email,
|
||||||
|
socket?.recordid,
|
||||||
|
{
|
||||||
|
wsmessage: "",//message,
|
||||||
|
curl: error.config.curl.curlCommand,
|
||||||
|
reqid: error.request.headers["Request-Id"] || null,
|
||||||
|
subscriptionId: error.request.headers["Subscription-Id"] || null,
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
// Throw custom error with all the details
|
|
||||||
throw new FortellisApiError(`Fortellis API call failed for ${apiName}: ${error.message}`, errorDetails);
|
throw new FortellisApiError(`Fortellis API call failed for ${apiName}: ${error.message}`, errorDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,7 +299,15 @@ function sleep(ms) {
|
|||||||
|
|
||||||
const isProduction = process.env.NODE_ENV === "production";
|
const isProduction = process.env.NODE_ENV === "production";
|
||||||
|
|
||||||
|
//Get requests should have the trailing slash as they are used that way in the calls.
|
||||||
const FortellisActions = {
|
const FortellisActions = {
|
||||||
|
GetSubscription: {
|
||||||
|
url: isProduction
|
||||||
|
? "https://subscriptions.fortellis.io/v1/solution/subscriptions"
|
||||||
|
: "https://subscriptions.fortellis.io/v1/solution/subscriptions",
|
||||||
|
type: "get",
|
||||||
|
apiName: "Fortellis Get Subscriptions"
|
||||||
|
},
|
||||||
QueryVehicles: {
|
QueryVehicles: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdkdrive/service/v1/vehicles/"
|
? "https://api.fortellis.io/cdkdrive/service/v1/vehicles/"
|
||||||
@@ -283,54 +315,61 @@ const FortellisActions = {
|
|||||||
type: "get",
|
type: "get",
|
||||||
apiName: "Service Vehicle - Query Vehicles"
|
apiName: "Service Vehicle - Query Vehicles"
|
||||||
},
|
},
|
||||||
|
GetMakeModel: {
|
||||||
|
url: isProduction
|
||||||
|
? "https://api.fortellis.io/cdk/drive/makemodel/v2/bulk"
|
||||||
|
: "https://api.fortellis.io/cdk-test/drive/makemodel/v2",
|
||||||
|
type: "get",
|
||||||
|
apiName: "CDK Drive Get Make Model Lite"
|
||||||
|
},
|
||||||
GetVehicleId: {
|
GetVehicleId: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/vehicle-ids/" //Request path params of vins
|
? "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/",
|
: "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/vehicle-ids/",
|
||||||
type: "get",
|
type: "get",
|
||||||
apiName: "CDK Drive Post Service Vehicle",
|
apiName: "CDK Drive Post Service Vehicle"
|
||||||
},
|
},
|
||||||
GetVehicleById: {
|
GetVehicleById: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/" //Request path params of vehicleId
|
? "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/",
|
: "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
|
||||||
type: "get",
|
type: "get",
|
||||||
apiName: "CDK Drive Post Service Vehicle",
|
apiName: "CDK Drive Post Service Vehicle"
|
||||||
},
|
},
|
||||||
QueryCustomerByName: {
|
QueryCustomerByName: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/customerpost/v1/search"
|
? "https://api.fortellis.io/cdk/drive/customerpost/v1/search"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/customerpost/v1/search",
|
: "https://api.fortellis.io/cdk-test/drive/customerpost/v1/search",
|
||||||
type: "get",
|
type: "get",
|
||||||
apiName: "CDK Drive Post Customer",
|
apiName: "CDK Drive Post Customer"
|
||||||
},
|
},
|
||||||
ReadCustomer: {
|
ReadCustomer: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/customerpost/v1/" //Customer ID is request param.
|
? "https://api.fortellis.io/cdk/drive/customerpost/v1/" //Customer ID is request param.
|
||||||
: "https://api.fortellis.io/cdk-test/drive/customerpost/v1/",
|
: "https://api.fortellis.io/cdk-test/drive/customerpost/v1/",
|
||||||
type: "get",
|
type: "get",
|
||||||
apiName: "CDK Drive Post Customer",
|
apiName: "CDK Drive Post Customer"
|
||||||
},
|
},
|
||||||
CreateCustomer: {
|
CreateCustomer: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/customerpost/v1/"
|
? "https://api.fortellis.io/cdk/drive/customerpost/v1/"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/customerpost/v1/",
|
: "https://api.fortellis.io/cdk-test/drive/customerpost/v1/",
|
||||||
type: "post",
|
type: "post",
|
||||||
apiName: "CDK Drive Post Customer",
|
apiName: "CDK Drive Post Customer"
|
||||||
},
|
},
|
||||||
InsertVehicle: {
|
InsertVehicle: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/"
|
? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
|
: "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
|
||||||
type: "post",
|
type: "post",
|
||||||
apiName: "CDK Drive Post Service Vehicle",
|
apiName: "CDK Drive Post Service Vehicle"
|
||||||
},
|
},
|
||||||
UpdateVehicle: {
|
UpdateVehicle: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/"
|
? "https://api.fortellis.io/cdk/drive/service-vehicle-mgmt/v2/"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
|
: "https://api.fortellis.io/cdk-test/drive/service-vehicle-mgmt/v2/",
|
||||||
type: "put",
|
type: "put",
|
||||||
apiName: "CDK Drive Post Service Vehicle",
|
apiName: "CDK Drive Post Service Vehicle"
|
||||||
},
|
},
|
||||||
GetCOA: {
|
GetCOA: {
|
||||||
type: "get",
|
type: "get",
|
||||||
@@ -343,37 +382,43 @@ const FortellisActions = {
|
|||||||
? "https://api.fortellis.io/cdk/drive/glpost/startWIP"
|
? "https://api.fortellis.io/cdk/drive/glpost/startWIP"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/glpost/startWIP",
|
: "https://api.fortellis.io/cdk-test/drive/glpost/startWIP",
|
||||||
type: "post",
|
type: "post",
|
||||||
apiName: "CDK Drive Post Accounting GL",
|
apiName: "CDK Drive Post Accounts GL"
|
||||||
},
|
},
|
||||||
TranBatchWip: {
|
TranBatchWip: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/glpost/transBatchWIP"
|
? "https://api.fortellis.io/cdk/drive/glpost/transBatchWIP"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/glpost/transBatchWIP",
|
: "https://api.fortellis.io/cdk-test/drive/glpost/transBatchWIP",
|
||||||
type: "post",
|
type: "post",
|
||||||
apiName: "CDK Drive Post Accounting GL",
|
apiName: "CDK Drive Post Accounts GL"
|
||||||
},
|
},
|
||||||
PostBatchWip: {
|
PostBatchWip: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/glpost/postBatchWIP"
|
? "https://api.fortellis.io/cdk/drive/glpost/postBatchWIP"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/glpost/postBatchWIP",
|
: "https://api.fortellis.io/cdk-test/drive/glpost/postBatchWIP",
|
||||||
type: "post",
|
type: "post",
|
||||||
apiName: "CDK Drive Post Accounting GL",
|
apiName: "CDK Drive Post Accounts GL"
|
||||||
|
},
|
||||||
|
DeleteTranWip: {
|
||||||
|
url: isProduction
|
||||||
|
? "https://api.fortellis.io/cdk/drive/glpost/postWIP"
|
||||||
|
: "https://api.fortellis.io/cdk-test/drive/glpost/postWIP",
|
||||||
|
type: "post",
|
||||||
|
apiName: "CDK Drive Post Accounts GL"
|
||||||
},
|
},
|
||||||
QueryErrorWip: {
|
QueryErrorWip: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/glpost/errWIP"
|
? "https://api.fortellis.io/cdk/drive/glpost/errWIP/"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/glpost/errWIP",
|
: "https://api.fortellis.io/cdk-test/drive/glpost/errWIP/",
|
||||||
type: "get",
|
type: "get",
|
||||||
apiName: "CDK Drive Post Accounting GL",
|
apiName: "CDK Drive Post Accounts GL"
|
||||||
},
|
},
|
||||||
ServiceHistoryInsert: {
|
ServiceHistoryInsert: {
|
||||||
url: isProduction
|
url: isProduction
|
||||||
? "https://api.fortellis.io/cdk/drive/post/service-vehicle-history-mgmt/v2/"
|
? "https://api.fortellis.io/cdk/drive/post/service-vehicle-history-mgmt/v2/"
|
||||||
: "https://api.fortellis.io/cdk-test/drive/post/service-vehicle-history-mgmt/v2/",
|
: "https://api.fortellis.io/cdk-test/drive/post/service-vehicle-history-mgmt/v2/",
|
||||||
type: "post",
|
type: "post",
|
||||||
apiName: "CDK Drive Post Service Vehicle History",
|
apiName: "CDK Drive Post Service Vehicle History"
|
||||||
},
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FortellisCacheEnums = {
|
const FortellisCacheEnums = {
|
||||||
@@ -391,7 +436,7 @@ const FortellisCacheEnums = {
|
|||||||
DMSTransHeader: "DMSTransHeader",
|
DMSTransHeader: "DMSTransHeader",
|
||||||
transWips: "transWips",
|
transWips: "transWips",
|
||||||
DmsBatchTxnPost: "DmsBatchTxnPost",
|
DmsBatchTxnPost: "DmsBatchTxnPost",
|
||||||
DMSVehHistory: "DMSVehHistory",
|
DMSVehHistory: "DMSVehHistory"
|
||||||
};
|
};
|
||||||
|
|
||||||
function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) {
|
function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) {
|
||||||
@@ -403,8 +448,6 @@ function constructFullUrl({ url, pathParams = "", requestSearchParams = [] }) {
|
|||||||
return fullUrl;
|
return fullUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
GetAuthToken,
|
GetAuthToken,
|
||||||
FortellisCacheEnums,
|
FortellisCacheEnums,
|
||||||
@@ -412,5 +455,6 @@ module.exports = {
|
|||||||
FortellisActions,
|
FortellisActions,
|
||||||
getTransactionType,
|
getTransactionType,
|
||||||
defaultFortellisTTL,
|
defaultFortellisTTL,
|
||||||
FortellisApiError
|
FortellisApiError,
|
||||||
|
GetDepartmentId
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
|
|
||||||
const CreateFortellisLogEvent = (socket, level, message, txnDetails) => {
|
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 });
|
logger.log("fortellis-log-event", level, socket?.user?.email, null, { wsmessage: message, txnDetails });
|
||||||
socket.emit("fortellis-log-event", { level, message, txnDetails });
|
socket.emit("fortellis-log-event", { level, message, txnDetails });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ async function FortellisJobExport({ socket, redisHelpers, txEnvelope, jobid }) {
|
|||||||
defaultFortellisTTL
|
defaultFortellisTTL
|
||||||
);
|
);
|
||||||
|
|
||||||
//TODO: Need to remove unnecessary stuff here to reduce the payload.
|
|
||||||
const JobData = await QueryJobData({ socket, jobid });
|
const JobData = await QueryJobData({ socket, jobid });
|
||||||
|
|
||||||
await setSessionTransactionData(
|
await setSessionTransactionData(
|
||||||
@@ -252,83 +251,70 @@ async function FortellisSelectedCustomer({ socket, redisHelpers, selectedCustome
|
|||||||
|
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{5.1} Creating Transaction with ID ${DMSTransHeader.transID}`);
|
CreateFortellisLogEvent(socket, "DEBUG", `{5.1} Creating Transaction with ID ${DMSTransHeader.transID}`);
|
||||||
|
|
||||||
const DMSBatchTxn = await InsertDmsBatchWip({ socket, redisHelpers, JobData });
|
if (DMSTransHeader.rtnCode === "0") {
|
||||||
await setSessionTransactionData(
|
try {
|
||||||
socket.id,
|
CreateFortellisLogEvent(socket, "DEBUG", `{6} Attempting to post Transaction with ID ${DMSTransHeader.transID}`);
|
||||||
getTransactionType(jobid),
|
|
||||||
FortellisCacheEnums.DMSBatchTxn,
|
|
||||||
DMSBatchTxn,
|
|
||||||
defaultFortellisTTL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (DMSBatchTxn.rtnCode === "0") {
|
const DmsBatchTxnPost = await PostDmsBatchWip({ socket, redisHelpers, JobData }); // 2 in 1 call that includes a post and the transactions.
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{6} Attempting to post Transaction with ID ${DMSTransHeader.transID}`);
|
|
||||||
|
|
||||||
const DmsBatchTxnPost = await PostDmsBatchWip({ socket, redisHelpers, JobData });
|
|
||||||
await setSessionTransactionData(
|
|
||||||
socket.id,
|
|
||||||
getTransactionType(jobid),
|
|
||||||
FortellisCacheEnums.DmsBatchTxnPost,
|
|
||||||
DmsBatchTxnPost,
|
|
||||||
defaultFortellisTTL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (DmsBatchTxnPost.rtnCode === "0") {
|
|
||||||
//TODO: Validate this is a string and not #
|
|
||||||
//something
|
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{6} Successfully posted transaction to DMS.`);
|
|
||||||
|
|
||||||
await MarkJobExported({ socket, jobid: JobData.id });
|
|
||||||
|
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`);
|
|
||||||
const DMSVehHistory = await InsertServiceVehicleHistory({ socket, redisHelpers, JobData });
|
|
||||||
await setSessionTransactionData(
|
await setSessionTransactionData(
|
||||||
socket.id,
|
socket.id,
|
||||||
getTransactionType(jobid),
|
getTransactionType(jobid),
|
||||||
FortellisCacheEnums.DMSVehHistory,
|
FortellisCacheEnums.DmsBatchTxnPost,
|
||||||
DMSVehHistory,
|
DmsBatchTxnPost,
|
||||||
defaultFortellisTTL
|
defaultFortellisTTL
|
||||||
);
|
);
|
||||||
socket.emit("export-success", JobData.id);
|
|
||||||
} else {
|
|
||||||
//Get the error code
|
if (DmsBatchTxnPost.rtnCode === "0") {
|
||||||
|
//TODO: Validate this is a string and not #
|
||||||
|
//something
|
||||||
|
CreateFortellisLogEvent(socket, "DEBUG", `{6} Successfully posted transaction to DMS.`);
|
||||||
|
|
||||||
|
await MarkJobExported({ socket, jobid: JobData.id, JobData });
|
||||||
|
|
||||||
|
CreateFortellisLogEvent(socket, "DEBUG", `{5} Updating Service Vehicle History.`);
|
||||||
|
const DMSVehHistory = await InsertServiceVehicleHistory({ socket, redisHelpers, JobData });
|
||||||
|
await setSessionTransactionData(
|
||||||
|
socket.id,
|
||||||
|
getTransactionType(jobid),
|
||||||
|
FortellisCacheEnums.DMSVehHistory,
|
||||||
|
DMSVehHistory,
|
||||||
|
defaultFortellisTTL
|
||||||
|
);
|
||||||
|
socket.emit("export-success", JobData.id);
|
||||||
|
} else {
|
||||||
|
//There was something wrong. Throw an error to trigger clean up.
|
||||||
|
throw new Error("Error posting DMS Batch Transaction");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
//Clean up the transaction and insert a faild error code
|
||||||
|
// //Get the error code
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{6.1} Getting errors for Transaction ID ${DMSTransHeader.transID}`);
|
CreateFortellisLogEvent(socket, "DEBUG", `{6.1} Getting errors for Transaction ID ${DMSTransHeader.transID}`);
|
||||||
|
|
||||||
await QueryDmsErrWip({ socket, redisHelpers, JobData });
|
await QueryDmsErrWip({ socket, redisHelpers, JobData });
|
||||||
|
|
||||||
const DmsError = await QueryDmsErrWip({ socket, redisHelpers, JobData });
|
const DmsError = await QueryDmsErrWip({ socket, redisHelpers, JobData });
|
||||||
|
// //Delete the transaction
|
||||||
|
CreateFortellisLogEvent(socket, "DEBUG", `{6.2} Deleting Transaction ID ${DMSTransHeader.transID}`);
|
||||||
|
|
||||||
//Delete the transaction
|
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{{ 6.2 } Deleting Transaction ID ${socket.DMSTransHeader.transID}`);
|
|
||||||
|
|
||||||
// Delete DMS Wip
|
|
||||||
await DeleteDmsWip({ socket, redisHelpers, JobData });
|
await DeleteDmsWip({ socket, redisHelpers, JobData });
|
||||||
|
|
||||||
DmsError.errMsg
|
DmsError.errLine.map(
|
||||||
.split("|")
|
(e) =>
|
||||||
.map(
|
e !== null &&
|
||||||
(e) =>
|
e !== "" &&
|
||||||
e !== null &&
|
CreateFortellisLogEvent(socket, "ERROR", `Error encountered in posting transaction => ${e} `)
|
||||||
e !== "" &&
|
);
|
||||||
CreateFortellisLogEvent(socket, "ERROR", `Error(s) encountered in posting transaction.${e} `)
|
await InsertFailedExportLog({
|
||||||
);
|
socket,
|
||||||
|
JobData,
|
||||||
|
error: DmsError.errLine
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
//Posting transaction failed.
|
|
||||||
CreateFortellisLogEvent(
|
|
||||||
socket,
|
|
||||||
"ERROR",
|
|
||||||
`DMS Batch Return code was not successful: ${DMSBatchTxn.rtnCode} - ${DMSBatchTxn.sendline}`
|
|
||||||
);
|
|
||||||
|
|
||||||
await InsertFailedExportLog({
|
|
||||||
socket,
|
|
||||||
JobData,
|
|
||||||
error: `DMS Batch Return code was not successful: ${DMSBatchTxn.rtnCode} - ${DMSBatchTxn.sendline}`
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// CdkBase.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer.${ error } `);
|
|
||||||
CreateFortellisLogEvent(socket, "ERROR", `Error in FortellisSelectedCustomer - ${error} `, {
|
CreateFortellisLogEvent(socket, "ERROR", `Error in FortellisSelectedCustomer - ${error} `, {
|
||||||
error: error.message,
|
error: error.message,
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
@@ -369,7 +355,7 @@ async function CalculateDmsVid({ socket, JobData, redisHelpers }) {
|
|||||||
vin: JobData.v_vin,
|
vin: JobData.v_vin,
|
||||||
jobId: JobData.id
|
jobId: JobData.id
|
||||||
});
|
});
|
||||||
throw error; // Re-throw to maintain existing error handling flow
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,12 +406,9 @@ async function QueryDmsCustomerByName({ socket, redisHelpers, JobData }) {
|
|||||||
JobData.ownr_co_nm && JobData.ownr_co_nm.trim() !== ""
|
JobData.ownr_co_nm && JobData.ownr_co_nm.trim() !== ""
|
||||||
? [["lastName", JobData.ownr_co_nm.replace(replaceSpecialRegex, "")]]
|
? [["lastName", JobData.ownr_co_nm.replace(replaceSpecialRegex, "")]]
|
||||||
: [
|
: [
|
||||||
["firstName", JobData.ownr_fn.replace(replaceSpecialRegex, "")],
|
["firstName", JobData.ownr_fn.replace(replaceSpecialRegex, "")],
|
||||||
["lastName", JobData.ownr_ln.replace(replaceSpecialRegex, "")]
|
["lastName", JobData.ownr_ln.replace(replaceSpecialRegex, "")]
|
||||||
];
|
];
|
||||||
|
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `Begin query DMS Customer by Name using ${JSON.stringify(ownerName)} `);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await MakeFortellisCall({
|
const result = await MakeFortellisCall({
|
||||||
...FortellisActions.QueryCustomerByName,
|
...FortellisActions.QueryCustomerByName,
|
||||||
@@ -526,18 +509,18 @@ async function InsertDmsCustomer({ socket, redisHelpers, JobData }) {
|
|||||||
emailAddresses: [
|
emailAddresses: [
|
||||||
...(!_.isEmpty(JobData.ownr_ea)
|
...(!_.isEmpty(JobData.ownr_ea)
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
//"uuid": "",
|
//"uuid": "",
|
||||||
address: JobData.ownr_ea,
|
address: JobData.ownr_ea,
|
||||||
type: "PERSONAL"
|
type: "PERSONAL"
|
||||||
// "doNotEmailSource": "",
|
// "doNotEmailSource": "",
|
||||||
// "doNotEmail": false,
|
// "doNotEmail": false,
|
||||||
// "isPreferred": true,
|
// "isPreferred": true,
|
||||||
// "transactionEmailNotificationOptIn": false,
|
// "transactionEmailNotificationOptIn": false,
|
||||||
// "optInRequestDate": null,
|
// "optInRequestDate": null,
|
||||||
// "optInDate": null
|
// "optInDate": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: [])
|
: [])
|
||||||
// {
|
// {
|
||||||
// "uuid": "",
|
// "uuid": "",
|
||||||
@@ -660,7 +643,7 @@ async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMS
|
|||||||
jobid: JobData.id,
|
jobid: JobData.id,
|
||||||
body: {
|
body: {
|
||||||
dealer: {
|
dealer: {
|
||||||
company: JobData.bodyshop.cdk_configuration.srcco || "77",
|
//company: JobData.bodyshop.cdk_configuration.srcco || "77",
|
||||||
// "dealNumber": "",
|
// "dealNumber": "",
|
||||||
// "dealerAssignedNumber": "82268",
|
// "dealerAssignedNumber": "82268",
|
||||||
// "dealerDefined1": "2WDSP",
|
// "dealerDefined1": "2WDSP",
|
||||||
@@ -677,9 +660,9 @@ async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMS
|
|||||||
txEnvelope.dms_unsold === true
|
txEnvelope.dms_unsold === true
|
||||||
? ""
|
? ""
|
||||||
: moment(txEnvelope.inservicedate)
|
: moment(txEnvelope.inservicedate)
|
||||||
//.tz(JobData.bodyshop.timezone)
|
//.tz(JobData.bodyshop.timezone)
|
||||||
.startOf("day")
|
.startOf("day")
|
||||||
.toISOString()
|
.toISOString()
|
||||||
}),
|
}),
|
||||||
//"lastServiceDate": "2011-11-23",
|
//"lastServiceDate": "2011-11-23",
|
||||||
vehicleId: DMSVid.vehiclesVehId
|
vehicleId: DMSVid.vehiclesVehId
|
||||||
@@ -721,8 +704,8 @@ async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMS
|
|||||||
txEnvelope.dms_unsold === true
|
txEnvelope.dms_unsold === true
|
||||||
? ""
|
? ""
|
||||||
: moment()
|
: moment()
|
||||||
// .tz(JobData.bodyshop.timezone)
|
// .tz(JobData.bodyshop.timezone)
|
||||||
.format("YYYY-MM-DD"),
|
.format("YYYY-MM-DD"),
|
||||||
// "deliveryMileage": 4,
|
// "deliveryMileage": 4,
|
||||||
// "doorsQuantity": 4,
|
// "doorsQuantity": 4,
|
||||||
// "engineNumber": "",
|
// "engineNumber": "",
|
||||||
@@ -739,8 +722,8 @@ async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMS
|
|||||||
: String(JobData.plate_no).replace(/([^\w]|_)/g, "").length === 0
|
: String(JobData.plate_no).replace(/([^\w]|_)/g, "").length === 0
|
||||||
? null
|
? null
|
||||||
: String(JobData.plate_no)
|
: String(JobData.plate_no)
|
||||||
.replace(/([^\w]|_)/g, "")
|
.replace(/([^\w]|_)/g, "")
|
||||||
.toUpperCase(),
|
.toUpperCase(),
|
||||||
make: txEnvelope.dms_make,
|
make: txEnvelope.dms_make,
|
||||||
// "model": "CC10753",
|
// "model": "CC10753",
|
||||||
modelAbrev: txEnvelope.dms_model,
|
modelAbrev: txEnvelope.dms_model,
|
||||||
@@ -886,13 +869,13 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust
|
|||||||
},
|
},
|
||||||
...(oldOwner
|
...(oldOwner
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
id: {
|
id: {
|
||||||
assigningPartyId: "PREVIOUS",
|
assigningPartyId: "PREVIOUS",
|
||||||
value: oldOwner.id
|
value: oldOwner.id
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
]
|
||||||
: [])
|
: [])
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -916,30 +899,30 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust
|
|||||||
...DMSVehToSend,
|
...DMSVehToSend,
|
||||||
dealer: {
|
dealer: {
|
||||||
...DMSVehToSend.dealer, //TODO: Check why company is blank on a queried record.
|
...DMSVehToSend.dealer, //TODO: Check why company is blank on a queried record.
|
||||||
//company: "77",
|
|
||||||
...((txEnvelope.inservicedate || DMSVehToSend.dealer.inServiceDate) && {
|
...((txEnvelope.inservicedate || DMSVehToSend.dealer.inServiceDate) && {
|
||||||
inServiceDate:
|
inServiceDate:
|
||||||
txEnvelope.dms_unsold === true
|
txEnvelope.dms_unsold === true
|
||||||
? ""
|
? ""
|
||||||
: moment(DMSVehToSend.dealer.inServiceDate || txEnvelope.inservicedate)
|
: moment(DMSVehToSend.dealer.inServiceDate || txEnvelope.inservicedate)
|
||||||
// .tz(JobData.bodyshop.timezone)
|
// .tz(JobData.bodyshop.timezone)
|
||||||
.toISOString()
|
.toISOString()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
vehicle: {
|
vehicle: {
|
||||||
...DMSVehToSend.vehicle,
|
...DMSVehToSend.vehicle,
|
||||||
...(txEnvelope.dms_model_override
|
...(txEnvelope.dms_model_override
|
||||||
? {
|
? {
|
||||||
make: txEnvelope.dms_make,
|
make: txEnvelope.dms_make,
|
||||||
modelAbrev: txEnvelope.dms_model
|
modelAbrev: txEnvelope.dms_model
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
deliveryDate:
|
deliveryDate:
|
||||||
txEnvelope.dms_unsold === true
|
txEnvelope.dms_unsold === true
|
||||||
? ""
|
? ""
|
||||||
: moment(DMSVehToSend.vehicle.deliveryDate)
|
: moment(DMSVehToSend.vehicle.deliveryDate)
|
||||||
//.tz(JobData.bodyshop.timezone)
|
//.tz(JobData.bodyshop.timezone)
|
||||||
.toISOString()
|
.toISOString()
|
||||||
},
|
},
|
||||||
owners: ids
|
owners: ids
|
||||||
}
|
}
|
||||||
@@ -1027,9 +1010,24 @@ async function InsertDmsStartWip({ socket, redisHelpers, JobData }) {
|
|||||||
srcCo: JobData.bodyshop.cdk_configuration.srcco,
|
srcCo: JobData.bodyshop.cdk_configuration.srcco,
|
||||||
srcJrnl: txEnvelope.journal,
|
srcJrnl: txEnvelope.journal,
|
||||||
transID: "",
|
transID: "",
|
||||||
userID: "csr" || JobData.bodyshop.cdk_configuration.cashierid,
|
userID: JobData.bodyshop.cdk_configuration.cashierid,
|
||||||
userName: "BSMS"
|
userName: "IMEX"
|
||||||
}
|
|
||||||
|
// acctgDate: "2025-07-07",
|
||||||
|
// desc: "DOCUMENT DESC. OPTIONAL REQUIREMENT",
|
||||||
|
// docType: "3",
|
||||||
|
// m13Flag: "0",
|
||||||
|
// refer: "707MISC01",
|
||||||
|
// rtnCode: "",
|
||||||
|
// sendline: "",
|
||||||
|
// groupName: "",
|
||||||
|
// srcCo: "77",
|
||||||
|
// srcJrnl: "80",
|
||||||
|
// transID: "",
|
||||||
|
// userID: "partprgm",
|
||||||
|
// userName: "PROGRAM, PARTNER"
|
||||||
|
},
|
||||||
|
//overrideDepartmentId: "D100152198" //TODO: REMOVE AFTER TESTING
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1041,26 +1039,6 @@ async function InsertDmsStartWip({ socket, redisHelpers, JobData }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function InsertDmsBatchWip({ socket, redisHelpers, JobData }) {
|
|
||||||
try {
|
|
||||||
const result = await MakeFortellisCall({
|
|
||||||
...FortellisActions.TranBatchWip,
|
|
||||||
headers: {},
|
|
||||||
redisHelpers,
|
|
||||||
socket,
|
|
||||||
jobid: JobData.id,
|
|
||||||
body: await GenerateTransWips({ socket, redisHelpers, JobData })
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
handleFortellisApiError(socket, error, "InsertDmsBatchWip", {
|
|
||||||
jobId: JobData.id,
|
|
||||||
errorStack: error.stack
|
|
||||||
});
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function GenerateTransWips({ socket, redisHelpers, JobData }) {
|
async function GenerateTransWips({ socket, redisHelpers, JobData }) {
|
||||||
//3rd prop sets fortellis to true to maintain logging.
|
//3rd prop sets fortellis to true to maintain logging.
|
||||||
const allocations = await CalculateAllocations(socket, JobData.id, true);
|
const allocations = await CalculateAllocations(socket, JobData.id, true);
|
||||||
@@ -1079,9 +1057,9 @@ async function GenerateTransWips({ socket, redisHelpers, JobData }) {
|
|||||||
acct: alloc.profitCenter.dms_acctnumber,
|
acct: alloc.profitCenter.dms_acctnumber,
|
||||||
cntl:
|
cntl:
|
||||||
alloc.profitCenter.dms_control_override &&
|
alloc.profitCenter.dms_control_override &&
|
||||||
alloc.profitCenter.dms_control_override !== null &&
|
alloc.profitCenter.dms_control_override !== null &&
|
||||||
alloc.profitCenter.dms_control_override !== undefined &&
|
alloc.profitCenter.dms_control_override !== undefined &&
|
||||||
alloc.profitCenter.dms_control_override?.trim() !== ""
|
alloc.profitCenter.dms_control_override?.trim() !== ""
|
||||||
? alloc.profitCenter.dms_control_override
|
? alloc.profitCenter.dms_control_override
|
||||||
: JobData.ro_number,
|
: JobData.ro_number,
|
||||||
cntl2: null,
|
cntl2: null,
|
||||||
@@ -1102,9 +1080,9 @@ async function GenerateTransWips({ socket, redisHelpers, JobData }) {
|
|||||||
acct: alloc.costCenter.dms_acctnumber,
|
acct: alloc.costCenter.dms_acctnumber,
|
||||||
cntl:
|
cntl:
|
||||||
alloc.costCenter.dms_control_override &&
|
alloc.costCenter.dms_control_override &&
|
||||||
alloc.costCenter.dms_control_override !== null &&
|
alloc.costCenter.dms_control_override !== null &&
|
||||||
alloc.costCenter.dms_control_override !== undefined &&
|
alloc.costCenter.dms_control_override !== undefined &&
|
||||||
alloc.costCenter.dms_control_override?.trim() !== ""
|
alloc.costCenter.dms_control_override?.trim() !== ""
|
||||||
? alloc.costCenter.dms_control_override
|
? alloc.costCenter.dms_control_override
|
||||||
: JobData.ro_number,
|
: JobData.ro_number,
|
||||||
cntl2: null,
|
cntl2: null,
|
||||||
@@ -1122,9 +1100,9 @@ async function GenerateTransWips({ socket, redisHelpers, JobData }) {
|
|||||||
acct: alloc.costCenter.dms_wip_acctnumber,
|
acct: alloc.costCenter.dms_wip_acctnumber,
|
||||||
cntl:
|
cntl:
|
||||||
alloc.costCenter.dms_control_override &&
|
alloc.costCenter.dms_control_override &&
|
||||||
alloc.costCenter.dms_control_override !== null &&
|
alloc.costCenter.dms_control_override !== null &&
|
||||||
alloc.costCenter.dms_control_override !== undefined &&
|
alloc.costCenter.dms_control_override !== undefined &&
|
||||||
alloc.costCenter.dms_control_override?.trim() !== ""
|
alloc.costCenter.dms_control_override?.trim() !== ""
|
||||||
? alloc.costCenter.dms_control_override
|
? alloc.costCenter.dms_control_override
|
||||||
: JobData.ro_number,
|
: JobData.ro_number,
|
||||||
cntl2: null,
|
cntl2: null,
|
||||||
@@ -1146,9 +1124,9 @@ async function GenerateTransWips({ socket, redisHelpers, JobData }) {
|
|||||||
acct: alloc.profitCenter.dms_acctnumber,
|
acct: alloc.profitCenter.dms_acctnumber,
|
||||||
cntl:
|
cntl:
|
||||||
alloc.profitCenter.dms_control_override &&
|
alloc.profitCenter.dms_control_override &&
|
||||||
alloc.profitCenter.dms_control_override !== null &&
|
alloc.profitCenter.dms_control_override !== null &&
|
||||||
alloc.profitCenter.dms_control_override !== undefined &&
|
alloc.profitCenter.dms_control_override !== undefined &&
|
||||||
alloc.profitCenter.dms_control_override?.trim() !== ""
|
alloc.profitCenter.dms_control_override?.trim() !== ""
|
||||||
? alloc.profitCenter.dms_control_override
|
? alloc.profitCenter.dms_control_override
|
||||||
: JobData.ro_number,
|
: JobData.ro_number,
|
||||||
cntl2: null,
|
cntl2: null,
|
||||||
@@ -1214,8 +1192,9 @@ async function PostDmsBatchWip({ socket, redisHelpers, JobData }) {
|
|||||||
jobid: JobData.id,
|
jobid: JobData.id,
|
||||||
body: {
|
body: {
|
||||||
opCode: "P",
|
opCode: "P",
|
||||||
transID: DMSTransHeader.transID
|
transID: DMSTransHeader.transID,
|
||||||
}
|
transWipReqList: await GenerateTransWips({ socket, redisHelpers, JobData })
|
||||||
|
},
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1243,7 +1222,7 @@ async function QueryDmsErrWip({ socket, redisHelpers, JobData }) {
|
|||||||
socket,
|
socket,
|
||||||
jobid: JobData.id,
|
jobid: JobData.id,
|
||||||
requestPathParams: DMSTransHeader.transID,
|
requestPathParams: DMSTransHeader.transID,
|
||||||
body: {}
|
body: {},
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1265,7 +1244,7 @@ async function DeleteDmsWip({ socket, redisHelpers, JobData }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const result = await MakeFortellisCall({
|
const result = await MakeFortellisCall({
|
||||||
...FortellisActions.PostBatchWip,
|
...FortellisActions.DeleteTranWip,
|
||||||
headers: {},
|
headers: {},
|
||||||
redisHelpers,
|
redisHelpers,
|
||||||
socket,
|
socket,
|
||||||
@@ -1273,7 +1252,7 @@ async function DeleteDmsWip({ socket, redisHelpers, JobData }) {
|
|||||||
body: {
|
body: {
|
||||||
opCode: "D",
|
opCode: "D",
|
||||||
transID: DMSTransHeader.transID
|
transID: DMSTransHeader.transID
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1285,7 +1264,7 @@ async function DeleteDmsWip({ socket, redisHelpers, JobData }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function MarkJobExported({ socket, jobid }) {
|
async function MarkJobExported({ socket, jobid, JobData }) {
|
||||||
CreateFortellisLogEvent(socket, "ERROR", `Marking job as exported for id ${jobid}`);
|
CreateFortellisLogEvent(socket, "ERROR", `Marking job as exported for id ${jobid}`);
|
||||||
|
|
||||||
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
||||||
@@ -1297,11 +1276,11 @@ async function MarkJobExported({ socket, jobid }) {
|
|||||||
.request(queries.MARK_JOB_EXPORTED, {
|
.request(queries.MARK_JOB_EXPORTED, {
|
||||||
jobId: jobid,
|
jobId: jobid,
|
||||||
job: {
|
job: {
|
||||||
status: socket.JobData.bodyshop.md_ro_statuses.default_exported || "Exported*",
|
status: JobData.bodyshop.md_ro_statuses.default_exported || "Exported*",
|
||||||
date_exported: new Date()
|
date_exported: new Date()
|
||||||
},
|
},
|
||||||
log: {
|
log: {
|
||||||
bodyshopid: socket.JobData.bodyshop.id,
|
bodyshopid: JobData.bodyshop.id,
|
||||||
jobid: jobid,
|
jobid: jobid,
|
||||||
successful: true,
|
successful: true,
|
||||||
useremail: socket.user.email,
|
useremail: socket.user.email,
|
||||||
@@ -1325,13 +1304,13 @@ async function InsertFailedExportLog({ socket, JobData, error }) {
|
|||||||
const result = await client
|
const result = await client
|
||||||
.setHeaders({ Authorization: `Bearer ${currentToken}` })
|
.setHeaders({ Authorization: `Bearer ${currentToken}` })
|
||||||
.request(queries.INSERT_EXPORT_LOG, {
|
.request(queries.INSERT_EXPORT_LOG, {
|
||||||
log: {
|
logs: [{
|
||||||
bodyshopid: JobData.bodyshop.id,
|
bodyshopid: JobData.bodyshop.id,
|
||||||
jobid: JobData.id,
|
jobid: JobData.id,
|
||||||
successful: false,
|
successful: false,
|
||||||
message: JSON.stringify(error),
|
message: JSON.stringify(error),
|
||||||
useremail: socket.user.email
|
useremail: socket.user.email
|
||||||
}
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -2178,19 +2178,7 @@ mutation UPDATE_BILLS($billids: [uuid!]!, $bill: bills_set_input!, $logs: [expor
|
|||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
exports.INSERT_EXPORT_LOG = `
|
|
||||||
mutation INSERT_EXPORT_LOG($log: exportlog_insert_input!) {
|
|
||||||
insert_exportlog_one(object: $log) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
exports.QUERY_EXISTING_TRANSITION = `
|
|
||||||
mutation INSERT_EXPORT_LOG($log: exportlog_insert_input!) {
|
|
||||||
insert_exportlog_one(object: $log) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
exports.UPDATE_OLD_TRANSITION = `mutation UPDATE_OLD_TRANSITION($jobid: uuid!, $existingTransition: transitions_set_input!){
|
exports.UPDATE_OLD_TRANSITION = `mutation UPDATE_OLD_TRANSITION($jobid: uuid!, $existingTransition: transitions_set_input!){
|
||||||
update_transitions(where:{jobid:{_eq:$jobid}, end:{_is_null:true
|
update_transitions(where:{jobid:{_eq:$jobid}, end:{_is_null:true
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const withUserGraphQLClientMiddleware = require("../middleware/withUserGraphQLCl
|
|||||||
router.use(validateFirebaseIdTokenMiddleware);
|
router.use(validateFirebaseIdTokenMiddleware);
|
||||||
|
|
||||||
router.post("/getvehicles", withUserGraphQLClientMiddleware, cdkGetMake.default);
|
router.post("/getvehicles", withUserGraphQLClientMiddleware, cdkGetMake.default);
|
||||||
|
router.post("/fortellis/getvehicles", withUserGraphQLClientMiddleware, cdkGetMake.fortellis);
|
||||||
router.post("/calculate-allocations", withUserGraphQLClientMiddleware, cdkCalculateAllocations.defaultRoute);
|
router.post("/calculate-allocations", withUserGraphQLClientMiddleware, cdkCalculateAllocations.defaultRoute);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ const redisSocketEvents = ({ io, redisHelpers, ioHelpers, logger }) => {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
|
FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
|
||||||
logger.log("fortellis-job-export-error", "error", null, null, {
|
logger.log("fortellis-job-export-error", "error", socket.user?.email, jobid, {
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack
|
stack: error.stack
|
||||||
});
|
});
|
||||||
@@ -320,7 +320,7 @@ const redisSocketEvents = ({ io, redisHelpers, ioHelpers, logger }) => {
|
|||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
|
FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
|
||||||
logger.log("fortellis-selectd-customer-error", "error", null, null, {
|
logger.log("fortellis-selectd-customer-error", "error", socket.user?.email, jobid, {
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack
|
stack: error.stack
|
||||||
});
|
});
|
||||||
@@ -333,7 +333,7 @@ const redisSocketEvents = ({ io, redisHelpers, ioHelpers, logger }) => {
|
|||||||
callback(allocations);
|
callback(allocations);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
|
FortellisLogger(socket, "error", `Error during Fortellis export : ${error.message}`);
|
||||||
logger.log("fortellis-selectd-customer-error", "error", null, null, {
|
logger.log("fortellis-selectd-customer-error", "error", socket.user?.email, jobid, {
|
||||||
message: error.message,
|
message: error.message,
|
||||||
stack: error.stack
|
stack: error.stack
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user