feat: implement payment step
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Form\Model;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
/**
|
||||
* DTO for bank account information used in payment processing.
|
||||
*/
|
||||
class BankAccountDto
|
||||
{
|
||||
#[Assert\NotBlank(message: 'Bitte geben Sie Ihre IBAN ein.')]
|
||||
#[Assert\Iban(message: 'Die eingegebene IBAN ist ungültig.')]
|
||||
public ?string $iban = null;
|
||||
|
||||
#[Assert\NotBlank(message: 'Bitte geben Sie den Kontoinhaber ein.')]
|
||||
#[Assert\Length(
|
||||
min: 2,
|
||||
max: 70,
|
||||
minMessage: 'Der Kontoinhaber muss mindestens {{ limit }} Zeichen lang sein.',
|
||||
maxMessage: 'Der Kontoinhaber darf maximal {{ limit }} Zeichen lang sein.'
|
||||
)]
|
||||
public ?string $accountHolder = null;
|
||||
|
||||
#[Assert\Length(
|
||||
max: 70,
|
||||
maxMessage: 'Der Bankname darf maximal {{ limit }} Zeichen lang sein.'
|
||||
)]
|
||||
public ?string $bankName = null;
|
||||
|
||||
#[Assert\IsTrue(message: 'Bitte akzeptieren Sie das SEPA-Mandat.')]
|
||||
public bool $sepaMandateAccepted = false;
|
||||
|
||||
/**
|
||||
* Returns IBAN formatted with spaces for display (e.g., DE12 3456 7890 1234 5678 90).
|
||||
*/
|
||||
public function getFormattedIban(): ?string
|
||||
{
|
||||
if (null === $this->iban) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cleanIban = $this->getIbanWithoutSpaces();
|
||||
|
||||
return chunk_split($cleanIban, 4, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns IBAN without spaces for storage and API submission.
|
||||
*/
|
||||
public function getIbanWithoutSpaces(): ?string
|
||||
{
|
||||
if (null === $this->iban) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string) preg_replace('/\s+/', '', $this->iban);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Form\Model;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
@@ -22,6 +23,14 @@ class BookingCreateDto implements BookingDtoInterface
|
||||
#[Assert\Valid]
|
||||
public array $participants = [];
|
||||
|
||||
#[Assert\Choice(
|
||||
choices: [Constants::PAYMENT_METHOD_TRANSFER, Constants::PAYMENT_METHOD_DEBIT],
|
||||
message: 'Bitte wählen Sie eine gültige Zahlungsart.'
|
||||
)]
|
||||
public ?string $paymentMethod = Constants::PAYMENT_METHOD_TRANSFER;
|
||||
|
||||
public ?BankAccountDto $bankAccount = null;
|
||||
|
||||
public function __construct(public Travel $travel, public int $hotelId)
|
||||
{
|
||||
}
|
||||
@@ -95,4 +104,41 @@ class BookingCreateDto implements BookingDtoInterface
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
|
||||
#[Assert\Callback]
|
||||
public function validateBankAccount(ExecutionContextInterface $context): void
|
||||
{
|
||||
if (Constants::PAYMENT_METHOD_DEBIT !== $this->paymentMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $this->bankAccount) {
|
||||
$context->buildViolation('Bitte geben Sie Ihre Bankverbindung an.')
|
||||
->atPath('bankAccount')
|
||||
->addViolation();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate IBAN
|
||||
if (null === $this->bankAccount->iban || '' === trim($this->bankAccount->iban)) {
|
||||
$context->buildViolation('Bitte geben Sie Ihre IBAN ein.')
|
||||
->atPath('bankAccount.iban')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
// Validate account holder
|
||||
if (null === $this->bankAccount->accountHolder || '' === trim($this->bankAccount->accountHolder)) {
|
||||
$context->buildViolation('Bitte geben Sie den Kontoinhaber ein.')
|
||||
->atPath('bankAccount.accountHolder')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
// Validate SEPA mandate
|
||||
if (false === $this->bankAccount->sepaMandateAccepted) {
|
||||
$context->buildViolation('Bitte akzeptieren Sie das SEPA-Mandat.')
|
||||
->atPath('bankAccount.sepaMandateAccepted')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,28 @@ use Symfony\Component\Validator\Constraints as Assert;
|
||||
#[AppAssert\Participant(groups: ['booking_edit', 'booking_create_step_2'])]
|
||||
class ParticipantDto
|
||||
{
|
||||
/**
|
||||
* List of dynamic participant fields that can be conditionally hidden/shown.
|
||||
*/
|
||||
public const DYNAMIC_FIELDS = [
|
||||
'assignedRoomId',
|
||||
'remarksRoom',
|
||||
'courses',
|
||||
'additionalServices',
|
||||
'board',
|
||||
'rentals',
|
||||
'rentalInsurance',
|
||||
'skiPass',
|
||||
'transportationOutbound',
|
||||
'transportationInbound',
|
||||
'pickupOutbound',
|
||||
'pickupInbound',
|
||||
'parking',
|
||||
'licensePlate',
|
||||
'bulkInsuranceBooking',
|
||||
'insurance',
|
||||
];
|
||||
|
||||
public ?int $index = null;
|
||||
public ?int $addressId = null;
|
||||
public ?int $personId = null;
|
||||
|
||||
Reference in New Issue
Block a user