import moment from "moment"; import { all, call, put, select, takeLatest } from "redux-saga/effects"; import { QUERY_SCHEDULE_LOAD_DATA } from "../../graphql/appointments.queries"; import { INSERT_AUDIT_TRAIL } from "../../graphql/audit_trail.queries"; import client from "../../utils/GraphQLClient"; import { CalculateLoad, CheckJobBucket } from "../../utils/SSSUtils"; import { scheduleLoadFailure, scheduleLoadSuccess, } from "./application.actions"; import ApplicationActionTypes from "./application.types"; export function* onCalculateScheduleLoad() { yield takeLatest( ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD, calculateScheduleLoad ); } export function* calculateScheduleLoad({ payload: end }) { //REMINDER: Moment.js is not immutable. Today WILL change when adjusted. const today = moment().startOf("day"); const state = yield select(); const buckets = state.user.bodyshop.ssbuckets; try { const result = yield client.query({ query: QUERY_SCHEDULE_LOAD_DATA, variables: { start: today, end: end, }, fetchPolicy: "network-only", }); const { prodJobs, arrJobs, compJobs } = result.data; const load = { productionTotal: {}, }; //Set the current load. buckets.forEach((bucket) => { load.productionTotal[bucket.id] = { count: 0, label: bucket.label }; }); prodJobs.forEach((item) => { //Add all of the jobs currently in production to the buckets so that we have a starting point. const bucketId = CheckJobBucket(buckets, item); if (bucketId) { load.productionTotal[bucketId].count = load.productionTotal[bucketId].count + 1; } else { console.log("Uh oh, this job doesn't fit in a bucket!", item); } }); arrJobs.forEach((item) => { const itemDate = moment(item.scheduled_in).format("yyyy-MM-DD"); if (!!load[itemDate]) { load[itemDate].hoursIn = (load[itemDate].hoursIn || 0) + item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs; load[itemDate].jobsIn.push(item); } else { load[itemDate] = { jobsIn: [item], jobsOut: [], hoursIn: item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs, }; } }); compJobs.forEach((item) => { const itemDate = moment(item.scheduled_completion).format("yyyy-MM-DD"); if (!!load[itemDate]) { load[itemDate].hoursOut = (load[itemDate].hoursOut || 0) + item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs; load[itemDate].jobsOut.push(item); } else { load[itemDate] = { jobsOut: [item], hoursOut: item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs, }; } }); //Propagate the expected load to each day. const range = Math.round(moment.duration(end.diff(today)).asDays()); for (var day = 0; day < range; day++) { const current = moment(today).add(day, "days").format("yyyy-MM-DD"); const prev = moment(today) .add(day - 1, "days") .format("yyyy-MM-DD"); if (!!!load[current]) { load[current] = {}; } if (day === 0) { //Starting on day 1. The load is current. load[current].expectedLoad = CalculateLoad( load.productionTotal, buckets, load[current].jobsIn || [], load[current].jobsOut || [] ); } else { load[current].expectedLoad = CalculateLoad( load[prev].expectedLoad, buckets, load[current].jobsIn || [], load[current].jobsOut || [] ); } } yield put(scheduleLoadSuccess(load)); } catch (error) { //console.log("Error in sendEmailFailure saga.", error.message); console.log("error", error); yield put(scheduleLoadFailure(error)); } } export function* onInsertAuditTrail() { yield takeLatest( ApplicationActionTypes.INSERT_AUDIT_TRAIL, insertAuditTrailSaga ); } export function* insertAuditTrailSaga({ payload: { jobid, billid, operation }, }) { const state = yield select(); const bodyshop = state.user.bodyshop; const currentUser = state.user.currentUser; console.log( "Inserting audit trail for", bodyshop.shopname, currentUser.email, jobid, billid, operation ); const variables = { auditObj: { bodyshopid: bodyshop.id, jobid, billid, operation, useremail: currentUser.email, }, }; yield client.mutate({ mutation: INSERT_AUDIT_TRAIL, variables, update(cache, { data }) { cache.modify({ fields: { audit_trail(existingAuditTrail, { readField }) { const newAuditTrail = cache.writeQuery({ data: data.insert_audit_trail_one, query: INSERT_AUDIT_TRAIL, variables, }); return [...existingAuditTrail, newAuditTrail]; }, }, }); }, }); } export function* applicationSagas() { yield all([call(onCalculateScheduleLoad), call(onInsertAuditTrail)]); }