diff --git a/electron/decoder/decoder.js b/electron/decoder/decoder.js
index c4f053a..209645e 100644
--- a/electron/decoder/decoder.js
+++ b/electron/decoder/decoder.js
@@ -31,6 +31,10 @@ async function DecodeEstimate(filePath) {
returnValue = {
ERROR: `Insurance Company Name is not valid for RPS. (${job.INS_CO_NM})`,
};
+ } else if (!job.clm_no) {
+ returnValue = {
+ ERROR: `An unique claim number must be set for all jobs sent to RPS.`,
+ };
} else {
returnValue = _.transform(job, function (result, val, key) {
result[key.toLowerCase()] = val;
diff --git a/src/components/atoms/part-type-converter/part-type-converter.atom.jsx b/src/components/atoms/part-type-converter/part-type-converter.atom.jsx
index 95fe49b..624027a 100644
--- a/src/components/atoms/part-type-converter/part-type-converter.atom.jsx
+++ b/src/components/atoms/part-type-converter/part-type-converter.atom.jsx
@@ -1,9 +1,9 @@
export default (part_type) => {
switch (part_type) {
case "PAA":
- return "Aftermarket";
+ return "A/M";
case "PAE":
- return "Existing";
+ return "Exist.";
case "PAN":
return "OEM";
case "PAL":
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
index 7d9655b..d5c7628 100644
--- 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
@@ -1,40 +1,22 @@
-import React, { useMemo } from "react";
+import { AlertFilled } from "@ant-design/icons";
+import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
-import { selectBodyshop } from "../../../redux/user/user.selectors";
+import { selectSelectedJobTargetPc } from "../../../redux/application/application.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))
+ selectedJobTargetPc: selectSelectedJobTargetPc,
});
export function PriceDiffPcFormatterAtom({
- bodyshop,
price_diff_pc,
- group,
- v_age,
+ selectedJobTargetPc,
}) {
- const metTarget = useMemo(() => {
- const targetsForGroup = bodyshop.targets.filter((t) => t.group === 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 (
selectedJobTargetPc ? "green" : "red",
display: "flex",
alignItems: "center",
}}
@@ -46,7 +28,4 @@ export function PriceDiffPcFormatterAtom({
);
}
-export default connect(
- mapStateToProps,
- mapDispatchToProps
-)(PriceDiffPcFormatterAtom);
+export default connect(mapStateToProps, null)(PriceDiffPcFormatterAtom);
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
deleted file mode 100644
index 1bf467e..0000000
--- a/src/components/atoms/target-price-diff/target-price-diff-pc.atom.jsx
+++ /dev/null
@@ -1,39 +0,0 @@
-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.filter((t) => t.group === 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-targets-stats/jobs-targets-stats.molecule.jsx b/src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx
index cd92bd9..b5dc058 100644
--- a/src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx
+++ b/src/components/molecules/jobs-targets-stats/jobs-targets-stats.molecule.jsx
@@ -1,10 +1,27 @@
import { Skeleton, Statistic } from "antd";
import Dinero from "dinero.js";
import React, { useMemo } from "react";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { selectSelectedJobTargetPc } from "../../../redux/application/application.selectors";
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
-import TargetPriceDiffPcAtom from "../../atoms/target-price-diff/target-price-diff-pc.atom";
-export default function JobsTargetsStatsMolecule({ loading, job }) {
+const mapStateToProps = createStructuredSelector({
+ selectedJobTargetPc: selectSelectedJobTargetPc,
+});
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(JobsTargetsStatsMolecule);
+
+export function JobsTargetsStatsMolecule({
+ loading,
+ job,
+ selectedJobTargetPc,
+}) {
const currentRpsDollars = useMemo(() => {
if (!job) {
return 0;
@@ -44,8 +61,20 @@ export default function JobsTargetsStatsMolecule({ loading, job }) {
marginBottom: "1rem",
}}
>
-
-
+
+ currentRpsPc ? "tomato" : "seagreen",
+ }}
+ value={currentRpsPc}
+ suffix="%"
+ />
);
diff --git a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx
index dbf01f7..e05f725 100644
--- a/src/components/organisms/jobs-detail/jobs-detail.organism.jsx
+++ b/src/components/organisms/jobs-detail/jobs-detail.organism.jsx
@@ -1,9 +1,10 @@
import { useQuery } from "@apollo/client";
import { Result } from "antd";
-import React from "react";
+import React, { useEffect } from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { QUERY_JOB_BY_PK } from "../../../graphql/jobs.queries";
+import { setSelectedJobTargetPc } from "../../../redux/application/application.actions";
import { selectSelectedJobId } from "../../../redux/application/application.selectors";
import ErrorResultAtom from "../../atoms/error-result/error-result.atom";
import JobsPartsGraphAtom from "../../atoms/jobs-parts-graph/jobs-parts-graph.atom";
@@ -18,14 +19,23 @@ const mapStateToProps = createStructuredSelector({
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
+ setSelectedJobTargetPc: (job) => dispatch(setSelectedJobTargetPc(job)),
});
-export function JobsDetailOrganism({ selectedJobId }) {
+export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
const { loading, error, data } = useQuery(QUERY_JOB_BY_PK, {
variables: { jobId: selectedJobId },
skip: !selectedJobId,
});
+ useEffect(() => {
+ if (data)
+ setSelectedJobTargetPc({
+ group: data.jobs_by_pk.group,
+ v_age: data.jobs_by_pk.v_age,
+ });
+ }, [data, setSelectedJobTargetPc]);
+
if (!selectedJobId) return ;
if (error)
return (
diff --git a/src/redux/application/application.actions.js b/src/redux/application/application.actions.js
index a5f9bfa..6eb245d 100644
--- a/src/redux/application/application.actions.js
+++ b/src/redux/application/application.actions.js
@@ -29,3 +29,12 @@ export const setSelectedJobId = (jobId) => ({
type: ApplicationActionTypes.SET_SELECTED_JOB_ID,
payload: jobId,
});
+export const setSelectedJobTargetPc = ({ group, v_age }) => ({
+ type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC,
+ payload: { group, v_age },
+});
+
+export const setSelectedJobTargetPcSuccess = (pct) => ({
+ type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC_SUCCESS,
+ payload: pct,
+});
diff --git a/src/redux/application/application.reducer.js b/src/redux/application/application.reducer.js
index c29a546..2e25874 100644
--- a/src/redux/application/application.reducer.js
+++ b/src/redux/application/application.reducer.js
@@ -4,6 +4,7 @@ const INITIAL_STATE = {
watchedPaths: [],
watcherError: null,
selectedJobId: null,
+ selectedJobTargetPc: 100,
};
const applicationReducer = (state = INITIAL_STATE, action) => {
@@ -33,6 +34,11 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
...state,
watcherError: action.payload,
};
+ case ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC_SUCCESS:
+ return {
+ ...state,
+ selectedJobTargetPc: action.payload,
+ };
case ApplicationActionTypes.SET_SELECTED_JOB_ID:
return { ...state, selectedJobId: action.payload };
default:
diff --git a/src/redux/application/application.sagas.js b/src/redux/application/application.sagas.js
index 4d19439..38fbe52 100644
--- a/src/redux/application/application.sagas.js
+++ b/src/redux/application/application.sagas.js
@@ -1,13 +1,30 @@
-//import { all, call, takeLatest } from "redux-saga/effects";
-//import ApplicationActionTypes from "./application.types";
+import { all, call, takeLatest, select, put } from "redux-saga/effects";
+import { setSelectedJobTargetPcSuccess } from "./application.actions";
+import ApplicationActionTypes from "./application.types";
-// export function* onJoinRoom() {
-// yield takeLatest(ApplicationActionTypes.JOIN_ROOM, joinRoom);
-// }
-// export function* joinRoom({ payload: roomId }) {
-// // console.log("function*joinRoom -> roomId", roomId);
-// }
+export function* onSetTargetPc() {
+ yield takeLatest(
+ ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC,
+ CalculateTarget
+ );
+}
+export function* CalculateTarget({ payload }) {
+ const { group, v_age } = payload;
+ const targets = yield select((state) => state.user.bodyshop.targets);
+
+ const targetsForGroup = targets.filter((t) => t.group === 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) yield put(setSelectedJobTargetPcSuccess(100));
+ else if (targetPc.length === 1)
+ yield put(setSelectedJobTargetPcSuccess(targetPc[0].target));
+ else {
+ yield put(setSelectedJobTargetPcSuccess(100));
+ }
+}
export function* applicationSagas() {
- //yield all([call(onJoinRoom)]);
+ yield all([call(onSetTargetPc)]);
}
diff --git a/src/redux/application/application.selectors.js b/src/redux/application/application.selectors.js
index 8fcd74e..db993f7 100644
--- a/src/redux/application/application.selectors.js
+++ b/src/redux/application/application.selectors.js
@@ -16,7 +16,13 @@ export const selectWatcherError = createSelector(
[selectApplication],
(application) => application.watcherError
);
+
export const selectSelectedJobId = createSelector(
[selectApplication],
(application) => application.selectedJobId
);
+
+export const selectSelectedJobTargetPc = createSelector(
+ [selectApplication],
+ (application) => application.selectedJobTargetPc
+);
diff --git a/src/redux/application/application.types.js b/src/redux/application/application.types.js
index 72b30fc..bac9945 100644
--- a/src/redux/application/application.types.js
+++ b/src/redux/application/application.types.js
@@ -5,5 +5,7 @@ const ApplicationActionTypes = {
SET_WATCHER_STATUS: "SET_WATCHER_STATUS",
SET_WATCHER_ERROR: "SET_WATCHER_ERROR",
SET_SELECTED_JOB_ID: "SET_SELECTED_JOB_ID",
+ SET_SELECTED_JOB_TARGET_PC: "SET_SELECTED_JOB_TARGET_PC",
+ SET_SELECTED_JOB_TARGET_PC_SUCCESS: "SET_SELECTED_JOB_TARGET_PC_SUCCESS",
};
export default ApplicationActionTypes;