Handling SEPA Direct Payment
This commit is contained in:
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace App\Domains\Event\Actions\SetPaymentMethods;
|
||||
|
||||
use App\EventPaymentModules\EventPaymentModuleRegistry;
|
||||
use App\Models\AvailablePaymentMethod;
|
||||
use App\Models\PaymentMethod;
|
||||
use App\RelationModels\EventPaymentMethods;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class SetPaymentMethodsCommand
|
||||
{
|
||||
@@ -25,7 +27,22 @@ class SetPaymentMethodsCommand
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->syncPaymentMethods();
|
||||
$existing = EventPaymentMethods::where('event_id', $this->request->event->id)->get()->keyBy('slug');
|
||||
$configurations = $this->configurationsToWrite($existing);
|
||||
|
||||
// Erst prüfen, dann schreiben: Eine Zahlungsart, die am Event unvollständig konfiguriert wäre,
|
||||
// ließe sich bei der Anmeldung wählen, ohne dass die Angaben für die Zahlung vorliegen.
|
||||
$incomplete = $this->incompleteNames($configurations);
|
||||
if ($incomplete !== []) {
|
||||
$response->success = false;
|
||||
$response->message = sprintf(
|
||||
'Die Konfiguration von „%s" ist unvollständig oder ungültig.',
|
||||
implode('", „', $incomplete),
|
||||
);
|
||||
return $response;
|
||||
}
|
||||
|
||||
$this->syncPaymentMethods($existing, $configurations);
|
||||
|
||||
$this->request->event->save();
|
||||
$response->success = true;
|
||||
@@ -34,48 +51,87 @@ class SetPaymentMethodsCommand
|
||||
}
|
||||
|
||||
/**
|
||||
* Differenzieller Sync der Zahlungsmethoden mit Snapshot-Copy-Semantik:
|
||||
* - entfernte Methoden werden gelöscht,
|
||||
* Die Configs, die geschrieben werden (Snapshot-Copy-Semantik):
|
||||
* - neue Methoden erhalten einen Snapshot der Tenant-Config (oder eines expliziten Overrides),
|
||||
* - bestehende Methoden behalten ihre pro-Event-Config, sofern kein Override übergeben wird.
|
||||
* - bestehende Methoden behalten ihre pro-Event-Config, sofern kein Override übergeben wird --
|
||||
* sie tauchen hier dann nicht auf.
|
||||
*
|
||||
* @param Collection<string, EventPaymentMethods> $existing
|
||||
* @return array<string, array<string, mixed>> slug => Config
|
||||
*/
|
||||
private function syncPaymentMethods(): void
|
||||
private function configurationsToWrite(Collection $existing): array
|
||||
{
|
||||
$event = $this->request->event;
|
||||
$desiredSlugs = $this->request->paymentMethods;
|
||||
$overrides = $this->request->paymentMethodConfigurations;
|
||||
|
||||
$existing = EventPaymentMethods::where('event_id', $event->id)->get()->keyBy('slug');
|
||||
|
||||
// Nicht mehr gewünschte Methoden entfernen.
|
||||
foreach ($existing as $slug => $row) {
|
||||
if (!in_array($slug, $desiredSlugs, true)) {
|
||||
$row->delete();
|
||||
}
|
||||
}
|
||||
|
||||
// Tenant-Instanzen (für Snapshot-Kopie neuer Methoden) laden.
|
||||
$tenantMethods = AvailablePaymentMethod::whereIn('slug', $desiredSlugs)->get()->keyBy('slug');
|
||||
|
||||
$configurations = [];
|
||||
foreach ($desiredSlugs as $slug) {
|
||||
$override = $overrides[$slug] ?? null;
|
||||
|
||||
if (isset($existing[$slug])) {
|
||||
// Bestehende Zuweisung: Config nur bei explizitem Override anpassen, sonst unverändert lassen.
|
||||
if ($override !== null) {
|
||||
$row = $existing[$slug];
|
||||
$row->configuration = $this->eventConfiguration($slug, $override);
|
||||
$row->save();
|
||||
}
|
||||
if (isset($existing[$slug]) && $override === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Neue Zuweisung: expliziter Override oder Snapshot der Tenant-Config.
|
||||
$snapshot = $override ?? ($tenantMethods[$slug]->configuration ?? []);
|
||||
$configurations[$slug] = $this->eventConfiguration($slug, $snapshot ?? []);
|
||||
}
|
||||
|
||||
return $configurations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Namen der Zahlungsarten, deren Config nicht vollständig oder nicht gültig ist.
|
||||
*
|
||||
* Geprüft wird auf der Event-Config, also ohne die tenant-weiten Optionen -- die sind ohnehin nie
|
||||
* Pflicht, weil sie am Event gar nicht liegen.
|
||||
*
|
||||
* @param array<string, array<string, mixed>> $configurations
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function incompleteNames(array $configurations): array
|
||||
{
|
||||
$names = [];
|
||||
foreach ($configurations as $slug => $configuration) {
|
||||
if (!PaymentMethod::isConfigurationComplete($slug, $configuration)) {
|
||||
$names[] = EventPaymentModuleRegistry::forSlug($slug)?->defaultName() ?? $slug;
|
||||
}
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Differenzieller Sync: entfernte Methoden werden gelöscht, die vorbereiteten Configs geschrieben.
|
||||
*
|
||||
* @param Collection<string, EventPaymentMethods> $existing
|
||||
* @param array<string, array<string, mixed>> $configurations
|
||||
*/
|
||||
private function syncPaymentMethods(Collection $existing, array $configurations): void
|
||||
{
|
||||
$event = $this->request->event;
|
||||
|
||||
// Nicht mehr gewünschte Methoden entfernen.
|
||||
foreach ($existing as $slug => $row) {
|
||||
if (!in_array($slug, $this->request->paymentMethods, true)) {
|
||||
$row->delete();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($configurations as $slug => $configuration) {
|
||||
if (isset($existing[$slug])) {
|
||||
$row = $existing[$slug];
|
||||
$row->configuration = $configuration;
|
||||
$row->save();
|
||||
continue;
|
||||
}
|
||||
|
||||
EventPaymentMethods::create([
|
||||
'event_id' => $event->id,
|
||||
'slug' => $slug,
|
||||
'configuration' => $this->eventConfiguration($slug, $snapshot ?? []),
|
||||
'configuration' => $configuration,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Enumerations\EatingHabit;
|
||||
use App\Enumerations\EfzStatus;
|
||||
use App\Enumerations\SwimmingPermission;
|
||||
use App\EventPaymentModules\EventPaymentModuleRegistry;
|
||||
use App\Repositories\PaymentMethodRepository;
|
||||
use App\ValueObjects\Age;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -17,6 +18,14 @@ class SignUpCommand {
|
||||
public function execute() : SignUpResponse {
|
||||
$response = new SignUpResponse();
|
||||
|
||||
// Nur eine Zahlungsart, die am Event hängt, aktiv und vollständig konfiguriert ist.
|
||||
if ($this->request->paymentMethod !== null
|
||||
&& !new PaymentMethodRepository()->isUsableForSignUp($this->request->event, $this->request->paymentMethod)) {
|
||||
$response->success = false;
|
||||
$response->message = 'Die gewählte Zahlungsart steht für diese Veranstaltung nicht zur Verfügung.';
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Teilnehmer-Eingaben der gewählten Zahlungsart gegen das Modul-Schema absichern.
|
||||
$module = $this->request->paymentMethod !== null
|
||||
? EventPaymentModuleRegistry::forSlug($this->request->paymentMethod)
|
||||
|
||||
Reference in New Issue
Block a user