Ver Fonte

absence_report - fix + performance

ferrari há 1 mês atrás
pai
commit
04a1e0382e
1 ficheiros alterados com 78 adições e 49 exclusões
  1. 78 49
      app/Http/Livewire/AbsenceReport.php

+ 78 - 49
app/Http/Livewire/AbsenceReport.php

@@ -10,7 +10,7 @@ class AbsenceReport extends Component
 
 
     public $records;
     public $records;
     public $record_assenze;
     public $record_assenze;
-    
+
     public $fiscalStartMonth = 9;
     public $fiscalStartMonth = 9;
     public $year;
     public $year;
 
 
@@ -22,7 +22,7 @@ class AbsenceReport extends Component
     public function render()
     public function render()
     {
     {
         setlocale(LC_ALL, 'it_IT');
         setlocale(LC_ALL, 'it_IT');
-        
+
         $this->record_assenze = [];
         $this->record_assenze = [];
 
 
         $today = now();
         $today = now();
@@ -39,61 +39,88 @@ class AbsenceReport extends Component
         ];
         ];
 
 
         try {
         try {
-            $courses = \App\Models\Course::whereDate('date_from', '<=', now())->whereDate('date_to', '>=', now())->where('active', true)->where('enabled', true)->get();
+            $courses = \App\Models\Course::whereDate('date_from', '<=', now())
+                ->whereDate('date_to', '>=', now())
+                ->where('active', true)
+                ->where('enabled', true)
+                ->get();
+
+            $limit = now()->endOfDay();
+
             foreach ($courses as $course) {
             foreach ($courses as $course) {
-                $course_members = \App\Models\MemberCourse::where('course_id', $course->id)->get();
+                $course_members = \App\Models\MemberCourse::with('member')->where('course_id', $course->id)->where('is_archived', false)->where('is_deleted', false)->get();
+
+                $courseCalendars = \App\Models\Calendar::where('course_id', $course->id)->where('from', '<=', $limit)->get();
+
+                $calendarIndex = [];
+                foreach ($courseCalendars as $cal) {
+                    $key = $cal->from . '|' . $cal->to;
+                    $calendarIndex[$key] = $cal;
+                }
+
+                $memberIds = $course_members->pluck('member_id')->unique()->values();
+
+                $presences = \App\Models\Presence::whereIn('calendar_id', $courseCalendars->pluck('id'))->whereIn('member_id', $memberIds)->get();
+
+                $presenceIndex = [];
+                foreach ($presences as $p) {
+                    $presenceIndex[$p->member_id . '|' . $p->calendar_id] = true;
+                }
+
                 $this->record_assenze[$course->id] = [
                 $this->record_assenze[$course->id] = [
                     'course' => $course,
                     'course' => $course,
-                    'members' => []
+                    'members' => [],
                 ];
                 ];
 
 
                 foreach ($course_members as $course_member) {
                 foreach ($course_members as $course_member) {
-                    $calendars_query = \App\Models\Calendar::where('course_id', $course->id);
+                    $this->record_assenze[$course->id]['members'][$course_member->id] = [
+                        'member' => $course_member->member,
+                        'count'  => 0,
+                        'dates'  => [],
+                    ];
 
 
-                    $calendars_query->where(function ($c_query) use ($course_member, $dayMap) {
-                        $months = array_column(array_filter(json_decode($course_member->months, true), function ($month) {
-                            return $month['status'] != 2;
-                        }), "m");
-                        sort($months);
+                    $months = array_column(
+                        array_filter(json_decode($course_member->months, true), fn($m) => $m['status'] != 2),
+                        'm'
+                    );
+                    sort($months);
 
 
-                        $when = json_decode($course_member->when, true);
-                        foreach ($when as $period) {
-                            $days = $period['day'];
+                    $when = json_decode($course_member->when, true);
 
 
-                            if ($days) {
-                                $from = $period['from'];
-                                $to = $period['to'];
+                    $memberCalendars = [];
 
 
-                                $ranges = $this->generateFiscalDateRanges($months, $days, $dayMap, $from, $to);
+                    foreach ($when as $period) {
+                        $days = $period['day'];
 
 
-                                foreach ($ranges as $range) {
-                                    $date_from = $range['from'];
-                                    $date_to   = $range['to'];
+                        if (!$days) {
+                            continue;
+                        }
 
 
-                                    $c_query->orWhere(function ($query) use ($date_from, $date_to) {
-                                        $query->where('from', $date_from)
-                                            ->where('to',   $date_to);
-                                    });
-                                }
+                        $fromTime = $period['from'];
+                        $toTime   = $period['to'];
+
+                        $ranges = $this->generateFiscalDateRanges($months, $days, $dayMap, $fromTime, $toTime);
+
+                        foreach ($ranges as $range) {
+                            $key = $range['from']->toDateTimeString() . '|' . $range['to']->toDateTimeString();
+
+                            if (isset($calendarIndex[$key])) {
+                                $memberCalendars[] = $calendarIndex[$key];
                             }
                             }
                         }
                         }
-                    });
-                    $calendars_query->orderBy('to', 'desc');
-                    $calendars = $calendars_query->get();
+                    }
 
 
-                    $this->record_assenze[$course->id]['members'][$course_member->id] = [
-                        'member' => $course_member->member,
-                        'count' => 0,
-                        'dates' => []
-                    ];
-                    foreach ($calendars as $calendar) {
-                        $presence_query = \App\Models\Presence::where('calendar_id', $calendar->id)->where('member_id', $course_member->member_id);
-                        $presence = $presence_query->first();
+                    usort($memberCalendars, fn($a, $b) => $b->to <=> $a->to);
 
 
-                        if (!$presence) {
+                    foreach ($memberCalendars as $calendar) {
+                        $pKey = $course_member->member_id . '|' . $calendar->id;
+
+                        $hasPresence = isset($presenceIndex[$pKey]);
+
+                        if (!$hasPresence) {
                             $this->record_assenze[$course->id]['members'][$course_member->id]['count']++;
                             $this->record_assenze[$course->id]['members'][$course_member->id]['count']++;
                             $this->record_assenze[$course->id]['members'][$course_member->id]['dates'][] = [
                             $this->record_assenze[$course->id]['members'][$course_member->id]['dates'][] = [
-                                'calendar_id' => $calendar->id, 
+                                'calendar_id' => $calendar->id,
                                 'date' => Carbon::parse($calendar->from)->translatedFormat('d/m'),
                                 'date' => Carbon::parse($calendar->from)->translatedFormat('d/m'),
                             ];
                             ];
                         } else {
                         } else {
@@ -109,16 +136,20 @@ class AbsenceReport extends Component
                 if (empty($this->record_assenze[$course->id]['members'])) {
                 if (empty($this->record_assenze[$course->id]['members'])) {
                     unset($this->record_assenze[$course->id]);
                     unset($this->record_assenze[$course->id]);
                 } else {
                 } else {
-                    usort($this->record_assenze[$course->id]['members'], function($a, $b) {
-                        $result = $a['count'] < $b['count'];
-                        if ($a['count'] == $b['count']) {
-                            $result = strcmp($a['member']->last_name, $b['member']->last_name);
-                            if ($result == 0) {
-                                $result = strcmp($a['member']->first_name, $b['member']->first_name);
-                            }
+                    $members = $this->record_assenze[$course->id]['members'];
+                    usort($members, function ($a, $b) {
+                        if ($a['count'] !== $b['count']) {
+                            return $b['count'] <=> $a['count'];
                         }
                         }
-                        return $result;
+
+                        $last = strcmp($a['member']->last_name, $b['member']->last_name);
+                        if ($last !== 0) {
+                            return $last;
+                        }
+
+                        return strcmp($a['member']->first_name, $b['member']->first_name);
                     });
                     });
+                    $this->record_assenze[$course->id]['members'] = $members;
                 }
                 }
             }
             }
         } catch (\Throwable $e) {
         } catch (\Throwable $e) {
@@ -204,8 +235,6 @@ class AbsenceReport extends Component
             ->unique()
             ->unique()
             ->values();
             ->values();
 
 
-        sort($months);
-
         $fromCarbon = Carbon::parse($fromTime);
         $fromCarbon = Carbon::parse($fromTime);
         $toCarbon = Carbon::parse($toTime);
         $toCarbon = Carbon::parse($toTime);