-
-
-
-
+ <>
+
-
-
0 && (
+ clearExcludedIds()}>
+ Clear
+
+ }
+ message={`There are ${excludedJobIds.length} jobs excluded from the totals above.`}
/>
-
-
-
-
+ )}
+ >
);
}
diff --git a/src/redux/reporting/reporting.actions.js b/src/redux/reporting/reporting.actions.js
index b89f82e..200c7a7 100644
--- a/src/redux/reporting/reporting.actions.js
+++ b/src/redux/reporting/reporting.actions.js
@@ -34,5 +34,21 @@ export const setAuditResults = (auditResults) => ({
type: ReportingActionTypes.SET_AUDIT_RESULTS,
payload: auditResults
});
+export const addExcludedId = (id) => ({
+ type: ReportingActionTypes.ADD_EXCLUDED_ID,
+ payload: id
+});
+export const removeExcludedId = (id) => ({
+ type: ReportingActionTypes.REMOVE_EXCLUDED_ID,
+ payload: id
+});
+export const clearExcludedIds = () => ({
+ type: ReportingActionTypes.CLEAR_EXCLUDED_IDS
+});
+
+export const setCachedJobs = (jobs) => ({
+ type: ReportingActionTypes.SET_CACHED_JOBS,
+ payload: jobs
+});
export const setAuditError = (error) => ({ type: ReportingActionTypes.SET_AUDIT_ERROR, payload: error });
diff --git a/src/redux/reporting/reporting.reducer.js b/src/redux/reporting/reporting.reducer.js
index 7593615..609d897 100644
--- a/src/redux/reporting/reporting.reducer.js
+++ b/src/redux/reporting/reporting.reducer.js
@@ -7,7 +7,9 @@ const INITIAL_STATE = {
loading: false,
auditLoading: false,
audit: {},
- auditError: null
+ auditError: null,
+ excludedIds: [],
+ cachedJobs: []
};
const applicationReducer = (state = INITIAL_STATE, action) => {
@@ -37,6 +39,14 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
return { ...state, loading: false, auditLoading: false, auditError: null, audit: action.payload };
case ReportingActionTypes.SET_AUDIT_ERROR:
return { ...state, auditLoading: false, auditError: action.payload };
+ case ReportingActionTypes.ADD_EXCLUDED_ID:
+ return { ...state, excludedIds: [...state.excludedIds, action.payload] };
+ case ReportingActionTypes.REMOVE_EXCLUDED_ID:
+ return { ...state, excludedIds: state.excludedIds.filter((id) => id !== action.payload) };
+ case ReportingActionTypes.CLEAR_EXCLUDED_IDS:
+ return { ...state, excludedIds: [] };
+ case ReportingActionTypes.SET_CACHED_JOBS:
+ return { ...state, cachedJobs: action.payload };
case ReportingActionTypes.TOGGLE_GROUP_VERIFIED:
return {
...state,
diff --git a/src/redux/reporting/reporting.sagas.js b/src/redux/reporting/reporting.sagas.js
index af8eaa6..767594c 100644
--- a/src/redux/reporting/reporting.sagas.js
+++ b/src/redux/reporting/reporting.sagas.js
@@ -12,7 +12,8 @@ import {
setScoreCard,
setReportingError,
setAuditResults,
- setAuditError
+ setAuditError,
+ setCachedJobs
} from "./reporting.actions";
import ReportingApplicationTypes from "./reporting.types";
@@ -21,6 +22,15 @@ const { log, ipcRenderer } = window;
export function* onQueryReportData() {
yield takeLatest(ReportingApplicationTypes.QUERY_REPORTING_DATA, queryReportingData);
}
+export function* onAddExcludedIds() {
+ yield takeLatest(ReportingApplicationTypes.ADD_EXCLUDED_ID, handleCalculateScoreCard);
+}
+export function* onRemoveExcludedId() {
+ yield takeLatest(ReportingApplicationTypes.REMOVE_EXCLUDED_ID, handleCalculateScoreCard);
+}
+export function* onClearExcludedIds() {
+ yield takeLatest(ReportingApplicationTypes.CLEAR_EXCLUDED_IDS, handleCalculateScoreCard);
+}
export function* queryReportingData({ payload: { startDate, endDate } }) {
const result = yield client.query({
query: REPORTING_GET_JOBS,
@@ -33,6 +43,7 @@ export function* queryReportingData({ payload: { startDate, endDate } }) {
log.error("Error fetching report data.", result.errors);
yield put(setReportingData(null));
} else {
+ yield put(setCachedJobs(result.data.jobs));
yield put(calculateScorecard(result.data.jobs));
}
}
@@ -90,15 +101,16 @@ export function* handleCalculateAudit({ payload: claimsArrayFromAudit }) {
export function* onCalculateScoreCard() {
yield takeLatest(ReportingApplicationTypes.CALCULATE_SCORE_CARD, handleCalculateScoreCard);
}
-export function* handleCalculateScoreCard({ payload: jobs }) {
+export function* handleCalculateScoreCard({ payload: queriedJobs }) {
try {
ipcRenderer.send(ipcTypes.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 excludedJobIds = yield select((state) => state.reporting.excludedIds);
+ const cachedJobs = yield select((state) => state.reporting.cachedJobs);
+ let jobs = Array.isArray(queriedJobs) ? queriedJobs : cachedJobs;
//Check to ensure every job has a group.
const jobsWithNoGroup = jobs
.filter((j) => !j.group)
@@ -135,6 +147,7 @@ export function* handleCalculateScoreCard({ payload: jobs }) {
//Get the RPS on a per job basis.
jobs = jobs.map((job) => {
+ const isJobExcludedFromCalculation = excludedJobIds.includes(job.id);
const { actPriceSum, jobRpsDollars } = CalculateJobRpsDollars(job, true);
const { dbPriceSum, jobRpsPc } = CalculateJobRpsPc(job, jobRpsDollars, true);
const jobTarget = GetJobTarget({
@@ -145,28 +158,30 @@ export function* handleCalculateScoreCard({ payload: jobs }) {
v_mileage: job.v_mileage,
job: job
});
- scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add(jobRpsDollars);
const expectedRpsDollars = dbPriceSum.percentage(jobTarget * 100);
- scoreCard.shopRpsExpectedDollars = scoreCard.shopRpsExpectedDollars.add(expectedRpsDollars);
+ if (!isJobExcludedFromCalculation) {
+ scoreCard.shopRpsTotalDollars = scoreCard.shopRpsTotalDollars.add(jobRpsDollars);
+ scoreCard.shopRpsExpectedDollars = scoreCard.shopRpsExpectedDollars.add(expectedRpsDollars);
- scoreCard.allJobsSumDbPrice = scoreCard.allJobsSumDbPrice.add(dbPriceSum);
- scoreCard.allJobsSumActPrice = scoreCard.allJobsSumActPrice.add(actPriceSum);
+ scoreCard.allJobsSumDbPrice = scoreCard.allJobsSumDbPrice.add(dbPriceSum);
+ scoreCard.allJobsSumActPrice = scoreCard.allJobsSumActPrice.add(actPriceSum);
- const deviationPc = Math.round((jobRpsPc - jobTarget) * 1000) / 10;
+ 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
- });
+ 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
+ });
+ }
const jobAlerts = job.joblines
.map((jobline) =>
@@ -213,5 +228,14 @@ export function* handleCalculateScoreCard({ payload: jobs }) {
}
export function* reportingSagas() {
- yield all([call(onQueryReportData), call(onSetReportData), call(onCalculateScoreCard), call(onCalculateAudit)]);
+ yield all([
+ call(onQueryReportData),
+ call(onSetReportData),
+ call(onCalculateScoreCard),
+ call(onCalculateAudit),
+
+ call(onClearExcludedIds),
+ call(onAddExcludedIds),
+ call(onRemoveExcludedId)
+ ]);
}
diff --git a/src/redux/reporting/reporting.selectors.js b/src/redux/reporting/reporting.selectors.js
index 2427308..585e223 100644
--- a/src/redux/reporting/reporting.selectors.js
+++ b/src/redux/reporting/reporting.selectors.js
@@ -10,6 +10,7 @@ export const selectReportData = createSelector([selectReporting], (reporting) =>
export const selectAuditData = createSelector([selectReporting], (reporting) => reporting.audit);
export const selectAuditError = createSelector([selectReporting], (reporting) => reporting.auditError);
export const selectAuditLoading = createSelector([selectReporting], (reporting) => reporting.auditLoading);
+export const selectExcludedIds = createSelector([selectReporting], (reporting) => reporting.excludedIds);
// export const selectWatchedPaths = createSelector(
// [selectReporting],
// (application) => application.watchedPaths
diff --git a/src/redux/reporting/reporting.types.js b/src/redux/reporting/reporting.types.js
index e7b87c4..fa2fc08 100644
--- a/src/redux/reporting/reporting.types.js
+++ b/src/redux/reporting/reporting.types.js
@@ -7,6 +7,10 @@ const ReportingActionTypes = {
TOGGLE_GROUP_VERIFIED: "TOGGLE_GROUP_VERIFIED",
CALCULATE_AUDIT: "CALCULATE_AUDIT",
SET_AUDIT_RESULTS: "SET_AUDIT_RESULTS",
- SET_AUDIT_ERROR: "SET_AUDIT_ERROR"
+ SET_AUDIT_ERROR: "SET_AUDIT_ERROR",
+ ADD_EXCLUDED_ID: "ADD_EXCLUDED_ID",
+ REMOVE_EXCLUDED_ID: "REMOVE_EXCLUDED_ID",
+ CLEAR_EXCLUDED_IDS: "CLEAR_EXCLUDED_IDS",
+ SET_CACHED_JOBS: "SET_CACHED_JOBS"
};
export default ReportingActionTypes;