feat: refactoring and cleanup
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\DataProcessor;
|
||||
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
|
||||
/**
|
||||
* Processes participant service selections for booking updates.
|
||||
*
|
||||
* Handles the assignment and mapping of services (additional, transportation,
|
||||
* pickup, room, insurance) from participant DTOs to the booking model during
|
||||
* the update request workflow.
|
||||
*/
|
||||
class ParticipantServiceProcessor
|
||||
{
|
||||
/**
|
||||
* Resets all existing participant-to-service mappings to start with a clean slate.
|
||||
*
|
||||
* This ensures that service assignments are rebuilt from scratch based on current form selections.
|
||||
* Includes resetting room mappings to allow room reassignments during edit.
|
||||
*
|
||||
* @param Booking $bookingData The booking data object containing services to reset
|
||||
*/
|
||||
public function resetServiceMappings(Booking $bookingData): void
|
||||
{
|
||||
$servicesToReset = [
|
||||
...$bookingData->additionalServices,
|
||||
...$bookingData->transportationServices,
|
||||
...$bookingData->pickupsOutbound,
|
||||
...$bookingData->pickupsInbound,
|
||||
...$bookingData->rooms,
|
||||
...$bookingData->insurances,
|
||||
];
|
||||
|
||||
foreach ($servicesToReset as $service) {
|
||||
$service->mapping = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes all services for a single participant.
|
||||
*
|
||||
* This orchestrator method handles the complete service assignment workflow for one participant,
|
||||
* including additional services, transportation services, pickup locations, and room assignments.
|
||||
*
|
||||
* @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 services
|
||||
*/
|
||||
public function processParticipantServices(ParticipantDto $participant, Booking $bookingData, Travel $travelData): void
|
||||
{
|
||||
if (true === $participant->isCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->processAdditionalServices($participant, $bookingData, $travelData);
|
||||
$this->processTransportationServices($participant, $bookingData, $travelData);
|
||||
$this->processPickupLocations($participant, $bookingData);
|
||||
$this->processRoomAssignment($participant, $bookingData);
|
||||
$this->processInsurance($participant, $bookingData, $travelData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes services and pickups with no participant mappings.
|
||||
*
|
||||
* Cleans up unused services to prevent empty services from being sent to the API.
|
||||
* This includes additional services, transportation services, pickup locations, and insurances.
|
||||
*
|
||||
* @param Booking $bookingData The booking data object to clean up
|
||||
*/
|
||||
public function removeUnusedServices(Booking $bookingData): void
|
||||
{
|
||||
foreach ($bookingData->additionalServices as $service) {
|
||||
if (0 === count($service->mapping)) {
|
||||
unset($bookingData->additionalServices[$service->id]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookingData->transportationServices as $service) {
|
||||
if (0 === count($service->mapping)) {
|
||||
unset($bookingData->transportationServices[$service->id]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookingData->pickupsOutbound as $pickup) {
|
||||
if (0 === count($pickup->mapping)) {
|
||||
unset($bookingData->pickupsOutbound[$pickup->id]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookingData->pickupsInbound as $pickup) {
|
||||
if (0 === count($pickup->mapping)) {
|
||||
unset($bookingData->pickupsInbound[$pickup->id]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookingData->insurances as $insurance) {
|
||||
if (0 === count($insurance->mapping)) {
|
||||
unset($bookingData->insurances[$insurance->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects additional services from a participant for mapping.
|
||||
*
|
||||
* Extracts all additional services (courses, board, rentals, ski pass, rental insurance,
|
||||
* additional services) from a participant into a flat array of Service objects.
|
||||
*
|
||||
* @param ParticipantDto $participant The participant data
|
||||
*
|
||||
* @return array<\App\BusProNet\Model\Service> Array of services selected by this participant
|
||||
*/
|
||||
private function collectParticipantAdditionalServices(ParticipantDto $participant): array
|
||||
{
|
||||
$services = [
|
||||
...$participant->courses,
|
||||
...$participant->additionalServices,
|
||||
...$participant->board,
|
||||
...$participant->rentals,
|
||||
];
|
||||
|
||||
// Add ski pass if selected (single service, not an array)
|
||||
if (null !== $participant->skiPass) {
|
||||
$services[] = $participant->skiPass;
|
||||
}
|
||||
|
||||
// Add rental insurance if selected (single service, not an array)
|
||||
if (null !== $participant->rentalInsurance) {
|
||||
$services[] = $participant->rentalInsurance;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes additional services for a participant.
|
||||
*
|
||||
* Maps additional services (courses, ski passes, board options, rentals) to the participant.
|
||||
* Adds new services to the booking if they don't already exist and sets individual pricing.
|
||||
*
|
||||
* @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 services
|
||||
*/
|
||||
private function processAdditionalServices(ParticipantDto $participant, Booking $bookingData, Travel $travelData): void
|
||||
{
|
||||
$servicesToMap = $this->collectParticipantAdditionalServices($participant);
|
||||
|
||||
foreach ($servicesToMap as $service) {
|
||||
if (false === isset($bookingData->additionalServices[$service->id])) {
|
||||
$serviceToAdd = $travelData->additionalServices[$service->id] ?? null;
|
||||
if (null !== $serviceToAdd) {
|
||||
$bookingData->additionalServices[$service->id] = $serviceToAdd;
|
||||
$bookingData->additionalServices[$service->id]->individualPrice[$participant->index] = $serviceToAdd->price;
|
||||
}
|
||||
}
|
||||
$bookingData->additionalServices[$service->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes transportation services for a participant.
|
||||
*
|
||||
* Maps transportation services (both directions: to and from destination) to the participant.
|
||||
* Adds new transportation services to the booking if they don't already exist.
|
||||
*
|
||||
* @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 services
|
||||
*/
|
||||
private function processTransportationServices(ParticipantDto $participant, Booking $bookingData, Travel $travelData): void
|
||||
{
|
||||
foreach ([$participant->transportationOutbound, $participant->transportationInbound] as $service) {
|
||||
if (false === isset($bookingData->transportationServices[$service->id])) {
|
||||
$serviceToAdd = $travelData->transportationServices[$service->id] ?? null;
|
||||
if (null !== $serviceToAdd) {
|
||||
$bookingData->transportationServices[$service->id] = $serviceToAdd;
|
||||
$bookingData->transportationServices[$service->id]->individualPrice[$participant->index] = $serviceToAdd->price;
|
||||
}
|
||||
}
|
||||
$bookingData->transportationServices[$service->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes pickup locations for participants using bus transportation.
|
||||
*
|
||||
* Only processes pickup locations for bus transportation services and maps the participant
|
||||
* to their selected pickup location.
|
||||
*
|
||||
* @param ParticipantDto $participant The participant data from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
*/
|
||||
private function processPickupLocations(ParticipantDto $participant, Booking $bookingData): void
|
||||
{
|
||||
// Check if either transportation direction is BUS and pickup is selected
|
||||
$hasOutboundBus = null !== $participant->transportationOutbound && 'BUS' === $participant->transportationOutbound->subType;
|
||||
$hasInboundBus = null !== $participant->transportationInbound && 'BUS' === $participant->transportationInbound->subType;
|
||||
|
||||
if (($hasOutboundBus || $hasInboundBus) && null !== $selectedPickup = $participant->pickup) {
|
||||
if (false === isset($bookingData->pickupsOutbound[$selectedPickup->id])) {
|
||||
$bookingData->pickupsOutbound[$selectedPickup->id] = $selectedPickup;
|
||||
}
|
||||
$bookingData->pickupsOutbound[$selectedPickup->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes room assignment for a participant.
|
||||
*
|
||||
* Maps the participant to their assigned room. Allows room reassignment during
|
||||
* booking edits while maintaining the constraint that participants can only be
|
||||
* assigned to room types that have already been booked.
|
||||
*
|
||||
* @param ParticipantDto $participant The participant data from the form
|
||||
* @param Booking $bookingData The booking data object to update
|
||||
*/
|
||||
private function processRoomAssignment(ParticipantDto $participant, Booking $bookingData): void
|
||||
{
|
||||
if (null === $participant->assignedRoomId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the room in the existing booking by ID
|
||||
foreach ($bookingData->rooms as $room) {
|
||||
if ($room->id === $participant->assignedRoomId) {
|
||||
$room->mapping[] = $participant->index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes travel insurance for a participant.
|
||||
*
|
||||
* Maps insurance to the participant. Adds new insurances to the booking if they don't exist.
|
||||
* Insurance can be either individual or package-based, with automatic price-tier adjustment.
|
||||
*
|
||||
* IMPORTANT: Excludes synthetic "no insurance" option from BPN transmission.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
private function processInsurance(ParticipantDto $participant, Booking $bookingData, Travel $travelData): void
|
||||
{
|
||||
// Skip if no insurance or if participant selected "keine Versicherung gewünscht"
|
||||
if (null === $participant->insurance || $participant->insurance->isNoInsurance()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$insurance = $participant->insurance;
|
||||
|
||||
if (false === isset($bookingData->insurances[$insurance->id])) {
|
||||
$insuranceToAdd = $travelData->insurances[$insurance->id] ?? null;
|
||||
if (null !== $insuranceToAdd) {
|
||||
$bookingData->insurances[$insurance->id] = $insuranceToAdd;
|
||||
$bookingData->insurances[$insurance->id]->individualPrice[$participant->index] = $insuranceToAdd->price;
|
||||
}
|
||||
}
|
||||
|
||||
// Only add mapping if insurance exists in booking data
|
||||
// This can legitimately be false if the insurance is no longer available in current travel data
|
||||
if (isset($bookingData->insurances[$insurance->id])) {
|
||||
$bookingData->insurances[$insurance->id]->mapping[] = $participant->index;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user