168 lines
5.5 KiB
PHP
168 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Form\Model;
|
|
|
|
use App\BusProNet\Model\Insurance;
|
|
use App\BusProNet\Model\PersonalData;
|
|
use App\BusProNet\Model\Pickup;
|
|
use App\BusProNet\Model\Service;
|
|
use App\Validator\Constraints as AppAssert;
|
|
use Symfony\Component\Validator\Constraints as Assert;
|
|
|
|
#[AppAssert\Participant(groups: ['booking_edit', 'booking_create_step_2'])]
|
|
class ParticipantDto
|
|
{
|
|
public ?int $index = null;
|
|
public ?int $addressId = null;
|
|
public ?int $personId = null;
|
|
public ?string $status = null;
|
|
public bool $mutable = false;
|
|
|
|
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['booking_edit', 'booking_create_step_2'])]
|
|
public ?string $firstName = null;
|
|
|
|
#[Assert\NotBlank(message: 'Bitte angeben', groups: ['booking_edit', 'booking_create_step_2'])]
|
|
public ?string $lastName = null;
|
|
public ?string $title = null;
|
|
public ?string $gender = null;
|
|
public ?string $nationality = null;
|
|
|
|
public ?string $height = null;
|
|
public ?string $shoeSize = null;
|
|
public ?string $weight = null;
|
|
|
|
#[Assert\NotNull(message: 'Bitte angeben', groups: ['booking_edit', 'booking_create_step_2'])]
|
|
public ?\DateTimeImmutable $dateOfBirth = null;
|
|
|
|
#[Assert\Email(message: 'Bitte eine gültige E-Mail Adresse angeben', mode: 'strict', groups: ['booking_edit', 'booking_create_step_2'])]
|
|
public ?string $email = null;
|
|
|
|
public ?string $mobile = null;
|
|
|
|
#[Assert\NotNull(message: 'Bitte ein Zimmer auswählen', groups: ['booking_create_step_2'])]
|
|
public ?int $assignedRoomId = null;
|
|
|
|
public ?string $remarksRoom = null;
|
|
|
|
public array $courses = [];
|
|
public array $additionalServices = [];
|
|
public ?Service $skiPass = null;
|
|
public array $board = [];
|
|
public array $rentals = [];
|
|
public ?Service $rentalInsurance = null;
|
|
|
|
// Rental insurance checkbox state (boolean: true if rental insurance requested)
|
|
public bool $rentalInsuranceSelected = false;
|
|
|
|
// Transportation services with improved naming (outbound/inbound)
|
|
public ?Service $transportationOutbound = null;
|
|
public ?Service $transportationInbound = null;
|
|
|
|
// Pickup locations for each direction
|
|
public ?Pickup $pickupOutbound = null;
|
|
public ?Pickup $pickupInbound = null;
|
|
|
|
// Parking service for self-organized transportation (boolean: true if parking requested)
|
|
public bool $parking = false;
|
|
|
|
// Parking service object for pricing calculation (new, contains actual service with pricing)
|
|
public ?Service $parkingService = null;
|
|
|
|
// License plate for participants with parking (optional, visible only when parking is selected)
|
|
public ?string $licensePlate = null;
|
|
|
|
// Selected insurance for this participant (individual insurance selection per participant)
|
|
public ?Insurance $insurance = null;
|
|
|
|
// Bulk insurance booking flag (applicant only: when checked, assigns same insurance type to all participants)
|
|
public bool $bulkInsuranceBooking = false;
|
|
|
|
public static function fromPersonalData(PersonalData $personalData): static
|
|
{
|
|
$instance = new static();
|
|
|
|
$instance->status = $personalData->status;
|
|
$instance->addressId = $personalData->addressId;
|
|
$instance->personId = $personalData->personId;
|
|
$instance->mutable = $personalData->mutable;
|
|
$instance->firstName = $personalData->firstName;
|
|
$instance->lastName = $personalData->name;
|
|
$instance->gender = $personalData->gender;
|
|
$instance->nationality = $personalData->nationality;
|
|
$instance->email = $personalData->communication?->email;
|
|
$instance->mobile = $personalData->communication?->mobile;
|
|
$instance->dateOfBirth = $personalData->dateOfBirth;
|
|
$instance->height = $personalData->height;
|
|
$instance->weight = $personalData->weight;
|
|
$instance->shoeSize = $personalData->shoeSize;
|
|
|
|
return $instance;
|
|
}
|
|
|
|
public function isApplicant(): bool
|
|
{
|
|
return 0 === $this->index;
|
|
}
|
|
|
|
public function isCanceled(): bool
|
|
{
|
|
return 'S' === $this->status;
|
|
}
|
|
|
|
public function isOption(): bool
|
|
{
|
|
return 'O' === $this->status;
|
|
}
|
|
|
|
/**
|
|
* Calculates the participant's age in complete years.
|
|
*
|
|
* Uses the same logic as existing age evaluators in the system
|
|
* for consistency across age-related calculations.
|
|
*
|
|
* @param \DateTimeImmutable|null $referenceDate The date to calculate age at (defaults to current date)
|
|
*
|
|
* @return int|null The calculated age in complete years, or null if no birth date
|
|
*/
|
|
public function getAge(?\DateTimeImmutable $referenceDate = null): ?int
|
|
{
|
|
if (null === $this->dateOfBirth) {
|
|
return null;
|
|
}
|
|
|
|
$referenceDate = $referenceDate ?? new \DateTimeImmutable();
|
|
|
|
return $this->dateOfBirth->diff($referenceDate)->y;
|
|
}
|
|
|
|
/**
|
|
* Checks if the participant has selected an insurance.
|
|
*
|
|
* @return bool True if an insurance is selected
|
|
*/
|
|
public function hasInsurance(): bool
|
|
{
|
|
return null !== $this->insurance;
|
|
}
|
|
|
|
/**
|
|
* Gets the insurance label for display purposes.
|
|
*
|
|
* @return string|null The insurance label or null if no insurance selected
|
|
*/
|
|
public function getInsuranceLabel(): ?string
|
|
{
|
|
return $this->insurance?->label;
|
|
}
|
|
|
|
/**
|
|
* Gets the insurance price for pricing calculations.
|
|
*
|
|
* @return float The insurance price (0.0 if no insurance selected)
|
|
*/
|
|
public function getInsurancePrice(): float
|
|
{
|
|
return $this->insurance?->price ?? 0.0;
|
|
}
|
|
}
|