* * möglich|erfolgt * 321530 * ... * * * * 671,78 * * * * * */ 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')); $message = $this->getStringOrNullValue($node->filterXPath('//hinweis')); $priceItems = $this->parsePriceItems($node); $paymentTerms = $this->parsePaymentTerms($node); return new BookingResponse( status: $status, transactionNumber: $transactionNumber, priceItems: $priceItems, totalPrice: $totalPrice, paymentTerms: $paymentTerms, message: $message, ); } /** * Parses individual price items from the response. * * @return array */ 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'); } // Parse purchase vouchers (kaufgutschein elements) $appliedPurchaseVouchers = []; $voucherNodes = $paymentNode->filterXPath('//kaufgutschein'); $voucherNodes->each(function (Crawler $voucherNode) use (&$appliedPurchaseVouchers): void { $appliedPurchaseVouchers[] = [ 'nummer' => $voucherNode->attr('nummer') ?? '', 'betrag' => $this->stringToFloat($voucherNode->attr('betrag')), ]; }); return new PaymentTerms( depositAmount: $depositAmount, depositDate: $depositDate, finalPaymentAmount: $finalPaymentAmount, finalPaymentDate: $finalPaymentDate, appliedPurchaseVouchers: $appliedPurchaseVouchers, ); } }