Anschrift für Veranstaltungsort
This commit is contained in:
@@ -33,7 +33,7 @@ function navigateTo(url) {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{participation.event.postal_code}} {{participation.event.location}}<br />
|
{{participation.eventAddress}}<br />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="link" :href="`/api/v1/event/participant/${participation.identifier}/ical`">In Kalender importieren</a>
|
<a class="link" :href="`/api/v1/event/participant/${participation.identifier}/ical`">In Kalender importieren</a>
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ class CreateEventCommand {
|
|||||||
'name' => $this->request->name,
|
'name' => $this->request->name,
|
||||||
'identifier' => Str::random(10),
|
'identifier' => Str::random(10),
|
||||||
'location' => $this->request->location,
|
'location' => $this->request->location,
|
||||||
|
'street' => $this->normalizeOptional($this->request->street),
|
||||||
|
'house_number' => $this->normalizeOptional($this->request->houseNumber),
|
||||||
'postal_code' => $this->request->postalCode,
|
'postal_code' => $this->request->postalCode,
|
||||||
'email' => $this->request->email,
|
'email' => $this->request->email,
|
||||||
'start_date' => $this->request->begin,
|
'start_date' => $this->request->begin,
|
||||||
@@ -107,6 +109,17 @@ class CreateEventCommand {
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Straße und Hausnummer sind optional. Ein leer gelassenes Eingabefeld liefert einen leeren String --
|
||||||
|
* gespeichert wird dafür `null`, damit „nicht angegeben" nur eine Darstellung hat.
|
||||||
|
*/
|
||||||
|
private function normalizeOptional(?string $value): ?string
|
||||||
|
{
|
||||||
|
$value = trim((string) $value);
|
||||||
|
|
||||||
|
return '' === $value ? null : $value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event-Teil der Rechnungsnummer, z.B. `WM-V-20260701`: Tenant-Präfix, Dokumentart „V" für
|
* Event-Teil der Rechnungsnummer, z.B. `WM-V-20260701`: Tenant-Präfix, Dokumentart „V" für
|
||||||
* Veranstaltung, dann ohne Trenner Jahr, Monat des Beginns und die laufende Nummer der
|
* Veranstaltung, dann ohne Trenner Jahr, Monat des Beginns und die laufende Nummer der
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ class CreateEventRequest {
|
|||||||
public string $accountOwner;
|
public string $accountOwner;
|
||||||
public string $accountIban;
|
public string $accountIban;
|
||||||
public bool $payPerDay;
|
public bool $payPerDay;
|
||||||
|
public ?string $street;
|
||||||
|
public ?string $houseNumber;
|
||||||
|
|
||||||
public function __construct(string $name, string $location, string $postalCode, string $email, DateTime $begin, DateTime $end, DateTime $earlyBirdEnd, DateTime $registrationFinalEnd, int $earlyBirdEndAmountIncrease, ParticipationFeeType $participationFeeType, string $accountOwner, string $accountIban, bool $payPerDay) {
|
public function __construct(string $name, string $location, string $postalCode, string $email, DateTime $begin, DateTime $end, DateTime $earlyBirdEnd, DateTime $registrationFinalEnd, int $earlyBirdEndAmountIncrease, ParticipationFeeType $participationFeeType, string $accountOwner, string $accountIban, bool $payPerDay, ?string $street = null, ?string $houseNumber = null) {
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->location = $location;
|
$this->location = $location;
|
||||||
$this->postalCode = $postalCode;
|
$this->postalCode = $postalCode;
|
||||||
@@ -34,5 +36,7 @@ class CreateEventRequest {
|
|||||||
$this->accountOwner = $accountOwner;
|
$this->accountOwner = $accountOwner;
|
||||||
$this->accountIban = $accountIban;
|
$this->accountIban = $accountIban;
|
||||||
$this->payPerDay = $payPerDay;
|
$this->payPerDay = $payPerDay;
|
||||||
|
$this->street = $street;
|
||||||
|
$this->houseNumber = $houseNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class GenerateIcalCommand
|
|||||||
$dtEnd = $event->end_date->copy()->addDay()->format('Ymd');
|
$dtEnd = $event->end_date->copy()->addDay()->format('Ymd');
|
||||||
$now = now()->format('Ymd\THis\Z');
|
$now = now()->format('Ymd\THis\Z');
|
||||||
$summary = $this->escapeIcal($event->name);
|
$summary = $this->escapeIcal($event->name);
|
||||||
$location = $this->escapeIcal(trim($event->postal_code . ' ' . $event->location));
|
$location = $this->escapeIcal($event->getFullAddress());
|
||||||
$description = $this->escapeIcal('Teilnahme als: ' . $participant->getOfficialName());
|
$description = $this->escapeIcal('Teilnahme als: ' . $participant->getOfficialName());
|
||||||
|
|
||||||
$icalContent = implode("\r\n", [
|
$icalContent = implode("\r\n", [
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class UpdateEventCommand {
|
|||||||
|
|
||||||
$this->request->event->name = $this->request->eventName;
|
$this->request->event->name = $this->request->eventName;
|
||||||
$this->request->event->location = $this->request->eventLocation;
|
$this->request->event->location = $this->request->eventLocation;
|
||||||
|
$this->request->event->street = $this->normalizeOptional($this->request->street);
|
||||||
|
$this->request->event->house_number = $this->normalizeOptional($this->request->houseNumber);
|
||||||
$this->request->event->postal_code = $this->request->postalCode;
|
$this->request->event->postal_code = $this->request->postalCode;
|
||||||
$this->request->event->email = $this->request->email;
|
$this->request->event->email = $this->request->email;
|
||||||
$this->request->event->early_bird_end = $this->request->earlyBirdEnd;
|
$this->request->event->early_bird_end = $this->request->earlyBirdEnd;
|
||||||
@@ -42,4 +44,15 @@ class UpdateEventCommand {
|
|||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Straße und Hausnummer sind optional. Ein geleertes Eingabefeld liefert einen leeren String --
|
||||||
|
* gespeichert wird dafür `null`, damit „nicht angegeben" nur eine Darstellung hat.
|
||||||
|
*/
|
||||||
|
private function normalizeOptional(?string $value): ?string
|
||||||
|
{
|
||||||
|
$value = trim((string) $value);
|
||||||
|
|
||||||
|
return '' === $value ? null : $value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ class UpdateEventRequest {
|
|||||||
public Event $event;
|
public Event $event;
|
||||||
public string $eventName;
|
public string $eventName;
|
||||||
public string $eventLocation;
|
public string $eventLocation;
|
||||||
|
public ?string $street;
|
||||||
|
public ?string $houseNumber;
|
||||||
public string $postalCode;
|
public string $postalCode;
|
||||||
public string $email;
|
public string $email;
|
||||||
public DateTime $earlyBirdEnd;
|
public DateTime $earlyBirdEnd;
|
||||||
@@ -24,11 +26,13 @@ class UpdateEventRequest {
|
|||||||
public array $contributingLocalGroups;
|
public array $contributingLocalGroups;
|
||||||
public array $eatingHabits;
|
public array $eatingHabits;
|
||||||
|
|
||||||
public function __construct(Event $event, string $eventName, string $eventLocation, string $postalCode, string $email, DateTime $earlyBirdEnd, DateTime $registrationFinalEnd, int $alcoholicsAge, bool $sendWeeklyReports, bool $registrationAllowed, Amount $flatSupport, Amount $supportPerPerson, array $contributingLocalGroups, array $eatingHabits, bool $shortRegistration = false, bool $swimmingPermissionRequired = true)
|
public function __construct(Event $event, string $eventName, string $eventLocation, string $postalCode, string $email, DateTime $earlyBirdEnd, DateTime $registrationFinalEnd, int $alcoholicsAge, bool $sendWeeklyReports, bool $registrationAllowed, Amount $flatSupport, Amount $supportPerPerson, array $contributingLocalGroups, array $eatingHabits, bool $shortRegistration = false, bool $swimmingPermissionRequired = true, ?string $street = null, ?string $houseNumber = null)
|
||||||
{
|
{
|
||||||
$this->event = $event;
|
$this->event = $event;
|
||||||
$this->eventName = $eventName;
|
$this->eventName = $eventName;
|
||||||
$this->eventLocation = $eventLocation;
|
$this->eventLocation = $eventLocation;
|
||||||
|
$this->street = $street;
|
||||||
|
$this->houseNumber = $houseNumber;
|
||||||
$this->postalCode = $postalCode;
|
$this->postalCode = $postalCode;
|
||||||
$this->email = $email;
|
$this->email = $email;
|
||||||
$this->earlyBirdEnd = $earlyBirdEnd;
|
$this->earlyBirdEnd = $earlyBirdEnd;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class ArchivedEventsController extends CommonController
|
|||||||
'name' => $event->name,
|
'name' => $event->name,
|
||||||
'location' => $event->location,
|
'location' => $event->location,
|
||||||
'postalCode' => $event->postal_code,
|
'postalCode' => $event->postal_code,
|
||||||
|
'fullAddress' => $event->getFullAddress(),
|
||||||
'eventBegin' => $event->start_date->format('d.m.Y'),
|
'eventBegin' => $event->start_date->format('d.m.Y'),
|
||||||
'eventEnd' => $event->end_date->format('d.m.Y'),
|
'eventEnd' => $event->end_date->format('d.m.Y'),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ class CreateController extends CommonController {
|
|||||||
$participationFeeType,
|
$participationFeeType,
|
||||||
$request->input('eventAccount'),
|
$request->input('eventAccount'),
|
||||||
$request->input('eventIban'),
|
$request->input('eventIban'),
|
||||||
$payPerDay
|
$payPerDay,
|
||||||
|
$request->input('eventStreet'),
|
||||||
|
$request->input('eventHouseNumber')
|
||||||
);
|
);
|
||||||
|
|
||||||
$wasSuccessful = false;
|
$wasSuccessful = false;
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ class DetailsController extends CommonController {
|
|||||||
$eatingHabits,
|
$eatingHabits,
|
||||||
(bool)$request->input('shortRegistration', false),
|
(bool)$request->input('shortRegistration', false),
|
||||||
(bool)$request->input('swimmingPermissionRequired', true),
|
(bool)$request->input('swimmingPermissionRequired', true),
|
||||||
|
$request->input('street'),
|
||||||
|
$request->input('houseNumber'),
|
||||||
);
|
);
|
||||||
|
|
||||||
$eventUpdateCommand = new UpdateEventCommand($eventUpdateRequest);
|
$eventUpdateCommand = new UpdateEventCommand($eventUpdateRequest);
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ async function unarchiveEvent(eventId) {
|
|||||||
<div>
|
<div>
|
||||||
<h2 style="margin: 0 0 4px 0; font-size: 1.1rem; font-weight: 600;">{{ event.name }}</h2>
|
<h2 style="margin: 0 0 4px 0; font-size: 1.1rem; font-weight: 600;">{{ event.name }}</h2>
|
||||||
<span style="color: #6b7280; font-size: 0.875rem;">
|
<span style="color: #6b7280; font-size: 0.875rem;">
|
||||||
{{ event.postalCode }} {{ event.location }}
|
{{ event.fullAddress }}
|
||||||
·
|
·
|
||||||
{{ event.eventBegin }} – {{ event.eventEnd }}
|
{{ event.eventBegin }} – {{ event.eventEnd }}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
eventName: '',
|
eventName: '',
|
||||||
eventPostalCode: '',
|
eventPostalCode: '',
|
||||||
eventLocation: '',
|
eventLocation: '',
|
||||||
|
eventStreet: '',
|
||||||
|
eventHouseNumber: '',
|
||||||
eventEmail: props.emailAddress ? props.emailAddress : '',
|
eventEmail: props.emailAddress ? props.emailAddress : '',
|
||||||
eventBegin: '',
|
eventBegin: '',
|
||||||
eventEnd: '',
|
eventEnd: '',
|
||||||
@@ -145,6 +147,8 @@
|
|||||||
eventName: formData.eventName,
|
eventName: formData.eventName,
|
||||||
eventPostalCode: formData.eventPostalCode,
|
eventPostalCode: formData.eventPostalCode,
|
||||||
eventLocation: formData.eventLocation,
|
eventLocation: formData.eventLocation,
|
||||||
|
eventStreet: formData.eventStreet,
|
||||||
|
eventHouseNumber: formData.eventHouseNumber,
|
||||||
eventEmail: formData.eventEmail,
|
eventEmail: formData.eventEmail,
|
||||||
eventBegin: formData.eventBegin,
|
eventBegin: formData.eventBegin,
|
||||||
eventEnd: formData.eventEnd,
|
eventEnd: formData.eventEnd,
|
||||||
@@ -195,6 +199,16 @@
|
|||||||
<ErrorText :message="errors.eventLocation" /></td>
|
<ErrorText :message="errors.eventLocation" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr style="vertical-align: top;">
|
||||||
|
<th class="width-medium pr-20 height-50">Straße (optional)</th>
|
||||||
|
<td class="height-50"><input type="text" v-model="formData.eventStreet" class="width-half-full" /></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr style="vertical-align: top;">
|
||||||
|
<th class="width-medium pr-20 height-50">Hausnummer (optional)</th>
|
||||||
|
<td class="height-50"><input type="text" v-model="formData.eventHouseNumber" class="width-half-full" /></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr style="vertical-align: top;">
|
<tr style="vertical-align: top;">
|
||||||
<th class="width-medium pr-20 height-50">Postleitzahl des Veranstaltungsorts</th>
|
<th class="width-medium pr-20 height-50">Postleitzahl des Veranstaltungsorts</th>
|
||||||
<td class="height-50"><input type="text" v-model="formData.eventPostalCode" class="width-half-full" />
|
<td class="height-50"><input type="text" v-model="formData.eventPostalCode" class="width-half-full" />
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const props = defineProps({
|
|||||||
<div class="available-event-header">
|
<div class="available-event-header">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="available-event-title">{{ event.name }}</h2>
|
<h2 class="available-event-title">{{ event.name }}</h2>
|
||||||
<span class="available-event-location">{{ event.postalCode }} {{ event.location }}</span>
|
<span class="available-event-location">{{ event.fullAddress }}</span>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
v-if="event.registrationAllowed"
|
v-if="event.registrationAllowed"
|
||||||
@@ -47,7 +47,7 @@ const props = defineProps({
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Veranstaltungsort</th>
|
<th>Veranstaltungsort</th>
|
||||||
<td>{{ event.postalCode }} {{ event.location }}</td>
|
<td>{{ event.fullAddress }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Frühbuchen bis</th>
|
<th>Frühbuchen bis</th>
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ const emit = defineEmits(['close'])
|
|||||||
contributingLocalGroups: contributingLocalGroups.value,
|
contributingLocalGroups: contributingLocalGroups.value,
|
||||||
eventName: props.event.name,
|
eventName: props.event.name,
|
||||||
eventLocation: props.event.location,
|
eventLocation: props.event.location,
|
||||||
|
street: props.event.street ?? '',
|
||||||
|
houseNumber: props.event.houseNumber ?? '',
|
||||||
postalCode: props.event.postalCode,
|
postalCode: props.event.postalCode,
|
||||||
email: props.event.email,
|
email: props.event.email,
|
||||||
earlyBirdEnd: props.event.earlyBirdEnd.internal,
|
earlyBirdEnd: props.event.earlyBirdEnd.internal,
|
||||||
@@ -59,6 +61,8 @@ const emit = defineEmits(['close'])
|
|||||||
body: {
|
body: {
|
||||||
eventName: formData.eventName,
|
eventName: formData.eventName,
|
||||||
eventLocation: formData.eventLocation,
|
eventLocation: formData.eventLocation,
|
||||||
|
street: formData.street,
|
||||||
|
houseNumber: formData.houseNumber,
|
||||||
postalCode: formData.postalCode,
|
postalCode: formData.postalCode,
|
||||||
email: formData.email,
|
email: formData.email,
|
||||||
earlyBirdEnd: formData.earlyBirdEnd,
|
earlyBirdEnd: formData.earlyBirdEnd,
|
||||||
@@ -109,6 +113,20 @@ const emit = defineEmits(['close'])
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>Straße (optional)</th>
|
||||||
|
<td>
|
||||||
|
<input type="text" v-model="formData.street" class="width-full" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>Hausnummer (optional)</th>
|
||||||
|
<td>
|
||||||
|
<input type="text" v-model="formData.houseNumber" class="width-full" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Postleitzahl des Veranstaltungsorts</th>
|
<th>Postleitzahl des Veranstaltungsorts</th>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function close() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="signup-event-location">
|
<p class="signup-event-location">
|
||||||
📍 {{ props.event.postalCode }} {{ props.event.location }}
|
📍 {{ props.event.fullAddress }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="signup-header signup-header--closed">
|
<div v-else class="signup-header signup-header--closed">
|
||||||
@@ -49,7 +49,7 @@ function close() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="signup-event-location">
|
<p class="signup-event-location">
|
||||||
📍 {{ props.event.postalCode }} {{ props.event.location }}
|
📍 {{ props.event.fullAddress }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
* @property int $cost_unit_id
|
* @property int $cost_unit_id
|
||||||
* @property string $name
|
* @property string $name
|
||||||
* @property string $location
|
* @property string $location
|
||||||
|
* @property string|null $street
|
||||||
|
* @property string|null $house_number
|
||||||
* @property string $postal_code
|
* @property string $postal_code
|
||||||
* @property string $email
|
* @property string $email
|
||||||
* @property DateTime $start_date
|
* @property DateTime $start_date
|
||||||
@@ -59,6 +61,8 @@ class Event extends InstancedModel
|
|||||||
'name',
|
'name',
|
||||||
'identifier',
|
'identifier',
|
||||||
'location',
|
'location',
|
||||||
|
'street',
|
||||||
|
'house_number',
|
||||||
'postal_code',
|
'postal_code',
|
||||||
'email',
|
'email',
|
||||||
'start_date',
|
'start_date',
|
||||||
@@ -131,6 +135,18 @@ class Event extends InstancedModel
|
|||||||
'swimming_permission_required' => 'boolean',
|
'swimming_permission_required' => 'boolean',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Anschrift des Veranstaltungsorts in einer Zeile. Straße und Hausnummer sind optional -- fehlen sie,
|
||||||
|
* bleibt es bei der bisherigen Ausgabe "PLZ Ort".
|
||||||
|
*/
|
||||||
|
public function getFullAddress(): string
|
||||||
|
{
|
||||||
|
$city = trim($this->postal_code . ' ' . $this->location);
|
||||||
|
$street = trim($this->street . ' ' . $this->house_number);
|
||||||
|
|
||||||
|
return '' === $street ? $city : $street . ', ' . $city;
|
||||||
|
}
|
||||||
|
|
||||||
public function tenant(): BelongsTo
|
public function tenant(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Tenant::class, 'tenant', 'slug');
|
return $this->belongsTo(Tenant::class, 'tenant', 'slug');
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ class EventParticipantResource extends JsonResource
|
|||||||
default => 'Nicht geprüft',
|
default => 'Nicht geprüft',
|
||||||
},
|
},
|
||||||
'eventName' => $this->resource->event()->first()->name,
|
'eventName' => $this->resource->event()->first()->name,
|
||||||
|
'eventAddress' => $event->getFullAddress(),
|
||||||
'arrivalDateReadable' => $this->resource->arrival_date->format('d.m.Y'),
|
'arrivalDateReadable' => $this->resource->arrival_date->format('d.m.Y'),
|
||||||
'departureDateReadable' => $this->resource->departure_date->format('d.m.Y'),
|
'departureDateReadable' => $this->resource->departure_date->format('d.m.Y'),
|
||||||
'participationOptions' => $this->resource->selectedOptions()->get()->map(
|
'participationOptions' => $this->resource->selectedOptions()->get()->map(
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ class EventResource extends JsonResource{
|
|||||||
'url' => 'https://' . currentTenant()->url . '/event/' . $this->event->identifier . '/signup',
|
'url' => 'https://' . currentTenant()->url . '/event/' . $this->event->identifier . '/signup',
|
||||||
'urlShort' => 'https://' . currentTenant()->url . '/event/' . $this->event->identifier,
|
'urlShort' => 'https://' . currentTenant()->url . '/event/' . $this->event->identifier,
|
||||||
'location' => $this->event->location,
|
'location' => $this->event->location,
|
||||||
|
'street' => $this->event->street,
|
||||||
|
'houseNumber' => $this->event->house_number,
|
||||||
'postalCode' => $this->event->postal_code,
|
'postalCode' => $this->event->postal_code,
|
||||||
|
// Fertig formatierte Anschrift für alle Anzeigen -- die Einzelfelder brauchen nur die
|
||||||
|
// Bearbeitungsformulare.
|
||||||
|
'fullAddress' => $this->event->getFullAddress(),
|
||||||
'email' => $this->event->email,
|
'email' => $this->event->email,
|
||||||
'accountOwner' => $this->event->account_owner,
|
'accountOwner' => $this->event->account_owner,
|
||||||
'accountIban' => $this->event->account_iban,
|
'accountIban' => $this->event->account_iban,
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Der Veranstaltungsort war bisher nur PLZ und Ort. Straße und Hausnummer kommen dazu, bleiben aber
|
||||||
|
* optional: Bestandsveranstaltungen haben sie nicht, und bei der Anlage sind sie oft noch unbekannt.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('events', function (Blueprint $table) {
|
||||||
|
$table->string('street')->nullable()->after('location');
|
||||||
|
$table->string('house_number')->nullable()->after('street');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('events', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['street', 'house_number']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Domains\Event\Actions\CreateEvent\CreateEventCommand;
|
||||||
|
use App\Domains\Event\Actions\CreateEvent\CreateEventRequest;
|
||||||
|
use App\Domains\Event\Actions\UpdateEvent\UpdateEventCommand;
|
||||||
|
use App\Domains\Event\Actions\UpdateEvent\UpdateEventRequest;
|
||||||
|
use App\Enumerations\CostUnitType;
|
||||||
|
use App\Enumerations\EatingHabit;
|
||||||
|
use App\Enumerations\ParticipationFeeType;
|
||||||
|
use App\Models\CostUnit;
|
||||||
|
use App\Models\Event;
|
||||||
|
use App\Models\Tenant;
|
||||||
|
use App\Resources\EventResource;
|
||||||
|
use App\ValueObjects\Amount;
|
||||||
|
use DateTime;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class EventAddressTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
private Tenant $tenant;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->tenant = Tenant::create([
|
||||||
|
'slug' => 'tv',
|
||||||
|
'name' => 'Test',
|
||||||
|
'email' => 't@example.com',
|
||||||
|
'email_finance' => 'finance@example.com',
|
||||||
|
'url' => 'test.local',
|
||||||
|
'account_name' => 'Test e.V.',
|
||||||
|
'account_iban' => 'DE00',
|
||||||
|
'account_bic' => 'XY',
|
||||||
|
'city' => 'Stadt',
|
||||||
|
'postcode' => '00000',
|
||||||
|
'is_active_local_group' => true,
|
||||||
|
'has_active_instance' => true,
|
||||||
|
'tax_liable' => false,
|
||||||
|
'vat_rate' => 0,
|
||||||
|
'vat_pricing_mode' => 'inclusive',
|
||||||
|
]);
|
||||||
|
|
||||||
|
app()->instance('tenant', $this->tenant);
|
||||||
|
|
||||||
|
DB::table('cost_unit_types')->insert(['slug' => CostUnitType::COST_UNIT_TYPE_EVENT, 'name' => 'Veranstaltung']);
|
||||||
|
DB::table('participation_types')->insert(['slug' => 'participant', 'name' => 'Teilnehmer']);
|
||||||
|
DB::table('participation_fee_types')->insert(['slug' => 'fixed', 'name' => 'Fix']);
|
||||||
|
EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_VEGAN, 'name' => 'Vegan']);
|
||||||
|
EatingHabit::create(['slug' => EatingHabit::EATING_HABIT_VEGETARIAN, 'name' => 'Vegetarisch']);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createEvent(?string $street = null, ?string $houseNumber = null): Event
|
||||||
|
{
|
||||||
|
$response = new CreateEventCommand(new CreateEventRequest(
|
||||||
|
name: 'Sommerlager',
|
||||||
|
location: 'Leipzig',
|
||||||
|
postalCode: '04103',
|
||||||
|
email: 'e@example.com',
|
||||||
|
begin: new DateTime('2026-09-01'),
|
||||||
|
end: new DateTime('2026-09-05'),
|
||||||
|
earlyBirdEnd: new DateTime('2026-08-20'),
|
||||||
|
registrationFinalEnd: new DateTime('2026-08-25'),
|
||||||
|
earlyBirdEndAmountIncrease: 0,
|
||||||
|
participationFeeType: ParticipationFeeType::where('slug', 'fixed')->first(),
|
||||||
|
accountOwner: 'Owner',
|
||||||
|
accountIban: 'DE00',
|
||||||
|
payPerDay: false,
|
||||||
|
street: $street,
|
||||||
|
houseNumber: $houseNumber,
|
||||||
|
))->execute();
|
||||||
|
|
||||||
|
$this->assertTrue($response->success);
|
||||||
|
|
||||||
|
return $response->event->fresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function updateEvent(Event $event, ?string $street, ?string $houseNumber): Event
|
||||||
|
{
|
||||||
|
$response = new UpdateEventCommand(new UpdateEventRequest(
|
||||||
|
event: $event,
|
||||||
|
eventName: $event->name,
|
||||||
|
eventLocation: $event->location,
|
||||||
|
postalCode: $event->postal_code,
|
||||||
|
email: $event->email,
|
||||||
|
earlyBirdEnd: new DateTime('2026-08-20'),
|
||||||
|
registrationFinalEnd: new DateTime('2026-08-25'),
|
||||||
|
alcoholicsAge: 16,
|
||||||
|
sendWeeklyReports: true,
|
||||||
|
registrationAllowed: true,
|
||||||
|
flatSupport: Amount::fromString('0,00'),
|
||||||
|
supportPerPerson: Amount::fromString('0,00'),
|
||||||
|
contributingLocalGroups: [],
|
||||||
|
eatingHabits: [],
|
||||||
|
street: $street,
|
||||||
|
houseNumber: $houseNumber,
|
||||||
|
))->execute();
|
||||||
|
|
||||||
|
$this->assertTrue($response->success);
|
||||||
|
|
||||||
|
return $event->fresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_anlage_speichert_strasse_und_hausnummer(): void
|
||||||
|
{
|
||||||
|
$event = $this->createEvent('Musterweg', '12');
|
||||||
|
|
||||||
|
$this->assertSame('Musterweg', $event->street);
|
||||||
|
$this->assertSame('12', $event->house_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_anlage_ohne_angabe_laesst_beide_felder_leer(): void
|
||||||
|
{
|
||||||
|
$event = $this->createEvent();
|
||||||
|
|
||||||
|
$this->assertNull($event->street);
|
||||||
|
$this->assertNull($event->house_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_leere_eingaben_werden_bei_der_anlage_zu_null(): void
|
||||||
|
{
|
||||||
|
$event = $this->createEvent('', ' ');
|
||||||
|
|
||||||
|
$this->assertNull($event->street);
|
||||||
|
$this->assertNull($event->house_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_einstellungen_ergaenzen_und_leeren_die_anschrift(): void
|
||||||
|
{
|
||||||
|
$event = $this->updateEvent($this->createEvent(), 'Musterweg', '12');
|
||||||
|
|
||||||
|
$this->assertSame('Musterweg', $event->street);
|
||||||
|
$this->assertSame('12', $event->house_number);
|
||||||
|
|
||||||
|
$event = $this->updateEvent($event, '', '');
|
||||||
|
|
||||||
|
$this->assertNull($event->street);
|
||||||
|
$this->assertNull($event->house_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_anschrift_enthaelt_strasse_nur_wenn_sie_gefuellt_ist(): void
|
||||||
|
{
|
||||||
|
$this->assertSame('Musterweg 12, 04103 Leipzig', $this->createEvent('Musterweg', '12')->getFullAddress());
|
||||||
|
$this->assertSame('04103 Leipzig', $this->createEvent()->getFullAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_resource_liefert_einzelfelder_und_fertige_anschrift(): void
|
||||||
|
{
|
||||||
|
$event = $this->createEvent('Musterweg', '12');
|
||||||
|
|
||||||
|
// Die Resource gibt auch die Kostenstelle aus; im Betrieb legt der Controller sie direkt nach
|
||||||
|
// der Veranstaltung an.
|
||||||
|
$event->cost_unit_id = CostUnit::create([
|
||||||
|
'tenant' => $this->tenant->slug,
|
||||||
|
'name' => 'Sommerlager',
|
||||||
|
'type' => CostUnitType::COST_UNIT_TYPE_EVENT,
|
||||||
|
'distance_allowance' => 0.25,
|
||||||
|
'mail_on_new' => false,
|
||||||
|
'allow_new' => true,
|
||||||
|
'archived' => false,
|
||||||
|
])->id;
|
||||||
|
$event->save();
|
||||||
|
|
||||||
|
$resource = new EventResource($event)->toArray(new Request());
|
||||||
|
|
||||||
|
$this->assertSame('Musterweg', $resource['street']);
|
||||||
|
$this->assertSame('12', $resource['houseNumber']);
|
||||||
|
$this->assertSame('Musterweg 12, 04103 Leipzig', $resource['fullAddress']);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user