Add in $0 target for jobs under 20000 KM.

This commit is contained in:
Patrick Fic
2024-08-06 15:21:46 -07:00
parent ee2f982b0b
commit dc94fa0a49
9 changed files with 53 additions and 62 deletions

View File

@@ -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")],
}, },
]; ];

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -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
}); });

View File

@@ -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(

View File

@@ -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);

View File

@@ -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;