Files
myep/src/BusProNet/DataProcessor/ServiceMappingCollector.php
T

226 lines
7.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\BusProNet\DataProcessor;
use App\Form\Model\BookingDto;
use App\Form\Model\ParticipantDto;
/**
* Collects service-to-participant mappings for BusProNet API payloads.
*
* Extracts and groups participant service selections into structured maps
* keyed by service ID with arrays of participant IDs (1-based for API).
*/
class ServiceMappingCollector
{
/**
* Collects room mappings.
*
* Groups participants by their assigned room ID.
*
* @return array<string, array<int>> Map of room ID to participant IDs
*/
public function collectRoomMappings(BookingDto $bookingDto): array
{
$roomMap = [];
foreach ($bookingDto->participants as $index => $participant) {
$participantId = $index + 1;
if (null !== $participant->assignedRoomId) {
$roomMap[$participant->assignedRoomId][] = $participantId;
}
}
return $roomMap;
}
/**
* Collects service mappings for the booking request.
*
* Groups board, ski passes, rentals, rental insurance, courses, parking, and additional services
* by service ID with their participant assignments (1-based).
*
* @return array<string, array<int>> Map of service ID to participant IDs
*/
public function collectServiceMappings(BookingDto $bookingDto): array
{
$serviceMap = [];
foreach ($bookingDto->participants as $index => $participant) {
$participantId = $index + 1;
// Board services
foreach ($participant->board as $board) {
$serviceMap[$board->id][] = $participantId;
}
// Ski pass
if (null !== $participant->skiPass) {
$serviceMap[$participant->skiPass->id][] = $participantId;
}
// Rentals
foreach ($participant->rentals as $rental) {
$serviceMap[$rental->id][] = $participantId;
}
// Rental insurance
if (null !== $participant->rentalInsurance) {
$serviceMap[$participant->rentalInsurance->id][] = $participantId;
}
// Courses
foreach ($participant->courses as $course) {
$serviceMap[$course->id][] = $participantId;
}
// Parking service (for self-organized transportation)
if (true === $participant->parking && null !== $participant->parkingService) {
$serviceMap[$participant->parkingService->id][] = $participantId;
}
// Additional services
foreach ($participant->additionalServices as $service) {
$serviceMap[$service->id][] = $participantId;
}
}
return $serviceMap;
}
/**
* Collects transportation service mappings.
*
* @return array<string, array<int>> Map of transportation service ID to participant IDs
*/
public function collectTransportationMappings(BookingDto $bookingDto): array
{
$transportationMap = [];
foreach ($bookingDto->participants as $index => $participant) {
$participantId = $index + 1;
if (null !== $participant->transportationOutbound) {
$transportationMap[$participant->transportationOutbound->id][] = $participantId;
}
if (null !== $participant->transportationInbound) {
$transportationMap[$participant->transportationInbound->id][] = $participantId;
}
}
return $transportationMap;
}
/**
* Collects pickup location mappings.
*
* Collects the unified pickup selection which applies to both directions.
* The API receives this as outbound pickup data.
*
* @return array<string, array<int>> Map of pickup ID to participant IDs
*/
public function collectPickupMappings(BookingDto $bookingDto): array
{
$pickupMap = [];
foreach ($bookingDto->participants as $index => $participant) {
$participantId = $index + 1;
if (null !== $participant->pickup) {
$pickupMap[$participant->pickup->id][] = $participantId;
}
}
return $pickupMap;
}
/**
* Collects insurance mappings.
*
* CRITICAL: Insurance data is only included in CREATE flow, not in UPDATE flow.
* IMPORTANT: Excludes synthetic "no insurance" option from BPN transmission.
*
* @return array<string, array<int>> Map of insurance ID to participant IDs
*/
public function collectInsuranceMappings(BookingDto $bookingDto): array
{
$insuranceMap = [];
foreach ($bookingDto->participants as $index => $participant) {
$participantId = $index + 1;
// Exclude synthetic "keine Versicherung gewünscht" option from BPN XML
if (null !== $participant->insurance && false === $participant->insurance->isNoInsurance()) {
$insuranceMap[$participant->insurance->id][] = $participantId;
}
}
return $insuranceMap;
}
/**
* Collects all purchase vouchers from participants.
*
* Removes duplicates and empty values, returning unique redemption codes
* for aggregation into the <gutscheine> collection in the booking payload.
*
* IMPORTANT: Goodwill vouchers (Kulanz) are excluded from this collection.
* They are added per participant as <aktionscode> instead.
*
* @return string[] Array of unique redemption codes (excluding Kulanz)
*/
public function collectPurchaseVouchers(BookingDto $bookingDto): array
{
$vouchers = [];
foreach ($bookingDto->participants as $participant) {
if (null !== $participant->purchaseVoucherCode && '' !== trim($participant->purchaseVoucherCode)) {
// Exclude goodwill vouchers
if (false === $participant->hasGoodwillVoucher()) {
$vouchers[] = trim($participant->purchaseVoucherCode);
}
}
}
// Remove duplicates (in case multiple participants enter same code)
return array_unique($vouchers);
}
/**
* Gets the aktionscode (promotional voucher code) for a participant.
*
* Returns the promotional voucher code if present.
* Goodwill vouchers are handled separately via getGoodwillVoucherCodeForParticipant().
*
* @return string|null The aktionscode to use, or null if none
*/
public function getPromoVoucherCodeForParticipant(ParticipantDto $participant): ?string
{
// Only return promotional voucher code (goodwill vouchers are handled separately)
if (null !== $participant->promoVoucherCode && '' !== trim($participant->promoVoucherCode)) {
return trim($participant->promoVoucherCode);
}
return null;
}
/**
* Extracts goodwill voucher code for a participant.
*
* Goodwill vouchers are sent as <einloesecode> per participant (not in aggregate),
* allowing them to coexist with promotional codes.
*/
public function getGoodwillVoucherCodeForParticipant(ParticipantDto $participant): ?string
{
if ($participant->hasGoodwillVoucher() && null !== $participant->purchaseVoucherCode && '' !== trim($participant->purchaseVoucherCode)) {
return trim($participant->purchaseVoucherCode);
}
return null;
}
}