wip: continue implementation

This commit is contained in:
Björn Fromme
2024-12-02 17:38:56 +01:00
parent 84ab6446ea
commit 6f989d4c7a
24 changed files with 444 additions and 237 deletions
@@ -2,6 +2,7 @@
namespace App\BusProNet\ApiResponseParser;
use App\BusProNet\Model\CrmAction;
use App\BusProNet\Model\CrmAttributes;
use App\BusProNet\Model\CrmSelection;
use App\BusProNet\Model\CrmSelectionGroup;
@@ -18,11 +19,13 @@ class CrmAttributesResponseParser
public function parse(\SimpleXMLElement $xml): CrmAttributes
{
$groups = [];
$actions = [];
$isAdmin = $isManager = $isHouseManager = $isTeamer = false;
$hotelCode = null;
foreach ($xml->selektionsmerkmale->selektionsgruppe as $item) {
$group = new CrmSelectionGroup();
$group->id = (int) $item->attributes()['id'];
$group->label = (string) $item->attributes()['bezeichnung'];
$attributes = [];
@@ -32,6 +35,7 @@ class CrmAttributesResponseParser
$attribute = new CrmSelection();
$attribute->id = (int) $subItemAttributes['id'];
$attribute->label = $attributeLabel;
$attribute->mutable = $this->stringToBool((string) $subItemAttributes['aenderbar']);
$attribute->selected = $this->stringToBool((string) $subItemAttributes['auswahl']);
if (1 === preg_match('/^Hausleitung ([A-Z0-9]+)$/', $attributeLabel, $matches) && true === $attribute->selected) {
@@ -54,8 +58,21 @@ class CrmAttributesResponseParser
$groups[] = $group;
}
foreach ($xml->crmaktionen->crmaktion as $item) {
$attributes = $item->attributes();
$crmAction = new CrmAction();
$crmAction->id = (int) $attributes['id'];
$crmAction->code = (string) $attributes['code'];
$crmAction->label = (string) $attributes['bezeichnung'];
$crmAction->mutable = $this->stringToBool((string) $attributes['aenderbar']);
$crmAction->selected = $this->stringToBool((string) $attributes['auswahl']);
$actions[] = $crmAction;
}
$response = new CrmAttributes();
$response->selectionGroups = $groups;
$response->crmActions = $actions;
$response->admin = $isAdmin;
$response->manager = $isManager;
$response->houseManager = $isHouseManager;
@@ -64,4 +81,4 @@ class CrmAttributesResponseParser
return $response;
}
}
}
+9 -1
View File
@@ -2,10 +2,18 @@
namespace App\BusProNet\Model;
class Availability
class Availability implements \JsonSerializable
{
public ?int $serviceId = null;
public ?string $status = null;
public ?int $available = null;
public ?float $price = null;
public function jsonSerialize(): array
{
return [
'id' => $this->serviceId,
'available' => $this->available,
];
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace App\BusProNet\Model;
class CrmAction
{
public ?int $id = null;
public ?string $code = null;
public ?string $label = null;
public bool $mutable = false;
public bool $selected = false;
}
+1 -21
View File
@@ -5,30 +5,10 @@ namespace App\BusProNet\Model;
class CrmAttributes
{
public ?array $selectionGroups = null;
public ?array $crmActions = null;
public bool $admin = false;
public bool $manager = false;
public bool $houseManager = false;
public bool $teamer = false;
public ?string $hotelCode = null;
public function toArray(): array
{
$crmSelections = [];
foreach ($this->selectionGroups as $group) {
/** @var CrmSelectionGroup $group */
if (false === isset($crmSelections[$group->label])) {
$crmSelections[$group->label] = [];
}
foreach ($group->selections as $attribute) {
/** @var CrmSelection $attribute */
if (false === $attribute->selected) {
continue;
}
$crmSelections[$group->label][] = $attribute->label;
}
}
return $crmSelections;
}
}
+1
View File
@@ -6,5 +6,6 @@ class CrmSelection
{
public ?int $id = null;
public ?string $label = null;
public bool $mutable = false;
public bool $selected = false;
}
+12
View File
@@ -19,4 +19,16 @@ class CrmSelectionGroup
public ?int $id = null;
public ?string $label = null;
public ?array $selections = null;
public function getMutableSelections(): array
{
return array_filter($this->selections, function (CrmSelection $selection) {
return $selection->mutable;
});
}
public function isVisible(): bool
{
return 0 < count($this->getMutableSelections());
}
}
+4 -4
View File
@@ -32,14 +32,14 @@ class PersonalDataController extends AbstractController
->getPersonalData($bpnUser->getEmail(), $bpnUser->getPassword())
;
$form = $this->createForm(PersonalDataType::class, $personalData, [
$personalDataForm = $this->createForm(PersonalDataType::class, $personalData, [
'attr' => ['novalidate' => 'novalidate'],
'hx_post' => $this->generateUrl('app_personal_data'),
'hx_target' => '#app',
]);
$form->handleRequest($request);
$personalDataForm->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($personalDataForm->isSubmitted() && $personalDataForm->isValid()) {
try {
$this->apiClient->updatePersonalData($bpnUser->getEmail(), $bpnUser->getPassword(), $personalData);
$this->addFlash('success', 'Deine persönlichen Daten wurden aktualisiert');
@@ -52,7 +52,7 @@ class PersonalDataController extends AbstractController
return $this->render('personal_data/index.html.twig', [
'personalData' => $personalData,
'form' => $form->createView(),
'personalDataForm' => $personalDataForm->createView(),
]);
}
+2 -2
View File
@@ -24,10 +24,10 @@ class ParticipantData
public ?string $gender = null;
public ?string $nationality = null;
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }}cm angeben', min: 140, max: 210)]
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }}cm angeben', min: 150, max: 210)]
public ?string $height = null;
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }} angeben', min: 35, max: 49)]
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }} angeben', min: 37, max: 49)]
public ?string $shoeSize = null;
#[Assert\Range(notInRangeMessage: 'Bitte einen Wert im Bereich {{ min }}-{{ max }}kg angeben', min: 40, max: 130)]
+128 -133
View File
@@ -21,55 +21,53 @@ class ParticipantType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
if (true === $options['personal_data_mutable']) {
$builder
->add('firstName', TextType::class, [
'label' => 'Vorname',
])
->add('lastName', TextType::class, [
'label' => 'Nachname',
])
->add('dateOfBirth', BirthdayType::class, [
'label' => 'Geburtsdatum',
'html5' => true,
'widget' => 'single_text',
'input' => 'datetime_immutable',
])
->add('gender', ChoiceType::class, [
'label' => 'Geschlecht',
'required' => false,
'placeholder' => 'keine Angabe',
'choices' => [
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('nationality', CountryType::class, [
'label' => 'Nationalität',
'property' => 'nationality',
'preferred_choices' => ['D', 'A', 'CH'],
])
->add('email', EmailType::class, [
'label' => 'E-Mail',
])
->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)',
])
->add('height', IntegerType::class, [
'label' => 'Körpergröße [cm]',
'required' => false,
])
->add('shoeSize', IntegerType::class, [
'label' => 'Schuhgröße',
'required' => false,
])
->add('weight', IntegerType::class, [
'label' => 'Gewicht [kg]',
'required' => false,
])
;
}
$builder
->add('firstName', TextType::class, [
'label' => 'Vorname',
])
->add('lastName', TextType::class, [
'label' => 'Nachname',
])
->add('dateOfBirth', BirthdayType::class, [
'label' => 'Geburtsdatum',
'html5' => true,
'widget' => 'single_text',
'input' => 'datetime_immutable',
])
->add('gender', ChoiceType::class, [
'label' => 'Geschlecht',
'required' => false,
'placeholder' => 'keine Angabe',
'choices' => [
'männlich' => 'M',
'weiblich' => 'W',
'divers' => 'D',
],
])
->add('nationality', CountryType::class, [
'label' => 'Nationalität',
'property' => 'nationality',
'preferred_choices' => ['D', 'A', 'CH'],
])
->add('email', EmailType::class, [
'label' => 'E-Mail',
])
->add('mobile', TextType::class, [
'label' => 'Telefon (mobil)',
])
->add('height', IntegerType::class, [
'label' => 'Körpergröße [cm]',
'required' => false,
])
->add('shoeSize', IntegerType::class, [
'label' => 'Schuhgröße',
'required' => false,
])
->add('weight', IntegerType::class, [
'label' => 'Gewicht [kg]',
'required' => false,
])
;
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
/** @var ParticipantData $participantData */
@@ -99,8 +97,8 @@ class ParticipantType extends AbstractType
},
'choice_attr' => function (?Service $service) {
$attributes = [
'data-available' => $service->available,
'data-availabilities-target' => 'field',
'data-booking-target' => 'field',
'data-action' => 'booking#toggle',
];
// forcibly select mandatory services
@@ -131,96 +129,93 @@ class ParticipantType extends AbstractType
];
// Additional services
if (true === $options['additional_services_mutable']) {
if (0 < count($options['selectable_courses'])) {
$form->add('courses', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Kurse',
'choices' => $options['selectable_courses'],
]);
}
if (0 < count($options['selectable_services'])) {
$form->add('additionalServices', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Zusatzleistungen',
'choices' => $options['selectable_services'],
]);
}
if (0 < count($options['selectable_ski_passes'])) {
$form->add('skiPass', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Skipass',
'choices' => $options['selectable_ski_passes'],
]);
}
if (0 < count($options['selectable_board'])) {
$form->add('board', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verpflegung',
'choices' => $options['selectable_board'],
]);
}
if (0 < count($options['selectable_rentals'])) {
$form->add('rentals', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verleih',
'choices' => $options['selectable_rentals'],
]);
}
if (0 < count($options['selectable_courses'])) {
$form->add('courses', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Kurse',
'choices' => $options['selectable_courses'],
]);
}
if (0 < count($options['selectable_services'])) {
$form->add('additionalServices', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Zusatzleistungen',
'choices' => $options['selectable_services'],
]);
}
if (0 < count($options['selectable_ski_passes'])) {
$form->add('skiPass', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Skipass',
'choices' => $options['selectable_ski_passes'],
]);
}
if (0 < count($options['selectable_board'])) {
$form->add('board', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verpflegung',
'choices' => $options['selectable_board'],
]);
}
if (0 < count($options['selectable_rentals'])) {
$form->add('rentals', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Verleih',
'choices' => $options['selectable_rentals'],
]);
}
// Transportation
if (true === $options['transportation_services_mutable']) {
$form
->add('transportationServiceTo', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Anreise',
'multiple' => false,
'choices' => $options['selectable_transportation_services_to'],
'choice_attr' => function (?Service $service) {
return [
'data-available' => $service->available,
'data-availabilities-target' => 'field',
'data-action' => 'select-toggle#toggle',
'data-select-toggle-value' => $service->subType,
];
},
])
->add('transportationServiceFro', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Rückreise',
'multiple' => false,
'choices' => $options['selectable_transportation_services_fro'],
]);
}
$form
->add('transportationServiceTo', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Anreise',
'required' => true,
'multiple' => false,
'choices' => $options['selectable_transportation_services_to'],
'choice_attr' => function (?Service $service) {
return [
'data-booking-target' => 'field',
'data-action' => 'select-toggle#toggle booking#toggle',
'data-select-toggle-value' => $service->subType,
];
},
])
->add('transportationServiceFro', ChoiceType::class, [
...$commonChoiceFieldOptions,
'label' => 'Rückreise',
'required' => true,
'multiple' => false,
'choices' => $options['selectable_transportation_services_fro'],
])
;
// Pickup
if (true === $options['pickups_mutable']) {
$form
->add('pickup', ChoiceType::class, [
'label' => 'Zustieg',
'multiple' => false,
'expanded' => false,
'choices' => $options['selectable_pickups'],
'choice_value' => 'id',
'choice_label' => function (?Pickup $pickup) {
if (null === $pickup) {
return null;
}
$form
->add('pickup', ChoiceType::class, [
'label' => 'Zustieg',
'multiple' => false,
'expanded' => false,
'choices' => $options['selectable_pickups'],
'choice_value' => 'id',
'choice_label' => function (?Pickup $pickup) {
if (null === $pickup) {
return null;
}
$price = $pickup->price;
$price = $pickup->price;
if (null === $price || 0.0 === $price) {
return $pickup->city;
}
if (null === $price || 0.0 === $price) {
return $pickup->city;
}
return sprintf('%s (%s €)',
$pickup->city,
number_format($price, 2, ',', '.')
);
},
]);
}
return sprintf('%s (%s €)',
$pickup->city,
number_format($price, 2, ',', '.')
);
},
])
;
})
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
$data = $event->getData();