From 49e25a2c07b5d31635847fd9e1c38fa564bd7bb9 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Thu, 1 Apr 2021 16:24:44 -0700 Subject: [PATCH] IO-594 Autohouse Fixes. --- bodyshop_translations.babel | 42 ++ client/src/translations/en_us/common.json | 2 + client/src/translations/es/common.json | 2 + client/src/translations/fr/common.json | 2 + client/src/utils/TemplateConstants.js | 16 + client/yarn.lock | 13 - package-lock.json | 151 +++- package.json | 2 +- server/accounting/qbxml/qbxml-payables.js | 2 +- server/accounting/qbxml/qbxml-payments.js | 2 +- server/accounting/qbxml/qbxml-receivables.js | 2 +- server/data/autohouse.js | 720 +++++++++++-------- 12 files changed, 611 insertions(+), 345 deletions(-) diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index 365f84061..492b9225e 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -28071,6 +28071,48 @@ templates + + estimator_detail + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + estimator_summary + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + hours_sold_detail_closed false diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index b1bd87558..31f75e069 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -1697,6 +1697,8 @@ "vendor": "Vendor" }, "templates": { + "estimator_detail": "Jobs by Estimator (Detail)", + "estimator_summary": "Jobs by Estimator (Summary)", "hours_sold_detail_closed": "Hours Sold Detail - Closed", "hours_sold_detail_closed_source": "Hours Sold Detail - Closed by Source", "hours_sold_detail_open": "Hours Sold Detail - Open", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index aed271929..63d1e8887 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -1697,6 +1697,8 @@ "vendor": "" }, "templates": { + "estimator_detail": "", + "estimator_summary": "", "hours_sold_detail_closed": "", "hours_sold_detail_closed_source": "", "hours_sold_detail_open": "", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index b7c0f47c1..2684ce231 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -1697,6 +1697,8 @@ "vendor": "" }, "templates": { + "estimator_detail": "", + "estimator_summary": "", "hours_sold_detail_closed": "", "hours_sold_detail_closed_source": "", "hours_sold_detail_open": "", diff --git a/client/src/utils/TemplateConstants.js b/client/src/utils/TemplateConstants.js index d95ae9ad3..6ba044339 100644 --- a/client/src/utils/TemplateConstants.js +++ b/client/src/utils/TemplateConstants.js @@ -495,6 +495,22 @@ export const TemplateList = (type, context) => { //idtype: "vendor", disabled: false, }, + estimator_detail: { + title: i18n.t("reportcenter.templates.estimator_detail"), + description: "", + subject: i18n.t("reportcenter.templates.estimator_detail"), + key: "estimator_detail", + //idtype: "vendor", + disabled: false, + }, + estimator_summary: { + title: i18n.t("reportcenter.templates.estimator_summary"), + description: "", + subject: i18n.t("reportcenter.templates.estimator_summary"), + key: "estimator_summary", + //idtype: "vendor", + disabled: false, + }, } : {}), ...(!type || type === "courtesycarcontract" diff --git a/client/yarn.lock b/client/yarn.lock index 07cec907e..d6e8aa390 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -2178,14 +2178,6 @@ prop-types "^15.7.2" react-use "^17.2.1" -"@tinymce/tinymce-react@^3.10.3": - version "3.12.0" - resolved "https://registry.yarnpkg.com/@tinymce/tinymce-react/-/tinymce-react-3.12.0.tgz#165f197011b0fef3178f82168735e18ee28bd38a" - integrity sha512-Mi/nOsJ8CAVlcX+6YuvSvlFzJ2/n9rZ4iDrU2WX2u1wBTugHvKGca26JGEIT5wKRlfXGv49ymriWQz7w00v0NA== - dependencies: - prop-types "^15.6.2" - tinymce "^5.7.1" - "@types/anymatch@*": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -12852,11 +12844,6 @@ tinycolor2@^1.4.1: resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== -tinymce@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-5.7.1.tgz#658a6fb4c7d53a8496cc00f8da33f4b8290da06d" - integrity sha512-1gY8RClc734srSlkYwY0MQzmkS1j73PuPC+nYtNtrrQVPY9VNcZ4bOiRwzTbdjPPD8GOtv6BAk8Ww/H2RiqKpA== - tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" diff --git a/package-lock.json b/package-lock.json index 039148913..29265dc0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "phone": "^2.4.20", "stripe": "^8.137.0", "twilio": "^3.56.0", - "xmlbuilder": "^15.1.1" + "xmlbuilder2": "^2.4.0" }, "devDependencies": { "concurrently": "^6.0.0", @@ -424,6 +424,50 @@ "resolved": "https://registry.npmjs.org/@jonkemp/package-utils/-/package-utils-1.0.7.tgz", "integrity": "sha512-OoK+K1RmhtS8SlORrlH7sW0CNdrnm0BxKNcv4pQIk6y6VORsHiX91gV3dh6XD2eS7J+iCXROcu5sGuH0tjmNEQ==" }, + "node_modules/@oozcitak/dom": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.8.tgz", + "integrity": "sha512-MoOnLBNsF+ok0HjpAvxYxR4piUhRDCEWK0ot3upwOOHYudJd30j6M+LNcE8RKpwfnclAX9T66nXXzkytd29XSw==", + "dependencies": { + "@oozcitak/infra": "1.0.8", + "@oozcitak/url": "1.0.4", + "@oozcitak/util": "8.3.8" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@oozcitak/infra": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", + "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", + "dependencies": { + "@oozcitak/util": "8.3.8" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@oozcitak/url": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", + "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", + "dependencies": { + "@oozcitak/infra": "1.0.8", + "@oozcitak/util": "8.3.8" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@oozcitak/util": { + "version": "8.3.8", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", + "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==", + "engines": { + "node": ">=8.0" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -739,7 +783,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -4999,8 +5042,7 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "node_modules/stack-trace": { "version": "0.0.10", @@ -5805,12 +5847,36 @@ "node": ">=8" } }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "node_modules/xmlbuilder2": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-2.4.0.tgz", + "integrity": "sha512-KrOVUGD65xTQ7ZA+GMQGdBSpe1Ufu5ylCQSYVk6QostySDkxPmAQ0WWIu7dR3JjLfVbF22RFQX7KyrZ6VTLcQg==", + "dependencies": { + "@oozcitak/dom": "1.15.8", + "@oozcitak/infra": "1.0.8", + "@oozcitak/util": "8.3.8", + "@types/node": "14.6.2", + "js-yaml": "3.14.0" + }, "engines": { - "node": ">=8.0" + "node": ">=10.0" + } + }, + "node_modules/xmlbuilder2/node_modules/@types/node": { + "version": "14.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz", + "integrity": "sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==" + }, + "node_modules/xmlbuilder2/node_modules/js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/xregexp": { @@ -6196,6 +6262,38 @@ "resolved": "https://registry.npmjs.org/@jonkemp/package-utils/-/package-utils-1.0.7.tgz", "integrity": "sha512-OoK+K1RmhtS8SlORrlH7sW0CNdrnm0BxKNcv4pQIk6y6VORsHiX91gV3dh6XD2eS7J+iCXROcu5sGuH0tjmNEQ==" }, + "@oozcitak/dom": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.8.tgz", + "integrity": "sha512-MoOnLBNsF+ok0HjpAvxYxR4piUhRDCEWK0ot3upwOOHYudJd30j6M+LNcE8RKpwfnclAX9T66nXXzkytd29XSw==", + "requires": { + "@oozcitak/infra": "1.0.8", + "@oozcitak/url": "1.0.4", + "@oozcitak/util": "8.3.8" + } + }, + "@oozcitak/infra": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", + "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", + "requires": { + "@oozcitak/util": "8.3.8" + } + }, + "@oozcitak/url": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", + "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", + "requires": { + "@oozcitak/infra": "1.0.8", + "@oozcitak/util": "8.3.8" + } + }, + "@oozcitak/util": { + "version": "8.3.8", + "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", + "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==" + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -6469,7 +6567,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -9906,8 +10003,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "stack-trace": { "version": "0.0.10", @@ -10550,10 +10646,33 @@ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "optional": true }, - "xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==" + "xmlbuilder2": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-2.4.0.tgz", + "integrity": "sha512-KrOVUGD65xTQ7ZA+GMQGdBSpe1Ufu5ylCQSYVk6QostySDkxPmAQ0WWIu7dR3JjLfVbF22RFQX7KyrZ6VTLcQg==", + "requires": { + "@oozcitak/dom": "1.15.8", + "@oozcitak/infra": "1.0.8", + "@oozcitak/util": "8.3.8", + "@types/node": "14.6.2", + "js-yaml": "3.14.0" + }, + "dependencies": { + "@types/node": { + "version": "14.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz", + "integrity": "sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==" + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } }, "xregexp": { "version": "2.0.0", diff --git a/package.json b/package.json index 269814541..a678254b7 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "phone": "^2.4.20", "stripe": "^8.137.0", "twilio": "^3.56.0", - "xmlbuilder": "^15.1.1" + "xmlbuilder2": "^2.4.0" }, "devDependencies": { "concurrently": "^6.0.0", diff --git a/server/accounting/qbxml/qbxml-payables.js b/server/accounting/qbxml/qbxml-payables.js index 1c2dc3d2a..1c5571403 100644 --- a/server/accounting/qbxml/qbxml-payables.js +++ b/server/accounting/qbxml/qbxml-payables.js @@ -3,7 +3,7 @@ const path = require("path"); const DineroQbFormat = require("../accounting-constants").DineroQbFormat; const queries = require("../../graphql-client/queries"); const Dinero = require("dinero.js"); -var builder = require("xmlbuilder"); +var builder = require("xmlbuilder2"); const QbXmlUtils = require("./qbxml-utils"); const moment = require("moment"); diff --git a/server/accounting/qbxml/qbxml-payments.js b/server/accounting/qbxml/qbxml-payments.js index 522fad375..9d7c8b852 100644 --- a/server/accounting/qbxml/qbxml-payments.js +++ b/server/accounting/qbxml/qbxml-payments.js @@ -3,7 +3,7 @@ const path = require("path"); const DineroQbFormat = require("../accounting-constants").DineroQbFormat; const queries = require("../../graphql-client/queries"); const Dinero = require("dinero.js"); -var builder = require("xmlbuilder"); +var builder = require("xmlbuilder2"); const moment = require("moment"); const QbXmlUtils = require("./qbxml-utils"); const QbxmlReceivables = require("./qbxml-receivables"); diff --git a/server/accounting/qbxml/qbxml-receivables.js b/server/accounting/qbxml/qbxml-receivables.js index cb1c6a6e6..fd885695b 100644 --- a/server/accounting/qbxml/qbxml-receivables.js +++ b/server/accounting/qbxml/qbxml-receivables.js @@ -4,7 +4,7 @@ const DineroQbFormat = require("../accounting-constants").DineroQbFormat; const queries = require("../../graphql-client/queries"); const Dinero = require("dinero.js"); const moment = require("moment"); -var builder = require("xmlbuilder"); +var builder = require("xmlbuilder2"); const QbXmlUtils = require("./qbxml-utils"); require("dotenv").config({ path: path.resolve( diff --git a/server/data/autohouse.js b/server/data/autohouse.js index 8a8c00553..3d4b70abf 100644 --- a/server/data/autohouse.js +++ b/server/data/autohouse.js @@ -1,9 +1,9 @@ -const GraphQLClient = require("graphql-request").GraphQLClient; const path = require("path"); const queries = require("../graphql-client/queries"); const Dinero = require("dinero.js"); const moment = require("moment"); -var builder = require("xmlbuilder"); +var builder = require("xmlbuilder2"); +const _ = require("lodash"); require("dotenv").config({ path: path.resolve( @@ -11,325 +11,386 @@ require("dotenv").config({ `.env.${process.env.NODE_ENV || "development"}` ), }); + const client = require("../graphql-client/graphql-client").client; - +const AHDineroFormat = "0.00"; const AhDateFormat = "MMDDYYYY"; - exports.default = async (req, res) => { //Get Client Dataset. const { jobs } = await client.request(queries.AUTOHOUSE_QUERY); + const erroredJobs = []; + const autoHouseObject = { - AutoHouseExport: { RepairOrder: jobs.map((j) => CreateRepairOrderTag(j)) }, - }; - - var ret = builder - .create(autoHouseObject, { - version: "1.0", - encoding: "UTF-8", - headless: false, - }) - .end({ pretty: true }); - - res.type("application/xml"); - res.send(ret); -}; - -const CreateRepairOrderTag = (job) => { - //Level 2 - const ret = { - RepairOrderInformation: { - ShopInternalName: job.bodyshop.autohouseid, - ID: job.id, - RO: job.ro_number, - Est: job.id, //We no longer use estimate id. - GUID: job.id, - TransType: StatusMapping(job.status, job.bodyshop.md_ro_statuses), - ShopName: job.bodyshop.shopname, - ShopAddress: job.bodyshop.address1, - ShopCity: job.bodyshop.city, - ShopState: job.bodyshop.state, - ShopZip: job.bodyshop.zip_post, - ShopPhone: job.bodyshop.phone, - EstimatorID: `${job.est_ct_fn} ${job.est_ct_ln}`, - EstimatorName: `${job.est_ct_fn} ${job.est_ct_ln}`, - }, - CustomerInformation: { - FirstName: null, - LastName: null, - Street: null, - City: null, - State: null, - Zip: "N6G", - Phone1: null, - Phone2: null, - Phone2Extension: null, - Phone3: null, - Phone3Extension: null, - FileComments: null, - Source: null, - Email: null, - RetWhsl: null, - Cat: null, - InsuredorClaimantFlag: null, - }, - VehicleInformation: { - Year: job.v_model_yr, - Make: job.v_make_desc, - Model: job.v_model_desc, - VIN: job.v_vin, - License: job.plate_no, - MileageIn: job.kmin, - Vehiclecolor: job.v_color, - VehicleProductionDate: null, - VehiclePaintCode: null, - VehicleTrimCode: null, - VehicleBodyStyle: null, - DriveableFlag: job.tlos_ind ? "Y" : "N", - }, - - InsuranceInformation: { - InsuranceCo: job.ins_co_nm, - CompanyName: job.ins_co_nm, - Address: job.ins_addr1, - City: job.ins_addr1, - State: job.ins_city, - Zip: job.ins_zip, - Phone: job.ins_ph1, - Fax: null, - ClaimType: null, - LossType: null, - Policy: null, - Claim: job.clm_no, - InsuredLastName: null, - InsuredFirstName: null, - ClaimantLastName: null, - ClaimantFirstName: null, - Assignment: null, - InsuranceAgentLastName: null, - InsuranceAgentFirstName: null, - InsAgentPhone: null, - InsideAdjuster: null, - OutsideAdjuster: null, - }, - Dates: { - DateofLoss: job.loss_date && moment(job.loss_date).format(AhDateFormat), - InitialCustomerContactDate: null, - FirstFollowUpDate: null, - ReferralDate: null, - EstimateAppointmentDate: null, - SecondFollowUpDate: null, - AssignedDate: null, - EstComplete: null, - CustomerAuthorizationDate: null, - InsuranceAuthorizationDate: null, - DateOpened: job.date_open && moment(job.date_open).format(AhDateFormat), - ScheduledArrivalDate: - job.scheduled_in && moment(job.scheduled_in).format(AhDateFormat), - CarinShop: job.actual_in && moment(job.actual_in).format(AhDateFormat), - InsInspDate: null, - StartDate: null, - PartsOrder: null, - TeardownHold: null, - SupplementSubmittedDate: null, - SupplementApprovedDate: null, - AssntoBody: null, - AssntoMech: null, - AssntoPaint: null, - AssntoDetail: null, - PromiseDate: - job.scheduled_completion && - moment(job.scheduled_completion).format(AhDateFormat), - InsuranceTargetOut: null, - CarComplete: - job.actual_completion && - moment(job.actual_completion).format(AhDateFormat), - DeliveryAppointmentDate: - job.scheduled_delivery && - moment(job.scheduled_delivery).format(AhDateFormat), - DateClosed: - job.date_invoiced && moment(job.date_invoiced).format(AhDateFormat), - CustomerPaidInFullDate: null, - InsurancePaidInFullDate: null, - CustPickup: - job.actual_delivery && moment(job.actual_delivery).format(AhDateFormat), - AccountPostedDate: - job.date_exported && moment(job.date_exported).format(AhDateFormat), - CSIProcessedDate: null, - ThankYouLetterSent: null, - AdditionalFollowUpDate: null, - }, - Rates: { - BodyRate: job.rate_lab, - RefinishRate: job.rate_lar, - MechanicalRate: job.rate_lam, - StructuralRate: job.rate_las, - PMRate: job.rate_mapa, - BMRate: job.rate_mash, - TaxRate: null, - StorageRateperDay: null, - DaysStored: null, - }, - EstimateTotals: { - BodyHours: null, - RefinishHours: null, - MechanicalHours: null, - StructuralHours: null, - PartsTotal: null, - PartsOEM: null, - PartsAM: null, - PartsReconditioned: null, - PartsRecycled: null, - PartsOther: null, - SubletTotal: null, - BodyLaborTotal: null, - RefinishLaborTotal: null, - MechanicalLaborTotal: null, - StructuralLaborTotal: null, - MiscellaneousChargeTotal: null, - PMTotal: null, - BMTotal: null, - MiscTotal: null, - TowingTotal: null, - StorageTotal: null, - DetailTotal: null, - SalesTaxTotal: null, - GrossTotal: null, - DeductibleTotal: null, - DepreciationTotal: null, - Discount: null, - CustomerPay: null, - InsurancePay: null, - Deposit: null, - AmountDue: null, - }, - SupplementTotals: { - BodyHours: null, - RefinishHours: null, - MechanicalHours: null, - StructuralHours: null, - PartsTotal: null, - PartsOEM: null, - PartsAM: null, - PartsReconditioned: null, - PartsRecycled: null, - PartsOther: null, - SubletTotal: null, - BodyLaborTotal: null, - RefinishLaborTotal: null, - MechanicalLaborTotal: null, - StructuralLaborTotal: null, - MiscellaneousChargeTotal: null, - PMTotal: null, - BMTotal: null, - MiscTotal: null, - TowingTotal: null, - StorageTotal: null, - DetailTotal: null, - SalesTaxTotal: null, - GrossTotal: null, - DeductibleTotal: null, - DepreciationTotal: null, - Discount: null, - CustomerPay: null, - InsurancePay: null, - Deposit: null, - AmountDue: null, - }, - RevisedTotals: { - BodyHours: "10.10", - RefinishHours: "4.70", - MechanicalHours: "2.90", - StructuralHours: null, - PartsTotal: "2630.24", - PartsTotalCost: "1655.67", - PartsOEM: "969.49", - PartsOEMCost: "761.91", - PartsAM: "1660.75", - PartsAMCost: "893.76", - PartsReconditioned: null, - PartsReconditionedCost: null, - PartsRecycled: null, - PartsRecycledCost: null, - PartsOther: null, - PartsOtherCost: null, - SubletTotal: "139.95", - SubletTotalCost: "0.00", - BodyLaborTotal: "642.46", - BodyLaborTotalCost: "0.00", - RefinishLaborTotal: "298.97", - RefinishLaborTotalCost: "0.00", - MechanicalLaborTotal: "276.69", - MechanicalLaborTotalCost: "0.00", - StructuralLaborTotal: null, - StructuralLaborTotalCost: null, - MiscellaneousChargeTotal: null, - MiscellaneousChargeTotalCost: null, - PMTotal: "159.42", - PMTotalCost: "0.00", - BMTotal: "40.30", - BMTotalCost: "36.27", - MiscTotal: "60.00", - MiscTotalCost: "9.00", - TowingTotal: null, - TowingTotalCost: null, - StorageTotal: null, - StorageTotalCost: null, - DetailTotal: null, - DetailTotalCost: null, - SalesTaxTotal: "552.24", - SalesTaxTotalCost: null, - GrossTotal: "4800.27", - DeductibleTotal: "500.00", - DepreciationTotal: "0.00", - Discount: "0", - CustomerPay: "500.00", - InsurancePay: "4300.27", - Deposit: null, - AmountDue: "4800.27", - }, - Misc: { - ProductionStatus: null, - StatusDescription: null, - Hub50Comment: null, - DateofChange: null, - BodyTechName: null, - TotalLossYN: null, - InsScreenCommentsLine1: null, - InsScreenCommentsLine2: null, - AssignmentCaller: null, - AssignmentDivision: null, - LocationofPrimaryImpact: "12", - LocationofSecondaryImpact: null, - PaintTechID: null, - PaintTechName: null, - ImportType: null, - ImportFile: null, - GSTTax: null, - RepairDelayStatusCode: null, - RepairDelaycomment: null, - AgentMktgID: null, - AgentCity: null, - Picture1: null, - Picture2: null, - ExtNoteDate: null, - RentalOrdDate: null, - RentalPUDate: null, - RentalDueDate: null, - RentalActRetDate: null, - RentalCompanyID: null, - CSIID: null, - InsGroupCode: null, - }, - - DetailLines: { - DetailLine: job.joblines.map((jl) => - GenerateDetailLines(jl, job.bodyshop.md_order_statuses) + AutoHouseExport: { + RepairOrder: jobs.map((j) => + CreateRepairOrderTag(j, (job, error) => { + erroredJobs.push({ job, error }); + }) ), }, }; - return ret; + console.log("***Number of Failed jobs***: ", erroredJobs.length); + var ret = builder + .create(autoHouseObject, { + version: "1.0", + encoding: "UTF-8", + }) + .end({ pretty: true }); + + //***TODO Change filing naming when creating the cron job. IM_ShopInternalName_DDMMYYYY_HHMMSS.xml + res.type("application/xml"); + //res.sendFile(ret); + res.send(ret); +}; + +const CreateRepairOrderTag = (job, errorCallback) => { + //Level 2 + + try { + const ret = { + RepairOrderInformation: { + ShopInternalName: job.bodyshop.autohouseid, + ID: job.id, + RO: job.ro_number, + Est: job.id, //We no longer use estimate id. + GUID: job.id, + TransType: StatusMapping(job.status, job.bodyshop.md_ro_statuses), + ShopName: job.bodyshop.shopname, + ShopAddress: job.bodyshop.address1, + ShopCity: job.bodyshop.city, + ShopState: job.bodyshop.state, + ShopZip: job.bodyshop.zip_post, + ShopPhone: job.bodyshop.phone, + EstimatorID: `${job.est_ct_fn} ${job.est_ct_ln}`, + EstimatorName: `${job.est_ct_fn} ${job.est_ct_ln}`, + }, + CustomerInformation: { + FirstName: job.ownr_fn, + LastName: job.ownr_ln, + Street: job.ownr_addr1, + City: job.ownr_city, + State: job.ownr_st, + Zip: job.ownr_zip, + Phone1: job.ownr_ph1, + Phone2: null, + Phone2Extension: null, + Phone3: null, + Phone3Extension: null, + FileComments: null, + Source: null, + Email: job.ownr_ea, + RetWhsl: null, + Cat: null, + InsuredorClaimantFlag: null, + }, + VehicleInformation: { + Year: job.v_model_yr, + Make: job.v_make_desc, + Model: job.v_model_desc, + VIN: job.v_vin, + License: job.plate_no, + MileageIn: job.kmin, + Vehiclecolor: job.v_color, + VehicleProductionDate: null, + VehiclePaintCode: null, + VehicleTrimCode: null, + VehicleBodyStyle: null, + DriveableFlag: job.tlos_ind ? "Y" : "N", + }, + + InsuranceInformation: { + InsuranceCo: job.ins_co_nm, + CompanyName: job.ins_co_nm, + Address: job.ins_addr1, + City: job.ins_addr1, + State: job.ins_city, + Zip: job.ins_zip, + Phone: job.ins_ph1, + Fax: null, + ClaimType: null, + LossType: null, + Policy: null, + Claim: job.clm_no, + InsuredLastName: null, + InsuredFirstName: null, + ClaimantLastName: null, + ClaimantFirstName: null, + Assignment: null, + InsuranceAgentLastName: null, + InsuranceAgentFirstName: null, + InsAgentPhone: null, + InsideAdjuster: null, + OutsideAdjuster: null, + }, + Dates: { + DateofLoss: job.loss_date && moment(job.loss_date).format(AhDateFormat), + InitialCustomerContactDate: null, + FirstFollowUpDate: null, + ReferralDate: null, + EstimateAppointmentDate: null, + SecondFollowUpDate: null, + AssignedDate: null, + EstComplete: null, + CustomerAuthorizationDate: null, + InsuranceAuthorizationDate: null, + DateOpened: job.date_open && moment(job.date_open).format(AhDateFormat), + ScheduledArrivalDate: + job.scheduled_in && moment(job.scheduled_in).format(AhDateFormat), + CarinShop: job.actual_in && moment(job.actual_in).format(AhDateFormat), + InsInspDate: null, + StartDate: null, + PartsOrder: null, + TeardownHold: null, + SupplementSubmittedDate: null, + SupplementApprovedDate: null, + AssntoBody: null, + AssntoMech: null, + AssntoPaint: null, + AssntoDetail: null, + PromiseDate: + job.scheduled_completion && + moment(job.scheduled_completion).format(AhDateFormat), + InsuranceTargetOut: null, + CarComplete: + job.actual_completion && + moment(job.actual_completion).format(AhDateFormat), + DeliveryAppointmentDate: + job.scheduled_delivery && + moment(job.scheduled_delivery).format(AhDateFormat), + DateClosed: + job.date_invoiced && moment(job.date_invoiced).format(AhDateFormat), + CustomerPaidInFullDate: null, + InsurancePaidInFullDate: null, + CustPickup: + job.actual_delivery && + moment(job.actual_delivery).format(AhDateFormat), + AccountPostedDate: + job.date_exported && moment(job.date_exported).format(AhDateFormat), + CSIProcessedDate: null, + ThankYouLetterSent: null, + AdditionalFollowUpDate: null, + }, + Rates: { + BodyRate: job.rate_lab, + RefinishRate: job.rate_lar, + MechanicalRate: job.rate_lam, + StructuralRate: job.rate_las, + PMRate: job.rate_mapa, + BMRate: job.rate_mash, + TaxRate: null, + StorageRateperDay: null, + DaysStored: null, + }, + EstimateTotals: { + BodyHours: null, + RefinishHours: null, + MechanicalHours: null, + StructuralHours: null, + PartsTotal: null, + PartsOEM: null, + PartsAM: null, + PartsReconditioned: null, + PartsRecycled: null, + PartsOther: null, + SubletTotal: null, + BodyLaborTotal: null, + RefinishLaborTotal: null, + MechanicalLaborTotal: null, + StructuralLaborTotal: null, + MiscellaneousChargeTotal: null, + PMTotal: null, + BMTotal: null, + MiscTotal: null, + TowingTotal: null, + StorageTotal: null, + DetailTotal: null, + SalesTaxTotal: null, + GrossTotal: null, + DeductibleTotal: null, + DepreciationTotal: null, + Discount: null, + CustomerPay: null, + InsurancePay: null, + Deposit: null, + AmountDue: null, + }, + SupplementTotals: { + BodyHours: null, + RefinishHours: null, + MechanicalHours: null, + StructuralHours: null, + PartsTotal: null, + PartsOEM: null, + PartsAM: null, + PartsReconditioned: null, + PartsRecycled: null, + PartsOther: null, + SubletTotal: null, + BodyLaborTotal: null, + RefinishLaborTotal: null, + MechanicalLaborTotal: null, + StructuralLaborTotal: null, + MiscellaneousChargeTotal: null, + PMTotal: null, + BMTotal: null, + MiscTotal: null, + TowingTotal: null, + StorageTotal: null, + DetailTotal: null, + SalesTaxTotal: null, + GrossTotal: null, + DeductibleTotal: null, + DepreciationTotal: null, + Discount: null, + CustomerPay: null, + InsurancePay: null, + Deposit: null, + AmountDue: null, + }, + RevisedTotals: { + BodyHours: job.job_totals.rates.lab.hours, + RefinishHours: job.job_totals.rates.lar.hours, + MechanicalHours: job.job_totals.rates.lam.hours, + StructuralHours: job.job_totals.rates.las.hours, + PartsTotal: Dinero(job.job_totals.parts.parts.total).toFormat( + AHDineroFormat + ), + PartsTotalCost: 0, + PartsOEM: Dinero( + job.job_totals.parts.parts.list.PAN && + job.job_totals.parts.parts.list.PAN.total + ).toFormat(AHDineroFormat), + PartsOEMCost: 0, + PartsAM: Dinero( + job.job_totals.parts.parts.list.PAA && + job.job_totals.parts.parts.list.PAA.total + ).toFormat(AHDineroFormat), + PartsAMCost: 0, + PartsReconditioned: null, + PartsReconditionedCost: null, + PartsRecycled: Dinero( + job.job_totals.parts.parts.list.PAR && + job.job_totals.parts.parts.list.PAR.total + ).toFormat(AHDineroFormat), + PartsRecycledCost: null, + PartsOther: Dinero( + job.job_totals.parts.parts.list.PAO && + job.job_totals.parts.parts.list.PAO.total + ).toFormat(AHDineroFormat), + PartsOtherCost: null, + SubletTotal: Dinero(job.job_totals.parts.sublets.total).toFormat( + AHDineroFormat + ), + SubletTotalCost: 0, + BodyLaborTotal: Dinero(job.job_totals.rates.lab.total).toFormat( + AHDineroFormat + ), + BodyLaborTotalCost: 0, + RefinishLaborTotal: Dinero(job.job_totals.rates.lar.total).toFormat( + AHDineroFormat + ), + RefinishLaborTotalCost: 0, + MechanicalLaborTotal: Dinero(job.job_totals.rates.lam.total).toFormat( + AHDineroFormat + ), + MechanicalLaborTotalCost: 0, + StructuralLaborTotal: Dinero(job.job_totals.rates.las.total).toFormat( + AHDineroFormat + ), + StructuralLaborTotalCost: null, + MiscellaneousChargeTotal: null, + MiscellaneousChargeTotalCost: null, + PMTotal: Dinero(job.job_totals.rates.mapa.total).toFormat( + AHDineroFormat + ), + PMTotalCost: 0, + BMTotal: Dinero(job.job_totals.rates.mash.total).toFormat( + AHDineroFormat + ), + BMTotalCost: 0, + MiscTotal: 0, + MiscTotalCost: 0, + TowingTotal: Dinero(job.job_totals.additional.towing).toFormat( + AHDineroFormat + ), + TowingTotalCost: null, + StorageTotal: Dinero(job.job_totals.additional.storage).toFormat( + AHDineroFormat + ), + StorageTotalCost: null, + DetailTotal: null, + DetailTotalCost: null, + SalesTaxTotal: Dinero(job.job_totals.totals.local_tax) + .add(Dinero(job.job_totals.totals.state_tax)) + .add(Dinero(job.job_totals.totals.federal_tax)) + .toFormat(AHDineroFormat), + SalesTaxTotalCost: null, + GrossTotal: Dinero(job.job_totals.totals.net_repairs).toFormat( + AHDineroFormat + ), + DeductibleTotal: job.ded_amt, + DepreciationTotal: Dinero( + job.job_totals.totals.custPayable.dep_taxes + ).toFormat(AHDineroFormat), + Discount: Dinero(job.job_totals.additional.adjustments).toFormat( + AHDineroFormat + ), + CustomerPay: Dinero(job.job_totals.totals.custPayable.total).toFormat( + AHDineroFormat + ), + InsurancePay: 0, + Deposit: 0, + AmountDue: 0, + }, + Misc: { + ProductionStatus: null, + StatusDescription: null, + Hub50Comment: null, + DateofChange: null, + BodyTechName: null, + TotalLossYN: null, + InsScreenCommentsLine1: null, + InsScreenCommentsLine2: null, + AssignmentCaller: null, + AssignmentDivision: null, + LocationofPrimaryImpact: "12", + LocationofSecondaryImpact: null, + PaintTechID: null, + PaintTechName: null, + ImportType: null, + ImportFile: null, + GSTTax: null, + RepairDelayStatusCode: null, + RepairDelaycomment: null, + AgentMktgID: null, + AgentCity: null, + Picture1: null, + Picture2: null, + ExtNoteDate: null, + RentalOrdDate: null, + RentalPUDate: null, + RentalDueDate: null, + RentalActRetDate: null, + RentalCompanyID: null, + CSIID: null, + InsGroupCode: null, + }, + + DetailLines: { + DetailLine: + job.joblines.length > 0 + ? job.joblines.map((jl) => + GenerateDetailLines(jl, job.bodyshop.md_order_statuses) + ) + : [generateNullDetailLine()], + }, + }; + return ret; + } catch (error) { + errorCallback(job, error); + } }; const StatusMapping = (status, md_ro_statuses) => { @@ -367,7 +428,7 @@ const GenerateDetailLines = (line, statuses) => { line.billlines[0] && (line.billlines[0].actual_cost * line.billlines[0].quantity).toFixed(2), Critical: null, - Description: line.desc, + Description: line.line_desc, DiscountMarkup: null, InvoiceNumber: line.billlines[0] && line.billlines[0].bill.invoice_number, IOUPart: null, @@ -377,7 +438,7 @@ const GenerateDetailLines = (line, statuses) => { OriginalCost: null, OriginalInvoiceNumber: null, PriceEach: line.billlines[0] && line.billlines[0].actual_cost, - PartNumber: line.oem_partno, + PartNumber: _.escape(line.oem_partno), ProfitPercent: null, PurchaseOrderNumber: null, Qty: line.part_qty, @@ -397,3 +458,38 @@ const GenerateDetailLines = (line, statuses) => { }; return ret; }; + +const generateNullDetailLine = () => { + return { + BackOrdered: "0", + Cost: 0, + Critical: null, + Description: "No Lines on Estimate", + DiscountMarkup: null, + InvoiceNumber: null, + IOUPart: null, + LineNumber: 0, + MarkUp: null, + OrderedOn: null, + OriginalCost: null, + OriginalInvoiceNumber: null, + PriceEach: 0, + PartNumber: 0, + ProfitPercent: null, + PurchaseOrderNumber: null, + Qty: 0, + Status: null, + SupplementNumber: null, + Type: null, + Vendor: null, + VendorPaid: null, + VendorPrice: null, + Deleted: null, + ExpectedOn: null, + ReceivedOn: null, + OrderedBy: null, + ShipVia: null, + VendorContact: null, + EstimateAmount: null, + }; +};