Search code examples
phparrayslaravellaravel-bladelaravel-collection

Is there any way to loop 2 foreach and one for loop together?


I am working on Laravel 8 project where i shall create Human Resources Management System, so i struggle now with reporting of employees attendance. I have 2 model User.php and Attendance.php also 2 controllers and relation between the models.

public function attendances()
{
    return $this->hasMany(Attendance::class, 'user_id');
}

This is coming from my AttendanceController.php

public function index()
{
    return view('frontend.attendances.index', [
        'employees' => $this->userRepository->getAllUsers()
            ->with(['attendances' => function($query) {
                $query->where('company_id', Auth::user()->company_id);
            }])
            ->get()
    ]);
}

So now i have to display table with all dates in current month and to show does each user were present on work or not. I have this is my summary.blade.php

@foreach($employees as $employee)
    <tr>
        <td>
            <img class="img-fluid rounded-circle mr-2" width="30" height="30" src="{{ $employee->image ? $employee->image : asset('assets/images/user.jpg') }}" alt="{{ $employee->firstname }}" data-original-title="{{ $employee->firstname }}">
            {{ $employee->name() }}
        </td>
        @php($count=0)
        @for($i=1; Carbon\Carbon::now()->daysInMonth >= $i; $i++)
            @foreach($employee->attendances as $attendance)
                @if($i == Carbon\Carbon::createFromFormat('Y-m-d H:m:s', $attendance->check_in)->isoFormat('D'))
                    <td class="text-center"><i class="fa fa-check text-success"></i></td>
                    @php($count++)
                @else
                    <td class="text-center"><i class="fa fa-times text-danger"></i></td>
                @endif
            @endforeach
        @endfor
        <td class="text-success text-center">{{ $count }} / {{ Carbon\Carbon::now()->daysInMonth }}</td>
    </tr>
@endforeach

This is not the way how it should work, but i have tried it in many ways and still cannot find some proper way. Here is picture what i am trying to achieve, and what i have with my code Picture of the final result

My result


Solution

  • How about something like this: loop through the dates and filter attendance for the employee based on the date.

    //First, create a date period. 
    
    //use Carbon\Carbon; use Carbon\CarbonPeriod;
    $daysOfThisMonth = CarbonPeriod::create(Carbon::now()->startOfMonth(),  Carbon::now()->endOfMonth());
     
    //Loop through the days 
    foreach($daysOfThisMonth as $day){
     //firstWhere will return one row if day exists in check_in field (equivalent to true), otherwise will return nothing, which will be equivalent to a false.
     if( $employee->attendance->firstWhere('check_in', $day ) ) //formatthe dates according to your preference
       echo "attended - print tick";
     else
       echo "not attended - print x";
    }