diff --git a/electron/changelog.json b/electron/changelog.json index ff88da2..8498c8b 100644 --- a/electron/changelog.json +++ b/electron/changelog.json @@ -193,5 +193,10 @@ "title": "Release Notes for 1.4.0", "date": "06/17/2025", "notes": "New Features: \r\n* Added a scenario manager to scorecards to dynamically remove and add jobs to see impacts without adjusting dates.\r\n* Added ability to print a job. \r\n\r\nImprovements:\r\n* Added dark mode for app.\r\n* Added variance dollars to the scorecard.\r\n* Adjusted layout of job details to more prominently display savings information." + }, + "1.4.1": { + "title": "Release Notes for 1.4.1", + "date": "07/04/2025", + "notes": "Improvements:\r\n* Increased performance of scenario manager.\r\n* Report lines will now display better on smaller screens." } } diff --git a/electron/estimate-scrubber/A.json b/electron/estimate-scrubber/A.json new file mode 100644 index 0000000..b1b6419 --- /dev/null +++ b/electron/estimate-scrubber/A.json @@ -0,0 +1,584 @@ +{ + "__typename": "jobs", + "ownr_fn": "", + "ownr_ln": "Customer", + "ownr_addr1": null, + "ownr_city": null, + "ownr_ph1": null, + "v_vin": "1G------", + "v_model_yr": "16", + "v_model": "Envoy", + "v_makedesc": "GMC", + "id": "6408d399-2a65-40cd-a4ea-1d416f865ad3", + "ins_co_nm": "MPI", + "clm_no": "73417632-01", + "clm_total": 7380.49, + "ro_number": null, + "updated_at": "2025-05-09T15:58:28.795165+00:00", + "group": "Group 12", + "group_verified": false, + "v_age": 19, + "v_type": "SUV", + "loss_date": "2024-11-22", + "close_date": null, + "requires_reimport": false, + "created_at": "2025-04-24T23:36:11.4287+00:00", + "v_mileage": 157269, + "db_date": "1/26/2025", + "policy_no": null, + "ded_amt": null, + "claim_no": null, + "est_ct_ln": null, + "est_ct_fn": null, + "rf_addr1": null, + "rf_city": null, + "rf_zip": "R0G 1Z0", + "rf_ph1": "2043792253", + "loss_type": null, + "impact_1": null, + "impact_2": null, + "v_prod_dt": null, + "v_color": null, + "dmg_memo": null, + "ins_co_name": null, + "plate_st": null, + "plate_no": null, + "g_ttl_amt": "4000.99", + "ttl_t_amt_pat": "500.99", + "sending_entity_id": "87330f61-412b-4251-baaa-d026565b23c5", + "sending_entity_clientid": "", + "sending_entity_accept_terms_of_use": true, + "profileid": "", + "association_switch": "ATAM", + "supp_amt": "5000", + "create_dt": "5/21/2025", + "loss_desc": "Collision", + "v_stage": "3", + "g_bett_amt": "49.44", + "supp_no": "0", + + "ca": [ + { + "ttl_typecd": "LAB", + "t_amt": "100", + "t_hrs": "0.0", + "nt_hrs": "0.0" + }, + { + "ttl_typecd": "LAR", + "t_amt": "75", + "t_hrs": "0.0", + "nt_hrs": "0.0" + }, + { + "ttl_typecd": "LAF", + "t_amt": "200", + "t_hrs": "0.0", + "nt_hrs": "0.0" + }, + { + "ttl_typecd": "LAM", + "t_amt": "150", + "t_hrs": "0.0", + "nt_hrs": "0.0" + }, + + { + "ttl_typecd": "PAT", + "t_amt": "500", + "nt_amt": "500" + }, + { + "ttl_typecd": "TOT", + "t_amt": "3500" + } + ], + + "rates": [ + { + "lbr_desc": "LABOR-BODY", + "lbr_rate": "1.23" + }, + { + "lbr_desc": "LABOR-BODY_S", + "lbr_rate": "2.34" + }, + { + "lbr_desc": "LABOR-REFINISH", + "lbr_rate": "2.34" + }, + { + "lbr_desc": "LABOR-FRAME", + "lbr_rate": "2.34" + }, + { + "lbr_desc": "LABOR-MECHANICAL", + "lbr_rate": "2.34" + }, + { + "lbr_desc": "LABOR-GLASS", + "lbr_rate": "2.34" + }, + { + "lbr_desc": "PDR", + "lbr_rate": "2.34" + }, + { + "mat_type": "MAPA", + "cal_prethr": "69.45" + }, + { + "mat_type": "MASH", + "cal_prethr": "7.81" + } + ], + + + "joblines": [ + { + "__typename": "joblines", + "LINE_NO": 1, + "LINE_IND": "", + "DB_REF": "201089", + "LINE_DESC": "Frt Bumper Cover Assy", + "PART_TYPE": "PAE", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "PAN", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "FALSE", + "DB_PRICE": "0.00", + "ACT_PRICE": "0.00", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAB", + "DB_HRS": "2.8", + "MOD_LB_HRS": "1.8", + "LBR_INC": "FALSE", + "LBR_OP": "OP5", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "159.17", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 2, + "LINE_IND": "S1", + "DB_REF": "201385", + "LINE_DESC": "R Fender Wheel Opening Mldg", + "PART_TYPE": "", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "FALSE", + "ACT_PRICE": "0.00", + "DB_PRICE": "0.00", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAB", + "DB_HRS": ".4", + "MOD_LB_HRS": "0", + "LBR_INC": "TRUE", + "LBR_OP": "OP2", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 3, + "LINE_IND": "E", + "DB_REF": "200599", + "LINE_DESC": "Frt Bumper Cover", + "PART_TYPE": "PAA", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "04711-3A0-A00ZZ", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "FALSE", + "DB_PRICE": "450.68", + "ACT_PRICE": "320.97", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "TRUE", + "ALT_PARTNO": "HO1014109", + "MOD_LBR_TY": "LAB", + "DB_HRS": "2.8", + "MOD_LB_HRS": "0", + "LBR_INC": "TRUE", + "LBR_OP": "OP11", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 4, + "LINE_IND": "E", + "DB_REF": "900501", + "LINE_DESC": "OEM MATCHED AM/ Part# 04711-3A0-A00ZZ", + "PART_TYPE": "", + "PART_DESCJ": "TRUE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "FALSE", + "DB_PRICE": "0.00", + "ACT_PRICE": "0.00", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "TRUE", + "ALT_PARTNO": "HO1014109", + "MOD_LBR_TY": "", + "DB_HRS": "0.0", + "MOD_LB_HRS": "0.0", + "LBR_INC": "FALSE", + "LBR_OP": "OP0", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 5, + "LINE_IND": "E", + "DB_REF": "200001", + "LINE_DESC": "Frt Bumper Cover", + "PART_TYPE": "", + "PART_DESCJ": "TRUE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "FALSE", + "DB_PRICE": "0.00", + "ACT_PRICE": "0.00", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAR", + "DB_HRS": "2.5", + "MOD_LB_HRS": "2.5", + "LBR_INC": "FALSE", + "LBR_OP": "OP6", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 6, + "LINE_IND": "E", + "DB_REF": "201386", + "LINE_DESC": "L Fender Wheel Opening Mldg", + "PART_TYPE": "", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "FALSE", + "DB_PRICE": "0.00", + "ACT_PRICE": "0.00", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAB", + "DB_HRS": "0.4", + "MOD_LB_HRS": "0.4", + "LBR_INC": "FALSE", + "LBR_OP": "OP2", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 7, + "LINE_IND": "E", + "DB_REF": "200746", + "LINE_DESC": "Frt Bumper Mounting Bracket", + "PART_TYPE": "PAN", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "71172-3A0-A00", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "3.46", + "ACT_PRICE": "3.46", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAB", + "DB_HRS": "0.0", + "MOD_LB_HRS": "0.1", + "LBR_INC": "FALSE", + "LBR_OP": "OP11", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "TRUE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 8, + "LINE_IND": "E", + "DB_REF": "201314", + "LINE_DESC": "R Frt Door Shell (Steel/Hss)", + "PART_TYPE": "PAE", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "71172-3A0-A00", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "1528.35", + "ACT_PRICE": "0.00", + "PRICE_J": "FALSE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAB", + "DB_HRS": "0.0", + "MOD_LB_HRS": "4.5", + "LBR_INC": "FALSE", + "LBR_OP": "OP9", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "TRUE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 9, + "LINE_IND": "E", + "DB_REF": "936009", + "LINE_DESC": "Estimate Charge", + "PART_TYPE": "", + "PART_DESCJ": "TRUE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "71172-3A0-A00", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "0.00", + "ACT_PRICE": "15.00", + "PRICE_J": "TRUE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "", + "DB_HRS": "0.0", + "MOD_LB_HRS": "0.0", + "LBR_INC": "FALSE", + "LBR_OP": "OP13", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "FALSE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "FALSE" + }, + { + "__typename": "joblines", + "LINE_NO": 10, + "LINE_IND": "E", + "DB_REF": "933014", + "LINE_DESC": "Three Stage", + "PART_TYPE": "", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "71172-3A0-A00", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "0.00", + "ACT_PRICE": "0.00", + "PRICE_J": "TRUE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAR", + "DB_HRS": "0.0", + "MOD_LB_HRS": "5.7", + "LBR_INC": "FALSE", + "LBR_OP": "OP14", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "FALSE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "FALSE" + }, + { + "__typename": "joblines", + "LINE_NO": 11, + "LINE_IND": "E", + "DB_REF": "933062", + "LINE_DESC": "Calibrate Forward Facing Radar", + "PART_TYPE": "", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "0.00", + "ACT_PRICE": "165.00", + "PRICE_J": "TRUE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAM", + "DB_HRS": "0.0", + "MOD_LB_HRS": "0.0", + "LBR_INC": "FALSE", + "LBR_OP": "OP14", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 12, + "LINE_IND": "E", + "DB_REF": "933018", + "LINE_DESC": "Mask For Overspray", + "PART_TYPE": "", + "PART_DESCJ": "FALSE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "0.00", + "ACT_PRICE": "0.00", + "PRICE_J": "TRUE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "", + "MOD_LBR_TY": "LAR", + "DB_HRS": "0.0", + "MOD_LB_HRS": "0.6", + "LBR_INC": "FALSE", + "LBR_OP": "OP14", + "LBR_OP_J": "FALSE", + "LBR_HRS_J": "FALSE", + "LBR_TYP_J": "FALSE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + }, + { + "__typename": "joblines", + "LINE_NO": 13, + "LINE_IND": "S1", + "DB_REF": "900500", + "LINE_DESC": "Closed System Top-Up - R1234YF", + "PART_TYPE": "PAA", + "PART_DESCJ": "TRUE", + "GLASS_FLAG": "FALSE", + "OEM_PARTNO": "", + "PRICE_INC": "FALSE", + "ALT_PART_I": "FALSE", + "TAX_PART": "TRUE", + "DB_PRICE": "0.00", + "ACT_PRICE": "17.55", + "PRICE_J": "TRUE", + "CERT_PART": "FALSE", + "PART_QTY": "1", + "ALT_CO_ID": "", + "ALT_PARTNO": "** QUAL REPL PART", + "MOD_LBR_TY": "LAM", + "DB_HRS": "0.0", + "MOD_LB_HRS": "0.0", + "LBR_INC": "FALSE", + "LBR_OP": "OP11", + "LBR_OP_J": "TRUE", + "LBR_HRS_J": "TRUE", + "LBR_TYP_J": "TRUE", + "PAINT_TONE": "0", + "LBR_TAX": "TRUE", + "LBR_AMT": "0.00", + "MISC_AMT": "0.00", + "MISC_TAX": "TRUE" + } + + + + ] +} \ No newline at end of file diff --git a/electron/estimate-scrubber/estimate-scrubber.js b/electron/estimate-scrubber/estimate-scrubber.js new file mode 100644 index 0000000..178d65d --- /dev/null +++ b/electron/estimate-scrubber/estimate-scrubber.js @@ -0,0 +1,50 @@ +const path = require("path"); +const fs = require("fs"); +const { store } = require("../electron-store"); +const log = require("electron-log"); +const fsPromises = fs.promises; +const { DecodeEstimate } = require("../decoder/decoder"); +const axios = require("axios"); +const TestJson = require("./A.json"); +const { BrowserWindow } = require("electron"); + + +async function ScrubEstimate({ job }) { + //These need to be removed. + const basicAuthUser = "Imex"; + const basicAuthpassword = "Patrick"; + const estimateScrubberUrl = "https://insurtechtoolkit.com/api/sendems"; + + const fileName = `RPSTest-${job.id}-${Date.now()}`; + console.log("*** ~ ScrubEstimate ~ job:", job); + + //Build the JSON Form Data + const formData = new FormData(); + const jsonString = JSON.stringify(job); + formData.append("file", new Blob([jsonString], { type: "application/json" }), `${fileName}.json`); + + console.log("*** ~ ScrubEstimate ~ formData.getHeaders();:", formData); + const result = await axios.post(estimateScrubberUrl, formData, { + auth: { + username: basicAuthUser, + password: basicAuthpassword + }, + headers: formData.getHeaders ? formData.getHeaders() : {} + }); + console.log("*** ~ handleScrub ~ result:", result.data); + + const resultPDFUrl = `https://www.insurtechtoolkit.com/analysis/${fileName}.pdf`; + + console.log("*** ~ handleScrub ~ resultPDFUrl:", resultPDFUrl); + const pdfWindow = new BrowserWindow({ + + webPreferences: { + plugins: true, // Enable PDF viewing + }, + }); + + pdfWindow.loadURL(resultPDFUrl); + pdfWindow.focus(); + return resultPDFUrl +} +exports.ScrubEstimate = ScrubEstimate \ No newline at end of file diff --git a/electron/ipc-main-handler.js b/electron/ipc-main-handler.js index 0caf698..469acb2 100644 --- a/electron/ipc-main-handler.js +++ b/electron/ipc-main-handler.js @@ -4,6 +4,7 @@ const { default: ipcTypes } = require("../src/ipc.types.commonjs"); const { store } = require("./electron-store"); const log = require("electron-log"); const { ImportJobWithCloseDate } = require("./decoder/decoder"); +const { ScrubEstimate } = require("./estimate-scrubber/estimate-scrubber"); //Import Ipc Handlers require("./file-watcher/file-watcher-ipc"); @@ -68,3 +69,8 @@ ipcMain.on(ipcTypes.app.toMain.log.error, (event, ...obj) => { ipcMain.on(ipcTypes.app.toMain.getAppVersion, (event, obj) => { event.sender.send(ipcTypes.app.toRenderer.appVersion, app.getVersion()); }); + +ipcMain.handle(ipcTypes.app.toMain.scrubEstimate, (event, { job }) => { + return ScrubEstimate({ job }) +}); + diff --git a/electron/preload.js b/electron/preload.js index 5093b7f..864635f 100644 --- a/electron/preload.js +++ b/electron/preload.js @@ -42,6 +42,9 @@ contextBridge.exposeInMainWorld("ipcRenderer", { ); // } }, + invoke: (channel, data) => { + return ipcRenderer.invoke(channel, data); + }, removeAllListeners: (...channels) => { // let validChannels = ["fromMain"]; // if (validChannels.includes(channel)) { diff --git a/package-lock.json b/package-lock.json index dae361e..c2fa3c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "imexrps", - "version": "1.4.0-alpha.4", + "version": "1.4.1-alpha.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "imexrps", - "version": "1.4.0-alpha.4", + "version": "1.4.1-alpha.1", "hasInstallScript": true, "dependencies": { "@ant-design/pro-layout": "^7.22.3", @@ -16,6 +16,7 @@ "antd": "^5.24.3", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.1.0", + "axios": "^1.10.0", "chokidar": "^4.0.3", "dayjs": "^1.11.13", "dayjs-business-days2": "^1.3.0", @@ -7430,7 +7431,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, "license": "MIT" }, "node_modules/at-least-node": { @@ -7476,6 +7476,17 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", @@ -8445,7 +8456,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -9286,7 +9296,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -11294,6 +11303,26 @@ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -11343,7 +11372,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", - "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -13603,7 +13631,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -13616,7 +13643,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -15106,6 +15132,12 @@ "node": ">=12.0.0" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", diff --git a/package.json b/package.json index fe64112..586be04 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "productName": "ImEX RPS", "author": "ImEX Systems Inc. ", "description": "ImEX RPS", - "version": "1.4.0", + "version": "1.4.1-alpha.1", "main": "electron/main.js", "homepage": "./", "dependencies": { @@ -14,6 +14,7 @@ "antd": "^5.24.3", "apollo-link-logger": "^2.0.1", "apollo-link-sentry": "^4.1.0", + "axios": "^1.10.0", "chokidar": "^4.0.3", "dayjs": "^1.11.13", "dayjs-business-days2": "^1.3.0", diff --git a/src/App/App.jsx b/src/App/App.jsx index 62a3607..bd3632c 100644 --- a/src/App/App.jsx +++ b/src/App/App.jsx @@ -12,9 +12,16 @@ import ipcTypes from "../ipc.types"; import "../ipc/ipc-renderer-handler"; import { checkUserSession } from "../redux/user/user.actions"; import { selectCurrentUser, selectDarkMode } from "../redux/user/user.selectors"; +import { loadErrorMessages, loadDevMessages } from "@apollo/client/dev"; import "./App.styles.scss"; const { ipcRenderer } = window; +if (process.env.NODE_ENV !== "production") { + // Adds messages only in a dev environment + loadDevMessages(); + loadErrorMessages(); +} + const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, darkMode: selectDarkMode diff --git a/src/components/molecules/estimate-scrubber-button/estimate-scrubber-button.molecule.jsx b/src/components/molecules/estimate-scrubber-button/estimate-scrubber-button.molecule.jsx new file mode 100644 index 0000000..51e1d02 --- /dev/null +++ b/src/components/molecules/estimate-scrubber-button/estimate-scrubber-button.molecule.jsx @@ -0,0 +1,59 @@ +import { Button, message } from "antd"; +import { useState } from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import ipcTypes from "../../../ipc.types"; +import { selectBodyshop } from "../../../redux/user/user.selectors"; +import { useApolloClient } from "@apollo/client"; +import { QUERY_JOB_ESTIMATE_SCRUBBER } from "../../../graphql/jobs.queries"; + +const { ipcRenderer } = window; +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser + bodyshop: selectBodyshop +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); +export default connect(mapStateToProps, mapDispatchToProps)(EstimateScrubberButton); + +export function EstimateScrubberButton({ bodyshop, jobid }) { + const [loading, setLoading] = useState(false); + const client = useApolloClient(); + const handleScrub = async () => { + try { + ipcRenderer.send(ipcTypes.app.toMain.track, { + event: "SCRUB_ESTIMATE", + jobId: jobid + }); + setLoading(true); + + const jobData = await client.query({ + query: QUERY_JOB_ESTIMATE_SCRUBBER, + variables: { jobId: jobid }, + fetchPolicy: "network-only" + }); + + const result = await ipcRenderer.invoke(ipcTypes.app.toMain.scrubEstimate, { + job: { + ...jobData.data.jobs_by_pk, + sending_entity_id: "87330f61-412b-4251-baaa-d026565b23c5", + sending_entity_clientid: "", + sending_entity_accept_terms_of_use: true, + profileid: "", + association_switch: "ATAM" + } + }); + } catch (error) { + message.error("Error scrubbing estimate: " + error.message); + console.error("Error scrubbing estimate:", error); + } + setLoading(false); + }; + + return ( + + ); +} diff --git a/src/components/molecules/reporting-jobs-list/reporting-jobs-list.molecule.jsx b/src/components/molecules/reporting-jobs-list/reporting-jobs-list.molecule.jsx index ed8c9f9..955cf66 100644 --- a/src/components/molecules/reporting-jobs-list/reporting-jobs-list.molecule.jsx +++ b/src/components/molecules/reporting-jobs-list/reporting-jobs-list.molecule.jsx @@ -74,19 +74,23 @@ export function ReportingJobsListMolecule({ key: "close_date", render: (text, record) => dayjs(record.close_date).format("MM/DD/YYYY"), defaultSortOrder: "ascend", + width: "110px", sorter: (a, b) => dayjs(a.close_date).unix() - dayjs(b.close_date).unix() }, { - title: "Ins Co.", + title: "Ins.", dataIndex: "ins_co_nm", key: "ins_co_nm", - sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm) + sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm), + width: "75px", + ellipsis: true }, { title: "First Name", dataIndex: "ownr_fn", key: "ownr_fn", - sorter: (a, b) => alphaSort(a.ownr_fn, b.ownr_fn) + sorter: (a, b) => alphaSort(a.ownr_fn, b.ownr_fn), + ellipsis: true }, { title: "Last Name", @@ -98,7 +102,8 @@ export function ReportingJobsListMolecule({ title: "Vehicle", dataIndex: "vehicle", key: "vehicle", - render: (text, record) => + render: (text, record) => , + //ellipsis: true }, { title: "Database Price Sum", @@ -119,7 +124,8 @@ export function ReportingJobsListMolecule({ dataIndex: "group_verified", key: "group_verified", sorter: (a, b) => a.group_verified - b.group_verified, - render: (text, record) => + render: (text, record) => , + width: "100px" }, { title: "$ Variance", @@ -179,7 +185,6 @@ export function ReportingJobsListMolecule({ { - console.log("Chcekedd", checked); checked ? addExcludedId(record.id) : removeExcludedId(record.id); }} /> @@ -235,9 +240,9 @@ export function ReportingJobsListMolecule({ // expandedRowRender: (record) => , // rowExpandable: (record) => record.alerts && record.alerts.length > 0 // }} - scroll={{ - x: true - }} + // scroll={{ + // x: true + // }} summary={() => ( diff --git a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx index 4470355..014abaf 100644 --- a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx +++ b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx @@ -13,6 +13,7 @@ import JobsLinesTableMolecule from "../../molecules/jobs-lines-table/jobs-lines- import JobsTargetsStatsMolecule from "../../molecules/jobs-targets-stats/jobs-targets-stats.molecule"; import "./jobs-detail.organism.styles.scss"; import JobsClaimClerk from "../../molecules/jobs-claims-clerk/jobs-claims-clerk.molecule"; +import { EstimateScrubberButton } from "../../molecules/estimate-scrubber-button/estimate-scrubber-button.molecule"; const mapStateToProps = createStructuredSelector({ //currentUser: selectCurrentUser @@ -73,7 +74,10 @@ export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) { //2025-05-27 Removing CC AI */} - + ]} + > diff --git a/src/graphql/jobs.queries.js b/src/graphql/jobs.queries.js index 70a0e61..0974bad 100644 --- a/src/graphql/jobs.queries.js +++ b/src/graphql/jobs.queries.js @@ -199,3 +199,58 @@ export const DELETE_JOB = gql` } } `; + +export const QUERY_JOB_ESTIMATE_SCRUBBER = gql` + query QUERY_JOB_ESTIMATE_SCRUBBER($jobId: uuid!) { + jobs_by_pk(id: $jobId) { + ownr_fn + ownr_ln + v_vin + v_model_yr + v_model + v_makedesc + id + ins_co_nm + clm_no + clm_total + ro_number + updated_at + group + group_verified + v_age + v_type + loss_date + close_date + updated_at + requires_reimport + created_at + v_mileage + joblines(order_by: {line_no: asc}) { + line_no + line_ind + db_ref + line_desc + part_type + glass_flag + oem_partno + db_price + act_price + price_j + part_qty + mod_lbr_ty + db_hrs + mod_lb_hrs + lbr_inc + lbr_op + lbr_hrs_j + lbr_amt + misc_amt + } + } +} + +`; + +//Missing Fields? +//db_date +//all rf_Fields diff --git a/src/ipc.types.json b/src/ipc.types.json index 5ddd5d0..a7e9894 100644 --- a/src/ipc.types.json +++ b/src/ipc.types.json @@ -16,6 +16,7 @@ "getAppVersion": "app_getApVersion", "importJob": "app_importJob", "setReleaseChannel": "app_setReleaseChannel", + "scrubEstimate": "app_scrubEstimate", "log": { "info": "app_logInfo", "debug": "app_logDebug", diff --git a/src/redux/store.js b/src/redux/store.js index 5e3b96a..aece08e 100644 --- a/src/redux/store.js +++ b/src/redux/store.js @@ -9,15 +9,15 @@ import rootSaga from "./root.saga"; const sagaMiddleWare = createSagaMiddleware(); const middlewares = [sagaMiddleWare]; -//if (process.env.NODE_ENV === "development") { -middlewares.push(createLogger({ collapsed: true, diff: true })); -//} +if (process.env.NODE_ENV === "development") { + middlewares.push(createLogger({ collapsed: true, diff: true })); +} const composeEnhancers = typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ - // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize... - }) + // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize... + }) : compose; const enhancer = composeEnhancers(