wip: update docs

This commit is contained in:
Björn Fromme
2026-03-16 11:59:10 +01:00
parent bd5c6359fe
commit 552dd029fa
6 changed files with 2161 additions and 0 deletions
+274
View File
@@ -0,0 +1,274 @@
# Pricing Display Implementation Plan
## Overview
Implement comprehensive pricing display functionality that shows costs both inline in form options and in a detailed sidebar summary with real-time updates via HTMX.
## Goals
1. **Inline pricing** in form options (rooms, services) so users see costs while selecting
2. **Sidebar pricing summary** with itemized breakdown and grand total
3. **Real-time updates** via existing HTMX integration
4. **Professional UX** with clear pricing integrated into the booking flow
## Implementation Strategy
### 1. Core Pricing Service (`src/Service/BookingPriceCalculatorService.php`)
**Purpose**: Central service for all pricing calculations
**Key Methods**:
- `calculateRoomPricing(BookingCreateDto $bookingDto): array`
- `calculateServicePricing(BookingCreateDto $bookingDto): array`
- `calculateGrandTotal(BookingCreateDto $bookingDto): float`
- `getPricingBreakdown(BookingCreateDto $bookingDto): array`
**Room Pricing Logic**:
```php
// For each selected room: quantity × room.price
foreach ($bookingDto->getSelectedRooms() as $roomSelection) {
$room = $bookingDto->travel->rooms[$roomSelection->roomId];
$totalPrice = $roomSelection->quantity * $room->price;
}
```
**Service Pricing Logic**:
```php
// For each participant's selected services
foreach ($bookingDto->getParticipants() as $participant) {
// Handle different service types (single vs multiple selection)
$serviceTotal += $participant->skiPass?->price ?? 0;
$serviceTotal += array_sum(array_map(fn($s) => $s->price, $participant->courses));
// etc.
}
```
### 2. Enhanced Form Field Options with Pricing ✅ COMPLETED
#### A. Room Selection Forms ✅ COMPLETED
**File**: `src/Form/RoomSelectType.php`
**Enhancement**: Choice labels include pricing information
```php
'choice_label' => function (Room $room) {
$priceText = $room->price ? sprintf(' (€%.2f pro Nacht)', $room->price) : '';
return $room->label . $priceText;
}
```
#### B. Service Selection Forms ✅ COMPLETED
**File**: `src/Form/Service/ParticipantFieldOptionsProvider.php`
**Enhancement**: Service labels include pricing via `formatServiceLabelWithPrice()` method
- Zero-priced services display without price suffix (e.g., "Vollpension" instead of "Vollpension (€0,00)")
- Priced services show with formatted price (e.g., "Halbpension (€45,00)")
- All services consistently show quantity prefix (e.g., "1x", "2x")
**Service Label Formatting Logic**:
```php
private function formatServiceLabelWithPrice(Service $service): string
{
$label = $service->label;
// Add price only if service has a cost
if ($service->price > 0) {
$label .= sprintf(' (€%.2f)', $service->price);
}
return $label;
}
```
**Affected Service Types**:
- Courses: `"Skikurs Anfänger (€25,00)"`
- Additional Services: `"Versicherung (€15,00)"`
- Ski Pass: `"5-Tage Skipass (€120,00)"`
- Rentals: `"Ski-Set (€30,00)"`
- Board: `"Halbpension (€45,00)"` or `"Vollpension"` (if €0,00)
### 3. Enhanced Unified Booking Summary ✅ COMPLETED
#### A. Unified Summary Component ✅ COMPLETED
**File**: `templates/booking/_summary.html.twig`
The pricing summary has been integrated into the main booking summary, creating a single cohesive sticky sidebar that displays:
**Travel Information Section**:
- Travel details (destination, dates, duration)
- Room selections with quantities
- Participant count summary
**Pricing Summary Section** (integrated):
- Room pricing breakdown with quantities (e.g., "2x Doppelzimmer")
- Service selections by participant with pricing
- Grand total calculation
**Key UX Improvements**:
- Single sticky summary box (eliminated separate pricing sidebar)
- Clean, unified layout with consistent typography
- Service labels show quantity and pricing appropriately
- Zero-priced services display without price suffix
- Real-time updates via HTMX for all pricing changes
#### B. Deprecated Separate Pricing Template ✅ COMPLETED
**File**: `templates/booking/_pricing_summary.html.twig` - REMOVED
The separate pricing summary template was removed in favor of the integrated approach within the main summary template for better UX.
### 4. Service Layer Integration ✅ COMPLETED
#### A. Enhanced BookingService ✅ COMPLETED
**File**: `src/Service/BookingService.php`
**Implemented Pricing Methods**:
```php
public function calculateServiceTotal(BookingCreateDto $bookingDto): float
{
// Groups services by type and calculates total pricing
$serviceGroups = $this->getServiceGroups($bookingDto);
return array_sum(array_column($serviceGroups, 'groupTotal'));
}
private function getServiceGroups(BookingCreateDto $bookingDto): array
{
// Groups selected services and calculates totals for pricing display
// Fixed bug: Uses 'groupTotal' instead of incorrect 'totalPrice' key
}
```
**Key Bug Fix**: The `calculateServiceTotal()` method was corrected to use `groupTotal` instead of `totalPrice` from the grouped array structure, ensuring selected services are properly included in the grand total calculation.
### 5. Controller Integration ✅ COMPLETED
#### A. Step 1 Controller Updates ✅ COMPLETED
**File**: `src/Controller/Booking/CreateStep1Controller.php`
**Enhancement**: Integrated pricing calculations into existing summary methods
```php
// In index() method - pricing data included in summary
$summary = $this->bookingService->getRoomSummaryAndParticipantCount($bookingCreateDto);
// Pricing calculated and passed to template
// In roomSummary() method - HTMX endpoint includes pricing updates
$summary = $this->bookingService->getRoomSummaryAndParticipantCount($bookingCreateDto);
return $this->render('booking/_summary.html.twig', [
// existing data with integrated pricing
]);
```
#### B. Step 2 Controller Updates ✅ COMPLETED
**File**: `src/Controller/Booking/CreateStep2Controller.php`
**Enhancement**: Service pricing calculations integrated into form refresh
```php
// In refresh() method - service selections update pricing in real-time
$summary = $this->bookingService->getRoomSummaryAndParticipantCount($bookingCreateDto);
// Service total calculation includes selected service pricing
```
#### C. HTMX Service Field Integration ✅ COMPLETED
**Critical Fix**: Service field HTMX triggers were moved from container elements to individual form inputs (checkboxes/radios) to ensure real-time updates work properly for expanded choice fields.
### 6. Error Handling & Edge Cases ✅ COMPLETED
**Price Data Handling** ✅ IMPLEMENTED:
- Zero prices handled gracefully (services show without price suffix)
- All prices rounded to 2 decimal places
- German number formatting implemented (comma as decimal separator)
- Null price handling via conditional display logic
**Service Quantity Logic** ✅ IMPLEMENTED:
- Single services (skiPass): price × 1 per participant
- Multiple services (courses, rentals): sum of all selected service prices per participant
- Service quantity consistently displayed (1x, 2x) in labels
- Field handlers store complete Service objects (not just IDs) for pricing access
**Field Handler Data Fix** ✅ COMPLETED:
- All service field handlers updated to store Service objects instead of service IDs
- Enables pricing calculator to access service price data
- Resolves issue where selected services were ignored in total calculations
## Implementation Progress
### ✅ Completed
- [x] Created implementation plan documentation
- [x] Enhanced BookingService with pricing calculation methods (`calculateServiceTotal`, `getServiceGroups`)
- [x] Updated ParticipantFieldOptionsProvider to add prices to service labels with smart formatting
- [x] Updated RoomSelectType to add prices to room labels
- [x] Integrated pricing into main summary template (unified approach)
- [x] Updated controllers to include pricing data in summary calculations
- [x] Fixed HTMX integration for service field real-time updates
- [x] Fixed field handler data storage (Service objects vs IDs)
- [x] Fixed pricing calculation bug (groupTotal vs totalPrice key)
- [x] Implemented smart service label formatting (zero-price handling)
- [x] Added consistent quantity display for all services
- [x] Completed comprehensive testing of pricing display and HTMX integration
### ✅ Additional Improvements Completed
- [x] Unified booking summary layout (eliminated separate pricing sidebar)
- [x] Enhanced UX with sticky summary positioning
- [x] Fixed service field HTMX triggers for expanded choice types
- [x] Resolved linter warnings with proper type annotations
- [x] Streamlined service label formatting logic
## Technical Considerations
### Performance
- All pricing calculations done in-memory (no database queries)
- Calculations triggered only on form changes via HTMX
- Efficient array operations for service aggregation
### HTMX Integration ✅ COMPLETED
- Uses existing `#booking-summary` target for seamless updates
- **Fixed service field triggers**: HTMX attributes moved to individual form inputs for expanded choice fields
- Real-time pricing updates work reliably for all service selections
- Maintains current real-time update behavior with improved reliability
### Styling
- CSS classes for pricing components:
- `.pricing-summary` - Overall container
- `.pricing-section` - Room/service sections
- `.pricing-item` - Individual line items
- `.pricing-total` - Grand total display
### Accessibility
- Proper semantic HTML structure
- ARIA labels for pricing information
- Screen reader friendly number formatting
## Testing Strategy
### Unit Tests
- Test pricing calculations with various room/service combinations
- Test edge cases (null prices, zero quantities)
- Test German number formatting
### Integration Tests
- Test HTMX updates with pricing changes
- Test form submission with pricing data
- Test step navigation with pricing persistence
### Manual Testing Scenarios
1. Select rooms and verify inline pricing appears
2. Change room quantities and verify total updates
3. Add/remove services and verify pricing updates
4. Navigate between steps and verify pricing persistence
5. Test with services that have null/zero prices
## Future Enhancements
### Potential Additions
- **Discounts/Promotions**: Add discount calculation logic
- **Currency Selection**: Support multiple currencies
- **Price History**: Track pricing changes during booking session
- **Export Pricing**: Add pricing breakdown to booking confirmations
- **Tax Calculations**: Add VAT/tax breakdown if needed
### Performance Optimizations
- Cache frequently calculated pricing data
- Optimize service aggregation algorithms
- Consider lazy loading for complex pricing scenarios
---
**Last Updated**: 2025-09-02
**Status**: ✅ Implementation completed successfully
**Completed Features**: Inline pricing, unified summary, HTMX integration, service field fixes, and comprehensive UX improvements