Reformat all project files to use the prettier config file.
This commit is contained in:
@@ -1,77 +1,77 @@
|
||||
import ApplicationActionTypes from "./application.types";
|
||||
|
||||
export const startLoading = () => ({
|
||||
type: ApplicationActionTypes.START_LOADING,
|
||||
type: ApplicationActionTypes.START_LOADING
|
||||
});
|
||||
|
||||
export const endLoading = (options) => ({
|
||||
type: ApplicationActionTypes.END_LOADING,
|
||||
payload: options,
|
||||
type: ApplicationActionTypes.END_LOADING,
|
||||
payload: options
|
||||
});
|
||||
|
||||
export const setBreadcrumbs = (breadcrumbs) => ({
|
||||
type: ApplicationActionTypes.SET_BREAD_CRUMBS,
|
||||
payload: breadcrumbs,
|
||||
type: ApplicationActionTypes.SET_BREAD_CRUMBS,
|
||||
payload: breadcrumbs
|
||||
});
|
||||
|
||||
export const calculateScheduleLoad = (rangeEnd) => ({
|
||||
type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD,
|
||||
payload: rangeEnd,
|
||||
type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD,
|
||||
payload: rangeEnd
|
||||
});
|
||||
|
||||
export const scheduleLoadSuccess = (load) => ({
|
||||
type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_SUCCESS,
|
||||
payload: load,
|
||||
type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_SUCCESS,
|
||||
payload: load
|
||||
});
|
||||
|
||||
export const scheduleLoadFailure = (error) => ({
|
||||
type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_FAILURE,
|
||||
payload: error,
|
||||
type: ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_FAILURE,
|
||||
payload: error
|
||||
});
|
||||
|
||||
export const addRecentItem = (item) => ({
|
||||
type: ApplicationActionTypes.ADD_RECENT_ITEM,
|
||||
payload: item,
|
||||
type: ApplicationActionTypes.ADD_RECENT_ITEM,
|
||||
payload: item
|
||||
});
|
||||
|
||||
export const setSelectedHeader = (key) => ({
|
||||
type: ApplicationActionTypes.SET_SELECTED_HEADER,
|
||||
payload: key,
|
||||
type: ApplicationActionTypes.SET_SELECTED_HEADER,
|
||||
payload: key
|
||||
});
|
||||
|
||||
export const setJobReadOnly = (bool) => ({
|
||||
type: ApplicationActionTypes.SET_JOB_READONLY,
|
||||
payload: bool,
|
||||
type: ApplicationActionTypes.SET_JOB_READONLY,
|
||||
payload: bool
|
||||
});
|
||||
|
||||
export const setPartnerVersion = (version) => ({
|
||||
type: ApplicationActionTypes.SET_PARTNER_VERSION,
|
||||
payload: version,
|
||||
type: ApplicationActionTypes.SET_PARTNER_VERSION,
|
||||
payload: version
|
||||
});
|
||||
|
||||
export const setOnline = (isOnline) => ({
|
||||
type: ApplicationActionTypes.SET_ONLINE_STATUS,
|
||||
payload: isOnline,
|
||||
type: ApplicationActionTypes.SET_ONLINE_STATUS,
|
||||
payload: isOnline
|
||||
});
|
||||
|
||||
export const insertAuditTrail = ({jobid, billid, operation, type}) => ({
|
||||
type: ApplicationActionTypes.INSERT_AUDIT_TRAIL,
|
||||
payload: {jobid, billid, operation, type },
|
||||
export const insertAuditTrail = ({ jobid, billid, operation, type }) => ({
|
||||
type: ApplicationActionTypes.INSERT_AUDIT_TRAIL,
|
||||
payload: { jobid, billid, operation, type }
|
||||
});
|
||||
export const setProblemJobs = (problemJobs) => ({
|
||||
type: ApplicationActionTypes.SET_PROBLEM_JOBS,
|
||||
payload: problemJobs,
|
||||
type: ApplicationActionTypes.SET_PROBLEM_JOBS,
|
||||
payload: problemJobs
|
||||
});
|
||||
|
||||
export const setUpdateAvailable = (isUpdateAvailable) => ({
|
||||
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
||||
payload: isUpdateAvailable,
|
||||
type: ApplicationActionTypes.SET_UPDATE_AVAILABLE,
|
||||
payload: isUpdateAvailable
|
||||
});
|
||||
export const setJoyRideSteps = (steps) => ({
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_STEPS,
|
||||
payload: steps,
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_STEPS,
|
||||
payload: steps
|
||||
});
|
||||
export const setJoyRideFinished = () => ({
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_FINISHED,
|
||||
//payload: isUpdateAvailable,
|
||||
type: ApplicationActionTypes.SET_JOYRIDE_FINISHED
|
||||
//payload: isUpdateAvailable,
|
||||
});
|
||||
|
||||
@@ -1,118 +1,114 @@
|
||||
import ApplicationActionTypes from "./application.types";
|
||||
|
||||
const INITIAL_STATE = {
|
||||
loading: false,
|
||||
online: true,
|
||||
updateAvailable: false,
|
||||
breadcrumbs: [],
|
||||
recentItems: [],
|
||||
selectedHeader: "home",
|
||||
problemJobs: [],
|
||||
scheduleLoad: {
|
||||
load: {},
|
||||
calculating: false,
|
||||
error: null,
|
||||
},
|
||||
jobReadOnly: false,
|
||||
partnerVersion: null,
|
||||
enableJoyRide: false,
|
||||
joyRideSteps: []
|
||||
loading: false,
|
||||
online: true,
|
||||
updateAvailable: false,
|
||||
breadcrumbs: [],
|
||||
recentItems: [],
|
||||
selectedHeader: "home",
|
||||
problemJobs: [],
|
||||
scheduleLoad: {
|
||||
load: {},
|
||||
calculating: false,
|
||||
error: null
|
||||
},
|
||||
jobReadOnly: false,
|
||||
partnerVersion: null,
|
||||
enableJoyRide: false,
|
||||
joyRideSteps: []
|
||||
};
|
||||
|
||||
const applicationReducer = (state = INITIAL_STATE, action) => {
|
||||
switch (action.type) {
|
||||
case ApplicationActionTypes.SET_UPDATE_AVAILABLE:
|
||||
return {
|
||||
...state,
|
||||
updateAvailable: action.payload,
|
||||
};
|
||||
case ApplicationActionTypes.SET_SELECTED_HEADER:
|
||||
return {
|
||||
...state,
|
||||
selectedHeader: action.payload,
|
||||
};
|
||||
case ApplicationActionTypes.SET_ONLINE_STATUS:
|
||||
return {
|
||||
...state,
|
||||
online: action.payload,
|
||||
};
|
||||
case ApplicationActionTypes.ADD_RECENT_ITEM:
|
||||
return {
|
||||
...state,
|
||||
recentItems: updateRecentItemsArray(state, action.payload),
|
||||
};
|
||||
case ApplicationActionTypes.SET_BREAD_CRUMBS:
|
||||
return {
|
||||
...state,
|
||||
breadcrumbs: action.payload,
|
||||
};
|
||||
case ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD:
|
||||
return {
|
||||
...state,
|
||||
problemJobs: [],
|
||||
scheduleLoad: {...state.scheduleLoad, calculating: true, error: null},
|
||||
};
|
||||
case ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
scheduleLoad: {
|
||||
...state.scheduleLoad,
|
||||
load: action.payload,
|
||||
calculating: false,
|
||||
},
|
||||
};
|
||||
case ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
scheduleLoad: {
|
||||
...state.scheduleLoad,
|
||||
calculating: false,
|
||||
error: action.payload,
|
||||
},
|
||||
};
|
||||
case ApplicationActionTypes.START_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: true,
|
||||
};
|
||||
case ApplicationActionTypes.END_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: false,
|
||||
};
|
||||
switch (action.type) {
|
||||
case ApplicationActionTypes.SET_UPDATE_AVAILABLE:
|
||||
return {
|
||||
...state,
|
||||
updateAvailable: action.payload
|
||||
};
|
||||
case ApplicationActionTypes.SET_SELECTED_HEADER:
|
||||
return {
|
||||
...state,
|
||||
selectedHeader: action.payload
|
||||
};
|
||||
case ApplicationActionTypes.SET_ONLINE_STATUS:
|
||||
return {
|
||||
...state,
|
||||
online: action.payload
|
||||
};
|
||||
case ApplicationActionTypes.ADD_RECENT_ITEM:
|
||||
return {
|
||||
...state,
|
||||
recentItems: updateRecentItemsArray(state, action.payload)
|
||||
};
|
||||
case ApplicationActionTypes.SET_BREAD_CRUMBS:
|
||||
return {
|
||||
...state,
|
||||
breadcrumbs: action.payload
|
||||
};
|
||||
case ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD:
|
||||
return {
|
||||
...state,
|
||||
problemJobs: [],
|
||||
scheduleLoad: { ...state.scheduleLoad, calculating: true, error: null }
|
||||
};
|
||||
case ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
scheduleLoad: {
|
||||
...state.scheduleLoad,
|
||||
load: action.payload,
|
||||
calculating: false
|
||||
}
|
||||
};
|
||||
case ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD_FAILURE:
|
||||
return {
|
||||
...state,
|
||||
scheduleLoad: {
|
||||
...state.scheduleLoad,
|
||||
calculating: false,
|
||||
error: action.payload
|
||||
}
|
||||
};
|
||||
case ApplicationActionTypes.START_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: true
|
||||
};
|
||||
case ApplicationActionTypes.END_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loading: false
|
||||
};
|
||||
|
||||
case ApplicationActionTypes.SET_JOB_READONLY:
|
||||
return {...state, jobReadOnly: action.payload};
|
||||
case ApplicationActionTypes.SET_JOB_READONLY:
|
||||
return { ...state, jobReadOnly: action.payload };
|
||||
|
||||
case ApplicationActionTypes.SET_PARTNER_VERSION:
|
||||
return {...state, partnerVersion: action.payload};
|
||||
case ApplicationActionTypes.SET_PROBLEM_JOBS: {
|
||||
return {...state, problemJobs: action.payload};
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_STEPS: {
|
||||
return {...state, enableJoyRide:true, joyRideSteps: action.payload}
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_FINISHED: {
|
||||
return {...state, enableJoyRide:false, joyRideSteps: []}
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
case ApplicationActionTypes.SET_PARTNER_VERSION:
|
||||
return { ...state, partnerVersion: action.payload };
|
||||
case ApplicationActionTypes.SET_PROBLEM_JOBS: {
|
||||
return { ...state, problemJobs: action.payload };
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_STEPS: {
|
||||
return { ...state, enableJoyRide: true, joyRideSteps: action.payload };
|
||||
}
|
||||
case ApplicationActionTypes.SET_JOYRIDE_FINISHED: {
|
||||
return { ...state, enableJoyRide: false, joyRideSteps: [] };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default applicationReducer;
|
||||
|
||||
const updateRecentItemsArray = (state, newItem) => {
|
||||
//Check to see if the new item is in the list.
|
||||
const matchingIndex = state.recentItems.findIndex((i) => i.id === newItem.id);
|
||||
//Check to see if the new item is in the list.
|
||||
const matchingIndex = state.recentItems.findIndex((i) => i.id === newItem.id);
|
||||
|
||||
if (matchingIndex >= 0) {
|
||||
return [
|
||||
newItem,
|
||||
...state.recentItems.slice(0, matchingIndex),
|
||||
...state.recentItems.slice(matchingIndex + 1, 9),
|
||||
];
|
||||
} else {
|
||||
return [newItem, ...state.recentItems.slice(0, 9)];
|
||||
}
|
||||
if (matchingIndex >= 0) {
|
||||
return [newItem, ...state.recentItems.slice(0, matchingIndex), ...state.recentItems.slice(matchingIndex + 1, 9)];
|
||||
} else {
|
||||
return [newItem, ...state.recentItems.slice(0, 9)];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,303 +1,263 @@
|
||||
import dayjs from "../../utils/day";
|
||||
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 { 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, setProblemJobs,} from "./application.actions";
|
||||
import { CalculateLoad, CheckJobBucket } from "../../utils/SSSUtils";
|
||||
import { scheduleLoadFailure, scheduleLoadSuccess, setProblemJobs } from "./application.actions";
|
||||
import ApplicationActionTypes from "./application.types";
|
||||
|
||||
export function* onCalculateScheduleLoad() {
|
||||
yield takeLatest(
|
||||
ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD,
|
||||
calculateScheduleLoad
|
||||
);
|
||||
yield takeLatest(ApplicationActionTypes.CALCULATE_SCHEDULE_LOAD, calculateScheduleLoad);
|
||||
}
|
||||
|
||||
export function* calculateScheduleLoad({payload: end}) {
|
||||
//REMINDER: dayjs.js is not immutable. Today WILL change when adjusted.
|
||||
const today = dayjs().startOf("day");
|
||||
const state = yield select();
|
||||
const buckets = state.user.bodyshop.ssbuckets;
|
||||
export function* calculateScheduleLoad({ payload: end }) {
|
||||
//REMINDER: dayjs.js is not immutable. Today WILL change when adjusted.
|
||||
const today = dayjs().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,
|
||||
},
|
||||
try {
|
||||
const result = yield client.query({
|
||||
query: QUERY_SCHEDULE_LOAD_DATA,
|
||||
variables: {
|
||||
start: today,
|
||||
end: end
|
||||
}
|
||||
});
|
||||
const { prodJobs, arrJobs, compJobs } = result.data;
|
||||
|
||||
const load = {
|
||||
productionTotal: {},
|
||||
productionHours: 0
|
||||
};
|
||||
let problemJobs = [];
|
||||
//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.
|
||||
if (!item.actual_completion && dayjs(item.scheduled_completion).isBefore(dayjs().startOf("day"))) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job was scheduled to go, but it has not been completed. Update the scheduled completion date to correct projections"
|
||||
});
|
||||
const {prodJobs, arrJobs, compJobs} = result.data;
|
||||
}
|
||||
|
||||
const load = {
|
||||
productionTotal: {},
|
||||
productionHours: 0,
|
||||
};
|
||||
let problemJobs = [];
|
||||
//Set the current load.
|
||||
buckets.forEach((bucket) => {
|
||||
load.productionTotal[bucket.id] = {count: 0, label: bucket.label};
|
||||
if (item.actual_completion && dayjs(item.actual_completion).isBefore(dayjs().startOf("day"))) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job is already marked as completed, but it is still in production. This job should be removed from production"
|
||||
});
|
||||
|
||||
prodJobs.forEach((item) => {
|
||||
//Add all of the jobs currently in production to the buckets so that we have a starting point.
|
||||
if (
|
||||
!item.actual_completion &&
|
||||
dayjs(item.scheduled_completion).isBefore(dayjs().startOf("day"))
|
||||
) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job was scheduled to go, but it has not been completed. Update the scheduled completion date to correct projections",
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
item.actual_completion &&
|
||||
dayjs(item.actual_completion).isBefore(dayjs().startOf("day"))
|
||||
) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job is already marked as completed, but it is still in production. This job should be removed from production",
|
||||
});
|
||||
}
|
||||
if (!(item.actual_completion || item.scheduled_completion)) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job does not have a scheduled or actual completion date. Update the scheduled or actual completion dates to correct projections",
|
||||
});
|
||||
}
|
||||
|
||||
const bucketId = CheckJobBucket(buckets, item);
|
||||
load.productionHours =
|
||||
load.productionHours +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (!(item.actual_completion || item.scheduled_completion)) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job does not have a scheduled or actual completion date. Update the scheduled or actual completion dates to correct projections"
|
||||
});
|
||||
}
|
||||
|
||||
arrJobs.forEach((item) => {
|
||||
if (!item.scheduled_in) {
|
||||
console.log("JOB HAS NO SCHEDULED IN DATE.", item);
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has no scheduled in date",
|
||||
});
|
||||
}
|
||||
if (!item.actual_completion && item.actual_in && !item.inproduction) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual in date, but no actual completion date and is not marked as in production",
|
||||
});
|
||||
}
|
||||
if (item.actual_in && dayjs(item.actual_in).isAfter(dayjs())) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual in date set in the future",
|
||||
});
|
||||
}
|
||||
if (
|
||||
item.actual_completion &&
|
||||
dayjs(item.actual_completion).isAfter(dayjs())
|
||||
) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual completion date set in the future",
|
||||
});
|
||||
}
|
||||
if (item.actual_completion && item.inproduction) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual completion date but it is still marked in production",
|
||||
});
|
||||
}
|
||||
const bucketId = CheckJobBucket(buckets, item);
|
||||
load.productionHours =
|
||||
load.productionHours + item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
const itemDate = dayjs(item.actual_in || item.scheduled_in).format(
|
||||
"YYYY-MM-DD"
|
||||
);
|
||||
|
||||
const AddJobForSchedulingCalc = !item.inproduction;
|
||||
|
||||
if (!!load[itemDate]) {
|
||||
load[itemDate].allHoursIn =
|
||||
(load[itemDate].allHoursIn || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
|
||||
//If the job hasn't already arrived, add it to the jobs in list.
|
||||
// Make sure it also hasn't already been completed, or isn't an in and out job.
|
||||
//This prevents the duplicate counting.
|
||||
load[itemDate].allJobsIn.push(item);
|
||||
if (AddJobForSchedulingCalc) {
|
||||
load[itemDate].jobsIn.push(item);
|
||||
load[itemDate].hoursIn =
|
||||
(load[itemDate].hoursIn || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
}
|
||||
} else {
|
||||
load[itemDate] = {
|
||||
allJobsIn: [item],
|
||||
jobsIn: AddJobForSchedulingCalc ? [item] : [], //Same as above, only add it if it isn't already in production.
|
||||
jobsOut: [],
|
||||
allJobsOut: [],
|
||||
allHoursIn:
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs,
|
||||
hoursIn: AddJobForSchedulingCalc
|
||||
? item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs
|
||||
: 0,
|
||||
};
|
||||
}
|
||||
arrJobs.forEach((item) => {
|
||||
if (!item.scheduled_in) {
|
||||
console.log("JOB HAS NO SCHEDULED IN DATE.", item);
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has no scheduled in date"
|
||||
});
|
||||
|
||||
compJobs.forEach((item) => {
|
||||
if (!(item.actual_completion || item.scheduled_completion))
|
||||
console.warn("JOB HAS NO COMPLETION DATE.", item);
|
||||
|
||||
const inProdJobs = prodJobs.find((p) => p.id === item.id);
|
||||
const inArrJobs = arrJobs.find((p) => p.id === item.id);
|
||||
|
||||
const AddJobForSchedulingCalc = inProdJobs || inArrJobs;
|
||||
|
||||
const itemDate = dayjs(
|
||||
item.actual_completion || item.scheduled_completion
|
||||
).format("YYYY-MM-DD");
|
||||
//Skip it, it's already completed.
|
||||
|
||||
if (!!load[itemDate]) {
|
||||
load[itemDate].allHoursOut =
|
||||
(load[itemDate].allHoursOut || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
//Add only the jobs that are still in production to get rid of.
|
||||
//If it's not in production, we'd subtract unnecessarily.
|
||||
load[itemDate].allJobsOut.push(item);
|
||||
|
||||
if (AddJobForSchedulingCalc) {
|
||||
load[itemDate].jobsOut.push(item);
|
||||
load[itemDate].hoursOut =
|
||||
(load[itemDate].hoursOut || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
}
|
||||
} else {
|
||||
load[itemDate] = {
|
||||
allJobsOut: [item],
|
||||
jobsOut: AddJobForSchedulingCalc ? [item] : [], //Same as above.
|
||||
hoursOut: AddJobForSchedulingCalc
|
||||
? item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs
|
||||
: 0,
|
||||
allHoursOut:
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!item.actual_completion && item.actual_in && !item.inproduction) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual in date, but no actual completion date and is not marked as in production"
|
||||
});
|
||||
}
|
||||
if (item.actual_in && dayjs(item.actual_in).isAfter(dayjs())) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual in date set in the future"
|
||||
});
|
||||
}
|
||||
if (item.actual_completion && dayjs(item.actual_completion).isAfter(dayjs())) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual completion date set in the future"
|
||||
});
|
||||
}
|
||||
if (item.actual_completion && item.inproduction) {
|
||||
problemJobs.push({
|
||||
...item,
|
||||
code: "Job has an actual completion date but it is still marked in production"
|
||||
});
|
||||
}
|
||||
|
||||
//Propagate the expected load to each day.
|
||||
const itemDate = dayjs(item.actual_in || item.scheduled_in).format("YYYY-MM-DD");
|
||||
|
||||
const range = Math.round(dayjs.duration(end.diff(today)).asDays()) + 1;
|
||||
for (var day = 0; day < range; day++) {
|
||||
const current = dayjs(today).add(day, "day").format("YYYY-MM-DD");
|
||||
const prev = dayjs(today)
|
||||
.add(day - 1, "day")
|
||||
.format("YYYY-MM-DD");
|
||||
if (!!!load[current]) {
|
||||
load[current] = {};
|
||||
}
|
||||
const AddJobForSchedulingCalc = !item.inproduction;
|
||||
|
||||
if (day === 0) {
|
||||
//Starting on day 1. The load is current.
|
||||
load[current].expectedLoad = CalculateLoad(
|
||||
load.productionTotal,
|
||||
buckets,
|
||||
load[current].jobsIn || [],
|
||||
load[current].jobsOut || []
|
||||
);
|
||||
load[current].expectedJobCount =
|
||||
prodJobs.length +
|
||||
(load[current].jobsIn || []).length -
|
||||
(load[current].jobsOut || []).length;
|
||||
load[current].expectedHours =
|
||||
load.productionHours +
|
||||
(load[current].hoursIn || 0) -
|
||||
(load[current].hoursOut || 0);
|
||||
} else {
|
||||
load[current].expectedLoad = CalculateLoad(
|
||||
load[prev].expectedLoad,
|
||||
buckets,
|
||||
load[current].jobsIn || [],
|
||||
load[current].jobsOut || []
|
||||
);
|
||||
load[current].expectedJobCount =
|
||||
load[prev].expectedJobCount +
|
||||
(load[current].jobsIn || []).length -
|
||||
(load[current].jobsOut || []).length;
|
||||
load[current].expectedHours =
|
||||
load[prev].expectedHours +
|
||||
(load[current].hoursIn || 0) -
|
||||
(load[current].hoursOut || 0);
|
||||
}
|
||||
if (!!load[itemDate]) {
|
||||
load[itemDate].allHoursIn =
|
||||
(load[itemDate].allHoursIn || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
|
||||
//If the job hasn't already arrived, add it to the jobs in list.
|
||||
// Make sure it also hasn't already been completed, or isn't an in and out job.
|
||||
//This prevents the duplicate counting.
|
||||
load[itemDate].allJobsIn.push(item);
|
||||
if (AddJobForSchedulingCalc) {
|
||||
load[itemDate].jobsIn.push(item);
|
||||
load[itemDate].hoursIn =
|
||||
(load[itemDate].hoursIn || 0) + item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
}
|
||||
} else {
|
||||
load[itemDate] = {
|
||||
allJobsIn: [item],
|
||||
jobsIn: AddJobForSchedulingCalc ? [item] : [], //Same as above, only add it if it isn't already in production.
|
||||
jobsOut: [],
|
||||
allJobsOut: [],
|
||||
allHoursIn: item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs,
|
||||
hoursIn: AddJobForSchedulingCalc
|
||||
? item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs
|
||||
: 0
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
yield put(setProblemJobs(problemJobs));
|
||||
yield put(scheduleLoadSuccess(load));
|
||||
} catch (error) {
|
||||
yield put(scheduleLoadFailure(error));
|
||||
compJobs.forEach((item) => {
|
||||
if (!(item.actual_completion || item.scheduled_completion)) console.warn("JOB HAS NO COMPLETION DATE.", item);
|
||||
|
||||
const inProdJobs = prodJobs.find((p) => p.id === item.id);
|
||||
const inArrJobs = arrJobs.find((p) => p.id === item.id);
|
||||
|
||||
const AddJobForSchedulingCalc = inProdJobs || inArrJobs;
|
||||
|
||||
const itemDate = dayjs(item.actual_completion || item.scheduled_completion).format("YYYY-MM-DD");
|
||||
//Skip it, it's already completed.
|
||||
|
||||
if (!!load[itemDate]) {
|
||||
load[itemDate].allHoursOut =
|
||||
(load[itemDate].allHoursOut || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
//Add only the jobs that are still in production to get rid of.
|
||||
//If it's not in production, we'd subtract unnecessarily.
|
||||
load[itemDate].allJobsOut.push(item);
|
||||
|
||||
if (AddJobForSchedulingCalc) {
|
||||
load[itemDate].jobsOut.push(item);
|
||||
load[itemDate].hoursOut =
|
||||
(load[itemDate].hoursOut || 0) +
|
||||
item.labhrs.aggregate.sum.mod_lb_hrs +
|
||||
item.larhrs.aggregate.sum.mod_lb_hrs;
|
||||
}
|
||||
} else {
|
||||
load[itemDate] = {
|
||||
allJobsOut: [item],
|
||||
jobsOut: AddJobForSchedulingCalc ? [item] : [], //Same as above.
|
||||
hoursOut: AddJobForSchedulingCalc
|
||||
? item.labhrs.aggregate.sum.mod_lb_hrs + item.larhrs.aggregate.sum.mod_lb_hrs
|
||||
: 0,
|
||||
allHoursOut: 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(dayjs.duration(end.diff(today)).asDays()) + 1;
|
||||
for (var day = 0; day < range; day++) {
|
||||
const current = dayjs(today).add(day, "day").format("YYYY-MM-DD");
|
||||
const prev = dayjs(today)
|
||||
.add(day - 1, "day")
|
||||
.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 || []
|
||||
);
|
||||
load[current].expectedJobCount =
|
||||
prodJobs.length + (load[current].jobsIn || []).length - (load[current].jobsOut || []).length;
|
||||
load[current].expectedHours =
|
||||
load.productionHours + (load[current].hoursIn || 0) - (load[current].hoursOut || 0);
|
||||
} else {
|
||||
load[current].expectedLoad = CalculateLoad(
|
||||
load[prev].expectedLoad,
|
||||
buckets,
|
||||
load[current].jobsIn || [],
|
||||
load[current].jobsOut || []
|
||||
);
|
||||
load[current].expectedJobCount =
|
||||
load[prev].expectedJobCount + (load[current].jobsIn || []).length - (load[current].jobsOut || []).length;
|
||||
load[current].expectedHours =
|
||||
load[prev].expectedHours + (load[current].hoursIn || 0) - (load[current].hoursOut || 0);
|
||||
}
|
||||
}
|
||||
|
||||
yield put(setProblemJobs(problemJobs));
|
||||
yield put(scheduleLoadSuccess(load));
|
||||
} catch (error) {
|
||||
yield put(scheduleLoadFailure(error));
|
||||
}
|
||||
}
|
||||
|
||||
export function* onInsertAuditTrail() {
|
||||
yield takeLatest(
|
||||
ApplicationActionTypes.INSERT_AUDIT_TRAIL,
|
||||
insertAuditTrailSaga
|
||||
);
|
||||
yield takeLatest(ApplicationActionTypes.INSERT_AUDIT_TRAIL, insertAuditTrailSaga);
|
||||
}
|
||||
|
||||
export function* insertAuditTrailSaga({
|
||||
payload: {jobid, billid, operation, type},
|
||||
}) {
|
||||
const state = yield select();
|
||||
const bodyshop = state.user.bodyshop;
|
||||
const currentUser = state.user.currentUser;
|
||||
export function* insertAuditTrailSaga({ payload: { jobid, billid, operation, type } }) {
|
||||
const state = yield select();
|
||||
const bodyshop = state.user.bodyshop;
|
||||
const currentUser = state.user.currentUser;
|
||||
|
||||
const variables = {
|
||||
auditObj: {
|
||||
bodyshopid: bodyshop.id,
|
||||
jobid,
|
||||
billid,
|
||||
operation,
|
||||
type,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,
|
||||
query: INSERT_AUDIT_TRAIL,
|
||||
variables,
|
||||
});
|
||||
return [...existingAuditTrail, newAuditTrail];
|
||||
},
|
||||
},
|
||||
const variables = {
|
||||
auditObj: {
|
||||
bodyshopid: bodyshop.id,
|
||||
jobid,
|
||||
billid,
|
||||
operation,
|
||||
type,
|
||||
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,
|
||||
query: INSERT_AUDIT_TRAIL,
|
||||
variables
|
||||
});
|
||||
},
|
||||
});
|
||||
return [...existingAuditTrail, newAuditTrail];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function* applicationSagas() {
|
||||
yield all([call(onCalculateScheduleLoad), call(onInsertAuditTrail)]);
|
||||
yield all([call(onCalculateScheduleLoad), call(onInsertAuditTrail)]);
|
||||
}
|
||||
|
||||
@@ -1,62 +1,26 @@
|
||||
import {createSelector} from "reselect";
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
const selectApplication = (state) => state.application;
|
||||
|
||||
export const selectLoading = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.loading
|
||||
);
|
||||
export const selectLoading = createSelector([selectApplication], (application) => application.loading);
|
||||
|
||||
export const selectBreadcrumbs = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.breadcrumbs
|
||||
);
|
||||
export const selectBreadcrumbs = createSelector([selectApplication], (application) => application.breadcrumbs);
|
||||
|
||||
export const selectRecentItems = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.recentItems
|
||||
);
|
||||
export const selectRecentItems = createSelector([selectApplication], (application) => application.recentItems);
|
||||
|
||||
export const selectScheduleLoad = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.scheduleLoad.load
|
||||
);
|
||||
export const selectPartnerVersion = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.partnerVersion
|
||||
);
|
||||
export const selectScheduleLoad = createSelector([selectApplication], (application) => application.scheduleLoad.load);
|
||||
export const selectPartnerVersion = createSelector([selectApplication], (application) => application.partnerVersion);
|
||||
|
||||
export const selectScheduleLoadCalculating = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.scheduleLoad.calculating
|
||||
[selectApplication],
|
||||
(application) => application.scheduleLoad.calculating
|
||||
);
|
||||
|
||||
export const selectSelectedHeader = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.selectedHeader
|
||||
);
|
||||
export const selectSelectedHeader = createSelector([selectApplication], (application) => application.selectedHeader);
|
||||
|
||||
export const selectJobReadOnly = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.jobReadOnly
|
||||
);
|
||||
export const selectOnline = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.online
|
||||
);
|
||||
export const selectProblemJobs = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.problemJobs
|
||||
);
|
||||
export const selectUpdateAvailable = createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.updateAvailable
|
||||
);
|
||||
export const selectEnableJoyRide= createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.enableJoyRide
|
||||
);
|
||||
export const selectJoyRideSteps= createSelector(
|
||||
[selectApplication],
|
||||
(application) => application.joyRideSteps
|
||||
);
|
||||
export const selectJobReadOnly = createSelector([selectApplication], (application) => application.jobReadOnly);
|
||||
export const selectOnline = createSelector([selectApplication], (application) => application.online);
|
||||
export const selectProblemJobs = createSelector([selectApplication], (application) => application.problemJobs);
|
||||
export const selectUpdateAvailable = createSelector([selectApplication], (application) => application.updateAvailable);
|
||||
export const selectEnableJoyRide = createSelector([selectApplication], (application) => application.enableJoyRide);
|
||||
export const selectJoyRideSteps = createSelector([selectApplication], (application) => application.joyRideSteps);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
const ApplicationActionTypes = {
|
||||
START_LOADING: "START_LOADING",
|
||||
END_LOADING: "END_LOADING",
|
||||
SET_BREAD_CRUMBS: "SET_BREAD_CRUMBS",
|
||||
CALCULATE_SCHEDULE_LOAD: "CALCULATE_SCHEDULE_LOAD",
|
||||
CALCULATE_SCHEDULE_LOAD_SUCCESS: "CALCULATE_SCHEDULE_LOAD_SUCCESS",
|
||||
CALCULATE_SCHEDULE_LOAD_FAILURE: "CALCULATE_SCHEDULE_LOAD_FAILURE",
|
||||
ADD_RECENT_ITEM: "ADD_RECENT_ITEM",
|
||||
SET_SELECTED_HEADER: "SET_SELECTED_HEADER",
|
||||
SET_JOB_READONLY: "SET_JOB_READONLY",
|
||||
SET_PARTNER_VERSION: "SET_PARTNER_VERSION",
|
||||
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
|
||||
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
|
||||
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
|
||||
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE",
|
||||
SET_JOYRIDE_STEPS: "SET_JOYRIDE_STEPS",
|
||||
SET_JOYRIDE_FINISHED:"SET_JOYRIDE_FINISHED"
|
||||
START_LOADING: "START_LOADING",
|
||||
END_LOADING: "END_LOADING",
|
||||
SET_BREAD_CRUMBS: "SET_BREAD_CRUMBS",
|
||||
CALCULATE_SCHEDULE_LOAD: "CALCULATE_SCHEDULE_LOAD",
|
||||
CALCULATE_SCHEDULE_LOAD_SUCCESS: "CALCULATE_SCHEDULE_LOAD_SUCCESS",
|
||||
CALCULATE_SCHEDULE_LOAD_FAILURE: "CALCULATE_SCHEDULE_LOAD_FAILURE",
|
||||
ADD_RECENT_ITEM: "ADD_RECENT_ITEM",
|
||||
SET_SELECTED_HEADER: "SET_SELECTED_HEADER",
|
||||
SET_JOB_READONLY: "SET_JOB_READONLY",
|
||||
SET_PARTNER_VERSION: "SET_PARTNER_VERSION",
|
||||
SET_ONLINE_STATUS: "SET_ONLINE_STATUS",
|
||||
INSERT_AUDIT_TRAIL: "INSERT_AUDIT_TRAIL",
|
||||
SET_PROBLEM_JOBS: "SET_PROBLEM_JOBS",
|
||||
SET_UPDATE_AVAILABLE: "SET_UPDATE_AVAILABLE",
|
||||
SET_JOYRIDE_STEPS: "SET_JOYRIDE_STEPS",
|
||||
SET_JOYRIDE_FINISHED: "SET_JOYRIDE_FINISHED"
|
||||
};
|
||||
export default ApplicationActionTypes;
|
||||
|
||||
Reference in New Issue
Block a user