wip: modernized edit flow, fix insurance tier calculation
This commit is contained in:
@@ -15,9 +15,7 @@ use App\BusProNet\Model\PersonalData;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\BusProNet\Traits\ApiClientTrait;
|
||||
use App\BusProNet\XmlParser\ApiResponseParser;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use App\Form\Model\RegistrationDto;
|
||||
use League\Flysystem\FilesystemException;
|
||||
use League\Flysystem\FilesystemOperator;
|
||||
@@ -215,14 +213,14 @@ class ApiClient
|
||||
* First phase of the two-phase booking process. Validates all booking data
|
||||
* and returns pricing information without creating an actual booking.
|
||||
*
|
||||
* @param BookingCreateDto $bookingDto The booking creation form data
|
||||
* @param bool $debug Enable debug mode (XML dumps)
|
||||
* @param BookingDto $bookingDto The booking creation form data
|
||||
* @param bool $debug Enable debug mode (XML dumps)
|
||||
*
|
||||
* @return Notification|BookingResponse Notification on error, BookingResponse on success
|
||||
*
|
||||
* @throws ApiClientException If the API request fails
|
||||
*/
|
||||
public function createBookingInquiry(BookingCreateDto $bookingDto, bool $debug = false): Notification|BookingResponse
|
||||
public function createBookingInquiry(BookingDto $bookingDto, bool $debug = false): Notification|BookingResponse
|
||||
{
|
||||
$payload = $this->bookingDataProcessor->createBookingRequestPayload($bookingDto, 'Anfrage');
|
||||
|
||||
@@ -242,14 +240,14 @@ class ApiClient
|
||||
* Second phase of the two-phase booking process. Creates the actual booking
|
||||
* after successful inquiry validation.
|
||||
*
|
||||
* @param BookingCreateDto $bookingDto The booking creation form data
|
||||
* @param bool $debug Enable debug mode (XML dumps)
|
||||
* @param BookingDto $bookingDto The booking creation form data
|
||||
* @param bool $debug Enable debug mode (XML dumps)
|
||||
*
|
||||
* @return Notification|BookingResponse Notification on error, BookingResponse with booking number on success
|
||||
*
|
||||
* @throws ApiClientException If the API request fails
|
||||
*/
|
||||
public function createBooking(BookingCreateDto $bookingDto, bool $debug = false): Notification|BookingResponse
|
||||
public function createBooking(BookingDto $bookingDto, bool $debug = false): Notification|BookingResponse
|
||||
{
|
||||
$payload = $this->bookingDataProcessor->createBookingRequestPayload($bookingDto, 'Buchung');
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@ use App\BusProNet\Model\PersonalData;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\BusProNet\Utility\DirectionMapper;
|
||||
use App\Form\Model\BankAccountDto;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\BookingEditDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
use App\Service\InsuranceMatchingService;
|
||||
|
||||
@@ -39,6 +37,12 @@ class BookingDataProcessor
|
||||
*
|
||||
* Extracts all service selections from the booking entity and assigns them
|
||||
* to participant DTOs, creating a unified data structure identical to create mode.
|
||||
*
|
||||
* IMPORTANT: Address handling for edit mode
|
||||
* - ParticipantDto::fromPersonalData() clones address objects to prevent shared references
|
||||
* - First participant's address is NOT auto-populated from applicant
|
||||
* - Template uses placeholders to show applicant's address as hints
|
||||
* - This prevents address data from being inadvertently modified during form binding
|
||||
*/
|
||||
public function createBookingDtoFromBooking(Booking $booking, Travel $travel): BookingDto
|
||||
{
|
||||
@@ -351,8 +355,8 @@ class BookingDataProcessor
|
||||
* Insurance can be either individual or package-based, with automatic price-tier adjustment.
|
||||
*
|
||||
* @param ParticipantDto $participant The participant data from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
* @param Travel $travelData The travel data containing available insurances
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
* @param Travel $travelData The travel data containing available insurances
|
||||
*/
|
||||
private function processInsurance(ParticipantDto $participant, Booking $bookingData, Travel $travelData): void
|
||||
{
|
||||
@@ -654,7 +658,7 @@ class BookingDataProcessor
|
||||
* ('Anfrage') or a final booking commit ('Buchung').
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking creation form data
|
||||
* @param string $bookingType Either 'Anfrage' (inquiry) or 'Buchung' (final booking)
|
||||
* @param string $bookingType Either 'Anfrage' (inquiry) or 'Buchung' (final booking)
|
||||
*
|
||||
* @return array The structured payload array for BusProNet API submission
|
||||
*/
|
||||
@@ -822,11 +826,11 @@ class BookingDataProcessor
|
||||
* - abreise (departure date)
|
||||
* - anzahl (number of rooms of this type booked)
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param array $roomMap Map of room ID to participant IDs
|
||||
* @param BookingCreateDto $bookingDto The booking data for accessing room details and quantities
|
||||
* @param array $payload The payload array to modify
|
||||
* @param array $roomMap Map of room ID to participant IDs
|
||||
* @param BookingDto $bookingDto The booking data for accessing room details and quantities
|
||||
*/
|
||||
private function addRoomMappingsToPayload(array &$payload, array $roomMap, BookingCreateDto $bookingDto): void
|
||||
private function addRoomMappingsToPayload(array &$payload, array $roomMap, BookingDto $bookingDto): void
|
||||
{
|
||||
if (empty($roomMap)) {
|
||||
return;
|
||||
@@ -870,7 +874,7 @@ class BookingDataProcessor
|
||||
*
|
||||
* @return array<string, array<int>> Map of room ID to participant IDs
|
||||
*/
|
||||
private function collectRoomMappings(BookingCreateDto $bookingDto): array
|
||||
private function collectRoomMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
$roomMap = [];
|
||||
|
||||
@@ -893,7 +897,7 @@ class BookingDataProcessor
|
||||
*
|
||||
* @return array<string, array<int>> Map of service ID to participant IDs
|
||||
*/
|
||||
private function collectServiceMappings(BookingCreateDto $bookingDto): array
|
||||
private function collectServiceMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
$serviceMap = [];
|
||||
|
||||
@@ -944,7 +948,7 @@ class BookingDataProcessor
|
||||
*
|
||||
* @return array<string, array<int>> Map of transportation service ID to participant IDs
|
||||
*/
|
||||
private function collectTransportationMappings(BookingCreateDto $bookingDto): array
|
||||
private function collectTransportationMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
$transportationMap = [];
|
||||
|
||||
@@ -971,7 +975,7 @@ class BookingDataProcessor
|
||||
*
|
||||
* @return array<string, array<int>> Map of pickup ID to participant IDs
|
||||
*/
|
||||
private function collectPickupMappings(BookingCreateDto $bookingDto): array
|
||||
private function collectPickupMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
$pickupMap = [];
|
||||
|
||||
@@ -993,7 +997,7 @@ class BookingDataProcessor
|
||||
*
|
||||
* @return array<string, array<int>> Map of insurance ID to participant IDs
|
||||
*/
|
||||
private function collectInsuranceMappings(BookingCreateDto $bookingDto): array
|
||||
private function collectInsuranceMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
$insuranceMap = [];
|
||||
|
||||
@@ -1033,7 +1037,12 @@ class BookingDataProcessor
|
||||
}
|
||||
|
||||
// Get all available insurances from travel data
|
||||
$availableInsurances = array_values($bookingDto->travel->insurances);
|
||||
$availableInsurances = $bookingDto->travel->insurances;
|
||||
|
||||
// Exclude complementary insurances from bulk assignment logic
|
||||
// They are only available as part of packages and cannot be directly selected
|
||||
$availableInsurances = array_filter($availableInsurances, fn ($insurance) => !$insurance->complementary);
|
||||
$availableInsurances = array_values($availableInsurances);
|
||||
|
||||
// Use InsuranceMatchingService for proper type-based assignment with price tier matching
|
||||
$assignments = $this->insuranceMatchingService->batchAssignInsuranceToParticipants(
|
||||
@@ -1055,7 +1064,7 @@ class BookingDataProcessor
|
||||
|
||||
// In edit mode: only apply bulk insurance if participant has no insurance
|
||||
// This respects the rule that once assigned, insurance cannot be changed
|
||||
if ($bookingDto instanceof BookingEditDto && null !== $participant->insurance) {
|
||||
if (BookingDto::MODE_EDIT === $bookingDto->getMode() && null !== $participant->insurance) {
|
||||
continue; // Skip participants with existing insurance assignment
|
||||
}
|
||||
|
||||
|
||||
@@ -96,4 +96,14 @@ class Service
|
||||
|
||||
#[Groups(['api:single', 'api:list'])]
|
||||
public ?string $description = null;
|
||||
|
||||
/**
|
||||
* Indicates whether this service should be included in insurance eligibility price calculation.
|
||||
*
|
||||
* Maps to XML attribute 'versicherungsberechnung' (J=true, N=false).
|
||||
* When false, this service's price is excluded when determining which insurance
|
||||
* tier is appropriate for a participant.
|
||||
*/
|
||||
#[Groups(['api:single', 'api:list'])]
|
||||
public bool $includeInInsuranceCalculation = true;
|
||||
}
|
||||
|
||||
@@ -145,6 +145,9 @@ class TravelParser extends AbstractParser
|
||||
// Parse age constraints
|
||||
$this->parseServiceAgeConstraints($serviceNode, $service);
|
||||
|
||||
// Parse insurance calculation flag
|
||||
$service->includeInInsuranceCalculation = $this->stringToBool($serviceNode->attr('versicherungsberechnung'));
|
||||
|
||||
$additionalServices[$serviceId] = $service;
|
||||
});
|
||||
|
||||
@@ -192,6 +195,9 @@ class TravelParser extends AbstractParser
|
||||
$service->dayTime = (new DayTimeUtility())->mapTime($timeFrom);
|
||||
}
|
||||
|
||||
// Parse insurance calculation flag
|
||||
$service->includeInInsuranceCalculation = $this->stringToBool($serviceNode->attr('versicherungsberechnung'));
|
||||
|
||||
$transportationServices[$serviceId] = $service;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user