-1

I have developed an Employees Lunch Break-Time Tracker where the employee has to punch in/out before and after their lunch break time. I calculated the total break in minutes and saved it in the DB. I provided a report to the HR department of all the break time. The challenging part for me here was to provide a report where evening shift employees took a lunch break the next day should appear on the previous day. What I did was, I created an 8 character code for each day and that code will be saved for each employee.

What I need to provide is a summary report where it will show the employee and the rest of the columns are the days for that month.

I have two tables now.

Table CODE:

ID   | CODE     | DATE_CREATED |
1    | 9VIHQIHE | 2019-03-30   |
2    | 6JFGGU9P | 2019-03-31   | 
3    | UYVEWVN0 | 2019-04-01   |

Table BREAKTIME:

ID   | EMPLOYEE   | CODE     | TOTAL_BREAKTIME 
1    | JOHN       | 9VIHQIHE | 00:59:01 
2    | RYAN       | 9VIHQIHE | 01:01:20
3    | JOHN       | 6JFGGU9P | 01:15:08
4    | RYAN       | 6JFGGU9P | 00:58:12
5    | JOHN       | UYVEWVN0 | 00:57:32
6    | RYAN       | UYVEWVN0 | 01:05:16

Now, I need a report that will give me a summary of total break of each employee month-wise.

The report should look like this when my search parameter is March 2019.

EMPLOYEE  |   01   |  02  | .......... |    30    |    31
JOHN      |   -    |  -   | .......... | 00:59:01 | 01:15:08
RYAN      |   -    |  -   | .......... | 01:01:20 | 00:58:12

I have not written any code because I don't know where to start with.

Please, I need your help.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Borgy ES
  • 11
  • 9

1 Answers1

0

You can accomplish this with a single JOIN:

SELECT 
    DATE_FORMAT(c.date_created, '%d') AS date,
    b.employee,
    b.total_breaktime
FROM
    code c
    JOIN breaktime b ON b.code = c.code
WHERE
    DATE_FORMAT(date_created, '%Y-%m') = '2019-03'
ORDER BY employee , date_created;

will get you a dataset like

30  JOHN    00:59:01
31  JOHN    01:15:08
30  RYAN    01:01:20
31  RYAN    00:58:12

You could then first loop through this data and restructure it into a 2D array with employee as the key so each "employee" can be its own row in the final output:

while($b = $result->fetch_assoc()){
    $employee = $b["employee"];
    $date = $b["date"];
    $time = $b["total_breaktime"];

    $BreakTime[$employee][$date] = $time;
}

results in:

$BreakTime = array(
    'JOHN' => array(
        '30' => '00:59:01',
        '31' => '01:15:08',
    ),
    'RYAN' => array(
        '30' => '01:01:20',
        '31' => '00:58:12',
    );
);

then finally you can loop through that data to output it to the page.

echo "<table><tbody>";

foreach($BreakTime as $key => $val) {
    echo "<tr><td>" .$key. "</td>";
    for($d=1; $d<=31; $d++) {
        echo "<td>";
        echo isset($BreakTime[$key][$d]) ? $BreakTime[$key][$d] : '00:00';
        echo "</td>";
    }
    echo "</tr>";
}

echo "</tbody></table>";
WOUNDEDStevenJones
  • 5,150
  • 6
  • 41
  • 53
  • Thanks @WOUNDEDStevenJones, what is "test" in the test.code? and the letter b and c? – Borgy ES Apr 04 '19 at 04:07
  • Sorry, `test` was my schema name that I copied the query from. Removed that from my answer now. `b` and `c` are optional table aliases (can search for "mysql table aliases" for more info) – WOUNDEDStevenJones Apr 04 '19 at 04:12
  • hi @WOUNDEDStevenJones. That is great! Please check the code below. Thanks! – Borgy ES Apr 04 '19 at 09:29
  • That error likely means that `$BreakTime[$key][1]` isn't set for that employee (maybe they didn't take a break that day). So before attempting to access that value, you can check if it's set with `isset()`. Also don't forget to echo that value, so line 207 should be something like `echo isset($BreakTime[$key][$d]) ? $BreakTime[$key][$d] : '0';`. Typing on mobile, but I can test this a bit later. – WOUNDEDStevenJones Apr 04 '19 at 12:20
  • Tried this echo isset($BreakTime[$key][$d]) ? $BreakTime[$key][$d] : '0'; but showing all columns "0". – Borgy ES Apr 04 '19 at 12:42
  • @BorgyES the PHP you had to restructure the MySQL data wasn't quite what I was thinking, so I've updated it above for more clarity. – WOUNDEDStevenJones Apr 04 '19 at 13:48
  • Hi WOUNDEDStevenJones, the code above works perfectly! However, When I select April 2019, all of the days shows 00:00. I am pretty sure that the dropdown gives the correct variable because it works in March 2019. – Borgy ES Apr 07 '19 at 05:19
  • @BorgyES Not sure what dropdown you're referring to. But if you run the query with `2019-04` the logic and everything should be the same as it was for `2019-03`. – WOUNDEDStevenJones Apr 07 '19 at 05:26
  • I'm sorry to make you confused. I have a dropdown for the selection of the month. Anyway, there's no issue with that. My query for 2019-04 should work the same as the 2019-03. But when I ran the query for April it shows all 00:00, I even print_r($BreakTime) and it has values. Strange isn't it.. hmmmm – Borgy ES Apr 07 '19 at 05:59
  • 1
    Hi WOUNDEDStevenJones, I have found the issue, in the query I have to use %e instead of %d so it will return without "0" because our loop doesn't start with 01, 02, 03 but 1, 2, 3... A very big THANKS to you! – Borgy ES Apr 07 '19 at 10:13