From 49c28c2f6b71b607eb123ef0a5b72ebd9a3a0979 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 18 Apr 2024 17:05:49 -0700 Subject: [PATCH] WIP Audit Changes --- electron/audit/audit-ipc.js | 17 ++-- .../audit-results/audit-results.organism.jsx | 92 +++++++++++++++++++ .../sider-menu/sider-menu.organism.jsx | 14 +-- src/components/pages/audit/audit.page.jsx | 68 ++++++++++++-- .../pages/audit/audit.page.styles.scss | 8 ++ src/redux/reporting/reporting.reducer.js | 11 ++- src/redux/reporting/reporting.sagas.js | 37 ++++---- src/redux/reporting/reporting.selectors.js | 4 + 8 files changed, 203 insertions(+), 48 deletions(-) create mode 100644 src/components/organisms/audit-results/audit-results.organism.jsx create mode 100644 src/components/pages/audit/audit.page.styles.scss diff --git a/electron/audit/audit-ipc.js b/electron/audit/audit-ipc.js index 51d2875..5319720 100644 --- a/electron/audit/audit-ipc.js +++ b/electron/audit/audit-ipc.js @@ -29,14 +29,15 @@ ipcMain.on(ipcTypes.default.audit.toMain.browseForFile, async (event, arg) => { clm_no: line[0], close_date: line[1], v_model_yr: line[3], - v_model_desc: line[4], - under20kmiles: line[5], - pan_total: line[6], - paa_total: line[7], - pal_total: line[8], - pam_total: line[9], - eligible_db_price_total: Math.round((line[10] + Number.EPSILON) * 100) / 100, - eligible_act_price_total: Math.round((line[11] + Number.EPSILON) * 100) / 100, + v_make_desc: line[4], + v_model: line[5], + under20kmiles: line[6], + pan_total: line[7], + paa_total: line[8], + pal_total: line[9], + pam_total: line[10], + eligible_db_price_total: Math.round((line[11] + Number.EPSILON) * 100) / 100, + eligible_act_price_total: Math.round((line[12] + Number.EPSILON) * 100) / 100, expected_rps_dollars: Math.round((line[15] + Number.EPSILON) * 100) / 100, actual_rps_dollars: Math.round((line[16] + Number.EPSILON) * 100) / 100 }; diff --git a/src/components/organisms/audit-results/audit-results.organism.jsx b/src/components/organisms/audit-results/audit-results.organism.jsx new file mode 100644 index 0000000..df17852 --- /dev/null +++ b/src/components/organisms/audit-results/audit-results.organism.jsx @@ -0,0 +1,92 @@ +import { Card, Col, Row, Table } from "antd"; +import React from "react"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { setSelectedJobTargetPc } from "../../../redux/application/application.actions"; +import { selectAuditData } from "../../../redux/reporting/reporting.selectors"; +import { DateFormat } from "../../../util/constants"; +import dayjs from "../../../util/day"; + +const mapStateToProps = createStructuredSelector({ + selectAuditData: selectAuditData +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) + setSelectedJobTargetPc: (job) => dispatch(setSelectedJobTargetPc(job)) +}); + +export function AuditResultsOrganism({ selectAuditData }) { + console.log("🚀 ~ AuditResultsOrganism ~ selectAuditData:", selectAuditData); + const missingColumns = [ + { key: "clm_no", title: "Claim No.", dataIndex: "clm_no" }, + { + key: "close_date", + title: "[RPS] R4P", + dataIndex: "close_date", + render: (text, record) => dayjs(record.close_date).format(DateFormat) + }, + { key: "v_model_yr", title: "Model Year", dataIndex: "v_model_yr" }, + { key: "v_make_desc", title: "Make", dataIndex: "v_make_desc" }, + { key: "v_model", title: "Model", dataIndex: "v_model" } + ]; + + const mismatchColumns = [ + { key: "clm_no", title: "Claim No.", dataIndex: ["rps", "clm_no"] }, + { + key: "close_date", + title: "[RPS] R4P", + dataIndex: "close_date", + render: (text, record) => dayjs(record.rps.close_date).format(DateFormat) + }, + { + key: "close_date_audit", + title: "[Audit] R4P", + dataIndex: "close_date_audit", + render: (text, record) => dayjs(record.audit.close_date).format(DateFormat) + }, + { key: "v_model_yr", title: "Model Year", dataIndex: ["audit", "v_model_yr"] }, + { key: "v_make_desc", title: "Make", dataIndex: ["audit", "v_make_desc"] }, + { key: "v_model", title: "Model", dataIndex: ["audit", "v_model"] }, + { + key: "expected_rps", + title: "[RPS] Expected", + dataIndex: ["audit", "expectedRpsDollars"], + render: (text, record) => record.rps.expectedRpsDollars.toFormat() + }, + { key: "expected_audit", title: "[AUDIT] Expected", dataIndex: ["audit", "expected_rps_dollars"] }, + { + key: "actual_rps", + title: "[RPS] Actual", + dataIndex: ["audit", "jobRpsDollars"], + render: (text, record) => record.rps.jobRpsDollars.toFormat() + }, + { key: "actual_audit", title: "[Audit] Actual", dataIndex: ["audit", "actual_rps_dollars"] } + ]; + return ( +
+ + + + + + + + +
+ + + + +
+ + + + +
+ + + + + ); +} +export default connect(mapStateToProps, mapDispatchToProps)(AuditResultsOrganism); diff --git a/src/components/organisms/sider-menu/sider-menu.organism.jsx b/src/components/organisms/sider-menu/sider-menu.organism.jsx index e484977..54aa3d2 100644 --- a/src/components/organisms/sider-menu/sider-menu.organism.jsx +++ b/src/components/organisms/sider-menu/sider-menu.organism.jsx @@ -1,17 +1,17 @@ import { - PieChartOutlined, - SettingFilled, - CloseOutlined, + AuditOutlined, BarChartOutlined, + CloseOutlined, FileAddFilled, - LogoutOutlined + LogoutOutlined, + PieChartOutlined, + SettingFilled } from "@ant-design/icons"; import { Menu } from "antd"; import React from "react"; -import { Link } from "react-router-dom"; +import { Link, useLocation } from "react-router-dom"; import ipcTypes from "../../../ipc.types"; import SiderSignOut from "../../molecules/sider-sign-out/sider-sign-out.molecule"; -import { useLocation } from "react-router-dom"; const { ipcRenderer } = window; export default function SiderMenuOrganism() { @@ -40,7 +40,7 @@ export default function SiderMenuOrganism() { }, { key: "/audit", - icon: , + icon: , label: Audit }, { diff --git a/src/components/pages/audit/audit.page.jsx b/src/components/pages/audit/audit.page.jsx index 77e43a7..6d40b85 100644 --- a/src/components/pages/audit/audit.page.jsx +++ b/src/components/pages/audit/audit.page.jsx @@ -1,12 +1,12 @@ -import { Button } from "antd"; +import { Button, DatePicker, Form } from "antd"; import React from "react"; import ipcTypes from "../../../ipc.types"; -import ReportingDatesMolecule from "../../molecules/reporting-dates/reporting-dates.molecule"; - import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { queryReportingData } from "../../../redux/reporting/reporting.actions"; import dayjs from "../../../util/day"; +import AuditResultsOrganism from "../../organisms/audit-results/audit-results.organism"; +import "./audit.page.styles.scss"; const { ipcRenderer } = window; @@ -19,14 +19,66 @@ const mapDispatchToProps = (dispatch) => ({ export default connect(mapStateToProps, mapDispatchToProps)(AuditPage); export function AuditPage({ queryReportingData }) { - const handleBrowseForFile = async () => { - queryReportingData({ startDate: dayjs("2024-03-01"), endDate: dayjs("2024-03-31") }); + const handleBrowseForFile = async ({ dateRange }) => { + console.log("🚀 ~ handleBrowseForFile ~ dateRange:", dateRange); + queryReportingData({ + startDate: dateRange[0] || dayjs("2024-03-01"), + endDate: dateRange[1] || dayjs("2024-03-31") + }); ipcRenderer.send(ipcTypes.audit.toMain.browseForFile); }; + return ( -
- - ; +
+
+ 1) { + return Promise.reject("Time period exceeds 1 month. Please select a shorter date range."); + } else { + return Promise.resolve(); + } + } + } + ]} + > + + + + +
); } diff --git a/src/components/pages/audit/audit.page.styles.scss b/src/components/pages/audit/audit.page.styles.scss new file mode 100644 index 0000000..a51d7c8 --- /dev/null +++ b/src/components/pages/audit/audit.page.styles.scss @@ -0,0 +1,8 @@ +.audit-container { + height: 100%; + overflow-y: auto; + background-color: rgb(244, 244, 244); + & > .reporting-cards > * { + margin: 0.7rem; + } +} diff --git a/src/redux/reporting/reporting.reducer.js b/src/redux/reporting/reporting.reducer.js index d4d24da..a949796 100644 --- a/src/redux/reporting/reporting.reducer.js +++ b/src/redux/reporting/reporting.reducer.js @@ -5,6 +5,7 @@ const INITIAL_STATE = { scoreCard: null, error: null, loading: false, + audit: {} }; const applicationReducer = (state = INITIAL_STATE, action) => { @@ -16,18 +17,20 @@ const applicationReducer = (state = INITIAL_STATE, action) => { error: null, dates: { startDate: action.payload.startDate.toISOString(), - endDate: action.payload.endDate.toISOString(), - }, + endDate: action.payload.endDate.toISOString() + } }; case ReportingActionTypes.SET_REPORTING_ERROR: return { ...state, - error: action.payload, + error: action.payload }; case ReportingActionTypes.SET_REPORTING_DATA: return { ...state, data: action.payload }; case ReportingActionTypes.SET_SCORE_CARD: return { ...state, loading: false, scoreCard: action.payload }; + case ReportingActionTypes.SET_AUDIT_RESULTS: + return { ...state, loading: false, audit: action.payload }; case ReportingActionTypes.TOGGLE_GROUP_VERIFIED: return { ...state, @@ -37,7 +40,7 @@ const applicationReducer = (state = INITIAL_STATE, action) => { } else { return d; } - }), + }) }; default: return state; diff --git a/src/redux/reporting/reporting.sagas.js b/src/redux/reporting/reporting.sagas.js index 66dcc1e..e9883aa 100644 --- a/src/redux/reporting/reporting.sagas.js +++ b/src/redux/reporting/reporting.sagas.js @@ -6,7 +6,13 @@ import { REPORTING_GET_JOBS } from "../../graphql/reporting.queries"; import ipcTypes from "../../ipc.types"; import { CalculateJobRpsDollars, CalculateJobRpsPc } from "../../util/CalculateJobRps"; import GetJobTarget from "../../util/GetJobTarget"; -import { calculateScorecard, setReportingData, setScoreCard, setReportingError } from "./reporting.actions"; +import { + calculateScorecard, + setReportingData, + setScoreCard, + setReportingError, + setAuditResults +} from "./reporting.actions"; import ReportingApplicationTypes from "./reporting.types"; const { log, ipcRenderer } = window; @@ -53,35 +59,24 @@ export function* handleCalculateAudit({ payload: claimsArrayFromAudit }) { claimsArrayHashObject[cleansedClaimNo] = claim; }); - const JobsThatDontMatch = []; + let expectedMismatch = []; + let actualMismatch = []; rpsJobs.forEach((rpsJob) => { const matchingAuditJob = claimsArrayHashObject[rpsJob.clm_no]; - + if (!matchingAuditJob) { + return; + } if (Math.abs(rpsJob.expectedRpsDollars.getAmount() / 100 - matchingAuditJob.expected_rps_dollars) > 0.01) { - let styles = - "font-weight: bold; font-size: 22px;color: yellow; 6px 6px 0 rgb(226,91,14) , 9px 9px 0 rgb(245,221,8) , 12px 12px 0 rgb(5,148,68) "; - console.log( - "%c %s", - styles, - `Expected Savings Mismatch for ${rpsJob.clm_no} || ${rpsJob.expectedRpsDollars.toFormat()} >> ${ - matchingAuditJob.expected_rps_dollars - }` - ); + expectedMismatch.push({ clm_no: rpsJob.clm_no, rps: rpsJob, audit: matchingAuditJob }); } if (Math.abs(rpsJob.jobRpsDollars.getAmount() / 100 - matchingAuditJob.actual_rps_dollars) > 0.01) { - let styles = - "font-weight: bold; font-size: 22px;color: red; 6px 6px 0 rgb(226,91,14) , 9px 9px 0 rgb(245,221,8) , 12px 12px 0 rgb(5,148,68) "; - console.log( - "%c %s", - styles, - `Actual Savings Mismatch for ${rpsJob.clm_no} || ${rpsJob.jobRpsDollars.toFormat()} >> ${ - matchingAuditJob.actual_rps_dollars - }` - ); + actualMismatch.push({ clm_no: rpsJob.clm_no, rps: rpsJob, audit: matchingAuditJob }); } }); + + yield put(setAuditResults({ missingFromRps, missingFromAudit, expectedMismatch, actualMismatch })); } export function* onCalculateScoreCard() { diff --git a/src/redux/reporting/reporting.selectors.js b/src/redux/reporting/reporting.selectors.js index 7780c2a..505509b 100644 --- a/src/redux/reporting/reporting.selectors.js +++ b/src/redux/reporting/reporting.selectors.js @@ -22,6 +22,10 @@ export const selectReportData = createSelector( [selectReporting], (reporting) => reporting.data ); +export const selectAuditData = createSelector( + [selectReporting], + (reporting) => reporting.audit +); // export const selectWatchedPaths = createSelector( // [selectReporting],