Cronjobs implemented

This commit is contained in:
2026-04-25 00:32:15 +02:00
parent 4878f750bd
commit 2e8daf78e1
10 changed files with 231 additions and 6 deletions

View File

@@ -158,6 +158,9 @@ class ProductionDataSeeder {
private function installCronTasks() { private function installCronTasks() {
CronTask::create(['name' => 'UploadInvoices', 'execution_type' => CronTaskType::CRON_TASK_TYPE_REALTIME]); 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']);
} }
} }

View File

@@ -0,0 +1,73 @@
<?php
namespace App\Mail\EventReportMails;
use App\Models\Event;
use App\Models\EventParticipant;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
class InformLocalGroupMail extends Mailable
{
public function __construct(
private Event $event,
private Collection $participants,
)
{
//
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
$subject = sprintf(
'Teilnehmendenübersicht %1$s %2$s',
'für die Veranstaltung',
$this->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<int, Attachment>
*/
public function attachments(): array
{
return [];
}
}

View File

@@ -9,4 +9,8 @@ class CronTask extends CommonModel
protected $table = 'cron_tasks'; protected $table = 'cron_tasks';
protected $fillable = ['name', 'execution_type', 'schedule_time', 'last_run']; protected $fillable = ['name', 'execution_type', 'schedule_time', 'last_run'];
protected $dates = ['last_run']; protected $dates = ['last_run'];
protected $casts = [
'last_run' => 'datetime',
];
} }

View File

@@ -17,11 +17,25 @@ class EventRepository {
} }
public function getAvailable(bool $accessCheck = true) : array { public function getUpcomming() : array {
return $this->getEventsByCriteria([ return $this->getEventsByCriteria([
'archived' => false, 'archived' => false,
'registration_allowed' => true 'upcomming' => true
],$accessCheck); ]);
}
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 { public function getForRegistration(int $id) : ?Event {

View File

@@ -0,0 +1,21 @@
<?php
namespace App\Tasks;
use App\Models\CostUnit;
use App\Repositories\CostUnitRepository;
class CloseCostUnit implements CronTask {
public function handle(): void
{
$now = now();
$costUnitRepository = new CostUnitRepository();
/** @var CostUnit $costUnit */
foreach ($costUnitRepository->getCurrentEvents() as $costUnit) {
if (\DateTime::createFromFormat('Y-m-d', $costUnit->billing_deadline) < $now ) {
$costUnit->allow_new = false;
$costUnit->save();
}
}
}
}

21
app/Tasks/CloseEvent.php Normal file
View File

@@ -0,0 +1,21 @@
<?php
namespace App\Tasks;
use App\Models\Event;
use App\Repositories\EventRepository;
class CloseEvent implements CronTask {
public function handle(): void
{
$now = now();
$eventRepository = new EventRepository();
/** @var Event $event */
foreach ($eventRepository->getAvailable(false) as $event) {
if ($event->registration_final_end < $now ) {
$event->registration_allowed = false;
$event->save();
}
}
}
}

41
app/Tasks/NotifyTeam.php Normal file
View File

@@ -0,0 +1,41 @@
<?php
namespace App\Tasks;
use App\Domains\Invoice\Actions\UploadInvoice\UploadInvoiceCommand;
use App\Domains\Invoice\Actions\UploadInvoice\UploadInvoiceRequest;
use App\Mail\EventReportMails\InformLocalGroupMail;
use App\Mail\ParticipantParticipationMails\ParticipantSignOffMail;
use App\Models\Event;
use App\Models\Tenant;
use App\Repositories\EventRepository;
use App\Repositories\InvoiceRepository;
use Illuminate\Support\Facades\Mail;
use Psr\Log\LoggerInterface;
class NotifyTeam implements CronTask {
public function handle(): void
{
if (date('w') !== 0) {
// return;
}
$eventRepository = new EventRepository();
/** @var Event $event */
foreach ($eventRepository->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,
));
}
}
}

View File

@@ -0,0 +1,42 @@
@php use App\Enumerations\EfzStatus; @endphp
<!DOCTYPE html>
<html>
<body>
<h1>Teilnahmebericht</h1>
<p>Für die Veranstaltung "{{$eventTitle}}" sind von eurem Stamm aktuell folgende Personen angemeldet:</p>
@foreach($participantGroups as $groupName => $participants)
<h2>{{$groupName}}</h2>
<table>
<tr>
<th style="padding: 8px 12px; width: 180px; font-weight: 600; color: #4b5563; border-bottom: 1px solid #e5e7eb;">
Name
</th>
<th style="padding: 8px 12px; width: 180px; font-weight: 600; color: #4b5563; border-bottom: 1px solid #e5e7eb;">
Zahlung noch offen
</th>
<th style="padding: 8px 12px; width: 180px; font-weight: 600; color: #4b5563; border-bottom: 1px solid #e5e7eb;">
eFZ-Bestätigung ausstehend
</th>
</tr>
@foreach($participants as $participant)
<tr>
<td style="padding: 8px 12px; border-bottom: 1px solid #e5e7eb;">{!! $participant['fullname'] !!}<br />Alter: {{$participant['age']}} Jahre</td>
<td style="padding: 8px 12px; border-bottom: 1px solid #e5e7eb;">{{$participant['needs_payment'] ? 'Ja' : 'Nein'}}</td>
<td style="padding: 8px 12px; border-bottom: 1px solid #e5e7eb;">{{in_array($participant['efz_status'], [
EfzStatus::EFZ_STATUS_CHECKED_VALID,
EfzStatus::EFZ_STATUS_NOT_REQUIRED
]) ? 'Nein' : 'Ja'}}</td>
</tr>
@endforeach
</table>
@endforeach
<br/><br/>
<p>
<hr/>
@include('emails.subparts.disclaimer_localgroups')
</p>
</body>
</html>

View File

@@ -1,6 +1,6 @@
Dies istt eine automatisch erzeugte E-Mail. Bitte antworte nicht auf diese E-Mail.<br /> Dies ist eine automatisch erzeugte E-Mail. Bitte antworte nicht auf diese E-Mail.<br />
Solltest du Fragen haben, kontaktiere bitte die Aktionsleitung direkt.<br /><br /> Solltest du Fragen haben, kontaktiere bitte die Aktionsleitung direkt.<br /><br />
Du erhältst diese E-Mail. da du dich für die Veranstaltung {{$eventTitle}} angemeldet hast.<br /> Du erhältst diese E-Mail, da du dich für die Veranstaltung {{$eventTitle}} angemeldet hast.<br />
Sollte dies nicht korrekt sein, oder wenn du weitere Fragen hast, wende dich bitte an die Veranstaltiungsleitung.<br /><br /> Sollte dies nicht korrekt sein, oder wenn du weitere Fragen hast, wende dich bitte an die Veranstaltungsleitung.<br /><br />
Du erreichst die Veranstaltungsleitung per E-Mail unter der Adresse: {{$eventEmail}} Du erreichst die Veranstaltungsleitung per E-Mail unter der Adresse: {{$eventEmail}}

View File

@@ -0,0 +1,6 @@
Dies ist eine automatisch erzeugte E-Mail. Bitte antworte nicht auf diese E-Mail.<br />
Solltest du Fragen haben, kontaktiere bitte die Aktionsleitung direkt.<br /><br />
Euer Stamm erhält diese E-Mail, da ihr Teilnehmende für die Veranstaltung {{$eventTitle}} angemeldet habt.<br />
Sollte dies nicht korrekt sein, oder wenn ihr weitere Fragen habt, wendet euch bitte an die Veranstaltungsleitung.<br /><br />
Ihr erreicht die Veranstaltungsleitung per E-Mail unter der Adresse: {{$eventEmail}}