Add feature wrapper to Audit.
This commit is contained in:
@@ -31,7 +31,7 @@ ipcMain.on(ipcTypes.default.audit.toMain.browseForFile, async (event, { sheetNam
|
||||
clm_no: line[0],
|
||||
close_date: line[1],
|
||||
v_model_yr: line[3],
|
||||
v_make_desc: line[4],
|
||||
v_makedesc: line[4],
|
||||
v_model: line[5],
|
||||
under20kmiles: line[6],
|
||||
pan_total: line[7],
|
||||
|
||||
@@ -29,6 +29,7 @@ select_permissions:
|
||||
columns:
|
||||
- accepted_ins_co
|
||||
- created_at
|
||||
- features
|
||||
- groups
|
||||
- id
|
||||
- ppd_diff_alert
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Could not auto-generate a down migration.
|
||||
-- Please write an appropriate down migration for the SQL below:
|
||||
-- alter table "public"."bodyshops" add column "features" jsonb
|
||||
-- null default jsonb_build_object();
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."bodyshops" add column "features" jsonb
|
||||
null default jsonb_build_object();
|
||||
@@ -7,6 +7,7 @@ import { selectAuditData } from "../../../redux/reporting/reporting.selectors";
|
||||
import { DateFormat } from "../../../util/constants";
|
||||
import dayjs from "../../../util/day";
|
||||
import Dinero from "dinero.js";
|
||||
import { alphaSort, dateSort } from "../../../util/sorters";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
selectAuditData: selectAuditData
|
||||
@@ -18,25 +19,41 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
export function AuditResultsOrganism({ selectAuditData }) {
|
||||
const missingColumns = [
|
||||
{ key: "clm_no", width: "20%", title: "Claim No.", dataIndex: "clm_no" },
|
||||
{
|
||||
key: "clm_no",
|
||||
width: "20%",
|
||||
title: "Claim No.",
|
||||
sorter: (a, b) => alphaSort(a.clm_no, b.clm_no),
|
||||
dataIndex: "clm_no"
|
||||
},
|
||||
{
|
||||
key: "close_date",
|
||||
width: "20%",
|
||||
title: "[RPS] R4P",
|
||||
dataIndex: "close_date",
|
||||
defaultSortOrder: "ascend",
|
||||
sorter: (a, b) => dateSort(a.close_date, b.close_date),
|
||||
render: (text, record) => dayjs(record.close_date).format(DateFormat)
|
||||
},
|
||||
{ key: "v_model_yr", width: "20%", title: "Model Year", dataIndex: "v_model_yr" },
|
||||
{ key: "v_make_desc", width: "20%", title: "Make", dataIndex: "v_make_desc" },
|
||||
{ key: "v_makedesc", width: "20%", title: "Make", dataIndex: "v_makedesc" },
|
||||
{ key: "v_model", width: "20%", title: "Model", dataIndex: "v_model" }
|
||||
];
|
||||
|
||||
const mismatchColumns = [
|
||||
{ key: "clm_no", width: "12%", title: "Claim No.", dataIndex: ["rps", "clm_no"] },
|
||||
{
|
||||
key: "clm_no",
|
||||
width: "12%",
|
||||
title: "Claim No.",
|
||||
sorter: (a, b) => alphaSort(a.rps.clm_no, b.rps.clm_no),
|
||||
dataIndex: ["rps", "clm_no"]
|
||||
},
|
||||
{
|
||||
key: "close_date",
|
||||
title: "[RPS] R4P",
|
||||
dataIndex: "close_date",
|
||||
defaultSortOrder: "ascend",
|
||||
sorter: (a, b) => dateSort(a.rps.close_date, b.rps.close_date),
|
||||
render: (text, record) => dayjs(record.rps.close_date).format(DateFormat)
|
||||
},
|
||||
{
|
||||
@@ -44,10 +61,12 @@ export function AuditResultsOrganism({ selectAuditData }) {
|
||||
width: "12%",
|
||||
title: "[Audit] R4P",
|
||||
dataIndex: "close_date_audit",
|
||||
sorter: (a, b) => dateSort(a.audit.close_date, b.audit.close_date),
|
||||
|
||||
render: (text, record) => dayjs(record.audit.close_date).format(DateFormat)
|
||||
},
|
||||
{ key: "v_model_yr", width: "12%", title: "Model Year", dataIndex: ["audit", "v_model_yr"] },
|
||||
{ key: "v_make_desc", width: "12%", title: "Make", dataIndex: ["audit", "v_make_desc"] },
|
||||
{ key: "v_makedesc", width: "12%", title: "Make", dataIndex: ["audit", "v_makedesc"] },
|
||||
{ key: "v_model", width: "12%", title: "Model", dataIndex: ["audit", "v_model"] },
|
||||
{
|
||||
key: "expected_rps",
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { Alert, Button, Card, Col, DatePicker, Form, Input, Row } from "antd";
|
||||
import React from "react";
|
||||
import ipcTypes from "../../../ipc.types";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import ipcTypes from "../../../ipc.types";
|
||||
import { queryReportingData } from "../../../redux/reporting/reporting.actions";
|
||||
import { selectAuditError } from "../../../redux/reporting/reporting.selectors";
|
||||
import dayjs from "../../../util/day";
|
||||
import AuditResultsOrganism from "../../organisms/audit-results/audit-results.organism";
|
||||
import FeatureWrapper from "../../templates/feature-wrapper";
|
||||
import "./audit.page.styles.scss";
|
||||
import { selectAuditError } from "../../../redux/reporting/reporting.selectors";
|
||||
|
||||
const { ipcRenderer } = window;
|
||||
|
||||
@@ -28,70 +29,81 @@ export function AuditPage({ auditError, queryReportingData }) {
|
||||
});
|
||||
ipcRenderer.send(ipcTypes.audit.toMain.browseForFile, { sheetName });
|
||||
};
|
||||
|
||||
if (auditError) console.log("Error when opening audit file.", auditError);
|
||||
return (
|
||||
<div className="audit-container">
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<Card>
|
||||
<Form onFinish={handleBrowseForFile}>
|
||||
<Form.Item
|
||||
label="Ready for Payment Date Between"
|
||||
name="dateRange"
|
||||
rules={[
|
||||
{ type: "array", required: true },
|
||||
{
|
||||
validator(rule, value) {
|
||||
if (!value || !value.length === 2) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// if (dayjs(value[1]).diff(dayjs(value[0]), "month", true) > 1) {
|
||||
// return Promise.reject("Time period exceeds 1 month. Please select a shorter date range.");
|
||||
// } else {
|
||||
return Promise.resolve();
|
||||
// }
|
||||
}
|
||||
}
|
||||
]}
|
||||
>
|
||||
<DatePicker.RangePicker
|
||||
format="MM/DD/YYYY"
|
||||
ranges={{
|
||||
"2 Months ago": [
|
||||
dayjs().startOf("month").subtract(2, "month"),
|
||||
dayjs().startOf("month").subtract(2, "month").endOf("month")
|
||||
],
|
||||
"Last Month": [
|
||||
dayjs().startOf("month").subtract(1, "month"),
|
||||
dayjs().startOf("month").subtract(1, "month").endOf("month")
|
||||
],
|
||||
"This Month": [dayjs().startOf("month"), dayjs().endOf("month")],
|
||||
"Last Quarter": [
|
||||
dayjs().startOf("quarter").subtract(1, "quarter"),
|
||||
dayjs().startOf("quarter").subtract(1, "day")
|
||||
],
|
||||
"Last 3 Months": [
|
||||
dayjs().startOf("month").subtract(3, "month"),
|
||||
dayjs().startOf("month").subtract(1, "month").endOf("month")
|
||||
]
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="Sheet Name" tooltip="" name="sheetName" initialValue="Shop RPS Claim Detail">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Button htmlType="submit">Select Audit XLS</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</Col>
|
||||
{auditError && (
|
||||
<FeatureWrapper featureName="audit">
|
||||
<div className="audit-container">
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<Alert type="error" banner message={auditError} />
|
||||
<Card>
|
||||
<Form onFinish={handleBrowseForFile}>
|
||||
<Form.Item
|
||||
label="Ready for Payment Date Between"
|
||||
name="dateRange"
|
||||
rules={[
|
||||
{ type: "array", required: true },
|
||||
{
|
||||
validator(rule, value) {
|
||||
if (!value || !value.length === 2) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// if (dayjs(value[1]).diff(dayjs(value[0]), "month", true) > 1) {
|
||||
// return Promise.reject("Time period exceeds 1 month. Please select a shorter date range.");
|
||||
// } else {
|
||||
return Promise.resolve();
|
||||
// }
|
||||
}
|
||||
}
|
||||
]}
|
||||
>
|
||||
<DatePicker.RangePicker
|
||||
format="MM/DD/YYYY"
|
||||
ranges={{
|
||||
"2 Months ago": [
|
||||
dayjs().startOf("month").subtract(2, "month"),
|
||||
dayjs().startOf("month").subtract(2, "month").endOf("month")
|
||||
],
|
||||
"Last Month": [
|
||||
dayjs().startOf("month").subtract(1, "month"),
|
||||
dayjs().startOf("month").subtract(1, "month").endOf("month")
|
||||
],
|
||||
"This Month": [dayjs().startOf("month"), dayjs().endOf("month")],
|
||||
"Last Quarter": [
|
||||
dayjs().startOf("quarter").subtract(1, "quarter"),
|
||||
dayjs().startOf("quarter").subtract(1, "day")
|
||||
],
|
||||
"Last 3 Months": [
|
||||
dayjs().startOf("month").subtract(3, "month"),
|
||||
dayjs().startOf("month").subtract(1, "month").endOf("month")
|
||||
]
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Sheet Name"
|
||||
tooltip="The name of the sheet which contains detailed RPS claim data."
|
||||
name="sheetName"
|
||||
initialValue="Shop RPS Claim Detail"
|
||||
>
|
||||
<Input width="200px" />
|
||||
</Form.Item>
|
||||
<Button htmlType="submit">Select MPI Audit XLS File</Button>
|
||||
</Form>
|
||||
</Card>
|
||||
</Col>
|
||||
)}
|
||||
<AuditResultsOrganism />
|
||||
</Row>
|
||||
</div>
|
||||
{auditError && (
|
||||
<Col span={24}>
|
||||
<Alert
|
||||
type="error"
|
||||
banner
|
||||
message="Error encountered when opening the audit file. Please ensure it is not open in any other programs, and the sheet name is correct."
|
||||
/>
|
||||
</Col>
|
||||
)}
|
||||
<AuditResultsOrganism />
|
||||
</Row>
|
||||
</div>
|
||||
</FeatureWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,7 @@ import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { setSelectedJobId } from "../../../redux/application/application.actions";
|
||||
import {
|
||||
selectDates,
|
||||
selectReportingError,
|
||||
} from "../../../redux/reporting/reporting.selectors";
|
||||
import { selectDates, selectReportingError } from "../../../redux/reporting/reporting.selectors";
|
||||
import ReportingTitleAtom from "../../atoms/reporting-title/reporting-title.atom";
|
||||
import ReportingDatesMolecule from "../../molecules/reporting-dates/reporting-dates.molecule";
|
||||
import ReportingJobsListMolecule from "../../molecules/reporting-jobs-list/reporting-jobs-list.molecule";
|
||||
@@ -17,10 +14,10 @@ import "./reporting.page.styles.scss";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
dates: selectDates,
|
||||
error: selectReportingError,
|
||||
error: selectReportingError
|
||||
});
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
setSelectedJobId: (id) => dispatch(setSelectedJobId(id)),
|
||||
setSelectedJobId: (id) => dispatch(setSelectedJobId(id))
|
||||
});
|
||||
|
||||
export function ReportingPage({ dates, error, setSelectedJobId }) {
|
||||
|
||||
40
src/components/templates/feature-wrapper.jsx
Normal file
40
src/components/templates/feature-wrapper.jsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import dayjs from "../../util/day";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { Alert } from "antd";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop
|
||||
});
|
||||
|
||||
function FeatureWrapper({ bodyshop, featureName, noauth, children, ...restProps }) {
|
||||
if (HasFeatureAccess({ featureName, bodyshop })) return children;
|
||||
|
||||
return (
|
||||
noauth || (
|
||||
<Alert
|
||||
message={
|
||||
"You do not currently have access to this feature. Please reach out to support at support@thinkimex.com or 604-839-3431 to request access."
|
||||
}
|
||||
type="warning"
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function HasFeatureAccess({ featureName, bodyshop }) {
|
||||
return bodyshop?.features?.allAccess || dayjs(bodyshop?.features[featureName]).isAfter(dayjs());
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, null)(FeatureWrapper);
|
||||
|
||||
/*
|
||||
dashboard
|
||||
production-board
|
||||
scoreboard
|
||||
csi
|
||||
tech-console
|
||||
mobile-imaging
|
||||
*/
|
||||
@@ -8,6 +8,7 @@ export const QUERY_BODYSHOP = gql`
|
||||
accepted_ins_co
|
||||
groups
|
||||
ppd_diff_alert
|
||||
features
|
||||
}
|
||||
targets {
|
||||
id
|
||||
@@ -33,6 +34,7 @@ export const UPDATE_SHOP = gql`
|
||||
accepted_ins_co
|
||||
groups
|
||||
ppd_diff_alert
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
export function alphaSort(a, b) {
|
||||
let A;
|
||||
let B;
|
||||
|
||||
A = a ? a.toLowerCase() : "";
|
||||
B = b ? b.toLowerCase() : "";
|
||||
if (A < B)
|
||||
//sort string ascending
|
||||
return -1;
|
||||
if (A > B) return 1;
|
||||
return 0; //default return value (no sorting)
|
||||
return (a ? a.toLowerCase() : "").localeCompare(b ? b.toLowerCase() : "");
|
||||
}
|
||||
|
||||
export function dateSort(a, b) {
|
||||
return new Date(a) - new Date(b);
|
||||
}
|
||||
|
||||
export function statusSort(a, b, statusList) {
|
||||
return statusList.findIndex((x) => x === a) - statusList.findIndex((x) => x === b);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user