diff --git a/WIP Changelog.txt b/WIP Changelog.txt index 0f25504..e4b2009 100644 --- a/WIP Changelog.txt +++ b/WIP Changelog.txt @@ -1,13 +1,3 @@ -New Features: -- Vehicles with mileage under 20,000kms will now be included in Watcher filtering criteria. -- Savings on OEM parts will always default to the user enter price and override the estimating system price. -- Wheel related lines will no longer be automatically ignored. -- Glass related lines will no longer be automatically ignored. -- Added 'Variance %' statistic to reporting totals. -- Automatically ignore any lines which have invalid prices from estimating system. -- Force line inclusion/exclusion - Using “ /rps-exclude” or “/rps” in the Part Number field to force inclusion or exclusion of lines for RPS calculation. -- Added automatic update checks every 30 minutes. - Bug Fixes: -- Resolved an issue where the updater would not show update progress to some users. -- Fixed a UI bug during job search that would cause the 'no close date' alert to be incorrectly shown. \ No newline at end of file +- Resolved an issue where N/A prices were being incorrectly included. +- Resolved a bug where clicking yes during update would not install the update. \ No newline at end of file diff --git a/electron/analytics.js b/electron/analytics.js index f7f22eb..2a45eb7 100644 --- a/electron/analytics.js +++ b/electron/analytics.js @@ -20,8 +20,8 @@ Nucleus.onError = (type, err) => { }; ipcMain.on(ipcTypes.app.toMain.setUserName, (event, userName) => { - Nucleus.appStarted(); Nucleus.setUserId(userName); + Nucleus.appStarted(); }); ipcMain.on(ipcTypes.app.toMain.track, (e, args) => { diff --git a/changelog.json b/electron/changelog.json similarity index 77% rename from changelog.json rename to electron/changelog.json index c935fca..982c529 100644 --- a/changelog.json +++ b/electron/changelog.json @@ -1,7 +1,12 @@ { "1.0.9": { "title": "Release Notes for 1.0.9", - "date": "11/16/2020", + "date": "11/17/2020", "notes": "New Features: \n- Vehicles with mileage under 20,000kms will now be included in Watcher filtering criteria.\n- Savings on OEM parts will always default to the user enter price and override the estimating system price.\n- Wheel related lines will no longer be automatically ignored.\n- Glass related lines will no longer be automatically ignored.\n- Added 'Variance %' statistic to reporting totals.\n- Automatically ignore any lines which have invalid prices from estimating system.\n- Force line inclusion/exclusion - Using “ /rps-exclude” or “/rps” in the Part Number field to force inclusion or exclusion of lines for RPS calculation.\n- Added automatic update checks every 30 minutes.\n\nBug Fixes: \n- Resolved an issue where the updater would not show update progress to some users.\n- Fixed a UI bug during job search that would cause the 'no close date' alert to be incorrectly shown." + }, + "1.0.10": { + "title": "Release Notes for 1.0.10", + "date": "11/19/2020", + "notes": "Bug Fixes: \n- Resolved an issue where N/A prices were being incorrectly included.\n- Resolved a bug where clicking yes during update would not install the update." } } diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index 1dca8d5..e323bd0 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -51,8 +51,8 @@ async function DecodeEstimate(filePath, includeFilePathInReturnJob = false) { const ad2 = await DecodeAd2File(extensionlessFilePath); - if (job.OWNR_FN === "") job.OWNR_FN = ad2.CLMT_FN; - if (job.OWNR_LN === "") job.OWNR_LN = ad2.CLMT_LN; + if (job.OWNR_FN === "" || !job.OWNR_FN) job.OWNR_FN = ad2.CLMT_FN; + if (job.OWNR_LN === "" || !job.OWNR_LN) job.OWNR_LN = ad2.CLMT_LN; const accepted_ins_co = store.get("accepted_ins_co"); @@ -298,9 +298,9 @@ async function DecodeLinFile(extensionlessFilePath) { // "TAX_PART", "DB_PRICE", "ACT_PRICE", - // "PRICE_J", - // "CERT_PART", "PART_QTY", + "PRICE_J", + // "CERT_PART", // "ALT_CO_ID", // "ALT_PARTNO", // "ALT_OVERRD", @@ -372,6 +372,15 @@ async function DecodeLinFile(extensionlessFilePath) { // jobline.db_price = jobline.act_price; // } + //RPS-46 Ignore NA Line Items. + if ( + jobline.part_type === "PAN" && + jobline.price_j === true && + jobline.db_price === 0 + ) { + jobline.ignore = true; + } + //RPS-39 - OEM ON OEM SAVINGS if ( jobline.part_type === "PAN" && @@ -403,9 +412,8 @@ async function DecodeLinFile(extensionlessFilePath) { // jobline.part_type.toUpperCase() === "PAG" ||Removed for RPS-43. jobline.part_type.toUpperCase() === "PAS" || jobline.part_type.toUpperCase() === "PASL" || - jobline.part_type.toUpperCase() === "PAE" || + jobline.part_type.toUpperCase() === "PAE" //jobline.glass_flag === true //Removed for RPS-43. - jobline.db_price === 0 //Added as a part of RPS-46. ) jobline.ignore = true; @@ -416,7 +424,10 @@ async function DecodeLinFile(extensionlessFilePath) { jobline.ignore = false; } + console.log("jobline", jobline); + delete jobline.glass_flag; + delete jobline.price_j; return jobline; }); diff --git a/electron/file-watcher/file-watcher.js b/electron/file-watcher/file-watcher.js index ba2522b..5f17c14 100644 --- a/electron/file-watcher/file-watcher.js +++ b/electron/file-watcher/file-watcher.js @@ -70,7 +70,7 @@ async function StartWatcher() { .on("error", function (error) { log.error("Error in Watcher", error); const b = BrowserWindow.getFocusedWindow(); - b.webContents.send(ipcTypes.fileWatcher.toRenderer.error, error); + b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.error, error); Nucleus.track("WATCHER_ERROR", error); }) .on("ready", onWatcherReady) diff --git a/electron/ipc-main-handler.js b/electron/ipc-main-handler.js index 2d28b1a..a016f03 100644 --- a/electron/ipc-main-handler.js +++ b/electron/ipc-main-handler.js @@ -37,7 +37,7 @@ ipcMain.on(ipcTypes.store.getAll, (event, obj) => { ipcMain.on(ipcTypes.app.toMain.getReleaseNotes, (event, obj) => { const showNotes = store.get("showChangeLog"); if (showNotes) { - const rn = require("../changelog.json")[electronApp.getVersion()]; + const rn = require("./changelog.json")[electronApp.getVersion()]; event.sender.send(ipcTypes.app.toRenderer.setReleaseNotes, rn); } else { event.sender.send(ipcTypes.app.toRenderer.setReleaseNotes, null); diff --git a/electron/main.js b/electron/main.js index 6c71781..0568aee 100644 --- a/electron/main.js +++ b/electron/main.js @@ -67,7 +67,7 @@ var menu = Menu.buildFromTemplate([ // Other code removed for brevity }, { - label: "Help", + label: isDev ? "DEVELOPMENT -- HELP" : "Help", submenu: [ { label: "Rescue", @@ -86,7 +86,7 @@ var menu = Menu.buildFromTemplate([ click() { mainWindow.webContents.send( ipcTypes.app.toRenderer.setReleaseNotes, - require("../changelog.json")[app.getVersion()] + require("./changelog.json")[app.getVersion()] ); }, }, @@ -295,10 +295,12 @@ ipcMain.on(ipcTypes.app.toMain.checkForUpdates, (event, args) => { }); ipcMain.on(ipcTypes.app.toMain.downloadUpdates, (event, args) => { + Nucleus.track("DOWNLOAD_UPDATE_FROM_RENDERER"); autoUpdater.downloadUpdate(); }); ipcMain.on(ipcTypes.app.toMain.installUpdates, (event, args) => { + Nucleus.track("INSTALL_UPDATE_FROM_RENDERER"); const isSilent = true; const isForceRunAfter = true; autoUpdater.quitAndInstall(isSilent, isForceRunAfter); @@ -313,38 +315,29 @@ autoUpdater.on("update-downloaded", (ev, info) => { Nucleus.track("UPDATE_DOWNLOADED", ev); // if (process.env.NODE_ENV === "production") { - dialog.showMessageBox( - { + dialog + .showMessageBox({ type: "info", title: "ImeX RPS Update Manager", message: `ImEX RPS is ready to update to Version ${ev.version}. It is highly recommended that you update immediately. Would you like to update now? RPS will automatically restart.`, buttons: ["Yes", "No"], - }, - (buttonIndex) => { - if (buttonIndex === 0) { + }) + .then(({ response }) => { + log.log("The button worked.", response); + if (response === 0) { const isSilent = true; const isForceRunAfter = true; store.set("showChangeLog", true); autoUpdater.quitAndInstall(isSilent, isForceRunAfter); } else { - logger.error("Error"); + log.warn("Updated ignored."); } - } - ); + }); }); async function checkForUpdates() { try { log.info("Checking for updates."); - //const result = await autoUpdater.checkForUpdates(); - // const { updateInfo } = result; - - // if (updateInfo.version !== app.getVersion()) { - // mainWindow.webContents.send( - // ipcTypes.app.toRenderer.updateAvailable, - // updateInfo - // ); - // } } catch (error) { log.error("Error while checking for update", error); } diff --git a/package.json b/package.json index 3d30c8f..d6834c1 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "productName": "ImEX RPS", "author": "ImEX Systems Inc. ", "description": "ImEX RPS", - "version": "1.0.9", + "version": "1.0.10", "main": "electron/main.js", "homepage": "./", "dependencies": { diff --git a/src/components/atoms/jobs-parts-graph/jobs-parts-graph.atom.jsx b/src/components/atoms/jobs-parts-graph/jobs-parts-graph.atom.jsx index f4ad1b3..2213976 100644 --- a/src/components/atoms/jobs-parts-graph/jobs-parts-graph.atom.jsx +++ b/src/components/atoms/jobs-parts-graph/jobs-parts-graph.atom.jsx @@ -20,7 +20,9 @@ export default function JobPartsGraphAtom({ } acc[val.part_type] = acc[val.part_type].add( - Dinero({ amount: Math.round((val[price] || 0) * 100) }) + Dinero({ amount: Math.round((val[price] || 0) * 100) }).multiply( + val.part_qty || 1 + ) ); return acc; diff --git a/src/components/molecules/jobs-lines-table/jobs-lines-table.molecule.jsx b/src/components/molecules/jobs-lines-table/jobs-lines-table.molecule.jsx index 173f152..735db1e 100644 --- a/src/components/molecules/jobs-lines-table/jobs-lines-table.molecule.jsx +++ b/src/components/molecules/jobs-lines-table/jobs-lines-table.molecule.jsx @@ -60,6 +60,13 @@ export default function JobLinesTableMolecule({ loading, job }) { width: "15%", sorter: (a, b) => alphaSort(a.oem_partno, b.oem_partno), }, + { + title: "Qty.", + dataIndex: "part_qty", + key: "part_qty", + width: "5%", + sorter: (a, b) => a.part_qty - b.part_qty, + }, { title: "Database Price", dataIndex: "db_price", diff --git a/src/components/organisms/jobs-list-search/jobs-list-search.organism.jsx b/src/components/organisms/jobs-list-search/jobs-list-search.organism.jsx index 118b090..7731a5c 100644 --- a/src/components/organisms/jobs-list-search/jobs-list-search.organism.jsx +++ b/src/components/organisms/jobs-list-search/jobs-list-search.organism.jsx @@ -4,12 +4,11 @@ import { Dropdown, List, Menu, Spin } from "antd"; import React, { useState } from "react"; import InfiniteScroll from "react-infinite-scroller"; import { SEARCH_JOBS_PAGINATED } from "../../../graphql/jobs.queries"; -import ipcTypes from "../../../ipc.types"; import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; import JobsListItemMolecule from "../../molecules/jobs-list-item/jobs-list-item.molecule"; import JobsSearchFieldsMolecule from "../../molecules/jobs-search-fields/jobs-search-fields.molecule"; -const { ipcRenderer } = window; + const limit = 20; export default function JobsTableOrganism() { @@ -36,9 +35,9 @@ export default function JobsTableOrganism() { const handleInfiniteOnLoad = (page) => { if (fetchMore) { - ipcRenderer.send(ipcTypes.default.app.toMain.track, { - event: "FETCH_MORE_JOBS", - }); + // ipcRenderer.send(ipcTypes.default.app.toMain.track, { + // event: "FETCH_MORE_JOBS", + // }); fetchMore({ variables: { offset: limit * page, diff --git a/src/ipc/ipc-estimate-utils.js b/src/ipc/ipc-estimate-utils.js index 8d50846..fa0664c 100644 --- a/src/ipc/ipc-estimate-utils.js +++ b/src/ipc/ipc-estimate-utils.js @@ -17,6 +17,9 @@ export async function UpsertEstimate(job) { logger.info("Beginning Upserting job from Renderer."); const parsedYr = parseInt(job.v_model_yr); logger.info( + "Job Loss Date", + job.loss_date, + "Parsed Year", moment(job.loss_date).year() - (parsedYr >= 0 ? 2000 + parsedYr : 1900 + parsedYr) ); @@ -29,6 +32,8 @@ export async function UpsertEstimate(job) { (parsedYr >= 0 ? 2000 + parsedYr : 1900 + parsedYr), }; + if (job.v_age < 0) job.v_age = 0; + const existingJobs = await client.query({ query: QUERY_JOB_BY_CLM_NO, variables: { clm_no: job.clm_no }, diff --git a/src/redux/application/application.reducer.js b/src/redux/application/application.reducer.js index 549bbcc..c4be730 100644 --- a/src/redux/application/application.reducer.js +++ b/src/redux/application/application.reducer.js @@ -57,9 +57,9 @@ const applicationReducer = (state = INITIAL_STATE, action) => { selectedJobTargetPc: action.payload, }; case ApplicationActionTypes.SET_SELECTED_JOB_ID: - ipcRenderer.send(ipcTypes.default.app.toMain.track, { - event: "SET_SELECTED_JOB", - }); + // ipcRenderer.send(ipcTypes.default.app.toMain.track, { + // event: "SET_SELECTED_JOB", + // }); return { ...state, selectedJobId: action.payload }; case ApplicationActionTypes.SET_SETTINGS: return { ...state, settings: { ...state.settings, ...action.payload } }; diff --git a/src/util/CalculateJobRps.js b/src/util/CalculateJobRps.js index c97aeda..fe8b4ae 100644 --- a/src/util/CalculateJobRps.js +++ b/src/util/CalculateJobRps.js @@ -9,11 +9,15 @@ export function CalculateJobRpsDollars(job, returnSumActPrice) { .filter((j) => !j.ignore) .reduce((acc, val) => { actPriceSum = actPriceSum.add( - Dinero({ amount: Math.round((val.act_price || 0) * 100) }) + Dinero({ amount: Math.round((val.act_price || 0) * 100) }).multiply( + val.part_qty || 1 + ) ); if (val.price_diff > 0) { return acc.add( - Dinero({ amount: Math.round((val.price_diff || 0) * 100) }) + Dinero({ amount: Math.round((val.price_diff || 0) * 100) }).multiply( + val.part_qty || 1 + ) ); } else { return acc; @@ -34,7 +38,11 @@ export function CalculateJobRpsPc( const dbPriceSum = job.joblines .filter((j) => !j.ignore) .reduce((acc, val) => { - return acc.add(Dinero({ amount: Math.round((val.db_price || 0) * 100) })); + return acc.add( + Dinero({ amount: Math.round((val.db_price || 0) * 100) }).multiply( + val.part_qty || 1 + ) + ); }, Dinero()); const jobRpsPc = currentRpsDollars.getAmount() / dbPriceSum.getAmount();