ARMS Updates

This commit is contained in:
Patrick Fic
2022-01-19 08:38:03 -08:00
parent 34ae2c56b7
commit bf81c6dd06
2 changed files with 191 additions and 168 deletions

View File

@@ -2,6 +2,7 @@ const path = require("path");
const queries = require("../graphql-client/queries"); const queries = require("../graphql-client/queries");
const Dinero = require("dinero.js"); const Dinero = require("dinero.js");
const moment = require("moment"); const moment = require("moment");
const fs = require("fs");
const _ = require("lodash"); const _ = require("lodash");
const logger = require("../utils/logger"); const logger = require("../utils/logger");
@@ -28,7 +29,6 @@ exports.default = async (req, res) => {
logger.log("arms-start", "DEBUG", "api", null, null); logger.log("arms-start", "DEBUG", "api", null, null);
const { bodyshops } = await client.request(queries.GET_ENTEGRAL_SHOPS); const { bodyshops } = await client.request(queries.GET_ENTEGRAL_SHOPS);
const allxmlsToUpload = [];
const allErrors = []; const allErrors = [];
try { try {
for (const bodyshop of bodyshops) { for (const bodyshop of bodyshops) {
@@ -40,10 +40,12 @@ exports.default = async (req, res) => {
const { jobs } = await client.request(queries.ENTEGRAL_EXPORT, { const { jobs } = await client.request(queries.ENTEGRAL_EXPORT, {
bodyshopid: bodyshop.id, bodyshopid: bodyshop.id,
}); });
const ret = jobs.map((job) => { const jobsToPush = [];
jobs.forEach((job) => {
const transId = uuid(); // Can this actually be the job id? const transId = uuid(); // Can this actually be the job id?
return { let obj = {
RqUID: transId, RqUID: transId,
DocumentInfo: { DocumentInfo: {
BMSVer: "4.0.0", BMSVer: "4.0.0",
@@ -55,16 +57,18 @@ exports.default = async (req, res) => {
TransmitDateTime: moment().format(momentFormat), // Omitted from ARMS docs TransmitDateTime: moment().format(momentFormat), // Omitted from ARMS docs
}, },
EventInfo: { EventInfo: {
AssignmentEvent: { // AssignmentEvent: {
CreateDateTime: // CreateDateTime:
job.asgn_date && moment(job.asgn_date).format(momentFormat), // job.asgn_date && moment(job.asgn_date).format(momentFormat),
}, // },
EstimateEvent: { // EstimateEvent: {
UploadDateTime: moment().format(momentFormat), // UploadDateTime: moment().format(momentFormat),
}, // },
RepairEvent: { RepairEvent: {
CreatedDateTime: CreatedDateTime: (job.date_open
job.date_open && moment(job.date_open).format(momentFormat), ? moment(job.date_open)
: moment()
).format(momentFormat),
ArrivalDateTime: ArrivalDateTime:
job.actual_in && moment(job.actual_in).format(momentFormat), job.actual_in && moment(job.actual_in).format(momentFormat),
ArrivalOdometerReading: job.kmin, ArrivalOdometerReading: job.kmin,
@@ -92,35 +96,35 @@ exports.default = async (req, res) => {
IDQualifierCode: "US", IDQualifierCode: "US",
IDNum: 44, // ** Not sure where to get this entegral ID from? IDNum: 44, // ** Not sure where to get this entegral ID from?
}, },
Communications: [ // Communications: [
{ // {
CommQualifier: "WA", // CommQualifier: "WA",
Address: { // Address: {
Address1: job.ins_addr1, // Address1: job.ins_addr1,
Address2: job.ins_addr2, // Address2: job.ins_addr2,
City: job.ins_city, // City: job.ins_city,
StateProvince: job.ins_st, // StateProvince: job.ins_st,
PostalCode: job.ins_zip, // PostalCode: job.ins_zip,
CountryCode: job.ins_ctry, // CountryCode: job.ins_ctry,
}, // },
}, // },
{ // {
CommQualifier: "WP", // CommQualifier: "WP",
CommPhone: job.ins_ph1, // CommPhone: job.ins_ph1,
}, // },
{ // {
CommQualifier: "WF", // CommQualifier: "WF",
CommPhone: job.ins_ph2, // CommPhone: job.ins_ph2,
}, // },
], // ],
},
ContactInfo: {
ContactJobTitle: "Adjuster",
ContactName: {
FirstName: job.est_ct_fn,
LastName: job.est_ct_ln,
},
}, },
// ContactInfo: {
// ContactJobTitle: "Adjuster",
// ContactName: {
// FirstName: job.est_ct_fn,
// LastName: job.est_ct_ln,
// },
// },
}, },
}, },
// InsuranceAgent: { // InsuranceAgent: {
@@ -141,16 +145,16 @@ exports.default = async (req, res) => {
// }, // },
// }, // },
// }, // },
Insured: { // Insured: {
Party: { // Party: {
PersonInfo: { // PersonInfo: {
PersonName: { // PersonName: {
FirstName: job.insd_fn, // FirstName: job.insd_fn,
LastName: job.insd_ln, // LastName: job.insd_ln,
}, // },
}, // },
}, // },
}, // },
Owner: { Owner: {
Party: { Party: {
PersonInfo: { PersonInfo: {
@@ -158,68 +162,70 @@ exports.default = async (req, res) => {
FirstName: job.ownr_fn, FirstName: job.ownr_fn,
LastName: job.ownr_ln, LastName: job.ownr_ln,
}, },
Communications: [ // Communications: [
{ // {
CommQualifier: "HA", // CommQualifier: "HA",
Address: { // Address: {
Address1: job.ownr_addr1, // Address1: job.ownr_addr1,
City: job.ownr_city, // City: job.ownr_city,
StateProvince: job.ownr_st, // StateProvince: job.ownr_st,
PostalCode: job.ownr_zip, // PostalCode: job.ownr_zip,
CountryCode: job.ownr_ctry, // CountryCode: job.ownr_ctry,
}, // },
}, // },
{ // {
CommQualifier: "HP", // CommQualifier: "HP",
CommPhone: job.ownr_ph1, // CommPhone: job.ownr_ph1,
}, // },
{ // {
CommQualifier: "WP", // CommQualifier: "WP",
CommPhone: job.ownr_ph2, // CommPhone: job.ownr_ph2,
}, // },
{ // {
CommQualifier: "CP", // CommQualifier: "CP",
CommPhone: job.ownr_ph1, // CommPhone: job.ownr_ph1,
}, // },
{ // {
CommQualifier: "EM", // CommQualifier: "EM",
CommEmail: job.ownr_ea, // CommEmail: job.ownr_ea,
}, // },
], // ],
},
},
},
Claimant: {
Party: {
PersonInfo: {
PersonName: {
FirstName: job.clm_ct_fn,
LastName: job.clm_ct_ln,
},
},
},
OwnerInd: true,
},
Estimator: {
Party: {
PersonInfo: {
PersonName: {
FirstName: job.est_ct_fn,
LastName: job.est_ct_ln,
},
// IDInfo: {
// IDQualifierCode: "US",
// IDNum: 2941,
// },
}, },
}, },
}, },
// Claimant: {
// Party: {
// PersonInfo: {
// PersonName: {
// FirstName: job.clm_ct_fn,
// LastName: job.clm_ct_ln,
// },
// },
// },
// OwnerInd: true,
// },
// Estimator: {
// Party: {
// PersonInfo: {
// PersonName: {
// FirstName: job.est_ct_fn,
// LastName: job.est_ct_ln,
// },
// // IDInfo: {
// // IDQualifierCode: "US",
// // IDNum: 2941,
// // },
// },
// },
// },
RepairFacility: { RepairFacility: {
//This section not in documentation.
Party: { Party: {
OrgInfo: { OrgInfo: {
CompanyName: bodyshop.shopname, CompanyName:
process.env.NODE_ENV === "production"
? bodyshop.shopname
: "IMEX Test Shop",
IDInfo: { IDInfo: {
IDQualifierCode: "US", IDQualifierCode: "US",
IDNum: bodyshop.entegral_id, IDNum: bodyshop.entegral_id,
@@ -233,7 +239,7 @@ exports.default = async (req, res) => {
// VendorCode: "C", // VendorCode: "C",
// EstimateDocumentID: "1223HJ76", // EstimateDocumentID: "1223HJ76",
}, },
//RepairOrderType: "DRP", RepairOrderType: "DirectRepairProgram", //Need to get from Entegral
//ReferralSourceType: "Yellow Pages", //ReferralSourceType: "Yellow Pages",
VehicleInfo: { VehicleInfo: {
VINInfo: { VINInfo: {
@@ -241,9 +247,9 @@ exports.default = async (req, res) => {
VINNum: job.v_vin, VINNum: job.v_vin,
}, },
}, },
License: { // License: {
LicensePlateNum: job.plate_no, // LicensePlateNum: job.plate_no,
}, // },
VehicleDesc: { VehicleDesc: {
//ProductionDate: "2009-10", //ProductionDate: "2009-10",
ModelYear: ModelYear:
@@ -255,23 +261,23 @@ exports.default = async (req, res) => {
MakeDesc: job.v_make_desc, MakeDesc: job.v_make_desc,
ModelName: job.v_model_desc, ModelName: job.v_model_desc,
}, },
Paint: { // Paint: {
Exterior: { // Exterior: {
Color: { // Color: {
ColorName: job.v_color, // ColorName: job.v_color,
// OEMColorCode: "1M3", // // OEMColorCode: "1M3",
}, // },
}, // },
}, // },
// Body: { // Body: {
// BodyStyle: "2 Door Convertible", // BodyStyle: "2 Door Convertible",
// Trim: { // Trim: {
// TrimCode: "1B3", // TrimCode: "1B3",
// }, // },
// }, // },
Condition: { // Condition: {
DrivableInd: job.driveable ? "Y" : "N", // DrivableInd: job.driveable ? "Y" : "N",
}, // },
}, },
ClaimInfo: { ClaimInfo: {
ClaimNum: job.clm_no, ClaimNum: job.clm_no,
@@ -296,7 +302,7 @@ exports.default = async (req, res) => {
}, },
}, },
ProfileInfo: { ProfileInfo: {
//ProfileName: "Shop Standard Rates", ProfileName: "ImEX",
RateInfo: [ RateInfo: [
{ {
RateType: "PA", RateType: "PA",
@@ -306,7 +312,7 @@ exports.default = async (req, res) => {
TaxableInd: true, TaxableInd: true,
TaxTierInfo: { TaxTierInfo: {
TierNum: 1, TierNum: 1,
Percentage: 0, //TODO Find the best place to take the tax rates for parts. Percentage: job.parts_tax_rates.PAN.prt_tax_rt * 100, //TODO Find the best place to take the tax rates for parts.
}, },
}, },
}, },
@@ -318,7 +324,7 @@ exports.default = async (req, res) => {
TaxableInd: true, TaxableInd: true,
TaxTierInfo: { TaxTierInfo: {
TierNum: 1, TierNum: 1,
Percentage: 0, //TODO Find the best place to take the tax rates for labor. Percentage: job.parts_tax_rates.PAN.prt_tax_rt * 100, //TODO Find the best place to take the tax rates for labor.
}, },
}, },
}, },
@@ -495,56 +501,56 @@ exports.default = async (req, res) => {
TotalType: "PAA", TotalType: "PAA",
TotalTypeDesc: "Aftermarket Parts", TotalTypeDesc: "Aftermarket Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.paa && job.job_totals.parts.parts.list.PAA &&
job.job_totals.parts.parts.list.paa.total job.job_totals.parts.parts.list.PAA.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
{ {
TotalType: "PAC", TotalType: "PAC",
TotalTypeDesc: "Re-Chromed Parts", TotalTypeDesc: "Re-Chromed Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.pac && job.job_totals.parts.parts.list.PAC &&
job.job_totals.parts.parts.list.pac.total job.job_totals.parts.parts.list.PAC.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
{ {
TotalType: "PAG", TotalType: "PAG",
TotalTypeDesc: "Glass Parts", TotalTypeDesc: "Glass Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.pag && job.job_totals.parts.parts.list.PAG &&
job.job_totals.parts.parts.list.pag.total job.job_totals.parts.parts.list.PAG.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
{ {
TotalType: "PAL", TotalType: "PAL",
TotalTypeDesc: "LKQ/Used Parts", TotalTypeDesc: "LKQ/Used Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.pal && job.job_totals.parts.parts.list.PAL &&
job.job_totals.parts.parts.list.pal.total job.job_totals.parts.parts.list.PAL.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
{ {
TotalType: "PAM", TotalType: "PAM",
TotalTypeDesc: "Remanufactured Parts", TotalTypeDesc: "Remanufactured Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.pam && job.job_totals.parts.parts.list.PAM &&
job.job_totals.parts.parts.list.pam.total job.job_totals.parts.parts.list.PAM.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
{ {
TotalType: "PAN", TotalType: "PAN",
TotalTypeDesc: "New Parts", TotalTypeDesc: "New Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.pan && job.job_totals.parts.parts.list.PAN &&
job.job_totals.parts.parts.list.pan.total job.job_totals.parts.parts.list.PAN.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
{ {
TotalType: "PAR", TotalType: "PAR",
TotalTypeDesc: "Recored Parts", TotalTypeDesc: "Recored Parts",
TotalAmt: Dinero( TotalAmt: Dinero(
job.job_totals.parts.parts.list.par && job.job_totals.parts.parts.list.PAR &&
job.job_totals.parts.parts.list.par.total job.job_totals.parts.parts.list.PAR.total
).toFormat("0.00"), ).toFormat("0.00"),
}, },
], ],
@@ -616,6 +622,14 @@ exports.default = async (req, res) => {
"0.00" "0.00"
), ),
}, },
{
TotalType: "TOT",
TotalSubType: "SM",
TotalTypeDesc: "Supplement Total",
TotalAmt: job.cieca_ttl
? job.cieca_ttl.data.supp_amt
: Dinero().toFormat("0.00"),
},
{ {
TotalType: "TOT", TotalType: "TOT",
TotalSubType: "F7", TotalSubType: "F7",
@@ -632,12 +646,14 @@ exports.default = async (req, res) => {
"0.00" "0.00"
), ),
}, },
// { {
// TotalType: "TOT", TotalType: "TOT",
// TotalSubType: "SM", TotalSubType: "D8",
// TotalTypeDesc: "Supplement Total", TotalTypeDesc: "Bottom Line Discount",
// TotalAmt: 0, TotalAmt: Dinero(
// }, job.job_totals.additional.adjustments
).toFormat("0.00"),
},
{ {
TotalType: "TOT", TotalType: "TOT",
TotalSubType: "D2", TotalSubType: "D2",
@@ -658,15 +674,13 @@ exports.default = async (req, res) => {
TotalType: "TOT", TotalType: "TOT",
TotalSubType: "AA", TotalSubType: "AA",
TotalTypeDesc: "Appearance Allowance", TotalTypeDesc: "Appearance Allowance",
TotalAmt: 0, TotalAmt: Dinero().toFormat("0.00"),
}, },
{ {
TotalType: "TOT", TotalType: "TOT",
TotalSubType: "D8", TotalSubType: "DEPOSIT",
TotalTypeDesc: "Bottom Line Discount", TotalTypeDesc: "Deposit",
TotalAmt: Dinero( TotalAmt: Dinero().toFormat("0.00"),
job.job_totals.additional.adjustments
).toFormat("0.00"),
}, },
{ {
TotalType: "TOT", TotalType: "TOT",
@@ -676,12 +690,6 @@ exports.default = async (req, res) => {
.subtract(Dinero(job.job_totals.totals.custPayable.total)) .subtract(Dinero(job.job_totals.totals.custPayable.total))
.toFormat("0.00"), .toFormat("0.00"),
}, },
// {
// TotalType: "TOT",
// TotalSubType: "DEPOSIT",
// TotalTypeDesc: "Deposit",
// TotalAmt: 0,
// },
{ {
TotalType: "TOT", TotalType: "TOT",
TotalSubType: "CUST", TotalSubType: "CUST",
@@ -691,7 +699,7 @@ exports.default = async (req, res) => {
).toFormat("0.00"), ).toFormat("0.00"),
}, },
], ],
RepairTotalsType: 1, // RepairTotalsType: 1,
}, },
// RepairLabor: { // RepairLabor: {
// LaborAllocations: { // LaborAllocations: {
@@ -741,7 +749,7 @@ exports.default = async (req, res) => {
// }, // },
ProductionStatus: { ProductionStatus: {
ProductionStage: { ProductionStage: {
ProductionStageCode: GetProductionStageCode(job), ProductionStageCode: GetProductionStageCode(job, bodyshop),
ProductionStageDateTime: moment().format(momentFormat), ProductionStageDateTime: moment().format(momentFormat),
// ProductionStageStatusComment: // ProductionStageStatusComment:
// "Going to be painted this afternoon", // "Going to be painted this afternoon",
@@ -777,6 +785,9 @@ exports.default = async (req, res) => {
// }, // },
// }, // },
}; };
deleteNullKeys(obj);
jobsToPush.push(obj);
}); });
if (erroredJobs.length > 0) { if (erroredJobs.length > 0) {
@@ -784,13 +795,12 @@ exports.default = async (req, res) => {
count: erroredJobs.length, count: erroredJobs.length,
jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number)), jobs: JSON.stringify(erroredJobs.map((j) => j.job.ro_number)),
}); });
allErrors = [...allErrors, ...erroredJobs];
} }
logger.log("arms-end-shop-extract", "DEBUG", "api", bodyshop.id, { logger.log("arms-end-shop-extract", "DEBUG", "api", bodyshop.id, {
shopname: bodyshop.shopname, shopname: bodyshop.shopname,
}); });
const abc = ret[1];
deleteNullKeys(abc);
try { try {
const entegralSoapClient = await soap.createClientAsync( const entegralSoapClient = await soap.createClientAsync(
@@ -798,7 +808,7 @@ exports.default = async (req, res) => {
{ {
ignoredNamespaces: true, ignoredNamespaces: true,
wsdl_options: { wsdl_options: {
useEmptyTag: true, // useEmptyTag: true,
}, },
wsdl_headers: { wsdl_headers: {
Authorization: `Basic ${new Buffer.from( Authorization: `Basic ${new Buffer.from(
@@ -816,14 +826,20 @@ exports.default = async (req, res) => {
); );
const entegralResponse = const entegralResponse =
await entegralSoapClient.RepairOrderFolderAddRqAsync(abc); await entegralSoapClient.RepairOrderFolderAddRqAsync(
jobsToPush,
function (err, result, rawResponse, soapHeader, rawRequest) {
fs.writeFileSync(`./logs/arms-request.xml`, rawRequest);
fs.writeFileSync(`./logs/arms-response.xml`, rawResponse);
res.json(err || result);
}
);
const [result, rawResponse, , rawRequest] = entegralResponse; const [result, rawResponse, , rawRequest] = entegralResponse;
console.log("🚀 ~ file: arms.js ~ line 806 ~ result", result);
res.json({ result, obj: abc });
} catch (error) { } catch (error) {
fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml);
console.log(error); console.log(error);
res.json(error);
} }
} catch (error) { } catch (error) {
//Error at the shop level. //Error at the shop level.
@@ -846,15 +862,18 @@ exports.default = async (req, res) => {
} }
} }
// res.sendStatus(200); res.sendStatus(200);
} catch (error) { } catch (error) {
res.status(200).json(error); res.status(200).json(error);
} }
}; };
function GetSupplementNumber(joblines) { function GetSupplementNumber(joblines) {
return 0; const max = _.max(
return _.max(joblines.map((jl) => jl.line_ind)); joblines.map((jl) => parseInt((jl.line_ind || "0").replace(/[^\d.-]/g, "")))
);
return max || 0;
} }
function GetDocumentstatus(job, bodyshop) { function GetDocumentstatus(job, bodyshop) {
@@ -873,7 +892,9 @@ function GetDocumentstatus(job, bodyshop) {
function GetRepairStatusCode(job) { function GetRepairStatusCode(job) {
return "25"; return "25";
} }
function GetProductionStageCode(job) { function GetProductionStageCode(job, bodyshop) {
if (bodyshop.md_ro_statuses.post_production_statuses.includes(job.status))
return "8D";
return "33"; return "33";
} }

View File

@@ -783,6 +783,8 @@ query ENTEGRAL_EXPORT($bodyshopid: uuid!) {
rate_matd rate_matd
job_totals job_totals
ded_amt ded_amt
cieca_ttl
adjustment_bottom_line
} }
} }
`; `;