Add in $0 target for jobs under 20000 KM.
This commit is contained in:
@@ -8,7 +8,11 @@ const RuleSets = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "V2",
|
title: "V2",
|
||||||
range: [moment("2023-04-01"), moment("2040-01-01")],
|
range: [moment("2023-04-01"), moment("2024-09-01")],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "V3",
|
||||||
|
range: [moment("2024-09-01"), moment("2040-01-01")],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import JobGroupMolecule from "../job-group/job-group.molecule";
|
|||||||
import DeleteJobAtom from "../../atoms/delete-job/delete-job.atom";
|
import DeleteJobAtom from "../../atoms/delete-job/delete-job.atom";
|
||||||
import VehicleGroupAlertAtom from "../../atoms/vehicle-group-alert/vehicle-group-alert.atom";
|
import VehicleGroupAlertAtom from "../../atoms/vehicle-group-alert/vehicle-group-alert.atom";
|
||||||
import { DateFormat } from "../../../util/constants";
|
import { DateFormat } from "../../../util/constants";
|
||||||
import dayjs from '../../../util/day.js';
|
import dayjs from "../../../util/day.js";
|
||||||
import { PageHeader } from "@ant-design/pro-layout";
|
import { PageHeader } from "@ant-design/pro-layout";
|
||||||
|
|
||||||
export default function JobsDetailDescriptionMolecule({ loading, job }) {
|
export default function JobsDetailDescriptionMolecule({ loading, job }) {
|
||||||
@@ -71,6 +71,7 @@ export default function JobsDetailDescriptionMolecule({ loading, job }) {
|
|||||||
<Descriptions.Item label="Loss Date">
|
<Descriptions.Item label="Loss Date">
|
||||||
{job.loss_date ? dayjs(job.loss_date).format(DateFormat) : "No Loss Date"}
|
{job.loss_date ? dayjs(job.loss_date).format(DateFormat) : "No Loss Date"}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="Mileage">{job.v_mileage}</Descriptions.Item>
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,17 +15,17 @@ import "./jobs-detail.organism.styles.scss";
|
|||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
//currentUser: selectCurrentUser
|
//currentUser: selectCurrentUser
|
||||||
selectedJobId: selectSelectedJobId,
|
selectedJobId: selectSelectedJobId
|
||||||
});
|
});
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
setSelectedJobTargetPc: (job) => dispatch(setSelectedJobTargetPc(job)),
|
setSelectedJobTargetPc: (job) => dispatch(setSelectedJobTargetPc(job))
|
||||||
});
|
});
|
||||||
|
|
||||||
export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
|
export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
|
||||||
const { loading, error, data } = useQuery(QUERY_JOB_BY_PK, {
|
const { loading, error, data } = useQuery(QUERY_JOB_BY_PK, {
|
||||||
variables: { jobId: selectedJobId },
|
variables: { jobId: selectedJobId },
|
||||||
skip: !selectedJobId,
|
skip: !selectedJobId
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -34,6 +34,7 @@ export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
|
|||||||
group: data.jobs_by_pk && data.jobs_by_pk.group,
|
group: data.jobs_by_pk && data.jobs_by_pk.group,
|
||||||
v_age: data.jobs_by_pk && data.jobs_by_pk.v_age,
|
v_age: data.jobs_by_pk && data.jobs_by_pk.v_age,
|
||||||
close_date: data.jobs_by_pk && data.jobs_by_pk.close_date,
|
close_date: data.jobs_by_pk && data.jobs_by_pk.close_date,
|
||||||
|
v_mileage: data.jobs_by_pk && data.jobs_by_pk.v_mileage
|
||||||
});
|
});
|
||||||
}, [data, setSelectedJobTargetPc]);
|
}, [data, setSelectedJobTargetPc]);
|
||||||
|
|
||||||
@@ -44,56 +45,34 @@ export function JobsDetailOrganism({ selectedJobId, setSelectedJobTargetPc }) {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Result title="No job selected." />
|
<Result title="No job selected." />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
if (error)
|
if (error) return <ErrorResultAtom title="Error fetching Job details.." errorMessage={JSON.stringify(error)} />;
|
||||||
return (
|
|
||||||
<ErrorResultAtom
|
|
||||||
title="Error fetching Job details.."
|
|
||||||
errorMessage={JSON.stringify(error)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="jobs-detail-container">
|
<div className="jobs-detail-container">
|
||||||
<Card>
|
<Card>
|
||||||
<JobsDetailDescriptionMolecule
|
<JobsDetailDescriptionMolecule loading={loading} job={data ? data.jobs_by_pk : null} />
|
||||||
loading={loading}
|
|
||||||
job={data ? data.jobs_by_pk : null}
|
|
||||||
/>
|
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
<JobsLinesTableMolecule
|
<JobsLinesTableMolecule loading={loading} job={data ? data.jobs_by_pk : {}} />
|
||||||
loading={loading}
|
|
||||||
job={data ? data.jobs_by_pk : {}}
|
|
||||||
/>
|
|
||||||
</Card>
|
</Card>
|
||||||
<Card>
|
<Card>
|
||||||
<JobsTargetsStatsMolecule
|
<JobsTargetsStatsMolecule loading={loading} job={data ? data.jobs_by_pk : null} />
|
||||||
loading={loading}
|
|
||||||
job={data ? data.jobs_by_pk : null}
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-evenly",
|
justifyContent: "space-evenly",
|
||||||
minHeight: "20rem",
|
minHeight: "20rem",
|
||||||
width: "100%",
|
width: "100%"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<JobsPartsGraphAtom
|
<JobsPartsGraphAtom job={data ? data.jobs_by_pk : null} loading={loading} price="db_price" />
|
||||||
job={data ? data.jobs_by_pk : null}
|
<JobsPartsGraphAtom job={data ? data.jobs_by_pk : null} loading={loading} />
|
||||||
loading={loading}
|
|
||||||
price="db_price"
|
|
||||||
/>
|
|
||||||
<JobsPartsGraphAtom
|
|
||||||
job={data ? data.jobs_by_pk : null}
|
|
||||||
loading={loading}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ export const QUERY_JOB_BY_PK = gql`
|
|||||||
close_date
|
close_date
|
||||||
updated_at
|
updated_at
|
||||||
requires_reimport
|
requires_reimport
|
||||||
|
v_mileage
|
||||||
joblines(order_by: { line_no: asc }) {
|
joblines(order_by: { line_no: asc }) {
|
||||||
id
|
id
|
||||||
line_no
|
line_no
|
||||||
@@ -170,6 +171,7 @@ export const UPDATE_JOB = gql`
|
|||||||
group
|
group
|
||||||
group_verified
|
group_verified
|
||||||
requires_reimport
|
requires_reimport
|
||||||
|
v_mileage
|
||||||
joblines(order_by: { line_no: asc }) {
|
joblines(order_by: { line_no: asc }) {
|
||||||
id
|
id
|
||||||
act_price
|
act_price
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export const REPORTING_GET_JOBS = gql`
|
|||||||
v_vin
|
v_vin
|
||||||
v_type
|
v_type
|
||||||
requires_reimport
|
requires_reimport
|
||||||
|
v_mileage
|
||||||
joblines {
|
joblines {
|
||||||
act_price
|
act_price
|
||||||
db_price
|
db_price
|
||||||
|
|||||||
@@ -2,58 +2,58 @@ import ApplicationActionTypes from "./application.types";
|
|||||||
|
|
||||||
export const setWatchedPaths = (watchedPaths) => ({
|
export const setWatchedPaths = (watchedPaths) => ({
|
||||||
type: ApplicationActionTypes.SET_WATCHED_PATHS,
|
type: ApplicationActionTypes.SET_WATCHED_PATHS,
|
||||||
payload: watchedPaths,
|
payload: watchedPaths
|
||||||
});
|
});
|
||||||
|
|
||||||
export const addWatchedPath = (path) => ({
|
export const addWatchedPath = (path) => ({
|
||||||
type: ApplicationActionTypes.ADD_WATCHED_PATH,
|
type: ApplicationActionTypes.ADD_WATCHED_PATH,
|
||||||
payload: path,
|
payload: path
|
||||||
});
|
});
|
||||||
|
|
||||||
export const removeWatchedPath = (path) => ({
|
export const removeWatchedPath = (path) => ({
|
||||||
type: ApplicationActionTypes.REMOVE_WATCHED_PATH,
|
type: ApplicationActionTypes.REMOVE_WATCHED_PATH,
|
||||||
payload: path,
|
payload: path
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setWatcherStatus = (status) => ({
|
export const setWatcherStatus = (status) => ({
|
||||||
type: ApplicationActionTypes.SET_WATCHER_STATUS,
|
type: ApplicationActionTypes.SET_WATCHER_STATUS,
|
||||||
payload: status,
|
payload: status
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setWatcherError = (error) => ({
|
export const setWatcherError = (error) => ({
|
||||||
type: ApplicationActionTypes.SET_WATCHER_ERROR,
|
type: ApplicationActionTypes.SET_WATCHER_ERROR,
|
||||||
payload: error,
|
payload: error
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setSelectedJobId = (jobId) => ({
|
export const setSelectedJobId = (jobId) => ({
|
||||||
type: ApplicationActionTypes.SET_SELECTED_JOB_ID,
|
type: ApplicationActionTypes.SET_SELECTED_JOB_ID,
|
||||||
payload: jobId,
|
payload: jobId
|
||||||
});
|
});
|
||||||
export const setSelectedJobTargetPc = ({ group, v_age,close_date }) => ({
|
export const setSelectedJobTargetPc = ({ group, v_age, close_date, v_mileage }) => ({
|
||||||
type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC,
|
type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC,
|
||||||
payload: { group, v_age, close_date },
|
payload: { group, v_age, close_date, v_mileage }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setSelectedJobTargetPcSuccess = (pct) => ({
|
export const setSelectedJobTargetPcSuccess = (pct) => ({
|
||||||
type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC_SUCCESS,
|
type: ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC_SUCCESS,
|
||||||
payload: pct,
|
payload: pct
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setSettings = (settingsObj) => ({
|
export const setSettings = (settingsObj) => ({
|
||||||
type: ApplicationActionTypes.SET_SETTINGS,
|
type: ApplicationActionTypes.SET_SETTINGS,
|
||||||
payload: settingsObj,
|
payload: settingsObj
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setUpdateAvailable = (available) => ({
|
export const setUpdateAvailable = (available) => ({
|
||||||
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
||||||
payload: available,
|
payload: available
|
||||||
});
|
});
|
||||||
export const setUpdateProgress = (progress) => ({
|
export const setUpdateProgress = (progress) => ({
|
||||||
type: ApplicationActionTypes.SET_UPDATE_PROGRESS,
|
type: ApplicationActionTypes.SET_UPDATE_PROGRESS,
|
||||||
payload: progress,
|
payload: progress
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setReleaseNotes = (releaseNotes) => ({
|
export const setReleaseNotes = (releaseNotes) => ({
|
||||||
type: ApplicationActionTypes.SET_RELEASE_NOTES,
|
type: ApplicationActionTypes.SET_RELEASE_NOTES,
|
||||||
payload: releaseNotes,
|
payload: releaseNotes
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,16 +4,13 @@ import { setSelectedJobTargetPcSuccess } from "./application.actions";
|
|||||||
import ApplicationActionTypes from "./application.types";
|
import ApplicationActionTypes from "./application.types";
|
||||||
|
|
||||||
export function* onSetTargetPc() {
|
export function* onSetTargetPc() {
|
||||||
yield takeLatest(
|
yield takeLatest(ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC, CalculateTarget);
|
||||||
ApplicationActionTypes.SET_SELECTED_JOB_TARGET_PC,
|
|
||||||
CalculateTarget
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
export function* CalculateTarget({ payload }) {
|
export function* CalculateTarget({ payload }) {
|
||||||
const { group, v_age, close_date } = payload;
|
const { group, v_age, close_date, v_mileage } = payload;
|
||||||
const targets = yield select((state) => state.user.bodyshop.targets);
|
const targets = yield select((state) => state.user.bodyshop.targets);
|
||||||
|
|
||||||
yield put(setSelectedJobTargetPcSuccess(GetJobTarget({group, v_age, targets, close_date})));
|
yield put(setSelectedJobTargetPcSuccess(GetJobTarget({ group, v_age, targets, close_date, v_mileage })));
|
||||||
// const targetsForGroup = targets.filter((t) => t.group === group);
|
// const targetsForGroup = targets.filter((t) => t.group === group);
|
||||||
// if (!targetsForGroup) return 0;
|
// if (!targetsForGroup) return 0;
|
||||||
// const targetPc = targetsForGroup.filter(
|
// const targetPc = targetsForGroup.filter(
|
||||||
|
|||||||
@@ -134,7 +134,13 @@ export function* handleCalculateScoreCard({ payload: jobs }) {
|
|||||||
jobs = jobs.map((job) => {
|
jobs = jobs.map((job) => {
|
||||||
const { actPriceSum, jobRpsDollars } = CalculateJobRpsDollars(job, true);
|
const { actPriceSum, jobRpsDollars } = CalculateJobRpsDollars(job, true);
|
||||||
const { dbPriceSum, jobRpsPc } = CalculateJobRpsPc(job, jobRpsDollars, true);
|
const { dbPriceSum, jobRpsPc } = CalculateJobRpsPc(job, jobRpsDollars, true);
|
||||||
const jobTarget = GetJobTarget({ group: job.group, v_age: job.v_age, targets, close_date: job.close_date });
|
const jobTarget = GetJobTarget({
|
||||||
|
group: job.group,
|
||||||
|
v_age: job.v_age,
|
||||||
|
targets,
|
||||||
|
close_date: job.close_date,
|
||||||
|
v_mileage: job.v_mileage
|
||||||
|
});
|
||||||
scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add(jobRpsDollars);
|
scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add(jobRpsDollars);
|
||||||
const expectedRpsDollars = dbPriceSum.percentage(jobTarget * 100);
|
const expectedRpsDollars = dbPriceSum.percentage(jobTarget * 100);
|
||||||
scoreCard.shopRpsExpectedDollars = scoreCard.shopRpsExpectedDollars.add(expectedRpsDollars);
|
scoreCard.shopRpsExpectedDollars = scoreCard.shopRpsExpectedDollars.add(expectedRpsDollars);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { store } from "../redux/store";
|
import { store } from "../redux/store";
|
||||||
import { WhichRulesetToApply } from "./constants";
|
import { WhichRulesetToApply } from "./constants";
|
||||||
|
|
||||||
export default function GetJobTarget({ group, v_age, targets, close_date }) {
|
export default function GetJobTarget({ group, v_age, targets, close_date, v_mileage }) {
|
||||||
// //Old Validation
|
// //Old Validation
|
||||||
// const targetsForGroup = targets.filter((t) => t.group === group);
|
// const targetsForGroup = targets.filter((t) => t.group === group);
|
||||||
// console.log(
|
// console.log(
|
||||||
@@ -20,17 +20,18 @@ export default function GetJobTarget({ group, v_age, targets, close_date }) {
|
|||||||
// console.log("Result:", 1);
|
// console.log("Result:", 1);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
//V3 Check - If vehicle is less than 20,000KM, there is NO TARGET.
|
||||||
|
if (v_mileage && v_mileage <= 20000) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//V2 Check
|
//V2 Check
|
||||||
const newTargets = store.getState().user.targets;
|
const newTargets = store.getState().user.targets;
|
||||||
const rulesToApply = WhichRulesetToApply(close_date);
|
const rulesToApply = WhichRulesetToApply(close_date);
|
||||||
const newTargetsForGroup = newTargets.filter(
|
const newTargetsForGroup = newTargets.filter((t) => t.name === rulesToApply && t.group === group);
|
||||||
(t) => t.name === rulesToApply && t.group === group
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!newTargetsForGroup) return 0;
|
if (!newTargetsForGroup) return 0;
|
||||||
const newTargetPc = newTargetsForGroup.filter(
|
const newTargetPc = newTargetsForGroup.filter((t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true));
|
||||||
(t) => t.ageGte <= v_age && (t.ageLt ? t.ageLt > v_age : true)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (newTargetPc.length === 0) return 1;
|
if (newTargetPc.length === 0) return 1;
|
||||||
else if (newTargetPc.length === 1) return newTargetPc[0].target;
|
else if (newTargetPc.length === 1) return newTargetPc[0].target;
|
||||||
|
|||||||
Reference in New Issue
Block a user