wip: submit booking to api

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent ee264e88d4
commit 7ea52670b9
34 changed files with 3316 additions and 31 deletions
+190
View File
@@ -0,0 +1,190 @@
# Address Fields Implementation
**Date:** 2025-10-06
**Status:** ✅ TESTED SUCCESSFULLY (2025-10-06)
## Overview
Added participant address collection to the booking create flow. Address is mandatory for the applicant (first participant) and optional for others.
## Implementation
### 1. Models
**ParticipantDto** (`src/Form/Model/ParticipantDto.php`):
- Added `Address $address` property
- Made email field required (`@Assert\NotBlank`)
- Added constructor to initialize `Address` object
- Removed `@Assert\NotNull` constraint (validation handled by ParticipantValidator)
**Address** (`src/BusProNet/Model/Address.php`):
- Already had `toPayload()` method for XML generation
- Properties: street, postCode, city, district, country
- No changes needed (existing model worked perfectly)
### 2. Forms
**AddressType** (`src/Form/AddressType.php`) - NEW:
```php
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('street', TextType::class, [...])
->add('postCode', TextType::class, [...])
->add('city', TextType::class, [...])
->add('country', CountryType::class, [
'property' => 'country',
'preferred_choices' => ['DE', 'AT', 'CH'],
]);
}
}
```
**BookingParticipantType** (`src/Form/BookingParticipantType.php`):
- Added address field after mobile field
- `required => 0 === $participantIndex` (mandatory for applicant)
- Added 'address' to `$baseFields` array for rebuild handling
### 3. Validation
**ParticipantValidator** (`src/Validator/Constraints/ParticipantValidator.php`):
- Added `assertApplicantAddressValid()` method
- Validates street, postCode, city, country for applicant only
- Uses `$participant->isApplicant()` to check if validation should run
- Error messages: "Bitte angeben" for each missing field
### 4. Payload Generation
**BookingDataProcessor** (`src/BusProNet/DataProcessor/BookingDataProcessor.php`):
**Applicant section** (lines 451-454):
```php
// Add address for applicant
if (null !== $firstParticipant->address) {
$payload['anmelder']['anschrift'] = $firstParticipant->address->toPayload();
}
```
**Participant list** (lines 481-488):
```php
// Add address (always include structure, even if empty)
$participantData['anschrift'] = $participant->address?->toPayload() ?? [
'strasse' => null,
'plz' => null,
'ort' => null,
'ortsteil' => null,
'land' => null,
];
```
**XML Output:**
```xml
<anmelder>
<anschrift>
<strasse>Gablonzer Straße 32</strasse>
<plz>53359</plz>
<ort>Rheinbach</ort>
<ortsteil />
<land>D</land>
</anschrift>
</anmelder>
<teilnehmerliste>
<teilnehmer id="1">
<anschrift>
<strasse>Gablonzer Straße 32</strasse>
<plz>53359</plz>
<ort>Rheinbach</ort>
<ortsteil />
<land>D</land>
</anschrift>
</teilnehmer>
</teilnehmerliste>
```
## Bug Fixes (Same Session)
### 1. Room Quantity Fix
**Issue:** Room `@anzahl` was set to participant count instead of room quantity
**Fix:** Use `roomSelections[].quantity` from step 1 (lines 576-603)
```php
$roomQuantities = [];
foreach ($bookingDto->roomSelections as $selection) {
if ($selection->quantity > 0) {
$roomQuantities[$selection->roomId] = $selection->quantity;
}
}
$quantity = $roomQuantities[$roomId] ?? 1;
```
### 2. Insurance Selection for Dependent Participants
**Issue:** `ParticipantBulkInsuranceFieldHandler` cleared independent selections on every form submit
**Fix:** Added `wasBulkInsurancePreviouslyEnabled()` check (lines 90, 144-176)
```php
if (false === $isBulkEnabled && $this->wasBulkInsurancePreviouslyEnabled($bookingDto)) {
$this->clearDependentParticipantsInsurance($bookingDto);
}
```
## Files Modified
1. `src/Form/Model/ParticipantDto.php` - Added address property, constructor, required email
2. `src/Form/AddressType.php` - NEW form type
3. `src/Form/BookingParticipantType.php` - Added address field
4. `src/Validator/Constraints/ParticipantValidator.php` - Added address validation
5. `src/BusProNet/DataProcessor/BookingDataProcessor.php` - Address in payload, room quantity fix, `isApplicant()` usage
6. `src/Form/Service/ParticipantBulkInsuranceFieldHandler.php` - Insurance clearing fix
## Testing
### Manual Testing Checklist:
- [x] Applicant address required (all fields) - ✅ PASSED
- [x] Dependent participant address optional - ✅ PASSED
- [x] Country dropdown shows DE, AT, CH first - ✅ PASSED
- [x] Address appears in XML for applicant - ✅ PASSED
- [x] Address appears in XML for all participants (empty if not provided) - ✅ PASSED
- [x] Email is mandatory for all participants - ✅ PASSED
- [x] Insurance selection works for dependent participants - ✅ PASSED
- [x] Room quantity matches selection from step 1 - ✅ PASSED
### Expected XML:
- Applicant: Full address in `<anmelder><anschrift>`
- All participants: Address structure in `<teilnehmer><anschrift>` (may be empty)
- Room quantity: Matches quantity selected in step 1, not participant count
## Notes
- Address object initialized in ParticipantDto constructor
- Uses existing `Address::toPayload()` method for XML generation
- CountryType provides nationality dropdown with German country codes
- Validation runs via existing ParticipantValidator constraint
- Template integration happens automatically via Symfony form system
---
**Implementation Status:** ✅ TESTED SUCCESSFULLY
**Code Quality:** ✅ PHP-CS-Fixer validated
**Test Date:** 2025-10-06
## Test Results
**Test Date:** 2025-10-06
**Environment:** DDEV sandbox with BusProNet API
**Validated Features:**
- ✅ Applicant address validation (all fields mandatory)
- ✅ Dependent participant address optional
- ✅ Country dropdown with preferred choices (DE, AT, CH)
- ✅ Address correctly included in XML payload for applicant
- ✅ Address structure included for all participants (empty nodes for optional)
- ✅ Email mandatory validation working for all participants
- ✅ Mobile mandatory validation working for applicant only
**Validated Bug Fixes:**
- ✅ Room quantity using correct value from step 1 selections
- ✅ Insurance selection working correctly for dependent participants
- ✅ Pickup locations included with correct quantities
**Result:** All address field requirements working correctly in production-like environment.