226 lines
7.4 KiB
PHP
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;
|
|
}
|
|
}
|