chore: fix phpstan errors
This commit is contained in:
1 parent
4e925171b3
commit
0fcecc9c58
109 files changed
+510
-429
No files matched your search
@@ -7,6 +7,7 @@ use App\BusProNet\Exception\ApiClientException;
|
||||
use App\BusProNet\Exception\ImmediateConnectionCloseException;
|
||||
use App\BusProNet\Exception\ResponseParserException;
|
||||
use App\BusProNet\Exception\TimeoutException;
|
||||
use App\BusProNet\Model\Agency;
|
||||
use App\BusProNet\Model\BaseData;
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\BusProNet\Model\BookingResponse;
|
||||
@@ -49,11 +50,13 @@ class ApiClient
|
||||
public const TYPE_PURCHASE_VOUCHER = 'GUTSCHEINPRUEFUNGEINLOESUNG';
|
||||
public const TYPE_PROMO_VOUCHER = 'AKTIONSGUTSCHEIN';
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private array $config;
|
||||
private float $operationStartTime;
|
||||
private int $selectedPort;
|
||||
private int $requestCounter = 0;
|
||||
|
||||
/** @param array<string, mixed> $options */
|
||||
public function __construct(
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly ApiResponseParser $responseParser,
|
||||
@@ -613,6 +616,10 @@ class ApiClient
|
||||
/**
|
||||
* @throws ApiClientException
|
||||
*/
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
* @param array<string, mixed> $additionalArgs
|
||||
*/
|
||||
private function sendRequest(string $type, array $data, array $additionalArgs = [], bool $debug = false): mixed
|
||||
{
|
||||
return $this->executeWithRetry(fn () => $this->doSendRequest($type, $data, $additionalArgs, $debug), $type);
|
||||
@@ -621,6 +628,7 @@ class ApiClient
|
||||
/**
|
||||
* @throws ApiClientException
|
||||
*/
|
||||
/** @param array<string, mixed> $data */
|
||||
private function sendRequestRaw(array $data): string
|
||||
{
|
||||
return $this->executeWithRetry(fn () => $this->doSendRequestRaw($data));
|
||||
@@ -676,6 +684,10 @@ class ApiClient
|
||||
* @throws ApiClientException
|
||||
* @throws ImmediateConnectionCloseException
|
||||
*/
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
* @param array<string, mixed> $additionalArgs
|
||||
*/
|
||||
private function doSendRequest(string $type, array $data, array $additionalArgs = [], bool $debug = false): mixed
|
||||
{
|
||||
$requestId = $this->getRequestId();
|
||||
@@ -733,6 +745,8 @@ class ApiClient
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @throws ApiClientException
|
||||
* @throws ImmediateConnectionCloseException
|
||||
*/
|
||||
@@ -794,6 +808,8 @@ class ApiClient
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*
|
||||
* @throws ApiClientException
|
||||
* @throws TimeoutException
|
||||
*/
|
||||
@@ -857,6 +873,8 @@ class ApiClient
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $socket
|
||||
*
|
||||
* @throws TimeoutException
|
||||
*/
|
||||
private function send($socket, string $data): void
|
||||
@@ -875,6 +893,8 @@ class ApiClient
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $socket
|
||||
*
|
||||
* @throws TimeoutException
|
||||
* @throws ImmediateConnectionCloseException
|
||||
*/
|
||||
@@ -937,11 +957,17 @@ class ApiClient
|
||||
return $response;
|
||||
}
|
||||
|
||||
/** @param resource $socket */
|
||||
private function disconnect($socket): void
|
||||
{
|
||||
@fclose($socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $options
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function resolveOptions(array $options): array
|
||||
{
|
||||
$optionsResolver = new OptionsResolver();
|
||||
|
||||
@@ -73,14 +73,12 @@ class BookingDataProcessor
|
||||
if (0 === $index) {
|
||||
// Copy address if first participant has no street (indicating empty/incomplete address)
|
||||
// This allows applicant and first participant to be different people with different addresses
|
||||
if (null !== $booking->applicant->address) {
|
||||
$isEmpty = null === $participantData->address
|
||||
|| null === $participantData->address->street
|
||||
|| '' === trim($participantData->address->street);
|
||||
$isEmpty = null === $participantData->address
|
||||
|| null === $participantData->address->street
|
||||
|| '' === trim($participantData->address->street);
|
||||
|
||||
if ($isEmpty) {
|
||||
$participantData->address = clone $booking->applicant->address;
|
||||
}
|
||||
if ($isEmpty) {
|
||||
$participantData->address = clone $booking->applicant->address;
|
||||
}
|
||||
|
||||
// Copy body dimensions from applicant if not present in participant
|
||||
@@ -284,7 +282,7 @@ class BookingDataProcessor
|
||||
*
|
||||
* @param BookingDto|null $formData The booking edit form data containing updated participant and service selections
|
||||
*
|
||||
* @return array The structured payload array ready for BusProNet API submission
|
||||
* @return array<string, mixed> The structured payload array ready for BusProNet API submission
|
||||
*/
|
||||
public function createUpdateRequestPayload(?BookingDto $formData): array
|
||||
{
|
||||
@@ -345,7 +343,7 @@ class BookingDataProcessor
|
||||
* @param BookingDto $bookingDto The booking creation form data
|
||||
* @param string $bookingType Either 'Anfrage' (inquiry) or 'Buchung' (final booking)
|
||||
*
|
||||
* @return array The structured payload array for BusProNet API submission
|
||||
* @return array<string, mixed> The structured payload array for BusProNet API submission
|
||||
*/
|
||||
public function createBookingRequestPayload(BookingDto $bookingDto, string $bookingType): array
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace App\BusProNet\DataProcessor;
|
||||
use App\BusProNet\Constants;
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\Form\Model\BookingDto;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
|
||||
/**
|
||||
* Builds API payload structures for BusProNet booking requests.
|
||||
@@ -30,7 +31,7 @@ class BookingPayloadBuilder
|
||||
*
|
||||
* @param Booking $bookingData The booking data object
|
||||
*
|
||||
* @return array The base payload structure
|
||||
* @return array<string, mixed> The base payload structure
|
||||
*/
|
||||
public function buildBasePayload(Booking $bookingData): array
|
||||
{
|
||||
@@ -66,8 +67,8 @@ class BookingPayloadBuilder
|
||||
*
|
||||
* Bank account information is required for direct debit payments.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
*/
|
||||
public function addBankAccountToPayload(array &$payload, Booking $bookingData): void
|
||||
{
|
||||
@@ -86,9 +87,9 @@ class BookingPayloadBuilder
|
||||
*
|
||||
* Includes status, personal data, and wishes (room remarks, license plate) for each participant.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
* @param array $participantDtos The participant DTOs from the form (for wishes data)
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
* @param array<int, ParticipantDto> $participantDtos The participant DTOs from the form (for wishes data)
|
||||
*/
|
||||
public function buildParticipantPayload(array &$payload, Booking $bookingData, array $participantDtos): void
|
||||
{
|
||||
@@ -141,8 +142,8 @@ class BookingPayloadBuilder
|
||||
* Includes additional services, transportation services, and accommodation details
|
||||
* with participant mappings and quantities.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
*/
|
||||
public function buildServicesPayload(array &$payload, Booking $bookingData): void
|
||||
{
|
||||
@@ -198,8 +199,8 @@ class BookingPayloadBuilder
|
||||
*
|
||||
* Only included in payload if there are actual pickup assignments for bus transportation.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
*/
|
||||
public function buildPickupPayload(array &$payload, Booking $bookingData): void
|
||||
{
|
||||
@@ -223,8 +224,8 @@ class BookingPayloadBuilder
|
||||
*
|
||||
* Only included in payload if there are actual drop-off assignments for bus transportation.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param Booking $bookingData The booking data object
|
||||
*/
|
||||
public function buildDropOffPayload(array &$payload, Booking $bookingData): void
|
||||
{
|
||||
@@ -249,7 +250,7 @@ class BookingPayloadBuilder
|
||||
* @param BookingDto $bookingDto The booking creation form data
|
||||
* @param string $bookingType Either 'Anfrage' (inquiry) or 'Buchung' (final booking)
|
||||
*
|
||||
* @return array The structured payload array for BusProNet API submission
|
||||
* @return array<string, mixed> The structured payload array for BusProNet API submission
|
||||
*/
|
||||
public function buildCreatePayload(BookingDto $bookingDto, string $bookingType): array
|
||||
{
|
||||
@@ -439,11 +440,11 @@ class BookingPayloadBuilder
|
||||
* Generic helper method that converts service ID => participant IDs mappings
|
||||
* into XML payload structure.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param string $sectionKey The section key (e.g., 'beförderungen', 'versicherungen')
|
||||
* @param string $itemKey The item key (e.g., 'beförderung', 'versicherung')
|
||||
* @param string $idAttributeName The ID attribute name (e.g., '@idleistung', '@idversicherung')
|
||||
* @param array $serviceMap Map of service ID to participant IDs
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param string $sectionKey The section key (e.g., 'beförderungen', 'versicherungen')
|
||||
* @param string $itemKey The item key (e.g., 'beförderung', 'versicherung')
|
||||
* @param string $idAttributeName The ID attribute name (e.g., '@idleistung', '@idversicherung')
|
||||
* @param array<int|string, int[]> $serviceMap Map of service ID to participant IDs
|
||||
*/
|
||||
public function addServicesFromMap(
|
||||
array &$payload,
|
||||
@@ -475,9 +476,9 @@ class BookingPayloadBuilder
|
||||
* - 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 BookingDto $bookingDto The booking data for accessing room details and quantities
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param array<int|string, int[]> $roomMap Map of room ID to participant IDs
|
||||
* @param BookingDto $bookingDto The booking data for accessing room details and quantities
|
||||
*/
|
||||
public function addRoomMappingsToPayload(array &$payload, array $roomMap, BookingDto $bookingDto): void
|
||||
{
|
||||
@@ -520,8 +521,8 @@ class BookingPayloadBuilder
|
||||
/**
|
||||
* Adds purchase vouchers to the payload.
|
||||
*
|
||||
* @param array $payload The payload array to modify
|
||||
* @param BookingDto $bookingDto The booking data
|
||||
* @param array<string, mixed> $payload The payload array to modify
|
||||
* @param BookingDto $bookingDto The booking data
|
||||
*/
|
||||
public function addPurchaseVouchersToPayload(array &$payload, BookingDto $bookingDto): void
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace App\BusProNet\DataProcessor;
|
||||
|
||||
use App\BusProNet\Model\Address;
|
||||
use App\BusProNet\Model\Booking;
|
||||
use App\BusProNet\Model\Communication;
|
||||
use App\BusProNet\Model\PersonalData;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
|
||||
@@ -86,9 +85,6 @@ class PersonalDataSynchronizer
|
||||
}
|
||||
|
||||
if ($participant->email || $participant->mobile) {
|
||||
if (null === $bookingData->participants[$participant->index]->communication) {
|
||||
$bookingData->participants[$participant->index]->communication = new Communication();
|
||||
}
|
||||
$bookingData->participants[$participant->index]->communication->email = $participant->email;
|
||||
$bookingData->participants[$participant->index]->communication->mobile = $participant->mobile;
|
||||
}
|
||||
@@ -127,10 +123,6 @@ class PersonalDataSynchronizer
|
||||
$applicant->dateOfBirth = new \DateTimeImmutable('-20 years');
|
||||
}
|
||||
|
||||
if (null === $applicant->communication) {
|
||||
$applicant->communication = new Communication();
|
||||
}
|
||||
|
||||
if (null === $applicant->communication->mobile || '' === $applicant->communication->mobile) {
|
||||
$applicant->communication->mobile = '12345';
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class ServiceMappingCollector
|
||||
*
|
||||
* Groups participants by their assigned room ID.
|
||||
*
|
||||
* @return array<string, array<int>> Map of room ID to participant IDs
|
||||
* @return array<int, list<int>> Map of room ID to participant IDs
|
||||
*/
|
||||
public function collectRoomMappings(BookingDto $bookingDto): array
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ class CountryDataProvider
|
||||
{
|
||||
}
|
||||
|
||||
/** @return array<string, Country> */
|
||||
public function getAll(): array
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -10,6 +10,7 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/** @extends AbstractType<string> */
|
||||
class CountryType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly CountryDataProvider $countries)
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace App\BusProNet\Model;
|
||||
*/
|
||||
class AgeConstraintResult
|
||||
{
|
||||
/** @param array<string, mixed> $metadata */
|
||||
public function __construct(
|
||||
public readonly string $type,
|
||||
public readonly ?int $ageFrom = null,
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace App\BusProNet\Model;
|
||||
*/
|
||||
class BaseData
|
||||
{
|
||||
/** @param array<array-key, mixed> $items */
|
||||
public function __construct(private readonly array $items)
|
||||
{
|
||||
}
|
||||
@@ -19,7 +20,7 @@ class BaseData
|
||||
/**
|
||||
* Retrieves all items in the base data collection.
|
||||
*
|
||||
* @return array The complete items array
|
||||
* @return array<array-key, mixed> The complete items array
|
||||
*/
|
||||
public function getItems(): array
|
||||
{
|
||||
|
||||
@@ -220,7 +220,7 @@ class Booking
|
||||
public function getInsuranceForParticipant(int $participantIndex): ?Insurance
|
||||
{
|
||||
foreach ($this->insurances as $insurance) {
|
||||
if (in_array($participantIndex, $insurance->mapping ?? [], true)) {
|
||||
if (in_array($participantIndex, $insurance->mapping, true)) {
|
||||
return $insurance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class CrmSelectionGroup
|
||||
* Maps BusPro IDs of CRM selection groups representing
|
||||
* included services.
|
||||
*
|
||||
* @var array<string, string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
public static array $includedServicesMapping = [
|
||||
7 => 'Skipass',
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\Model;
|
||||
|
||||
/**
|
||||
* Represents error codes and messages for the BusProNet API.
|
||||
*
|
||||
* This class provides a static mapping of error codes to their corresponding
|
||||
* German error messages for consistent error handling across the application.
|
||||
* Error codes range from 100-999 and cover various API scenarios.
|
||||
*/
|
||||
class Error
|
||||
{
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private static array $errors = [
|
||||
100 => 'Anfrageknoten fehlt',
|
||||
101 => 'Satzknoten fehlt in Anfrageknoten',
|
||||
102 => 'Ungültiger Satztyp [#1#]',
|
||||
103 => 'User fehlt',
|
||||
104 => 'User fehlerhaft',
|
||||
105 => 'Key fehlt',
|
||||
106 => 'Key fehlerhaft',
|
||||
200 => 'Keine Einträge vorhanden',
|
||||
201 => 'Keine Partner zur Auswahl gefunden',
|
||||
202 => 'Keinen Partner mit der ID [#1#] gefunden',
|
||||
203 => 'Ungültiger Termin',
|
||||
300 => 'IDReise fehlt',
|
||||
301 => 'Reise nicht gefunden',
|
||||
302 => 'IDLeistung (Hin & Rück) fehlt',
|
||||
303 => 'IDLeistung passt nicht zu IDReise',
|
||||
304 => 'Es konnte nicht für alle Teilnehmer ein Sitzplatz ermittelt werden',
|
||||
305 => 'Anzahl Personen fehlt',
|
||||
306 => 'Leistungen mit ID #1# nicht gefunden',
|
||||
307 => 'Leistungen mit ID #1# passen nicht zur Reise mit ID #2#',
|
||||
308 => 'Keine Zahlungsarten gefunden',
|
||||
400 => 'IDPartner fehlt',
|
||||
401 => 'Partner nicht gefunden',
|
||||
402 => 'Bis-Termin fehlt',
|
||||
403 => 'Keine Unterbringungsleistungen gefunden',
|
||||
500 => 'Art fehlt',
|
||||
501 => 'Reise- und Buchungszeitraum fehlen',
|
||||
502 => 'Keine Kunden gefunden',
|
||||
600 => 'Keine Gutscheine gefunden',
|
||||
601 => 'Gutschein-IDs fehlen',
|
||||
602 => 'Gutscheine mit ID #1# nicht gefunden',
|
||||
610 => 'Buchungsart fehlt',
|
||||
611 => 'Buchungsart falsch',
|
||||
612 => 'Gutscheinart fehlt',
|
||||
613 => 'Gutscheinart falsch',
|
||||
614 => 'Gutscheinstamm-ID fehlt',
|
||||
615 => 'Gutschein (Stamm) mit ID #1# nicht gefunden',
|
||||
616 => 'Kapazität beim Gutschein #1# nicht ausreichend',
|
||||
617 => 'Rechnungsempfänger fehlt',
|
||||
618 => 'Zahlungsart fehlt',
|
||||
619 => 'Agentur-ID fehlt',
|
||||
620 => 'Agentur mit ID #1# nicht gefunden',
|
||||
650 => '#1#',
|
||||
700 => 'Keine Agenturen gefunden',
|
||||
701 => 'Agentur mit ID #1# nicht gefunden',
|
||||
800 => 'Produkt-ID fehlt',
|
||||
801 => 'Produkt mit ID #1# nicht gefunden',
|
||||
805 => 'Es wurden keine Produkte gefunden',
|
||||
810 => 'Stammdaten (#1#) nicht gefunden',
|
||||
900 => 'Buchungsart fehlt',
|
||||
901 => 'Buchungsart falsch',
|
||||
902 => 'Status fehlt',
|
||||
903 => 'Status falsch',
|
||||
904 => 'Agentur-ID fehlt',
|
||||
905 => 'Agentur mit ID #1# nicht gefunden',
|
||||
906 => 'Reise-ID fehlt',
|
||||
907 => 'Reise mit ID #1# nicht gefunden',
|
||||
908 => 'Reise mit ID #1# ist storniert',
|
||||
909 => 'Beförderungen fehlen',
|
||||
910 => 'Leistung mit ID #1# gehört nicht zur Reise',
|
||||
911 => 'Leistung mit ID #1# gehört nicht zum Produkt',
|
||||
912 => 'Beförderungsleistung für die #1# fehlt',
|
||||
913 => 'Unterbringungen fehlen',
|
||||
914 => 'Partner-ID fehlt',
|
||||
915 => 'Partner mit ID #1# nicht gefunden',
|
||||
916 => 'Ferienziel-Unterbringungen fehlen',
|
||||
917 => 'Ferienziel: Zimmer-IDZ fehlt',
|
||||
918 => 'Ferienziel: Kategorie fehlt',
|
||||
919 => 'Ferienziel: Verpflegungs-ID fehlt',
|
||||
920 => 'Ferienziel: Anreise fehlt',
|
||||
921 => 'Ferienziel: Anreise passt nicht zur Beförderungsleistung (Hinfahrt)',
|
||||
922 => 'Ferienziel: Abreise fehlt',
|
||||
923 => 'Ferienziel: Abreise passt nicht zur Beförderungsleistung (Rückfahrt)',
|
||||
924 => 'Ferienziel: Keine Preise zu den Daten gefunden',
|
||||
925 => 'Ferienziel: Preis zu den Daten nicht gefunden',
|
||||
930 => 'Zustiege fehlen',
|
||||
931 => 'Zustieg mit ID #1# nicht gefunden',
|
||||
932 => 'Zustieg mit ID #1# bei Leistung #2# nicht freigegeben',
|
||||
933 => 'Sitzplan mit ID #1# bei Leistung #2# nicht freigegeben',
|
||||
935 => 'Versicherung mit ID #1# nicht gefunden',
|
||||
940 => 'Zahlungsart fehlt',
|
||||
941 => 'Zahlungsart-ID fehlt',
|
||||
942 => 'Zahlungsart mit ID #1# nicht gültig',
|
||||
950 => 'Anmelder fehlt',
|
||||
951 => 'Teilnehmerliste fehlt',
|
||||
952 => 'Teilnehmer-ID fehlt',
|
||||
960 => 'Preisfehler: Struct #1# / Obj #2#',
|
||||
961 => 'Buchung konnte nicht gespeichert werden',
|
||||
980 => 'Reise ist fürs Internet gesperrt',
|
||||
981 => 'Reise ist nicht mehr buchbar (#1#)',
|
||||
982 => 'Optionsbuchungen nicht zugelassen',
|
||||
983 => 'Anfragebuchung nicht zugelassen',
|
||||
984 => 'Leistung mit ID #1# nicht fürs Internet buchbar',
|
||||
985 => 'Zustieg mit ID #1# nicht fürs Internet buchbar',
|
||||
999 => 'Systemfehler: #1#',
|
||||
];
|
||||
}
|
||||
@@ -56,7 +56,9 @@ class PersonalData
|
||||
#[Assert\Valid(groups: ['personal_data'])]
|
||||
public Communication $communication;
|
||||
|
||||
/** @var list<string> */
|
||||
public array $roles = [];
|
||||
/** @var list<string> */
|
||||
public array $hotelCodes = [];
|
||||
|
||||
public function __construct()
|
||||
|
||||
@@ -45,6 +45,7 @@ class Pickup
|
||||
#[Groups(['api:single', 'snapshot'])]
|
||||
public ?float $priceInbound = null;
|
||||
|
||||
/** @var list<int> */
|
||||
#[Groups(['api:booking'])]
|
||||
public array $mapping = [];
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ class Room
|
||||
#[Groups(['booking'])]
|
||||
public ?string $board = null;
|
||||
|
||||
/** @var list<int> */
|
||||
#[Groups(['booking'])]
|
||||
public array $mapping = [];
|
||||
|
||||
@@ -73,6 +74,7 @@ class Room
|
||||
#[Groups(['booking'])]
|
||||
public ?float $totalPrice = null;
|
||||
|
||||
/** @var array<int, float|null> */
|
||||
#[Groups(['booking'])]
|
||||
public array $individualPrice = [];
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ class Service
|
||||
#[Groups(['booking'])]
|
||||
public ?int $totalCount = null;
|
||||
|
||||
/** @var list<int> */
|
||||
#[Groups(['api:single', 'snapshot'])]
|
||||
public array $mapping = [];
|
||||
|
||||
@@ -64,6 +65,7 @@ class Service
|
||||
#[Groups(['api:single', 'snapshot'])]
|
||||
public ?float $totalPrice = null;
|
||||
|
||||
/** @var array<int, float|null> */
|
||||
#[Groups(['api:single', 'snapshot'])]
|
||||
public array $individualPrice = [];
|
||||
|
||||
@@ -91,6 +93,7 @@ class Service
|
||||
#[Groups(['api:single', 'api:list', 'snapshot'])]
|
||||
public ?string $ageConstraintType = null;
|
||||
|
||||
/** @var array<string, mixed>|null */
|
||||
#[Groups(['api:single'])]
|
||||
public ?array $ageConstraintMetadata = null;
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@ namespace App\BusProNet\Model;
|
||||
class Surcharge
|
||||
{
|
||||
public ?string $label = null;
|
||||
/** @var list<int> */
|
||||
public array $mapping = [];
|
||||
public ?float $totalPrice = null;
|
||||
/** @var array<int, float|null> */
|
||||
public array $individualPrice = [];
|
||||
}
|
||||
@@ -203,7 +203,7 @@ class Travel
|
||||
* Maps selection group IDs to their corresponding services based on
|
||||
* the predefined included services mapping.
|
||||
*
|
||||
* @return array<int, Service> The included services from selection groups
|
||||
* @return array<int, CrmSelectionGroup> The included services from selection groups
|
||||
*/
|
||||
public function getIncludedServices(): array
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ class ChaperonServiceStatusRule implements BookingStatusRuleInterface
|
||||
|
||||
foreach ($arrayServices as $services) {
|
||||
foreach ($services as $service) {
|
||||
if ($service instanceof Service && true === $this->containsSearchTerm($service->label)) {
|
||||
if (true === $this->containsSearchTerm($service->label)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ trait SortByPriceTrait
|
||||
* collections in the application. Items are sorted from lowest to highest price,
|
||||
* with null prices being treated as zero (appearing first).
|
||||
*
|
||||
* @param array $items Array of objects with a price property to sort
|
||||
* @param array<array-key, object> $items Array of objects with a price property to sort
|
||||
*
|
||||
* @return array The sorted array of objects (ascending by price)
|
||||
* @return array<array-key, object> The sorted array of objects (ascending by price)
|
||||
*/
|
||||
protected function sortByPrice(array $items): array
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ use Carbon\Exceptions\InvalidFormatException;
|
||||
|
||||
trait TypeConversionTrait
|
||||
{
|
||||
/** @return list<string> */
|
||||
protected function stringToArray(?string $string, string $separator = ','): array
|
||||
{
|
||||
if (true === empty($string)) {
|
||||
|
||||
@@ -11,6 +11,7 @@ use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
class HotelLoader extends AbstractLoader
|
||||
{
|
||||
/** @return array<int, Hotel> */
|
||||
public function loadAll(?string $filename = 'hotel.xml'): array
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -22,6 +22,7 @@ class InsuranceLoader extends AbstractLoader
|
||||
parent::__construct($cache, $xmlExport);
|
||||
}
|
||||
|
||||
/** @return array<string|int, Insurance> */
|
||||
public function loadAll(?string $filename = 'versicherungen.xml'): array
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -10,6 +10,7 @@ use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
class PickupLoader extends AbstractLoader
|
||||
{
|
||||
/** @return array<int|string, Pickup> */
|
||||
public function loadAll(?string $filename = 'zustiege.xml'): array
|
||||
{
|
||||
try {
|
||||
@@ -65,6 +66,11 @@ class PickupLoader extends AbstractLoader
|
||||
$travel->dropOffs = $this->patchAndOrderDropOffs($travel->dropOffs, $travel->pickups);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, Pickup> $pickups
|
||||
*
|
||||
* @return array<int, Pickup>
|
||||
*/
|
||||
private function patchAndSortPickups(array $pickups): array
|
||||
{
|
||||
$this->enrichPickupDetails($pickups);
|
||||
|
||||
@@ -51,7 +51,7 @@ class TravelLoader extends AbstractLoader
|
||||
* including ID, code, label, dates, and associated hotels. The mapping is
|
||||
* cached for 3 hours to improve performance.
|
||||
*
|
||||
* @return array<int, array> Mapping of travel IDs to their metadata and file paths
|
||||
* @return array<int, array<string, mixed>> Mapping of travel IDs to their metadata and file paths
|
||||
*/
|
||||
public function generateFilesMap(): array
|
||||
{
|
||||
@@ -74,7 +74,7 @@ class TravelLoader extends AbstractLoader
|
||||
$travelDataNodes = $crawler->filterXPath('//reisen/reise/termin');
|
||||
|
||||
$travelDataNodes->each(function (Crawler $node) use (&$mapping, $hotels, $file) {
|
||||
$travelId = $node->attr('idbuspro');
|
||||
$travelId = (int) $node->attr('idbuspro');
|
||||
|
||||
$mapping[$travelId] = [
|
||||
'id' => $travelId,
|
||||
@@ -173,6 +173,7 @@ class TravelLoader extends AbstractLoader
|
||||
*
|
||||
* @throws TravelNotFoundException When travel ID is not found
|
||||
* @throws HotelNotInTravelException When hotel ID exists but not for this travel
|
||||
* @throws \RuntimeException When cached mapping generation fails unexpectedly
|
||||
*/
|
||||
public function loadById(int $dateId, ?int $hotelId = null, ?string $filename = null): Travel
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ abstract class AbstractParser
|
||||
return 0 < $node->count() && $this->stringToBool($node->text());
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
protected function getArrayValue(Crawler $node, string $separator = ','): array
|
||||
{
|
||||
if (0 === $node->count()) {
|
||||
|
||||
@@ -53,6 +53,7 @@ class AgeConstraintParserRegistry
|
||||
return $this->mergeConstraintResults($results, $constraintData);
|
||||
}
|
||||
|
||||
/** @param list<AgeConstraintResult> $results */
|
||||
private function mergeConstraintResults(array $results, string $rawData): AgeConstraintResult
|
||||
{
|
||||
if (empty($results)) {
|
||||
|
||||
@@ -11,6 +11,7 @@ class ApiResponseParser extends AbstractParser
|
||||
/**
|
||||
* @throws ResponseParserException
|
||||
*/
|
||||
/** @param array<string, mixed> $additionalArgs */
|
||||
public function parseXmlString(string $type, string $xml, array $additionalArgs = []): mixed
|
||||
{
|
||||
$crawler = new Crawler($xml);
|
||||
|
||||
@@ -15,6 +15,7 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
*/
|
||||
class BookingInsurancesParser extends AbstractParser
|
||||
{
|
||||
/** @return array<string, Insurance> */
|
||||
public function parse(Crawler $result): array
|
||||
{
|
||||
$insurances = [];
|
||||
|
||||
@@ -112,6 +112,7 @@ class BookingParser extends AbstractParser
|
||||
return $booking;
|
||||
}
|
||||
|
||||
/** @return array<int, PersonalData> */
|
||||
private function parseParticipants(Crawler $node): array
|
||||
{
|
||||
$participants = [];
|
||||
|
||||
@@ -27,7 +27,7 @@ class CrmAttributesResponseParser
|
||||
|
||||
$result
|
||||
->filterXPath('//selektionsmerkmale/selektionsgruppe')
|
||||
->each(function (Crawler $node) use (&$groups, &$roles, &$hotelCode) {
|
||||
->each(function (Crawler $node) use (&$groups, &$roles) {
|
||||
$group = new CrmSelectionGroup();
|
||||
$group->id = (int) $node->attr('id');
|
||||
$group->label = $node->attr('bezeichnung');
|
||||
@@ -47,14 +47,14 @@ class CrmAttributesResponseParser
|
||||
$roles[] = 'ROLE_HOUSE_MANAGER';
|
||||
$hotelCodes[] = $matches[1];
|
||||
}
|
||||
if (static::BPN_CRM_ID_ADMIN === $attribute->id && true === $attribute->selected) {
|
||||
if (self::BPN_CRM_ID_ADMIN === $attribute->id && true === $attribute->selected) {
|
||||
$roles[] = 'ROLE_ADMIN';
|
||||
$roles[] = 'ROLE_HOUSE_MANAGER';
|
||||
}
|
||||
if (static::BPN_CRM_ID_MANAGER === $attribute->id && true === $attribute->selected) {
|
||||
if (self::BPN_CRM_ID_MANAGER === $attribute->id && true === $attribute->selected) {
|
||||
$roles[] = 'ROLE_MANAGER';
|
||||
}
|
||||
if (static::BPN_CRM_ID_TEAMER === $attribute->id && true === $attribute->selected) {
|
||||
if (self::BPN_CRM_ID_TEAMER === $attribute->id && true === $attribute->selected) {
|
||||
$roles[] = 'ROLE_TEAMER';
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class CrmAttributesResponseParser
|
||||
;
|
||||
|
||||
if (true === in_array('ROLE_ADMIN', $roles, true)) {
|
||||
$hotelCodes[] = static::BPN_DEFAULT_HOTEL_CODE;
|
||||
$hotelCodes[] = self::BPN_DEFAULT_HOTEL_CODE;
|
||||
}
|
||||
|
||||
$response = new CrmAttributes();
|
||||
|
||||
@@ -58,6 +58,7 @@ class DocumentsParser
|
||||
return base64_decode($pdfData);
|
||||
}
|
||||
|
||||
/** @return array{string, string} */
|
||||
private function getFileInfo(Crawler $node): array
|
||||
{
|
||||
$pdfData = $this->decode($node->filterXPath('.//pdf'));
|
||||
|
||||
@@ -37,7 +37,7 @@ class InsuranceParser extends AbstractParser
|
||||
|
||||
// Parse all individual insurances for reference lookup
|
||||
$insurance = $this->parseInsuranceNode($node, false);
|
||||
if (null !== $insurance && null !== $insurance->id) {
|
||||
if (null !== $insurance->id) {
|
||||
// Set complementary flag from XML attribute
|
||||
$insurance->complementary = $isComplementary;
|
||||
|
||||
@@ -53,7 +53,7 @@ class InsuranceParser extends AbstractParser
|
||||
$xmlContent->filterXPath('//versicherungspakete/versicherungspaket')
|
||||
->each(function (Crawler $node) use (&$insurances, $individualInsurances) {
|
||||
$insurance = $this->parseInsuranceNode($node, true, $individualInsurances);
|
||||
if (null !== $insurance && null !== $insurance->id) {
|
||||
if (null !== $insurance->id) {
|
||||
// Parse contained insurance IDs
|
||||
$insurance->containedInsuranceIds = $this->parseContainedInsuranceIds($node);
|
||||
|
||||
@@ -75,8 +75,8 @@ class InsuranceParser extends AbstractParser
|
||||
/**
|
||||
* Determines if a package contains any family insurances.
|
||||
*
|
||||
* @param Crawler $packageNode The package XML node
|
||||
* @param array<int, Insurance> $individualInsurances Parsed individual insurances for reference
|
||||
* @param Crawler $packageNode The package XML node
|
||||
* @param array<string, Insurance> $individualInsurances Parsed individual insurances for reference
|
||||
*
|
||||
* @return bool True if any contained insurance is a family insurance
|
||||
*/
|
||||
@@ -96,13 +96,13 @@ class InsuranceParser extends AbstractParser
|
||||
/**
|
||||
* Parses a single insurance or package node.
|
||||
*
|
||||
* @param Crawler $node The XML node to parse
|
||||
* @param bool $isPackage Whether this is a package node
|
||||
* @param array<int, Insurance> $individualInsurances Individual insurances for package family detection
|
||||
* @param Crawler $node The XML node to parse
|
||||
* @param bool $isPackage Whether this is a package node
|
||||
* @param array<string, Insurance> $individualInsurances Individual insurances for package family detection
|
||||
*
|
||||
* @return Insurance|null The parsed insurance object
|
||||
* @return Insurance The parsed insurance object
|
||||
*/
|
||||
private function parseInsuranceNode(Crawler $node, bool $isPackage, array $individualInsurances = []): ?Insurance
|
||||
private function parseInsuranceNode(Crawler $node, bool $isPackage, array $individualInsurances = []): Insurance
|
||||
{
|
||||
$insurance = new Insurance();
|
||||
$insurance->package = $isPackage;
|
||||
@@ -159,7 +159,7 @@ class InsuranceParser extends AbstractParser
|
||||
*
|
||||
* @param Crawler $xmlContent The XML content to scan
|
||||
*
|
||||
* @return array<int> Array of referenced insurance IDs
|
||||
* @return list<string> Array of referenced insurance IDs
|
||||
*/
|
||||
private function collectReferencedInsuranceIds(Crawler $xmlContent): array
|
||||
{
|
||||
@@ -180,7 +180,7 @@ class InsuranceParser extends AbstractParser
|
||||
*
|
||||
* @param Crawler $node The package XML node
|
||||
*
|
||||
* @return array<int> Array of contained insurance IDs (always int, as they reference individual insurances)
|
||||
* @return list<string> Array of contained insurance IDs
|
||||
*/
|
||||
private function parseContainedInsuranceIds(Crawler $node): array
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
class PickupsParser extends AbstractParser
|
||||
{
|
||||
/** @return array<int, Pickup> */
|
||||
public function parse(Crawler $result): array
|
||||
{
|
||||
$pickups = [];
|
||||
|
||||
@@ -7,6 +7,7 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
class RoomsParser extends AbstractParser
|
||||
{
|
||||
/** @return array<int, Room> */
|
||||
public function parse(Crawler $result): array
|
||||
{
|
||||
$rooms = [];
|
||||
|
||||
@@ -8,6 +8,7 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
class ServicesParser extends AbstractParser
|
||||
{
|
||||
/** @return array<int, Service> */
|
||||
public function parse(Crawler $result, string $category, string $source): array
|
||||
{
|
||||
$services = [];
|
||||
|
||||
@@ -7,6 +7,7 @@ use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
class SurchargesParser extends AbstractParser
|
||||
{
|
||||
/** @return list<Surcharge> */
|
||||
public function parse(Crawler $result): array
|
||||
{
|
||||
$surcharges = [];
|
||||
|
||||
Reference in new issue
Block a user