skip to Main Content

I’m struggling with code that would group attendance data.
Usually, in cases where arrival and departure are on the same day, it’s not a problem to group the attendance.
The problem becomes if I have a "night shift": arriving at 10pm and leaving at 06am the next day. In that case, I would like to have a new group of attendances. And than If there are any attendance entries for the next day as well (later than the first check-out for that day), I want to combine them into a new group.

$attendances = [

//Group 1

{
    "id": 1,
    "attendance_date": "2023-08-24",
    "time": "11:00:00",
    "status": "arrival"
},
{
    "id": 2,
    "attendance_date": "2023-08-24",
    "time": "14:00:00",
    "status": "departure"
},

//Group 2

{
    "id": 3,
    "attendance_date": "2023-08-24",
    "time": "22:00:00",
    "status": "arrival"
},
{
    "id": 4,
    "attendance_date": "2023-08-25",
    "time": "06:00:00",
    "status": "departure"
},

// Group 3

{
    "id": 5,
    "attendance_date": "2023-08-25",
    "time": "10:00:00",
    "status": "arrival"
},
{
    "id": 6,
    "attendance_date": "2023-08-25",
    "time": "18:00:00",
    "status": "departure"
}

]

My current code for grouping array is this and it only works in some cases.

        $currentDate = null;
        $groupedAttendances = [];
        $currentGroup = [];

        foreach ($attendances as $attendance) {
            if ($attendance->attendance_date !== $currentDate) {
                // New attendance_date encountered, create a new group
                $currentDate = $attendance->attendance_date;
                if (!empty($currentGroup)) {
                    $groupedAttendances[] = $currentGroup;
                }
                $currentGroup = [$attendance];
            } else {
                // Adding to the current group
                $currentGroup[] = $attendance;
            }
        }

        if (!empty($currentGroup)) {
            $groupedAttendances[] = $currentGroup;
        }

2

Answers


  1. Chosen as BEST ANSWER

    Maybe I was unclear. But I managed to get the wanted result.

    Example data from database:

    $data = [
                (object) [
                    "id" => 1,
                    "attendance_date" => "2023-08-24",
                    "time" => "11:00:00",
                    "status" => "arrival",
                ],
                (object) [
                    "id" => 2,
                    "attendance_date" => "2023-08-24",
                    "time" => "14:00:00",
                    "status" => "departure",
                ],
                (object) [
                    "id" => 3,
                    "attendance_date" => "2023-08-24",
                    "time" => "22:00:00",
                    "status" => "arrival",
                ],
                (object) [
                    "id" => 4,
                    "attendance_date" => "2023-08-25",
                    "time" => "06:00:00",
                    "status" => "departure",
                ],
                (object) [
                    "id" => 5,
                    "attendance_date" => "2023-08-25",
                    "time" => "10:00:00",
                    "status" => "arrival",
                ],
                (object) [
                    "id" => 6,
                    "attendance_date" => "2023-08-25",
                    "time" => "18:00:00",
                    "status" => "departure",
                ],
            ];
    

    The code for groupping attendances:

    $attendances = collect($data);
            $groupedAttendances = [];
            $currentGroup = [];
    
            foreach ($attendances as $attendance) {
                if ($attendance->status === 'arrival') {
                    if (!empty($currentGroup)) {
                        if (count($currentGroup) === 1 && $currentGroup[0]->status === 'arrival') {
                            // Handle night shift with no departure on the same day
                            $currentGroup[0]->night_shift = true;
                        }
                        $groupedAttendances[] = $currentGroup;
                        $currentGroup = [];
                    }
                }
    
                $currentGroup[] = $attendance;
            }
    
            if (!empty($currentGroup)) {
                if (count($currentGroup) === 1 && $currentGroup[0]->status === 'arrival') {
                    // Handle night shift with no departure on the same day
                    $currentGroup[0]->night_shift = true;
                }
                $groupedAttendances[] = $currentGroup;
            }
    
            print_r($groupedAttendances);
    

    Output results:

    array:3 [▼ 
      0 => array:2 [▼
        0 => {#1580 ▼
          +"id": 1
          +"attendance_date": "2023-08-24"
          +"time": "11:00:00"
          +"status": "arrival"
        }
        1 => {#1581 ▼
          +"id": 2
          +"attendance_date": "2023-08-24"
          +"time": "14:00:00"
          +"status": "departure"
        }
      ]
      1 => array:2 [▼
        0 => {#1552 ▼
          +"id": 3
          +"attendance_date": "2023-08-24"
          +"time": "22:00:00"
          +"status": "arrival"
        }
        1 => {#1579 ▼
          +"id": 4
          +"attendance_date": "2023-08-25"
          +"time": "06:00:00"
          +"status": "departure"
        }
      ]
      2 => array:2 [▼
        0 => {#1578 ▼
          +"id": 5
          +"attendance_date": "2023-08-25"
          +"time": "10:00:00"
          +"status": "arrival"
        }
        1 => {#1577 ▼
          +"id": 6
          +"attendance_date": "2023-08-25"
          +"time": "18:00:00"
          +"status": "departure"
        }
      ]
    ]
    

  2. It is not explained in the question which two entries form attendance pairs. Only the comments ‘Group 1’ etc. give a hint. So my assumption is that they are to be grouped in pairs as they are appearing in the array (hence the use of array_chunk):

    $attendances = [
      [
        'id'              => 1,
        'attendance_date' => '2023-08-24',
        'time'            => '11:00:00',
        'status'          => 'arrival'
      ],
      [
        'id'              => 2,
        'attendance_date' => '2023-08-24',
        'time'            => '14:00:00',
        'status'          => 'departure'
      ],
      [
        'id'              => 3,
        'attendance_date' => '2023-08-24',
        'time'            => '22:00:00',
        'status'          => 'arrival'
      ],
      [
        'id'              => 4,
        'attendance_date' => '2023-08-25',
        'time'            => '06:00:00',
        'status'          => 'departure'
      ],
      [
        'id'              => 5,
        'attendance_date' => '2023-08-25',
        'time'            => '10:00:00',
        'status'          => 'arrival'
      ],
      [
        'id'              => 6,
        'attendance_date' => '2023-08-25',
        'time'            => '18:00:00',
        'status'          => 'departure'
      ]
    ];
    
    $result = [];
    
    foreach (array_chunk($attendances, 2) as $item) {
      if ($item[0]['attendance_date'] === $item[1]['attendance_date']) {
        $result[$item[0]['attendance_date']][] = $item;
      } else {
        $result[$item[0]['attendance_date']][] = [
          $item[0],
          [
            'id'              => $item[0]['id'],
            'attendance_date' => $item[0]['attendance_date'],
            'time'            => '23:59:59',
            'status'          => 'end of day'
          ],
        ];
        $result[$item[1]['attendance_date']][] = [
          [
            'id'              => $item[1]['id'],
            'attendance_date' => $item[1]['attendance_date'],
            'time'            => '00:00:00',
            'status'          => 'start of day'
          ],
          $item[1]
        ];
      }
    }
    
    print_r($result);
    

    Output:

    Array
    (
        [2023-08-24] => Array
            (
                [0] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [attendance_date] => 2023-08-24
                                [time] => 11:00:00
                                [status] => arrival
                            )
    
                        [1] => Array
                            (
                                [id] => 2
                                [attendance_date] => 2023-08-24
                                [time] => 14:00:00
                                [status] => departure
                            )
    
                    )
    
                [1] => Array
                    (
                        [0] => Array
                            (
                                [id] => 3
                                [attendance_date] => 2023-08-24
                                [time] => 22:00:00
                                [status] => arrival
                            )
    
                        [1] => Array
                            (
                                [id] => 3
                                [attendance_date] => 2023-08-24
                                [time] => 23:59:59
                                [status] => end of day
                            )
    
                    )
    
            )
    
        [2023-08-25] => Array
            (
                [0] => Array
                    (
                        [0] => Array
                            (
                                [id] => 4
                                [attendance_date] => 2023-08-25
                                [time] => 00:00:00
                                [status] => start of day
                            )
    
                        [1] => Array
                            (
                                [id] => 4
                                [attendance_date] => 2023-08-25
                                [time] => 06:00:00
                                [status] => departure
                            )
    
                    )
    
                [1] => Array
                    (
                        [0] => Array
                            (
                                [id] => 5
                                [attendance_date] => 2023-08-25
                                [time] => 10:00:00
                                [status] => arrival
                            )
    
                        [1] => Array
                            (
                                [id] => 6
                                [attendance_date] => 2023-08-25
                                [time] => 18:00:00
                                [status] => departure
                            )
    
                    )
    
            )
    
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search