|
@@ -2,13 +2,16 @@
|
|
|
|
|
|
|
|
namespace App\Http\Livewire;
|
|
namespace App\Http\Livewire;
|
|
|
|
|
|
|
|
|
|
+use Illuminate\Support\Carbon;
|
|
|
use Livewire\Component;
|
|
use Livewire\Component;
|
|
|
|
|
|
|
|
class AbsenceReport extends Component
|
|
class AbsenceReport extends Component
|
|
|
{
|
|
{
|
|
|
|
|
|
|
|
public $records;
|
|
public $records;
|
|
|
-
|
|
|
|
|
|
|
+ public $record_assenze;
|
|
|
|
|
+
|
|
|
|
|
+ public $fiscalStartMonth = 9;
|
|
|
public $year;
|
|
public $year;
|
|
|
|
|
|
|
|
public function mount()
|
|
public function mount()
|
|
@@ -19,71 +22,241 @@ class AbsenceReport extends Component
|
|
|
public function render()
|
|
public function render()
|
|
|
{
|
|
{
|
|
|
setlocale(LC_ALL, 'it_IT');
|
|
setlocale(LC_ALL, 'it_IT');
|
|
|
|
|
+
|
|
|
|
|
+ $this->record_assenze = [];
|
|
|
|
|
+
|
|
|
|
|
+ $today = now();
|
|
|
|
|
+ $this->year = ($today->month >= $this->fiscalStartMonth) ? $today->year : $today->year - 1;
|
|
|
|
|
+
|
|
|
|
|
+ $dayMap = [
|
|
|
|
|
+ 'lun' => 1,
|
|
|
|
|
+ 'mar' => 2,
|
|
|
|
|
+ 'mer' => 3,
|
|
|
|
|
+ 'gio' => 4,
|
|
|
|
|
+ 'ven' => 5,
|
|
|
|
|
+ 'sab' => 6,
|
|
|
|
|
+ 'dom' => 0,
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ $courses = \App\Models\Course::whereDate('date_from', '<=', now())->whereDate('date_to', '>=', now())->where('active', true)->where('enabled', true)->get();
|
|
|
|
|
+ foreach ($courses as $course) {
|
|
|
|
|
+ $course_members = \App\Models\MemberCourse::where('course_id', $course->id)->get();
|
|
|
|
|
+ $this->record_assenze[$course->id] = [
|
|
|
|
|
+ 'course' => $course,
|
|
|
|
|
+ 'members' => []
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($course_members as $course_member) {
|
|
|
|
|
+ $calendars_query = \App\Models\Calendar::where('course_id', $course->id);
|
|
|
|
|
+
|
|
|
|
|
+ $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);
|
|
|
|
|
|
|
|
- $this->records = [];
|
|
|
|
|
|
|
+ $when = json_decode($course_member->when, true);
|
|
|
|
|
+ foreach ($when as $period) {
|
|
|
|
|
+ $days = $period['day'];
|
|
|
|
|
+
|
|
|
|
|
+ if ($days) {
|
|
|
|
|
+ $from = $period['from'];
|
|
|
|
|
+ $to = $period['to'];
|
|
|
|
|
+
|
|
|
|
|
+ $ranges = $this->generateFiscalDateRanges($months, $days, $dayMap, $from, $to);
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($ranges as $range) {
|
|
|
|
|
+ $date_from = $range['from'];
|
|
|
|
|
+ $date_to = $range['to'];
|
|
|
|
|
+
|
|
|
|
|
+ $c_query->orWhere(function ($query) use ($date_from, $date_to) {
|
|
|
|
|
+ $query->where('from', $date_from)
|
|
|
|
|
+ ->where('to', $date_to);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ $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();
|
|
|
|
|
+
|
|
|
|
|
+ if (!$presence) {
|
|
|
|
|
+ $this->record_assenze[$course->id]['members'][$course_member->id]['count']++;
|
|
|
|
|
+ $this->record_assenze[$course->id]['members'][$course_member->id]['dates'][] = [
|
|
|
|
|
+ 'calendar_id' => $calendar->id,
|
|
|
|
|
+ 'date' => Carbon::parse($calendar->from)->translatedFormat('d/m'),
|
|
|
|
|
+ ];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if ($this->record_assenze[$course->id]['members'][$course_member->id]['count'] < 2) {
|
|
|
|
|
+ unset($this->record_assenze[$course->id]['members'][$course_member->id]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (empty($this->record_assenze[$course->id]['members'])) {
|
|
|
|
|
+ unset($this->record_assenze[$course->id]);
|
|
|
|
|
+ } 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);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (\Throwable $e) {
|
|
|
|
|
+ dd($e->getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // $this->records = [];
|
|
|
|
|
|
|
|
// $to = date("Y-m-d 23:59:59");
|
|
// $to = date("Y-m-d 23:59:59");
|
|
|
// $calendars = \App\Models\Calendar::where('from', '<=', $to)->orderBy('from')->get();
|
|
// $calendars = \App\Models\Calendar::where('from', '<=', $to)->orderBy('from')->get();
|
|
|
|
|
|
|
|
- $month = date("n");
|
|
|
|
|
- $this->year = ($month >= 9) ? date("Y") : date("Y") - 1;
|
|
|
|
|
|
|
+ // $month = date("n");
|
|
|
|
|
+ // $this->year = ($month >= 9) ? date("Y") : date("Y") - 1;
|
|
|
|
|
+
|
|
|
|
|
+ // $start = date("Y-m-d H:i:s", mktime(0, 0, 0, 9, 1, $this->year));
|
|
|
|
|
+ // $end = date("Y-m-d 23:59:59");
|
|
|
|
|
+
|
|
|
|
|
+ // $calendars = \App\Models\Calendar::whereBetween('from', [$start, $end])->orderBy('from')->get();
|
|
|
|
|
|
|
|
- $start = date("Y-m-d H:i:s", mktime(0, 0, 0, 9, 1, $this->year));
|
|
|
|
|
- $end = date("Y-m-d 23:59:59");
|
|
|
|
|
|
|
+ // foreach ($calendars as $calendar) {
|
|
|
|
|
|
|
|
- $calendars = \App\Models\Calendar::whereBetween('from', [$start, $end])->orderBy('from')->get();
|
|
|
|
|
|
|
+ // $presences = \App\Models\Presence::where('calendar_id', $calendar->id)->where('status', '<>', 99);
|
|
|
|
|
+ // $presences = $presences->pluck('member_id')->toArray();
|
|
|
|
|
+ // $presences_annullate = \App\Models\Presence::where('calendar_id', $calendar->id)->where('status', 99)->pluck('member_id')->toArray();
|
|
|
|
|
|
|
|
- foreach ($calendars as $calendar) {
|
|
|
|
|
|
|
+ // $days = ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'];
|
|
|
|
|
+ // $dow = date('w', strtotime($calendar->from));
|
|
|
|
|
+ // $d = $days[$dow];
|
|
|
|
|
|
|
|
- $presences = \App\Models\Presence::where('calendar_id', $calendar->id)->where('status', '<>', 99);
|
|
|
|
|
- $presences = $presences->pluck('member_id')->toArray();
|
|
|
|
|
- $presences_annullate = \App\Models\Presence::where('calendar_id', $calendar->id)->where('status', 99)->pluck('member_id')->toArray();
|
|
|
|
|
|
|
+ // $h = date('H:i', strtotime($calendar->from));
|
|
|
|
|
|
|
|
- $days = ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'];
|
|
|
|
|
- $dow = date('w', strtotime($calendar->from));
|
|
|
|
|
- $d = $days[$dow];
|
|
|
|
|
|
|
+ // // 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);
|
|
|
|
|
+ // $courses = $courses->pluck('id')->toArray();
|
|
|
|
|
|
|
|
- $h = date('H:i', strtotime($calendar->from));
|
|
|
|
|
|
|
+ // $months = date("n", strtotime($calendar->from));
|
|
|
|
|
|
|
|
- // 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);
|
|
|
|
|
- $courses = $courses->pluck('id')->toArray();
|
|
|
|
|
|
|
+ // // Elenco utenti iscritti al corso "padre"
|
|
|
|
|
+ // $members = \App\Models\MemberCourse::where('when', 'like', "%" . $d . "%")
|
|
|
|
|
+ // ->where('when', 'like', '%"from":"' . $h . '"%')
|
|
|
|
|
+ // ->whereNot('months', 'like', '%"m":' . $months . ',"status":2%')
|
|
|
|
|
+ // ->whereDate('date_from', '<=', $calendar->from)
|
|
|
|
|
+ // ->whereDate('date_to', '>=', $calendar->from)
|
|
|
|
|
+ // ->whereIn('course_id', $courses)
|
|
|
|
|
+ // ->orderBy('member_id')
|
|
|
|
|
+ // ->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) {
|
|
|
|
|
|
|
|
- $months = date("n", strtotime($calendar->from));
|
|
|
|
|
|
|
+ // $presence = \App\Models\Presence::where('member_id', $member->member->id)->where('calendar_id', $calendar->id)->first();
|
|
|
|
|
|
|
|
- // Elenco utenti iscritti al corso "padre"
|
|
|
|
|
- $members = \App\Models\MemberCourse::where('when', 'like', "%" . $d . "%")
|
|
|
|
|
- ->where('when', 'like', '%"from":"' . $h . '"%')
|
|
|
|
|
- ->whereNot('months', 'like', '%"m":' . $months . ',"status":2%')
|
|
|
|
|
- ->whereDate('date_from', '<=', $calendar->from)
|
|
|
|
|
- ->whereDate('date_to', '>=', $calendar->from)
|
|
|
|
|
- ->whereIn('course_id', $courses)
|
|
|
|
|
- ->orderBy('member_id')
|
|
|
|
|
- ->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) {
|
|
|
|
|
|
|
+ // if (!in_array($member->member->id, $presences)) {
|
|
|
|
|
+ // if (!in_array($member->member->id, $presences_annullate)) {
|
|
|
|
|
+ // if (array_key_exists($member->member->id, $this->records)) {
|
|
|
|
|
+ // $this->records[$member->member->id]['total'] += 1;
|
|
|
|
|
+ // $this->records[$member->member->id]['date'] .= " - " . date("d/m", strtotime($calendar->from));
|
|
|
|
|
+ // } else
|
|
|
|
|
+ // $this->records[$member->member->id] = array("last_name" => $member->member->last_name, "first_name" => $member->member->first_name, "course" => $calendar->name, "total" => 1, "date" => date("d/m", strtotime($calendar->from)));
|
|
|
|
|
+ // }
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ // if (array_key_exists($member->member->id, $this->records))
|
|
|
|
|
+ // unset($this->records[$member->member->id]);
|
|
|
|
|
+ // }
|
|
|
|
|
+ // }
|
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
- $presence = \App\Models\Presence::where('member_id', $member->member->id)->where('calendar_id', $calendar->id)->first();
|
|
|
|
|
|
|
+ // array_multisort(array_column($this->records, 'total'), SORT_DESC, $this->records);
|
|
|
|
|
|
|
|
- if (!in_array($member->member->id, $presences)) {
|
|
|
|
|
- if (!in_array($member->member->id, $presences_annullate)) {
|
|
|
|
|
- if (array_key_exists($member->member->id, $this->records)) {
|
|
|
|
|
- $this->records[$member->member->id]['total'] += 1;
|
|
|
|
|
- $this->records[$member->member->id]['date'] .= " - " . date("d/m", strtotime($calendar->from));
|
|
|
|
|
- } else
|
|
|
|
|
- $this->records[$member->member->id] = array("last_name" => $member->member->last_name, "first_name" => $member->member->first_name, "course" => $calendar->name, "total" => 1, "date" => date("d/m", strtotime($calendar->from)));
|
|
|
|
|
|
|
+ return view('livewire.absence_report');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected function generateFiscalDateRanges($months, $days, $dayMap, $fromTime, $toTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $limit = now()->endOfDay();
|
|
|
|
|
+
|
|
|
|
|
+ $today = $limit;
|
|
|
|
|
+
|
|
|
|
|
+ $startYear = ($today->month >= $this->fiscalStartMonth) ? $today->year : $today->year - 1;
|
|
|
|
|
+
|
|
|
|
|
+ $allowedDow = collect($days)
|
|
|
|
|
+ ->map(fn($d) => $dayMap[$d] ?? null)
|
|
|
|
|
+ ->filter(fn($v) => $v !== null)
|
|
|
|
|
+ ->unique()
|
|
|
|
|
+ ->values();
|
|
|
|
|
+
|
|
|
|
|
+ sort($months);
|
|
|
|
|
+
|
|
|
|
|
+ $fromCarbon = Carbon::parse($fromTime);
|
|
|
|
|
+ $toCarbon = Carbon::parse($toTime);
|
|
|
|
|
+
|
|
|
|
|
+ $fromHour = $fromCarbon->hour;
|
|
|
|
|
+ $fromMinute = $fromCarbon->minute;
|
|
|
|
|
+ $fromSecond = $fromCarbon->second;
|
|
|
|
|
+
|
|
|
|
|
+ $toHour = $toCarbon->hour;
|
|
|
|
|
+ $toMinute = $toCarbon->minute;
|
|
|
|
|
+ $toSecond = $toCarbon->second;
|
|
|
|
|
+
|
|
|
|
|
+ $ranges = [];
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($months as $month) {
|
|
|
|
|
+ $yearForMonth = ($month >= $this->fiscalStartMonth)
|
|
|
|
|
+ ? $startYear
|
|
|
|
|
+ : $startYear + 1;
|
|
|
|
|
+
|
|
|
|
|
+ if (
|
|
|
|
|
+ $yearForMonth > $limit->year ||
|
|
|
|
|
+ ($yearForMonth === $limit->year && $month > $limit->month)
|
|
|
|
|
+ ) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $firstOfMonth = Carbon::create($yearForMonth, $month, 1)->startOfDay();
|
|
|
|
|
+
|
|
|
|
|
+ foreach ($allowedDow as $dow) {
|
|
|
|
|
+ $offset = ($dow - $firstOfMonth->dayOfWeek + 7) % 7;
|
|
|
|
|
+ $current = $firstOfMonth->copy()->addDays($offset);
|
|
|
|
|
+
|
|
|
|
|
+ while ($current->month === $month) {
|
|
|
|
|
+ $fromDateTime = $current->copy()->setTime($fromHour, $fromMinute, $fromSecond);
|
|
|
|
|
+ $toDateTime = $current->copy()->setTime($toHour, $toMinute, $toSecond);
|
|
|
|
|
+
|
|
|
|
|
+ if ($fromDateTime->gt($limit)) {
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- if (array_key_exists($member->member->id, $this->records))
|
|
|
|
|
- unset($this->records[$member->member->id]);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ $ranges[] = [
|
|
|
|
|
+ 'from' => $fromDateTime,
|
|
|
|
|
+ 'to' => $toDateTime,
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $current->addWeek();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- array_multisort(array_column($this->records, 'total'), SORT_DESC, $this->records);
|
|
|
|
|
|
|
+ usort($ranges, fn($a, $b) => $a['from'] <=> $b['from']);
|
|
|
|
|
|
|
|
- return view('livewire.absence_report');
|
|
|
|
|
|
|
+ return $ranges;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|