wip: transportation services
This commit is contained in:
@@ -5,7 +5,9 @@ declare(strict_types=1);
|
||||
namespace App\Form\Service;
|
||||
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Pickup;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\BusProNet\Utility\DirectionMapper;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use App\Form\Model\BookingDtoInterface;
|
||||
use App\Form\Service\Abstract\AbstractFieldOptionsProvider;
|
||||
@@ -187,6 +189,75 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
],
|
||||
];
|
||||
|
||||
// Transportation field providers - handles outbound/inbound transportation and pickup selection
|
||||
|
||||
// Outbound Transportation
|
||||
$this->fieldOptionProviders['transportationOutbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Hinfahrt',
|
||||
'choices' => $bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::OUTBOUND_TRAVEL),
|
||||
'choice_label' => fn (Service $service) => $this->formatTransportationServiceLabel($service),
|
||||
'choice_value' => 'id',
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'hx-post' => '#', // Will be configured when HTMX integration is implemented
|
||||
'hx-target' => '#booking-summary',
|
||||
'hx-trigger' => 'change',
|
||||
],
|
||||
];
|
||||
|
||||
// Inbound Transportation
|
||||
$this->fieldOptionProviders['transportationInbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Rückfahrt',
|
||||
'choices' => $bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::INBOUND_TRAVEL),
|
||||
'choice_label' => fn (Service $service) => $this->formatTransportationServiceLabel($service),
|
||||
'choice_value' => 'id',
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
'attr' => [
|
||||
'hx-post' => '#', // Will be configured when HTMX integration is implemented
|
||||
'hx-target' => '#booking-summary',
|
||||
'hx-trigger' => 'change',
|
||||
],
|
||||
];
|
||||
|
||||
// Outbound Pickup (conditional - only shown when outbound transportation is bus)
|
||||
$this->fieldOptionProviders['pickupOutbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Zustieg Hinfahrt',
|
||||
'choices' => $bookingDto->travel->pickupsTo,
|
||||
'choice_label' => fn (Pickup $pickup) => $this->formatPickupLabel($pickup),
|
||||
'choice_value' => 'id',
|
||||
'expanded' => false, // Dropdown for pickups
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
'placeholder' => 'Zustieg auswählen',
|
||||
];
|
||||
|
||||
// Inbound Pickup (conditional - only shown when inbound transportation is bus)
|
||||
$this->fieldOptionProviders['pickupInbound'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Zustieg Rückfahrt',
|
||||
'choices' => $bookingDto->travel->pickupsFro,
|
||||
'choice_label' => fn (Pickup $pickup) => $this->formatPickupLabel($pickup),
|
||||
'choice_value' => 'id',
|
||||
'expanded' => false,
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
'placeholder' => 'Zustieg auswählen',
|
||||
];
|
||||
|
||||
// Parking (conditional - only shown when at least one transportation direction is PKW)
|
||||
$this->fieldOptionProviders['parking'] = fn (BookingDtoInterface $bookingDto, int $participantIndex, array $options = []) => [
|
||||
'label' => 'Parkplatz',
|
||||
'choices' => $bookingDto->travel->getAdditionalServicesBySubTypes(Constants::TOKEN_PARKING, true),
|
||||
'choice_label' => fn (?Service $service) => $this->formatServiceLabelWithPrice($service),
|
||||
'choice_value' => 'id',
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'required' => false,
|
||||
];
|
||||
|
||||
// Future field providers would be added here, for example:
|
||||
//
|
||||
// $this->fieldOptionProviders['mealPreference'] = fn($bookingDto, $participantIndex) => [
|
||||
@@ -219,6 +290,73 @@ class ParticipantFieldOptionsProvider extends AbstractFieldOptionsProvider
|
||||
return sprintf('%s (€%s)', $service->label, number_format($service->price, 2, ',', '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Format transportation service labels with type indicator and pricing.
|
||||
*
|
||||
* Creates user-friendly labels for transportation services that include:
|
||||
* - Transportation type icon (🚌 for bus, 🚗 for car)
|
||||
* - Service name
|
||||
* - Pricing (with discount indication for negative prices)
|
||||
* - Availability warning for limited services
|
||||
*
|
||||
* @param Service $service The transportation service to format
|
||||
*
|
||||
* @return string The formatted transportation service label
|
||||
*/
|
||||
private function formatTransportationServiceLabel(Service $service): string
|
||||
{
|
||||
$label = $service->label;
|
||||
|
||||
// Add transportation type indicator
|
||||
$typeIndicator = match ($service->subType) {
|
||||
'BUS' => '🚌',
|
||||
'PKW' => '🚗',
|
||||
default => '',
|
||||
};
|
||||
|
||||
if ($typeIndicator) {
|
||||
$label = $typeIndicator.' '.$label;
|
||||
}
|
||||
|
||||
// Add pricing with discount indication
|
||||
if (null !== $service->price) {
|
||||
if ($service->price > 0) {
|
||||
$label .= sprintf(' (+€%.2f)', $service->price);
|
||||
} elseif ($service->price < 0) {
|
||||
$label .= sprintf(' (-€%.2f Discount)', abs($service->price));
|
||||
}
|
||||
}
|
||||
|
||||
// Add availability warning if limited
|
||||
if (null !== $service->available && $service->available <= 5) {
|
||||
$label .= sprintf(' (nur %d verfügbar)', $service->available);
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format pickup labels with city and street information.
|
||||
*
|
||||
* Creates user-friendly labels for pickup locations following the existing pattern:
|
||||
* - Primary format: "City (Street)" if street is available
|
||||
* - Fallback format: "City" if no street information
|
||||
*
|
||||
* @param Pickup $pickup The pickup location to format
|
||||
*
|
||||
* @return string The formatted pickup location label
|
||||
*/
|
||||
private function formatPickupLabel(Pickup $pickup): string
|
||||
{
|
||||
$label = $pickup->city ?? '';
|
||||
|
||||
if (null !== $pickup->street && '' !== trim($pickup->street)) {
|
||||
$label .= ' ('.$pickup->street.')';
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters services based on participant's age constraints.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user