chore: fix phpstan errors
This commit is contained in:
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
|
||||
@@ -36,7 +37,7 @@ class BookingChangeTracker
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking DTO to extract data from
|
||||
*
|
||||
* @return array Serializable array of all user-editable data
|
||||
* @return array<string, mixed> Serializable array of all user-editable data
|
||||
*/
|
||||
public function extractUserData(BookingDto $bookingDto): array
|
||||
{
|
||||
@@ -61,7 +62,7 @@ class BookingChangeTracker
|
||||
*
|
||||
* @param ParticipantDto $participant The participant to extract data from
|
||||
*
|
||||
* @return array Serializable array of participant data
|
||||
* @return array<string, mixed> Serializable array of participant data
|
||||
*/
|
||||
private function extractParticipantData(ParticipantDto $participant): array
|
||||
{
|
||||
@@ -120,9 +121,9 @@ class BookingChangeTracker
|
||||
* This ensures that associative arrays, indexed arrays, and different orders
|
||||
* all produce the same fingerprint as long as the same services are present.
|
||||
*
|
||||
* @param array $services Array of Service objects
|
||||
* @param list<Service> $services Array of Service objects
|
||||
*
|
||||
* @return array Sorted array of service IDs
|
||||
* @return list<int|null> Sorted array of service IDs
|
||||
*/
|
||||
private function normalizeServiceArray(array $services): array
|
||||
{
|
||||
@@ -130,7 +131,7 @@ class BookingChangeTracker
|
||||
$ids = array_unique($ids);
|
||||
sort($ids);
|
||||
|
||||
return array_values($ids);
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,8 +95,8 @@ class BookingConfigurator
|
||||
* Converts a Room model into a RoomSelectionDto with the specified quantity
|
||||
* selection. Used during booking initialization to create selectable room options.
|
||||
*
|
||||
* @param Room $room The room model to convert
|
||||
* @param array $roomsIdsAndQuantities Array of room ID to quantity mappings
|
||||
* @param Room $room The room model to convert
|
||||
* @param array<int|string, int> $roomsIdsAndQuantities Array of room ID to quantity mappings
|
||||
*
|
||||
* @return RoomSelectionDto The room selection DTO
|
||||
*/
|
||||
@@ -249,6 +249,7 @@ class BookingConfigurator
|
||||
return $this->participantEligibilityService->isParticipantEligible($bookingDto, $participantIndex);
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $mandatoryAdditionalServices */
|
||||
private function preselectMandatoryAdditionalServices(
|
||||
ParticipantDto $participant,
|
||||
array $mandatoryAdditionalServices,
|
||||
@@ -266,6 +267,7 @@ class BookingConfigurator
|
||||
$this->appendAdditionalServices($participant, $eligibleServices, false);
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $autoBookAdditionalServices */
|
||||
private function preselectAutoBookAdditionalServices(
|
||||
ParticipantDto $participant,
|
||||
array $autoBookAdditionalServices,
|
||||
@@ -283,6 +285,7 @@ class BookingConfigurator
|
||||
$this->appendAdditionalServices($participant, $eligibleServices, true);
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $mandatorySkiPassServices */
|
||||
private function preselectMandatorySkiPass(
|
||||
ParticipantDto $participant,
|
||||
array $mandatorySkiPassServices,
|
||||
@@ -308,6 +311,7 @@ class BookingConfigurator
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $autoBookSkiPassServices */
|
||||
private function preselectAutoBookSkiPass(
|
||||
ParticipantDto $participant,
|
||||
array $autoBookSkiPassServices,
|
||||
@@ -338,6 +342,7 @@ class BookingConfigurator
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $mandatoryBoardServices */
|
||||
private function preselectMandatoryBoardServices(
|
||||
ParticipantDto $participant,
|
||||
array $mandatoryBoardServices,
|
||||
@@ -355,6 +360,7 @@ class BookingConfigurator
|
||||
$this->appendBoardServices($participant, $eligibleServices, false);
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $autoBookBoardServices */
|
||||
private function preselectAutoBookBoardServices(
|
||||
ParticipantDto $participant,
|
||||
array $autoBookBoardServices,
|
||||
@@ -372,6 +378,7 @@ class BookingConfigurator
|
||||
$this->appendBoardServices($participant, $eligibleServices, true);
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $mandatoryRentalServices */
|
||||
private function preselectMandatoryRentals(
|
||||
ParticipantDto $participant,
|
||||
array $mandatoryRentalServices,
|
||||
@@ -395,6 +402,7 @@ class BookingConfigurator
|
||||
$this->appendRentalServices($participant, $matchingDurationServices, false);
|
||||
}
|
||||
|
||||
/** @param array<int, Service> $autoBookRentalServices */
|
||||
private function preselectAutoBookRentals(
|
||||
ParticipantDto $participant,
|
||||
array $autoBookRentalServices,
|
||||
@@ -445,7 +453,7 @@ class BookingConfigurator
|
||||
*/
|
||||
private function appendAdditionalServices(ParticipantDto $participant, array $services, bool $respectOptOut): void
|
||||
{
|
||||
$currentSelections = $participant->additionalServices ?? [];
|
||||
$currentSelections = $participant->additionalServices;
|
||||
$currentServiceIds = array_map(static fn (Service $service): ?int => $service->id, $currentSelections);
|
||||
|
||||
foreach ($services as $service) {
|
||||
@@ -469,7 +477,7 @@ class BookingConfigurator
|
||||
*/
|
||||
private function appendBoardServices(ParticipantDto $participant, array $services, bool $respectOptOut): void
|
||||
{
|
||||
$currentSelections = $participant->board ?? [];
|
||||
$currentSelections = $participant->board;
|
||||
$currentServiceIds = array_map(static fn (Service $service): ?int => $service->id, $currentSelections);
|
||||
|
||||
foreach ($services as $service) {
|
||||
@@ -493,7 +501,7 @@ class BookingConfigurator
|
||||
*/
|
||||
private function appendRentalServices(ParticipantDto $participant, array $services, bool $respectOptOut): void
|
||||
{
|
||||
$currentSelections = $participant->rentals ?? [];
|
||||
$currentSelections = $participant->rentals;
|
||||
$currentServiceIds = array_map(static fn (Service $service): ?int => $service->id, $currentSelections);
|
||||
|
||||
foreach ($services as $service) {
|
||||
|
||||
@@ -178,6 +178,7 @@ class BookingEditDraftManager
|
||||
/**
|
||||
* Applies bank account data from draft to BookingDto.
|
||||
*/
|
||||
/** @param array<string, mixed> $bankAccountData */
|
||||
private function applyBankAccountData(BookingDto $dto, array $bankAccountData): void
|
||||
{
|
||||
$iban = $bankAccountData['iban'] ?? null;
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
@@ -21,6 +22,7 @@ use App\Form\Model\ParticipantDto;
|
||||
*/
|
||||
class BookingEditDraftMerger
|
||||
{
|
||||
/** @param array<string, mixed> $data */
|
||||
public function apply(
|
||||
BookingDto $bookingDto,
|
||||
int $participantIndex,
|
||||
@@ -79,6 +81,7 @@ class BookingEditDraftMerger
|
||||
return $participant->mutable;
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
private function applyPersonalData(ParticipantDto $participant, array $data): void
|
||||
{
|
||||
if (true === array_key_exists('firstName', $data)) {
|
||||
@@ -104,6 +107,7 @@ class BookingEditDraftMerger
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
private function applyAddressData(ParticipantDto $participant, array $data): void
|
||||
{
|
||||
$hasAddressData = null !== ($data['street'] ?? null)
|
||||
@@ -133,6 +137,7 @@ class BookingEditDraftMerger
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
private function applyBodyDimensions(ParticipantDto $participant, array $data): void
|
||||
{
|
||||
if (true === array_key_exists('height', $data)) {
|
||||
@@ -146,6 +151,7 @@ class BookingEditDraftMerger
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
private function applyRoomAssignment(ParticipantDto $participant, array $data): void
|
||||
{
|
||||
if (true === array_key_exists('assignedRoomId', $data)) {
|
||||
@@ -156,6 +162,7 @@ class BookingEditDraftMerger
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $data */
|
||||
private function applyVoucherCodes(ParticipantDto $participant, array $data): void
|
||||
{
|
||||
if (true === array_key_exists('purchaseVoucherCode', $data)) {
|
||||
@@ -177,6 +184,7 @@ class BookingEditDraftMerger
|
||||
* Multi-select fields (checkboxes) and booleans use overwrite strategy: draft values
|
||||
* always replace API data, since users can intentionally clear these selections.
|
||||
*/
|
||||
/** @param array<string, mixed> $data */
|
||||
private function applyServiceSelections(ParticipantDto $participant, array $data, Travel $travel): void
|
||||
{
|
||||
// Additional services category — only apply draft data when services are mutable.
|
||||
@@ -296,11 +304,11 @@ class BookingEditDraftMerger
|
||||
* The mandatory flag must be looked up from travel data since booking data
|
||||
* doesn't include the pflicht attribute.
|
||||
*
|
||||
* @param array $draftServices Services resolved from draft data
|
||||
* @param array $originalServices Services from fresh API data (booking assignments)
|
||||
* @param Travel $travel Travel data containing mandatory flag on services
|
||||
* @param list<Service> $draftServices Services resolved from draft data
|
||||
* @param list<Service> $originalServices Services from fresh API data (booking assignments)
|
||||
* @param Travel $travel Travel data containing mandatory flag on services
|
||||
*
|
||||
* @return array Merged array with draft services plus any missing mandatory services
|
||||
* @return list<Service> Merged array with draft services plus any missing mandatory services
|
||||
*/
|
||||
private function preserveMandatoryServices(array $draftServices, array $originalServices, Travel $travel): array
|
||||
{
|
||||
|
||||
@@ -171,6 +171,10 @@ class BookingEditSubmitGuard
|
||||
return $changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<Service> $left
|
||||
* @param list<Service> $right
|
||||
*/
|
||||
private function areServiceListsEqual(array $left, array $right): bool
|
||||
{
|
||||
return $this->normalizeServiceIds($left) === $this->normalizeServiceIds($right);
|
||||
|
||||
@@ -13,6 +13,7 @@ use App\Form\Model\BookingDto;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Session\FlashBagAwareSessionInterface;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
|
||||
/**
|
||||
@@ -119,7 +120,10 @@ class BookingEditSubmitter
|
||||
|
||||
private function addFlash(Request $request, string $type, string $message): void
|
||||
{
|
||||
$request->getSession()->getFlashBag()->add($type, $message);
|
||||
$session = $request->getSession();
|
||||
if ($session instanceof FlashBagAwareSessionInterface) {
|
||||
$session->getFlashBag()->add($type, $message);
|
||||
}
|
||||
}
|
||||
|
||||
private function redirectToEdit(int $bookingId): RedirectResponse
|
||||
|
||||
@@ -156,8 +156,8 @@ class BookingExporter
|
||||
/**
|
||||
* Creates the spreadsheet with participant data.
|
||||
*
|
||||
* @param BookingEditDraft $draft The draft containing form data
|
||||
* @param array $lookups The ID to label lookup arrays
|
||||
* @param BookingEditDraft $draft The draft containing form data
|
||||
* @param array<string, array<int, string>> $lookups The ID to label lookup arrays
|
||||
*/
|
||||
private function createSpreadsheet(BookingEditDraft $draft, array $lookups): Spreadsheet
|
||||
{
|
||||
@@ -203,6 +203,10 @@ class BookingExporter
|
||||
/**
|
||||
* Writes a single participant row to the spreadsheet.
|
||||
*/
|
||||
/**
|
||||
* @param array<string, mixed> $participant
|
||||
* @param array<string, array<int, string>> $lookups
|
||||
*/
|
||||
private function writeParticipantRow(
|
||||
\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet,
|
||||
int $row,
|
||||
@@ -298,6 +302,7 @@ class BookingExporter
|
||||
/**
|
||||
* Resolves a single service ID to its label.
|
||||
*/
|
||||
/** @param array<int, string> $lookup */
|
||||
private function resolveService(int|string|null $serviceId, array $lookup): string
|
||||
{
|
||||
if (null === $serviceId || '' === $serviceId) {
|
||||
@@ -312,6 +317,10 @@ class BookingExporter
|
||||
/**
|
||||
* Resolves an array of service IDs to labels, joined by pipe.
|
||||
*/
|
||||
/**
|
||||
* @param list<int|string|null> $serviceIds
|
||||
* @param array<int, string> $lookup
|
||||
*/
|
||||
private function resolveServiceArray(array $serviceIds, array $lookup): string
|
||||
{
|
||||
if (true === empty($serviceIds)) {
|
||||
@@ -332,6 +341,7 @@ class BookingExporter
|
||||
/**
|
||||
* Resolves a room ID to its label.
|
||||
*/
|
||||
/** @param array<int, string> $lookup */
|
||||
private function resolveRoom(?int $roomId, array $lookup): string
|
||||
{
|
||||
if (null === $roomId) {
|
||||
@@ -344,6 +354,7 @@ class BookingExporter
|
||||
/**
|
||||
* Resolves a pickup ID to its label.
|
||||
*/
|
||||
/** @param array<int, string> $lookup */
|
||||
private function resolvePickup(?int $pickupId, array $lookup): string
|
||||
{
|
||||
if (null === $pickupId) {
|
||||
|
||||
@@ -26,8 +26,8 @@ class BookingPriceMismatchAnalyzer
|
||||
{
|
||||
$pricingBreakdown = $this->pricingAssembler->getPricingBreakdown($bookingCreateDto);
|
||||
|
||||
$roomLines = $pricingBreakdown['rooms'] ?? [];
|
||||
$serviceGroups = $pricingBreakdown['services'] ?? [];
|
||||
$roomLines = $pricingBreakdown['rooms'];
|
||||
$serviceGroups = $pricingBreakdown['services'];
|
||||
|
||||
$roomTotal = round(array_sum(array_column($roomLines, 'totalPrice')), 2);
|
||||
$serviceTotal = round(array_sum(array_column($serviceGroups, 'groupTotal')), 2);
|
||||
@@ -70,14 +70,14 @@ class BookingPriceMismatchAnalyzer
|
||||
$apiTotal = round($response->totalPrice ?? 0.0, 2);
|
||||
$apiServiceTotal = round($apiTotal - $apiRoomTotal, 2);
|
||||
|
||||
$deltaTotal = round(($pricingBreakdown['grandTotal'] ?? 0.0) - $apiTotal, 2);
|
||||
$deltaTotal = round($pricingBreakdown['grandTotal'] - $apiTotal, 2);
|
||||
$deltaRoom = round($roomTotal - $apiRoomTotal, 2);
|
||||
$deltaService = round($serviceTotal - $apiServiceTotal, 2);
|
||||
$deltaInsurance = round($insuranceTotal - $apiInsuranceTotal, 2);
|
||||
|
||||
return [
|
||||
'localBreakdown' => [
|
||||
'grandTotal' => round($pricingBreakdown['grandTotal'] ?? 0.0, 2),
|
||||
'grandTotal' => round($pricingBreakdown['grandTotal'], 2),
|
||||
'roomTotal' => $roomTotal,
|
||||
'serviceTotal' => $serviceTotal,
|
||||
'insuranceTotal' => $insuranceTotal,
|
||||
|
||||
@@ -31,7 +31,7 @@ class BookingPricingAssembler
|
||||
/**
|
||||
* Assembles a complete pricing breakdown for display or diagnostic use.
|
||||
*
|
||||
* @return array{rooms: array, services: array, grandTotal: float, surcharges?: array}
|
||||
* @return array{rooms: array<int, array<string, mixed>>, services: array<int, array<string, mixed>>, grandTotal: float, surcharges?: array<int, array<string, mixed>>}
|
||||
*/
|
||||
public function getPricingBreakdown(
|
||||
BookingDto $bookingDto,
|
||||
@@ -251,7 +251,8 @@ class BookingPricingAssembler
|
||||
|
||||
foreach ($serviceAggregation as $serviceData) {
|
||||
$subType = $serviceData['subType'] ?? 'other';
|
||||
if (null === $subType || '' === $subType) {
|
||||
|
||||
if ('' === $subType) {
|
||||
$subType = 'other';
|
||||
}
|
||||
|
||||
@@ -308,6 +309,7 @@ class BookingPricingAssembler
|
||||
return Constants::SERVICE_LABELS[$subType] ?? 'Sonstige Leistungen';
|
||||
}
|
||||
|
||||
/** @param array<string, array<string, mixed>> $serviceAggregation */
|
||||
private function aggregateParticipantServices(
|
||||
ParticipantDto $participant,
|
||||
array &$serviceAggregation,
|
||||
@@ -338,16 +340,15 @@ class BookingPricingAssembler
|
||||
];
|
||||
|
||||
foreach ($multipleServiceArrays as $serviceArray) {
|
||||
if (true === is_array($serviceArray)) {
|
||||
foreach ($serviceArray as $service) {
|
||||
if ($service instanceof Service && null !== $service->price) {
|
||||
$this->addToServiceAggregation($serviceAggregation, $service);
|
||||
}
|
||||
foreach ($serviceArray as $service) {
|
||||
if (null !== $service->price) {
|
||||
$this->addToServiceAggregation($serviceAggregation, $service);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array<string, array<string, mixed>> $serviceAggregation */
|
||||
private function addToServiceAggregation(array &$serviceAggregation, Service $service, int $quantity = 1): void
|
||||
{
|
||||
$serviceKey = $service->id.'_'.$service->label;
|
||||
@@ -367,6 +368,7 @@ class BookingPricingAssembler
|
||||
$serviceAggregation[$serviceKey]['totalPrice'] += $service->price * $quantity;
|
||||
}
|
||||
|
||||
/** @param array<string, array<string, mixed>> $serviceAggregation */
|
||||
private function addInsuranceToServiceAggregation(array &$serviceAggregation, Insurance $insurance, int $quantity = 1): void
|
||||
{
|
||||
$serviceKey = $insurance->id.'_'.$insurance->label;
|
||||
|
||||
@@ -5,6 +5,8 @@ declare(strict_types=1);
|
||||
namespace App\Service;
|
||||
|
||||
use App\Exception\BookingSessionNotFoundException;
|
||||
use App\Exception\HotelNotInTravelException;
|
||||
use App\Exception\TravelNotFoundException;
|
||||
use App\Form\Model\BookingDto;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
@@ -32,6 +34,8 @@ class BookingSessionManager
|
||||
* Retrieves the booking creation DTO from the session.
|
||||
*
|
||||
* @throws BookingSessionNotFoundException
|
||||
* @throws TravelNotFoundException
|
||||
* @throws HotelNotInTravelException
|
||||
*/
|
||||
public function getOrCreateBookingCreateDto(Request $request): BookingDto
|
||||
{
|
||||
@@ -46,6 +50,8 @@ class BookingSessionManager
|
||||
|
||||
/**
|
||||
* Gets or creates the baseline room selection snapshot for change detection.
|
||||
*
|
||||
* @return array<int, array{int, int}>
|
||||
*/
|
||||
public function getOrCreateBaselineSnapshot(Request $request, BookingDto $bookingCreateDto): array
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ class CmsDataProvider
|
||||
return $result['hotel']['images'] ?? null;
|
||||
}
|
||||
|
||||
/** @return array<string, mixed> */
|
||||
public function getProductDetails(string $productCode, ?string $hotelCode = null): array
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -43,7 +43,7 @@ class InsuranceManager
|
||||
{
|
||||
$cacheKey = 'selectable_insurances_'.$travel->id;
|
||||
|
||||
return $this->selectableInsurancesCache[$cacheKey] ??= $this->filterNonComplementary($travel->insurances ?? []);
|
||||
return $this->selectableInsurancesCache[$cacheKey] ??= $this->filterNonComplementary($travel->insurances);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,7 +69,7 @@ class NewsletterManager
|
||||
];
|
||||
$this->mailer->createAndSendEmail($context, $options);
|
||||
} catch (\Throwable $exception) {
|
||||
if (true === $wasExisting && null !== $previousTokenHash && null !== $previousExpiresAt) {
|
||||
if (true === $wasExisting) {
|
||||
$pendingConfirmation->refreshRequest($previousTokenHash, $previousExpiresAt);
|
||||
} else {
|
||||
$this->entityManager->remove($pendingConfirmation);
|
||||
|
||||
@@ -65,7 +65,7 @@ class ParticipantPricingCalculator
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking data containing all participants
|
||||
*
|
||||
* @return array Array indexed by participant index containing individual prices
|
||||
* @return array<int, float> Array indexed by participant index containing individual prices
|
||||
*/
|
||||
public function calculateAllParticipantIndividualPrices(BookingDto $bookingDto): array
|
||||
{
|
||||
@@ -106,17 +106,17 @@ class ParticipantPricingCalculator
|
||||
// Generate cache key based on participant state that affects pricing
|
||||
$stateComponents = [
|
||||
'room' => $participant->assignedRoomId ?? 'none',
|
||||
'skiPass' => $participant->skiPass?->id ?? 'none',
|
||||
'rentalInsurance' => $participant->rentalInsurance?->id ?? 'none',
|
||||
'transportationOut' => $participant->transportationOutbound?->id ?? 'none',
|
||||
'transportationIn' => $participant->transportationInbound?->id ?? 'none',
|
||||
'pickup' => $participant->pickup?->id ?? 'none',
|
||||
'dropOff' => $participant->dropOff?->id ?? 'none',
|
||||
'parking' => $participant->parkingService?->id ?? 'none',
|
||||
'courses' => implode('_', array_map(fn ($s) => $s->id, $participant->courses ?? [])),
|
||||
'additionalServices' => implode('_', array_map(fn ($s) => $s->id, $participant->additionalServices ?? [])),
|
||||
'board' => implode('_', array_map(fn ($s) => $s->id, $participant->board ?? [])),
|
||||
'rentals' => implode('_', array_map(fn ($s) => $s->id, $participant->rentals ?? [])),
|
||||
'skiPass' => $participant->skiPass->id ?? 'none',
|
||||
'rentalInsurance' => $participant->rentalInsurance->id ?? 'none',
|
||||
'transportationOut' => $participant->transportationOutbound->id ?? 'none',
|
||||
'transportationIn' => $participant->transportationInbound->id ?? 'none',
|
||||
'pickup' => $participant->pickup->id ?? 'none',
|
||||
'dropOff' => $participant->dropOff->id ?? 'none',
|
||||
'parking' => $participant->parkingService->id ?? 'none',
|
||||
'courses' => implode('_', array_map(fn ($s) => $s->id, $participant->courses)),
|
||||
'additionalServices' => implode('_', array_map(fn ($s) => $s->id, $participant->additionalServices)),
|
||||
'board' => implode('_', array_map(fn ($s) => $s->id, $participant->board)),
|
||||
'rentals' => implode('_', array_map(fn ($s) => $s->id, $participant->rentals)),
|
||||
];
|
||||
|
||||
$cacheKey = sprintf(
|
||||
@@ -261,12 +261,10 @@ class ParticipantPricingCalculator
|
||||
];
|
||||
|
||||
foreach ($multipleServiceArrays as $serviceArray) {
|
||||
if (true === is_array($serviceArray)) {
|
||||
foreach ($serviceArray as $service) {
|
||||
if ($service instanceof Service && null !== $service->price) {
|
||||
if (false === $onlyInsuranceCalculationServices || true === $service->includeInInsuranceCalculation) {
|
||||
$serviceTotal += $service->price;
|
||||
}
|
||||
foreach ($serviceArray as $service) {
|
||||
if (null !== $service->price) {
|
||||
if (false === $onlyInsuranceCalculationServices || true === $service->includeInInsuranceCalculation) {
|
||||
$serviceTotal += $service->price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class RoomPricingCalculator
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking data containing room selections
|
||||
*
|
||||
* @return array Array of room pricing data with labels, quantities, and totals
|
||||
* @return array<int, array<string, mixed>> Array of room pricing data with labels, quantities, and totals
|
||||
*/
|
||||
public function calculateRoomPricing(
|
||||
BookingDto $bookingDto,
|
||||
@@ -73,7 +73,7 @@ class RoomPricingCalculator
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking data containing room selections
|
||||
*
|
||||
* @return array Array of room pricing data
|
||||
* @return array<int, array<string, mixed>> Array of room pricing data
|
||||
*/
|
||||
private function calculateRoomPricingFromSelections(BookingDto $bookingDto, string $pricingMode): array
|
||||
{
|
||||
@@ -122,7 +122,7 @@ class RoomPricingCalculator
|
||||
*
|
||||
* @param BookingDto $bookingDto The booking data with booking entity
|
||||
*
|
||||
* @return array Array of room pricing data with labels, quantities, and totals
|
||||
* @return array<int, array<string, mixed>> Array of room pricing data with labels, quantities, and totals
|
||||
*/
|
||||
private function calculateRoomPricingFromBooking(BookingDto $bookingDto): array
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Service;
|
||||
use App\BusProNet\Utility\DirectionMapper;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
|
||||
/**
|
||||
* Calculates dynamic service availability based on current booking selections.
|
||||
@@ -52,11 +53,11 @@ class ServiceAvailabilityCalculator
|
||||
/**
|
||||
* Filter services array to only include those with remaining availability.
|
||||
*
|
||||
* @param array $services Array of Service objects to filter
|
||||
* @param BookingDto $bookingDto The booking data with participant selections
|
||||
* @param int $participantIndex The index of the participant currently filling the form
|
||||
* @param array<int, Service> $services Array of Service objects to filter
|
||||
* @param BookingDto $bookingDto The booking data with participant selections
|
||||
* @param int $participantIndex The index of the participant currently filling the form
|
||||
*
|
||||
* @return array Filtered array containing only available services
|
||||
* @return array<int, Service> Filtered array containing only available services
|
||||
*/
|
||||
public function filterAvailableServices(array $services, BookingDto $bookingDto, int $participantIndex): array
|
||||
{
|
||||
@@ -139,7 +140,11 @@ class ServiceAvailabilityCalculator
|
||||
}
|
||||
|
||||
// Count service selections for this participant
|
||||
$this->countParticipantServiceUsage($participant, $serviceUsage);
|
||||
$participantUsage = $this->countParticipantServiceUsage($participant);
|
||||
|
||||
foreach ($participantUsage as $serviceId => $count) {
|
||||
$serviceUsage[$serviceId] = ($serviceUsage[$serviceId] ?? 0) + $count;
|
||||
}
|
||||
}
|
||||
|
||||
return $serviceUsage;
|
||||
@@ -148,56 +153,57 @@ class ServiceAvailabilityCalculator
|
||||
/**
|
||||
* Count service usage for a single participant and add to the usage array.
|
||||
*
|
||||
* @param mixed $participant The participant DTO object
|
||||
* @param array $serviceUsage Reference to the service usage array to update
|
||||
* @param ParticipantDto $participant The participant DTO object
|
||||
*
|
||||
* @return array<int, int> Usage counts keyed by service ID
|
||||
*/
|
||||
private function countParticipantServiceUsage($participant, array &$serviceUsage): void
|
||||
private function countParticipantServiceUsage(ParticipantDto $participant): array
|
||||
{
|
||||
$serviceUsage = [];
|
||||
|
||||
// Board service (single selection)
|
||||
if (isset($participant->board) && $participant->board instanceof Service) {
|
||||
$serviceUsage[$participant->board->id] = ($serviceUsage[$participant->board->id] ?? 0) + 1;
|
||||
foreach ($participant->board as $service) {
|
||||
if (null !== $service->id) {
|
||||
$serviceUsage[$service->id] = ($serviceUsage[$service->id] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Ski pass service (single selection)
|
||||
if (isset($participant->skiPass) && $participant->skiPass instanceof Service) {
|
||||
if (null !== $participant->skiPass && null !== $participant->skiPass->id) {
|
||||
$serviceUsage[$participant->skiPass->id] = ($serviceUsage[$participant->skiPass->id] ?? 0) + 1;
|
||||
}
|
||||
|
||||
// Transportation services (single selection each)
|
||||
if (isset($participant->transportationOutbound) && $participant->transportationOutbound instanceof Service) {
|
||||
if (null !== $participant->transportationOutbound && null !== $participant->transportationOutbound->id) {
|
||||
$serviceUsage[$participant->transportationOutbound->id] = ($serviceUsage[$participant->transportationOutbound->id] ?? 0) + 1;
|
||||
}
|
||||
|
||||
if (isset($participant->transportationInbound) && $participant->transportationInbound instanceof Service) {
|
||||
if (null !== $participant->transportationInbound && null !== $participant->transportationInbound->id) {
|
||||
$serviceUsage[$participant->transportationInbound->id] = ($serviceUsage[$participant->transportationInbound->id] ?? 0) + 1;
|
||||
}
|
||||
|
||||
// Courses (multiple selection)
|
||||
if (isset($participant->courses) && is_array($participant->courses)) {
|
||||
foreach ($participant->courses as $course) {
|
||||
if ($course instanceof Service) {
|
||||
$serviceUsage[$course->id] = ($serviceUsage[$course->id] ?? 0) + 1;
|
||||
}
|
||||
foreach ($participant->courses as $course) {
|
||||
if (null !== $course->id) {
|
||||
$serviceUsage[$course->id] = ($serviceUsage[$course->id] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional services (multiple selection)
|
||||
if (isset($participant->additionalServices) && is_array($participant->additionalServices)) {
|
||||
foreach ($participant->additionalServices as $additionalService) {
|
||||
if ($additionalService instanceof Service) {
|
||||
$serviceUsage[$additionalService->id] = ($serviceUsage[$additionalService->id] ?? 0) + 1;
|
||||
}
|
||||
foreach ($participant->additionalServices as $additionalService) {
|
||||
if (null !== $additionalService->id) {
|
||||
$serviceUsage[$additionalService->id] = ($serviceUsage[$additionalService->id] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Rentals (multiple selection)
|
||||
if (isset($participant->rentals) && is_array($participant->rentals)) {
|
||||
foreach ($participant->rentals as $rental) {
|
||||
if ($rental instanceof Service) {
|
||||
$serviceUsage[$rental->id] = ($serviceUsage[$rental->id] ?? 0) + 1;
|
||||
}
|
||||
foreach ($participant->rentals as $rental) {
|
||||
if (null !== $rental->id) {
|
||||
$serviceUsage[$rental->id] = ($serviceUsage[$rental->id] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $serviceUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,8 +219,8 @@ class ServiceAvailabilityCalculator
|
||||
|
||||
// Get all transportation services
|
||||
$transportationServices = array_merge(
|
||||
$bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::OUTBOUND_TRAVEL) ?? [],
|
||||
$bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::INBOUND_TRAVEL) ?? []
|
||||
$bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::OUTBOUND_TRAVEL),
|
||||
$bookingDto->travel->getTransportationServicesByDirection(DirectionMapper::INBOUND_TRAVEL)
|
||||
);
|
||||
$allServices = array_merge($allServices, $transportationServices);
|
||||
|
||||
@@ -228,7 +234,7 @@ class ServiceAvailabilityCalculator
|
||||
];
|
||||
|
||||
foreach ($additionalServiceTokens as $token) {
|
||||
$categoryServices = $bookingDto->travel->getAdditionalServicesBySubTypes($token) ?? [];
|
||||
$categoryServices = $bookingDto->travel->getAdditionalServicesBySubTypes($token);
|
||||
$allServices = array_merge($allServices, $categoryServices);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,10 +40,6 @@ final class ServiceLabelFormatter
|
||||
return $fallbackLabel;
|
||||
}
|
||||
|
||||
if (!$service instanceof Service) {
|
||||
return $fallbackLabel;
|
||||
}
|
||||
|
||||
return $this->formatServiceLabel($service);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ use App\BusProNet\Model\Notification;
|
||||
use App\BusProNet\Model\ServiceAvailabilityResponse;
|
||||
use App\BusProNet\Model\Travel;
|
||||
use App\BusProNet\XmlLoader\TravelLoader;
|
||||
use App\Exception\HotelNotFoundException;
|
||||
use App\Exception\HotelNotInTravelException;
|
||||
use App\Exception\TravelNotFoundException;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
@@ -86,7 +85,6 @@ class TravelDataProvider
|
||||
* @return Travel|null The travel data or null on unexpected failure
|
||||
*
|
||||
* @throws TravelNotFoundException When the travel date is not found
|
||||
* @throws HotelNotFoundException When the requested hotel is not found
|
||||
* @throws HotelNotInTravelException When the hotel does not belong to this travel
|
||||
*/
|
||||
public function getTravelDataFromXml(int $dateId, ?int $hotelId = null): ?Travel
|
||||
@@ -100,7 +98,7 @@ class TravelDataProvider
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
throw $e;
|
||||
} catch (HotelNotFoundException|HotelNotInTravelException $e) {
|
||||
} catch (HotelNotInTravelException $e) {
|
||||
$this->logger->debug('Hotel not found in XML', [
|
||||
'dateId' => $dateId,
|
||||
'hotelId' => $hotelId,
|
||||
|
||||
Reference in New Issue
Block a user