diff --git a/src/BusProNet/Model/BookingResponse.php b/src/BusProNet/Model/BookingResponse.php
index 70afd5f..b1f0da2 100644
--- a/src/BusProNet/Model/BookingResponse.php
+++ b/src/BusProNet/Model/BookingResponse.php
@@ -111,8 +111,12 @@ class BookingResponse
* - ERM/GRU: Gruppenrabatt (group discount for large bookings)
* - Other ERM subtypes: Various automatic discounts
*
- * These discounts appear as negative price items and must be accounted for when
- * comparing the API total price against the locally calculated price.
+ * These discounts appear as negative price items with type "ERM" and must be
+ * accounted for when comparing the API total price against the locally calculated price.
+ *
+ * Important: Only ERM type discounts are considered API-applied. Other negative price
+ * items (like BEF transportation discounts) are already handled by the local price
+ * calculator and should not be subtracted again.
*
* Note: Voucher discounts (AKTION, KULANZGUTSCHEIN) are handled separately via
* getVoucherDiscountFromPrices() as they are user-initiated, not automatic.
@@ -123,8 +127,7 @@ class BookingResponse
{
return array_filter(
$this->priceItems,
- fn (PriceItem $item) => $item->totalPrice < 0
- && false === \in_array($item->type, ['AKTION', 'KULANZGUTSCHEIN'], true)
+ fn (PriceItem $item) => $item->totalPrice < 0 && 'ERM' === $item->type
);
}
diff --git a/tests/BusProNet/XmlParser/BookingResponseParserTest.php b/tests/BusProNet/XmlParser/BookingResponseParserTest.php
index 6000add..90b186f 100644
--- a/tests/BusProNet/XmlParser/BookingResponseParserTest.php
+++ b/tests/BusProNet/XmlParser/BookingResponseParserTest.php
@@ -312,4 +312,73 @@ class BookingResponseParserTest extends TestCase
$this->assertCount(0, $response->getApiAppliedDiscounts());
$this->assertEquals(0.0, $response->getApiAppliedDiscountTotal());
}
+
+ public function testParseBookingResponseWithTransportationDiscountNotCountedAsApiApplied(): void
+ {
+ $xmlContent = '
+
+
+ möglich
+ 321530
+
+
+
+
+
+
+
+ 1682,00
+
+
+
+';
+
+ $crawler = new Crawler($xmlContent);
+ $response = $this->parser->parse($crawler->filter('ergebnis'));
+
+ $this->assertTrue($response->isInquiryValid());
+ $this->assertEquals(1682.0, $response->totalPrice);
+
+ // Transportation discount (BEF with negative price) should NOT be counted as API-applied discount
+ // because it's already handled by the local price calculator
+ $this->assertCount(0, $response->getApiAppliedDiscounts());
+ $this->assertEquals(0.0, $response->getApiAppliedDiscountTotal());
+
+ // Verify no voucher discounts either
+ $this->assertEquals(0.0, $response->getVoucherDiscountFromPrices());
+ }
+
+ public function testParseBookingResponseWithBothTransportationAndGruppenrabatt(): void
+ {
+ $xmlContent = '
+
+
+ möglich
+ 321530
+
+
+
+
+
+ 1600,00
+
+
+
+';
+
+ $crawler = new Crawler($xmlContent);
+ $response = $this->parser->parse($crawler->filter('ergebnis'));
+
+ // Only ERM (Gruppenrabatt) should be counted as API-applied discount
+ // BEF transportation discount should NOT be counted
+ $apiAppliedDiscounts = $response->getApiAppliedDiscounts();
+ $this->assertCount(1, $apiAppliedDiscounts);
+
+ $gruppenrabatt = array_values($apiAppliedDiscounts)[0];
+ $this->assertEquals('ERM', $gruppenrabatt->type);
+ $this->assertEquals(-100.0, $gruppenrabatt->totalPrice);
+
+ // Total API-applied discount should only include Gruppenrabatt (100), not transportation (300)
+ $this->assertEquals(100.0, $response->getApiAppliedDiscountTotal());
+ }
}