diff --git a/src/BusProNet/Model/Pickup.php b/src/BusProNet/Model/Pickup.php index d4ae1c1..62c6a77 100644 --- a/src/BusProNet/Model/Pickup.php +++ b/src/BusProNet/Model/Pickup.php @@ -76,10 +76,14 @@ class Pickup { $label = $this->getLabel(); - if (null === $this->price || 0.0 === $this->price) { + if (null === $this->price) { return $label; } + if (0.0 === $this->price) { + return sprintf('%s (inkl.)', $label); + } + if ($this->price < 0) { return sprintf('%s (-%s€ Rabatt)', $label, number_format(abs($this->price), 2, ',', '.')); } diff --git a/src/Form/BookingEditParticipantType.php b/src/Form/BookingEditParticipantType.php index e147be3..39fb931 100644 --- a/src/Form/BookingEditParticipantType.php +++ b/src/Form/BookingEditParticipantType.php @@ -102,10 +102,14 @@ class BookingEditParticipantType extends AbstractType 'choice_value' => 'id', 'choice_label' => function (?Service $service) use ($participantIndex) { $price = $service->individualPrice[$participantIndex] ?? $service->price; - if (null === $price || 0.0 === $price) { + if (null === $price) { return $service->label; } + if (0.0 === $price) { + return sprintf('%s (inkl.)', $service->label); + } + return sprintf( '%s (%s €)', $service->label, @@ -256,10 +260,14 @@ class BookingEditParticipantType extends AbstractType $price = $pickup->price; - if (null === $price || 0.0 === $price) { + if (null === $price) { return $pickupLabel; } + if (0.0 === $price) { + return sprintf('%s (inkl.)', $pickupLabel); + } + return sprintf( '%s %s€', $pickupLabel, diff --git a/src/Form/Service/ParticipantFieldOptionsProvider.php b/src/Form/Service/ParticipantFieldOptionsProvider.php index 4a9bcdc..969867f 100644 --- a/src/Form/Service/ParticipantFieldOptionsProvider.php +++ b/src/Form/Service/ParticipantFieldOptionsProvider.php @@ -605,10 +605,14 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider return ''; } - if (null === $service->price || 0.0 === $service->price) { + if (null === $service->price) { return $service->label; } + if (0.0 === $service->price) { + return sprintf('%s (inkl.)', $service->label); + } + if ($service->price < 0) { // Negative prices are discounts return sprintf('%s (-%s€ Rabatt)', $service->label, number_format(abs($service->price), 2, ',', '.')); diff --git a/src/Service/ParticipantCardDataService.php b/src/Service/ParticipantCardDataService.php index 9066fc8..1165870 100644 --- a/src/Service/ParticipantCardDataService.php +++ b/src/Service/ParticipantCardDataService.php @@ -86,7 +86,7 @@ class ParticipantCardDataService $name = trim($firstName.' '.$lastName); if ('' === $name) { - return 0 === $index ? 'Anmelder:in' : sprintf('Teilnehmer:in %d', $index); + return 0 === $index ? 'Anmelder:in' : 'Teilnehmer:in'; } return $name; diff --git a/src/Service/ServicePricingCalculator.php b/src/Service/ServicePricingCalculator.php index eed8e89..be19dfa 100644 --- a/src/Service/ServicePricingCalculator.php +++ b/src/Service/ServicePricingCalculator.php @@ -217,10 +217,6 @@ class ServicePricingCalculator $servicesBySubtypeAndSign = []; foreach ($serviceAggregation as $serviceData) { - if (0.0 === $serviceData['totalPrice']) { - continue; // Skip zero-price services - } - $subType = $serviceData['subType'] ?? 'other'; // Normalize rental subtypes to avoid duplicate sections diff --git a/src/Twig/AppExtension.php b/src/Twig/AppExtension.php index 86ee014..a5fe3f1 100644 --- a/src/Twig/AppExtension.php +++ b/src/Twig/AppExtension.php @@ -14,6 +14,7 @@ class AppExtension extends AbstractExtension new TwigFilter('file_size', [AppRuntime::class, 'formatBytes']), new TwigFilter('file_icon', [AppRuntime::class, 'fileIconFilter'], ['is_safe' => ['html']]), new TwigFilter('format_money', [AppRuntime::class, 'formatMoney']), + new TwigFilter('format_service_price', [AppRuntime::class, 'formatServicePrice']), new TwigFilter('map_gender', [AppRuntime::class, 'mapGender']), new TwigFilter('map_status', [AppRuntime::class, 'mapStatus']), new TwigFilter('map_country', [AppRuntime::class, 'mapCountry']), diff --git a/src/Twig/AppRuntime.php b/src/Twig/AppRuntime.php index 5081871..9c4a001 100644 --- a/src/Twig/AppRuntime.php +++ b/src/Twig/AppRuntime.php @@ -52,6 +52,26 @@ class AppRuntime implements RuntimeExtensionInterface return $this->intlExtension->formatCurrency($amount, 'EUR'); } + /** + * Formats a service price, showing "inkl." for zero-priced (included) services. + * + * @param float|int|null $price The price to format + * + * @return string The formatted price or "inkl." for zero/null prices + */ + public function formatServicePrice(float|int|null $price): string + { + if (null === $price) { + return ''; + } + + if (0 === $price || 0.0 === $price) { + return 'inkl.'; + } + + return $this->intlExtension->formatCurrency((float) $price, 'EUR'); + } + public function mapStatus(string $status): string { $status = strtoupper($status); diff --git a/templates/booking/_form_theme.html.twig b/templates/booking/_form_theme.html.twig index 578b69d..2509064 100644 --- a/templates/booking/_form_theme.html.twig +++ b/templates/booking/_form_theme.html.twig @@ -67,8 +67,8 @@ {% if choiceData %}