feat: finalize voucher handling and discount display in summary and overview

This commit is contained in:
Björn Fromme
2026-03-16 11:59:12 +01:00
parent 2e40cbc7c7
commit 230c53875f
15 changed files with 762 additions and 46 deletions
@@ -6,6 +6,7 @@ namespace App\Controller\Booking\Create;
use App\BusProNet\ApiClient;
use App\BusProNet\Exception\TimeoutException;
use App\BusProNet\Model\BookingResponse;
use App\BusProNet\Model\Notification;
use App\Controller\Booking\Traits\BookingCreateTrait;
use App\Controller\Booking\Traits\BookingExceptionHandlerTrait;
@@ -121,16 +122,22 @@ class Step3Controller extends AbstractController
}
// Validate price match (rounded to cent precision to avoid floating-point errors)
// API gesamtpreis includes promotional/goodwill voucher discounts (negative price items),
// but NOT purchase vouchers (those reduce restzahlung, not gesamtpreis)
$apiTotal = round($inquiryResponse->totalPrice ?? 0.0, 2);
$calculatedTotal = round($this->priceCalculator->calculateGrandTotal($bookingCreateDto), 2);
$calculatedSubtotal = round($this->priceCalculator->calculateGrandTotal($bookingCreateDto), 2);
$promoGoodwillDiscount = round($inquiryResponse->getVoucherDiscountFromPrices(), 2);
$expectedTotal = round($calculatedSubtotal - $promoGoodwillDiscount, 2);
if ($apiTotal !== $calculatedTotal) {
if ($apiTotal !== $expectedTotal) {
return $this->handleApiError(
'Price mismatch detected - payload incomplete',
[
'apiTotal' => $apiTotal,
'calculatedTotal' => $calculatedTotal,
'difference' => abs($apiTotal - $calculatedTotal),
'calculatedSubtotal' => $calculatedSubtotal,
'promoGoodwillDiscount' => $promoGoodwillDiscount,
'expectedTotal' => $expectedTotal,
'difference' => abs($apiTotal - $expectedTotal),
],
'Ein technischer Fehler ist aufgetreten.',
$bookingCreateDto,
@@ -225,11 +232,11 @@ class Step3Controller extends AbstractController
* an inquiry rather than showing an error. This handles scenarios where
* availability changes between booking initialization and validation.
*
* @param \App\BusProNet\Model\BookingResponse $response The API response
* @param BookingResponse $response The API response
*
* @return bool True if should fallback to inquiry mode, false if should show error
*/
private function shouldFallbackToInquiryMode(\App\BusProNet\Model\BookingResponse $response): bool
private function shouldFallbackToInquiryMode(BookingResponse $response): bool
{
// Check for "nicht möglich" status + inquiry suggestion in message
if ('nicht möglich' !== $response->status) {