107 lines
4.0 KiB
PHP
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],
|
|
);
|
|
}
|
|
}
|