165 lines
4.8 KiB
JavaScript
165 lines
4.8 KiB
JavaScript
import Dinero from "dinero.js";
|
|
import _ from "lodash";
|
|
import { all, call, put, select, takeLatest } from "redux-saga/effects";
|
|
import client from "../../graphql/GraphQLClient";
|
|
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,
|
|
} from "./reporting.actions";
|
|
import ReportingApplicationTypes from "./reporting.types";
|
|
|
|
const { log, ipcRenderer } = window;
|
|
|
|
export function* onQueryReportData() {
|
|
yield takeLatest(
|
|
ReportingApplicationTypes.QUERY_REPORTING_DATA,
|
|
queryReportingData
|
|
);
|
|
}
|
|
export function* queryReportingData({ payload: { startDate, endDate } }) {
|
|
const result = yield client.query({
|
|
query: REPORTING_GET_JOBS,
|
|
variables: { startDate, endDate },
|
|
});
|
|
if (result.errors) {
|
|
log.error("Error fetching report data.", result.errors);
|
|
yield put(setReportingData(null));
|
|
} else {
|
|
yield put(calculateScorecard(result.data.jobs));
|
|
}
|
|
}
|
|
|
|
export function* onSetReportData() {
|
|
yield takeLatest(
|
|
ReportingApplicationTypes.SET_REPORTING_DATA,
|
|
handleSetReportData
|
|
);
|
|
}
|
|
export function* handleSetReportData({ payload: jobs }) {
|
|
// yield put(calculateScorecard(jobs));
|
|
}
|
|
|
|
export function* onCalculateScoreCard() {
|
|
yield takeLatest(
|
|
ReportingApplicationTypes.CALCULATE_SCORE_CARD,
|
|
handleCalculateScoreCard
|
|
);
|
|
}
|
|
export function* handleCalculateScoreCard({ payload: jobs }) {
|
|
try {
|
|
ipcRenderer.send(ipcTypes.default.app.toMain.track, {
|
|
event: "CALCULATE_SCORECARD",
|
|
});
|
|
|
|
const targets = yield select((state) => state.user.bodyshop.targets);
|
|
const groups = yield select((state) => state.user.bodyshop.groups);
|
|
|
|
const scoreCard = {
|
|
shopRpsTotalDollars: Dinero(),
|
|
shopRpsExpectedDollars: Dinero(),
|
|
varianceDollars: null,
|
|
variancePc: 0,
|
|
allJobsSumDbPrice: Dinero(),
|
|
allJobsSumActPrice: Dinero(),
|
|
currentRpsPc: 0,
|
|
targetRpsPc: 0,
|
|
scatterChart: _.sortBy(
|
|
groups,
|
|
[(group) => group.toLowerCase()],
|
|
["desc"]
|
|
).reduce((acc, val) => {
|
|
return { ...acc, [val]: [] };
|
|
}, {}),
|
|
};
|
|
|
|
//Get the RPS on a per job basis.
|
|
jobs = jobs.map((job) => {
|
|
const { actPriceSum, jobRpsDollars } = CalculateJobRpsDollars(job, true);
|
|
const { dbPriceSum, jobRpsPc } = CalculateJobRpsPc(
|
|
job,
|
|
jobRpsDollars,
|
|
true
|
|
);
|
|
const jobTarget = GetJobTarget(job.group, job.v_age, targets);
|
|
scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add(
|
|
jobRpsDollars
|
|
);
|
|
const expectedRpsDollars = dbPriceSum.percentage(jobTarget * 100);
|
|
scoreCard.shopRpsExpectedDollars = scoreCard.shopRpsExpectedDollars.add(
|
|
expectedRpsDollars
|
|
);
|
|
|
|
scoreCard.allJobsSumDbPrice = scoreCard.allJobsSumDbPrice.add(dbPriceSum);
|
|
scoreCard.allJobsSumActPrice = scoreCard.allJobsSumActPrice.add(
|
|
actPriceSum
|
|
);
|
|
|
|
const deviationPc = Math.round((jobRpsPc - jobTarget) * 1000) / 10;
|
|
|
|
scoreCard.scatterChart[job.group].push({
|
|
deviationPc: isNaN(deviationPc) ? -100 : deviationPc,
|
|
deviationDollars: (
|
|
jobRpsDollars.subtract(expectedRpsDollars).getAmount() / 100
|
|
).toFixed(2),
|
|
age: job.v_age,
|
|
dbPriceSum,
|
|
dbPriceSumAmt: dbPriceSum.getAmount() / 100,
|
|
id: job.id,
|
|
owner: `${job.ownr_fn} ${job.ownr_ln}`,
|
|
vehicle: `${job.v_model_yr} ${job.v_makedesc} ${job.v_model} (${job.v_type}) - ${job.group}`,
|
|
clm_no: job.clm_no,
|
|
jobRpsDollars,
|
|
jobRpsPc: isNaN(jobRpsPc) ? -1 : jobRpsPc,
|
|
});
|
|
|
|
//sum db price * percentage expected.
|
|
return {
|
|
...job,
|
|
actPriceSum,
|
|
jobRpsDollars,
|
|
dbPriceSum,
|
|
jobRpsPc,
|
|
jobTarget,
|
|
expectedRpsDollars,
|
|
};
|
|
});
|
|
|
|
scoreCard.varianceDollars = scoreCard.shopRpsTotalDollars.subtract(
|
|
scoreCard.shopRpsExpectedDollars
|
|
);
|
|
|
|
scoreCard.currentRpsPc =
|
|
scoreCard.shopRpsTotalDollars.getAmount() /
|
|
scoreCard.allJobsSumDbPrice.getAmount();
|
|
scoreCard.targetRpsPc =
|
|
scoreCard.shopRpsExpectedDollars.getAmount() /
|
|
scoreCard.allJobsSumDbPrice.getAmount();
|
|
|
|
scoreCard.variancePc = scoreCard.currentRpsPc - scoreCard.targetRpsPc;
|
|
//Set the data.
|
|
yield put(setScoreCard(scoreCard));
|
|
yield put(setReportingData(jobs));
|
|
} catch (error) {
|
|
ipcRenderer.send(ipcTypes.default.app.toMain.track, {
|
|
event: "CALCULATE_SCORE_CARD_ERROR",
|
|
error: error,
|
|
});
|
|
}
|
|
}
|
|
|
|
export function* reportingSagas() {
|
|
yield all([
|
|
call(onQueryReportData),
|
|
call(onSetReportData),
|
|
call(onCalculateScoreCard),
|
|
]);
|
|
}
|