From 584f43bc4e146c3144df9c16cb2b6450494457e4 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Fri, 16 Oct 2020 15:14:25 -0700 Subject: [PATCH] Additional Changes for calculations of RPS %. --- electron/decoder/decoder.js | 179 +++++++++++------- electron/file-watcher/file-watcher.js | 3 +- .../down.yaml | 5 + .../up.yaml | 23 +++ .../down.yaml | 6 + .../up.yaml | 20 ++ .../down.yaml | 1 + .../up.yaml | 5 + .../down.yaml | 5 + .../up.yaml | 6 + .../down.yaml | 25 +++ .../up.yaml | 26 +++ .../down.yaml | 6 + .../up.yaml | 16 ++ hasura/migrations/metadata.yaml | 16 +- .../price-diff-pc-formatter.atom.jsx | 52 +++++ .../price-diff-pc-formatter.styles.scss | 9 + .../target-price-diff-pc.atom.jsx | 39 ++++ .../jobs-detail-description.molecule.jsx | 31 ++- .../jobs-lines-table.molecule.jsx | 29 ++- .../jobs-targets-stats.molecule.jsx | 52 +++++ .../jobs-detail/jobs-detail.organism.jsx | 9 +- .../jobs-list/jobs-list.organism.jsx | 31 +-- src/components/pages/jobs/jobs.page.jsx | 7 +- src/graphql/bodyshop.queries.js | 1 + src/graphql/veh_group.queries.js | 11 +- src/ipc/ipc-estimate-utils.js | 6 +- 27 files changed, 504 insertions(+), 115 deletions(-) create mode 100644 hasura/migrations/1602881581659_create_table_public_targets/down.yaml create mode 100644 hasura/migrations/1602881581659_create_table_public_targets/up.yaml create mode 100644 hasura/migrations/1602881591377_update_permission_user_public_table_targets/down.yaml create mode 100644 hasura/migrations/1602881591377_update_permission_user_public_table_targets/up.yaml create mode 100644 hasura/migrations/1602881684708_drop_table_public_targets/down.yaml create mode 100644 hasura/migrations/1602881684708_drop_table_public_targets/up.yaml create mode 100644 hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/down.yaml create mode 100644 hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/up.yaml create mode 100644 hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/down.yaml create mode 100644 hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/up.yaml create mode 100644 hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/down.yaml create mode 100644 hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/up.yaml create mode 100644 src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx create mode 100644 src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.styles.scss create mode 100644 src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx create mode 100644 src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js index bfc41fc..448ac7b 100644 --- a/electron/decoder/decoder.js +++ b/electron/decoder/decoder.js @@ -184,76 +184,128 @@ async function DecodeTtlFile(extensionlessFilePath) { async function DecodeLinFile(extensionlessFilePath) { let dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`); let records = await dbf.readRecords(); - let joblines = records.map((record) => - _.transform( - _.pick(record, [ - "LINE_NO", - "LINE_IND", - // "LINE_REF", - // "TRAN_CODE", - "DB_REF", - "UNQ_SEQ", - // "WHO_PAYS", - "LINE_DESC", - "PART_TYPE", - // "PART_DESCJ", - "GLASS_FLAG", - "OEM_PARTNO", - // "PRICE_INC", - // "ALT_PART_I", - // "TAX_PART", - "DB_PRICE", - "ACT_PRICE", - // "PRICE_J", - // "CERT_PART", - "PART_QTY", - // "ALT_CO_ID", - // "ALT_PARTNO", - // "ALT_OVERRD", - // "ALT_PARTM", - // "PRT_DSMK_P", - // "PRT_DSMK_M", - // "MOD_LBR_TY", - // "DB_HRS", - // "MOD_LB_HRS", - // "LBR_INC", - // "LBR_OP", - // "LBR_HRS_J", - // "LBR_TYP_J", - // "LBR_OP_J", - // "PAINT_STG", - // "PAINT_TONE", - // "LBR_TAX", - // "LBR_AMT", - // "MISC_AMT", - // "MISC_SUBLT", - // "MISC_TAX", - // "BETT_TYPE", - // "BETT_PCTG", - // "BETT_AMT", - // "BETT_TAX", - ]), - function (result, val, key) { - //Required because unq_seq gets pulled as a numeric instaed of a string. - console.log("key", key); - if (key === "UNQ_SEQ") { - return (result[key.toLowerCase()] = val.toString()); - } - return (result[key.toLowerCase()] = val); - } - ) - ); + let joblines = records + .map((record) => { + console.log( + "object", + _.pick(record, [ + "LINE_NO", + "LINE_IND", + // "LINE_REF", + // "TRAN_CODE", + "DB_REF", + "UNQ_SEQ", + // "WHO_PAYS", + "LINE_DESC", + "PART_TYPE", + // "PART_DESCJ", + "GLASS_FLAG", + "OEM_PARTNO", + // "PRICE_INC", + // "ALT_PART_I", + // "TAX_PART", + "DB_PRICE", + "ACT_PRICE", + // "PRICE_J", + // "CERT_PART", + "PART_QTY", + // "ALT_CO_ID", + // "ALT_PARTNO", + // "ALT_OVERRD", + // "ALT_PARTM", + // "PRT_DSMK_P", + // "PRT_DSMK_M", + // "MOD_LBR_TY", + // "DB_HRS", + // "MOD_LB_HRS", + // "LBR_INC", + // "LBR_OP", + // "LBR_HRS_J", + // "LBR_TYP_J", + // "LBR_OP_J", + // "PAINT_STG", + // "PAINT_TONE", + // "LBR_TAX", + // "LBR_AMT", + // "MISC_AMT", + // "MISC_SUBLT", + // "MISC_TAX", + // "BETT_TYPE", + // "BETT_PCTG", + // "BETT_AMT", + // "BETT_TAX", + ]) + ); + return _.transform( + _.pick(record, [ + "LINE_NO", + "LINE_IND", + // "LINE_REF", + // "TRAN_CODE", + "DB_REF", + "UNQ_SEQ", + // "WHO_PAYS", + "LINE_DESC", + "PART_TYPE", + // "PART_DESCJ", - const m = joblines + "OEM_PARTNO", + // "PRICE_INC", + // "ALT_PART_I", + // "TAX_PART", + "DB_PRICE", + "ACT_PRICE", + // "PRICE_J", + // "CERT_PART", + "PART_QTY", + // "ALT_CO_ID", + // "ALT_PARTNO", + // "ALT_OVERRD", + // "ALT_PARTM", + // "PRT_DSMK_P", + // "PRT_DSMK_M", + // "MOD_LBR_TY", + // "DB_HRS", + // "MOD_LB_HRS", + // "LBR_INC", + // "LBR_OP", + // "LBR_HRS_J", + // "LBR_TYP_J", + // "LBR_OP_J", + // "PAINT_STG", + // "PAINT_TONE", + // "LBR_TAX", + // "LBR_AMT", + // "MISC_AMT", + // "MISC_SUBLT", + // "MISC_TAX", + // "BETT_TYPE", + // "BETT_PCTG", + // "BETT_AMT", + // "BETT_TAX", + "GLASS_FLAG", + ]), + function (result, val, key) { + //Required because unq_seq gets pulled as a numeric instaed of a string. + console.log("key", key); + if (key === "UNQ_SEQ") { + return (result[key.toLowerCase()] = val.toString()); + } + return (result[key.toLowerCase()] = val); + } + ); + }) .filter( (jobline) => - jobline.PART_TYPE && + jobline.part_type && !jobline.db_ref.startsWith("900") && - (jobline.part_type && 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 === false ) .map((jobline) => { - console.log("Massagejobline", jobline); if ( (jobline.db_price === null || jobline.db_price === 0) && !!jobline.act_price && @@ -285,7 +337,6 @@ async function DecodeLinFile(extensionlessFilePath) { } delete jobline.glass_flag; - console.log(jobline); return jobline; }); diff --git a/electron/file-watcher/file-watcher.js b/electron/file-watcher/file-watcher.js index 1e8caf0..edde955 100644 --- a/electron/file-watcher/file-watcher.js +++ b/electron/file-watcher/file-watcher.js @@ -3,7 +3,6 @@ const ipcTypes = require("../../src/ipc.types"); const path = require("path"); const { DecodeEstimate } = require("../decoder/decoder"); const { BrowserWindow } = require("electron"); -const _ = require("lodash"); const { store } = require("../electron-store"); const { NewNotification, @@ -26,7 +25,7 @@ async function StartWatcher() { if (watcher) { try { - console.log("Trying to close watcher - it already existed.111"); + console.log("Trying to close watcher - it already existed."); await watcher.close(); console.log("Watcher closed successfully!"); diff --git a/hasura/migrations/1602881581659_create_table_public_targets/down.yaml b/hasura/migrations/1602881581659_create_table_public_targets/down.yaml new file mode 100644 index 0000000..58d4141 --- /dev/null +++ b/hasura/migrations/1602881581659_create_table_public_targets/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: DROP TABLE "public"."targets"; + type: run_sql diff --git a/hasura/migrations/1602881581659_create_table_public_targets/up.yaml b/hasura/migrations/1602881581659_create_table_public_targets/up.yaml new file mode 100644 index 0000000..bdb42ab --- /dev/null +++ b/hasura/migrations/1602881581659_create_table_public_targets/up.yaml @@ -0,0 +1,23 @@ +- args: + cascade: false + read_only: false + sql: CREATE EXTENSION IF NOT EXISTS pgcrypto; + type: run_sql +- args: + cascade: false + read_only: false + sql: "CREATE TABLE \"public\".\"targets\"(\"id\" uuid NOT NULL DEFAULT gen_random_uuid(), + \"updated_at\" timestamptz NOT NULL DEFAULT now(), \"created_at\" timestamptz + NOT NULL DEFAULT now(), \"label\" text NOT NULL, \"config\" jsonb NOT NULL DEFAULT + jsonb_build_object(), \"start_date\" date NOT NULL, \"end_date\" date, PRIMARY + KEY (\"id\") );\nCREATE OR REPLACE FUNCTION \"public\".\"set_current_timestamp_updated_at\"()\nRETURNS + TRIGGER AS $$\nDECLARE\n _new record;\nBEGIN\n _new := NEW;\n _new.\"updated_at\" + = NOW();\n RETURN _new;\nEND;\n$$ LANGUAGE plpgsql;\nCREATE TRIGGER \"set_public_targets_updated_at\"\nBEFORE + UPDATE ON \"public\".\"targets\"\nFOR EACH ROW\nEXECUTE PROCEDURE \"public\".\"set_current_timestamp_updated_at\"();\nCOMMENT + ON TRIGGER \"set_public_targets_updated_at\" ON \"public\".\"targets\" \nIS + 'trigger to set value of column \"updated_at\" to current timestamp on row update';" + type: run_sql +- args: + name: targets + schema: public + type: add_existing_table_or_view diff --git a/hasura/migrations/1602881591377_update_permission_user_public_table_targets/down.yaml b/hasura/migrations/1602881591377_update_permission_user_public_table_targets/down.yaml new file mode 100644 index 0000000..f39ea3a --- /dev/null +++ b/hasura/migrations/1602881591377_update_permission_user_public_table_targets/down.yaml @@ -0,0 +1,6 @@ +- args: + role: user + table: + name: targets + schema: public + type: drop_select_permission diff --git a/hasura/migrations/1602881591377_update_permission_user_public_table_targets/up.yaml b/hasura/migrations/1602881591377_update_permission_user_public_table_targets/up.yaml new file mode 100644 index 0000000..c50793b --- /dev/null +++ b/hasura/migrations/1602881591377_update_permission_user_public_table_targets/up.yaml @@ -0,0 +1,20 @@ +- args: + permission: + allow_aggregations: false + backend_only: false + columns: + - id + - updated_at + - created_at + - label + - config + - start_date + - end_date + computed_fields: [] + filter: {} + limit: null + role: user + table: + name: targets + schema: public + type: create_select_permission diff --git a/hasura/migrations/1602881684708_drop_table_public_targets/down.yaml b/hasura/migrations/1602881684708_drop_table_public_targets/down.yaml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/hasura/migrations/1602881684708_drop_table_public_targets/down.yaml @@ -0,0 +1 @@ +[] diff --git a/hasura/migrations/1602881684708_drop_table_public_targets/up.yaml b/hasura/migrations/1602881684708_drop_table_public_targets/up.yaml new file mode 100644 index 0000000..58d4141 --- /dev/null +++ b/hasura/migrations/1602881684708_drop_table_public_targets/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: DROP TABLE "public"."targets"; + type: run_sql diff --git a/hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/down.yaml b/hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/down.yaml new file mode 100644 index 0000000..29153d6 --- /dev/null +++ b/hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/down.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."bodyshops" DROP COLUMN "targets"; + type: run_sql diff --git a/hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/up.yaml b/hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/up.yaml new file mode 100644 index 0000000..2656d12 --- /dev/null +++ b/hasura/migrations/1602881697769_alter_table_public_bodyshops_add_column_targets/up.yaml @@ -0,0 +1,6 @@ +- args: + cascade: false + read_only: false + sql: ALTER TABLE "public"."bodyshops" ADD COLUMN "targets" jsonb NULL DEFAULT + jsonb_build_object(); + type: run_sql diff --git a/hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/down.yaml new file mode 100644 index 0000000..6854447 --- /dev/null +++ b/hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/down.yaml @@ -0,0 +1,25 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - id + - created_at + - updated_at + - shopname + computed_fields: [] + filter: + associations: + user: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: bodyshops + schema: public + type: create_select_permission diff --git a/hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/up.yaml new file mode 100644 index 0000000..a777f71 --- /dev/null +++ b/hasura/migrations/1602881706088_update_permission_user_public_table_bodyshops/up.yaml @@ -0,0 +1,26 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_select_permission +- args: + permission: + allow_aggregations: false + columns: + - created_at + - id + - shopname + - targets + - updated_at + computed_fields: [] + filter: + associations: + user: + authid: + _eq: X-Hasura-User-Id + role: user + table: + name: bodyshops + schema: public + type: create_select_permission diff --git a/hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/down.yaml b/hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/down.yaml new file mode 100644 index 0000000..0c08e23 --- /dev/null +++ b/hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/down.yaml @@ -0,0 +1,6 @@ +- args: + role: user + table: + name: bodyshops + schema: public + type: drop_update_permission diff --git a/hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/up.yaml b/hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/up.yaml new file mode 100644 index 0000000..04abe31 --- /dev/null +++ b/hasura/migrations/1602881715816_update_permission_user_public_table_bodyshops/up.yaml @@ -0,0 +1,16 @@ +- args: + permission: + backend_only: false + columns: + - targets + filter: + associations: + user: + authid: + _eq: X-Hasura-User-Id + set: {} + role: user + table: + name: bodyshops + schema: public + type: create_update_permission diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index e64d1e2..eb3f498 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -42,15 +42,27 @@ tables: - role: user permission: columns: - - id - created_at - - updated_at + - id - shopname + - targets + - updated_at filter: associations: user: authid: _eq: X-Hasura-User-Id + update_permissions: + - role: user + permission: + columns: + - targets + filter: + associations: + user: + authid: + _eq: X-Hasura-User-Id + check: null - table: schema: public name: joblines diff --git a/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx b/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx new file mode 100644 index 0000000..0225585 --- /dev/null +++ b/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom.jsx @@ -0,0 +1,52 @@ +import React, { useMemo } from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../../redux/user/user.selectors"; +import "./price-diff-pc-formatter.styles.scss"; +import { AlertFilled } from "@ant-design/icons"; +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); + +export function PriceDiffPcFormatterAtom({ + bodyshop, + price_diff_pc, + group, + v_age, +}) { + const metTarget = useMemo(() => { + const targetsForGroup = bodyshop.targets[group]; + if (!targetsForGroup) return 0; + const targetPc = targetsForGroup.filter( + (t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true) + ); + if (targetPc.length === 0) return false; + else if (targetPc.length === 1) return price_diff_pc >= targetPc[0].target; + else { + alert("Multiple targets match."); + return false; + } + }, [bodyshop, group, price_diff_pc, v_age]); + + return ( +
+ {(price_diff_pc * 100).toFixed(1)}% + {price_diff_pc === 1 ? ( + + ) : null} +
+ ); +} +export default connect( + mapStateToProps, + mapDispatchToProps +)(PriceDiffPcFormatterAtom); diff --git a/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.styles.scss b/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.styles.scss new file mode 100644 index 0000000..bd4b9f5 --- /dev/null +++ b/src/components/atoms/price-diff-pc-formatter/price-diff-pc-formatter.styles.scss @@ -0,0 +1,9 @@ +.blink_me { + animation: blinker 1s linear infinite; +} + +@keyframes blinker { + 50% { + opacity: 0; + } +} diff --git a/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx b/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx new file mode 100644 index 0000000..41ad786 --- /dev/null +++ b/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx @@ -0,0 +1,39 @@ +import { Statistic } from "antd"; +import React, { useMemo } from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../../redux/user/user.selectors"; + +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop, +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); + +export function PriceDiffPcFormatterAtom({ bodyshop, group, v_age }) { + const metTarget = useMemo(() => { + const targetsForGroup = bodyshop.targets[group]; + if (!targetsForGroup) return 0; + const targetPc = targetsForGroup.filter( + (t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true) + ); + if (targetPc.length === 0) return 0; + else if (targetPc.length === 1) return targetPc[0].target; + else { + return 0; + } + }, [bodyshop, group, v_age]); + + return ( + + ); +} +export default connect( + mapStateToProps, + mapDispatchToProps +)(PriceDiffPcFormatterAtom); diff --git a/src/components/molecules/jobs-detail-description/jobs-detail-description.molecule.jsx b/src/components/molecules/jobs-detail-description/jobs-detail-description.molecule.jsx index efc66e3..bfa497d 100644 --- a/src/components/molecules/jobs-detail-description/jobs-detail-description.molecule.jsx +++ b/src/components/molecules/jobs-detail-description/jobs-detail-description.molecule.jsx @@ -1,4 +1,4 @@ -import { Descriptions, Skeleton } from "antd"; +import { Descriptions, PageHeader, Skeleton } from "antd"; import React from "react"; import CurrencyFormatterAtom from "../../atoms/currency-formatter/currency-formatter.atom"; import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; @@ -10,24 +10,17 @@ export default function JobsDetailDescriptionMolecule({ loading, job }) { return (
- - {job.clm_no} - - {job.ins_co_nm} - - {`${job.ownr_fn} ${job.ownr_ln}`} - {`${job.v_model_yr} ${job.v_makedesc} ${job.v_model}`} - - {job.clm_total} - - {job.group} - {job.v_age} - + + + {`${job.ownr_fn} ${job.ownr_ln}`} + {`${job.v_model_yr} ${job.v_makedesc} ${job.v_model}`} + + {job.clm_total} + + {job.group} + {job.v_age} + +
); } 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 6c59a12..ddac46a 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 @@ -1,8 +1,10 @@ import { Table } from "antd"; import React from "react"; import CurrencyFormatterAtom from "../../atoms/currency-formatter/currency-formatter.atom"; +import PriceDiffPcFormatterAtom from "../../atoms/price-diff-pc-formatter/price-diff-pc-formatter.atom"; -export default function JobLinesTableMolecule({ loading, jobLines }) { +export default function JobLinesTableMolecule({ loading, job }) { + const { joblines } = job; const columns = [ { title: "#", @@ -48,9 +50,26 @@ export default function JobLinesTableMolecule({ loading, jobLines }) { ), }, { - title: "Qty.", - dataIndex: "part_qty", - key: "part_qty", + title: "Price Diff.", + dataIndex: "price_diff", + key: "price_diff", + + render: (text, record) => ( + {record.price_diff} + ), + }, + { + title: "Price Diff. %", + dataIndex: "price_diff_pc", + key: "price_diff_pc", + + render: (text, record) => ( + + ), }, ]; @@ -62,7 +81,7 @@ export default function JobLinesTableMolecule({ loading, jobLines }) { loading={loading} size="small" pagination={false} - dataSource={jobLines} + dataSource={joblines} scroll={{ x: true, //y: "40rem" diff --git a/src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx b/src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx new file mode 100644 index 0000000..3946596 --- /dev/null +++ b/src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx @@ -0,0 +1,52 @@ +import { Skeleton, Space, Statistic } from "antd"; +import React, { useMemo } from "react"; +import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; +import TargetPriceDiffPcAtom from "../../atoms/target-price-diff/target-price-diff-pc.atom"; +import _ from "lodash"; +import Dinero from "dinero.js"; + +export default function JobsTargetsStatsMolecule({ loading, job }) { + const currentRpsPc = useMemo(() => { + if (!job) { + return 0; + } + return ( + (_.sum(job.joblines.map((jl) => jl.price_diff_pc)) / + job.joblines.length) * + 100 + ).toFixed(1); + }, [job]); + + const currentRpsDollars = useMemo(() => { + if (!job) { + return 0; + } + return job.joblines.reduce((acc, val) => { + console.log("val.price_diff :>> ", val.price_diff); + if (val.price_diff > 0) { + return acc.add( + Dinero({ amount: Math.round((val.price_diff || 0) * 100) }) + ); + } else { + return acc; + } + }, Dinero()); + }, [job]); + + if (loading) return ; + if (!job) return ; + + return ( +
+ + + +
+ ); +} diff --git a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx index b4b5d14..2bb2c0b 100644 --- a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx +++ b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx @@ -8,6 +8,7 @@ import { selectSelectedJobId } from "../../../redux/application/application.sele import ErrorResultAtom from "../../atoms/error-result/error-result.atom"; import JobsDetailDescriptionMolecule from "../../molecules/jobs-detail-description/jobs-detail-description.molecule"; import JobsLinesTableMolecule from "../../molecules/jobs-lines-table/jobs-lines-table.molecule"; +import JobsTargetsStatsMolecule from "../../molecules/jobs-targets-stats/jobs-targets-stats.molecule"; import "./jobs-detail.organism.styles.scss"; const mapStateToProps = createStructuredSelector({ @@ -32,17 +33,21 @@ export function JobsDetailOrganism({ selectedJobId }) { errorMessage={JSON.stringify(error)} /> ); + return (
+ - {selectedJobId}
); } diff --git a/src/components/organisms/jobs-list/jobs-list.organism.jsx b/src/components/organisms/jobs-list/jobs-list.organism.jsx index 2583451..13e80f4 100644 --- a/src/components/organisms/jobs-list/jobs-list.organism.jsx +++ b/src/components/organisms/jobs-list/jobs-list.organism.jsx @@ -1,6 +1,6 @@ import { SyncOutlined } from "@ant-design/icons"; import { useQuery } from "@apollo/client"; -import { Button, List, Space, Spin, Typography } from "antd"; +import { Button, Divider, List, Space, Spin } from "antd"; import React, { useState } from "react"; import InfiniteScroll from "react-infinite-scroller"; import { connect } from "react-redux"; @@ -87,6 +87,7 @@ export function JobsTableOrganism({ selectedJobId, setSelectedJobId }) { useWindow={false} > ( -
- - {`${item.clm_no}${ - item.ins_co_nm ? ` | ${item.ins_co_nm}` : "" - }`} - - +
+ {item.clm_no || "No Claim Number"} + {item.updated_at}
- - {`${item.ownr_fn} ${item.ownr_ln}`} - - {`${item.v_model_yr} ${item.v_makedesc} ${item.v_model} ${item.v_vin}`} - - + +
{item.ins_co_nm || "No Insurance Co."}
+
{`${item.ownr_fn} ${item.ownr_ln}`}
+
+ {`${item.v_model_yr} ${item.v_makedesc} ${item.v_model} ${item.v_vin}`} +
)} diff --git a/src/components/pages/jobs/jobs.page.jsx b/src/components/pages/jobs/jobs.page.jsx index 8954478..e46adf3 100644 --- a/src/components/pages/jobs/jobs.page.jsx +++ b/src/components/pages/jobs/jobs.page.jsx @@ -2,8 +2,8 @@ import { Col, Row } from "antd"; import React from "react"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -import JobsListOrganism from "../../organisms/jobs-list/jobs-list.organism"; import JobsDetailOrganism from "../../organisms/jobs-detail/jobs-detail.organism"; +import JobsListOrganism from "../../organisms/jobs-list/jobs-list.organism"; const mapStateToProps = createStructuredSelector({}); const mapDispatchToProps = (dispatch) => ({}); @@ -12,11 +12,10 @@ export function JobsPage() { return (
- + - - + diff --git a/src/graphql/bodyshop.queries.js b/src/graphql/bodyshop.queries.js index 2c8c8bd..45e3d8c 100644 --- a/src/graphql/bodyshop.queries.js +++ b/src/graphql/bodyshop.queries.js @@ -4,6 +4,7 @@ export const QUERY_BODYSHOP = gql` bodyshops { id shopname + targets } } `; diff --git a/src/graphql/veh_group.queries.js b/src/graphql/veh_group.queries.js index 70f59a2..c2c517f 100644 --- a/src/graphql/veh_group.queries.js +++ b/src/graphql/veh_group.queries.js @@ -1,9 +1,16 @@ import gql from "graphql-tag"; export const QUERY_GROUPS_BY_MAKE_TYPE = gql` - query QUERY_GROUPS_BY_MAKE_TYPE($make: String!, $type: String) { + query QUERY_GROUPS_BY_MAKE_TYPE( + $make: String! + $type: String + $isNull: Boolean + ) { veh_groups( - where: { _and: { make: { _eq: $make } }, type: { _eq: $type } } + where: { + _and: { make: { _eq: $make } } + type: { _eq: $type, _is_null: $isNull } + } ) { id group diff --git a/src/ipc/ipc-estimate-utils.js b/src/ipc/ipc-estimate-utils.js index 312ace7..8b684e9 100644 --- a/src/ipc/ipc-estimate-utils.js +++ b/src/ipc/ipc-estimate-utils.js @@ -166,7 +166,11 @@ const DetermineVehicleGroup = async (job) => { query: QUERY_GROUPS_BY_MAKE_TYPE, variables: { make: job.v_makedesc.toUpperCase(), - type: job.v_type ? job.v_type.toUpperCase() : null, + type: + job.v_type && job.v_type.toUpperCase() !== "PC" + ? job.v_type.toUpperCase() + : null, + isNull: job.v_type && job.v_type.toUpperCase() !== "PC" ? false : true, }, });