Goutam.A.S Goutam.A.S - 9 days ago 6
Ajax Question

How to calculate total hours?

I am trying to calculate total hours based on "employeeId". I couldn't figure out how to write logic for this. What is the best way to solve this problem?

Expected Result,

[
{

"employeeId": "105",
"totalHours": "2:45"
},
{
"employeeId": "777",
"totalHours": "2:15"
}
]


Response From Ajax Call

[
{
"employeeId": "105",
"totalHours": "1:30"
},
{
"employeeId": "777",
"totalHours": "1:15"
},
{
"employeeId": "105",
"totalHours": "1:15"
},
{
"employeeId": "777",
"totalHours": "1:00"
}
]


My Code

var jrr = new Array();
Ext.Ajax.request({
url: '/common/services/general/basicOperations/getDataByModelUsingGetMethod',
method: 'GET',
params : {
actionId : 'payroll',
dataJson : '{"aspectType":"Payroll Profile"}'
},
success: function(response){
try{
var response = response.responseText;
var resObj = Ext.decode(response);
for(var j = 0; j < resObj.data.length; j++)
{
for(var k = 0; k < resObj.data[j].payrolltransactionDetail.length; k++)
{
jrr.push(resObj.data[j].payrolltransactionDetail[k]);
}
}
console.log(JSON.stringify(jrr, null, 4));
}
catch(e){
console.log(e);
}
},
failure: function(response){
deferred.reject("Error Fetching.");
}
});

Answer

Here is an implementation using js functional programming. You can transform the data to your desired output using just the reduce function. If you cannot change your query result using some kind of aggregation on the server side then you can implement something akin to the below.

var input = [
    {
        "employeeId": "105",
        "totalHours": "1:46"
    },
    {
        "employeeId": "777",
        "totalHours": "1:15"
    },
    {
        "employeeId": "105",
        "totalHours": "1:15"
    },
    {
        "employeeId": "777",
        "totalHours": "1:00"
    }
]

var obj = input.reduce( function(init, e){
    //if aggregating init object doesn't have the employee then add the employeeId (key) and time (value)
    if (init[e["employeeId"]] == undefined){
         init[e["employeeId"]] = {hours: parseInt(e["totalHours"].split(":")[0]),minutes: parseInt(e["totalHours"].split(":")[1])};
         init[e["employeeId"]].timeString = e["totalHours"];
         return init;
     //otherwise add to the existing employeeId the hour and minute values, while remembering to carry the extra hour if minutes exceed 59.
      }else{
         init[e["employeeId"]].hours += (parseInt(e["totalHours"].split(":")[0]) + Math.floor((init[e["employeeId"]].minutes + parseInt(e["totalHours"].split(":")[1]))/60));
         init[e["employeeId"]].minutes = (init[e["employeeId"]].minutes + parseInt(e["totalHours"].split(":")[1]))%60;
         init[e["employeeId"]].timeString = init[e["employeeId"]].minutes > 9 ? init[e["employeeId"]].hours + ":" + init[e["employeeId"]].minutes : init[e["employeeId"]].hours + ":0" + init[e["employeeId"]].minutes;
         return init;
      }
  }, {});

var arr = [];
for (var prop in obj) arr.push({employeeId: prop, totalHours: obj[prop].timeString});
console.log(arr);

Comments