Bladeren bron

presence_report - modificata logica per motivation_course_id

ferrari 1 maand geleden
bovenliggende
commit
a1b537ab8a
2 gewijzigde bestanden met toevoegingen van 192 en 233 verwijderingen
  1. 179 225
      app/Http/Livewire/PresenceReport.php
  2. 13 8
      resources/views/livewire/presence_report.blade.php

+ 179 - 225
app/Http/Livewire/PresenceReport.php

@@ -3,35 +3,18 @@
 namespace App\Http\Livewire;
 
 use Livewire\Component;
+use Illuminate\Support\Carbon;
 
 class PresenceReport extends Component
 {
-
-    public $calendar;
-
-    public $records;
-
+    public $records = [];
     public $date;
 
-    public $member_ids = [];
-
-
     public $courses = [];
     public $courts = [];
     public $instructors = [];
     public $motivations = [];
 
-    public $court_filter;
-    public $instructor_filter;
-    public $motivation_filter;
-
-
-    public $members = [];
-
-    public $newMembers = [];
-
-    public $ids = [];
-
     public $course_name;
     public $from;
     public $to;
@@ -44,14 +27,14 @@ class PresenceReport extends Component
 
     public function mount()
     {
-        $this->courts = \App\Models\Court::select('*')->where('enabled', true)->get();
-        $this->instructors = \App\Models\User::select('*')->where('level', 2)->where('enabled', true)->orderBy('name', 'asc')->get();
-        $this->motivations = \App\Models\Motivation::select('*')->where('enabled', true)->where('type', 'del')->get();
+        $this->courts = \App\Models\Court::where('enabled', true)->orderBy('name')->get();
+        $this->instructors = \App\Models\User::where('level', 2)->where('enabled', true)->orderBy('name')->get();
+        $this->motivations = \App\Models\Motivation::where('enabled', true)->where('type', 'del')->orderBy('name')->get();
 
         $this->from = "00:00:00";
         $this->to = "23:59:59";
-
         $this->date = date("Y-m-d");
+
         setlocale(LC_ALL, 'it_IT');
     }
 
@@ -60,254 +43,225 @@ class PresenceReport extends Component
         setlocale(LC_ALL, 'it_IT');
 
         $this->records = [];
-        $this->courses = [];
-
-        $from = $this->date . " " . $this->from;
-        $to = $this->date . " " . $this->to;
-
-        $calendars = \App\Models\Calendar::where('from', '>=', $from)->where('from', '<=', $to)->orderBy('from')->get();
 
-        if (!is_null($this->court_id) && $this->court_id > 0)
-            $this->court_name = \App\Models\Court::findOrFail($this->court_id)->name;
-        else
-            $this->court_name = '';
+        $fromDt = Carbon::parse($this->date . ' ' . ($this->from ?: '00:00:00'));
+        $toDt = Carbon::parse($this->date . ' ' . ($this->to ?: '23:59:59'));
 
-        if (!is_null($this->instructor_id) && $this->instructor_id > 0)
-            $this->instructor_name = \App\Models\User::findOrFail($this->instructor_id)->name;
-        else
-            $this->instructor_name = '';
+        $this->court_name = '';
+        if (!empty($this->court_id)) {
+            $court = $this->courts->firstWhere('id', (int)$this->court_id);
+            $this->court_name = $court?->name ?? '';
+        }
 
-        foreach ($calendars as $calendar) {
+        $this->instructor_name = '';
+        if (!empty($this->instructor_id)) {
+            $instr = $this->instructors->firstWhere('id', (int)$this->instructor_id);
+            $this->instructor_name = $instr?->name ?? '';
+        }
 
-            $presences = \App\Models\Presence::where('calendar_id', $calendar->id)->where('status', '<>', 99);
-            $presences_annullate = \App\Models\Presence::where('calendar_id', $calendar->id)->where('status', 99);
-            
-            // filtra per campo court_id
-            if (!is_null($this->court_id) && $this->court_id > 0) {
-                $presences->where('court_id', $this->court_id);
-                $presences_annullate->where('court_id', $this->court_id);
-            }
+        $calendars = \App\Models\Calendar::with(['course.level'])
+            ->whereBetween('from', [$fromDt->toDateTimeString(), $toDt->toDateTimeString()])
+            ->orderBy('from')
+            ->get();
 
-            // filtra per campo istructor_id/user_id
-            if (!is_null($this->instructor_id) && $this->instructor_id > 0) {
-                $presences->where(function ($query) {
-                    $query->where('instructor_id', $this->instructor_id)
-                        ->orWhere('user_id', $this->instructor_id);
-                });
-                $presences_annullate->where(function ($query) {
-                    $query->where('instructor_id', $this->instructor_id)
-                        ->orWhere('user_id', $this->instructor_id);
-                });
-            }
+        if ($calendars->isEmpty()) {
+            $this->courses = \App\Models\Calendar::orderBy('name')->groupBy('name')->pluck('name')->toArray();
+            return view('livewire.presence_report');
+        }
 
-            // filtra per campo search (nome/cognome)
-            if (!is_null($this->search) && $this->search != "") {
-                $search_value = $this->search;
-                $presences->whereHas('member', function ($q) use ($search_value) {
-                    $q->where(function ($qq) use ($search_value) {
-                        $qq->whereRaw("CONCAT(TRIM(first_name), ' ', TRIM(last_name)) LIKE ?", ["%{$search_value}%"])
-                        ->orWhereRaw("CONCAT(TRIM(last_name), ' ', TRIM(first_name)) LIKE ?", ["%{$search_value}%"]);
-                    });
+        $calendarIds = $calendars->pluck('id')->all();
+
+        $presencesAll = \App\Models\Presence::with([
+            'member:id,first_name,last_name',
+            'court:id,name',
+            'user:id,name',
+            'instructor:id,name',
+            'motivation:id,name',
+            'motivationCourse:id,name',
+        ])
+            ->whereIn('calendar_id', $calendarIds)
+            ->when(!empty($this->court_id), fn($q) => $q->where('court_id', (int)$this->court_id))
+            ->when(!empty($this->instructor_id), function ($q) {
+                $iid = (int)$this->instructor_id;
+                $q->where(function ($qq) use ($iid) {
+                    $qq->where('instructor_id', $iid)->orWhere('user_id', $iid);
                 });
-                $presences_annullate->whereHas('member', function ($q) use ($search_value) {
-                    $q->where(function ($qq) use ($search_value) {
-                        $qq->whereRaw("CONCAT(TRIM(first_name), ' ', TRIM(last_name)) LIKE ?", ["%{$search_value}%"])
-                        ->orWhereRaw("CONCAT(TRIM(last_name), ' ', TRIM(first_name)) LIKE ?", ["%{$search_value}%"]);
+            })
+            ->when(!empty($this->search), function ($q) {
+                $s = trim($this->search);
+                $q->whereHas('member', function ($mq) use ($s) {
+                    $mq->where(function ($qq) use ($s) {
+                        $qq->whereRaw("CONCAT(TRIM(first_name), ' ', TRIM(last_name)) LIKE ?", ["%{$s}%"])
+                            ->orWhereRaw("CONCAT(TRIM(last_name), ' ', TRIM(first_name)) LIKE ?", ["%{$s}%"]);
                     });
                 });
-            }
+            })
+            ->get();
 
-            $presences = $presences->pluck('member_id')->toArray();
-            $presences_annullate = $presences_annullate->pluck('member_id')->toArray();
+        $presenceByCalMember = [];
+        $presencesByCalendar = [];
 
-            $days = ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'];
-            $dow = date('w', strtotime($calendar->from));
-            $d = $days[$dow];
+        foreach ($presencesAll as $p) {
+            $presenceByCalMember[$p->calendar_id . '|' . $p->member_id] = $p;
+            $presencesByCalendar[$p->calendar_id][] = $p;
+        }
 
-            $h = date('H:i', strtotime($calendar->from));
+        $days = ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'];
 
-            // Elenco corsi per tipologia in base al calendario
-            $courses = \App\Models\Course::where('name', $calendar->name)->where('date_from', '<=', $calendar->from)->where('date_to', '>=', $calendar->to);
-            if (!is_null($this->course_name) && $this->course_name != "") {
-                $courses = $courses->where('name', $this->course_name);
+        foreach ($calendars as $calendar) {
+            $h = Carbon::parse($calendar->from)->format('H:i');
+            $dow = (int) Carbon::parse($calendar->from)->format('w'); // 0..6
+            $d = $days[$dow];
+            $month = (int) Carbon::parse($calendar->from)->format('n');
+
+            $courseIds = \App\Models\Course::query()
+                ->where('name', $calendar->name)
+                ->where('date_from', '<=', $calendar->from)
+                ->where('date_to', '>=', $calendar->to)
+                ->when(!empty($this->course_name), fn($q) => $q->where('name', $this->course_name))
+                ->pluck('id')
+                ->toArray();
+
+            if (empty($courseIds)) {
+                continue;
             }
-            $courses = $courses->pluck('id')->toArray();
-
-            $mids = [];
 
-            $months = date("n", strtotime($calendar->from));
-
-            // Elenco utenti iscritti al corso "padre"
-            $members = \App\Models\MemberCourse::where('when', 'like', "%" . $d . "%")
+            $membersQuery = \App\Models\MemberCourse::with(['member', 'course.level'])
+                ->whereIn('course_id', $courseIds)
+                ->where('when', 'like', "%{$d}%")
                 ->where('when', 'like', '%"from":"' . $h . '"%')
-                ->whereDate('date_from', '<=', $calendar->from)                                 
-                ->whereDate('date_to', '>=', $calendar->from)      
-                ->whereNot('months', 'like', '%"m":' . $months . ',"status":2%')
-                ->whereIn('course_id', $courses);
-                
-            if (!is_null($this->search) && $this->search != "") {
-                $search_value = $this->search;
-                $members->whereHas('member', function ($q) use ($search_value) {
-                    $q->where(function ($qq) use ($search_value) {
-                        $qq->whereRaw("CONCAT(TRIM(first_name), ' ', TRIM(last_name)) LIKE ?", ["%{$search_value}%"])
-                        ->orWhereRaw("CONCAT(TRIM(last_name), ' ', TRIM(first_name)) LIKE ?", ["%{$search_value}%"]);
+                ->whereDate('date_from', '<=', $calendar->from)
+                ->whereDate('date_to', '>=', $calendar->from)
+                ->whereNot('months', 'like', '%"m":' . $month . ',"status":2%');
+
+            if (!empty($this->search)) {
+                $s = trim($this->search);
+                $membersQuery->whereHas('member', function ($mq) use ($s) {
+                    $mq->where(function ($qq) use ($s) {
+                        $qq->whereRaw("CONCAT(TRIM(first_name), ' ', TRIM(last_name)) LIKE ?", ["%{$s}%"])
+                            ->orWhereRaw("CONCAT(TRIM(last_name), ' ', TRIM(first_name)) LIKE ?", ["%{$s}%"]);
                     });
                 });
             }
 
-            $members = $members->get();
+            $members = $membersQuery->get();
 
-            //$members = \App\Models\MemberCourse::where('when', 'like', "%" . $d . "%")->where('when', 'like', '%"from":"' . $h . '"%')->whereIn('member_id', $presences)->whereIn('course_id', $courses)->get();
-            foreach ($members as $member) {
+            $expectedMemberIds = [];
 
-                $court = '';
-                $instructor = '';
-                $motivation = '';
+            foreach ($members as $mc) {
+                $mid = $mc->member->id;
+                $expectedMemberIds[] = $mid;
 
-                $presence = \App\Models\Presence::where('member_id', $member->member->id)->where('calendar_id', $calendar->id)->first();
-                if ($presence) {
-                    $court = $presence->court ? $presence->court->name : "";
-                    $instructor = [
-                        $presence->user ? $presence->user->name : "",
-                        $presence->instuctor && $presence->instructor !== $presence->user ? $presence->instuctor->name : "",
-                    ];
-                    $instructor = implode(", ", array_filter($instructor));
-                    $motivation = $presence->motivation ? $presence->motivation->name : "";
-                }
+                $p = $presenceByCalMember[$calendar->id . '|' . $mid] ?? null;
 
-                $status = '';
-                if (in_array($member->member->id, $presences)) {
-                    $status = "<span class='fw-bold' style='color:#0c6197'>Presente</span>";
-                } else {
-                    if (in_array($member->member->id, $presences_annullate)) {
-                        $status = "<span class='fw-bold' style='color:gray'>Annullata</span>";
-                    } else {
-                        if (date("Ymd") > date("Ymd", strtotime($calendar->from))) {
-                            $status = "<span class='fw-bold' style='color:red'>Assente</span>";
-                        }
-                    }
+                [$court, $instructor, $motivation] = $this->presenceMeta($p);
+
+                $status = $this->presenceStatusHtml($p, $calendar);
+
+                $course_level = '';
+                if ($mc->course && $mc->course->level) {
+                    $course_level = trim($mc->course->level->name);
                 }
 
-                if ($calendar->status == 99) {
-                    $status = "<span class='fw-bold' style='color:gray'>Annullata</span>";
+                $this->records[$calendar->name][$h][] = [
+                    'course_level' => $course_level,
+                    'last_name' => $mc->member->last_name,
+                    'first_name' => $mc->member->first_name,
+                    'court' => $court,
+                    'instructor' => $instructor,
+                    'status' => $status,
+                    'motivation' => $motivation,
+                ];
+            }
+
+            $extras = $presencesByCalendar[$calendar->id] ?? [];
+
+            foreach ($extras as $p) {
+                if (in_array($p->member_id, $expectedMemberIds, true)) {
+                    continue;
                 }
 
-                $show = true;
-                if ($this->court_name != '')
-                    $show = $this->court_name == $court;
-                if ($show && $this->instructor_name != '')
-                    $show = $this->instructor_name == $instructor;
-
-                if ($show)
-                {
-                    $course_level = "";
-                    if ($member->course && $member->course->level) {
-                        $course_level = trim($member->course->level->name);
+                if (!empty($this->course_name)) {
+                    $motCourseName = $p->motivationCourse?->name;
+                    if (!$motCourseName || $motCourseName !== $this->course_name) {
+                        continue;
                     }
-                    $this->records[$calendar->name][$h][] = array(
-                        "course_level" => $course_level,
-                        "last_name" => $member->member->last_name,
-                        "first_name" => $member->member->first_name,
-                        "court" => $court,
-                        "instructor" => $instructor,
-                        "status" => $status,
-                        'motivation' => $motivation
-                    );
-
-                    $mids[] = $member->member->id;
                 }
-            }
 
-            $presences_recuperi = \App\Models\Presence::join('calendars', 'presences.calendar_id', '=', 'calendars.id')
-                ->join('courses', 'calendars.course_id', '=', 'courses.id')
-                ->where('calendar_id', $calendar->id)
-                ->whereNotIn('member_id', $mids);
-            if (!is_null($this->course_name) && $this->course_name != "") {
-                $presences_recuperi = $presences_recuperi->where('courses.name', $this->course_name);
-            }
-            if (!is_null($this->court_id) && $this->court_id > 0) {
-                $presences_recuperi->where('court_id', $this->court_id);
-            }
-            if (!is_null($this->instructor_id) && $this->instructor_id > 0) {
-                $presences_recuperi->where(function ($query) {
-                    $query->where('instructor_id', $this->instructor_id)
-                        ->orWhere('user_id', $this->instructor_id);
-                });
-            }
-            if (!is_null($this->search) && $this->search != "") {
-                $search_value = $this->search;
-                $presences_recuperi->whereHas('member', function ($q) use ($search_value) {
-                    $q->where(function ($qq) use ($search_value) {
-                        $qq->whereRaw("CONCAT(TRIM(first_name), ' ', TRIM(last_name)) LIKE ?", ["%{$search_value}%"])
-                        ->orWhereRaw("CONCAT(TRIM(last_name), ' ', TRIM(first_name)) LIKE ?", ["%{$search_value}%"]);
-                    });
-                });
-            }
-            $presences_recuperi = $presences_recuperi->get();
-            // dd($courses, $members, $presences_recuperi, $calendar->from, $calendar->to);
-            foreach ($presences_recuperi as $p) {
-                $court = $p->court ? $p->court->name : "";
-                $instructor = [
-                    $p->user ? $p->user->name : "",
-                    $p->instuctor && $p->instructor !== $p->user ? $p->instuctor->name : "",
-                ];
-                $instructor = implode(", ", array_filter($instructor));
-                $motivation = $p->motivation ? $p->motivation->name : "";
-                // $status = "<span class='fw-bold' style='color:gray'>Recupero</span>";
-                $status = "<span class='fw-bold' style='color:#0c6197'>Presente</span>";
-                
-                $course_level = "";
+                [$court, $instructor, $motivation] = $this->presenceMeta($p);
+                $status = $this->presenceStatusHtml($p, $calendar);
+
+                $course_level = '';
                 if ($calendar->course && $calendar->course->level) {
                     $course_level = trim($calendar->course->level->name);
                 }
-                $this->records[$calendar->name][$h][] = array(
-                    "course_level" => $course_level,
-                    "last_name" => $p->member->last_name,
-                    "first_name" => $p->member->first_name,
-                    "court" => $court,
-                    "instructor" => $instructor,
-                    "status" => $status,
-                    'motivation' => $motivation
-                );
+
+                $this->records[$calendar->name][$h][] = [
+                    'course_level' => $course_level,
+                    'last_name' => $p->member?->last_name ?? '',
+                    'first_name' => $p->member?->first_name ?? '',
+                    'court' => $court,
+                    'instructor' => $instructor,
+                    'status' => $status,
+                    'motivation' => $motivation,
+                ];
             }
 
-            /*
-            $calendar_recuperi = \App\Models\Calendar::where('manual', 1)->where('id', $calendar->id)->pluck('id')->toArray();
-            $presences_recuperi = \App\Models\Presence::whereIn('calendar_id', $calendar_recuperi)->where('member_id', $this->dataId)->get();
-            foreach($presences_recuperi as $p)
-            {
-                $this->member_presences[] = array('calendar_id' => $p->calendar->id, 'from' => $p->calendar->from, 'to' => $p->calendar->to, 'status' => '<span style="color:#7136f6">Recupero</span>');//\App\Models\Presence::where('member_id', $this->dataId)->get();
-                $this->recuperi += 1;
-            } 
-                */
-
-            //array_push($this->courses, $calendar->course_id);
-
-            // sort records per cognome-nome
-            if (isset($this->records[$calendar->name]) && isset($this->records[$calendar->name][$h])) {
-                usort($this->records[$calendar->name][$h], function($a, $b) {
+            if (isset($this->records[$calendar->name][$h])) {
+                usort($this->records[$calendar->name][$h], function ($a, $b) {
                     $course_level_compare = strcmp($a['course_level'], $b['course_level']);
+                    if ($course_level_compare !== 0) return $course_level_compare;
+
                     $last_name_compare = strcmp($a['last_name'], $b['last_name']);
-                    $first_name_compare = strcmp($a['first_name'], $b['first_name']);
-                    
-                    return $course_level_compare != 0 ? $course_level_compare : ($last_name_compare != 0 ? $last_name_compare : $first_name_compare);
+                    if ($last_name_compare !== 0) return $last_name_compare;
+
+                    return strcmp($a['first_name'], $b['first_name']);
                 });
             }
         }
 
         $this->courses = \App\Models\Calendar::orderBy('name')->groupBy('name')->pluck('name')->toArray();
 
-        /*$this->courses = array_unique($this->courses);
-        $this->courses = array_map(function ($course_id) {
-            try {
-                return \App\Models\Course::findOrFail($course_id);
-            } catch (\Throwable $e) {
-                return null;
+        return view('livewire.presence_report');
+    }
+
+    protected function presenceStatusHtml($presence, $calendar): string
+    {
+        if ($calendar->status == 99) {
+            return "<span class='fw-bold' style='color:gray'>Annullata</span>";
+        }
+
+        if ($presence) {
+            if ((int)$presence->status === 99) {
+                return "<span class='fw-bold' style='color:gray'>Annullata</span>";
             }
-        }, $this->courses);
-        $this->courses = array_filter($this->courses);*/
+            return "<span class='fw-bold' style='color:#0c6197'>Presente</span>";
+        }
 
-        return view('livewire.presence_report');
+        if (Carbon::now()->format('Ymd') > Carbon::parse($calendar->from)->format('Ymd')) {
+            return "<span class='fw-bold' style='color:red'>Assente</span>";
+        }
+
+        return '';
+    }
+
+    protected function presenceMeta($presence): array
+    {
+        if (!$presence) return ['', '', ''];
+
+        $court = $presence->court?->name ?? '';
+
+        $instructorParts = [
+            $presence->user?->name ?? '',
+            ($presence->instructor && $presence->user && $presence->instructor->id !== $presence->user->id)
+                ? $presence->instructor->name
+                : ($presence->instructor?->name ?? ''),
+        ];
+        $instructor = implode(', ', array_values(array_filter(array_unique($instructorParts))));
+
+        $motivation = $presence->motivation?->name ?? '';
+
+        return [$court, $instructor, $motivation];
     }
 
     public function prev()

+ 13 - 8
resources/views/livewire/presence_report.blade.php

@@ -24,13 +24,18 @@
                 <i class="fa-solid fa-chevron-left"></i>
             </a>
             @php
-                $date_title = \Illuminate\Support\Carbon::parse($date)->locale('it-IT')->translatedFormat("j F Y");
+                $date = \Illuminate\Support\Carbon::parse($date);
+                $date_back = $date->format('Y-m-d');
+                $date_title = $date->locale('it-IT')->translatedFormat("j F Y");
             @endphp
             <h4 class="text-uppercase m-0">{{$date_title}}</h4>
             <a style="cursor:pointer;" wire:click="next()">
                 <i class="fa-solid fa-chevron-right"></i>
             </a>
         </div>
+        <div class="col-auto">
+            <a class="btn--ui btn-primary" style="cursor:pointer;" href='/calendar?last_date={{$date_back}}'>Vai al calendario</a>
+        </div>
         <div class="col-auto">
             <a class="btn--ui btn-primary" style="cursor:pointer;" href='/absence_reports'>Alert assenze</a>
         </div>
@@ -109,13 +114,13 @@
                     <table class="report-table">
                         <thead>
                             <tr>
-                                <td>Livello</td>
-                                <td>Cognome</td>
-                                <td>Nome</td>
-                                <td>Campo</td>
-                                <td>Istruttore</td>
-                                <td>Stato</td>
-                                <td>Motivazione</td>
+                                <td style="width: 15%">Livello</td>
+                                <td style="width: 15%">Cognome</td>
+                                <td style="width: 15%">Nome</td>
+                                <td style="width: 10%">Campo</td>
+                                <td style="width: 15%">Istruttore</td>
+                                <td style="width: 10%">Stato</td>
+                                <td style="width: 20%">Motivazione</td>
                             </tr>
                         </thead>
                         <tbody>