wip: modernized edit flow, fix insurance tier calculation

This commit is contained in:
Björn Fromme
2025-10-09 17:42:39 +02:00
parent cba0f747cd
commit 67c642bc2f
31 changed files with 272 additions and 536 deletions
@@ -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
}