Files
myep/src/Service/BookingCreateContextFactory.php
T

107 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service;
use App\BusProNet\Model\Room;
use App\Form\Model\BookingCreateContext;
use App\Form\Model\BookingDto;
use App\Form\Model\BookingSummaryDto;
use App\Form\Model\RoomGroupsDto;
/**
* Prepares the shared view model for booking create.
*/
class BookingCreateContextFactory
{
public function __construct(
private readonly ParticipantCardAssembler $participantCardDataService,
private readonly BookingSummaryAssembler $summaryDataService,
private readonly BookingPriceCalculator $priceCalculator,
private readonly FamilyInsuranceAvailabilityChecker $familyInsuranceService,
) {
}
public function create(
BookingDto $bookingDto,
string $pricingMode = RoomPricingCalculator::PRICING_MODE_ASSIGNMENT,
): BookingCreateContext {
$baseContext = $this->buildBaseContext($bookingDto, $pricingMode);
return new BookingCreateContext(
bookingDto: $bookingDto,
summaryData: $baseContext['summaryData'],
groupedRooms: $baseContext['groupedRooms'],
familyInsuranceUpgradeAvailable: $baseContext['familyInsuranceUpgradeAvailable'],
);
}
public function createWithParticipantCards(BookingDto $bookingDto, bool $isSubmitted): BookingCreateContext
{
$baseContext = $this->buildBaseContext($bookingDto, RoomPricingCalculator::PRICING_MODE_SELECTION);
return new BookingCreateContext(
bookingDto: $bookingDto,
summaryData: $baseContext['summaryData'],
groupedRooms: $baseContext['groupedRooms'],
cardsData: $this->participantCardDataService->getAllCardsDataWithValidation($bookingDto),
isSubmitted: $isSubmitted,
familyInsuranceUpgradeAvailable: $baseContext['familyInsuranceUpgradeAvailable'],
);
}
public function createWithParticipantPrices(BookingDto $bookingDto): BookingCreateContext
{
$baseContext = $this->buildBaseContext($bookingDto, RoomPricingCalculator::PRICING_MODE_ASSIGNMENT);
return new BookingCreateContext(
bookingDto: $bookingDto,
summaryData: $baseContext['summaryData'],
groupedRooms: $baseContext['groupedRooms'],
participantPrices: $this->priceCalculator->calculateAllParticipantIndividualPrices($bookingDto),
familyInsuranceUpgradeAvailable: $baseContext['familyInsuranceUpgradeAvailable'],
);
}
/**
* @return array{summaryData: BookingSummaryDto, groupedRooms: RoomGroupsDto, familyInsuranceUpgradeAvailable: bool}
*/
private function buildBaseContext(BookingDto $bookingDto, string $pricingMode): array
{
return [
'summaryData' => $this->summaryDataService->getSummaryData($bookingDto, $pricingMode),
'groupedRooms' => $this->groupRoomsBySelectionType($bookingDto->travel->getAvailableRooms()),
'familyInsuranceUpgradeAvailable' => $this->familyInsuranceService->isFamilyInsuranceUpgradeAvailable($bookingDto),
];
}
/**
* @param array<int, Room> $rooms
*/
private function groupRoomsBySelectionType(array $rooms): RoomGroupsDto
{
$groups = [
Room::SELECTION_TYPE_BY_PAX => [],
Room::SELECTION_TYPE_BY_ROOM => [],
];
foreach ($rooms as $room) {
if (false !== stripos($room->label, 'bett')) {
$groups[Room::SELECTION_TYPE_BY_PAX][$room->id] = $room;
continue;
}
$groups[Room::SELECTION_TYPE_BY_ROOM][$room->id] = $room;
}
uasort($groups[Room::SELECTION_TYPE_BY_PAX], static fn (Room $a, Room $b): int => $a->maxPax <=> $b->maxPax);
uasort($groups[Room::SELECTION_TYPE_BY_ROOM], static fn (Room $a, Room $b): int => $a->maxPax <=> $b->maxPax);
return new RoomGroupsDto(
byPax: $groups[Room::SELECTION_TYPE_BY_PAX],
byRoom: $groups[Room::SELECTION_TYPE_BY_ROOM],
);
}
}