Signup for events implemented
This commit is contained in:
@@ -7,8 +7,6 @@ use App\Providers\InertiaProvider;
|
||||
use App\Scopes\CommonController;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Js;
|
||||
|
||||
class DashboardController extends CommonController {
|
||||
public function __invoke(Request $request) {
|
||||
|
||||
@@ -6,17 +6,16 @@ use App\Domains\Event\Actions\CertificateOfConductionCheck\CertificateOfConducti
|
||||
use App\Domains\Event\Actions\CertificateOfConductionCheck\CertificateOfConductionCheckRequest;
|
||||
use App\Domains\Event\Actions\SignUp\SignUpCommand;
|
||||
use App\Domains\Event\Actions\SignUp\SignUpRequest;
|
||||
use App\Mail\EventSignUpSuccessfull;
|
||||
use App\Models\Tenant;
|
||||
use App\Models\User;
|
||||
use App\Providers\DoubleCheckEventRegistrationProvider;
|
||||
use App\Providers\InertiaProvider;
|
||||
use App\Resources\EventResource;
|
||||
use App\Resources\UserResource;
|
||||
use App\Scopes\CommonController;
|
||||
use App\ValueObjects\Amount;
|
||||
use http\Env\Response;
|
||||
use DateTime;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SignupController extends CommonController {
|
||||
public function __invoke(int $eventId, Request $request) {
|
||||
@@ -76,11 +75,17 @@ class SignupController extends CommonController {
|
||||
$departure = \DateTime::createFromFormat('Y-m-d', $registrationData['departure']);
|
||||
$tetanusVaccination = $registrationData['tetanusVaccination'] ? \DateTime::createFromFormat('Y-m-d', $registrationData['tetanusVaccination']) : null;
|
||||
|
||||
// Steps:
|
||||
// 1. Check, if bereits angemeldet
|
||||
$doubleCheckEventRegistrationProvider = new DoubleCheckEventRegistrationProvider(
|
||||
$event,
|
||||
$registrationData['vorname'],
|
||||
$registrationData['nachname'],
|
||||
$registrationData['email_1'],
|
||||
DateTime::createFromFormat('Y-m-d', $registrationData['geburtsdatum']));
|
||||
|
||||
if ($doubleCheckEventRegistrationProvider->isRegistered()) {
|
||||
return response()->json(['status' => 'exists']);
|
||||
}
|
||||
|
||||
//
|
||||
$amount = $eventResource->calculateAmount(
|
||||
$registrationData['participationType'],
|
||||
$registrationData['beitrag'],
|
||||
@@ -138,9 +143,15 @@ class SignupController extends CommonController {
|
||||
$signupResponse->participant->efz_status = $certificateOfConductionCheckResponse->status;
|
||||
$signupResponse->participant->save();
|
||||
|
||||
// 6. E-Mail senden & Bestätigung senden
|
||||
|
||||
Mail::to($signupResponse->participant->email_1)->send(new EventSignUpSuccessfull(
|
||||
participant: $signupResponse->participant,
|
||||
));
|
||||
|
||||
if ($signupResponse->participant->email_2 !== null) {
|
||||
Mail::to($signupResponse->participant->email_2)->send(new EventSignUpSuccessfull(
|
||||
participant: $signupResponse->participant,
|
||||
));
|
||||
}
|
||||
|
||||
return response()->json(
|
||||
[
|
||||
|
||||
@@ -18,8 +18,6 @@ const props = defineProps({
|
||||
localGroups: Array,
|
||||
})
|
||||
|
||||
console.log(props.participantData);
|
||||
|
||||
const emit = defineEmits(['registrationDone'])
|
||||
|
||||
const {
|
||||
@@ -48,7 +46,7 @@ const steps = [
|
||||
:participant="submitResult?.participant"
|
||||
:event="event"
|
||||
/>
|
||||
<SubmitAlreadyExists v-else-if="submitResult?.type === 'exists'" :data="submitResult.data" />
|
||||
<SubmitAlreadyExists v-else-if="submitResult?.status === 'exists'" :event="event" />
|
||||
|
||||
<template v-else>
|
||||
<!-- Fortschrittsleiste (ab Step 2) -->
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<script setup>
|
||||
defineProps({ data: Object })
|
||||
const props = defineProps({
|
||||
event: Object
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div style="padding: 20px 0;">
|
||||
<h3>{{ data.nicename }}</h3>
|
||||
<p>{{ data.text_1 }}</p>
|
||||
<p>{{ data.text_2 }}</p>
|
||||
<a :href="data.email_link" style="color: #2563eb;">{{ data.email_text }}</a>
|
||||
<h3>Registrierung nicht möglich</h3>
|
||||
<p>
|
||||
Leider konnte deine Anmeldung nicht ausgeführt werden, da du bereits für die Veranstaltung {{props.event.name}} angemeldet bist.
|
||||
</p>
|
||||
<p>
|
||||
Falls du bereits angemeldet warst und abgemeldet wurdest, oder andere Fragen hast, kontaktiere die Veranstaltungsleitung:
|
||||
<a href="mailto:{{props.event.email}}">{{props.event.email}}</a>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -16,7 +16,7 @@ console.log(props.participant)
|
||||
<table class="form-table" style="margin-bottom: 20px;">
|
||||
<tr><td>Anreise:</td><td>{{ props.participant.arrival }}</td></tr>
|
||||
<tr><td>Abreise:</td><td>{{ props.participant.departure }}</td></tr>
|
||||
<tr><td>Teilnahmegruppe:</td><td>{{ props.participant.participation_group }}</td></tr>
|
||||
<tr><td>Teilnahmegruppe:</td><td>{{ props.participant.participationType }}</td></tr>
|
||||
</table>
|
||||
|
||||
<div v-if="props.participant.efz_status === 'NOT_CHECKED'" style="font-weight: bold; color: #b45309; margin-bottom: 20px;">
|
||||
|
||||
@@ -14,6 +14,35 @@ function formatDate(dateString) {
|
||||
if (!dateString) return ''
|
||||
return format(parseISO(dateString), 'dd.MM.yyyy')
|
||||
}
|
||||
|
||||
function participationGroup() {
|
||||
if (props.formData.participationType === 'team') {
|
||||
return 'Kernteam';
|
||||
}
|
||||
|
||||
if (props.formData.participationType === 'participant') {
|
||||
return 'Teilnehmende';
|
||||
}
|
||||
|
||||
if (props.formData.participationType === 'volunteer') {
|
||||
return 'Unterstützende';
|
||||
}
|
||||
|
||||
return 'Sonstige';
|
||||
}
|
||||
|
||||
function eatingHabit() {
|
||||
if (props.formData.eatingHabit === 'EATING_HABIT_VEGAN') {
|
||||
return 'Vegan';
|
||||
}
|
||||
|
||||
if (props.formData.eatingHabit === 'EATING_HABIT_VEGETARIAN') {
|
||||
return 'Vegetarisch';
|
||||
}
|
||||
|
||||
return 'Omnivor';
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -23,6 +52,65 @@ function formatDate(dateString) {
|
||||
<div v-if="summaryLoading" style="color: #6b7280; padding: 20px 0;">Wird geladen…</div>
|
||||
<div v-else>
|
||||
<table class="form-table" style="margin-bottom: 20px;">
|
||||
<tr>
|
||||
<td>Dein Name:</td>
|
||||
<td>{{props.formData.vorname}} {{props.formData.vorname}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Deine E-Mail:</td>
|
||||
<td>{{props.formData.email_1}}</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="props.formData.ansprechpartner !== ''">
|
||||
<td>Name deiner Kontaktperson:</td>
|
||||
<td>{{props.formData.ansprechpartner}}</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="props.formData.email_2 !== ''">
|
||||
<td>E-Mail-Adresse deiner Kontaktperson:</td>
|
||||
<td>{{props.formData.email_2}}</td>
|
||||
</tr>
|
||||
|
||||
<tr v-if="props.formData.telefon_2 !== ''">
|
||||
<td>Telefonnummer deiner Kontaktperson:</td>
|
||||
<td>{{props.formData.telefon_2}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Teilnahmegruppe:</td>
|
||||
<td>{{ participationGroup() }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Foto-Erlaubnis:</td>
|
||||
<td>
|
||||
<strong>Social Media:</strong> {{props.formData.foto.socialmedia ? 'Ja' : 'Nein'}},
|
||||
<strong>Printmedien:</strong> {{props.formData.foto.print ? 'Ja' : 'Nein'}},
|
||||
<strong>Webseite:</strong> {{props.formData.foto.webseite ? 'Ja' : 'Nein'}},
|
||||
<strong>Partnerorganisationen:</strong> {{props.formData.foto.partner ? 'Ja' : 'Nein'}},
|
||||
<strong>Interne Zwecke:</strong> {{props.formData.foto.intern ? 'Ja' : 'Nein'}}
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Allergien:</td>
|
||||
<td>{{props.formData.allergien}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Lebensmittelunverträglichkeiten:</td>
|
||||
<td>{{props.formData.intolerances}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Ernährungsweise:</td>
|
||||
<td>{{eatingHabit()}}</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr><td>Veranstaltung:</td><td><strong>{{ event.name }}</strong></td></tr>
|
||||
<tr><td>Anreise:</td><td>{{ formatDate(formData.arrival) }}</td></tr>
|
||||
<tr><td>Abreise:</td><td>{{ formatDate(formData.departure) }}</td></tr>
|
||||
|
||||
97
app/Mail/EventSignUpSuccessfull.php
Normal file
97
app/Mail/EventSignUpSuccessfull.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Enumerations\EfzStatus;
|
||||
use App\Models\EventParticipant;
|
||||
use App\Resources\EventParticipantResource;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Attachment;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class EventSignUpSuccessfull extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*/
|
||||
public function __construct(
|
||||
private EventParticipant $participant,
|
||||
)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*/
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
$participant = $this->participant->toResource()->toArray(new Request());
|
||||
|
||||
$subject = sprintf(
|
||||
$participant['needs_payment'] ? 'Teilnahme- & Zahlungsinformationen %1$s %2$s' : 'Anmeldebestätigung %1$s %2$s',
|
||||
'für die Veranstaltung',
|
||||
$this->participant->event()->first()->name
|
||||
);
|
||||
|
||||
|
||||
return new Envelope(
|
||||
subject: $subject,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*/
|
||||
public function content(): Content
|
||||
{
|
||||
$event = $this->participant->event()->first()->toResource()->toArray(new Request());
|
||||
$participant = $this->participant->toResource()->toArray(new Request());
|
||||
|
||||
$girocodeProvider = new \App\Providers\GiroCodeProvider(
|
||||
$event['accountOwner'],
|
||||
$event['accountIban'],
|
||||
(float) $participant['amount_left_value'],
|
||||
$participant['payment_purpose']
|
||||
);
|
||||
$girocodeBinary = (string)$girocodeProvider->create();
|
||||
|
||||
return new Content(
|
||||
view: 'emails.events.signup_complete',
|
||||
with: [
|
||||
'participationType' => $participant['participationType'],
|
||||
'name' => $participant['nicename'],
|
||||
'eventTitle' => $event['name'],
|
||||
'eventEmail' => $event['email'],
|
||||
'arrival' => $participant['arrival'],
|
||||
'departure' => $participant['departure'],
|
||||
'amount' => $participant['amount_left_string'],
|
||||
'paymentFinalDate' => $event['registrationFinalEnd']['formatted'],
|
||||
'paymentRequired' => $participant['needs_payment'],
|
||||
'accountOwner' => $event['accountOwner'],
|
||||
'accountIban' => $event['accountIban'],
|
||||
'paymentPurpose' => $participant['payment_purpose'],
|
||||
'girocodeBinary' => $girocodeBinary,
|
||||
'efzStatus' => $participant['efz_status']
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the attachments for the message.
|
||||
*
|
||||
* @return array<int, Attachment>
|
||||
*/
|
||||
public function attachments(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
30
app/Providers/DoubleCheckEventRegistrationProvider.php
Normal file
30
app/Providers/DoubleCheckEventRegistrationProvider.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Event;
|
||||
use DateTime;
|
||||
|
||||
class DoubleCheckEventRegistrationProvider {
|
||||
function __construct(
|
||||
private Event $event,
|
||||
private string $firstname,
|
||||
private string $lastname,
|
||||
private string $email,
|
||||
private DateTime $birthday,
|
||||
|
||||
) {}
|
||||
|
||||
public function isRegistered() : bool
|
||||
{
|
||||
$checkconditions = array(
|
||||
'firstname' => $this->firstname,
|
||||
'lastname' => $this->lastname,
|
||||
'email_1' => $this->email,
|
||||
'birthday' => $this->birthday->format('Y-m-d'),
|
||||
);
|
||||
|
||||
|
||||
return $this->event->participants()->where($checkconditions)->exists();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Resources;
|
||||
|
||||
use App\Enumerations\ParticipationType;
|
||||
use App\Models\EventParticipant;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
@@ -16,16 +17,23 @@ class EventParticipantResource extends JsonResource
|
||||
{
|
||||
$event = $this->resource->event;
|
||||
|
||||
|
||||
$amountLeft = $this->resource->amount;
|
||||
if ($this->resource->amount_paid !== null) {
|
||||
$amountLeft->subtractAmount($this->resource->amount_paid);
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
$this->resource->toArray(),
|
||||
[
|
||||
'participationType' => ParticipationType::where(['slug' => $this->resource->participation_type])->first()->name,
|
||||
'needs_payment' => $this->resource->amount->getAmount() > 0 && $event->pay_direct,
|
||||
'nicename' => $this->resource->getNicename(),
|
||||
'arrival' => $this->resource->arrival_date->format('d.m.Y'),
|
||||
'departure' => $this->resource->departure_date->format('d.m.Y'),
|
||||
'amount_left_string' => $this->resource->amount->toString(),
|
||||
'amount_left_string' => $amountLeft->toString(),
|
||||
'amount_left_value' => $amountLeft->getAmount(),
|
||||
'email_1' => $this->resource->email_1,
|
||||
|
||||
]
|
||||
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user