wip: booking process
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use App\Form\Model\ParticipantDto;
|
||||
|
||||
class BookingCreateParticipantType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => ParticipantDto::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
use App\Form\RoomSelectType;
|
||||
|
||||
class BookingCreateStep1Type extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('roomSelections', CollectionType::class, [
|
||||
'entry_type' => RoomSelectType::class,
|
||||
'label' => false,
|
||||
'entry_options' => [
|
||||
'label' => false,
|
||||
],
|
||||
'allow_add' => false,
|
||||
'allow_delete' => false,
|
||||
'by_reference' => false,
|
||||
'error_bubbling' => false,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => BookingCreateDto::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
use App\Form\Model\BookingCreateDto;
|
||||
|
||||
class BookingCreateStep2Type extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('participants', CollectionType::class, [
|
||||
'entry_type' => BookingCreateParticipantType::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => BookingCreateDto::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
final class BookingType extends AbstractType
|
||||
final class BookingEditType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
@@ -23,7 +23,7 @@ final class BookingType extends AbstractType
|
||||
|
||||
$travelData = $data->travel;
|
||||
$form->add('participants', CollectionType::class, [
|
||||
'entry_type' => ParticipantType::class,
|
||||
'entry_type' => BoolingEditParticipantType::class,
|
||||
'entry_options' => [
|
||||
'selectable_courses' => $this->mergeSelectableServices($data, Constants::TOKEN_COURSES),
|
||||
'selectable_ski_passes' => $this->mergeSelectableServices($data, Constants::TOKEN_SKI_PASS),
|
||||
@@ -17,7 +17,7 @@ use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class ParticipantType extends AbstractType
|
||||
class BoolingEditParticipantType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form\Model;
|
||||
|
||||
use App\BusProNet\Model\Travel;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
|
||||
class BookingCreateDto
|
||||
{
|
||||
public int $currentStep = 1;
|
||||
|
||||
#[Assert\Valid]
|
||||
/**
|
||||
* @var array<int, RoomSelectionDto>
|
||||
*/
|
||||
public array $roomSelections = [];
|
||||
|
||||
/**
|
||||
* @var array<int, ParticipantDto>
|
||||
*/
|
||||
#[Assert\Valid]
|
||||
public array $participants = [];
|
||||
|
||||
public function __construct(public Travel $travelData, public int $hotelId)
|
||||
{
|
||||
}
|
||||
|
||||
#[Assert\Callback]
|
||||
public function assertValidRoomSelections(ExecutionContextInterface $context): void
|
||||
{
|
||||
$participantsCount = $this->getParticipantsCount();
|
||||
$selectedContingent = 0;
|
||||
|
||||
foreach ($this->roomSelections as $roomSelection) {
|
||||
$selectedContingent += $roomSelection->quantity * $roomSelection->minPax;
|
||||
}
|
||||
|
||||
if (0 === $selectedContingent) {
|
||||
$context->buildViolation('Bitte mindestens ein Zimmer auswählen.')
|
||||
->atPath('roomSelections')
|
||||
->addViolation();
|
||||
}
|
||||
|
||||
if ($selectedContingent !== $participantsCount) {
|
||||
$context->buildViolation('Die ausgewählten Zimmer passen nicht zur Teilnehmerzahl.')
|
||||
->atPath('roomSelections')
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
|
||||
public function getParticipantsCount(): int
|
||||
{
|
||||
$participantsCount = 0;
|
||||
$rooms = $this->travelData->getAvailableRooms();
|
||||
|
||||
foreach ($this->roomSelections as $roomSelection) {
|
||||
$room = $rooms[$roomSelection->roomId];
|
||||
$participantsCount += $room->minPax * $roomSelection->quantity;
|
||||
}
|
||||
|
||||
return $participantsCount;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ class BookingEditDto
|
||||
public ?Booking $booking = null;
|
||||
public ?Travel $travel = null;
|
||||
|
||||
/**
|
||||
* @var array<int, ParticipantDto>
|
||||
*/
|
||||
#[Assert\Valid]
|
||||
public array $participants = [];
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form\Model;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
class RoomSelectionDto
|
||||
{
|
||||
#[Assert\NotNull(message: 'Bitte eine Zimmerkategorie auswählen')]
|
||||
public ?int $roomId = null;
|
||||
|
||||
public ?string $roomLabel = null;
|
||||
|
||||
public ?int $quantity = null;
|
||||
|
||||
public int $maxQuantity = 100;
|
||||
|
||||
public int $minPax = 0;
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
if (1 === preg_match('/bett/i', $this->roomLabel)) {
|
||||
return 'by_pax';
|
||||
}
|
||||
|
||||
return 'by_room';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use App\Form\Model\RoomSelectionDto;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
|
||||
class RoomSelectType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('roomId', HiddenType::class)
|
||||
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
|
||||
$data = $event->getData();
|
||||
$form = $event->getForm();
|
||||
|
||||
$form->add('quantity', ChoiceType::class, [
|
||||
'label' => 'Anzahl '.$data->roomLabel,
|
||||
'required' => false,
|
||||
'placeholder' => '-',
|
||||
'choices' => array_combine(range(1, $data->maxQuantity), range(1, $data->maxQuantity)),
|
||||
]);
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => RoomSelectionDto::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user