Compare commits
71 Commits
feature/IO
...
test-AIO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
045f36e294 | ||
|
|
c7c6dfcd7d | ||
|
|
c1c0b35c8f | ||
|
|
c024fdd57b | ||
|
|
a4ccacf83a | ||
|
|
aa3b303fe9 | ||
|
|
fdaf50d778 | ||
|
|
468ed23f73 | ||
|
|
322ebd3bc7 | ||
|
|
b887cfed01 | ||
|
|
0f800c5a4c | ||
|
|
6cce92b0fd | ||
|
|
60ab04cb38 | ||
|
|
345a470731 | ||
|
|
0025e113c6 | ||
|
|
dc435b2bb0 | ||
|
|
fd72d244e7 | ||
|
|
87bb472271 | ||
|
|
825959880e | ||
|
|
c40fea0ec9 | ||
|
|
ebdf427b58 | ||
|
|
b3fdd68276 | ||
|
|
3e63c58b9b | ||
|
|
7e2df3e341 | ||
|
|
709b6ef1d6 | ||
|
|
b920bb4437 | ||
|
|
4d299bb226 | ||
|
|
99b65e8186 | ||
|
|
426283ffee | ||
|
|
4fc86ccaa3 | ||
|
|
a67946c5a3 | ||
|
|
e43923b7a0 | ||
|
|
e9ef429729 | ||
|
|
db01ad9155 | ||
|
|
8bf7fbd1f1 | ||
|
|
c37037ef21 | ||
|
|
6050aebcd5 | ||
|
|
77d0f5ab38 | ||
|
|
a0692f8c69 | ||
|
|
4f76aeb06f | ||
|
|
302a42089f | ||
|
|
906265c4b2 | ||
|
|
388b042037 | ||
|
|
73eb76a230 | ||
|
|
d5e9b79f75 | ||
|
|
56d0c009e2 | ||
|
|
79030f6b36 | ||
|
|
5e78cdd8ae | ||
|
|
8f4ac866f1 | ||
|
|
9ad2a53bec | ||
|
|
6590f8961b | ||
|
|
7df71b8f44 | ||
|
|
4776b03a21 | ||
|
|
20943f74e9 | ||
|
|
4af312854e | ||
|
|
ff084f6fb8 | ||
|
|
5c9e4517a6 | ||
|
|
190217ffce | ||
|
|
28dc1d4533 | ||
|
|
a97e03e0b1 | ||
|
|
e30353cab6 | ||
|
|
c9b9f67170 | ||
|
|
4a47f543b2 | ||
|
|
3b60aa89f1 | ||
|
|
20d2572087 | ||
|
|
ac4c09af60 | ||
|
|
6a60af9dfe | ||
|
|
dfb6f02864 | ||
|
|
48bb494e0f | ||
|
|
9b74cba56b | ||
|
|
6fc8124268 |
@@ -63,7 +63,9 @@ export function JobLineDispatchButton({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//joblineids: selectedLines.map((l) => l.id),
|
//joblineids: selectedLines.map((l) => l.id),
|
||||||
}
|
},
|
||||||
|
refetchQueries: ["QUERY_PARTS_BILLS_BY_JOBID", "GET_JOB_BY_PK"],
|
||||||
|
awaitRefetchQueries: true
|
||||||
});
|
});
|
||||||
if (result.errors) {
|
if (result.errors) {
|
||||||
console.log("🚀 ~ handleConvert ~ result.errors:", result.errors);
|
console.log("🚀 ~ handleConvert ~ result.errors:", result.errors);
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import { createStructuredSelector } from "reselect";
|
|||||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
import {
|
import {
|
||||||
|
CHECK_EMPLOYEE_EMAIL,
|
||||||
CHECK_EMPLOYEE_NUMBER,
|
CHECK_EMPLOYEE_NUMBER,
|
||||||
DELETE_VACATION,
|
DELETE_VACATION,
|
||||||
INSERT_EMPLOYEES,
|
INSERT_EMPLOYEES,
|
||||||
QUERY_EMPLOYEE_BY_ID,
|
QUERY_EMPLOYEE_BY_ID,
|
||||||
QUERY_USERS_BY_EMAIL,
|
|
||||||
UPDATE_EMPLOYEE
|
UPDATE_EMPLOYEE
|
||||||
} from "../../graphql/employees.queries";
|
} from "../../graphql/employees.queries";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
@@ -174,9 +174,10 @@ export function ShopEmployeesFormComponent({ bodyshop, form, onDirtyChange, isDi
|
|||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
const submitAction = saveAndResetSubmitAction();
|
const submitAction = saveAndResetSubmitAction();
|
||||||
|
const userEmail = typeof values.user_email === "string" ? values.user_email.trim() : values.user_email;
|
||||||
const normalizedValues = {
|
const normalizedValues = {
|
||||||
...values,
|
...values,
|
||||||
user_email: values.user_email === "" ? null : values.user_email
|
user_email: userEmail === "" ? null : userEmail
|
||||||
};
|
};
|
||||||
|
|
||||||
if (search.employeeId && search.employeeId !== "new") {
|
if (search.employeeId && search.employeeId !== "new") {
|
||||||
@@ -491,18 +492,29 @@ export function ShopEmployeesFormComponent({ bodyshop, form, onDirtyChange, isDi
|
|||||||
rules={[
|
rules={[
|
||||||
({ getFieldValue }) => ({
|
({ getFieldValue }) => ({
|
||||||
async validator(rule, value) {
|
async validator(rule, value) {
|
||||||
const user_email = getFieldValue("user_email");
|
const user_email = typeof value === "string" ? value.trim() : getFieldValue("user_email");
|
||||||
|
|
||||||
if (user_email && value) {
|
if (user_email && value) {
|
||||||
const response = await client.query({
|
const response = await client.query({
|
||||||
query: QUERY_USERS_BY_EMAIL,
|
query: CHECK_EMPLOYEE_EMAIL,
|
||||||
variables: {
|
variables: {
|
||||||
email: user_email
|
email: user_email,
|
||||||
|
shopId: bodyshop.id
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.data.users.length === 1) {
|
if (response.data.users.length === 1) {
|
||||||
return Promise.resolve();
|
const matchingEmployees = response.data.employees_aggregate.nodes;
|
||||||
|
const currentEmployeeId = form.getFieldValue("id") ?? search.employeeId;
|
||||||
|
|
||||||
|
if (
|
||||||
|
response.data.employees_aggregate.aggregate.count === 0 ||
|
||||||
|
matchingEmployees.every((employee) => employee.id === currentEmployeeId)
|
||||||
|
) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(t("employees.validation.unique_user_email"));
|
||||||
}
|
}
|
||||||
return Promise.reject(t("bodyshop.validation.useremailmustexist"));
|
return Promise.reject(t("bodyshop.validation.useremailmustexist"));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import {
|
import {
|
||||||
|
CHECK_EMPLOYEE_EMAIL,
|
||||||
DELETE_VACATION,
|
DELETE_VACATION,
|
||||||
INSERT_EMPLOYEES,
|
INSERT_EMPLOYEES,
|
||||||
QUERY_EMPLOYEE_BY_ID,
|
QUERY_EMPLOYEE_BY_ID,
|
||||||
@@ -16,6 +17,7 @@ const updateEmployeeMock = vi.fn();
|
|||||||
const deleteVacationMock = vi.fn();
|
const deleteVacationMock = vi.fn();
|
||||||
const useQueryMock = vi.fn();
|
const useQueryMock = vi.fn();
|
||||||
const useMutationMock = vi.fn();
|
const useMutationMock = vi.fn();
|
||||||
|
const apolloClientQueryMock = vi.fn();
|
||||||
const navigateMock = vi.fn();
|
const navigateMock = vi.fn();
|
||||||
const notification = {
|
const notification = {
|
||||||
error: vi.fn(),
|
error: vi.fn(),
|
||||||
@@ -87,6 +89,10 @@ vi.mock("react-i18next", () => ({
|
|||||||
return "Employee number must be unique";
|
return "Employee number must be unique";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key === "employees.validation.unique_user_email") {
|
||||||
|
return "User email already assigned";
|
||||||
|
}
|
||||||
|
|
||||||
if (key === "bodyshop.validation.useremailmustexist") {
|
if (key === "bodyshop.validation.useremailmustexist") {
|
||||||
return "User email must exist";
|
return "User email must exist";
|
||||||
}
|
}
|
||||||
@@ -203,18 +209,20 @@ describe("ShopEmployeesFormComponent", () => {
|
|||||||
return [vi.fn()];
|
return [vi.fn()];
|
||||||
});
|
});
|
||||||
|
|
||||||
useApolloClient.mockReturnValue({
|
apolloClientQueryMock.mockResolvedValue({
|
||||||
query: vi.fn().mockResolvedValue({
|
data: {
|
||||||
data: {
|
employees_aggregate: {
|
||||||
employees_aggregate: {
|
aggregate: {
|
||||||
aggregate: {
|
count: 0
|
||||||
count: 0
|
|
||||||
},
|
|
||||||
nodes: []
|
|
||||||
},
|
},
|
||||||
users: []
|
nodes: []
|
||||||
}
|
},
|
||||||
})
|
users: []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
useApolloClient.mockReturnValue({
|
||||||
|
query: apolloClientQueryMock
|
||||||
});
|
});
|
||||||
|
|
||||||
insertEmployeesMock.mockResolvedValue({
|
insertEmployeesMock.mockResolvedValue({
|
||||||
@@ -356,4 +364,59 @@ describe("ShopEmployeesFormComponent", () => {
|
|||||||
title: "Saved"
|
title: "Saved"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("blocks saving when the user email belongs to another employee in the shop", async () => {
|
||||||
|
apolloClientQueryMock.mockImplementation(({ query }) => {
|
||||||
|
if (query === CHECK_EMPLOYEE_EMAIL) {
|
||||||
|
return Promise.resolve({
|
||||||
|
data: {
|
||||||
|
users: [{ email: "jamie@example.com" }],
|
||||||
|
employees_aggregate: {
|
||||||
|
aggregate: {
|
||||||
|
count: 1
|
||||||
|
},
|
||||||
|
nodes: [{ id: "other-employee" }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve({
|
||||||
|
data: {
|
||||||
|
employees_aggregate: {
|
||||||
|
aggregate: {
|
||||||
|
count: 0
|
||||||
|
},
|
||||||
|
nodes: []
|
||||||
|
},
|
||||||
|
users: []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.change(screen.getByRole("textbox", { name: "First Name" }), {
|
||||||
|
target: { value: "Jamie" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByRole("textbox", { name: "Last Name" }), {
|
||||||
|
target: { value: "Rivera" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByRole("textbox", { name: "Employee Number" }), {
|
||||||
|
target: { value: "42" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByRole("textbox", { name: "PIN" }), {
|
||||||
|
target: { value: "1234" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByRole("textbox", { name: "Hire Date" }), {
|
||||||
|
target: { value: "2026-04-20" }
|
||||||
|
});
|
||||||
|
fireEvent.change(screen.getByRole("textbox", { name: "User Email" }), {
|
||||||
|
target: { value: "jamie@example.com" }
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByRole("button", { name: "Save Employee" }));
|
||||||
|
|
||||||
|
expect(await screen.findByText("User email already assigned")).toBeInTheDocument();
|
||||||
|
expect(insertEmployeesMock).not.toHaveBeenCalled();
|
||||||
|
expect(notification.success).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -157,36 +157,36 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
|
|||||||
</Col>
|
</Col>
|
||||||
{HasFeatureAccess({ featureName: "export", bodyshop }) &&
|
{HasFeatureAccess({ featureName: "export", bodyshop }) &&
|
||||||
ClosingPeriod.treatment === "on" && (
|
ClosingPeriod.treatment === "on" && (
|
||||||
<Col xs={24} sm={12} xl={8}>
|
<Col xs={24} sm={12} xl={8}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
key="ClosingPeriod"
|
key="ClosingPeriod"
|
||||||
name={["accountingconfig", "ClosingPeriod"]}
|
name={["accountingconfig", "ClosingPeriod"]}
|
||||||
label={t("bodyshop.fields.closingperiod")}
|
label={t("bodyshop.fields.closingperiod")}
|
||||||
>
|
>
|
||||||
<DatePicker.RangePicker format="MM/DD/YYYY" presets={DatePickerRanges} />
|
<DatePicker.RangePicker format="MM/DD/YYYY" presets={DatePickerRanges} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
{HasFeatureAccess({ featureName: "export", bodyshop }) &&
|
{HasFeatureAccess({ featureName: "export", bodyshop }) &&
|
||||||
ADPPayroll.treatment === "on" && (
|
ADPPayroll.treatment === "on" && (
|
||||||
<Col xs={24} sm={12} xl={8}>
|
<Col xs={24} sm={12} xl={8}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
key="companyCode"
|
key="companyCode"
|
||||||
name={["accountingconfig", "companyCode"]}
|
name={["accountingconfig", "companyCode"]}
|
||||||
label={t("bodyshop.fields.companycode")}
|
label={t("bodyshop.fields.companycode")}
|
||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
{HasFeatureAccess({ featureName: "export", bodyshop }) &&
|
{HasFeatureAccess({ featureName: "export", bodyshop }) &&
|
||||||
ADPPayroll.treatment === "on" && (
|
ADPPayroll.treatment === "on" && (
|
||||||
<Col xs={24} sm={12} xl={8}>
|
<Col xs={24} sm={12} xl={8}>
|
||||||
<Form.Item key="batchID" name={["accountingconfig", "batchID"]} label={t("bodyshop.fields.batchid")}>
|
<Form.Item key="batchID" name={["accountingconfig", "batchID"]} label={t("bodyshop.fields.batchid")}>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
{HasFeatureAccess({ featureName: "export", bodyshop }) && !hasDMSKey && (
|
{HasFeatureAccess({ featureName: "export", bodyshop }) && !hasDMSKey && (
|
||||||
<>
|
<>
|
||||||
<Col xs={24} sm={12} xl={8}>
|
<Col xs={24} sm={12} xl={8}>
|
||||||
@@ -512,6 +512,15 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
|
|||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} suffix="%" />
|
<InputNumber min={0} max={100} suffix="%" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
{bodyshop.cdk_dealerid && (
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.dms.disablecontact")}
|
||||||
|
valuePropName="checked"
|
||||||
|
name={["cdk_configuration", "disablecontact"]}
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
{bodyshop.pbs_serialnumber && (
|
{bodyshop.pbs_serialnumber && (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.dms.disablecontactvehiclecreation")}
|
label={t("bodyshop.fields.dms.disablecontactvehiclecreation")}
|
||||||
|
|||||||
@@ -49,6 +49,22 @@ export const CHECK_EMPLOYEE_NUMBER = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const CHECK_EMPLOYEE_EMAIL = gql`
|
||||||
|
query CHECK_EMPLOYEE_EMAIL($email: String!, $shopId: uuid!) {
|
||||||
|
users(where: { email: { _ilike: $email } }) {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
employees_aggregate(where: { user_email: { _ilike: $email }, shopid: { _eq: $shopId } }) {
|
||||||
|
aggregate {
|
||||||
|
count
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const QUERY_ACTIVE_EMPLOYEES = gql`
|
export const QUERY_ACTIVE_EMPLOYEES = gql`
|
||||||
query QUERY_ACTIVE_EMPLOYEES {
|
query QUERY_ACTIVE_EMPLOYEES {
|
||||||
employees(where: { active: { _eq: true } }) {
|
employees(where: { active: { _eq: true } }) {
|
||||||
|
|||||||
@@ -370,6 +370,7 @@
|
|||||||
"cashierid": "Cashier ID",
|
"cashierid": "Cashier ID",
|
||||||
"default_journal": "Default Journal",
|
"default_journal": "Default Journal",
|
||||||
"disablebillwip": "Disable bill WIP for A/P Posting",
|
"disablebillwip": "Disable bill WIP for A/P Posting",
|
||||||
|
"disablecontact": "Disable Contact Updates/Creation",
|
||||||
"disablecontactvehiclecreation": "Disable Contact & Vehicle Updates/Creation",
|
"disablecontactvehiclecreation": "Disable Contact & Vehicle Updates/Creation",
|
||||||
"dms_acctnumber": "DMS Account #",
|
"dms_acctnumber": "DMS Account #",
|
||||||
"dms_control_override": "Static Control # Override",
|
"dms_control_override": "Static Control # Override",
|
||||||
@@ -1350,7 +1351,8 @@
|
|||||||
"vacationadded": "Employee vacation added."
|
"vacationadded": "Employee vacation added."
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"unique_employee_number": "You must enter a unique employee number."
|
"unique_employee_number": "You must enter a unique employee number.",
|
||||||
|
"unique_user_email": "This email is already assigned to another employee."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esignature": {
|
"esignature": {
|
||||||
|
|||||||
@@ -370,6 +370,7 @@
|
|||||||
"cashierid": "",
|
"cashierid": "",
|
||||||
"default_journal": "",
|
"default_journal": "",
|
||||||
"disablebillwip": "",
|
"disablebillwip": "",
|
||||||
|
"disablecontact": "",
|
||||||
"disablecontactvehiclecreation": "",
|
"disablecontactvehiclecreation": "",
|
||||||
"dms_acctnumber": "",
|
"dms_acctnumber": "",
|
||||||
"dms_control_override": "",
|
"dms_control_override": "",
|
||||||
@@ -1350,7 +1351,8 @@
|
|||||||
"vacationadded": ""
|
"vacationadded": ""
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"unique_employee_number": ""
|
"unique_employee_number": "",
|
||||||
|
"unique_user_email": "Este correo electrónico ya está asignado a otro empleado."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esignature": {
|
"esignature": {
|
||||||
|
|||||||
@@ -370,6 +370,7 @@
|
|||||||
"cashierid": "",
|
"cashierid": "",
|
||||||
"default_journal": "",
|
"default_journal": "",
|
||||||
"disablebillwip": "",
|
"disablebillwip": "",
|
||||||
|
"disablecontact": "",
|
||||||
"disablecontactvehiclecreation": "",
|
"disablecontactvehiclecreation": "",
|
||||||
"dms_acctnumber": "",
|
"dms_acctnumber": "",
|
||||||
"dms_control_override": "",
|
"dms_control_override": "",
|
||||||
@@ -1350,7 +1351,8 @@
|
|||||||
"vacationadded": ""
|
"vacationadded": ""
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
"unique_employee_number": ""
|
"unique_employee_number": "",
|
||||||
|
"unique_user_email": "Cette adresse courriel est déjà assignée à un autre employé."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esignature": {
|
"esignature": {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const _ = require("lodash");
|
|||||||
const moment = require("moment-timezone");
|
const moment = require("moment-timezone");
|
||||||
|
|
||||||
const replaceSpecialRegex = /[^a-zA-Z0-9 ]+/g;
|
const replaceSpecialRegex = /[^a-zA-Z0-9 ]+/g;
|
||||||
|
const bypassCustomerId = "bypass";
|
||||||
// Helper function to handle FortellisApiError logging
|
// Helper function to handle FortellisApiError logging
|
||||||
function handleFortellisApiError(socket, error, functionName, additionalDetails = {}) {
|
function handleFortellisApiError(socket, error, functionName, additionalDetails = {}) {
|
||||||
if (error instanceof FortellisApiError) {
|
if (error instanceof FortellisApiError) {
|
||||||
@@ -95,7 +95,8 @@ async function FortellisJobExport({ socket, redisHelpers, txEnvelope, jobid }) {
|
|||||||
defaultFortellisTTL
|
defaultFortellisTTL
|
||||||
);
|
);
|
||||||
|
|
||||||
let DMSVehCustomer;
|
let DMSVehCustomerFromVehicle;
|
||||||
|
//let DMSVehCustomer;
|
||||||
if (!DMSVid.newId) {
|
if (!DMSVid.newId) {
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{2.1} Querying the Vehicle using the DMSVid: ${DMSVid.vehiclesVehId}`);
|
CreateFortellisLogEvent(socket, "DEBUG", `{2.1} Querying the Vehicle using the DMSVid: ${DMSVid.vehiclesVehId}`);
|
||||||
const DMSVeh = await QueryDmsVehicleById({ socket, redisHelpers, JobData, DMSVid });
|
const DMSVeh = await QueryDmsVehicleById({ socket, redisHelpers, JobData, DMSVid });
|
||||||
@@ -106,46 +107,66 @@ async function FortellisJobExport({ socket, redisHelpers, txEnvelope, jobid }) {
|
|||||||
DMSVeh,
|
DMSVeh,
|
||||||
defaultFortellisTTL
|
defaultFortellisTTL
|
||||||
);
|
);
|
||||||
|
DMSVehCustomerFromVehicle = DMSVeh?.owners && DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
|
||||||
|
|
||||||
const DMSVehCustomerFromVehicle =
|
// //Add in contact bypass for Fortellis.
|
||||||
DMSVeh?.owners && DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
|
// if (!JobData.bodyshop.cdk_configuration.disablecontact) {
|
||||||
|
// const DMSVehCustomerFromVehicle =
|
||||||
|
// DMSVeh?.owners && DMSVeh.owners.find((o) => o.id.assigningPartyId === "CURRENT");
|
||||||
|
|
||||||
if (DMSVehCustomerFromVehicle?.id && DMSVehCustomerFromVehicle.id.value) {
|
// if (DMSVehCustomerFromVehicle?.id && DMSVehCustomerFromVehicle.id.value) {
|
||||||
CreateFortellisLogEvent(
|
// CreateFortellisLogEvent(
|
||||||
socket,
|
// socket,
|
||||||
"DEBUG",
|
// "DEBUG",
|
||||||
`{2.2} Querying the Customer using the ID from DMSVeh: ${DMSVehCustomerFromVehicle.id.value}`
|
// `{2.2} Querying the Customer using the ID from DMSVeh: ${DMSVehCustomerFromVehicle.id.value}`
|
||||||
);
|
// );
|
||||||
DMSVehCustomer = await QueryDmsCustomerById({
|
// DMSVehCustomer = await QueryDmsCustomerById({
|
||||||
socket,
|
// socket,
|
||||||
redisHelpers,
|
// redisHelpers,
|
||||||
JobData,
|
// JobData,
|
||||||
CustomerId: DMSVehCustomerFromVehicle.id.value
|
// CustomerId: DMSVehCustomerFromVehicle.id.value
|
||||||
});
|
// });
|
||||||
await setSessionTransactionData(
|
// await setSessionTransactionData(
|
||||||
socket.id,
|
// socket.id,
|
||||||
getTransactionType(jobid),
|
// getTransactionType(jobid),
|
||||||
FortellisCacheEnums.DMSVehCustomer,
|
// FortellisCacheEnums.DMSVehCustomer,
|
||||||
DMSVehCustomer,
|
// DMSVehCustomer,
|
||||||
defaultFortellisTTL
|
// defaultFortellisTTL
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{2.3} Querying the Customer using the name.`);
|
CreateFortellisLogEvent(socket, "DEBUG", `{2.3} Querying the Customer using the name.`);
|
||||||
|
if (JobData.bodyshop.cdk_configuration.disablecontact) {
|
||||||
|
//Just go straight to posting.
|
||||||
|
await FortellisSelectedCustomer({ socket, redisHelpers, selectedCustomerId: bypassCustomerId, jobid });
|
||||||
|
} else {
|
||||||
|
const DMSCustList = await QueryDmsCustomerByName({ socket, redisHelpers, JobData });
|
||||||
|
await setSessionTransactionData(
|
||||||
|
socket.id,
|
||||||
|
getTransactionType(jobid),
|
||||||
|
FortellisCacheEnums.DMSCustList,
|
||||||
|
DMSCustList,
|
||||||
|
defaultFortellisTTL
|
||||||
|
);
|
||||||
|
|
||||||
const DMSCustList = await QueryDmsCustomerByName({ socket, redisHelpers, JobData });
|
socket.emit("fortellis-select-customer",
|
||||||
await setSessionTransactionData(
|
//Removed to save one one API call while disputing with fortellis.
|
||||||
socket.id,
|
// [
|
||||||
getTransactionType(jobid),
|
// // ...(DMSVehCustomer ? [{ ...DMSVehCustomer, vinOwner: true }] : []),
|
||||||
FortellisCacheEnums.DMSCustList,
|
// ...DMSCustList
|
||||||
DMSCustList,
|
// ]
|
||||||
defaultFortellisTTL
|
DMSVehCustomerFromVehicle ?
|
||||||
);
|
DMSCustList.map(c => {
|
||||||
|
//if customer id is the same as the current assigned owner on the vehicle id, set it as vinowner true. )
|
||||||
socket.emit("fortellis-select-customer", [
|
if (DMSVehCustomerFromVehicle?.id?.value === c.customerId) {
|
||||||
...(DMSVehCustomer ? [{ ...DMSVehCustomer, vinOwner: true }] : []),
|
return { ...c, vinOwner: true }
|
||||||
...DMSCustList
|
} else {
|
||||||
]);
|
return c
|
||||||
|
}
|
||||||
|
}) : DMSCustList
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
CreateFortellisLogEvent(socket, "ERROR", `Error in FortellisJobExport - ${error} `, {
|
CreateFortellisLogEvent(socket, "ERROR", `Error in FortellisJobExport - ${error} `, {
|
||||||
error: error.message,
|
error: error.message,
|
||||||
@@ -218,36 +239,40 @@ async function FortellisSelectedCustomer({ socket, redisHelpers, selectedCustome
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//Bypass only the customer creation. We still need to create the vehicle and update it to post the service history later on.
|
||||||
let DMSCust;
|
let DMSCust;
|
||||||
if (selectedCustomerId) {
|
if (!JobData.bodyshop.cdk_configuration.disablecontact) {
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{3.1} Querying the Customer using Customer ID: ${selectedCustomerId}`);
|
if (selectedCustomerId) {
|
||||||
|
CreateFortellisLogEvent(socket, "DEBUG", `{3.1} Querying the Customer using Customer ID: ${selectedCustomerId}`);
|
||||||
|
|
||||||
//Get cust list from Redis. Return the item
|
//Get cust list from Redis. Return the item
|
||||||
const DMSCustList =
|
const DMSCustList =
|
||||||
(await getSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSCustList)) || [];
|
(await getSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSCustList)) || [];
|
||||||
const existingCustomerInDMSCustList = DMSCustList.find((c) => c.customerId === selectedCustomerId);
|
const existingCustomerInDMSCustList = DMSCustList.find((c) => c.customerId === selectedCustomerId);
|
||||||
DMSCust = existingCustomerInDMSCustList || {
|
DMSCust = existingCustomerInDMSCustList || {
|
||||||
customerId: selectedCustomerId //This is the fall back in case it is the generic customer.
|
customerId: selectedCustomerId //This is the fall back in case it is the generic customer.
|
||||||
};
|
};
|
||||||
await setSessionTransactionData(
|
await setSessionTransactionData(
|
||||||
socket.id,
|
socket.id,
|
||||||
getTransactionType(jobid),
|
getTransactionType(jobid),
|
||||||
FortellisCacheEnums.DMSCust,
|
FortellisCacheEnums.DMSCust,
|
||||||
DMSCust,
|
DMSCust,
|
||||||
defaultFortellisTTL
|
defaultFortellisTTL
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{3.2} Creating new customer.`);
|
CreateFortellisLogEvent(socket, "DEBUG", `{3.2} Creating new customer.`);
|
||||||
const DMSCustomerInsertResponse = await InsertDmsCustomer({ socket, redisHelpers, JobData });
|
const DMSCustomerInsertResponse = await InsertDmsCustomer({ socket, redisHelpers, JobData });
|
||||||
DMSCust = { customerId: DMSCustomerInsertResponse.data };
|
DMSCust = { customerId: DMSCustomerInsertResponse.data };
|
||||||
await setSessionTransactionData(
|
await setSessionTransactionData(
|
||||||
socket.id,
|
socket.id,
|
||||||
getTransactionType(jobid),
|
getTransactionType(jobid),
|
||||||
FortellisCacheEnums.DMSCust,
|
FortellisCacheEnums.DMSCust,
|
||||||
DMSCust,
|
DMSCust,
|
||||||
defaultFortellisTTL
|
defaultFortellisTTL
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
DMSCust = { customerId: bypassCustomerId };
|
||||||
}
|
}
|
||||||
|
|
||||||
let DMSVeh;
|
let DMSVeh;
|
||||||
@@ -258,8 +283,12 @@ async function FortellisSelectedCustomer({ socket, redisHelpers, selectedCustome
|
|||||||
DMSVeh = await getSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSVeh);
|
DMSVeh = await getSessionTransactionData(socket.id, getTransactionType(jobid), FortellisCacheEnums.DMSVeh);
|
||||||
CreateFortellisLogEvent(socket, "DEBUG", `{4.3} Updating Existing Vehicle to associate to owner.`);
|
CreateFortellisLogEvent(socket, "DEBUG", `{4.3} Updating Existing Vehicle to associate to owner.`);
|
||||||
|
|
||||||
|
//If it's a bypass scenario, skip this all.
|
||||||
//Check to see if the vehicle needs to be updated - i.e. the owner is not the selected customer.
|
//Check to see if the vehicle needs to be updated - i.e. the owner is not the selected customer.
|
||||||
if (!DMSVeh?.owners.find((o) => o.id.value === DMSCust.customerId && o.id.assigningPartyId === "CURRENT")) {
|
if (
|
||||||
|
selectedCustomerId !== bypassCustomerId &&
|
||||||
|
!DMSVeh?.owners.find((o) => o.id.value === DMSCust.customerId && o.id.assigningPartyId === "CURRENT")
|
||||||
|
) {
|
||||||
DMSVeh = await UpdateDmsVehicle({
|
DMSVeh = await UpdateDmsVehicle({
|
||||||
socket,
|
socket,
|
||||||
redisHelpers,
|
redisHelpers,
|
||||||
@@ -782,12 +811,14 @@ async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMS
|
|||||||
// "chassis": "",
|
// "chassis": "",
|
||||||
// "color": "",
|
// "color": "",
|
||||||
// "dealerBodyStyle": "",
|
// "dealerBodyStyle": "",
|
||||||
deliveryDate:
|
...(DMSCust?.customerId !== bypassCustomerId && {
|
||||||
txEnvelope.dms_unsold === true
|
deliveryDate:
|
||||||
? ""
|
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": "",
|
||||||
@@ -902,14 +933,17 @@ async function InsertDmsVehicle({ socket, redisHelpers, JobData, txEnvelope, DMS
|
|||||||
// "warrantyExpDate": "2015-01-12",
|
// "warrantyExpDate": "2015-01-12",
|
||||||
// "wheelbase": ""
|
// "wheelbase": ""
|
||||||
},
|
},
|
||||||
owners: [
|
// Owners is not required. Exclude it if we are bypassing.
|
||||||
{
|
...(DMSCust?.customerId !== bypassCustomerId && {
|
||||||
id: {
|
owners: [
|
||||||
assigningPartyId: "CURRENT",
|
{
|
||||||
value: DMSCust.customerId
|
id: {
|
||||||
|
assigningPartyId: "CURRENT",
|
||||||
|
value: DMSCust.customerId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
]
|
})
|
||||||
//"inventoryAccount": "237"
|
//"inventoryAccount": "237"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1009,12 +1043,14 @@ async function UpdateDmsVehicle({ socket, redisHelpers, JobData, DMSVeh, DMSCust
|
|||||||
modelAbrev: txEnvelope.dms_model
|
modelAbrev: txEnvelope.dms_model
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
deliveryDate:
|
...(DMSCust?.customerId !== bypassCustomerId && {
|
||||||
txEnvelope.dms_unsold === true
|
deliveryDate:
|
||||||
? ""
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user