Files
imexrps/src/redux/reporting/reporting.sagas.js
2020-11-16 10:48:09 -08:00

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