fix: correctly handle discounts applied by dpn api
This commit is contained in:
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -312,4 +312,73 @@ class BookingResponseParserTest extends TestCase
|
||||
$this->assertCount(0, $response->getApiAppliedDiscounts());
|
||||
$this->assertEquals(0.0, $response->getApiAppliedDiscountTotal());
|
||||
}
|
||||
|
||||
public function testParseBookingResponseWithTransportationDiscountNotCountedAsApiApplied(): void
|
||||
{
|
||||
$xmlContent = '<?xml version="1.0" encoding="utf-8"?>
|
||||
<ergebnis>
|
||||
<satz typ="BUCHUNG" />
|
||||
<buchung>möglich</buchung>
|
||||
<vorgang>321530</vorgang>
|
||||
<preise>
|
||||
<preis position="1" art="BEF" unterart="PKW" bezeichnung="Eigene Anreise mit Rabatt" terminvon="20.03.2026" terminbis="20.03.2026" anzahl="5" zuordnung="1,2,3,4,5" preis="-30,00" gesamtpreis="-150,00" id="185481" />
|
||||
<preis position="2" art="BEF" unterart="PKW" bezeichnung="Eigene Abreise" terminvon="22.03.2026" terminbis="22.03.2026" anzahl="5" zuordnung="1,2,3,4,5" preis="0,00" gesamtpreis="0,00" id="185497" />
|
||||
<preis position="3" art="UNT" unterart="ZIM" bezeichnung="5er Zimmer Etagendusche/-WC" terminvon="20.03.2026" terminbis="22.03.2026" anzahl="1" zuordnung="1,2,3,4,5" preis="319,00" gesamtpreis="1595,00" />
|
||||
<preis position="4" art="SON" unterart="SON" bezeichnung="Keycard-Pfand" terminvon="20.03.2026" terminbis="22.03.2026" anzahl="5" zuordnung="1,2,3,4,5" preis="5,40" gesamtpreis="27,00" id="185484" />
|
||||
<preis position="5" art="SON" unterart="SPA" bezeichnung="Skipass 3 Tage" terminvon="20.03.2026" terminbis="22.03.2026" anzahl="3" zuordnung="1,4,5" preis="70,00" gesamtpreis="210,00" id="185486" />
|
||||
</preise>
|
||||
<gesamtpreis>1682,00</gesamtpreis>
|
||||
<zahlungsbedingungen>
|
||||
<restzahlung betrag="1682,00" termin="02.12.2029"></restzahlung>
|
||||
</zahlungsbedingungen>
|
||||
</ergebnis>';
|
||||
|
||||
$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 = '<?xml version="1.0" encoding="utf-8"?>
|
||||
<ergebnis>
|
||||
<satz typ="BUCHUNG" />
|
||||
<buchung>möglich</buchung>
|
||||
<vorgang>321530</vorgang>
|
||||
<preise>
|
||||
<preis position="1" art="BEF" unterart="PKW" bezeichnung="Eigene Anreise mit Rabatt" anzahl="10" preis="-30,00" gesamtpreis="-300,00" />
|
||||
<preis position="2" art="UNT" unterart="ZIM" bezeichnung="Doppelzimmer" anzahl="5" preis="400,00" gesamtpreis="2000,00" />
|
||||
<preis position="3" art="ERM" unterart="GRU" bezeichnung="Gruppenrabatt" anzahl="1" preis="-100,00" gesamtpreis="-100,00" />
|
||||
</preise>
|
||||
<gesamtpreis>1600,00</gesamtpreis>
|
||||
<zahlungsbedingungen>
|
||||
<restzahlung betrag="1600,00" termin="02.12.2029"></restzahlung>
|
||||
</zahlungsbedingungen>
|
||||
</ergebnis>';
|
||||
|
||||
$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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user