From 2e8daf78e179b673920400a3df0e85fa7b629df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCnther?= Date: Sat, 25 Apr 2026 00:32:15 +0200 Subject: [PATCH] Cronjobs implemented --- app/Installer/ProductionDataSeeder.php | 3 + .../EventReportMails/InformLocalGroupMail.php | 73 +++++++++++++++++++ app/Models/CronTask.php | 4 + app/Repositories/EventRepository.php | 20 ++++- app/Tasks/CloseCostUnit.php | 21 ++++++ app/Tasks/CloseEvent.php | 21 ++++++ app/Tasks/NotifyTeam.php | 41 +++++++++++ .../participant_report_localgroups.blade.php | 42 +++++++++++ .../emails/subparts/disclaimer.blade.php | 6 +- .../subparts/disclaimer_localgroups.blade.php | 6 ++ 10 files changed, 231 insertions(+), 6 deletions(-) create mode 100644 app/Mail/EventReportMails/InformLocalGroupMail.php create mode 100644 app/Tasks/CloseCostUnit.php create mode 100644 app/Tasks/CloseEvent.php create mode 100644 app/Tasks/NotifyTeam.php create mode 100644 resources/views/emails/events/participant_report_localgroups.blade.php create mode 100644 resources/views/emails/subparts/disclaimer_localgroups.blade.php diff --git a/app/Installer/ProductionDataSeeder.php b/app/Installer/ProductionDataSeeder.php index d15c425..ba02cae 100644 --- a/app/Installer/ProductionDataSeeder.php +++ b/app/Installer/ProductionDataSeeder.php @@ -158,6 +158,9 @@ class ProductionDataSeeder { private function installCronTasks() { CronTask::create(['name' => 'UploadInvoices', 'execution_type' => CronTaskType::CRON_TASK_TYPE_REALTIME]); + CronTask::create(['name' => 'CloseCostUnit', 'execution_type' => CronTaskType::CRON_TASK_TYPE_DAILY, 'schedule_time' => '00:05']); + CronTask::create(['name' => 'CloseEvent', 'execution_type' => CronTaskType::CRON_TASK_TYPE_DAILY, 'schedule_time' => '00:10']); + CronTask::create(['name' => 'NotifyTeam', 'execution_type' => CronTaskType::CRON_TASK_TYPE_DAILY, 'schedule_time' => '20:00']); } } diff --git a/app/Mail/EventReportMails/InformLocalGroupMail.php b/app/Mail/EventReportMails/InformLocalGroupMail.php new file mode 100644 index 0000000..f5b6907 --- /dev/null +++ b/app/Mail/EventReportMails/InformLocalGroupMail.php @@ -0,0 +1,73 @@ +event->name + ); + + + return new Envelope( + subject: $subject, + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + $event = $this->event->toResource()->toArray(new Request()); + $participants = []; + foreach ($this->participants as $participant) { + $_t = $participant->toResource()->toArray(new Request()); + $participants[$_t['participationType']][] = $_t; + } + + return new Content( + view: 'emails.events.participant_report_localgroups', + with: [ + 'participantGroups' => $participants, + 'eventTitle' => $event['name'], + 'eventEmail' => $event['email'], + ], + ); + } + + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Models/CronTask.php b/app/Models/CronTask.php index 01930ca..e6c48fb 100644 --- a/app/Models/CronTask.php +++ b/app/Models/CronTask.php @@ -9,4 +9,8 @@ class CronTask extends CommonModel protected $table = 'cron_tasks'; protected $fillable = ['name', 'execution_type', 'schedule_time', 'last_run']; protected $dates = ['last_run']; + + protected $casts = [ + 'last_run' => 'datetime', + ]; } diff --git a/app/Repositories/EventRepository.php b/app/Repositories/EventRepository.php index d5b6a03..a6afd28 100644 --- a/app/Repositories/EventRepository.php +++ b/app/Repositories/EventRepository.php @@ -17,11 +17,25 @@ class EventRepository { } - public function getAvailable(bool $accessCheck = true) : array { + public function getUpcomming() : array { return $this->getEventsByCriteria([ 'archived' => false, - 'registration_allowed' => true - ],$accessCheck); + 'upcomming' => true + ]); + } + + public function getAvailable(bool $accessCheck = true) : array { + $events = []; + foreach ( $this->getEventsByCriteria([ + 'archived' => false, + + ],$accessCheck) as $event) { + if ($event->start_date > now()) { + $events[] = $event; + } + }; + + return $events; } public function getForRegistration(int $id) : ?Event { diff --git a/app/Tasks/CloseCostUnit.php b/app/Tasks/CloseCostUnit.php new file mode 100644 index 0000000..42a5ae3 --- /dev/null +++ b/app/Tasks/CloseCostUnit.php @@ -0,0 +1,21 @@ +getCurrentEvents() as $costUnit) { + if (\DateTime::createFromFormat('Y-m-d', $costUnit->billing_deadline) < $now ) { + $costUnit->allow_new = false; + $costUnit->save(); + } + } + } +} diff --git a/app/Tasks/CloseEvent.php b/app/Tasks/CloseEvent.php new file mode 100644 index 0000000..77cd5fa --- /dev/null +++ b/app/Tasks/CloseEvent.php @@ -0,0 +1,21 @@ +getAvailable(false) as $event) { + if ($event->registration_final_end < $now ) { + $event->registration_allowed = false; + $event->save(); + } + } + } +} diff --git a/app/Tasks/NotifyTeam.php b/app/Tasks/NotifyTeam.php new file mode 100644 index 0000000..13e9c23 --- /dev/null +++ b/app/Tasks/NotifyTeam.php @@ -0,0 +1,41 @@ +getAvailable(false) as $event) { + foreach (Tenant::all() as $tenant) { + $participants = $event->participants()->where('local_group', $tenant->slug)->whereNull('unregistered_at')->get(); + } + + if ($participants->isEmpty()) { + continue; + } + + + Mail::to($tenant->email)->send(new InformLocalGroupMail( + event: $event, + participants: $participants, + )); + } + } +} diff --git a/resources/views/emails/events/participant_report_localgroups.blade.php b/resources/views/emails/events/participant_report_localgroups.blade.php new file mode 100644 index 0000000..da29e75 --- /dev/null +++ b/resources/views/emails/events/participant_report_localgroups.blade.php @@ -0,0 +1,42 @@ +@php use App\Enumerations\EfzStatus; @endphp + + + +

Teilnahmebericht

+

Für die Veranstaltung "{{$eventTitle}}" sind von eurem Stamm aktuell folgende Personen angemeldet:

+ + +@foreach($participantGroups as $groupName => $participants) +

{{$groupName}}

+ + + + + + + + @foreach($participants as $participant) + + + + + + @endforeach +
+ Name + + Zahlung noch offen + + eFZ-Bestätigung ausstehend +
{!! $participant['fullname'] !!}
Alter: {{$participant['age']}} Jahre
{{$participant['needs_payment'] ? 'Ja' : 'Nein'}}{{in_array($participant['efz_status'], [ + EfzStatus::EFZ_STATUS_CHECKED_VALID, + EfzStatus::EFZ_STATUS_NOT_REQUIRED + ]) ? 'Nein' : 'Ja'}}
+@endforeach +

+

+


+@include('emails.subparts.disclaimer_localgroups') +

+ + diff --git a/resources/views/emails/subparts/disclaimer.blade.php b/resources/views/emails/subparts/disclaimer.blade.php index cb77d78..6bc5009 100644 --- a/resources/views/emails/subparts/disclaimer.blade.php +++ b/resources/views/emails/subparts/disclaimer.blade.php @@ -1,6 +1,6 @@ -Dies istt eine automatisch erzeugte E-Mail. Bitte antworte nicht auf diese E-Mail.
+Dies ist eine automatisch erzeugte E-Mail. Bitte antworte nicht auf diese E-Mail.
Solltest du Fragen haben, kontaktiere bitte die Aktionsleitung direkt.

-Du erhältst diese E-Mail. da du dich für die Veranstaltung {{$eventTitle}} angemeldet hast.
-Sollte dies nicht korrekt sein, oder wenn du weitere Fragen hast, wende dich bitte an die Veranstaltiungsleitung.

+Du erhältst diese E-Mail, da du dich für die Veranstaltung {{$eventTitle}} angemeldet hast.
+Sollte dies nicht korrekt sein, oder wenn du weitere Fragen hast, wende dich bitte an die Veranstaltungsleitung.

Du erreichst die Veranstaltungsleitung per E-Mail unter der Adresse: {{$eventEmail}} diff --git a/resources/views/emails/subparts/disclaimer_localgroups.blade.php b/resources/views/emails/subparts/disclaimer_localgroups.blade.php new file mode 100644 index 0000000..96ca361 --- /dev/null +++ b/resources/views/emails/subparts/disclaimer_localgroups.blade.php @@ -0,0 +1,6 @@ +Dies ist eine automatisch erzeugte E-Mail. Bitte antworte nicht auf diese E-Mail.
+Solltest du Fragen haben, kontaktiere bitte die Aktionsleitung direkt.

+Euer Stamm erhält diese E-Mail, da ihr Teilnehmende für die Veranstaltung {{$eventTitle}} angemeldet habt.
+Sollte dies nicht korrekt sein, oder wenn ihr weitere Fragen habt, wendet euch bitte an die Veranstaltungsleitung.

+ +Ihr erreicht die Veranstaltungsleitung per E-Mail unter der Adresse: {{$eventEmail}}