|
|
|
|
@@ -3,6 +3,8 @@ const AxiosLib = require("axios").default;
|
|
|
|
|
const queries = require("../../graphql-client/queries");
|
|
|
|
|
const { PBS_ENDPOINTS, PBS_CREDENTIALS } = require("./pbs-constants");
|
|
|
|
|
const WsLogger = require("../../web-sockets/createLogEvent");
|
|
|
|
|
const fs = require("fs");
|
|
|
|
|
const path = require("path");
|
|
|
|
|
|
|
|
|
|
//const { CDK_CREDENTIALS, CheckCdkResponseForError } = require("./cdk-wsdl");
|
|
|
|
|
const CalculateAllocations = require("../../cdk/cdk-calculate-allocations").default;
|
|
|
|
|
@@ -22,9 +24,9 @@ axios.interceptors.request.use((x) => {
|
|
|
|
|
const printable = `${new Date()} | Request: ${x.method.toUpperCase()} | ${
|
|
|
|
|
x.url
|
|
|
|
|
} | ${JSON.stringify(x.data)} | ${JSON.stringify(headers)}`;
|
|
|
|
|
//console.log(printable);
|
|
|
|
|
//logRequestToFile(printable);
|
|
|
|
|
|
|
|
|
|
WsLogger.createJsonEvent(socket, "SILLY", `Raw Request: ${printable}`, x.data);
|
|
|
|
|
WsLogger.createJsonEvent(socket, "DEBUG", `Raw Request: ${printable}`, x.data);
|
|
|
|
|
|
|
|
|
|
return x;
|
|
|
|
|
});
|
|
|
|
|
@@ -32,23 +34,36 @@ axios.interceptors.request.use((x) => {
|
|
|
|
|
axios.interceptors.response.use((x) => {
|
|
|
|
|
const socket = x.config.socket;
|
|
|
|
|
|
|
|
|
|
const printable = `${new Date()} | Response: ${x.status} | ${JSON.stringify(x.data)}`;
|
|
|
|
|
//console.log(printable);
|
|
|
|
|
WsLogger.createJsonEvent(socket, "SILLY", `Raw Response: ${printable}`, x.data);
|
|
|
|
|
const printable = `${new Date()} | Response: ${x.status} ${x.statusText} |${JSON.stringify(x.data)}`;
|
|
|
|
|
//logRequestToFile(printable);
|
|
|
|
|
WsLogger.createJsonEvent(socket, "DEBUG", `Raw Response: ${printable}`, x.data);
|
|
|
|
|
|
|
|
|
|
return x;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function logRequestToFile(printable) {
|
|
|
|
|
try {
|
|
|
|
|
const logDir = path.join(process.cwd(), "logs");
|
|
|
|
|
if (!fs.existsSync(logDir)) {
|
|
|
|
|
fs.mkdirSync(logDir, { recursive: true });
|
|
|
|
|
}
|
|
|
|
|
const logFile = path.join(logDir, "pbs-http.log");
|
|
|
|
|
fs.appendFileSync(logFile, `${printable}\n`);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Unexpected error in logRequestToFile:", err);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const defaultHandler = async (socket, { txEnvelope, jobid }) => {
|
|
|
|
|
socket.logEvents = [];
|
|
|
|
|
socket.recordid = jobid;
|
|
|
|
|
socket.txEnvelope = txEnvelope;
|
|
|
|
|
try {
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Received Job export request for id ${jobid}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Received Job export request for id ${jobid}`);
|
|
|
|
|
|
|
|
|
|
const JobData = await QueryJobData(socket, jobid);
|
|
|
|
|
socket.JobData = JobData;
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Querying the DMS for the Vehicle Record.`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Querying the DMS for the Vehicle Record.`);
|
|
|
|
|
//Query for the Vehicle record to get the associated customer.
|
|
|
|
|
socket.DmsVeh = await QueryVehicleFromDms(socket);
|
|
|
|
|
//Todo: Need to validate the lines and methods below.
|
|
|
|
|
@@ -71,42 +86,54 @@ exports.default = defaultHandler;
|
|
|
|
|
|
|
|
|
|
exports.PbsSelectedCustomer = async function PbsSelectedCustomer(socket, selectedCustomerId) {
|
|
|
|
|
try {
|
|
|
|
|
if (socket.JobData.bodyshop.pbs_configuration.disablecontactvehicle === false) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `User selected customer ${selectedCustomerId || "NEW"}`);
|
|
|
|
|
socket.selectedCustomerId = selectedCustomerId;
|
|
|
|
|
if (socket.JobData.bodyshop.pbs_configuration.disablecontactvehicle !== true) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `User selected customer ${selectedCustomerId || "NEW"}`);
|
|
|
|
|
|
|
|
|
|
//Upsert the contact information as per Wafaa's Email.
|
|
|
|
|
WsLogger.createLogEvent(
|
|
|
|
|
socket,
|
|
|
|
|
"DEBUG",
|
|
|
|
|
"INFO",
|
|
|
|
|
`Upserting contact information to DMS for ${
|
|
|
|
|
socket.JobData.ownr_fn || ""
|
|
|
|
|
} ${socket.JobData.ownr_ln || ""} ${socket.JobData.ownr_co_nm || ""}`
|
|
|
|
|
);
|
|
|
|
|
const ownerRef = await UpsertContactData(socket, selectedCustomerId);
|
|
|
|
|
socket.ownerRef = ownerRef;
|
|
|
|
|
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Upserting vehicle information to DMS for ${socket.JobData.v_vin}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Upserting vehicle information to DMS for ${socket.JobData.v_vin}`);
|
|
|
|
|
await UpsertVehicleData(socket, ownerRef.ReferenceId);
|
|
|
|
|
const vehicleRef = await UpsertVehicleData(socket, ownerRef.ReferenceId);
|
|
|
|
|
socket.vehicleRef = vehicleRef;
|
|
|
|
|
} else {
|
|
|
|
|
WsLogger.createLogEvent(
|
|
|
|
|
socket,
|
|
|
|
|
"DEBUG",
|
|
|
|
|
`Contact and Vehicle updates disabled. Skipping to accounting data insert.`
|
|
|
|
|
"INFO",
|
|
|
|
|
`Contact and Vehicle updates disabled. Querying data and skipping to accounting data insert.`
|
|
|
|
|
);
|
|
|
|
|
//Must query for records to insert $0 RO.
|
|
|
|
|
if (!socket.ownerRef) {
|
|
|
|
|
const ownerRef = (await QueryCustomerBycodeFromDms(socket, selectedCustomerId))?.[0];
|
|
|
|
|
socket.ownerRef = ownerRef;
|
|
|
|
|
}
|
|
|
|
|
const vehicleRef = await GetVehicleData(socket, socket.ownerRef?.ReferenceId || socket.selectedCustomerId);
|
|
|
|
|
socket.vehicleRef = vehicleRef;
|
|
|
|
|
}
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Inserting account data.`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Inserting accounting posting data..`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Inserting account posting data...`);
|
|
|
|
|
const insertResponse = await InsertAccountPostingData(socket);
|
|
|
|
|
|
|
|
|
|
if (insertResponse.WasSuccessful) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Marking job as exported.`);
|
|
|
|
|
if (socket.JobData.bodyshop.pbs_configuration.ro_posting) {
|
|
|
|
|
await CreateRepairOrderInPBS(socket, socket.ownerRef, socket.vehicleRef);
|
|
|
|
|
}
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Marking job as exported.`);
|
|
|
|
|
await MarkJobExported(socket, socket.JobData.id);
|
|
|
|
|
|
|
|
|
|
socket.emit("export-success", socket.JobData.id);
|
|
|
|
|
} else {
|
|
|
|
|
WsLogger.createLogEvent(socket, "ERROR", `Export was not successful.`);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "ERROR", `Error encountered in CdkSelectedCustomer. ${error}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "ERROR", `Error encountered in PbsSelectedCustomer. ${error}`);
|
|
|
|
|
await InsertFailedExportLog(socket, error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
@@ -114,24 +141,24 @@ exports.PbsSelectedCustomer = async function PbsSelectedCustomer(socket, selecte
|
|
|
|
|
// Was Successful
|
|
|
|
|
async function CheckForErrors(socket, response) {
|
|
|
|
|
if (response.WasSuccessful === undefined || response.WasSuccessful === true) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Successful response from DMS. ${response.Message || ""}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Successful response from DMS. ${response.Message || ""}`);
|
|
|
|
|
} else {
|
|
|
|
|
WsLogger.createLogEvent(socket, "ERROR", `Error received from DMS: ${response.Message}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "SILLY", `Error received from DMS: ${JSON.stringify(response)}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Error received from DMS: ${JSON.stringify(response)}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exports.CheckForErrors = CheckForErrors;
|
|
|
|
|
|
|
|
|
|
async function QueryJobData(socket, jobid) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Querying job data for id ${jobid}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Querying job data for id ${jobid}`);
|
|
|
|
|
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
|
|
|
|
|
|
|
|
|
const result = await client
|
|
|
|
|
.setHeaders({ Authorization: `Bearer ${socket.handshake.auth.token}` })
|
|
|
|
|
.request(queries.QUERY_JOBS_FOR_PBS_EXPORT, { id: jobid });
|
|
|
|
|
|
|
|
|
|
WsLogger.createLogEvent(socket, "SILLY", `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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -336,7 +363,7 @@ async function UpsertVehicleData(socket, ownerRef) {
|
|
|
|
|
//FleetNumber: "String",
|
|
|
|
|
//Status: "String",
|
|
|
|
|
OwnerRef: ownerRef, // "00000000000000000000000000000000",
|
|
|
|
|
ModelNumber: socket.JobData.vehicle?.v_makecode,
|
|
|
|
|
// ModelNumber: socket.JobData.vehicle?.v_makecode,
|
|
|
|
|
Make: socket.JobData.v_make_desc,
|
|
|
|
|
Model: socket.JobData.v_model_desc,
|
|
|
|
|
Trim: socket.JobData.vehicle?.v_trimcode,
|
|
|
|
|
@@ -344,7 +371,7 @@ async function UpsertVehicleData(socket, ownerRef) {
|
|
|
|
|
Year: socket.JobData.v_model_yr,
|
|
|
|
|
Odometer: socket.JobData.kmout,
|
|
|
|
|
ExteriorColor: {
|
|
|
|
|
Code: socket.JobData.v_color,
|
|
|
|
|
// Code: socket.JobData.v_color,
|
|
|
|
|
Description: socket.JobData.v_color
|
|
|
|
|
}
|
|
|
|
|
// InteriorColor: { Code: "String", Description: "String" },
|
|
|
|
|
@@ -474,6 +501,56 @@ async function UpsertVehicleData(socket, ownerRef) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function GetVehicleData(socket, ownerRef) {
|
|
|
|
|
try {
|
|
|
|
|
const {
|
|
|
|
|
data: { Vehicles }
|
|
|
|
|
} = await axios.post(
|
|
|
|
|
PBS_ENDPOINTS.VehicleGet,
|
|
|
|
|
{
|
|
|
|
|
SerialNumber: socket.JobData.bodyshop.pbs_serialnumber,
|
|
|
|
|
// "VehicleId": "00000000000000000000000000000000",
|
|
|
|
|
// "Year": "String",
|
|
|
|
|
// "YearFrom": "String",
|
|
|
|
|
// "YearTo": "String",
|
|
|
|
|
// "Make": "String",
|
|
|
|
|
// "Model": "String",
|
|
|
|
|
// "Trim": "String",
|
|
|
|
|
// "ModelNumber": "String",
|
|
|
|
|
// "StockNumber": "String",
|
|
|
|
|
VIN: socket.JobData.v_vin
|
|
|
|
|
// "LicenseNumber": "String",
|
|
|
|
|
// "Lot": "String",
|
|
|
|
|
// "Status": "String",
|
|
|
|
|
// "StatusList": ["String"],
|
|
|
|
|
// "OwnerRef": "00000000000000000000000000000000",
|
|
|
|
|
// "ModifiedSince": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "ModifiedUntil": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "LastSaleSince": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "VehicleIDList": ["00000000000000000000000000000000"],
|
|
|
|
|
// "IncludeInactive": false,
|
|
|
|
|
// "IncludeBuildVehicles": false,
|
|
|
|
|
// "IncludeBlankLot": false,
|
|
|
|
|
// "ShortVIN": "String",
|
|
|
|
|
// "ResultLimit": 0,
|
|
|
|
|
// "LotAccessDivisions": [0],
|
|
|
|
|
// "OdometerTo": 0,
|
|
|
|
|
// "OdometerFrom": 0
|
|
|
|
|
},
|
|
|
|
|
{ auth: PBS_CREDENTIALS, socket }
|
|
|
|
|
);
|
|
|
|
|
CheckForErrors(socket, Vehicles);
|
|
|
|
|
if (Vehicles.length === 1) {
|
|
|
|
|
return Vehicles[0];
|
|
|
|
|
} else {
|
|
|
|
|
CdkBase.createLogEvent(socket, "ERROR", `Error in Getting Vehicle Data - ${Vehicles.length} vehicle(s) found`);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
CdkBase.createLogEvent(socket, "ERROR", `Error in UpsertVehicleData - ${error}`);
|
|
|
|
|
throw new Error(error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function InsertAccountPostingData(socket) {
|
|
|
|
|
try {
|
|
|
|
|
const allocations = await CalculateAllocations(socket, socket.JobData.id);
|
|
|
|
|
@@ -577,7 +654,7 @@ async function InsertAccountPostingData(socket) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function MarkJobExported(socket, jobid) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "DEBUG", `Marking job as exported for id ${jobid}`);
|
|
|
|
|
WsLogger.createLogEvent(socket, "INFO", `Marking job as exported for id ${jobid}`);
|
|
|
|
|
const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, {});
|
|
|
|
|
|
|
|
|
|
const result = await client
|
|
|
|
|
@@ -625,3 +702,161 @@ async function InsertFailedExportLog(socket, error) {
|
|
|
|
|
WsLogger.createLogEvent(socket, "ERROR", `Error in InsertFailedExportLog - ${error} - ${JSON.stringify(error2)}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function CreateRepairOrderInPBS(socket) {
|
|
|
|
|
try {
|
|
|
|
|
const { RepairOrders } = await RepairOrderGet(socket);
|
|
|
|
|
if (RepairOrders.length === 0) {
|
|
|
|
|
const InsertedRepairOrder = await RepairOrderChange(socket);
|
|
|
|
|
socket.InsertedRepairOrder = InsertedRepairOrder;
|
|
|
|
|
CdkBase.createLogEvent(socket, "INFO", `No repair orders found for vehicle. Inserting record.`);
|
|
|
|
|
} else if (RepairOrders.length > 0) {
|
|
|
|
|
//Find out if it's a matching RO.
|
|
|
|
|
//This logic is used because the integration will simply add another line to an open RO if it exists.
|
|
|
|
|
const matchingRo = RepairOrders.find((ro) =>
|
|
|
|
|
ro.Memo?.toLowerCase()?.includes(socket.JobData.ro_number.toLowerCase())
|
|
|
|
|
);
|
|
|
|
|
if (!matchingRo) {
|
|
|
|
|
CdkBase.createLogEvent(socket, "INFO", `ROs found for vehicle, but none match. Inserting record.`);
|
|
|
|
|
const InsertedRepairOrder = await RepairOrderChange(socket);
|
|
|
|
|
socket.InsertedRepairOrder = InsertedRepairOrder;
|
|
|
|
|
} else {
|
|
|
|
|
CdkBase.createLogEvent(
|
|
|
|
|
socket,
|
|
|
|
|
"WARN",
|
|
|
|
|
`Repair order appears to already exist in PBS. ${matchingRo.RepairOrderNumber}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
CdkBase.createLogEvent(socket, "ERROR", `Error in CreateRepairOrderInPBS - ${error} - ${JSON.stringify(error)}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function RepairOrderGet(socket) {
|
|
|
|
|
try {
|
|
|
|
|
const { data: RepairOrderGet } = await axios.post(
|
|
|
|
|
PBS_ENDPOINTS.RepairOrderGet,
|
|
|
|
|
{
|
|
|
|
|
SerialNumber: socket.JobData.bodyshop.pbs_serialnumber,
|
|
|
|
|
//"RepairOrderId": "374728766",
|
|
|
|
|
//"RepairOrderNumber": "4" || socket.JobData.ro_number,
|
|
|
|
|
//"RawRepairOrderNumber": socket.JobData.ro_number,
|
|
|
|
|
// "Tag": "String",
|
|
|
|
|
//"ContactRef": socket.contactRef,
|
|
|
|
|
// "ContactRefList": ["00000000000000000000000000000000"],
|
|
|
|
|
VehicleRef: socket.vehicleRef?.ReferenceId || socket.vehicleRef?.VehicleId
|
|
|
|
|
// "VehicleRefList": ["00000000000000000000000000000000"],
|
|
|
|
|
// "Status": "String",
|
|
|
|
|
// "CashieredSince": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "CashieredUntil": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "OpenDateSince": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "OpenDateUntil": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
//"ModifiedSince": "2025-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "ModifiedUntil": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "Shop": "String"
|
|
|
|
|
},
|
|
|
|
|
{ auth: PBS_CREDENTIALS, socket }
|
|
|
|
|
);
|
|
|
|
|
CheckForErrors(socket, RepairOrderGet);
|
|
|
|
|
return RepairOrderGet;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
CdkBase.createLogEvent(socket, "ERROR", `Error in RepairOrderChange - ${error}`);
|
|
|
|
|
throw new Error(error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function RepairOrderChange(socket) {
|
|
|
|
|
try {
|
|
|
|
|
const { data: RepairOrderChangeResponse } = await axios.post(
|
|
|
|
|
PBS_ENDPOINTS.RepairOrderChange,
|
|
|
|
|
{
|
|
|
|
|
//Additional details at https://partnerhub.pbsdealers.com/json/metadata?op=RepairOrderChange
|
|
|
|
|
RepairOrderInfo: {
|
|
|
|
|
//"Id": "string/00000000-0000-0000-0000-000000000000",
|
|
|
|
|
//"RepairOrderId": "00000000000000000000000000000000",
|
|
|
|
|
SerialNumber: socket.JobData.bodyshop.pbs_serialnumber,
|
|
|
|
|
RepairOrderNumber: "00000000000000000000000000000000", //This helps force a new RO.
|
|
|
|
|
RawRepairOrderNumber: "00000000000000000000000000000000",
|
|
|
|
|
// "RepairOrderNumber": socket.JobData.ro_number, //These 2 values are ignored as confirmed by PBS.
|
|
|
|
|
// "RawRepairOrderNumber": socket.JobData.ro_number,
|
|
|
|
|
DateOpened: moment(),
|
|
|
|
|
// "DateOpenedUTC": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "DateCashiered": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "DateCashieredUTC": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
DatePromised: socket.JobData.scheduled_completion,
|
|
|
|
|
// "DatePromisedUTC": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
DateVehicleCompleted: socket.JobData.actual_completion,
|
|
|
|
|
// "DateCustomerNotified": "0001-01-01T00:00:00.0000000Z",
|
|
|
|
|
// "CSR": "String",
|
|
|
|
|
// "CSRRef": "00000000000000000000000000000000",
|
|
|
|
|
// "BookingUser": "String",
|
|
|
|
|
// "BookingUserRef": "00000000000000000000000000000000",
|
|
|
|
|
ContactRef: socket.ownerRef?.ReferenceId || socket.ownerRef?.ContactId,
|
|
|
|
|
VehicleRef: socket.vehicleRef?.ReferenceId || socket.vehicleRef?.VehicleId,
|
|
|
|
|
MileageIn: socket.JobData.km_in,
|
|
|
|
|
Tag: "BODYSHOP",
|
|
|
|
|
//"Status": "CLOSED", //Values here do not impact the status. Confirmed by PBS support.
|
|
|
|
|
Requests: [
|
|
|
|
|
{
|
|
|
|
|
// "RepairOrderRequestRef": "b1842ecad62c4279bbc2fef4f6bf6cde",
|
|
|
|
|
// "RepairOrderRequestId": 1,
|
|
|
|
|
// "CSR": "PBS",
|
|
|
|
|
// "CSRRef": "1ce12ac692564e94bda955d529ee911a",
|
|
|
|
|
// "Skill": "GEN",
|
|
|
|
|
RequestCode: "MISC",
|
|
|
|
|
RequestDescription: `VEHICLE REPAIRED AT BODYSHOP. PLEASE REFERENCE IMEX SHOP MANAGEMENT SYSTEM. ${socket.txEnvelope.story}`,
|
|
|
|
|
Status: "Completed",
|
|
|
|
|
// "TechRef": "00000000000000000000000000000000",
|
|
|
|
|
AllowedHours: 0,
|
|
|
|
|
EstimateLabour: 0,
|
|
|
|
|
EstimateParts: 0,
|
|
|
|
|
ComeBack: false,
|
|
|
|
|
AddedOperation: true,
|
|
|
|
|
PartLines: [],
|
|
|
|
|
PartRequestLines: [],
|
|
|
|
|
LabourLines: [],
|
|
|
|
|
SubletLines: [],
|
|
|
|
|
TimePunches: [],
|
|
|
|
|
Summary: {
|
|
|
|
|
Labour: 0,
|
|
|
|
|
Parts: 0,
|
|
|
|
|
OilGas: 0,
|
|
|
|
|
SubletTow: 0,
|
|
|
|
|
Misc: 0,
|
|
|
|
|
Environment: 0,
|
|
|
|
|
ShopSupplies: 0,
|
|
|
|
|
Freight: 0,
|
|
|
|
|
WarrantyDeductible: 0,
|
|
|
|
|
Discount: 0,
|
|
|
|
|
SubTotal: 0,
|
|
|
|
|
Tax1: 0,
|
|
|
|
|
Tax2: 0,
|
|
|
|
|
InvoiceTotal: 0,
|
|
|
|
|
CustomerDeductible: 0,
|
|
|
|
|
GrandTotal: 0,
|
|
|
|
|
LabourDiscount: 0,
|
|
|
|
|
PartDiscount: 0,
|
|
|
|
|
ServiceFeeTotal: 0,
|
|
|
|
|
OEMDiscount: 0
|
|
|
|
|
},
|
|
|
|
|
LineType: "RequestLine"
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
Memo: socket.txEnvelope.story
|
|
|
|
|
},
|
|
|
|
|
IsAsynchronous: false
|
|
|
|
|
// "UserRequest": "String",
|
|
|
|
|
// "UserRef": "00000000000000000000000000000000"
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{ auth: PBS_CREDENTIALS, socket }
|
|
|
|
|
);
|
|
|
|
|
CheckForErrors(socket, RepairOrderChangeResponse);
|
|
|
|
|
return RepairOrderChangeResponse;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
CdkBase.createLogEvent(socket, "ERROR", `Error in RepairOrderChange - ${error}`);
|
|
|
|
|
throw new Error(error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|