Goutam.A.S
Goutam.A.S

Reputation: 47

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.");
      }
    });

Upvotes: 1

Views: 200

Answers (3)

Luke Kot-Zaniewski
Luke Kot-Zaniewski

Reputation: 1161

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);

Upvotes: 1

Jonas Wilms
Jonas Wilms

Reputation: 138267

//  Expecting input to be your custom object
var output={};
for(i=0;i<input.length;i++){
el = input[i];
a=output[el.id];
a.employeId=el.employeId;
a.totalHours=a.totalHours||"0:0";
b=el.totalHours.split(":");
c=a.totalHours.split(":");
b[0]=+b[0]+c[0];
if(b[1]+c[1]>60){
b[0]++;
}
b[1]=(+b[1]+c[1])%60;
a.totalHours=b.join(":");
}

The result is not exactly what youve expected. I dont wanted to search the employe id in the array each times:

{
105:{
   employeid:105;
   totalHours:"15:20";
 }
 }

Upvotes: 0

Evan Trimboli
Evan Trimboli

Reputation: 30082

Here is an implementation. I think it's cleaner than some of the other answers:

function calc(data) {
    const seen = {};
    const result = [];

    data.forEach(item => {
        const id = item.employeeId;
        if (!seen.hasOwnProperty(id)) {
            seen[id] = result.length;
            result.push({
                employeeId: id,
                minutes: 0
            });
        }
        const idx = seen[id];
        const parts = item.totalHours.split(':');
        result[idx].minutes += (parseInt(parts[0], 10) * 60) + parseInt(parts[1]);
    });

    result.forEach(item => {
        const minutes = item.minutes;
        delete item.minutes;
        item.totalHours = Ext.String.leftPad(Math.floor(minutes / 60), 2, '0') 
                            + ':' + Ext.String.leftPad(minutes % 60, 2, '0');
    });

    return result;
}

console.log(calc([{
    "employeeId": "105",
    "totalHours": "1:30"
}, {
    "employeeId": "777",
    "totalHours": "1:15"
}, {
    "employeeId": "105",
    "totalHours": "1:15"
}, {
    "employeeId": "777",
    "totalHours": "1:00"
}]));

Upvotes: 1

Related Questions