From 63479086545b7135b57bac967f3e4bee20ec5ad5 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 6 Nov 2020 08:32:13 -0800 Subject: [PATCH 01/15] Updated package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f2a446f..3d30c8f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "productName": "ImEX RPS", "author": "ImEX Systems Inc. ", "description": "ImEX RPS", - "version": "1.0.8", + "version": "1.0.9", "main": "electron/main.js", "homepage": "./", "dependencies": { From 6d9be1810dd9921c420df09b1a7509f6596acac8 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 6 Nov 2020 11:29:54 -0800 Subject: [PATCH 02/15] Added close date to searching of Job. --- src/graphql/jobs.queries.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphql/jobs.queries.js b/src/graphql/jobs.queries.js index 03e7064..1077399 100644 --- a/src/graphql/jobs.queries.js +++ b/src/graphql/jobs.queries.js @@ -60,6 +60,7 @@ export const SEARCH_JOBS_PAGINATED = gql` ins_co_nm clm_no updated_at + close_date } search_jobs_aggregate( args: { enddate: $endDate, search: $search, startdate: $startDate } From 0aa8d2ead6a4b9942aae7693d6895c2d4e665b03 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 10 Nov 2020 16:07:54 -0800 Subject: [PATCH 03/15] Added ID field to associations table. --- hasura/config.yaml | 3 +-- .../down.yaml | 6 +++++ .../up.yaml | 5 ++++ .../down.yaml | 5 ++++ .../up.yaml | 11 +++++++++ .../down.yaml | 5 ++++ .../up.yaml | 6 +++++ .../down.yaml | 22 ++++++++++++++++++ .../up.yaml | 23 +++++++++++++++++++ hasura/migrations/metadata.yaml | 3 ++- 10 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 hasura/migrations/1605053078816_modify_primarykey_public_associations/down.yaml create mode 100644 hasura/migrations/1605053078816_modify_primarykey_public_associations/up.yaml create mode 100644 hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/down.yaml create mode 100644 hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/up.yaml create mode 100644 hasura/migrations/1605053131947_modify_primarykey_public_associations/down.yaml create mode 100644 hasura/migrations/1605053131947_modify_primarykey_public_associations/up.yaml create mode 100644 hasura/migrations/1605053139986_update_permission_user_public_table_associations/down.yaml create mode 100644 hasura/migrations/1605053139986_update_permission_user_public_table_associations/up.yaml diff --git a/hasura/config.yaml b/hasura/config.yaml index 5909335..3b809c2 100644 --- a/hasura/config.yaml +++ b/hasura/config.yaml @@ -1,2 +1 @@ -#endpoint: https://rps.bodyshop.app -endpoint: https://db.rps.imex.online +endpoint: https://rps.bodyshop.app diff --git a/hasura/migrations/1605053078816_modify_primarykey_public_associations/down.yaml b/hasura/migrations/1605053078816_modify_primarykey_public_associations/down.yaml new file mode 100644 index 0000000..27ddc0a --- /dev/null +++ b/hasura/migrations/1605053078816_modify_primarykey_public_associations/down.yaml @@ -0,0 +1,6 @@ +- args: + cascade: false + read_only: false + sql: "alter table \"public\".\"associations\"\n add constraint \"associations_pkey\" + \n primary key ( \"bodyshopid\", \"email\" );" + type: run_sql diff --git a/hasura/migrations/1605053078816_modify_primarykey_public_associations/up.yaml b/hasura/migrations/1605053078816_modify_primarykey_public_associations/up.yaml new file mode 100644 index 0000000..772aa8e --- /dev/null +++ b/hasura/migrations/1605053078816_modify_primarykey_public_associations/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."associations" drop constraint "associations_pkey"; + type: run_sql diff --git a/hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/down.yaml b/hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/down.yaml new file mode 100644 index 0000000..5d8e8a8 --- /dev/null +++ b/hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."associations" DROP COLUMN "id"; + type: run_sql diff --git a/hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/up.yaml b/hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/up.yaml new file mode 100644 index 0000000..9b56fce --- /dev/null +++ b/hasura/migrations/1605053124904_alter_table_public_associations_add_column_id/up.yaml @@ -0,0 +1,11 @@ +- args: + cascade: false + read_only: false + sql: CREATE EXTENSION IF NOT EXISTS pgcrypto; + type: run_sql +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."associations" ADD COLUMN "id" uuid NULL UNIQUE DEFAULT + gen_random_uuid(); + type: run_sql diff --git a/hasura/migrations/1605053131947_modify_primarykey_public_associations/down.yaml b/hasura/migrations/1605053131947_modify_primarykey_public_associations/down.yaml new file mode 100644 index 0000000..772aa8e --- /dev/null +++ b/hasura/migrations/1605053131947_modify_primarykey_public_associations/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: alter table "public"."associations" drop constraint "associations_pkey"; + type: run_sql diff --git a/hasura/migrations/1605053131947_modify_primarykey_public_associations/up.yaml b/hasura/migrations/1605053131947_modify_primarykey_public_associations/up.yaml new file mode 100644 index 0000000..a0bf100 --- /dev/null +++ b/hasura/migrations/1605053131947_modify_primarykey_public_associations/up.yaml @@ -0,0 +1,6 @@ +- args: + cascade: false + read_only: false + sql: "alter table \"public\".\"associations\"\n add constraint \"associations_pkey\" + \n primary key ( \"id\" );" + type: run_sql diff --git a/hasura/migrations/1605053139986_update_permission_user_public_table_associations/down.yaml b/hasura/migrations/1605053139986_update_permission_user_public_table_associations/down.yaml new file mode 100644 index 0000000..a078ae4 --- /dev/null +++ b/hasura/migrations/1605053139986_update_permission_user_public_table_associations/down.yaml @@ -0,0 +1,22 @@ +- args: + role: user + table: + name: associations + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - email + - bodyshopid + computed_fields: [] + filter: + user: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: associations + schema: public + type: create_select_permission diff --git a/hasura/migrations/1605053139986_update_permission_user_public_table_associations/up.yaml b/hasura/migrations/1605053139986_update_permission_user_public_table_associations/up.yaml new file mode 100644 index 0000000..7bfbc75 --- /dev/null +++ b/hasura/migrations/1605053139986_update_permission_user_public_table_associations/up.yaml @@ -0,0 +1,23 @@ +- args: + role: user + table: + name: associations + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - bodyshopid + - email + - id + computed_fields: [] + filter: + user: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: associations + schema: public + type: create_select_permission diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index 171c7b2..26f5753 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -14,8 +14,9 @@ tables: - role: user permission: columns: - - email - bodyshopid + - email + - id filter: user: authid: From 8d858cbf9bd88f5a775bb2a24c710d3514ba50f1 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 12 Nov 2020 14:25:48 -0800 Subject: [PATCH 04/15] RPS Admin db schema changes + flag updates. --- electron/decoder/decoder.js | 37 +++++++++++-------- .../down.yaml | 5 +++ .../up.yaml | 10 +++++ .../down.yaml | 23 ++++++++++++ .../up.yaml | 24 ++++++++++++ hasura/migrations/metadata.yaml | 3 +- 6 files changed, 85 insertions(+), 17 deletions(-) create mode 100644 hasura/migrations/1605053333239_alter_table_public_users_add_column_id/down.yaml create mode 100644 hasura/migrations/1605053333239_alter_table_public_users_add_column_id/up.yaml create mode 100644 hasura/migrations/1605053392992_update_permission_user_public_table_users/down.yaml create mode 100644 hasura/migrations/1605053392992_update_permission_user_public_table_users/up.yaml diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index 85a8485..28d1c8d 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -351,22 +351,26 @@ async function DecodeLinFile(extensionlessFilePath) { // jobline.glass_flag === false // ) .map((jobline) => { - if ( - (jobline.db_price === null || jobline.db_price === 0) && - !!jobline.act_price && - jobline.act_price > 0 - ) { - // log.info( - // "DB Price null/lower than act price", - // jobline.line_desc, - // jobline.db_price, - // jobline.act_price - // ); - jobline.db_price = jobline.act_price; - } + //Removed as a result of conversation with Norm. + // Appears you are calculating based on ‘N.A.’ part values in the Mitchell database. + // Reminder – if Mitchell DB has $0.00 price updates can be tracked, if it has N.A. it cannot calculate RPS value. + + // if ( + // (jobline.db_price === null || jobline.db_price === 0) && + // !!jobline.act_price && + // jobline.act_price > 0 + // ) { + // // log.info( + // // "DB Price null/lower than act price", + // // jobline.line_desc, + // // jobline.db_price, + // // jobline.act_price + // // ); + // jobline.db_price = jobline.act_price; + // } if ( - jobline.db_price && + jobline.db_price > 0 && jobline.act_price && jobline.act_price > jobline.db_price ) { @@ -388,11 +392,12 @@ async function DecodeLinFile(extensionlessFilePath) { jobline.line_desc.toLowerCase().startsWith("hazardous") || jobline.line_desc.toLowerCase().startsWith("detail") || jobline.line_desc.toLowerCase().startsWith("clean") || - jobline.part_type.toUpperCase() === "PAG" || + // jobline.part_type.toUpperCase() === "PAG" || jobline.part_type.toUpperCase() === "PAS" || jobline.part_type.toUpperCase() === "PASL" || jobline.part_type.toUpperCase() === "PAE" || - jobline.glass_flag === true + //jobline.glass_flag === true || + jobline.db_price === 0 ) jobline.ignore = true; diff --git a/hasura/migrations/1605053333239_alter_table_public_users_add_column_id/down.yaml b/hasura/migrations/1605053333239_alter_table_public_users_add_column_id/down.yaml new file mode 100644 index 0000000..032a708 --- /dev/null +++ b/hasura/migrations/1605053333239_alter_table_public_users_add_column_id/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."users" DROP COLUMN "id"; + type: run_sql diff --git a/hasura/migrations/1605053333239_alter_table_public_users_add_column_id/up.yaml b/hasura/migrations/1605053333239_alter_table_public_users_add_column_id/up.yaml new file mode 100644 index 0000000..2a4b2b5 --- /dev/null +++ b/hasura/migrations/1605053333239_alter_table_public_users_add_column_id/up.yaml @@ -0,0 +1,10 @@ +- args: + cascade: false + read_only: false + sql: CREATE EXTENSION IF NOT EXISTS pgcrypto; + type: run_sql +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."users" ADD COLUMN "id" uuid NULL UNIQUE DEFAULT gen_random_uuid(); + type: run_sql diff --git a/hasura/migrations/1605053392992_update_permission_user_public_table_users/down.yaml b/hasura/migrations/1605053392992_update_permission_user_public_table_users/down.yaml new file mode 100644 index 0000000..6613a78 --- /dev/null +++ b/hasura/migrations/1605053392992_update_permission_user_public_table_users/down.yaml @@ -0,0 +1,23 @@ +- args: + role: user + table: + name: users + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - authid + - email + - created_at + - updated_at + computed_fields: [] + filter: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: users + schema: public + type: create_select_permission diff --git a/hasura/migrations/1605053392992_update_permission_user_public_table_users/up.yaml b/hasura/migrations/1605053392992_update_permission_user_public_table_users/up.yaml new file mode 100644 index 0000000..a055b70 --- /dev/null +++ b/hasura/migrations/1605053392992_update_permission_user_public_table_users/up.yaml @@ -0,0 +1,24 @@ +- args: + role: user + table: + name: users + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - authid + - created_at + - email + - id + - updated_at + computed_fields: [] + filter: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: users + schema: public + type: create_select_permission diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index 26f5753..97056b2 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -317,8 +317,9 @@ tables: permission: columns: - authid - - email - created_at + - email + - id - updated_at filter: authid: From 9f75080705a52bddf3cab60947e55619bd69fc6b Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 13 Nov 2020 11:41:32 -0800 Subject: [PATCH 05/15] Added OEM on OEM Savings Logic. RPS-31 RPS-39 --- electron/decoder/decoder.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index 28d1c8d..a06d0f8 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -369,9 +369,18 @@ async function DecodeLinFile(extensionlessFilePath) { // jobline.db_price = jobline.act_price; // } + //RPS-39 - OEM ON OEM SAVINGS if ( + jobline.part_type === "PAN" && + jobline.db_price !== jobline.act_price + ) { + jobline.db_price = jobline.act_price; + } + + if ( + !!jobline.db_price && jobline.db_price > 0 && - jobline.act_price && + !!jobline.act_price && jobline.act_price > jobline.db_price ) { // log.info( From 680fa7fc8439820087b3da712d8e760e34b3c30b Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 13 Nov 2020 11:44:26 -0800 Subject: [PATCH 06/15] Removed 20,000 kms restriction RPS-40 --- electron/decoder/decoder.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index a06d0f8..d69be2f 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -57,9 +57,12 @@ async function DecodeEstimate(filePath, includeFilePathInReturnJob = false) { const accepted_ins_co = store.get("accepted_ins_co"); let returnValue; - if (job.V_MILEAGE <= 20000) { - returnValue = { ERROR: "Vehicle mileage is less than 20,000kms." }; - } else if (!accepted_ins_co.includes(job.INS_CO_NM)) { + //Removed as a part of RPS-40. + // if (job.V_MILEAGE <= 20000) { + // returnValue = { ERROR: "Vehicle mileage is less than 20,000kms." }; + // } else + + if (!accepted_ins_co.includes(job.INS_CO_NM)) { returnValue = { ERROR: `Insurance Company Name is not valid for RPS. (${ job.INS_CO_NM || "No name set" From ffea9ad109ac3999b9d2adc780c2555fc847bbd1 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 13 Nov 2020 11:46:07 -0800 Subject: [PATCH 07/15] Removed wheel exclusions as a part of RPS-41. --- electron/decoder/decoder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index d69be2f..8354e3c 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -399,7 +399,7 @@ async function DecodeLinFile(extensionlessFilePath) { !jobline.part_type || jobline.db_ref.startsWith("900") || jobline.line_desc.toLowerCase().startsWith("urethane") || - jobline.line_desc.toLowerCase().includes("wheel") || + //jobline.line_desc.toLowerCase().includes("wheel") || Removed as a part of RPS-41 jobline.line_desc.toLowerCase().includes("tire") || jobline.line_desc.toLowerCase().startsWith("hazardous") || jobline.line_desc.toLowerCase().startsWith("detail") || From 26af34e73dc7bf42a39e214a55aedb0140702621 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 13 Nov 2020 11:51:40 -0800 Subject: [PATCH 08/15] Added OEM Partno dynamic inclusion and exclusion. RPS-42. Removed glass exclusions RPS-43. --- electron/decoder/decoder.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index 8354e3c..77bc966 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -60,8 +60,8 @@ async function DecodeEstimate(filePath, includeFilePathInReturnJob = false) { //Removed as a part of RPS-40. // if (job.V_MILEAGE <= 20000) { // returnValue = { ERROR: "Vehicle mileage is less than 20,000kms." }; - // } else - + // } else + if (!accepted_ins_co.includes(job.INS_CO_NM)) { returnValue = { ERROR: `Insurance Company Name is not valid for RPS. (${ @@ -377,7 +377,7 @@ async function DecodeLinFile(extensionlessFilePath) { jobline.part_type === "PAN" && jobline.db_price !== jobline.act_price ) { - jobline.db_price = jobline.act_price; + jobline.db_price = jobline.act_price; } if ( @@ -386,15 +386,11 @@ async function DecodeLinFile(extensionlessFilePath) { !!jobline.act_price && jobline.act_price > jobline.db_price ) { - // log.info( - // "Act price higher than existing db price", - // jobline.line_desc, - // jobline.db_price, - // jobline.act_price - // ); + //Actual price should never be higher than the DB Price. jobline.db_price = jobline.act_price; } + //Logic Based Exclusions. if ( !jobline.part_type || jobline.db_ref.startsWith("900") || @@ -404,15 +400,22 @@ async function DecodeLinFile(extensionlessFilePath) { jobline.line_desc.toLowerCase().startsWith("hazardous") || jobline.line_desc.toLowerCase().startsWith("detail") || jobline.line_desc.toLowerCase().startsWith("clean") || - // jobline.part_type.toUpperCase() === "PAG" || + // 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.glass_flag === true || + //jobline.glass_flag === true //Removed for RPS-43. jobline.db_price === 0 ) jobline.ignore = true; + //RPS-42 Dynamic Inclusion or Exclusion of Lines based on RPS-EXCLUDE or RPS. + if (jobline.oem_partno.toLowerCase().includes("/rps-exclude")) { + jobline.ignore = true; + } else if (jobline.oem_partno.toLowerCase().includes("/rps")) { + jobline.ignore = false; + } + delete jobline.glass_flag; return jobline; }); From a92b04a37b5886ce3dbbc6c750285102ef5b3526 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 13 Nov 2020 14:33:59 -0800 Subject: [PATCH 09/15] Added reporting variance to header of reporting RPS-45 --- .../reporting-totals-stats.molecule.jsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/molecules/reporting-totals-stats/reporting-totals-stats.molecule.jsx b/src/components/molecules/reporting-totals-stats/reporting-totals-stats.molecule.jsx index 066fe24..a7f69e8 100644 --- a/src/components/molecules/reporting-totals-stats/reporting-totals-stats.molecule.jsx +++ b/src/components/molecules/reporting-totals-stats/reporting-totals-stats.molecule.jsx @@ -54,6 +54,15 @@ export function ReportingTotalsStatsMolecule({ reportingLoading, scoreCard }) { value={((scoreCard.currentRpsPc || 0) * 100).toFixed(1)} suffix="%" /> +
Date: Fri, 13 Nov 2020 14:38:17 -0800 Subject: [PATCH 10/15] Added NA DB Price Exclusion. RPS-46 --- electron/decoder/decoder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index 77bc966..1dca8d5 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -405,7 +405,7 @@ async function DecodeLinFile(extensionlessFilePath) { jobline.part_type.toUpperCase() === "PASL" || jobline.part_type.toUpperCase() === "PAE" || //jobline.glass_flag === true //Removed for RPS-43. - jobline.db_price === 0 + jobline.db_price === 0 //Added as a part of RPS-46. ) jobline.ignore = true; From b6ce94df0811a039e9a645b72fb6a2092acd639d Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Fri, 13 Nov 2020 15:54:39 -0800 Subject: [PATCH 11/15] Added variance reporting on header RPS-45 --- .../reporting-scatterchart.molecule.jsx | 92 ++++++++++++++----- src/redux/reporting/reporting.sagas.js | 9 +- 2 files changed, 78 insertions(+), 23 deletions(-) diff --git a/src/components/molecules/reporting-scatterchart/reporting-scatterchart.molecule.jsx b/src/components/molecules/reporting-scatterchart/reporting-scatterchart.molecule.jsx index c1fd722..5ecf75b 100644 --- a/src/components/molecules/reporting-scatterchart/reporting-scatterchart.molecule.jsx +++ b/src/components/molecules/reporting-scatterchart/reporting-scatterchart.molecule.jsx @@ -1,5 +1,11 @@ -import { Card, Skeleton, Typography, Tooltip as AntdToolTip } from "antd"; -import React from "react"; +import { + Card, + Radio, + Skeleton, + Tooltip as AntdToolTip, + Typography, +} from "antd"; +import React, { useState } from "react"; import { connect } from "react-redux"; import { CartesianGrid, @@ -24,19 +30,23 @@ const mapStateToProps = createStructuredSelector({ reportingLoading: selectReportLoading, scoreCard: selectScorecard, }); -const mapDispatchToProps = (dispatch) => ({ - //setUserLanguage: language => dispatch(setUserLanguage(language)) -}); +const mapDispatchToProps = (dispatch) => ({}); export default connect( mapStateToProps, mapDispatchToProps )(ReportingScatterChartMolecule); export function ReportingScatterChartMolecule({ reportingLoading, scoreCard }) { + const [type, setType] = useState("percent"); + if (reportingLoading) return ; if (!scoreCard) return ; + const handleTypeChange = (e) => { + setType(e.target.value); + }; + return (
- - % Variance from Target - +
+ {type === "percent" && ( + + + % Variance from Target + + + )} + {type === "dollars" && ( + + + $ Variance from Target + + + )} + + + % - Percent + $ - Dollars + +
- + {type === "percent" && ( + + )} + {type === "dollars" && ( + + )} + -
-
{item.owner} {item.vehicle} @@ -88,6 +132,12 @@ export function ReportingScatterChartMolecule({ reportingLoading, scoreCard }) { {item.dbPriceSum.toFormat()} + + {`${item.deviationPc}%`} + + + ${item.deviationDollars} + ); }} diff --git a/src/redux/reporting/reporting.sagas.js b/src/redux/reporting/reporting.sagas.js index 7af6c47..055797c 100644 --- a/src/redux/reporting/reporting.sagas.js +++ b/src/redux/reporting/reporting.sagas.js @@ -102,8 +102,13 @@ export function* handleCalculateScoreCard({ payload: jobs }) { actPriceSum ); + const deviationPc = Math.round((jobRpsPc - jobTarget) * 1000) / 10; + scoreCard.scatterChart[job.group].push({ - deviation: Math.round((jobRpsPc - jobTarget) * 1000) / 10, + deviationPc: isNaN(deviationPc) ? -100 : deviationPc, + deviationDollars: ( + jobRpsDollars.subtract(expectedRpsDollars).getAmount() / 100 + ).toFixed(2), age: job.v_age, dbPriceSum, dbPriceSumAmt: dbPriceSum.getAmount() / 100, @@ -112,7 +117,7 @@ export function* handleCalculateScoreCard({ payload: jobs }) { vehicle: `${job.v_model_yr} ${job.v_makedesc} ${job.v_model} (${job.v_type}) - ${job.group}`, clm_no: job.clm_no, jobRpsDollars, - jobRpsPc, + jobRpsPc: isNaN(jobRpsPc) ? -1 : jobRpsPc, }); //sum db price * percentage expected. From ecf911bc436750c64fa75076bf5fd5e4e5d0758e Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 16 Nov 2020 10:04:11 -0800 Subject: [PATCH 12/15] Added release notes display to updater. RPS-48 --- README.md | 3 ++ WIP Changelog.txt | 18 ++++++++ changelog.json | 7 +++ electron/electron-store.js | 3 +- electron/ipc-main-handler.js | 13 +++++- electron/main.js | 10 +++++ .../release-notes/release-notes.molecule.jsx | 44 +++++++++++++++++++ src/components/pages/routes/routes.page.jsx | 3 +- src/ipc.types.js | 2 + src/ipc/ipc-renderer-handler.js | 8 ++++ src/redux/application/application.actions.js | 5 +++ src/redux/application/application.reducer.js | 3 ++ .../application/application.selectors.js | 6 +++ src/redux/application/application.types.js | 2 +- 14 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 WIP Changelog.txt create mode 100644 changelog.json create mode 100644 src/components/molecules/release-notes/release-notes.molecule.jsx diff --git a/README.md b/README.md index 89b278a..3a21f6d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +Creating Release Notes Tools: +https://onlinestringtools.com/json-stringify-string + This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). ## Available Scripts diff --git a/WIP Changelog.txt b/WIP Changelog.txt new file mode 100644 index 0000000..b72b11e --- /dev/null +++ b/WIP Changelog.txt @@ -0,0 +1,18 @@ +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. + + +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. + + + diff --git a/changelog.json b/changelog.json new file mode 100644 index 0000000..4ae60ec --- /dev/null +++ b/changelog.json @@ -0,0 +1,7 @@ +{ + "1.0.9": { + "title": "Release Notes for 1.0.9", + "date": "11/16/2020", + "notes": "New Features: \n\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\n\nBug Fixes: \n\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." + } +} diff --git a/electron/electron-store.js b/electron/electron-store.js index b444ac8..488fe8d 100644 --- a/electron/electron-store.js +++ b/electron/electron-store.js @@ -2,13 +2,14 @@ const Store = require("electron-store"); const store = new Store({ defaults: { + showChangeLog: true, enableNotifications: true, filePaths: [], accepted_ins_co: [], runWatcherOnStartup: true, polling: { enabled: false, - pollingInterval: 1000, + pollingInterval: 30000, }, }, }); diff --git a/electron/ipc-main-handler.js b/electron/ipc-main-handler.js index 54f9858..2d28b1a 100644 --- a/electron/ipc-main-handler.js +++ b/electron/ipc-main-handler.js @@ -1,4 +1,5 @@ -const { ipcMain } = require("electron"); +const { ipcMain, app: electronApp } = require("electron"); +const { app } = require("firebase"); const { default: ipcTypes } = require("../src/ipc.types"); const { store } = require("./electron-store"); //Import Ipc Handlers @@ -32,3 +33,13 @@ ipcMain.on(ipcTypes.store.getAll, (event, obj) => { const val = store.get(); event.sender.send(ipcTypes.store.response, val); }); + +ipcMain.on(ipcTypes.app.toMain.getReleaseNotes, (event, obj) => { + const showNotes = store.get("showChangeLog"); + if (showNotes) { + 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 f8f6d25..e9bb080 100644 --- a/electron/main.js +++ b/electron/main.js @@ -81,6 +81,15 @@ var menu = Menu.buildFromTemplate([ checkForUpdates(); }, }, + { + label: `Show Release Notes`, + click() { + mainWindow.webContents.send( + ipcTypes.app.toRenderer.setReleaseNotes, + require("../changelog.json")[app.getVersion()] + ); + }, + }, { label: "Open Config File", click() { @@ -318,6 +327,7 @@ autoUpdater.on("update-downloaded", (ev, info) => { if (buttonIndex === 0) { const isSilent = true; const isForceRunAfter = true; + store.set("showChangeLog", true); autoUpdater.quitAndInstall(isSilent, isForceRunAfter); } else { logger.error("Error"); diff --git a/src/components/molecules/release-notes/release-notes.molecule.jsx b/src/components/molecules/release-notes/release-notes.molecule.jsx new file mode 100644 index 0000000..6f118fc --- /dev/null +++ b/src/components/molecules/release-notes/release-notes.molecule.jsx @@ -0,0 +1,44 @@ +import { Modal } from "antd"; +import React, { useEffect } from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import ipcTypes from "../../../ipc.types"; +import { setReleaseNotes } from "../../../redux/application/application.actions"; +import { selectReleaseNotes } from "../../../redux/application/application.selectors"; +const mapStateToProps = createStructuredSelector({ + releaseNotes: selectReleaseNotes, +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) + setReleaseNotes: (notes) => dispatch(setReleaseNotes(notes)), +}); +const { ipcRenderer } = window; + +export function ReleaseNotes({ releaseNotes, setReleaseNotes }) { + console.log("ReleaseNotes -> releaseNotes", releaseNotes); + + useEffect(() => { + ipcRenderer.send(ipcTypes.default.app.toMain.getReleaseNotes); + }, []); + + const handleOk = () => { + ipcRenderer.send(ipcTypes.default.store.set, { showChangeLog: false }); + setReleaseNotes(null); + }; + + return ( + +
{releaseNotes && releaseNotes.date}
+
+ {releaseNotes && releaseNotes.notes} +
+
+ ); +} +export default connect(mapStateToProps, mapDispatchToProps)(ReleaseNotes); diff --git a/src/components/pages/routes/routes.page.jsx b/src/components/pages/routes/routes.page.jsx index b9299bb..4e89cff 100644 --- a/src/components/pages/routes/routes.page.jsx +++ b/src/components/pages/routes/routes.page.jsx @@ -5,6 +5,7 @@ import { Route } from "react-router-dom"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../../redux/user/user.selectors"; import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; +import ReleaseNotes from "../../molecules/release-notes/release-notes.molecule"; import SiderMenuOrganism from "../../organisms/sider-menu/sider-menu.organism"; import UpdateManagerOrganism from "../../organisms/update-manager/update-manager.organism"; import JobsPage from "../jobs/jobs.page"; @@ -40,7 +41,7 @@ export function RoutesPage({ bodyshop }) { - + diff --git a/src/ipc.types.js b/src/ipc.types.js index c4ebd88..95bdd3f 100644 --- a/src/ipc.types.js +++ b/src/ipc.types.js @@ -12,11 +12,13 @@ exports.default = { checkForUpdates: "app_checkForUpdates", downloadUpdates: "app_downloadUpdates", installUpdates: "app_installupdates", + getReleaseNotes: "app_getReleaseNotes", }, toRenderer: { updateAvailable: "app_updateAvailable", downloadProgress: "app_downloadProgress", signOut: "app_signOut", + setReleaseNotes: "app_setReleaseNotes", }, }, store: { diff --git a/src/ipc/ipc-renderer-handler.js b/src/ipc/ipc-renderer-handler.js index 87faa92..1d47322 100644 --- a/src/ipc/ipc-renderer-handler.js +++ b/src/ipc/ipc-renderer-handler.js @@ -1,5 +1,6 @@ import ipcTypes from "../ipc.types"; import { + setReleaseNotes, setSettings, setUpdateAvailable, setUpdateProgress, @@ -89,3 +90,10 @@ ipcRenderer.on( store.dispatch(signOutStart()); } ); + +ipcRenderer.on( + ipcTypes.default.app.toRenderer.setReleaseNotes, + async (event, releaseNotes) => { + store.dispatch(setReleaseNotes(releaseNotes)); + } +); diff --git a/src/redux/application/application.actions.js b/src/redux/application/application.actions.js index 71c4a0c..e38f2b8 100644 --- a/src/redux/application/application.actions.js +++ b/src/redux/application/application.actions.js @@ -52,3 +52,8 @@ export const setUpdateProgress = (progress) => ({ type: ApplicationActionTypes.SET_UPDATE_PROGRESS, payload: progress, }); + +export const setReleaseNotes = (releaseNotes) => ({ + type: ApplicationActionTypes.SET_RELEASE_NOTES, + payload: releaseNotes, +}); diff --git a/src/redux/application/application.reducer.js b/src/redux/application/application.reducer.js index c4896cc..549bbcc 100644 --- a/src/redux/application/application.reducer.js +++ b/src/redux/application/application.reducer.js @@ -9,6 +9,7 @@ const INITIAL_STATE = { settings: {}, updateAvailable: false, updateProgress: null, + releaseNotes: null, }; const { ipcRenderer } = window; @@ -66,6 +67,8 @@ const applicationReducer = (state = INITIAL_STATE, action) => { return { ...state, updateAvailable: action.payload }; case ApplicationActionTypes.SET_UPDATE_PROGRESS: return { ...state, updateProgress: action.payload }; + case ApplicationActionTypes.SET_RELEASE_NOTES: + return { ...state, releaseNotes: action.payload }; default: return state; } diff --git a/src/redux/application/application.selectors.js b/src/redux/application/application.selectors.js index aad8463..729e391 100644 --- a/src/redux/application/application.selectors.js +++ b/src/redux/application/application.selectors.js @@ -36,7 +36,13 @@ export const selectUpdateAvailable = createSelector( [selectApplication], (application) => application.updateAvailable ); + export const selectUpdateProgress = createSelector( [selectApplication], (application) => application.updateProgress ); + +export const selectReleaseNotes = createSelector( + [selectApplication], + (application) => application.releaseNotes +); diff --git a/src/redux/application/application.types.js b/src/redux/application/application.types.js index 3e24870..bdb4e27 100644 --- a/src/redux/application/application.types.js +++ b/src/redux/application/application.types.js @@ -10,6 +10,6 @@ const ApplicationActionTypes = { SET_SETTINGS: "SET_SETTINGS", SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE", SET_UPDATE_PROGRESS: "SET_UPDATE_PROGRESS", - + SET_RELEASE_NOTES: "SET_RELEASE_NOTES", }; export default ApplicationActionTypes; From be6262f4ec37dc0768c8dbfb83a9d9c7a3d12f9c Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 16 Nov 2020 10:08:21 -0800 Subject: [PATCH 13/15] Added auto update check every 30 minutes. RPS-38 --- Xdev-app-update.yml => dev-app-update.yml | 0 electron/main.js | 11 ++++------- 2 files changed, 4 insertions(+), 7 deletions(-) rename Xdev-app-update.yml => dev-app-update.yml (100%) diff --git a/Xdev-app-update.yml b/dev-app-update.yml similarity index 100% rename from Xdev-app-update.yml rename to dev-app-update.yml diff --git a/electron/main.js b/electron/main.js index e9bb080..6c71781 100644 --- a/electron/main.js +++ b/electron/main.js @@ -204,6 +204,10 @@ app.whenReady().then(() => { .catch((error) => console.log(`An error occurred: , ${error}`)); } + setInterval(() => { + checkForUpdates(); + }, 1000 * 60 * 30); //Added auto update check for RPS-38 + // ipcMain.on(ipcTypes.default.webcontent, (event, ...obj) => { // console.log("event", event); // mainWindow.webContents.send(event, obj); @@ -255,9 +259,6 @@ function createTray() { return appIcon; } -// autoUpdater.on("checking-for-update", () => { -// log.log("Checking for update..."); -// }); autoUpdater.on("update-available", (ev) => { log.log("Update available.", ev); mainWindow.webContents.send(ipcTypes.app.toRenderer.updateAvailable, ev); @@ -270,10 +271,6 @@ autoUpdater.on("error", (ev, err) => { log.log("Error in auto-updater.", ev, err); }); -// // autoUpdater.on("update-downloaded", (ev, info) => { -// // console.log("Update downloaded; will install in 5 seconds"); -// // }); - function openNoticeWindow() { if (noticeWindow) { noticeWindow.focus(); From 93ca4e257ffbf059bc50d4545d0a8f583646ebb3 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 16 Nov 2020 10:09:43 -0800 Subject: [PATCH 14/15] Updated release notes. --- WIP Changelog.txt | 9 ++------- dev-app-update.yml => Xdev-app-update.yml | 0 changelog.json | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) rename dev-app-update.yml => Xdev-app-update.yml (100%) diff --git a/WIP Changelog.txt b/WIP Changelog.txt index b72b11e..0f25504 100644 --- a/WIP Changelog.txt +++ b/WIP Changelog.txt @@ -1,5 +1,4 @@ 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. @@ -7,12 +6,8 @@ New Features: - 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. - - - +- 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 diff --git a/dev-app-update.yml b/Xdev-app-update.yml similarity index 100% rename from dev-app-update.yml rename to Xdev-app-update.yml diff --git a/changelog.json b/changelog.json index 4ae60ec..c935fca 100644 --- a/changelog.json +++ b/changelog.json @@ -2,6 +2,6 @@ "1.0.9": { "title": "Release Notes for 1.0.9", "date": "11/16/2020", - "notes": "New Features: \n\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\n\nBug Fixes: \n\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." + "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." } } From f4f4c403d41870269a2c97d6382d32bb49f12fae Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Mon, 16 Nov 2020 10:48:09 -0800 Subject: [PATCH 15/15] Fixed incorrect RPS Variance % display. --- electron/analytics.js | 1 + src/redux/reporting/reporting.sagas.js | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/electron/analytics.js b/electron/analytics.js index 5d8b23b..f7f22eb 100644 --- a/electron/analytics.js +++ b/electron/analytics.js @@ -7,6 +7,7 @@ const { default: ipcTypes } = require("../src/ipc.types"); Nucleus.init("5f91b569b95bac34eefdb63a", { disableInDev: true, debug: false, + version: app.getVersion(), }); Nucleus.setProps({ diff --git a/src/redux/reporting/reporting.sagas.js b/src/redux/reporting/reporting.sagas.js index 055797c..f22c7f9 100644 --- a/src/redux/reporting/reporting.sagas.js +++ b/src/redux/reporting/reporting.sagas.js @@ -136,16 +136,14 @@ export function* handleCalculateScoreCard({ payload: jobs }) { scoreCard.shopRpsExpectedDollars ); - scoreCard.variancePc = - scoreCard.varianceDollars.getAmount() / - scoreCard.shopRpsExpectedDollars.getAmount(); - scoreCard.currentRpsPc = scoreCard.shopRpsTotalDollars.getAmount() / scoreCard.allJobsSumDbPrice.getAmount(); scoreCard.targetRpsPc = scoreCard.shopRpsExpectedDollars.getAmount() / scoreCard.allJobsSumDbPrice.getAmount(); + + scoreCard.variancePc = scoreCard.currentRpsPc - scoreCard.targetRpsPc; //Set the data. yield put(setScoreCard(scoreCard)); yield put(setReportingData(jobs));