const Dinero = require("dinero.js"); const queries = require("../graphql-client/queries"); const GraphQLClient = require("graphql-request").GraphQLClient; const logger = require("../utils/logger"); const { CalculateExpectedHoursForJob, CalculateTicketsHoursForJob, } = require("./pay-all"); // Dinero.defaultCurrency = "USD"; // Dinero.globalLocale = "en-CA"; Dinero.globalRoundingMode = "HALF_EVEN"; exports.calculatelabor = async function (req, res) { const {jobid, calculateOnly} = req.body; logger.log("job-payroll-calculate-labor", "DEBUG", req.user.email, jobid, null); const BearerToken = req.BearerToken; const client = req.userGraphQLClient; try { const {jobs_by_pk: job} = await client .setHeaders({Authorization: BearerToken}) .request(queries.QUERY_JOB_PAYROLL_DATA, { id: jobid, }); //iterate over each ticket, building a hash of team -> employee to calculate total assigned hours. const {employeeHash, assignmentHash} = CalculateExpectedHoursForJob(job); const ticketHash = CalculateTicketsHoursForJob(job); const totals = []; //Iteratively go through all 4 levels of the object and create an array that can be presented. // use the employee hash as the golden record (i.e. what they should have), and add what they've claimed. //While going through, delete items from ticket hash. //Anything left in ticket hash is an extra entered item. Object.keys(employeeHash).forEach((employeeIdKey) => { //At the employee level. Object.keys(employeeHash[employeeIdKey]).forEach((laborTypeKey) => { //At the labor level Object.keys(employeeHash[employeeIdKey][laborTypeKey]).forEach( (rateKey) => { //At the rate level. const expectedHours = employeeHash[employeeIdKey][laborTypeKey][rateKey]; //Will the following line fail? Probably if it doesn't exist. const claimedHours = get( ticketHash, `${employeeIdKey}.${laborTypeKey}.${rateKey}` ); if (claimedHours) { delete ticketHash[employeeIdKey][laborTypeKey][rateKey]; } totals.push({ employeeid: employeeIdKey, rate: rateKey, mod_lbr_ty: laborTypeKey, expectedHours, claimedHours: claimedHours || 0, }); } ); }); }); Object.keys(ticketHash).forEach((employeeIdKey) => { //At the employee level. Object.keys(ticketHash[employeeIdKey]).forEach((laborTypeKey) => { //At the labor level Object.keys(ticketHash[employeeIdKey][laborTypeKey]).forEach( (rateKey) => { //At the rate level. const expectedHours = 0; //Will the following line fail? Probably if it doesn't exist. const claimedHours = get( ticketHash, `${employeeIdKey}.${laborTypeKey}.${rateKey}` ); if (claimedHours) { delete ticketHash[employeeIdKey][laborTypeKey][rateKey]; } totals.push({ employeeid: employeeIdKey, rate: rateKey, mod_lbr_ty: laborTypeKey, expectedHours, claimedHours: claimedHours || 0, }); } ); }); }); if (assignmentHash.unassigned > 0) { totals.push({ employeeid: undefined, //rate: rateKey, //mod_lbr_ty: laborTypeKey, expectedHours: assignmentHash.unassigned, claimedHours: 0, }); } res.json(totals); //res.json(assignmentHash); } catch (error) { logger.log( "job-payroll-calculate-labor-error", "ERROR", req.user.email, jobid, { jobid: jobid, error, } ); res.status(503).send(); } }; get = function (obj, key) { return key.split(".").reduce(function (o, x) { return typeof o == "undefined" || o === null ? o : o[x]; }, obj); };