const GraphQLClient = require("graphql-request").GraphQLClient; const path = require("path"); const queries = require("../graphql-client/queries"); const Dinero = require("dinero.js"); const moment = require("moment"); require("dotenv").config({ path: path.resolve( process.cwd(), `.env.${process.env.NODE_ENV || "development"}` ), }); exports.job = async (req, res) => { try { const BearerToken = req.headers.authorization; const { jobId } = req.body; const client = new GraphQLClient(process.env.GRAPHQL_ENDPOINT, { headers: { Authorization: BearerToken, }, }); const result = await client .setHeaders({ Authorization: BearerToken }) .request(queries.QUERY_UPCOMING_APPOINTMENTS, { now: new Date(), jobId: jobId, }); const { appointments, productionview } = result; const { ssbuckets } = result.jobs_by_pk.bodyshop; const jobHrs = result.jobs_by_pk.jobhrs.aggregate.sum.mod_lb_hrs; const JobBucket = ssbuckets.filter( (bucket) => bucket.gte <= jobHrs && (!!bucket.lt ? bucket.lt > jobHrs : true) )[0]; const bucketMatrix = {}; //Get latest date + add 5 days to allow for back end adding.. const totalMatrixDays = moment .max([ ...appointments.map((a) => moment(a.start)), ...productionview .map((p) => moment(p.scheduled_completion)) .filter((p) => p.isValid()), ]) .add("5", "days") .diff(moment(), "days"); //Initialize the bucket matrix for (i = 0; i < totalMatrixDays; i++) { const theDate = moment().add(i, "days").toISOString().substr(0, 10); //Only need to create a matrix for jobs of the same bucket. bucketMatrix[theDate] = { in: 0, out: 0 }; // ssbuckets.forEach((bucket) => { // bucketMatrix[theDate] = { // ...bucketMatrix[theDate], // [bucket.id]: { in: 0, out: 0 }, // }; // }); } //Populate the jobs scheduled to come in. appointments.forEach((appointment) => { const jobHrs = appointment.job.joblines_aggregate.aggregate.sum.mod_lb_hrs; //Is the job in the same bucket? const appointmentBucket = ssbuckets.filter( (bucket) => bucket.gte <= jobHrs && (!!bucket.lt ? bucket.lt > jobHrs : true) )[0]; if (appointmentBucket.id === JobBucket.id) { //Theyre the same classification. Add it to the matrix. const appDate = moment(appointment.start).toISOString().substr(0, 10); bucketMatrix[appDate] = { ...bucketMatrix[appDate], in: bucketMatrix[appDate].in + 1, }; } }); //Populate the jobs that are leaving today. const todayIsoString = moment().toISOString().substr(0, 10); productionview.forEach((pjob) => { const jobHrs = pjob.larhrs + pjob.labhrs; //Is the job in the same bucket? const pjobBucket = ssbuckets.filter( (bucket) => bucket.gte <= jobHrs && (!!bucket.lt ? bucket.lt > jobHrs : true) )[0]; if (pjobBucket.id === JobBucket.id) { //Theyre the same classification. Add it to the matrix. const compDate = moment(pjob.scheduled_completion); //Is the schedule completion behind today? If so, use today as it. let dateToUse; dateToUse = compDate.isValid() ? moment().diff(compDate, "days") <= 0 ? compDate.toISOString().substr(0, 10) : todayIsoString : todayIsoString; bucketMatrix[dateToUse] = { ...bucketMatrix[dateToUse], out: bucketMatrix[dateToUse].out + 1, }; } }); //Propose the first 5 dates where we are below target. const possibleDates = []; const bucketMatrixKeys = Object.keys(bucketMatrix); bucketMatrixKeys.forEach((bmkey) => { if (JobBucket.target > bucketMatrix[bmkey].in - bucketMatrix[bmkey].out) possibleDates.push(new Date(bmkey).toISOString().substr(0, 10)); }); //Temp // possibleDates.push(new Date()); // possibleDates.push(new Date()); // possibleDates.push(new Date()); // possibleDates.push(new Date()); // possibleDates.push(new Date()); //Get a list of upcoming appointments //Get the config for each day res.json(possibleDates); } catch (error) { console.log("error", error); res.status(400).send(error); } };