wip: submit booking to api
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\XmlParser;
|
||||
|
||||
use App\BusProNet\Model\Agency;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
final class AgencyParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* @return Agency[]
|
||||
*/
|
||||
public function parse(Crawler $node): array
|
||||
{
|
||||
$agencies = [];
|
||||
|
||||
$node->filterXPath('//agenturen/agentur')->each(function (Crawler $agencyNode) use (&$agencies): void {
|
||||
$id = (int) $agencyNode->attr('id');
|
||||
$name = $this->getStringOrNullValue($agencyNode->filterXPath('//name')) ?? '';
|
||||
$code = $this->getStringOrNullValue($agencyNode->filterXPath('//code')) ?? '';
|
||||
$street = $this->getStringOrNullValue($agencyNode->filterXPath('//strasse'));
|
||||
$postCode = $this->getStringOrNullValue($agencyNode->filterXPath('//plz'));
|
||||
$city = $this->getStringOrNullValue($agencyNode->filterXPath('//ort'));
|
||||
$phone = $this->getStringOrNullValue($agencyNode->filterXPath('//telefon'));
|
||||
|
||||
$agencies[] = new Agency(
|
||||
id: $id,
|
||||
name: $name,
|
||||
code: $code,
|
||||
street: $street,
|
||||
postCode: $postCode,
|
||||
city: $city,
|
||||
phone: $phone
|
||||
);
|
||||
});
|
||||
|
||||
return $agencies;
|
||||
}
|
||||
}
|
||||
@@ -59,12 +59,16 @@ class ApiResponseParser extends AbstractParser
|
||||
return (new AvailabilitiesParser())->parseRooms($resultNode);
|
||||
case ApiClient::TYPE_BOOKING_UPDATE:
|
||||
return (new BookingUpdateParser())->parse($resultNode);
|
||||
case ApiClient::TYPE_BOOKING:
|
||||
return (new BookingResponseParser())->parse($resultNode);
|
||||
case ApiClient::TYPE_PRODUCTS:
|
||||
return (new ProductsParser())->parse($resultNode);
|
||||
case ApiClient::TYPE_PRODUCT_DATA:
|
||||
$travelNode = $crawler->filterXPath('//reise/termin');
|
||||
|
||||
return (new TravelParser())->parse($travelNode->first(), ...$additionalArgs);
|
||||
case ApiClient::TYPE_AGENCIES:
|
||||
return (new AgencyParser())->parse($resultNode);
|
||||
}
|
||||
|
||||
throw new ResponseParserException('Unable to parse XML response');
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\BusProNet\XmlParser;
|
||||
|
||||
use App\BusProNet\Model\BookingResponse;
|
||||
use App\BusProNet\Model\PaymentTerms;
|
||||
use App\BusProNet\Model\PriceItem;
|
||||
use Symfony\Component\DomCrawler\Crawler;
|
||||
|
||||
/**
|
||||
* Parses XML responses from booking requests (inquiry and final booking).
|
||||
*
|
||||
* Expected XML structure:
|
||||
* <ergebnis>
|
||||
* <satz typ="BUCHUNG" />
|
||||
* <buchung>möglich|erfolgt</buchung>
|
||||
* <vorgang>321530</vorgang>
|
||||
* <preise>
|
||||
* <preis position="1" art="BEF" unterart="BUS" bezeichnung="..." ... />
|
||||
* </preise>
|
||||
* <gesamtpreis>671,78</gesamtpreis>
|
||||
* <zahlungsbedingungen>
|
||||
* <anzahlung betrag="128,00" termin="21.03.2017" />
|
||||
* <restzahlung betrag="543,78" termin="12.11.2017" />
|
||||
* </zahlungsbedingungen>
|
||||
* </ergebnis>
|
||||
*/
|
||||
class BookingResponseParser extends AbstractParser
|
||||
{
|
||||
public function parse(Crawler $node): BookingResponse
|
||||
{
|
||||
$status = $node->filterXPath('//buchung')->text();
|
||||
$transactionNumber = $this->getStringOrNullValue($node->filterXPath('//vorgang'));
|
||||
$totalPrice = $this->getFloatOrNullValue($node->filterXPath('//gesamtpreis'));
|
||||
|
||||
$priceItems = $this->parsePriceItems($node);
|
||||
$paymentTerms = $this->parsePaymentTerms($node);
|
||||
|
||||
return new BookingResponse(
|
||||
status: $status,
|
||||
transactionNumber: $transactionNumber,
|
||||
priceItems: $priceItems,
|
||||
totalPrice: $totalPrice,
|
||||
paymentTerms: $paymentTerms
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses individual price items from the response.
|
||||
*
|
||||
* @return array<int, PriceItem>
|
||||
*/
|
||||
private function parsePriceItems(Crawler $node): array
|
||||
{
|
||||
$priceItems = [];
|
||||
|
||||
$node->filterXPath('//preise/preis')->each(function (Crawler $priceNode) use (&$priceItems): void {
|
||||
$priceItems[] = new PriceItem(
|
||||
position: (int) $priceNode->attr('position'),
|
||||
type: $priceNode->attr('art'),
|
||||
subType: $priceNode->attr('unterart'),
|
||||
label: $priceNode->attr('bezeichnung'),
|
||||
dateFrom: $priceNode->attr('terminvon'),
|
||||
dateTo: $priceNode->attr('terminbis'),
|
||||
quantity: (int) $priceNode->attr('anzahl'),
|
||||
assignment: $priceNode->attr('zuordnung'),
|
||||
unitPrice: $this->stringToFloat($priceNode->attr('preis')),
|
||||
totalPrice: $this->stringToFloat($priceNode->attr('gesamtpreis')),
|
||||
id: $priceNode->attr('id')
|
||||
);
|
||||
});
|
||||
|
||||
return $priceItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses payment terms from the response.
|
||||
*/
|
||||
private function parsePaymentTerms(Crawler $node): ?PaymentTerms
|
||||
{
|
||||
$paymentNode = $node->filterXPath('//zahlungsbedingungen');
|
||||
|
||||
if (0 === $paymentNode->count()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$depositAmount = null;
|
||||
$depositDate = null;
|
||||
$finalPaymentAmount = null;
|
||||
$finalPaymentDate = null;
|
||||
|
||||
$depositNode = $paymentNode->filterXPath('//anzahlung');
|
||||
if ($depositNode->count() > 0) {
|
||||
$depositAmount = $this->stringToFloat($depositNode->attr('betrag'));
|
||||
$depositDate = $depositNode->attr('termin');
|
||||
}
|
||||
|
||||
$finalPaymentNode = $paymentNode->filterXPath('//restzahlung');
|
||||
if ($finalPaymentNode->count() > 0) {
|
||||
$finalPaymentAmount = $this->stringToFloat($finalPaymentNode->attr('betrag'));
|
||||
$finalPaymentDate = $finalPaymentNode->attr('termin');
|
||||
}
|
||||
|
||||
return new PaymentTerms(
|
||||
depositAmount: $depositAmount,
|
||||
depositDate: $depositDate,
|
||||
finalPaymentAmount: $finalPaymentAmount,
|
||||
finalPaymentDate: $finalPaymentDate
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ class InsuranceParser extends AbstractParser
|
||||
// Second pass: Parse individual insurances with conditional filtering
|
||||
$individualInsurances = [];
|
||||
$xmlContent->filterXPath('//versicherungen/versicherung')
|
||||
->each(function (Crawler $node) use (&$individualInsurances, &$insurances, $referencedIds) {
|
||||
->each(function (Crawler $node) use (&$individualInsurances, &$insurances) {
|
||||
$id = (int) $node->attr('idbuspro'); // Individual insurances have int IDs
|
||||
$isComplementary = $this->getBoolAttributeValue($node->attr('zusatzversicherung'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user