How can i count month wise present day in laravel?

All we need is an easy explanation of the problem, so here it is.

I have a column for months and years after choosing month and year it will give count of Total present days of employee which subtract leaves that employee took in that month.

here is my code of controller file

 public function employeeAttendance(Request $request)
    {
        $employeeName = User::all();
        $employeeLeave = LeaveManagement::all();

        $countMonth = $request->get('month');
        $countYear = $request->get('year');

        function countDays($year, $month, $ignore) 
        {
            $count = 0;
            $counter = mktime(0, 0, 0, $month, 1, $year);
            while (date("n", $counter) == $month) {
                if (in_array(date("w", $counter), $ignore) == false) 
                {
                    $count++;
                }
                $counter = strtotime("+1 day", $counter);
            }
            return $count;
        }

        $totalWorkingDays = countDays($countYear, $countMonth, array(0, 6));

        return view('pages.attendance', compact('employeeName', 'totalWorkingDays', 'employeeLeave', 'countMonth', 'countYear'));
    }

And Here is my code of view file

<div class="col-md-5 align-self-center">
                    <h4 class="text-themecolor">{{__('Employee Attendance')}}</h4>
                </div>
            </div>

            <div class="card">
                <div class="card-body">
                <form action="{{ route('employee_attendance') }}" method="GET">
                    <select class="custom-select col-md-2" name="month">
                        <option value="">Select Month</option>
                        <option value="01">January</option>
                        <option value="02">February</option>
                        <option value="03">March</option>
                        <option value="04">April</option>
                        <option value="05">May</option>
                        <option value="06">June</option>
                        <option value="07">July</option>
                        <option value="08">August</option>
                        <option value="09">September</option>
                        <option value="10">October</option>
                        <option value="11">November</option>
                        <option value="12">December</option>
                    </select>
                    <select class="custom-select col-md-2" name="year">
                        <option value="">Select Year</option>
                        <?php
                          for ($year = 2000; $year <= 2050; $year++) 
                          {
                            $selected = (isset($getYear) && $getYear == $year) ? 'selected' : '';
                            echo "<option value=$year $selected>$year</option>";
                          }
                        ?>
                    </select>
                    <button class="btn btn-info" type="submit"><i class="fa fa-search "></i></button>

                    <span style="float:right" class = "btn btn-info" disabled>Total Working Days : {{ $totalWorkingDays }} </span>
                </form>

                    <div class="table-responsive m-t-40">
                        <table class="table table-bordered table-striped ">
                            <thead>
                                <tr>
                                    <th>Employee Name</th>
                                    <th>Present Day</th>
                                    <th>Casual Leave</th>
                                    <th>Medical Leave</th>
                                </tr>
                            </thead>
                            <tbody>

                                @foreach ($employeeName as $empName)
                                @php
                                    $casualCount = $medicalCount = 0;
                                @endphp
                                @foreach($employeeLeave as $empleave)
                                    @if($empName['personal_detail']['first_name'] == $empleave->name)
                                            @if($empleave->type == 'casual')
                                                @php $casualCount++; @endphp
                                            @endif

                                            @if($empleave->type == 'medical')
                                                @php $medicalCount++; @endphp
                                            @endif
                                    @endif
                                @endforeach

                                    @if($empName['username'] != 'admin')
                                        <tr>
                                            <td>
                                                {{$empName['personal_detail']['first_name']}}
                                            </td>
                                            <td>
                                            @if($totalWorkingDays == 0)
                                                {{ $totalWorkingDays }}
                                            @else
                                                @php 
                                                    $totalLeave = $casualCount + $medicalCount;
                                                    $presentDay = $totalWorkingDays - $totalLeave;
                                                @endphp
                                                {{ $presentDay }}
                                            @endif
                                            </td>
                                            <td>
                                                @if( $totalWorkingDays == 0 )
                                                    {{ $totalWorkingDays }}
                                                @elseif( $countMonth ==  date('m', strtotime($empleave->start)) && $countYear ==  date('Y', strtotime($empleave->start))) 
                                                        {{ $casualCount }}
                                                @endif
                                            </td>

                                            <td>
                                                @if( $totalWorkingDays == 0 )
                                                    {{ $totalWorkingDays }}
                                                @elseif( $countMonth ==  date('m', strtotime($empleave->start)) && $countYear ==  date('Y', strtotime($empleave->start))) 
                                                    {{ $medicalCount }}
                                                @endif
                                            </td>
                                        </tr>
                                    @endif
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>

I want that If I select March 2019 than it will give me all the employees name their present days in that month and if they took any medical or casual leave in that month than it will subtract from it in present day column

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

This is your controller function

public function employeeAttendance(Request $request)
{
    $employeeName = User::all();
    $countMonth   = (!empty($request->get('month')) ? intval($request->get('month')) : 0);
    $countYear    = (!empty($request->get('year')) ? intval($request->get('year')) : 0);
    $firstDay     = new DateTime(date('F jS Y h:i:s A', strtotime('first day of ' . date('Y-m', strtotime("$countYear-$countYear")))));
    $lastDay      = new DateTime(date('F jS Y h:i:s A', strtotime('last day of ' . date('Y-m', strtotime("$countYear-$countYear")))));

    $employeeLeave = LeaveManagement::where('yourdatefield', '>=', $firstDay)
        ->where('yourdatefield', '<=', $lastDay)->get();
    $totalWorkingDays = 0;
    if (!empty($countMonth && $countYear)) {
        $totalWorkingDays = $this->countDays($countYear, $countMonth, array(0, 6));
    }
    $result = [];
    foreach ($employeeLeave as $empleave) {
        if ($empleave->type == 'casual') {
            $result[$empleave->name]['casual'][] = $empleave;
        }
        if ($empleave->type == 'medical') {
            $result[$empleave->name]['medical'][] = $empleave;
        }
    }
    return view('pages.attendance', compact('employeeName', 'totalWorkingDays', 'employeeLeave','result'));
}



public function countDays($year, $month, $ignore)
{
    $count   = 0;
    $counter = mktime(0, 0, 0, $month, 1, $year);
    while (date("n", $counter) == $month) {
        if (!in_array(date("w", $counter), $ignore)) {
            $count++;
        }
        $counter = strtotime("+1 day", $counter);
    }
    return $count;
}

I have changed forloop a little bit

for ($year = 2000; $year <= 2050; $year++) {
    $selected = (isset($getYear) && $getYear == $year) ? 'selected' : '';
    echo "<option value='$year' $selected>$year</option>";
}

Rest everything is taken care in previous question, check if it works.

EDIT

Create result array after fetching data for $employeeLeave

$result = [];
foreach ($employeeLeave as $empleave) {
    if ($empleave->type == 'casual') {
        $result[$empleave->name]['casual'][] = $empleave;
    }
    if ($empleave->type == 'medical') {
        $result[$empleave->name]['medical'][] = $empleave;
    }
}

send $result to blade.

Change your html table structure as below,

<table class="table table-bordered table-striped ">
    <thead>
        <tr>
            <th>Employee Name</th>
            <th>Present Day</th>
            <th>Casual Leave</th>
            <th>Medical Leave</th>
        </tr>
    </thead>
    <tbody>
        @foreach($result as $empname => $empleave)
            <tr>
                <td>{{ $empname }}</td>
                <td>{{ $totalWorkingDays }}</td>
                <td>{{ count($result[$empname]['casual']) }}</td>
                <td>{{ count($result[$empname]['medical']) }}</td>

            </tr>    
        @endforeach
    </tbody>
</table>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply