wip: show pricing

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent 6bd483d768
commit bd5c6359fe
19 changed files with 602 additions and 183 deletions
@@ -69,7 +69,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
protected function registerFieldOptionProviders(): void
{
// Room assignment field provider (only available for create workflow)
$this->fieldOptionProviders['assignedRoomId'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['assignedRoomId'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Zimmer',
'placeholder' => 'Bitte wählen',
// Use factory to create context-aware choice loader that:
@@ -86,7 +86,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
];
// Courses field provider - provides age-appropriate courses from travel data
$this->fieldOptionProviders['courses'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['courses'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Kurse',
'multiple' => true,
'expanded' => true,
@@ -97,11 +97,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
$participantIndex
),
'choice_value' => 'id',
'choice_label' => 'label',
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
];
// Additional services field provider - provides age-appropriate additional services with mandatory pre-selection
$this->fieldOptionProviders['additionalServices'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['additionalServices'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Zusatzleistungen',
'multiple' => true,
'expanded' => true,
@@ -112,7 +112,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
$participantIndex
),
'choice_value' => 'id',
'choice_label' => 'label',
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
'choice_attr' => function (?Service $service) {
if (null === $service) {
return [];
@@ -133,7 +133,7 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
];
// Board field provider - provides age-appropriate board options from travel data
$this->fieldOptionProviders['board'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['board'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Verpflegung',
'multiple' => true,
'expanded' => true,
@@ -144,11 +144,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
$participantIndex
),
'choice_value' => 'id',
'choice_label' => 'label',
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
];
// Rentals field provider - provides age-appropriate rental options from travel data filtered by date range
$this->fieldOptionProviders['rentals'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['rentals'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Leihmaterial',
'multiple' => true,
'expanded' => true,
@@ -159,11 +159,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
$participantIndex
),
'choice_value' => 'id',
'choice_label' => 'label',
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
];
// Skipass field provider - provides age-appropriate skipass options from travel data filtered by date range
$this->fieldOptionProviders['skiPass'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['skiPass'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Skipass',
'multiple' => false,
'expanded' => true,
@@ -174,11 +174,11 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
$participantIndex
),
'choice_value' => 'id',
'choice_label' => 'label',
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
];
// Room remarks field provider - provides textarea for room-specific remarks (only for 'mbz' rooms)
$this->fieldOptionProviders['remarksRoom'] = fn (BookingDtoInterface $bookingDto, int $participantIndex) => [
$this->fieldOptionProviders['remarksRoom'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
'label' => 'Wünsche oder Anmerkungen zum Zimmer',
'required' => false,
'clean_xss' => true,
@@ -199,6 +199,26 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
// ];
}
/**
* Formats service label with pricing information.
*
* @param Service|null $service The service to format
*
* @return string The formatted label
*/
private function formatServiceLabelWithPrice(?Service $service): string
{
if (null === $service) {
return '';
}
if (null === $service->price || 0.0 === $service->price) {
return $service->label;
}
return sprintf('%s (€%s)', $service->label, number_format($service->price, 2, ',', '.'));
}
/**
* Filters services based on participant's age constraints.
*