Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 140
MonthlyNotifications
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
1980
0.00% covered (danger)
0.00%
0 / 140
 __construct
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 handle
0.00% covered (danger)
0.00%
0 / 1
1482
0.00% covered (danger)
0.00%
0 / 122
 isLeave
0.00% covered (danger)
0.00%
0 / 1
30
0.00% covered (danger)
0.00%
0 / 16
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Leave\LeaveEntitlement;
use Carbon\Carbon;
use App\Models\Auth\User;
use DB;
use App\Notifications\AppNotifications;
use App\Models\Admin\Holiday;
use Carbon\CarbonPeriod;
use App\Models\Leave\ApplyLeave;
use App\Models\Auth\UserWeeklyOff;
use App\Helpers\HolidayHelper;
class MonthlyNotifications extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'monthly:notifications';
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Monthly notofications for leave and attendance';
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $users = User::all();
        $month = Carbon::now(config('settings.time_zone'))->format('M');
        //if current month is january, get previous year
        if($month == 'Jan'){
            $year = Carbon::now(config('settings.time_zone'))->subYear()->year;
        }else{
            $year = Carbon::now(config('settings.time_zone'))->year;
        }
        
        foreach ($users as $key => $user) {
            if (!empty($user->userdetail)) {
                //get all leaves
                $leaves = DB::table('leaves')->get();
                $leaveBal = [];
                foreach ($leaves as $leave) {
                    //get leave balance for each leave
                    $query = LeaveEntitlement::query();
                    $query->where('user_id', '=', $user->id);
                    $query->where('year', '=', $year);
                    $query->where('leave_id', '=', $leave->id);
                    $leaveEntitlementArr = $query->get();
                    $leaveBalance = null;
                    foreach ($leaveEntitlementArr as $leaveEntitlement) {
                        $leaveBalance = $leaveEntitlement->leave_balance; //leave balance
                    }
                    if ($leaveBalance == null) {
                        $leaveBalance = '0';
                    }
                    $leaveBal[$leave->id] =  $leaveBalance;
                }
                //notification to user 
                $title = "Monthly Leave Balance";
                $month = Carbon::now(config('settings.time_zone'))->subMonth()->format('M');
                $message = "Your leave balance until " . $month . " is " . $leaveBal[1] . " Casual and " . $leaveBal[2] . " Sick leaves";
                $actionUrl = null;
                $arr = null;
                $arr = [$title, $message, $actionUrl];
                //notify to user
                $user->notify(new AppNotifications($arr));
               
            }
            //monthly attendance report notification
            $month = Carbon::now(config('settings.time_zone'))->subMonth()->format('m-Y');
            $startDate = Carbon::parse('01-' . $month);
            $startDate = $startDate->format('Y-m-d');
            $endDate =  Carbon::parse('01-' . $month)->endOfMonth()->format('Y-m-d');
            $endDateForQuery =  Carbon::parse('01-' . $month)->addMonth()->format('Y-m-d');
            //start date and end date for query
            $selectedDateWithTimezone = Carbon::parse($startDate.'000000', config('settings.time_zone'))->setTimezone(config('app.time_zone'));
            $selectedEndDateWithTimezone = Carbon::parse($endDateForQuery.'000000', config('settings.time_zone'))->setTimezone(config('app.time_zone'));
       
            
            // $attendanceReport = DB::select('select us.id,us.name,us.lastName,t.team,a.check_in as check_in,
            //                             a.check_out as check_out
            //                             from users us
            //                             join user_details u on us.id = u.user_id
            //                             join team_user_detail tsd on  tsd.user_detail_id = u.id
            //                             join teams t on t.id = tsd.team_id
            //                             left join attendance_details a on a.user_id = u.user_id
            //                             where ((a.check_in between :startDate1 and :endDate1)) and 
            //                             us.id = ('.$user->id.') order by us.id,a.id',
            //                             ['startDate1' => $selectedDateWithTimezone, 'endDate1' => $selectedEndDateWithTimezone]
            //                             );
            $attendanceReport = DB::select('select us.id,us.name,us.lastName,t.team,a.check_in as check_in,
                                        a.check_out as check_out
                                        from users us
                                        join user_details u on us.id = u.user_id
                                        join teams t on t.id = u.primary_team_id
                                        left join attendance_details a on a.user_id = u.user_id
                                        where ((a.check_in between :startDate1 and :endDate1)) and 
                                        us.id = ('.$user->id.') order by us.id,a.id',
                                        ['startDate1' => $selectedDateWithTimezone, 'endDate1' => $selectedEndDateWithTimezone]
                                        );
            
            $allDates = CarbonPeriod::create($startDate, $endDate);
            
            $count = 0;
            $attendanceReportColl = collect($attendanceReport);
            $attendanceReportCollOfColl = collect([]);
            $attendanceUserColl = collect([]);
           
            foreach ($attendanceReportColl as $attendance) {
                if ($count == 0) {
                    $currenUserId = $attendance->id;
                    $count = $count + 1;
                }
                if ($currenUserId ==  $attendance->id) {
                    $attendanceUserColl->push($attendance);
                } else {
                    $attendanceReportCollOfColl->push($attendanceUserColl);
                    $attendanceUserColl = collect([]);
                    $attendanceUserColl->push($attendance);
                    $count = 0;
                }
            }
            if ($attendanceUserColl->count() != 0) {
                $attendanceReportCollOfColl->push($attendanceUserColl);
                $attendanceUserColl = collect([]);
            }
            $count = 0;
            $present = 0;
            $leave = 0;
            $absent = 0;
            
            
            foreach ($attendanceReportCollOfColl as $attendanceUserColl) {
               
                $user = User::find($attendanceUserColl->pluck('id')->first());
               
                
                $currentDate = Carbon::now(config('settings.time_zone'))->toDateString();
                $working_days = 0;
                foreach ($allDates as $allDate) {
                    $date = Carbon::parse($allDate)->format('Y-m-d');
                    
                    //start date and end date for weekly off                     
                    $startDateForWeeklyOff = Carbon::parse($date.'00:00:00', config('settings.time_zone'))->setTimezone(config('app.time_zone'));
                    $endDateForWeeklyOff = Carbon::parse(Carbon::parse($date)->addDay()->toDateString().'00:00:00', config('settings.time_zone'))->setTimezone(config('app.time_zone'));
                    //get holidays
                    $holidayIds = HolidayHelper::getholidayList($user->id);
                    $holiday = Holiday::where('date', $date)->whereIn('id', $holidayIds)->first();
                    //get user wekends
                    $userWeeklyOff = UserWeeklyOff::where('user_id',$user->id)
                                                ->whereBetween('created_at', [$startDateForWeeklyOff, $endDateForWeeklyOff])
                                                ->where('weekly_off',1)->first();
                    //check user is not on weekend and holiday
                    if (empty($userWeeklyOff) && empty($holiday)) {
                        $working_days = $working_days + 1; //working days
                    }    
                    foreach($attendanceUserColl as $value){
                        if(isset($value->check_in)){
                            $value->check_in = Carbon::parse($value->check_in)->setTimezone(config('settings.time_zone'))->toDateString();
                        }
                        if(isset($value->check_out)){
                            $value->check_out = Carbon::parse($value->check_out)->setTimezone(config('settings.time_zone'))->toDateString();
    
                        }
                    }
                    if ($attendanceUserColl->contains('check_in', $date)) {
                        $plucked = $attendanceUserColl->where('check_in', '==', $date);
                        $isLeave = $this->isLeave($plucked->pluck('id'), $date);
    
                        //if check out is not null
                        if ($plucked->pluck('check_out')->first() != '') {
                            if (!empty($isLeave)) {
                                if (empty($userWeeklyOff) && empty($holiday)) {
                                    if ($isLeave['leave_type'] == 'L') { // if leave is full day
                                        $leave = $leave + 1;
                                    } else {
                                        $leave = $leave + 0.5; //half day leave
                                        $present = $present + 0.5;
                                    }
                                    
                                }
                            }else {
                           
                            $present = $present + 1;
                            }
                        } else {
                            if (!empty($isLeave)) {
                                if (empty($userWeeklyOff) && empty($holiday)) {
                                    if ($isLeave['leave_type'] == 'L') {
                                        $leave = $leave + 1;
                                    } else {
                                        $leave = $leave + 0.5;
                                        $present = $present + 0.5;
                                    }
                                    
                                }
                            }else{
                                if($currentDate > $date){
                                if (empty($userWeeklyOff) && empty($holiday)) {
                                   
                                    $absent = $absent + 1;
                                    }
    
    
                                }
    
                            }
    
                        }
                    } else {
                        
                        if($currentDate > $date){
                            $isLeave = $this->isLeave($attendanceUserColl->pluck('id')->first(), $date);
    
                        if (!empty($isLeave)) {
                            if (empty($userWeeklyOff) && empty($holiday)) {
                                if ($isLeave['leave_type'] == 'L') {
                                $leave = $leave + 1;
                                } else {
                                    $leave = $leave + 0.5;
                                    $present = $present + 0.5;
                                }
                                
                            }
                        }else{
                            if (empty($userWeeklyOff) && empty($holiday)) {
                           
                            $absent = $absent + 1;
                            }
                        }
                        }
    
                    }
                }
                // notification to user 
                $title = "Monthly Attendance";
                $month = Carbon::now(config('settings.time_zone'))->subMonth()->format('M Y');
                $message = "You have marked attendance for ".$present." days out of ".$working_days." working days in ". $month;
                $actionUrl = null;
                $arr = null;
                $arr = [$title, $message, $actionUrl];
                
                //notify to user 
                $user->notify(new AppNotifications($arr));
                
                
                $count = 0;
                $present = 0;
                $leave = 0;
                $absent = 0;
            }
        }
    }
    public function isLeave($user_id, $date)
    {
        if ($user_id instanceof \Illuminate\Support\Collection) {
            $user_id = $user_id[0];
        }
        $userOnLeave = ApplyLeave::where('from_date', '<=', $date)
            ->where('to_date', '>=', $date)
            ->where('status', 'Approve')
            ->where('user_id','=', $user_id)
            ->first();
            
        $leave_details = [];
        if (!empty($userOnLeave)) {
            if ($userOnLeave->leave_type == 'full_day') {
                $type = 'L';
            } else {
                if ($userOnLeave->half_day_type == 'first_half') {
                    $type = 'L-FN';
                } else {
                    $type = 'L-AN';
                }
            }
            $leave_details['leave_type'] = $type;
        }
        return $leave_details;
    }
}