| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- <?php
- namespace App\Http\Livewire;
- use Livewire\Component;
- use Illuminate\Support\Carbon;
- class PresenceReport extends Component
- {
- public $records = [];
- public $date;
- public $courses = [];
- public $courts = [];
- public $instructors = [];
- public $motivations = [];
- public $course_name;
- public $from;
- public $to;
- public $court_id;
- public $instructor_id;
- public $search;
- public $court_name = '';
- public $instructor_name = '';
- public function mount()
- {
- $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');
- }
- public function render()
- {
- setlocale(LC_ALL, 'it_IT');
- $this->records = [];
- $fromDt = Carbon::parse($this->date . ' ' . ($this->from ?: '00:00:00'));
- $toDt = Carbon::parse($this->date . ' ' . ($this->to ?: '23:59:59'));
- $this->court_name = '';
- if (!empty($this->court_id)) {
- $court = $this->courts->firstWhere('id', (int)$this->court_id);
- $this->court_name = $court?->name ?? '';
- }
- $this->instructor_name = '';
- if (!empty($this->instructor_id)) {
- $instr = $this->instructors->firstWhere('id', (int)$this->instructor_id);
- $this->instructor_name = $instr?->name ?? '';
- }
- $calendars = \App\Models\Calendar::with(['course.level'])
- ->whereBetween('from', [$fromDt->toDateTimeString(), $toDt->toDateTimeString()])
- ->orderBy('from')
- ->get();
- if ($calendars->isEmpty()) {
- $this->courses = \App\Models\Calendar::orderBy('name')->groupBy('name')->pluck('name')->toArray();
- return view('livewire.presence_report');
- }
- $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);
- });
- })
- ->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();
- $presenceByCalMember = [];
- $presencesByCalendar = [];
- foreach ($presencesAll as $p) {
- $presenceByCalMember[$p->calendar_id . '|' . $p->member_id] = $p;
- $presencesByCalendar[$p->calendar_id][] = $p;
- }
- $days = ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'];
- 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;
- }
- $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":' . $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 = $membersQuery->get();
- $expectedMemberIds = [];
- foreach ($members as $mc) {
- $mid = $mc->member->id;
- $expectedMemberIds[] = $mid;
- $p = $presenceByCalMember[$calendar->id . '|' . $mid] ?? null;
- [$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);
- }
- $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;
- }
- if (!empty($this->course_name)) {
- $motCourseName = $p->motivationCourse?->name;
- if (!$motCourseName || $motCourseName !== $this->course_name) {
- continue;
- }
- }
- [$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][] = [
- 'course_level' => $course_level,
- 'last_name' => $p->member?->last_name ?? '',
- 'first_name' => $p->member?->first_name ?? '',
- 'court' => $court,
- 'instructor' => $instructor,
- 'status' => $status,
- 'motivation' => $motivation,
- ];
- }
- 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']);
- 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();
- 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>";
- }
- return "<span class='fw-bold' style='color:#0c6197'>Presente</span>";
- }
- 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()
- {
- $this->date = date("Y-m-d", strtotime("-1 day", strtotime($this->date)));
- }
- public function next()
- {
- $this->date = date("Y-m-d", strtotime("+1 day", strtotime($this->date)));
- }
- public function today()
- {
- $this->date = date("Y-m-d");
- }
- }
|