Index: /controller/wpsg_OrderController.class.php
===================================================================
--- /controller/wpsg_OrderController.class.php	(revision 8539)
+++ /controller/wpsg_OrderController.class.php	(revision 8540)
@@ -1602,5 +1602,6 @@
 						$this->shop->addBackendError(wpsg_translate(__('#1# Bestellung(en) gelÃ¶scht.', 'wpsg'), sizeof($arOrder)));
 
-					} else if ($_REQUEST['wpsg_action'] == 'writeRechnung') {
+					} 
+					else if ($_REQUEST['wpsg_action'] == 'writeRechnung') {
 
 						$nWriteRechnung = 0;
@@ -1772,5 +1773,5 @@
 							// $_REQUEST['wpsg_Multirechnung_email'] = $this->db->fetchOne("SELECT K.`email` FROM `".WPSG_TBL_ORDER."` AS O LEFT JOIN `".WPSG_TBL_KU."` AS K ON (O.`k_id` = K.`id`) WHERE O.`id` = '".wpsg_q($k)."'");
 							
-							if (intval($_REQUEST['wpsg_Multirechnung_sendmail']) !== 1) {
+							if (intval($_REQUEST['wpsg_Multirechnung_sendmail']??'') !== 1) {
 								
 								$oOrder = wpsg_order::getInstance(intval($k));
@@ -1803,8 +1804,6 @@
 							$this->shop->callMod('wpsg_mod_rechnungen', 'writeMultiRechnung', [$arIDs, $bPreview]); 
 
-							// Downloadlink buggy
 							if (!$bPreview) $this->addBackendMessage(
 								'nohspc_'.wpsg_translate(__('Rechnungen als Sammelechnung geschrieben', 'wpsg'))
-								//.' <a href="'.WPSG_URL_WP.'wp-admin/admin.php?page=wpsg-Order&noheader=1&do=writeMultiRechnung&ids='.implode('_', $arIDs).'" target="_new">'.__('Download', 'wpsg').'</a>'
 							);
 
Index: /controller/wpsg_ShopController.class.php
===================================================================
--- /controller/wpsg_ShopController.class.php	(revision 8539)
+++ /controller/wpsg_ShopController.class.php	(revision 8540)
@@ -331,4 +331,7 @@
 			// Bestellbedingungen aktivieren
 			$this->update_option('wpsg_mod_ordercondition', time());
+			
+			// Widerrufsformular aktivieren
+			$this->update_option('wpsg_mod_revocation', time());
 
 			$this->loadModule(true);
@@ -336,4 +339,5 @@
 			$this->arModule['wpsg_mod_versandarten']->install();
 			$this->arModule['wpsg_mod_prepayment']->install();
+			$this->arModule['wpsg_mod_revocation']->install();
 			
 			// Versandzone anlegen
@@ -742,4 +746,5 @@
 					self::STATUS_ZAHLUNGAKZEPTIERT => __('Zahlung akzeptiert', 'wpsg'),
 					self::STATUS_RECHNUNGGESCHRIEBEN => __('Rechnung geschrieben', 'wpsg'),
+					self::STATUS_SAMMELRECHNUNGGESCHRIEBEN => __('Sammelrechnung geschrieben', 'wpsg'),
 					self::STATUS_ZAHLUNGFEHLGESCHLAGEN => __('Zahlung fehlgeschlagen', 'wpsg'),
 					self::STATUS_WAREVERSENDET => __('Ware versendet', 'wpsg'),
Index: /lib/wpsg_basket.class.php
===================================================================
--- /lib/wpsg_basket.class.php	(revision 8539)
+++ /lib/wpsg_basket.class.php	(revision 8540)
@@ -1093,5 +1093,5 @@
 				}
 				
-				if (intval($custom_config['eInvoice']) === 1 && trim($this->arCheckout['email_einvoice']??'') !== '') { // e-Mail fÃŒr eRechnung wird abgefragt und ist angegeben
+				if (intval($custom_config['eInvoice']??0) === 1 && trim($this->arCheckout['email_einvoice']??'') !== '') { // e-Mail fÃŒr eRechnung wird abgefragt und ist angegeben
 					
 					if (!wpsg_isValidEMail($this->arCheckout['email_einvoice'])) {
Index: /mods/mod_rechnungen/eInvoice.php
===================================================================
--- /mods/mod_rechnungen/eInvoice.php	(revision 8539)
+++ /mods/mod_rechnungen/eInvoice.php	(revision 8540)
@@ -32,8 +32,6 @@
 		}
 		
-		public static function writeEInvoice(int $order_id, int $invoice_id, int $profil_id = 0): string {
-			
-			$oInvoice = wpsg_invoice::getInstance($invoice_id);
-			
+		public static function writeMultiEInvoice(wpsg_invoice $oInvoice, int $profil_id = 0): string {
+					
 			$shop = \wpsg_ShopController::getShop();
 			
@@ -41,84 +39,75 @@
 			
 			if ($profil_id >= 0) {
-
-				/** @var \wpsg_order $oOrder */
-				$oOrder = wpsg_order::getInstance($order_id);
-				
+			
 				$pdf_file = $oInvoice->getFilePath(true);
 				$pdf_path = dirname($pdf_file).DIRECTORY_SEPARATOR;
-
+	
 				$document = ZugferdDocumentBuilder::CreateNew($profil_id);
-				
-				$arCalculation = wpsg_calculation::getOrderCalculation($order_id)->getCalculationArray();
-
-				$buyer_reference = trim($oOrder->getLeitwegId());
-				if ($buyer_reference === '') $buyer_reference = $oOrder->getCustomer()->getNr();
-
-				// https://www.e-rechnung-bund.de/wp-content/uploads/2023/04/Uebersichtslisten-Eingabefelder-OZG-RE.pdf
-				// https://easyfirma.net/e-rechnung/zugferd/bt-felder
-				// https://www.xoev.de/sixcms/media.php/13/201-xrechnung-2020-12-16.pdf
-				// https://erechnungsvalidator.service-bw.de/
-
+
+				/** @var \wpsg_customer $oCustomer */
+				$oCustomer = $oInvoice->getCustomer();
+
+				$buyer_reference = trim($oCustomer->getLeitwegId());
+				if ($buyer_reference === '') $buyer_reference = $oCustomer->getNr();
+				
 				$bt_9 = null;
-
+	
 				$bt_20 = "Bitte Zahlungsanweisung auf PDF beachten.";
-
+				
 				// Zuschlagbetrag (ohne Umsatzsteuer), der zum Gesamtrechnungsbetrag hinzugefÃŒgt wird.
 				$bt_99 = 0;
-
+	
 				// BT-106 / Hier finden Sie die Summe aller Nettopositionen ohne Umsatzsteuer, NachlÃ€sse und ZuschlÃ€ge.
 				$bt_106 = $oInvoice->getSumNetto();
-
+	
 				// BT-107 / Hier finden Sie die Summe aller NachlÃ€sse auf Ebene der Rechnung (ohne NachlÃ€sse auf Positionsebene).
 				$bt_107 = 0;
-
+	
 				// BT-108 / Hier finden Sie die Summe aller ZuschlÃ€ge auf Dokumentenebene (ohne ZuschlÃ€ge auf Positionsebene).
 				$bt_108 = 0;
-
+	
 				// BT-109 / Hier finden Sie den Gesamtbetrag der Rechnung ohne Umsatzsteuer.
 				$bt_109 = $oInvoice->getSumNetto();
-
+	
 				// BT-110 / Hier finden Sie den Gesamtbetrag der Umsatzsteuer der Rechnung.
 				$bt_110 = $oInvoice->getTaxSum();
-
+	
 				// BT-112 / Gesamtbetrag der Rechnungsumsatzsteuer
 				$bt_112 = $oInvoice->getSumBrutto();
-
+	
 				// BT-113 / Vorauszahlungsbetrag
 				$bt_113 = 0;
-
+	
 				// BT-114 / Rundungsbetrag
 				$bt_114 = 0;
-
+	
 				// BT-115 / Hier finden Sie den ausstehenden Betrag. Er ergibt sich aus dem Rechnungsbetrag (brutto) abzÃŒglich des gezahlten Betrags.
 				$bt_115 = round($oInvoice->getSumBrutto(), 2);
-
+	
 				// BT-131 / Gesamtpreis ohne Umsatzsteuer, einschlieÃlich aller NachlÃ€sse, ZuschlÃ€ge und weiterer anfallender Steuern.
 				$bt_131 = round($oInvoice->getSumNetto(), 2);
-
-				$buyer_email = trim($oOrder->getCustomer()->getEMailEInvoice()??'');
-				if ($buyer_email === '') $buyer_email = $oOrder->getCustomer()->getEMail();
-
-				$buyer_email = trim($oOrder->getCustomer()->getEMailEInvoice()??'');
-				if ($buyer_email === '') $buyer_email = $oOrder->getCustomer()->getEMail();
+	
+				$buyer_email = trim($oCustomer->getEMailEInvoice()??'');
+				if ($buyer_email === '') $buyer_email = $oCustomer->getEMail();
+
+				$arOrder = []; $arOrderNr = [];
+				foreach ($oInvoice->getOrderIds() as $order_id) {
+
+					$arOrder[] = wpsg_order::getInstance($order_id);
+					$arOrderNr[] = wpsg_order::getInstance($order_id)->getNr();
+
+				}
+
+				$arCalculation = wpsg_calculation::getOrderCalculation($arOrder[0]->getId())->getCalculationArray();
 
 				$document
-					 //->addDocumentAllowanceCharge($bt_99, true, 'S', 'VAT', 0)
+					//->addDocumentAllowanceCharge($bt_99, true, 'S', 'VAT', 0)
 					->setDocumentSellerLegalOrganisation(null, null, $shop->get_option('wpsg_shopdata_owner', default: ''))
 					->setDocumentInformation($oInvoice->getNr(), ZugferdInvoiceType::INVOICE, \DateTime::createFromFormat("Ymd", $oInvoice->getDate('Ymd')), "EUR")
-					->addDocumentNote(wpsg_translate(__('Rechnung #1# zu Bestellung #2#', 'wpsg'), $oInvoice->getNr(), $oOrder->getNr()))
+					->addDocumentNote(wpsg_translate(__('Rechnung #1# zu Bestellungen #2#', 'wpsg'), $oInvoice->getNr(), implode(',', $arOrderNr)))
 					// ->setDocumentSupplyChainEvent(\DateTime::createFromFormat('Ymd', '20180305')) Lieferinformation
-					->setDocumentSeller($shop->get_option('wpsg_shopdata_name', default: ''))
 					->setDocumentSellerCommunication('EM', $shop->get_option('wpsg_shopdata_email', default: ''))
-
 //					->setDocumentBuyerReference("04011000-12345ABCXYZ-86")
 					->setDocumentBuyerReference($buyer_reference)
-
-					// https://service.unece.org/trade/untdid/d16b/tred/tred4461.htm
-					->addDocumentPaymentMean(match($oOrder->getPaymentID()) {
-						/** TODO: Zahlungsarten Codes */
-						default => 'ZZZ'
-					}, $oOrder->getPaymentLabel())
-
 					//->addDocumentSellerGlobalId("4000001123452", "0088")
 					->addDocumentSellerTaxRegistration("FC", $shop->get_option('wpsg_shopdata_taxnr', default: ''))
@@ -147,30 +136,74 @@
 					)
 					->addDocumentBuyerTaxRegistration(
-						$oOrder->getInvoiceFax(),
-					)
-					->setDocumentBuyer($oOrder->getInvoiceFirstName() . " " . $oOrder->getInvoiceName(), strval($oOrder->getId()))
+						$arOrder[0]->getInvoiceFax(),
+					)
+					->setDocumentBuyer($oCustomer->getFirstname() . " " . $oCustomer->getName(), strval($oCustomer->getNr()))
 					->setDocumentBuyerAddress(
-						$oOrder->getInvoiceStreet(),
-						"",
-						"",
-						$oOrder->getInvoiceZip(),
-						$oOrder->getInvoiceCity(),
-						$oOrder->getInvoiceCountryKuerzel()
+						$oCustomer->getStreet(),
+						"",
+						"",
+						$oCustomer->getZip(),
+						$oCustomer->getCity(),
+						$oCustomer->getCountryKuerzel()
 					)
 					->setDocumentBuyerContact(
-						$oOrder->getInvoiceName() . " " . $oOrder->getInvoiceFirstName(),
-						"",
-						$oOrder->getInvoicePhone(),
-						$oOrder->getInvoiceFax(),
+						$oCustomer->getName() . " " . $oCustomer->getFirstname(),
+						"",
+						$oCustomer->getPhone(),
+						$oCustomer->getFax(),
 						$buyer_email
 					)
 					->setDocumentBuyerCommunication('EM', $buyer_email);
-				
-				// Lieferanschrift = Rechnungsanschfitt
-				$shipping_name = $oOrder->getShippingCompany();
-				if (trim($shipping_name) === '') $shipping_name = $oOrder->getShippingFirstName().' '.$oOrder->getShippingName();
-
-				$document->setDocumentShipTo($shipping_name, '');
-				$document->setDocumentShipToAddress($oOrder->getShippingStreet(), '', '', $oOrder->getShippingZip(), $oOrder->getShippingCity(), $oOrder->getShippingCountryKuerzel());
+
+				$seller = $shop->get_option('wpsg_shopdata_name', default: '');
+				if (trim($seller) !== '') $document->setDocumentSeller($seller);
+				else $document->setDocumentSeller(get_bloginfo('name'));
+				
+				// https://service.unece.org/trade/untdid/d16b/tred/tred4461.htm
+				$arPaymentIds = [];
+				foreach ($arOrder as $oOrder) {
+
+					if (in_array($oOrder->getPaymentID(), $arPaymentIds, true)) continue;
+
+					$arPaymentIds[] = $oOrder->getPaymentID();
+
+					$document->addDocumentPaymentMean(match($oOrder->getPaymentID()) {
+						/** TODO: Zahlungsarten Codes */
+						default => 'ZZZ'
+					}, $oOrder->getPaymentLabel());
+
+				}
+
+				// Lieferanschrift = Rechnungsanschrift, nur wenn bei allen Bestellungen identisch
+				$bShippingIdentical = true;
+				foreach ($arOrder as $oOrder) {
+
+					if (
+						$oOrder->getShippingStreet() !== $arOrder[0]->getShippingStreet() ||
+						$oOrder->getShippingZip() !== $arOrder[0]->getShippingZip() ||
+						$oOrder->getShippingCity() !== $arOrder[0]->getShippingCity() ||
+						$oOrder->getShippingCountryKuerzel() !== $arOrder[0]->getShippingCountryKuerzel() ||
+						$oOrder->getShippingCompany() !== $arOrder[0]->getShippingCompany() ||
+						$oOrder->getShippingFirstName() !== $arOrder[0]->getShippingFirstName() ||
+						$oOrder->getShippingName() !== $arOrder[0]->getShippingName()
+					) {
+
+						$bShippingIdentical = false;
+						break;
+
+					}
+
+				}
+
+				if ($bShippingIdentical) {
+
+					$shipping_name = $arOrder[0]->getShippingCompany();
+					if (trim($shipping_name) === '') $shipping_name = $arOrder[0]->getShippingFirstName().' '.$arOrder[0]->getShippingName();
+
+					$document->setDocumentShipTo($shipping_name, '');
+					$document->setDocumentShipToAddress($arOrder[0]->getShippingStreet(), '', '', $arOrder[0]->getShippingZip(), $arOrder[0]->getShippingCity(), $arOrder[0]->getShippingCountryKuerzel());
+
+				}
+
 				$document->setDocumentSupplyChainEvent(\DateTime::createFromFormat("Ymd", $oInvoice->getDate('Ymd')));
 				
@@ -237,5 +270,5 @@
 				
 				foreach ($oInvoice->getItems() as $oInvoiceItem) {
-				
+
 					$lineID = ($lineID??0) + 1;
 
@@ -265,13 +298,274 @@
 				$pdf_path .= 'e'.$oInvoice->getId().'_'.$profil_id.'.pdf';
 				
-  				$pdfBuilder->generateDocument()->saveDocument($pdf_path);
-				 
+				$pdfBuilder->generateDocument()->saveDocument($pdf_path);
+
+				if (isset($_GET['xml_debug'])) {
+
+					header('Content-Type: application/xml; charset=utf-8');
+					echo $document->getContent();
+					exit;
+
+				}
+
 				return $pdf_path;
-				
+
 			}
-			
+
 			return $oInvoice->getFilePath(true);
-			
+
 		}
-	
+
+		public static function writeEInvoice(int $order_id, int $invoice_id, int $profil_id = 0): string {
+;
+			$oInvoice = wpsg_invoice::getInstance($invoice_id);			
+			$shop = \wpsg_ShopController::getShop();
+			
+			if ($profil_id === 0) $profil_id = intval($shop->get_option('wpsg_mod_rechnungen_einvoice')) - 100;
+
+			if ($profil_id >= 0) {
+
+				/** @var \wpsg_order $oOrder */
+				$oOrder = wpsg_order::getInstance($order_id);
+				
+				$pdf_file = $oInvoice->getFilePath(true);
+				$pdf_path = dirname($pdf_file).DIRECTORY_SEPARATOR;
+
+				$document = ZugferdDocumentBuilder::CreateNew($profil_id);
+				
+				$arCalculation = wpsg_calculation::getOrderCalculation($order_id)->getCalculationArray();
+
+				$buyer_reference = trim($oOrder->getLeitwegId());
+				if ($buyer_reference === '') $buyer_reference = $oOrder->getCustomer()->getNr();
+
+				// https://www.e-rechnung-bund.de/wp-content/uploads/2023/04/Uebersichtslisten-Eingabefelder-OZG-RE.pdf
+				// https://easyfirma.net/e-rechnung/zugferd/bt-felder
+				// https://www.xoev.de/sixcms/media.php/13/201-xrechnung-2020-12-16.pdf
+				// https://erechnungsvalidator.service-bw.de/
+
+				$bt_9 = null;
+
+				$bt_20 = "Bitte Zahlungsanweisung auf PDF beachten.";
+
+				// Zuschlagbetrag (ohne Umsatzsteuer), der zum Gesamtrechnungsbetrag hinzugefÃŒgt wird.
+				$bt_99 = 0;
+
+				// BT-106 / Hier finden Sie die Summe aller Nettopositionen ohne Umsatzsteuer, NachlÃ€sse und ZuschlÃ€ge.
+				$bt_106 = $oInvoice->getSumNetto();
+
+				// BT-107 / Hier finden Sie die Summe aller NachlÃ€sse auf Ebene der Rechnung (ohne NachlÃ€sse auf Positionsebene).
+				$bt_107 = 0;
+
+				// BT-108 / Hier finden Sie die Summe aller ZuschlÃ€ge auf Dokumentenebene (ohne ZuschlÃ€ge auf Positionsebene).
+				$bt_108 = 0;
+
+				// BT-109 / Hier finden Sie den Gesamtbetrag der Rechnung ohne Umsatzsteuer.
+				$bt_109 = $oInvoice->getSumNetto();
+
+				// BT-110 / Hier finden Sie den Gesamtbetrag der Umsatzsteuer der Rechnung.
+				$bt_110 = $oInvoice->getTaxSum();
+
+				// BT-112 / Gesamtbetrag der Rechnungsumsatzsteuer
+				$bt_112 = $oInvoice->getSumBrutto();
+
+				// BT-113 / Vorauszahlungsbetrag
+				$bt_113 = 0;
+
+				// BT-114 / Rundungsbetrag
+				$bt_114 = 0;
+
+				// BT-115 / Hier finden Sie den ausstehenden Betrag. Er ergibt sich aus dem Rechnungsbetrag (brutto) abzÃŒglich des gezahlten Betrags.
+				$bt_115 = round($oInvoice->getSumBrutto(), 2);
+
+				// BT-131 / Gesamtpreis ohne Umsatzsteuer, einschlieÃlich aller NachlÃ€sse, ZuschlÃ€ge und weiterer anfallender Steuern.
+				$bt_131 = round($oInvoice->getSumNetto(), 2);
+
+				$buyer_email = trim($oOrder->getCustomer()->getEMailEInvoice()??'');
+				if ($buyer_email === '') $buyer_email = $oOrder->getCustomer()->getEMail();
+
+				$buyer_email = trim($oOrder->getCustomer()->getEMailEInvoice()??'');
+				if ($buyer_email === '') $buyer_email = $oOrder->getCustomer()->getEMail();
+
+				$document
+					 //->addDocumentAllowanceCharge($bt_99, true, 'S', 'VAT', 0)
+					->setDocumentSellerLegalOrganisation(null, null, $shop->get_option('wpsg_shopdata_owner', default: ''))
+					->setDocumentInformation($oInvoice->getNr(), ZugferdInvoiceType::INVOICE, \DateTime::createFromFormat("Ymd", $oInvoice->getDate('Ymd')), "EUR")
+					->addDocumentNote(wpsg_translate(__('Rechnung #1# zu Bestellung #2#', 'wpsg'), $oInvoice->getNr(), $oOrder->getNr()))
+					// ->setDocumentSupplyChainEvent(\DateTime::createFromFormat('Ymd', '20180305')) Lieferinformation
+					->setDocumentSellerCommunication('EM', $shop->get_option('wpsg_shopdata_email', default: ''))
+
+//					->setDocumentBuyerReference("04011000-12345ABCXYZ-86")
+					->setDocumentBuyerReference($buyer_reference)
+
+					// https://service.unece.org/trade/untdid/d16b/tred/tred4461.htm
+					->addDocumentPaymentMean(match($oOrder->getPaymentID()) {
+						/** TODO: Zahlungsarten Codes */
+						default => 'ZZZ'
+					}, $oOrder->getPaymentLabel())
+
+					//->addDocumentSellerGlobalId("4000001123452", "0088")
+					->addDocumentSellerTaxRegistration("FC", $shop->get_option('wpsg_shopdata_taxnr', default: ''))
+					->addDocumentSellerTaxRegistration("VA", $shop->get_option('wpsg_shopdata_ustidnr', default: ''))
+					->setDocumentSellerAddress(
+						$shop->get_option('wpsg_shopdata_street', default: ''),
+						"",
+						"",
+						$shop->get_option('wpsg_shopdata_zip', default: ''),
+						$shop->get_option('wpsg_shopdata_city', default: ''),
+						\wpsg_country::getInstance(intval($shop->get_option('wpsg_shopdata_country')))->getShorttext()
+					)
+					->addDocumentSellerContact(
+						$shop->get_option('wpsg_shopdata_owner', default: ''),
+						__('Rechnungsabteilung', 'wpsg'),
+						$shop->get_option('wpsg_shopdata_eu_tel', default: ''),
+						$shop->get_option('wpsg_shopdata_eu_fax', default: ''),
+						$shop->get_option('wpsg_shopdata_email', default: '')
+					)
+					->setDocumentSellerContact(
+						$shop->get_option('wpsg_shopdata_owner', default: ''),
+						__('Rechnungsabteilung', 'wpsg'),
+						$shop->get_option('wpsg_shopdata_eu_tel', default: ''),
+						$shop->get_option('wpsg_shopdata_eu_fax', default: ''),
+						$shop->get_option('wpsg_shopdata_email', default: '')
+					)
+					->addDocumentBuyerTaxRegistration(
+						$oOrder->getInvoiceFax(),
+					)
+					->setDocumentBuyer($oOrder->getInvoiceFirstName() . " " . $oOrder->getInvoiceName(), strval($oOrder->getId()))
+					->setDocumentBuyerAddress(
+						$oOrder->getInvoiceStreet(),
+						"",
+						"",
+						$oOrder->getInvoiceZip(),
+						$oOrder->getInvoiceCity(),
+						$oOrder->getInvoiceCountryKuerzel()
+					)
+					->setDocumentBuyerContact(
+						$oOrder->getInvoiceName() . " " . $oOrder->getInvoiceFirstName(),
+						"",
+						$oOrder->getInvoicePhone(),
+						$oOrder->getInvoiceFax(),
+						$buyer_email
+					)
+					->setDocumentBuyerCommunication('EM', $buyer_email);
+				
+				$seller = $shop->get_option('wpsg_shopdata_name', default: '');
+				if (trim($seller) !== '') $document->setDocumentSeller($seller);
+				else $document->setDocumentSeller(get_bloginfo('name'));
+				
+				// Lieferanschrift = Rechnungsanschfitt
+				$shipping_name = $oOrder->getShippingCompany();
+				if (trim($shipping_name) === '') $shipping_name = $oOrder->getShippingFirstName().' '.$oOrder->getShippingName();
+
+				$document->setDocumentShipTo($shipping_name, '');
+				$document->setDocumentShipToAddress($oOrder->getShippingStreet(), '', '', $oOrder->getShippingZip(), $oOrder->getShippingCity(), $oOrder->getShippingCountryKuerzel());
+				$document->setDocumentSupplyChainEvent(\DateTime::createFromFormat("Ymd", $oInvoice->getDate('Ymd')));
+				
+				// Steueranteile
+				foreach ($oInvoice->getTaxInfo() as $tax_info) {
+
+					// BT-118 / VAT category code
+					$bt_118 = 'S';
+
+					// BT-118-1 ??
+					$bt_118_0 = 'VAT';
+
+					// BT-116 / Summe aller zu versteuernden BetrÃ€ge, fÃŒr die ein bestimmter Code der Umsatzsteuerkategorie und ein bestimmter Umsatzsteuersatz gelten (falls ein kategoriespezifischer Umsatzsteuersatz gilt).
+					$bt_116 = round($tax_info['netto'], 2);
+
+					// BT-117 / Der fÃŒr die betreffende Umsatzsteuerkategorie zu entrichtende Gesamtbetrag.
+					$bt_117 = $tax_info['tax_value'];
+
+					// BT-119 / Der Umsatzsteuersatz, angegeben als fÃŒr die betreffende Umsatzsteuerkategorie geltender Prozentsatz.
+					$bt_119 = $tax_info['tax_rate'];
+
+					$document->addDocumentTax(
+						$bt_118,
+						$bt_118_0,
+						$bt_116,
+						$bt_117,
+						$bt_119
+					);
+					
+				}
+
+				$PaymentNettoPos = 0; $PaymentNettoNeg = 0;
+				$PaymentNetto = $arCalculation['sum']['payment_brutto_calculated'];
+				if ($PaymentNetto > 0) {$PaymentNettoPos = $PaymentNetto;}
+				elseif ($PaymentNetto < 0) {$PaymentNettoNeg = $PaymentNetto;}
+
+				$document->setDocumentSummation(
+					$bt_112,
+					$bt_115,
+					$bt_106,
+					$bt_108,
+					$bt_107,
+					$bt_109,
+					$bt_110,
+					$bt_114,
+					$bt_113
+				);
+
+				/*
+				$document->setDocumentSummation(
+					$bt_112,
+					$bt_115,
+					$oInvoice->getSumNetto(),
+					$arCalculation['sum']['shipping_brutto_calculated'] + $PaymentNettoPos,
+					($arCalculation['sum']['voucher_brutto']??0) + $PaymentNettoNeg,
+					$oInvoice->getSumNetto(),
+					$oInvoice->getSumBrutto() - $oInvoice->getSumNetto(),
+					0.0,
+					0.0
+				);
+				*/
+
+				$document->addDocumentPaymentTerm($bt_20, $bt_9);
+				
+				foreach ($oInvoice->getItems() as $oInvoiceItem) {
+
+					$lineID = ($lineID??0) + 1;
+
+					$bt_131 = $oInvoiceItem->getNettoSum();
+
+					$document->addNewPosition(strval($lineID));
+					$document->setDocumentPositionProductDetails(
+						$oInvoiceItem->getLabel(),
+						"",
+						strval($oInvoiceItem->getId()),
+						null,
+						"0160", // GS1 Global Trade Item Number (GTIN, EAN)
+						$oInvoiceItem->getGTIN()
+					);
+					$document->setDocumentPositionGrossPrice($oInvoiceItem->getNetto());
+					$document->setDocumentPositionNetPrice($oInvoiceItem->getNetto());
+					$document->setDocumentPositionQuantity($oInvoiceItem->getAmount(), "H87");
+					$document->addDocumentPositionTax('S', 'VAT', $oInvoiceItem->getTaxRate());
+					$document->setDocumentPositionLineSummation($bt_131);
+					
+				}
+
+				$document->writeFile($pdf_path."/e".$oInvoice->getId()."_".$profil_id.".xml");
+				
+				$pdfBuilder = new ZugferdDocumentPdfBuilder($document, $pdf_file);
+				
+				$pdf_path .= 'e'.$oInvoice->getId().'_'.$profil_id.'.pdf';
+				
+				$pdfBuilder->generateDocument()->saveDocument($pdf_path);
+
+				if (isset($_GET['xml_debug'])) {
+
+					header('Content-Type: application/xml; charset=utf-8');
+					echo $document->getContent();
+					exit;
+
+				}
+
+				return $pdf_path;
+
+			}
+
+			return $oInvoice->getFilePath(true);
+
+		}
+
 	}
Index: /mods/mod_rechnungen/lib/composer.lock
===================================================================
--- /mods/mod_rechnungen/lib/composer.lock	(revision 8539)
+++ /mods/mod_rechnungen/lib/composer.lock	(revision 8540)
@@ -325,17 +325,18 @@
         {
             "name": "horstoeko/zugferd",
-            "version": "v1.0.115",
+            "version": "v1.0.123",
             "source": {
                 "type": "git",
                 "url": "https://github.com/horstoeko/zugferd.git",
-                "reference": "9bbf0c06942645001d10e88d6e26ff6d8983da2c"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/9bbf0c06942645001d10e88d6e26ff6d8983da2c",
-                "reference": "9bbf0c06942645001d10e88d6e26ff6d8983da2c",
-                "shasum": ""
-            },
-            "require": {
+                "reference": "79354388b286dd2c3a53025ca570c9039b74460a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/79354388b286dd2c3a53025ca570c9039b74460a",
+                "reference": "79354388b286dd2c3a53025ca570c9039b74460a",
+                "shasum": ""
+            },
+            "require": {
+                "ext-fileinfo": "*",
                 "ext-simplexml": "*",
                 "goetas-webservices/xsd2php-runtime": "^0.2.13",
@@ -347,8 +348,8 @@
                 "setasign/fpdi": "^2",
                 "smalot/pdfparser": "^0|^2",
-                "symfony/finder": "^5|^6|^7",
-                "symfony/process": "^5|^6|^7",
-                "symfony/validator": "^5|^6|^7",
-                "symfony/yaml": "^5|^6|^7"
+                "symfony/finder": "^5|^6|^7|^8",
+                "symfony/process": "^5|^6|^7|^8",
+                "symfony/validator": "^5|^6|^7|^8",
+                "symfony/yaml": "^5|^6|^7|^8"
             },
             "require-dev": {
@@ -393,7 +394,7 @@
             "support": {
                 "issues": "https://github.com/horstoeko/zugferd/issues",
-                "source": "https://github.com/horstoeko/zugferd/tree/v1.0.115"
-            },
-            "time": "2025-06-06T08:14:02+00:00"
+                "source": "https://github.com/horstoeko/zugferd/tree/v1.0.123"
+            },
+            "time": "2026-05-23T14:14:15+00:00"
         },
         {
Index: /mods/mod_rechnungen/lib/vendor/composer/installed.json
===================================================================
--- /mods/mod_rechnungen/lib/vendor/composer/installed.json	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/composer/installed.json	(revision 8540)
@@ -334,18 +334,19 @@
         {
             "name": "horstoeko/zugferd",
-            "version": "v1.0.115",
-            "version_normalized": "1.0.115.0",
+            "version": "v1.0.123",
+            "version_normalized": "1.0.123.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/horstoeko/zugferd.git",
-                "reference": "9bbf0c06942645001d10e88d6e26ff6d8983da2c"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/9bbf0c06942645001d10e88d6e26ff6d8983da2c",
-                "reference": "9bbf0c06942645001d10e88d6e26ff6d8983da2c",
-                "shasum": ""
-            },
-            "require": {
+                "reference": "79354388b286dd2c3a53025ca570c9039b74460a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/horstoeko/zugferd/zipball/79354388b286dd2c3a53025ca570c9039b74460a",
+                "reference": "79354388b286dd2c3a53025ca570c9039b74460a",
+                "shasum": ""
+            },
+            "require": {
+                "ext-fileinfo": "*",
                 "ext-simplexml": "*",
                 "goetas-webservices/xsd2php-runtime": "^0.2.13",
@@ -357,8 +358,8 @@
                 "setasign/fpdi": "^2",
                 "smalot/pdfparser": "^0|^2",
-                "symfony/finder": "^5|^6|^7",
-                "symfony/process": "^5|^6|^7",
-                "symfony/validator": "^5|^6|^7",
-                "symfony/yaml": "^5|^6|^7"
+                "symfony/finder": "^5|^6|^7|^8",
+                "symfony/process": "^5|^6|^7|^8",
+                "symfony/validator": "^5|^6|^7|^8",
+                "symfony/yaml": "^5|^6|^7|^8"
             },
             "require-dev": {
@@ -375,5 +376,5 @@
                 "squizlabs/php_codesniffer": "^3"
             },
-            "time": "2025-06-06T08:14:02+00:00",
+            "time": "2026-05-23T14:14:15+00:00",
             "type": "package",
             "installation-source": "dist",
@@ -405,5 +406,5 @@
             "support": {
                 "issues": "https://github.com/horstoeko/zugferd/issues",
-                "source": "https://github.com/horstoeko/zugferd/tree/v1.0.115"
+                "source": "https://github.com/horstoeko/zugferd/tree/v1.0.123"
             },
             "install-path": "../horstoeko/zugferd"
Index: /mods/mod_rechnungen/lib/vendor/composer/installed.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/composer/installed.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/composer/installed.php	(revision 8540)
@@ -57,7 +57,7 @@
         ),
         'horstoeko/zugferd' => array(
-            'pretty_version' => 'v1.0.115',
-            'version' => '1.0.115.0',
-            'reference' => '9bbf0c06942645001d10e88d6e26ff6d8983da2c',
+            'pretty_version' => 'v1.0.123',
+            'version' => '1.0.123.0',
+            'reference' => '79354388b286dd2c3a53025ca570c9039b74460a',
             'type' => 'package',
             'install_path' => __DIR__ . '/../horstoeko/zugferd',
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/.github/workflows/maintain-issues-stale.yml
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/.github/workflows/maintain-issues-stale.yml	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/.github/workflows/maintain-issues-stale.yml	(revision 8540)
@@ -13,5 +13,5 @@
       pull-requests: write
     steps:
-      - uses: actions/stale@v9
+      - uses: actions/stale@v10
         with:
           days-before-issue-stale: 7
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/README.md
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/README.md	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/README.md	(revision 8540)
@@ -11,4 +11,33 @@
 [![Continuous Integration](https://github.com/horstoeko/zugferd/actions/workflows/build.ci.yml/badge.svg?branch=master)](https://github.com/horstoeko/zugferd/actions/workflows/build.ci.yml)
 [![Release Status](https://github.com/horstoeko/zugferd/actions/workflows/build.release.yml/badge.svg)](https://github.com/horstoeko/zugferd/actions/workflows/build.release.yml)
+
+<!-- omit in toc -->
+## Searching for contributors
+
+> [!IMPORTANT]
+> ## Zukunft / Nachfolger-Projekt
+> Dieses Projekt hat lange gute Dienste geleistet, aber die Codebasis ist inzwischen in die Jahre gekommen â es ist Zeit fÃŒr eine grundlegende Modernisierung.
+>
+> **Keine Sorge:** `horstoeko/zugferd` wird weiterhin betreut. Ich werde bestmÃ¶glich Bugfixes liefern und Pull Requests prÃŒfen, sodass bestehende Anwender sich weiterhin darauf verlassen kÃ¶nnen.
+>
+> Parallel entsteht eine neue, modernere Codebasis. Sie wird einen **Legacy-Support** erhalten, damit die Migration fÃŒr bestehende Nutzer so reibungslos wie mÃ¶glich ablÃ€uft.
+>
+> Ich suche einfach **helfende HÃ€nde**, die mich wegen **Zeitmangels** bei der Weiterentwicklung und Pflege unterstÃŒtzen kÃ¶nnen â ganz egal ob Code, Tests, Doku, Reviews, Beispiele, Issue-Triage oder einfach Feedback.
+>
+> **Kontakt (gern auch unverbindlich):** horstoeko-invoicesuite@erling.com.de
+> Schreib kurz, wobei du unterstÃŒtzen mÃ¶chtest und wie viel Zeit du grob hast.
+
+> [!IMPORTANT]
+> ## Future / Successor project
+> This project has served well for a long time, but the codebase is getting old and itâs time for a major modernization.
+>
+> **No worries:** `horstoeko/zugferd` will continue to be maintained. I will keep providing best-effort bugfixes and reviewing PRs so existing users can continue to rely on it.
+>
+> In parallel, a new, modern codebase is being built. It will include **legacy support** to make migration as smooth as possible for current users.
+>
+> Iâm simply looking for **helping hands** because my time is limited â whether itâs code, tests, docs, reviews, examples, issue triage, or just feedback.
+>
+> **Contact (also just for an informal chat):** horstoeko-invoicesuite@erling.com.de
+> Please share what youâd like to help with and roughly how much time you have.
 
 <!-- omit in toc -->
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/build/phpunit.xml
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/build/phpunit.xml	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/build/phpunit.xml	(revision 8540)
@@ -66,4 +66,5 @@
             <file>../tests/testcases/issues/Issue268Test.php</file>
             <file>../tests/testcases/issues/Issue270Test.php</file>
+            <file>../tests/testcases/issues/Issue337Test.php</file>
         </testsuite>
     </testsuites>
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/composer.json
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/composer.json	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/composer.json	(revision 8540)
@@ -30,4 +30,5 @@
     "require": {
         "php": ">=7.3",
+        "ext-fileinfo": "*",
         "ext-simplexml": "*",
         "goetas-webservices/xsd2php-runtime": "^0.2.13",
@@ -38,8 +39,8 @@
         "setasign/fpdi": "^2",
         "smalot/pdfparser": "^0|^2",
-        "symfony/finder": "^5|^6|^7",
-        "symfony/process": "^5|^6|^7",
-        "symfony/validator": "^5|^6|^7",
-        "symfony/yaml": "^5|^6|^7"
+        "symfony/finder": "^5|^6|^7|^8",
+        "symfony/process": "^5|^6|^7|^8",
+        "symfony/validator": "^5|^6|^7|^8",
+        "symfony/yaml": "^5|^6|^7|^8"
     },
     "require-dev": {
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/make/gencodelists.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/make/gencodelists.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/make/gencodelists.php	(revision 8540)
@@ -86,5 +86,5 @@
 
     $strArray = explode(" ", $str);
-    if (count($strArray) == 1) {
+    if (count($strArray) === 1) {
         $strNew = $strArray[0];
     } else {
@@ -456,5 +456,5 @@
                 $downloadedContentObjectData[] = $row;
             }
-            
+
             fclose($handle);
         } else {
@@ -497,8 +497,8 @@
 
             if (($handle = fopen($fileToDownload[DOWNLOADDEF_KEY_TOFILE][$idx], "r")) !== false) {
-                while (($row = fgetcsv($handle, null, "|")) !== false) {
+                while (($row = fgetcsv($handle, null, "|", '"', "\\")) !== false) {
                     $downloadedContentObjectData[] = $row;
                 }
-                
+
                 fclose($handle);
             } else {
@@ -540,5 +540,5 @@
                     $downloadedContentObjectData[] = $row;
                 }
-                
+
                 fclose($handle);
             } else {
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php	(revision 8540)
@@ -10,5 +10,5 @@
 namespace horstoeko\zugferd;
 
-use DateTime;
+use DateTimeInterface;
 use DOMXPath;
 use DOMDocument;
@@ -172,14 +172,14 @@
      * Set main information about this document.
      *
-     * @param  string        $documentNo               __BT-1, From MINIMUM__ The document no issued by the seller
-     * @param  string        $documentTypeCode         __BT-3, From MINIMUM__ The type of the document, See \horstoeko\codelists\ZugferdInvoiceType for details
-     * @param  DateTime      $documentDate             __BT-2, From MINIMUM__ Date of invoice. The date when the document was issued by the seller
-     * @param  string        $invoiceCurrency          __BT-5, From MINIMUM__ Code for the invoice currency
-     * @param  string|null   $documentName             __BT-X-2, From EXTENDED__ Document Type. The documenttype (free text)
-     * @param  string|null   $documentLanguage         __BT-X-4, From EXTENDED__ Language indicator. The language code in which the document was written
-     * @param  DateTime|null $effectiveSpecifiedPeriod __BT-X-6-000, From EXTENDED__ The contractual due date of the invoice
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentInformation(string $documentNo, string $documentTypeCode, DateTime $documentDate, string $invoiceCurrency, ?string $documentName = null, ?string $documentLanguage = null, ?DateTime $effectiveSpecifiedPeriod = null): ZugferdDocumentBuilder
+     * @param  string                 $documentNo               __BT-1, From MINIMUM__ The document no issued by the seller
+     * @param  string                 $documentTypeCode         __BT-3, From MINIMUM__ The type of the document, See \horstoeko\codelists\ZugferdInvoiceType for details
+     * @param  DateTimeInterface      $documentDate             __BT-2, From MINIMUM__ Date of invoice. The date when the document was issued by the seller
+     * @param  string                 $invoiceCurrency          __BT-5, From MINIMUM__ Code for the invoice currency
+     * @param  string|null            $documentName             __BT-X-2, From EXTENDED__ Document Type. The documenttype (free text)
+     * @param  string|null            $documentLanguage         __BT-X-4, From EXTENDED__ Language indicator. The language code in which the document was written
+     * @param  DateTimeInterface|null $effectiveSpecifiedPeriod __BT-X-6-000, From EXTENDED__ The contractual due date of the invoice
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentInformation(string $documentNo, string $documentTypeCode, DateTimeInterface $documentDate, string $invoiceCurrency, ?string $documentName = null, ?string $documentLanguage = null, ?DateTimeInterface $effectiveSpecifiedPeriod = null): ZugferdDocumentBuilder
     {
         $this->getObjectHelper()->tryCall($this->getInvoiceObject()->getExchangedDocument(), "setID", $this->getObjectHelper()->getIdType($documentNo));
@@ -1911,9 +1911,9 @@
      * Set details of the associated order confirmation.
      *
-     * @param  string        $issuerAssignedId __BT-14, From EN 16931__ An identifier issued by the seller for a referenced sales order (Order confirmation number)
-     * @param  DateTime|null $issueDate        __BT-X-146, From EXTENDED__ Order confirmation date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentSellerOrderReferencedDocument(string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-14, From EN 16931__ An identifier issued by the seller for a referenced sales order (Order confirmation number)
+     * @param  DateTimeInterface|null $issueDate        __BT-X-146, From EXTENDED__ Order confirmation date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentSellerOrderReferencedDocument(string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $sellerorderrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -1927,9 +1927,9 @@
      * Set details of the related buyer order.
      *
-     * @param  string        $issuerAssignedId __BT-13, From MINIMUM__ An identifier issued by the buyer for a referenced order (order number)
-     * @param  DateTime|null $issueDate        __BT-X-147, From EXTENDED__ Date of order
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentBuyerOrderReferencedDocument(?string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-13, From MINIMUM__ An identifier issued by the buyer for a referenced order (order number)
+     * @param  DateTimeInterface|null $issueDate        __BT-X-147, From EXTENDED__ Date of order
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentBuyerOrderReferencedDocument(?string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $buyerorderrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -1943,9 +1943,9 @@
      * Set details of the associated offer
      *
-     * @param  string        $issuerAssignedId __BT-X-403, From EXTENDED__ Offer number
-     * @param  DateTime|null $issueDate        __BT-X-404, From EXTENDED__ Date of offer
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentQuotationReferencedDocument(?string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-403, From EXTENDED__ Offer number
+     * @param  DateTimeInterface|null $issueDate        __BT-X-404, From EXTENDED__ Date of offer
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentQuotationReferencedDocument(?string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $quotationrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -1959,9 +1959,9 @@
      * Set details of the associated contract
      *
-     * @param  string        $issuerAssignedId __BT-12, From BASIC WL__ The contract reference should be assigned once in the context of the specific trade relationship and for a defined period of time (contract number)
-     * @param  DateTime|null $issueDate        __BT-X-26, From EXTENDED__ Contract date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentContractReferencedDocument(?string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-12, From BASIC WL__ The contract reference should be assigned once in the context of the specific trade relationship and for a defined period of time (contract number)
+     * @param  DateTimeInterface|null $issueDate        __BT-X-26, From EXTENDED__ Contract date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentContractReferencedDocument(?string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $contractrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -1982,21 +1982,22 @@
      *    from the bill
      *
-     * @param  string            $issuerAssignedId   __BT-122, From EN 16931__ The identifier of the tender or lot to which the invoice relates, or an identifier specified by the seller for an object on which the invoice is based, or an identifier of the document on which the invoice is based.
-     * @param  string            $typeCode           __BT-122-0, From EN 16931__ Type of referenced document (See codelist UNTDID 1001)
-     *                                               - Code 916 "reference paper" is used to reference the identification of the
-     *                                               document on which the invoice is based - Code 50 "Price / sales catalog response"
-     *                                               is used to reference the tender or the lot - Code 130 "invoice data sheet" is used
-     *                                               to reference an identifier for an object specified by the seller.
-     * @param  string|null       $uriId              __BT-124, From EN 16931__ A means of locating the resource, including the primary access method intended for it, e.g. http:// or ftp://. The storage location of the external document must be used if the buyer requires further information as
-     *                                               supporting documents for the invoiced amounts. External documents are not part of the invoice. Invoice processing should be possible without access to external documents. Access to external documents can entail certain risks.
-     * @param  string|array|null $name               __BT-123, From EN 16931__ A description of the document, e.g. Hourly billing, usage or consumption report, etc.
-     * @param  string|null       $refTypeCode        __BT-18-1, From ENN 16931__ The identifier for the identification scheme of the identifier of the item invoiced. If it is not clear to the recipient which scheme is used for the identifier, an identifier of the scheme should be used, which must be selected from UNTDID 1153 in accordance with the code list entries.
-     * @param  DateTime|null     $issueDate          __BT-X-149, From EXTENDED__ Document date
-     * @param  string|null       $binaryDataFilename __BT-125, From EN 16931__ Contains a file name of an attachment document embedded as a binary object
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentAdditionalReferencedDocument(string $issuerAssignedId, string $typeCode, ?string $uriId = null, $name = null, ?string $refTypeCode = null, ?DateTime $issueDate = null, ?string $binaryDataFilename = null): ZugferdDocumentBuilder
-    {
-        $additionalrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, $uriId, null, $typeCode, $name, $refTypeCode, $issueDate, $binaryDataFilename);
+     * @param  string                 $issuerAssignedId   __BT-122, From EN 16931__ The identifier of the tender or lot to which the invoice relates, or an identifier specified by the seller for an object on which the invoice is based, or an identifier of the document on which the invoice is based.
+     * @param  string                 $typeCode           __BT-122-0, From EN 16931__ Type of referenced document (See codelist UNTDID 1001)
+     *                                                    - Code 916 "reference paper" is used to reference the identification of the
+     *                                                    document on which the invoice is based - Code 50 "Price / sales catalog response"
+     *                                                    is used to reference the tender or the lot - Code 130 "invoice data sheet" is used
+     *                                                    to reference an identifier for an object specified by the seller.
+     * @param  string|null            $uriId              __BT-124, From EN 16931__ A means of locating the resource, including the primary access method intended for it, e.g. http:// or ftp://. The storage location of the external document must be used if the buyer requires further information as
+     *                                                    supporting documents for the invoiced amounts. External documents are not part of the invoice. Invoice processing should be possible without access to external documents. Access to external documents can entail certain risks.
+     * @param  string|array|null      $name               __BT-123, From EN 16931__ A description of the document, e.g. Hourly billing, usage or consumption report, etc.
+     * @param  string|null            $refTypeCode        __BT-18-1, From ENN 16931__ The identifier for the identification scheme of the identifier of the item invoiced. If it is not clear to the recipient which scheme is used for the identifier, an identifier of the scheme should be used, which must be selected from UNTDID 1153 in accordance with the code list entries.
+     * @param  DateTimeInterface|null $issueDate          __BT-X-149, From EXTENDED__ Document date
+     * @param  string|null            $binaryDataFilename __BT-125, From EN 16931__ Contains a file name of an attachment document embedded as a binary object
+     * @param  string|null            $base64EncodedData  __BT-125, From EN 16931__ Contains BASE64-Encoded data an attachment document embedded as a binary object. You must provide $binaryDataFilename
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentAdditionalReferencedDocument(string $issuerAssignedId, string $typeCode, ?string $uriId = null, $name = null, ?string $refTypeCode = null, ?DateTimeInterface $issueDate = null, ?string $binaryDataFilename = null, ?string $base64EncodedData = null): ZugferdDocumentBuilder
+    {
+        $additionalrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, $uriId, null, $typeCode, $name, $refTypeCode, $issueDate, $binaryDataFilename, $base64EncodedData);
 
         $this->getObjectHelper()->tryCall($this->headerTradeAgreement, "addToAdditionalReferencedDocument", $additionalrefdoc);
@@ -2050,5 +2051,5 @@
      * Add details of the calculated object
      *
-     * @param  string $issuerAssignedId __BT-122, From EN 16931__ Depending on the application, this can be a subscription number, a telephone number, a meter reading, a vehicle, a person, etc.
+     * @param  string $issuerAssignedId __BT-18, From EN 16931__ Depending on the application, this can be a subscription number, a telephone number, a meter reading, a vehicle, a person, etc.
      * @param  string $refTypeCode      __BT-18-1, From ENN 16931__ The identifier for the identification scheme of the identifier of the item invoiced. If it is not clear to the recipient which scheme is used for the identifier, an identifier of the scheme should be used, which must be selected from UNTDID 1153 in accordance with the code list entries.
      * @return ZugferdDocumentBuilder
@@ -2057,4 +2058,20 @@
     {
         return $this->addDocumentAdditionalReferencedDocument($issuerAssignedId, ZugferdDocumentType::INVOICING_DATA_SHEET, null, null, $refTypeCode);
+    }
+
+    /**
+     * Add an invoice supporting additional document reference with an URL which specifies the location where the information can be found
+     * The invoice supporting documents can be used to reference both a document number, which should be known to the recipient, and an embedded file (such as a timesheet as a PDF file).
+     *
+     * @param  string            $issuerAssignedId   __BT-122, From EN 16931__ Identification of the document supporting the invoice
+     * @param  string            $attachmentFilename __BT-125, From EN 16931__ Contains a file name of an attachment document embedded as a binary object
+     * @param  string            $base64EncodedData  __BT-125, From EN 16931__ Contains BASE64-Encoded data an attachment document embedded as a binary object. You must provide $binaryDataFilename
+     * @param  string|array|null $name               __BT-123, From EN 16931__ A description of the document, e.g. Hourly billing, usage or consumption report, etc.
+     * @return ZugferdDocumentBuilder
+     * @throws ZugferdUnsupportedMimetype
+     */
+    public function addDocumentInvoiceSupportingDocumentWithBase64Data(string $issuerAssignedId, string $attachmentFilename, string $base64EncodedData, $name = null): ZugferdDocumentBuilder
+    {
+        return $this->addDocumentAdditionalReferencedDocument($issuerAssignedId, ZugferdDocumentType::RELATED_DOCUMENT, null, $name, null, null, $attachmentFilename, $base64EncodedData);
     }
 
@@ -2067,10 +2084,10 @@
      *  - reference is made from a final invoice to previous invoices for advance payments.     *
      *
-     * @param  string        $issuerAssignedId __BT-25, From BASIC WL__ The identification of an invoice previously sent by the seller
-     * @param  string|null   $typeCode         __BT-X-555, From EXTENDED__ Type of previous invoice (code)
-     * @param  DateTime|null $issueDate        __BT-26, From BASIC WL__ Date of the previous invoice
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentInvoiceReferencedDocument(string $issuerAssignedId, ?string $typeCode = null, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-25, From BASIC WL__ The identification of an invoice previously sent by the seller
+     * @param  string|null            $typeCode         __BT-X-555, From EXTENDED__ Type of previous invoice (code)
+     * @param  DateTimeInterface|null $issueDate        __BT-26, From BASIC WL__ Date of the previous invoice
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentInvoiceReferencedDocument(string $issuerAssignedId, ?string $typeCode = null, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $invoicerefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, $typeCode, null, null, $issueDate, null);
@@ -2089,10 +2106,10 @@
      *  - reference is made from a final invoice to previous invoices for advance payments.     *
      *
-     * @param  string        $issuerAssignedId __BT-25, From BASIC WL__ The identification of an invoice previously sent by the seller
-     * @param  string|null   $typeCode         __BT-X-555, From EXTENDED__ Type of previous invoice (code)
-     * @param  DateTime|null $issueDate        __BT-26, From BASIC WL__ Date of the previous invoice
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentInvoiceReferencedDocument(string $issuerAssignedId, ?string $typeCode = null, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-25, From BASIC WL__ The identification of an invoice previously sent by the seller
+     * @param  string|null            $typeCode         __BT-X-555, From EXTENDED__ Type of previous invoice (code)
+     * @param  DateTimeInterface|null $issueDate        __BT-26, From BASIC WL__ Date of the previous invoice
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentInvoiceReferencedDocument(string $issuerAssignedId, ?string $typeCode = null, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $invoicerefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, $typeCode, null, null, $issueDate, null);
@@ -2122,9 +2139,9 @@
      * Details of the associated end customer order
      *
-     * @param  string        $issuerAssignedId __BT-X-150, From EXTENDED__ Order number of the end customer
-     * @param  DateTime|null $issueDate        __BT-X-151, From EXTENDED__ Date of the order issued by the end customer
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentUltimateCustomerOrderReferencedDocument(string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-150, From EXTENDED__ Order number of the end customer
+     * @param  DateTimeInterface|null $issueDate        __BT-X-151, From EXTENDED__ Date of the order issued by the end customer
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentUltimateCustomerOrderReferencedDocument(string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $additionalrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -2138,8 +2155,8 @@
      * Set detailed information on the actual delivery
      *
-     * @param  DateTime|null $date __BT-72, From BASIC WL__ Actual delivery time
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentSupplyChainEvent(?DateTime $date): ZugferdDocumentBuilder
+     * @param  DateTimeInterface|null $date __BT-72, From BASIC WL__ Actual delivery time
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentSupplyChainEvent(?DateTimeInterface $date): ZugferdDocumentBuilder
     {
         $supplyChainevent = $this->getObjectHelper()->getSupplyChainEventType($date);
@@ -2153,9 +2170,9 @@
      * Set Detailed information on the actual delivery
      *
-     * @param  string        $issuerAssignedId __BT-16, From BASIC WL__ Shipping notification reference
-     * @param  DateTime|null $issueDate        __BT-X-200, From EXTENDED__ Shipping notification date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentDespatchAdviceReferencedDocument(?string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-16, From BASIC WL__ Shipping notification reference
+     * @param  DateTimeInterface|null $issueDate        __BT-X-200, From EXTENDED__ Shipping notification date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentDespatchAdviceReferencedDocument(?string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $despatchddvicerefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -2169,9 +2186,9 @@
      * Set detailed information on the associated goods receipt notification
      *
-     * @param  string        $issuerAssignedId __BT-15, From EN 16931__ An identifier for a referenced goods receipt notification (Goods receipt number)
-     * @param  DateTime|null $issueDate        __BT-X-201, From EXTENDED__ Goods receipt date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentReceivingAdviceReferencedDocument(string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-15, From EN 16931__ An identifier for a referenced goods receipt notification (Goods receipt number)
+     * @param  DateTimeInterface|null $issueDate        __BT-X-201, From EXTENDED__ Goods receipt date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentReceivingAdviceReferencedDocument(string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $receivingadvicerefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -2185,9 +2202,9 @@
      * Set detailed information on the associated delivery bill
      *
-     * @param  string        $issuerAssignedId __BT-X-202, From EXTENDED__ Delivery slip number
-     * @param  DateTime|null $issueDate        __BT-X-203, From EXTENDED__ Delivery slip date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentDeliveryNoteReferencedDocument(string $issuerAssignedId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-202, From EXTENDED__ Delivery slip number
+     * @param  DateTimeInterface|null $issueDate        __BT-X-203, From EXTENDED__ Delivery slip date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentDeliveryNoteReferencedDocument(string $issuerAssignedId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $deliverynoterefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, null, null, null, null, $issueDate, null);
@@ -2372,40 +2389,36 @@
      * Add a VAT breakdown (at document level)
      *
-     * @param  string        $categoryCode               __BT-118, From BASIC WL__ Coded description of a sales tax category
-     *
-     *                                                   The following entries from UNTDID 5305 are used (details in brackets):
-     *                                                   - Standard rate (sales tax is due according to the normal procedure)
-     *                                                   - Goods to be taxed according to the zero rate (sales tax is charged with a percentage of zero)
-     *                                                   - Tax exempt (USt./IGIC/IPSI)
-     *                                                   - Reversal of the tax liability (the rules for reversing the tax liability at USt./IGIC/IPSI apply)
-     *                                                   - VAT exempt for intra-community deliveries of goods (USt./IGIC/IPSI not levied due to rules on intra-community deliveries)
-     *                                                   - Free export item, tax not levied (VAT / IGIC/IPSI not levied due to export outside the EU)
-     *                                                   - Services outside the tax scope (sales are not subject to VAT / IGIC/IPSI)
-     *                                                   - Canary Islands general indirect tax (IGIC tax applies)
-     *                                                   - IPSI (tax for Ceuta / Melilla) applies.
-     *
-     *                                                   The codes for the VAT category are as follows:
-     *                                                   - S = sales tax is due at the normal rate
-     *                                                   - Z = goods to be taxed according to the zero rate
-     *                                                   - E = tax exempt
-     *                                                   - AE = reversal of tax liability
-     *                                                   - K = VAT is not shown for intra-community deliveries
-     *                                                   - G = tax not levied due to export outside the EU
-     *                                                   - O = Outside the tax scope
-     *                                                   - L = IGIC (Canary Islands)
-     *                                                   - M = IPSI (Ceuta / Melilla)
-     * @param  string        $typeCode                   __BT-118-0, From BASIC WL__ Coded description of a sales tax category. Note: Fixed value = "VAT"
-     * @param  float         $basisAmount                __BT-116, From BASIC WL__ Tax base amount, Each sales tax breakdown must show a category-specific tax base amount.
-     * @param  float         $calculatedAmount           __BT-117, From BASIC WL__ The total amount to be paid for the relevant VAT category. Note: Calculated by multiplying the amount to be taxed according to the sales tax category by the sales tax rate applicable for the sales tax category concerned
-     * @param  float|null    $rateApplicablePercent      __BT-119, From BASIC WL__ The sales tax rate, expressed as the percentage applicable to the sales tax category in question. Note: The code of the sales tax category and the category-specific sales tax rate must correspond to one another. The value to be given is the percentage. For example, the value 20 is given for 20% (and not 0.2)
-     * @param  string|null   $exemptionReason            __BT-120, From BASIC WL__ Reason for tax exemption (free text)
-     * @param  string|null   $exemptionReasonCode        __BT-121, From BASIC WL__ Reason given in code form for the exemption of the amount from VAT. Note: Code list issued and maintained by the Connecting Europe Facility.
-     * @param  float|null    $lineTotalBasisAmount       __BT-X-262, From EXTENDED__ An amount used as the basis for calculating sales tax, duty or customs duty
-     * @param  float|null    $allowanceChargeBasisAmount __BT-X-263, From EXTENDED__ Total amount Additions and deductions to the tax rate at document level
-     * @param  DateTime|null $taxPointDate               __BT-7-00, From EN 16931__ Date on which tax is due. This is not used in Germany. Instead, the delivery and service date must be specified.
-     * @param  string|null   $dueDateTypeCode            __BT-8, From BASIC WL__ The code for the date on which the VAT becomes relevant for settlement for the seller and for the buyer
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentTax(string $categoryCode, string $typeCode, float $basisAmount, float $calculatedAmount, ?float $rateApplicablePercent = null, ?string $exemptionReason = null, ?string $exemptionReasonCode = null, ?float $lineTotalBasisAmount = null, ?float $allowanceChargeBasisAmount = null, ?DateTime $taxPointDate = null, ?string $dueDateTypeCode = null): ZugferdDocumentBuilder
+     * @param  string                 $categoryCode               __BT-118, From BASIC WL__ Coded description of a sales tax category
+     *                                                            The following entries from UNTDID 5305 are used (details in
+     *                                                            brackets): - Standard rate (sales tax is due according to the
+     *                                                            normal procedure) - Goods to be taxed according to the zero rate
+     *                                                            (sales tax is charged with a percentage of zero) - Tax exempt
+     *                                                            (USt./IGIC/IPSI) - Reversal of the tax liability (the rules for
+     *                                                            reversing the tax liability at USt./IGIC/IPSI apply) - VAT exempt
+     *                                                            for intra-community deliveries of goods (USt./IGIC/IPSI not levied
+     *                                                            due to rules on intra-community deliveries) - Free export item, tax
+     *                                                            not levied (VAT / IGIC/IPSI not levied due to export outside the
+     *                                                            EU) - Services outside the tax scope (sales are not subject to VAT
+     *                                                            / IGIC/IPSI) - Canary Islands general indirect tax (IGIC tax
+     *                                                            applies) - IPSI (tax for Ceuta / Melilla) applies. The codes for
+     *                                                            the VAT category are as follows: - S = sales tax is due at the
+     *                                                            normal rate - Z = goods to be taxed according to the zero rate - E
+     *                                                            = tax exempt - AE = reversal of tax liability - K = VAT is not
+     *                                                            shown for intra-community deliveries - G = tax not levied due to
+     *                                                            export outside the EU - O = Outside the tax scope - L = IGIC
+     *                                                            (Canary Islands) - M = IPSI (Ceuta / Melilla)
+     * @param  string                 $typeCode                   __BT-118-0, From BASIC WL__ Coded description of a sales tax category. Note: Fixed value = "VAT"
+     * @param  float                  $basisAmount                __BT-116, From BASIC WL__ Tax base amount, Each sales tax breakdown must show a category-specific tax base amount.
+     * @param  float                  $calculatedAmount           __BT-117, From BASIC WL__ The total amount to be paid for the relevant VAT category. Note: Calculated by multiplying the amount to be taxed according to the sales tax category by the sales tax rate applicable for the sales tax category concerned
+     * @param  float|null             $rateApplicablePercent      __BT-119, From BASIC WL__ The sales tax rate, expressed as the percentage applicable to the sales tax category in question. Note: The code of the sales tax category and the category-specific sales tax rate must correspond to one another. The value to be given is the percentage. For example, the value 20 is given for 20% (and not 0.2)
+     * @param  string|null            $exemptionReason            __BT-120, From BASIC WL__ Reason for tax exemption (free text)
+     * @param  string|null            $exemptionReasonCode        __BT-121, From BASIC WL__ Reason given in code form for the exemption of the amount from VAT. Note: Code list issued and maintained by the Connecting Europe Facility.
+     * @param  float|null             $lineTotalBasisAmount       __BT-X-262, From EXTENDED__ An amount used as the basis for calculating sales tax, duty or customs duty
+     * @param  float|null             $allowanceChargeBasisAmount __BT-X-263, From EXTENDED__ Total amount Additions and deductions to the tax rate at document level
+     * @param  DateTimeInterface|null $taxPointDate               __BT-7-00, From EN 16931__ Date on which tax is due. This is not used in Germany. Instead, the delivery and service date must be specified.
+     * @param  string|null            $dueDateTypeCode            __BT-8, From BASIC WL__ The code for the date on which the VAT becomes relevant for settlement for the seller and for the buyer
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentTax(string $categoryCode, string $typeCode, float $basisAmount, float $calculatedAmount, ?float $rateApplicablePercent = null, ?string $exemptionReason = null, ?string $exemptionReasonCode = null, ?float $lineTotalBasisAmount = null, ?float $allowanceChargeBasisAmount = null, ?DateTimeInterface $taxPointDate = null, ?string $dueDateTypeCode = null): ZugferdDocumentBuilder
     {
         $tax = $this->getObjectHelper()->getTradeTaxType($categoryCode, $typeCode, $basisAmount, $calculatedAmount, $rateApplicablePercent, $exemptionReason, $exemptionReasonCode, $lineTotalBasisAmount, $allowanceChargeBasisAmount, $taxPointDate, $dueDateTypeCode);
@@ -2452,10 +2465,10 @@
      * Get detailed information on the billing period
      *
-     * @param  DateTime|null $startDate   __BT-73, From BASIC WL__ Start of the billing period
-     * @param  DateTime|null $endDate     __BT-74, From BASIC WL__ End of the billing period
-     * @param  string|null   $description __BT-X-264, From EXTENDED__ Further information of the billing period (Obsolete)
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentBillingPeriod(?DateTime $startDate, ?DateTime $endDate, ?string $description): ZugferdDocumentBuilder
+     * @param  DateTimeInterface|null $startDate   __BT-73, From BASIC WL__ Start of the billing period
+     * @param  DateTimeInterface|null $endDate     __BT-74, From BASIC WL__ End of the billing period
+     * @param  string|null            $description __BT-X-264, From EXTENDED__ Further information of the billing period (Obsolete)
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentBillingPeriod(?DateTimeInterface $startDate, ?DateTimeInterface $endDate, ?string $description): ZugferdDocumentBuilder
     {
         $period = $this->getObjectHelper()->getSpecifiedPeriodType($startDate, $endDate, null, $description);
@@ -2561,11 +2574,11 @@
      * Add a payment term
      *
-     * @param  string|null   $description          __BT-20, From _BASIC WL__ A text description of the payment terms that apply to the payment amount due (including a description of possible penalties). Note: This element can contain multiple lines and multiple conditions.
-     * @param  DateTime|null $dueDate              __BT-9, From BASIC WL__ The date by which payment is due Note: The payment due date reflects the net payment due date. In the case of partial payments, this indicates the first due date of a net payment. The corresponding description of more complex payment terms can be given in BT-20.
-     * @param  string|null   $directDebitMandateID __BT-89, From BASIC WL__ Unique identifier assigned by the payee to reference the direct debit authorization.
-     * @param  float|null    $partialPaymentAmount __BT-X-275, From EXTENDED__ Amount of the partial payment
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentPaymentTerm(?string $description = null, ?DateTime $dueDate = null, ?string $directDebitMandateID = null, ?float $partialPaymentAmount = null): ZugferdDocumentBuilder
+     * @param  string|null            $description          __BT-20, From _BASIC WL__ A text description of the payment terms that apply to the payment amount due (including a description of possible penalties). Note: This element can contain multiple lines and multiple conditions.
+     * @param  DateTimeInterface|null $dueDate              __BT-9, From BASIC WL__ The date by which payment is due Note: The payment due date reflects the net payment due date. In the case of partial payments, this indicates the first due date of a net payment. The corresponding description of more complex payment terms can be given in BT-20.
+     * @param  string|null            $directDebitMandateID __BT-89, From BASIC WL__ Unique identifier assigned by the payee to reference the direct debit authorization.
+     * @param  float|null             $partialPaymentAmount __BT-X-275, From EXTENDED__ Amount of the partial payment
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentPaymentTerm(?string $description = null, ?DateTimeInterface $dueDate = null, ?string $directDebitMandateID = null, ?float $partialPaymentAmount = null): ZugferdDocumentBuilder
     {
         $paymentTerms = $this->getObjectHelper()->getTradePaymentTermsType($description, $dueDate, $directDebitMandateID, $partialPaymentAmount);
@@ -2581,13 +2594,13 @@
      * Add discount Terms to last added payment term
      *
-     * @param  float|null    $calculationPercent         __BT-X-286, From EXTENDED__ Percentage of the down payment
-     * @param  DateTime|null $basisDateTime              __BT-X-282, From EXTENDED__ Due date reference date
-     * @param  float|null    $basisPeriodMeasureValue    __BT-X-283, From EXTENDED__ Maturity period (basis)
-     * @param  string|null   $basisPeriodMeasureUnitCode __BT-X-284, From EXTENDED__ Maturity period (unit)
-     * @param  float|null    $basisAmount                __BT-X-285, From EXTENDED__ Base amount of the payment discount
-     * @param  float|null    $actualDiscountAmount       __BT-X-287, From EXTENDED__ Amount of the payment discount
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDiscountTermsToPaymentTerms(?float $calculationPercent = null, ?DateTime $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $actualDiscountAmount = null): ZugferdDocumentBuilder
+     * @param  float|null             $calculationPercent         __BT-X-286, From EXTENDED__ Percentage of the down payment
+     * @param  DateTimeInterface|null $basisDateTime              __BT-X-282, From EXTENDED__ Due date reference date
+     * @param  float|null             $basisPeriodMeasureValue    __BT-X-283, From EXTENDED__ Maturity period (basis)
+     * @param  string|null            $basisPeriodMeasureUnitCode __BT-X-284, From EXTENDED__ Maturity period (unit)
+     * @param  float|null             $basisAmount                __BT-X-285, From EXTENDED__ Base amount of the payment discount
+     * @param  float|null             $actualDiscountAmount       __BT-X-287, From EXTENDED__ Amount of the payment discount
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDiscountTermsToPaymentTerms(?float $calculationPercent = null, ?DateTimeInterface $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $actualDiscountAmount = null): ZugferdDocumentBuilder
     {
         $discountTerms = $this->getObjectHelper()->getTradePaymentDiscountTermsType($basisDateTime, $basisPeriodMeasureValue, $basisPeriodMeasureUnitCode, $basisAmount, $calculationPercent, $actualDiscountAmount);
@@ -2601,13 +2614,13 @@
      * Add penalty Terms to last added payment term
      *
-     * @param  float|null    $calculationPercent         __BT-X-280, From EXTENDED__ Percentage of the payment surcharge
-     * @param  DateTime|null $basisDateTime              __BT-X-276, From EXTENDED__ Due date reference date
-     * @param  float|null    $basisPeriodMeasureValue    __BT-X-277, From EXTENDED__ Maturity period (basis)
-     * @param  string|null   $basisPeriodMeasureUnitCode __BT-X-278, From EXTENDED__ Maturity period (unit)
-     * @param  float|null    $basisAmount                __BT-X-279, From EXTENDED__ Basic amount of the payment surcharge
-     * @param  float|null    $actualPenaltyAmount        __BT-X-281, From EXTENDED__ Amount of the payment surcharge
-     * @return ZugferdDocumentBuilder
-     */
-    public function addPenaltyTermsToPaymentTerms(?float $calculationPercent = null, ?DateTime $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $actualPenaltyAmount = null): ZugferdDocumentBuilder
+     * @param  float|null             $calculationPercent         __BT-X-280, From EXTENDED__ Percentage of the payment surcharge
+     * @param  DateTimeInterface|null $basisDateTime              __BT-X-276, From EXTENDED__ Due date reference date
+     * @param  float|null             $basisPeriodMeasureValue    __BT-X-277, From EXTENDED__ Maturity period (basis)
+     * @param  string|null            $basisPeriodMeasureUnitCode __BT-X-278, From EXTENDED__ Maturity period (unit)
+     * @param  float|null             $basisAmount                __BT-X-279, From EXTENDED__ Basic amount of the payment surcharge
+     * @param  float|null             $actualPenaltyAmount        __BT-X-281, From EXTENDED__ Amount of the payment surcharge
+     * @return ZugferdDocumentBuilder
+     */
+    public function addPenaltyTermsToPaymentTerms(?float $calculationPercent = null, ?DateTimeInterface $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $actualPenaltyAmount = null): ZugferdDocumentBuilder
     {
         $penaltyTerms = $this->getObjectHelper()->getTradePaymentPenaltyTermsType($basisDateTime, $basisPeriodMeasureValue, $basisPeriodMeasureUnitCode, $basisAmount, $calculationPercent, $actualPenaltyAmount);
@@ -2621,13 +2634,13 @@
      * Add a payment term in XRechnung-Style (in the Form #SKONTO#TAGE=14#PROZENT=1.00#BASISBETRAG=2.53#)
      *
-     * @param  string        $description                __BT-20, From _EN 16931 XRECHNUNG__ Text to add
-     * @param  int[]         $paymentDiscountDays        __BT-20, BR-DE-18, From _EN 16931 XRECHNUNG__ Array of Payment discount days (array of integer)
-     * @param  float[]       $paymentDiscountPercents    __BT-20, BR-DE-18, From _EN 16931 XRECHNUNG__ Array of Payment discount percents (array of decimal)
-     * @param  float[]       $paymentDiscountBaseAmounts __BT-20, BR-DE-18, From _EN 16931 XRECHNUNG__ Array of Payment discount base amounts (array of decimal)
-     * @param  DateTime|null $dueDate                    __BT-9, From EN 16931 XRECHNUNG__ The date by which payment is due Note: The payment due date reflects the net payment due date. In the case of partial payments, this indicates the first due date of a net payment. The corresponding description of more complex payment terms can be given in BT-20.
-     * @param  string|null   $directDebitMandateID       __BT-89, From EN 16931 XRECHNUNG__ Unique identifier assigned by the payee to reference the direct debit authorization.
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentPaymentTermXRechnung(string $description, array $paymentDiscountDays = [], array $paymentDiscountPercents = [], array $paymentDiscountBaseAmounts = [], ?DateTime $dueDate = null, ?string $directDebitMandateID = null): ZugferdDocumentBuilder
+     * @param  string                 $description                __BT-20, From _EN 16931 XRECHNUNG__ Text to add
+     * @param  int[]                  $paymentDiscountDays        __BT-20, BR-DE-18, From _EN 16931 XRECHNUNG__ Array of Payment discount days (array of integer)
+     * @param  float[]                $paymentDiscountPercents    __BT-20, BR-DE-18, From _EN 16931 XRECHNUNG__ Array of Payment discount percents (array of decimal)
+     * @param  float[]                $paymentDiscountBaseAmounts __BT-20, BR-DE-18, From _EN 16931 XRECHNUNG__ Array of Payment discount base amounts (array of decimal)
+     * @param  DateTimeInterface|null $dueDate                    __BT-9, From EN 16931 XRECHNUNG__ The date by which payment is due Note: The payment due date reflects the net payment due date. In the case of partial payments, this indicates the first due date of a net payment. The corresponding description of more complex payment terms can be given in BT-20.
+     * @param  string|null            $directDebitMandateID       __BT-89, From EN 16931 XRECHNUNG__ Unique identifier assigned by the payee to reference the direct debit authorization.
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentPaymentTermXRechnung(string $description, array $paymentDiscountDays = [], array $paymentDiscountPercents = [], array $paymentDiscountBaseAmounts = [], ?DateTimeInterface $dueDate = null, ?string $directDebitMandateID = null): ZugferdDocumentBuilder
     {
         $paymentTermsDescription = [];
@@ -2896,10 +2909,10 @@
      * Set details of a sales order reference.
      *
-     * @param  string        $issuerAssignedId __BT-X-537, From EXTENDED__ Document number of a sales order reference
-     * @param  string        $lineId           __BT-X-538, From EXTENDED__ An identifier for a position within a sales order.
-     * @param  DateTime|null $issueDate        __BT-X-539, From EXTENDED__ Date of sales order
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionSellerOrderReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-537, From EXTENDED__ Document number of a sales order reference
+     * @param  string                 $lineId           __BT-X-538, From EXTENDED__ An identifier for a position within a sales order.
+     * @param  DateTimeInterface|null $issueDate        __BT-X-539, From EXTENDED__ Date of sales order
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionSellerOrderReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $sellerorderrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, $lineId, null, null, null, $issueDate, null);
@@ -2914,10 +2927,10 @@
      * Set details of the related buyer order position.
      *
-     * @param  string        $issuerAssignedId __BT-X-21, From EXTENDED__ An identifier issued by the buyer for a referenced order (order number)
-     * @param  string        $lineId           __BT-132, From EN 16931__ An identifier for a position within an order placed by the buyer. Note: Reference is made to the order reference at the document level.
-     * @param  DateTime|null $issueDate        __BT-X-22, From EXTENDED__ Date of order
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionBuyerOrderReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-21, From EXTENDED__ An identifier issued by the buyer for a referenced order (order number)
+     * @param  string                 $lineId           __BT-132, From EN 16931__ An identifier for a position within an order placed by the buyer. Note: Reference is made to the order reference at the document level.
+     * @param  DateTimeInterface|null $issueDate        __BT-X-22, From EXTENDED__ Date of order
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionBuyerOrderReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $buyerorderrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, $lineId, null, null, null, $issueDate, null);
@@ -2932,10 +2945,10 @@
      * Set details of the associated offer position.
      *
-     * @param  string        $issuerAssignedId __BT-X-310, From EXTENDED__ Offer number
-     * @param  string        $lineId           __BT-X-311, From EXTENDED__ Position identifier within the offer
-     * @param  DateTime|null $issueDate        __BT-X-312, From EXTENDED__ Date of offder
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionQuotationReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-310, From EXTENDED__ Offer number
+     * @param  string                 $lineId           __BT-X-311, From EXTENDED__ Position identifier within the offer
+     * @param  DateTimeInterface|null $issueDate        __BT-X-312, From EXTENDED__ Date of offder
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionQuotationReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $quotationrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, $lineId, null, null, null, $issueDate, null);
@@ -2950,10 +2963,10 @@
      * Set details of the related contract position.
      *
-     * @param  string        $issuerAssignedId __BT-X-24, From EXTENDED__ The contract reference should be assigned once in the context of the specific trade relationship and for a defined period of time (contract number)
-     * @param  string        $lineId           __BT-X-25, From EXTENDED__ Identifier of the according contract position
-     * @param  DateTime|null $issueDate        __BT-X-26, From EXTENDED__ Contract date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionContractReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-24, From EXTENDED__ The contract reference should be assigned once in the context of the specific trade relationship and for a defined period of time (contract number)
+     * @param  string                 $lineId           __BT-X-25, From EXTENDED__ Identifier of the according contract position
+     * @param  DateTimeInterface|null $issueDate        __BT-X-26, From EXTENDED__ Contract date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionContractReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $contractrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, $lineId, null, null, null, $issueDate, null);
@@ -2974,15 +2987,15 @@
      * from the bill
      *
-     * @param  string        $issuerAssignedId   __BT-X-27, From EXTENDED__ The identifier of the tender or lot to which the invoice relates, or an identifier specified by the seller for an object on which the invoice is based, or an identifier of the document on which the invoice is based.
-     * @param  string        $typeCode           __BT-X-30, From EXTENDED__ Type of referenced document (See codelist UNTDID 1001)
-     * @param  string|null   $uriId              __BT-X-28, From EXTENDED__ The Uniform Resource Locator (URL) at which the external document is available. A means of finding the resource including the primary access method intended for it, e.g. http: // or ftp: //. The location of the external document must be used if the buyer needs additional information to support the amounts billed. External documents are not part of the invoice. Access to external documents can involve certain risks.
-     * @param  string|null   $lineId             __BT-X-29, From EXTENDED__ The referenced position identifier in the additional document
-     * @param  string|null   $name               __BT-X-299, From EXTENDED__ A description of the document, e.g. Hourly billing, usage or consumption report, etc.
-     * @param  string|null   $refTypeCode        __BT-X-32, From EXTENDED__ The identifier for the identification scheme of the identifier of the item invoiced. If it is not clear to the recipient which scheme is used for the identifier, an identifier of the scheme should be used, which must be selected from UNTDID 1153 in accordance with the code list entries.
-     * @param  DateTime|null $issueDate          __BT-X-33, From EXTENDED__ Document date
-     * @param  string|null   $binaryDataFilename __BT-X-31, From EXTENDED__ Contains a file name of an attachment document embedded as a binary object
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentPositionAdditionalReferencedDocument(string $issuerAssignedId, string $typeCode, ?string $uriId = null, ?string $lineId = null, ?string $name = null, ?string $refTypeCode = null, ?DateTime $issueDate = null, ?string $binaryDataFilename = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId   __BT-X-27, From EXTENDED__ The identifier of the tender or lot to which the invoice relates, or an identifier specified by the seller for an object on which the invoice is based, or an identifier of the document on which the invoice is based.
+     * @param  string                 $typeCode           __BT-X-30, From EXTENDED__ Type of referenced document (See codelist UNTDID 1001)
+     * @param  string|null            $uriId              __BT-X-28, From EXTENDED__ The Uniform Resource Locator (URL) at which the external document is available. A means of finding the resource including the primary access method intended for it, e.g. http: // or ftp: //. The location of the external document must be used if the buyer needs additional information to support the amounts billed. External documents are not part of the invoice. Access to external documents can involve certain risks.
+     * @param  string|null            $lineId             __BT-X-29, From EXTENDED__ The referenced position identifier in the additional document
+     * @param  string|null            $name               __BT-X-299, From EXTENDED__ A description of the document, e.g. Hourly billing, usage or consumption report, etc.
+     * @param  string|null            $refTypeCode        __BT-X-32, From EXTENDED__ The identifier for the identification scheme of the identifier of the item invoiced. If it is not clear to the recipient which scheme is used for the identifier, an identifier of the scheme should be used, which must be selected from UNTDID 1153 in accordance with the code list entries.
+     * @param  DateTimeInterface|null $issueDate          __BT-X-33, From EXTENDED__ Document date
+     * @param  string|null            $binaryDataFilename __BT-X-31, From EXTENDED__ Contains a file name of an attachment document embedded as a binary object
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentPositionAdditionalReferencedDocument(string $issuerAssignedId, string $typeCode, ?string $uriId = null, ?string $lineId = null, ?string $name = null, ?string $refTypeCode = null, ?DateTimeInterface $issueDate = null, ?string $binaryDataFilename = null): ZugferdDocumentBuilder
     {
         $addrefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, $uriId, $lineId, $typeCode, $name, $refTypeCode, $issueDate, $binaryDataFilename);
@@ -2997,10 +3010,10 @@
      * Add a referennce of a associated end customer order.
      *
-     * @param  string        $issuerAssignedId __BT-X-43, From EXTENDED__ Order number of the end customer
-     * @param  string        $lineId           __BT-X-44, From EXTENDED__ Order item (end customer)
-     * @param  DateTime|null $issueDate        __BT-X-45, From EXTENDED__ Document date of end customer order
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentPositionUltimateCustomerOrderReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-43, From EXTENDED__ Order number of the end customer
+     * @param  string                 $lineId           __BT-X-44, From EXTENDED__ Order item (end customer)
+     * @param  DateTimeInterface|null $issueDate        __BT-X-45, From EXTENDED__ Document date of end customer order
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentPositionUltimateCustomerOrderReferencedDocument(string $issuerAssignedId, string $lineId, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $ultimaterefdoc = $this->getObjectHelper()->getReferencedDocumentType($issuerAssignedId, null, $lineId, null, null, null, $issueDate, null);
@@ -3397,8 +3410,8 @@
      * Detailed information on the actual delivery on position level.
      *
-     * @param  DateTime|null $date __BT-X-85, From EXTENDED__ Actual delivery date
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionSupplyChainEvent(?DateTime $date): ZugferdDocumentBuilder
+     * @param  DateTimeInterface|null $date __BT-X-85, From EXTENDED__ Actual delivery date
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionSupplyChainEvent(?DateTimeInterface $date): ZugferdDocumentBuilder
     {
         $positiondelivery = $this->getObjectHelper()->tryCallAndReturn($this->currentPosition, "getSpecifiedLineTradeDelivery");
@@ -3413,10 +3426,10 @@
      * Detailed information on the associated shipping notification on position level.
      *
-     * @param  string        $issuerAssignedId __BT-X-86, From EXTENDED__ Shipping notification number
-     * @param  string|null   $lineId           __BT-X-87, From EXTENDED__ Shipping notification position
-     * @param  DateTime|null $issueDate        __BT-X-88, From EXTENDED__ Date of Shipping notification number
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionDespatchAdviceReferencedDocument(string $issuerAssignedId, ?string $lineId = null, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-86, From EXTENDED__ Shipping notification number
+     * @param  string|null            $lineId           __BT-X-87, From EXTENDED__ Shipping notification position
+     * @param  DateTimeInterface|null $issueDate        __BT-X-88, From EXTENDED__ Date of Shipping notification number
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionDespatchAdviceReferencedDocument(string $issuerAssignedId, ?string $lineId = null, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $positiondelivery = $this->getObjectHelper()->tryCallAndReturn($this->currentPosition, "getSpecifiedLineTradeDelivery");
@@ -3431,10 +3444,10 @@
      * Detailed information on the associated goods receipt notification.
      *
-     * @param  string        $issuerAssignedId __BT-X-89, From EXTENDED__ Goods receipt number
-     * @param  string|null   $lineId           __BT-X-90, From EXTENDED__ Goods receipt position
-     * @param  DateTime|null $issueDate        __BT-X-91, From EXTENDED__ Date of Goods receipt
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionReceivingAdviceReferencedDocument(string $issuerAssignedId, ?string $lineId = null, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-89, From EXTENDED__ Goods receipt number
+     * @param  string|null            $lineId           __BT-X-90, From EXTENDED__ Goods receipt position
+     * @param  DateTimeInterface|null $issueDate        __BT-X-91, From EXTENDED__ Date of Goods receipt
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionReceivingAdviceReferencedDocument(string $issuerAssignedId, ?string $lineId = null, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $positiondelivery = $this->getObjectHelper()->tryCallAndReturn($this->currentPosition, "getSpecifiedLineTradeDelivery");
@@ -3449,10 +3462,10 @@
      * Detailed information on the associated delivery bill on position level.
      *
-     * @param  string        $issuerAssignedId __BT-X-92, From EXTENDED__ Delivery note number
-     * @param  string|null   $lineId           __BT-X-93, From EXTENDED__ Delivery note position
-     * @param  DateTime|null $issueDate        __BT-X-94, From EXTENDED__ Date of Delivery note
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionDeliveryNoteReferencedDocument(string $issuerAssignedId, ?string $lineId = null, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-92, From EXTENDED__ Delivery note number
+     * @param  string|null            $lineId           __BT-X-93, From EXTENDED__ Delivery note position
+     * @param  DateTimeInterface|null $issueDate        __BT-X-94, From EXTENDED__ Date of Delivery note
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionDeliveryNoteReferencedDocument(string $issuerAssignedId, ?string $lineId = null, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $positiondelivery = $this->getObjectHelper()->tryCallAndReturn($this->currentPosition, "getSpecifiedLineTradeDelivery");
@@ -3488,9 +3501,9 @@
      * Set information about the period relevant for the invoice item. Also known as the invoice line delivery period.
      *
-     * @param  DateTime|null $startDate __BT-134, From BASIC__ Start of the billing period
-     * @param  DateTime|null $endDate   __BT-135, From BASIC__ End of the billing period
-     * @return ZugferdDocumentBuilder
-     */
-    public function setDocumentPositionBillingPeriod(?DateTime $startDate, ?DateTime $endDate): ZugferdDocumentBuilder
+     * @param  DateTimeInterface|null $startDate __BT-134, From BASIC__ Start of the billing period
+     * @param  DateTimeInterface|null $endDate   __BT-135, From BASIC__ End of the billing period
+     * @return ZugferdDocumentBuilder
+     */
+    public function setDocumentPositionBillingPeriod(?DateTimeInterface $startDate, ?DateTimeInterface $endDate): ZugferdDocumentBuilder
     {
         $positionsettlement = $this->getObjectHelper()->tryCallAndReturn($this->currentPosition, "getSpecifiedLineTradeSettlement");
@@ -3568,11 +3581,11 @@
      *  - reference is made from a final invoice to previous invoices for advance payments.     *
      *
-     * @param  string        $issuerAssignedId __BT-X-331, From EXTENDED__ The identification of an invoice previously sent by the seller
-     * @param  string        $lineid           __BT-X-540, From EXTENDED__ Identification of the invoice item
-     * @param  string|null   $typeCode         __BT-X-332, From EXTENDED__ Type of previous invoice (code)
-     * @param  DateTime|null $issueDate        __BT-X-333, From EXTENDED__ Date of the previous invoice
-     * @return ZugferdDocumentBuilder
-     */
-    public function addDocumentPositionInvoiceReferencedDocument(string $issuerAssignedId, string $lineid, ?string $typeCode = null, ?DateTime $issueDate = null): ZugferdDocumentBuilder
+     * @param  string                 $issuerAssignedId __BT-X-331, From EXTENDED__ The identification of an invoice previously sent by the seller
+     * @param  string                 $lineid           __BT-X-540, From EXTENDED__ Identification of the invoice item
+     * @param  string|null            $typeCode         __BT-X-332, From EXTENDED__ Type of previous invoice (code)
+     * @param  DateTimeInterface|null $issueDate        __BT-X-333, From EXTENDED__ Date of the previous invoice
+     * @return ZugferdDocumentBuilder
+     */
+    public function addDocumentPositionInvoiceReferencedDocument(string $issuerAssignedId, string $lineid, ?string $typeCode = null, ?DateTimeInterface $issueDate = null): ZugferdDocumentBuilder
     {
         $positionsettlement = $this->getObjectHelper()->tryCallAndReturn($this->currentPosition, "getSpecifiedLineTradeSettlement");
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentPdfBuilderAbstract.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentPdfBuilderAbstract.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentPdfBuilderAbstract.php	(revision 8540)
@@ -54,4 +54,14 @@
 
     /**
+     * Constants for PDF Conformance Levels
+     * 'Accessible', 'Basic', 'Unicode
+     */
+    public const PDFA_CONFORMANCE_LEVEL_ACCESSIBLE = "A";
+
+    public const PDFA_CONFORMANCE_LEVEL_BASIC = "B";
+
+    public const PDFA_CONFORMANCE_LEVEL_UNICODE = "U";
+
+    /**
      * Additional creator tool (e.g. the ERP software that called the PHP library)
      *
@@ -129,4 +139,11 @@
      */
     private $attachmentPaneVisibility = true;
+
+    /**
+     * Internal status of PDF/A conformance level
+     *
+     * @var string
+     */
+    private $pdfAConformanceLevel = "B";
 
     /**
@@ -275,4 +292,61 @@
     {
         return $this->setAttachmentRelationshipType(static::AF_RELATIONSHIP_SOURCE);
+    }
+
+    /**
+     * Set the PDF/A Conformance Level. Valid values are "A", "B" and "U"
+     *
+     * @param  string $pdfAConformanceLevel
+     * @return static
+     */
+    public function setPdfAConformanceLevel(string $pdfAConformanceLevel)
+    {
+        if (!in_array($pdfAConformanceLevel, [self::PDFA_CONFORMANCE_LEVEL_ACCESSIBLE, self::PDFA_CONFORMANCE_LEVEL_BASIC, self::PDFA_CONFORMANCE_LEVEL_UNICODE])) {
+            $pdfAConformanceLevel = self::PDFA_CONFORMANCE_LEVEL_BASIC;
+        }
+
+        $this->pdfAConformanceLevel = $pdfAConformanceLevel;
+
+        return $this;
+    }
+
+    /**
+     * Returns the PDF/A Conformance Level. This will return "A", "B" or "U"
+     *
+     * @return string
+     */
+    public function getPdfAConformanceLevel(): string
+    {
+        return $this->pdfAConformanceLevel;
+    }
+
+    /**
+     * Set the PDF/A Conformane Level to "Accessible" (A)
+     *
+     * @return static
+     */
+    public function setPdfAConformanceLevelToAccessible()
+    {
+        return $this->setPdfAConformanceLevel(self::PDFA_CONFORMANCE_LEVEL_ACCESSIBLE);
+    }
+
+    /**
+     * Set the PDF/A Conformane Level to "Basic" (B)
+     *
+     * @return static
+     */
+    public function setPdfAConformanceLevelToBasic()
+    {
+        return $this->setPdfAConformanceLevel(self::PDFA_CONFORMANCE_LEVEL_BASIC);
+    }
+
+    /**
+     * Set the PDF/A Conformane Level to "Unicode" (U)
+     *
+     * @return static
+     */
+    public function setPdfAConformanceLevelToUnicode()
+    {
+        return $this->setPdfAConformanceLevel(self::PDFA_CONFORMANCE_LEVEL_UNICODE);
     }
 
@@ -584,5 +658,5 @@
         // Set flag to always show the attachment pane
 
-        if ($this->getAttachmentPaneIsVisible() === true) {
+        if ($this->getAttachmentPaneIsVisible()) {
             $this->pdfWriter->openAttachmentPane();
         }
@@ -631,4 +705,5 @@
 
         $descPdfAid = $descriptionNodes[2];
+        $descPdfAid->children('pdfaid', true)->{'conformance'} = $this->getPdfAConformanceLevel();
         $this->pdfWriter->addMetadataDescriptionNode($descPdfAid->asXML());
 
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentReader.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentReader.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdDocumentReader.php	(revision 8540)
@@ -2052,8 +2052,10 @@
      * @param  string|null   $refTypeCode        __BT-, From __ The identifier for the identification scheme of the identifier of the item invoiced. If it is not clear to the recipient which scheme is used for the identifier, an identifier of the scheme should be used, which must be selected from UNTDID 1153 in accordance with the code list entries.
      * @param  DateTime|null $issueDate          __BT-X-149, From EXTENDED__ Document date
-     * @param  string|null   $binaryDataFilename __BT-125, From EN 16931__ Contains a file name of an attachment document embedded as a binary object
-     * @return ZugferdDocumentReader
-     */
-    public function getDocumentAdditionalReferencedDocument(?string &$issuerAssignedId, ?string &$typeCode, ?string &$uriId, ?array &$name, ?string &$refTypeCode, ?DateTime &$issueDate, ?string &$binaryDataFilename): ZugferdDocumentReader
+     * @param  string|null   $binaryDataFilename __BT-125, From EN 16931__ Contains the content located at the path $this->binarydatadirectory + filename of the embedded binary object Attachment
+     * @param  string|null   $binaryMimeCode     __BT-125-1 From _EN 16931__ Contains the mime code of the embedded binary object Attachment
+     * @param  string|null   $binaryFilename     __BT-125-2 From _EN 16931__ Contains the filename of the embedded binary object Attachment
+     * @return ZugferdDocumentReader
+     */
+    public function getDocumentAdditionalReferencedDocument(?string &$issuerAssignedId, ?string &$typeCode, ?string &$uriId, ?array &$name, ?string &$refTypeCode, ?DateTime &$issueDate, ?string &$binaryDataFilename, ?string &$binaryMimeCode = null, ?string &$binaryFilename = null): ZugferdDocumentReader
     {
         $addRefDoc = $this->getInvoiceValueByPath("getSupplyChainTradeTransaction.getApplicableHeaderTradeAgreement.getAdditionalReferencedDocument", []);
@@ -2070,14 +2072,15 @@
         );
 
-        $binaryDataFilename = $this->getInvoiceValueByPathFrom($addRefDoc, "getAttachmentBinaryObject.getFilename", "");
-        $binarydata = $this->getInvoiceValueByPathFrom($addRefDoc, "getAttachmentBinaryObject.value", "");
+        $binaryMimeCode = $this->getInvoiceValueByPathFrom($addRefDoc, "getAttachmentBinaryObject.getMimeCode", null);
+        $binaryFilename = $this->getInvoiceValueByPathFrom($addRefDoc, "getAttachmentBinaryObject.getFilename", null);
+        $binaryObject = $this->getInvoiceValueByPathFrom($addRefDoc, "getAttachmentBinaryObject.value", null);
 
         if (
-            StringUtils::stringIsNullOrEmpty($binaryDataFilename) === false
-            && StringUtils::stringIsNullOrEmpty($binarydata) === false
+            StringUtils::stringIsNullOrEmpty($binaryFilename) === false
+            && StringUtils::stringIsNullOrEmpty($binaryObject) === false
             && StringUtils::stringIsNullOrEmpty($this->binarydatadirectory) === false
         ) {
-            $binaryDataFilename = PathUtils::combinePathWithFile($this->binarydatadirectory, $binaryDataFilename);
-            FileUtils::base64ToFile($binarydata, $binaryDataFilename);
+            $binaryDataFilename = PathUtils::combinePathWithFile($this->binarydatadirectory, $binaryFilename);
+            FileUtils::base64ToFile($binaryObject, $binaryDataFilename);
         } else {
             $binaryDataFilename = "";
@@ -4140,5 +4143,5 @@
     {
         $result = [];
-        $isFlat = count($methods) == 1;
+        $isFlat = count($methods) === 1;
         $value = $this->getObjectHelper()->ensureArray($value);
 
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdKositValidator.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdKositValidator.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdKositValidator.php	(revision 8540)
@@ -807,10 +807,15 @@
 
             $responseStatusCode = curl_getinfo($httpConnection, CURLINFO_HTTP_CODE);
-
-            curl_close($httpConnection);
+            $responseError = curl_error($httpConnection);
+
+            if (PHP_VERSION_ID >= 80000) {
+                unset($httpConnection);
+            } else {
+                curl_close($httpConnection);
+            }
 
             if (($responseStatusCode < 200) || ($responseStatusCode >= 400)) {
                 $this->addToMessageBag("Failed to connect to the host where the Validator is running in daemon mode");
-                $this->addToMessageBag(curl_error($httpConnection));
+                $this->addToMessageBag($responseError);
                 return false;
             }
@@ -903,5 +908,5 @@
         }
 
-        if ($numFilesExists == $zipArchive->numFiles) {
+        if ($numFilesExists === $zipArchive->numFiles) {
             return true;
         }
@@ -1004,5 +1009,9 @@
             $responseStatusCode = curl_getinfo($httpConnection, CURLINFO_HTTP_CODE);
 
-            curl_close($httpConnection);
+            if (PHP_VERSION_ID >= 80000) {
+                unset($httpConnection);
+            } else {
+                curl_close($httpConnection);
+            }
 
             if (($responseStatusCode < 200) || ($responseStatusCode >= 400)) {
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdObjectHelper.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdObjectHelper.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdObjectHelper.php	(revision 8540)
@@ -11,4 +11,6 @@
 
 use DateTime;
+use DateTimeInterface;
+use finfo;
 use horstoeko\mimedb\MimeDb;
 use horstoeko\stringmanagement\FileUtils;
@@ -53,5 +55,4 @@
         "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
         "application/vnd.oasis.opendocument.spreadsheet",
-        "application/xml",
     ];
 
@@ -204,8 +205,8 @@
      * Get formatted issue date
      *
-     * @param  DateTime|null $dateTime
-     * @return object|null
-     */
-    public function getFormattedDateTimeType(?DateTime $dateTime = null): ?object
+     * @param  DateTimeInterface|null $dateTime
+     * @return object|null
+     */
+    public function getFormattedDateTimeType(?DateTimeInterface $dateTime = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -226,8 +227,8 @@
      * Get formatted issue date
      *
-     * @param  DateTime|null $dateTime
-     * @return object|null
-     */
-    public function getDateTimeType(?DateTime $dateTime = null): ?object
+     * @param  DateTimeInterface|null $dateTime
+     * @return object|null
+     */
+    public function getDateTimeType(?DateTimeInterface $dateTime = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -248,8 +249,8 @@
      * Get date
      *
-     * @param  DateTime|null $dateTime
-     * @return object|null
-     */
-    public function getDateType(?DateTime $dateTime = null): ?object
+     * @param  DateTimeInterface|null $dateTime
+     * @return object|null
+     */
+    public function getDateType(?DateTimeInterface $dateTime = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -440,11 +441,11 @@
      * Get Specified Period type
      *
-     * @param  DateTime|null $startDate
-     * @param  DateTime|null $endDate
-     * @param  DateTime|null $completeDate
-     * @param  string|null   $description
-     * @return object|null
-     */
-    public function getSpecifiedPeriodType(?DateTime $startDate = null, ?DateTime $endDate = null, ?DateTime $completeDate = null, ?string $description = null): ?object
+     * @param  DateTimeInterface|null $startDate
+     * @param  DateTimeInterface|null $endDate
+     * @param  DateTimeInterface|null $completeDate
+     * @param  string|null            $description
+     * @return object|null
+     */
+    public function getSpecifiedPeriodType(?DateTimeInterface $startDate = null, ?DateTimeInterface $endDate = null, ?DateTimeInterface $completeDate = null, ?string $description = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -488,15 +489,16 @@
      * Get a reference document object
      *
-     * @param  string|null       $issuerAssignedId
-     * @param  string|null       $uriId
-     * @param  string|null       $lineId
-     * @param  string|null       $typeCode
-     * @param  string|array|null $name
-     * @param  string|null       $refTypeCode
-     * @param  DateTime|null     $issueDate
-     * @param  string|null       $binaryDataFilename
-     * @return object|null
-     */
-    public function getReferencedDocumentType(?string $issuerAssignedId = null, ?string $uriId = null, ?string $lineId = null, ?string $typeCode = null, $name = null, ?string $refTypeCode = null, ?DateTime $issueDate = null, ?string $binaryDataFilename = null): ?object
+     * @param  string|null            $issuerAssignedId
+     * @param  string|null            $uriId
+     * @param  string|null            $lineId
+     * @param  string|null            $typeCode
+     * @param  string|array|null      $name
+     * @param  string|null            $refTypeCode
+     * @param  DateTimeInterface|null $issueDate
+     * @param  string|null            $binaryDataFilename
+     * @param  string|null            $base64EncodedData
+     * @return object|null
+     */
+    public function getReferencedDocumentType(?string $issuerAssignedId = null, ?string $uriId = null, ?string $lineId = null, ?string $typeCode = null, $name = null, ?string $refTypeCode = null, ?DateTimeInterface $issueDate = null, ?string $binaryDataFilename = null, ?string $base64EncodedData = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -517,22 +519,77 @@
         }
 
-        if (StringUtils::stringIsNullOrEmpty($binaryDataFilename) === false && FileUtils::fileExists($binaryDataFilename)) {
+        $loadedFromBase64 = false;
+
+        if (
+            StringUtils::stringIsNullOrEmpty($binaryDataFilename) === false &&
+            StringUtils::stringIsNullOrEmpty($base64EncodedData) === false &&
+            base64_encode($base64EncodedData) !== false
+        ) {
+            $finfo = new finfo();
+            $mimetype = $finfo->buffer(base64_decode($base64EncodedData), FILEINFO_MIME_TYPE);
+            if ($mimetype === false) {
+                throw new ZugferdUnsupportedMimetype('of ' . $binaryDataFilename);
+            }
+
+            $fileExtension = FileUtils::getFileExtension($binaryDataFilename);
+            if ($mimetype === 'text/plain' && strtolower($fileExtension) === 'csv') {
+                $mimetype = 'text/csv';
+            }
+
+            /**
+             * PHP 8.0 may misdetect CSV files as "application/csv"; normalize to the standard "text/csv"
+             */
+            if (PHP_VERSION_ID >= 80000 && PHP_VERSION_ID < 81000 && $mimetype === 'application/csv') {
+                $mimetype = 'text/csv';
+            }
+
+            if (!in_array($mimetype, self::SUPPORTEDTMIMETYPES)) {
+                throw new ZugferdUnsupportedMimetype($mimetype);
+            }
+
+            $fileExtension = (new MimeDb())->findFirstFileExtensionByMimeType($mimetype);
+            if (is_null($fileExtension)) {
+                throw new ZugferdUnsupportedMimetype($mimetype);
+            }
+
+            $this->tryCall(
+                $referencedDocumentType,
+                'setAttachmentBinaryObject',
+                $this->getBinaryObjectType(
+                    $base64EncodedData,
+                    $mimetype,
+                    FileUtils::getFilenameWithExtension(
+                        FileUtils::changeFileExtension(
+                            FileUtils::getFilenameWithExtension($binaryDataFilename),
+                            $fileExtension,
+                        ),
+                    ),
+                ),
+            );
+            $loadedFromBase64 = true;
+        }
+
+        if (
+            $loadedFromBase64 === false &&
+            StringUtils::stringIsNullOrEmpty($binaryDataFilename) === false &&
+            FileUtils::fileExists($binaryDataFilename)
+        ) {
             $mimeDb = new MimeDb();
             $mimeTypes = $mimeDb->findAllMimeTypesByExtension(FileUtils::getFileExtension($binaryDataFilename));
-            if (!is_null($mimeTypes)) {
-                $mimeTypesSupported = array_intersect($mimeTypes, self::SUPPORTEDTMIMETYPES);
-                if ($mimeTypesSupported !== []) {
-                    $content = FileUtils::fileToBase64($binaryDataFilename);
-                    $this->tryCall(
-                        $referencedDocumentType,
-                        'setAttachmentBinaryObject',
-                        $this->getBinaryObjectType($content, $mimeTypesSupported[0], FileUtils::getFilenameWithExtension($binaryDataFilename))
-                    );
-                } else {
-                    throw new ZugferdUnsupportedMimetype();
-                }
-            } else {
-                throw new ZugferdUnsupportedMimetype();
+            if (is_null($mimeTypes)) {
+                throw new ZugferdUnsupportedMimetype('of ' . $binaryDataFilename);
             }
+
+            $mimeTypesSupported = array_intersect($mimeTypes, self::SUPPORTEDTMIMETYPES);
+            if ($mimeTypesSupported === []) {
+                throw new ZugferdUnsupportedMimetype(implode(', ', $mimeTypes));
+            }
+
+            $content = FileUtils::fileToBase64($binaryDataFilename);
+            $this->tryCall(
+                $referencedDocumentType,
+                'setAttachmentBinaryObject',
+                $this->getBinaryObjectType($content, $mimeTypesSupported[0], FileUtils::getFilenameWithExtension($binaryDataFilename))
+            );
         }
 
@@ -824,8 +881,8 @@
      * Undocumented function
      *
-     * @param  DateTime|null $date
-     * @return object|null
-     */
-    public function getSupplyChainEventType(?DateTime $date = null): ?object
+     * @param  DateTimeInterface|null $date
+     * @return object|null
+     */
+    public function getSupplyChainEventType(?DateTimeInterface $date = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -857,5 +914,5 @@
         // last 4 digits are the maximum number of digits to be shown.
 
-        $id = substr($id, 0, 6) . substr($id, -4);
+        $id = strlen($id) > 4 ? substr($id, 0, 6) . substr($id, -4) : $id;
 
         $tradeSettlementFinancialCardType = $this->createClassInstance('ram\TradeSettlementFinancialCardType');
@@ -952,11 +1009,11 @@
      * Get instance of TradePaymentTermsType
      *
-     * @param  null|string   $description
-     * @param  null|DateTime $dueDate
-     * @param  null|string   $directDebitMandateID
-     * @param  null|float    $partialPaymentAmount
+     * @param  null|string            $description
+     * @param  null|DateTimeInterface $dueDate
+     * @param  null|string            $directDebitMandateID
+     * @param  null|float             $partialPaymentAmount
      * @return null|object
      */
-    public function getTradePaymentTermsType(?string $description = null, ?DateTime $dueDate = null, ?string $directDebitMandateID = null, ?float $partialPaymentAmount = null): ?object
+    public function getTradePaymentTermsType(?string $description = null, ?DateTimeInterface $dueDate = null, ?string $directDebitMandateID = null, ?float $partialPaymentAmount = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -977,13 +1034,13 @@
      * Get instance of TradePaymentDiscountTermsType
      *
-     * @param  DateTime|null $basisDateTime
-     * @param  float|null    $basisPeriodMeasureValue
-     * @param  string|null   $basisPeriodMeasureUnitCode
-     * @param  float|null    $basisAmount
-     * @param  float|null    $calculationPercent
-     * @param  float|null    $actualDiscountAmount
-     * @return object|null
-     */
-    public function getTradePaymentDiscountTermsType(?DateTime $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $calculationPercent = null, ?float $actualDiscountAmount = null): ?object
+     * @param  DateTimeInterface|null $basisDateTime
+     * @param  float|null             $basisPeriodMeasureValue
+     * @param  string|null            $basisPeriodMeasureUnitCode
+     * @param  float|null             $basisAmount
+     * @param  float|null             $calculationPercent
+     * @param  float|null             $actualDiscountAmount
+     * @return object|null
+     */
+    public function getTradePaymentDiscountTermsType(?DateTimeInterface $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $calculationPercent = null, ?float $actualDiscountAmount = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -1005,13 +1062,13 @@
      * Get instance of TradePaymentPenaltyTermsType
      *
-     * @param  DateTime|null $basisDateTime
-     * @param  float|null    $basisPeriodMeasureValue
-     * @param  string|null   $basisPeriodMeasureUnitCode
-     * @param  float|null    $basisAmount
-     * @param  float|null    $calculationPercent
-     * @param  float|null    $actualPenaltyAmount
-     * @return object|null
-     */
-    public function getTradePaymentPenaltyTermsType(?DateTime $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $calculationPercent = null, ?float $actualPenaltyAmount = null): ?object
+     * @param  DateTimeInterface|null $basisDateTime
+     * @param  float|null             $basisPeriodMeasureValue
+     * @param  string|null            $basisPeriodMeasureUnitCode
+     * @param  float|null             $basisAmount
+     * @param  float|null             $calculationPercent
+     * @param  float|null             $actualPenaltyAmount
+     * @return object|null
+     */
+    public function getTradePaymentPenaltyTermsType(?DateTimeInterface $basisDateTime = null, ?float $basisPeriodMeasureValue = null, ?string $basisPeriodMeasureUnitCode = null, ?float $basisAmount = null, ?float $calculationPercent = null, ?float $actualPenaltyAmount = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -1034,18 +1091,18 @@
      * Sales tax breakdown, UmsatzsteueraufschlÃŒsselung
      *
-     * @param  string|null   $categoryCode
-     * @param  string|null   $typeCode
-     * @param  float|null    $basisAmount
-     * @param  float|null    $calculatedAmount
-     * @param  float|null    $rateApplicablePercent
-     * @param  string|null   $exemptionReason
-     * @param  string|null   $exemptionReasonCode
-     * @param  float|null    $lineTotalBasisAmount
-     * @param  float|null    $allowanceChargeBasisAmount
-     * @param  DateTime|null $taxPointDate
-     * @param  string|null   $dueDateTypeCode
-     * @return object|null
-     */
-    public function getTradeTaxType(?string $categoryCode = null, ?string $typeCode = null, ?float $basisAmount = null, ?float $calculatedAmount = null, ?float $rateApplicablePercent = null, ?string $exemptionReason = null, ?string $exemptionReasonCode = null, ?float $lineTotalBasisAmount = null, ?float $allowanceChargeBasisAmount = null, ?DateTime $taxPointDate = null, ?string $dueDateTypeCode = null): ?object
+     * @param  string|null            $categoryCode
+     * @param  string|null            $typeCode
+     * @param  float|null             $basisAmount
+     * @param  float|null             $calculatedAmount
+     * @param  float|null             $rateApplicablePercent
+     * @param  string|null            $exemptionReason
+     * @param  string|null            $exemptionReasonCode
+     * @param  float|null             $lineTotalBasisAmount
+     * @param  float|null             $allowanceChargeBasisAmount
+     * @param  DateTimeInterface|null $taxPointDate
+     * @param  string|null            $dueDateTypeCode
+     * @return object|null
+     */
+    public function getTradeTaxType(?string $categoryCode = null, ?string $typeCode = null, ?float $basisAmount = null, ?float $calculatedAmount = null, ?float $rateApplicablePercent = null, ?string $exemptionReason = null, ?string $exemptionReasonCode = null, ?float $lineTotalBasisAmount = null, ?float $allowanceChargeBasisAmount = null, ?DateTimeInterface $taxPointDate = null, ?string $dueDateTypeCode = null): ?object
     {
         if (self::isAllNullOrEmpty(func_get_args())) {
@@ -1253,5 +1310,5 @@
         $this->tryCall($doclinedoc, "setLineStatusCode", $this->getCodeType($lineStatusCode));
         $this->tryCall($doclinedoc, "setLineStatusReasonCode", $this->getCodeType($lineStatusReasonCode));
-        if ($isTextPosition == false) {
+        if ($isTextPosition === false) {
             $this->tryCall($supplyChainTradeLineItemType, "setSpecifiedLineTradeAgreement", $lineTradeAgreementType);
             $this->tryCall($supplyChainTradeLineItemType, "setSpecifiedLineTradeDelivery", $lineTradeDeliveryType);
@@ -1437,11 +1494,11 @@
      * Undocumented function
      *
-     * @param  string|null   $sourceCurrencyCode
-     * @param  string|null   $targetCurrencyCode
-     * @param  float|null    $rate
-     * @param  DateTime|null $rateDateTime
-     * @return object|null
-     */
-    public function getTaxApplicableTradeCurrencyExchangeType(?string $sourceCurrencyCode = null, ?string $targetCurrencyCode = null, ?float $rate = null, ?DateTime $rateDateTime = null): ?object
+     * @param  string|null            $sourceCurrencyCode
+     * @param  string|null            $targetCurrencyCode
+     * @param  float|null             $rate
+     * @param  DateTimeInterface|null $rateDateTime
+     * @return object|null
+     */
+    public function getTaxApplicableTradeCurrencyExchangeType(?string $sourceCurrencyCode = null, ?string $targetCurrencyCode = null, ?float $rate = null, ?DateTimeInterface $rateDateTime = null): ?object
     {
         if (self::isOneNullOrEmpty(func_get_args())) {
@@ -1633,5 +1690,5 @@
 
         foreach ($methods as $index => $method) {
-            if ($index == count($methods) - 1) {
+            if ($index === count($methods) - 1) {
                 $this->tryCall($instance, $method, $value);
             } else {
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdPdfWriter.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdPdfWriter.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdPdfWriter.php	(revision 8540)
@@ -142,5 +142,5 @@
         if ('' == $mimetype) {
             $mimetype = mime_content_type($file);
-            if ($mimetype === '' || $mimetype === '0' || $mimetype === false) {
+            if (in_array($mimetype, ['', '0', false], true)) {
                 $mimetype = 'application/octet-stream';
             }
@@ -477,4 +477,73 @@
 
     /**
+     * Override for PDF-A/3 conformant links.
+     *
+     * This fixes the following issues:
+     * - Fix 1: Annotation dictionaries need /F and should be printable => /F 4
+     * - Fix 2: Ensure our PDF/A-compliant /F stays effective and avoid duplicate /F keys
+     *
+     * @param  int  $n
+     * @return void
+     */
+    protected function _putlinks($n)
+    {
+        foreach ($this->PageLinks[$n] as $pl) {
+            $this->_newobj();
+            $rect = sprintf('%.2F %.2F %.2F %.2F', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3]);
+            $this->_put('<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /F 4', false); // Fix 1
+
+            if (is_string($pl[4])) {
+                if (isset($pl['importedLink'])) {
+                    $this->_put('/A <</S /URI /URI ('.$this->_escape($pl[4]).')>>');
+                    $values = $pl['importedLink']['pdfObject']->value;
+
+                    foreach ($values as $name => $entry) {
+                        if ('F' === $name) { // Fix 2
+                            continue;
+                        }
+
+                        $this->_put('/'.$name.' ', false);
+                        $this->writePdfType($entry);
+                    }
+
+                    if (isset($pl['quadPoints'])) {
+                        $s = '/QuadPoints[';
+                        foreach ($pl['quadPoints'] as $value) {
+                            $s .= sprintf('%.2F ', $value);
+                        }
+
+                        $s .= ']';
+                        $this->_put($s);
+                    }
+                } else {
+                    $this->_put('/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>');
+                    $this->_put('/Border [0 0 0]', false);
+                }
+
+                $this->_put('>>');
+            } else {
+                $this->_put('/Border [0 0 0] ', false);
+                $l = $this->links[$pl[4]];
+
+                if (isset($this->PageInfo[$l[0]]['size'])) {
+                    $h = $this->PageInfo[$l[0]]['size'][1];
+                } else {
+                    $h = ('P' === $this->DefOrientation)
+                        ? $this->DefPageSize[1] * $this->k
+                        : $this->DefPageSize[0] * $this->k;
+                }
+
+                $this->_put(sprintf(
+                    '/Dest [%d 0 R /XYZ 0 %.2F null]>>',
+                    $this->PageInfo[$l[0]]['n'],
+                    $h - $l[1] * $this->k
+                ));
+            }
+
+            $this->_put('endobj');
+        }
+    }
+
+    /**
      * Generate metadata string.
      *
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdProfileResolver.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdProfileResolver.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdProfileResolver.php	(revision 8540)
@@ -43,4 +43,6 @@
             libxml_clear_errors();
             $xmldocument = new SimpleXMLElement($xmlContent);
+            $xmldocument->registerXPathNamespace("rsm", "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100");
+            $xmldocument->registerXPathNamespace("ram", "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100");
             $typeelement = $xmldocument->xpath('/rsm:CrossIndustryInvoice/rsm:ExchangedDocumentContext/ram:GuidelineSpecifiedDocumentContextParameter/ram:ID');
             if (libxml_get_last_error()) {
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdProfiles.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdProfiles.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/ZugferdProfiles.php	(revision 8540)
@@ -72,5 +72,5 @@
 
     /**
-     * Internal constant that identifies the XRECHNUNG profile version 2.3 (germany only)
+     * Internal constant that identifies the XRECHNUNG profile version 3.0 (germany only)
      */
     public const PROFILE_XRECHNUNG_3 = 10;
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/quick/ZugferdQuickDescriptor.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/quick/ZugferdQuickDescriptor.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/src/quick/ZugferdQuickDescriptor.php	(revision 8540)
@@ -519,5 +519,5 @@
     public function doAddTradeLineItem(string $lineId, string $productName, float $unitPrice, float $quantity, string $unitCode, float $allowanceChargeAmount, string $allowanceChargeReason, string $taxCategoryCode, string $taxTypeCode, float $taxPercent): ZugferdQuickDescriptor
     {
-        $hasChargeAmountIsAllowance = $allowanceChargeAmount != 0.0;
+        $hasChargeAmountIsAllowance = $allowanceChargeAmount !== 0.0;
         $allowanceChargeAmountIsAllowance = $allowanceChargeAmount < 0.0;
         $allowanceAmount = $allowanceChargeAmountIsAllowance ? abs($allowanceChargeAmount) : 0.0;
@@ -533,5 +533,5 @@
         $this->setDocumentPositionLineSummation($lineTotalAmount);
 
-        if ($hasChargeAmountIsAllowance == true) {
+        if ($hasChargeAmountIsAllowance) {
             $this->addDocumentPositionAllowanceCharge($allowanceChargeAmount, $allowanceChargeAmountIsAllowance === false, null, null, null, $allowanceChargeReason);
         }
@@ -647,5 +647,5 @@
     public function doAddTradeAllowanceCharge(float $actualAmount, string $reason, string $taxCategoryCode, string $taxTypeCode, float $taxPercent): ZugferdQuickDescriptor
     {
-        if ($actualAmount == 0.0) {
+        if ($actualAmount === 0.0) {
             return $this;
         }
@@ -655,5 +655,5 @@
         $chargeAmount = $allowanceChargeAmountIsAllowance === false ? abs($actualAmount) : 0.0;
 
-        $this->addDocumentAllowanceCharge(abs($actualAmount), $allowanceChargeAmountIsAllowance == false, $taxCategoryCode, $taxTypeCode, $taxPercent, null, null, null, null, null, null, $reason);
+        $this->addDocumentAllowanceCharge(abs($actualAmount), $allowanceChargeAmountIsAllowance === false, $taxCategoryCode, $taxTypeCode, $taxPercent, null, null, null, null, null, null, $reason);
 
         $this->addToInternalVatBuffer(
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/BuilderExtendedTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/BuilderExtendedTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/BuilderExtendedTest.php	(revision 8540)
@@ -1852,5 +1852,5 @@
         $this->assertXPathValueWithIndexAndAttribute('/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime/udt:DateTimeString', 5, (new DateTime())->format("Ymd"), "format", "102");
         $this->assertXPathValueWithIndex('/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:DirectDebitMandateID', 5, "mandate with partial payment amount");
-        $this->assertXPathValueWithIndex('/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:PartialPaymentAmount', 0, 100.0);
+        $this->assertXPathValueWithIndex('/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:PartialPaymentAmount', 0, '100');
         $this->assertXPathNotExistsWithIndex('/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:PartialPaymentAmount', 1);
     }
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ObjectHelperEn16931Test.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ObjectHelperEn16931Test.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ObjectHelperEn16931Test.php	(revision 8540)
@@ -602,5 +602,5 @@
          * @var \horstoeko\zugferd\entities\en16931\ram\ReferencedDocumentType
          */
-        $refdoctype = self::$objectHelper->getReferencedDocumentType("issuerid", "uriid", "lineid", "typecode", "name", "reftypcode", new \DateTime(), __DIR__ . "/../assets/xml_en16931_2.xml");
+        $refdoctype = self::$objectHelper->getReferencedDocumentType("issuerid", "uriid", "lineid", "typecode", "name", "reftypcode", new \DateTime(), __DIR__ . "/../assets/dummy_picture.jpg");
         $this->assertEquals("issuerid", $refdoctype->getIssuerAssignedID()->value());
         $this->assertEquals("uriid", $refdoctype->getURIID()->value());
@@ -904,4 +904,15 @@
         $this->assertEquals("type", $fincard->getID()->getSchemeID());
         $this->assertEquals("6759 68453", $fincard->getID());
+        $this->assertEquals("name", $fincard->getCardholderName());
+    }
+
+    public function testGetTradeSettlementFinancialCardType4DigitValue(): void
+    {
+        /**
+         * @var \horstoeko\zugferd\entities\en16931\ram\TradeSettlementFinancialCardType
+         */
+        $fincard = self::$objectHelper->getTradeSettlementFinancialCardType("type", "8453", "name");
+        $this->assertEquals("type", $fincard->getID()->getSchemeID());
+        $this->assertEquals("8453", $fincard->getID());
         $this->assertEquals("name", $fincard->getCardholderName());
     }
@@ -1375,5 +1386,5 @@
         $this->assertNotInstanceOf(\DateTime::class, self::$objectHelper->toDateTime("", null));
         $this->assertNotInstanceOf(\DateTime::class, self::$objectHelper->toDateTime(null, ""));
-        $this->assertNull(self::$objectHelper->toDateTime(null, null));
+        $this->assertNotInstanceOf(\DateTime::class, self::$objectHelper->toDateTime(null, null));
         $this->expectException(ZugferdUnknownDateFormatException::class);
         $this->expectExceptionMessage("Invalid date format 999");
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ObjectHelperExtendedTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ObjectHelperExtendedTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ObjectHelperExtendedTest.php	(revision 8540)
@@ -604,5 +604,5 @@
          * @var \horstoeko\zugferd\entities\extended\ram\ReferencedDocumentType
          */
-        $refdoctype = self::$objectHelper->getReferencedDocumentType("issuerid", "uriid", "lineid", "typecode", "name", "reftypcode", new \DateTime(), __DIR__ . "/../assets/xml_en16931_2.xml");
+        $refdoctype = self::$objectHelper->getReferencedDocumentType("issuerid", "uriid", "lineid", "typecode", "name", "reftypcode", new \DateTime(), __DIR__ . "/../assets/dummy_picture.jpg");
         $this->assertEquals("issuerid", $refdoctype->getIssuerAssignedID()->value());
         $this->assertEquals("uriid", $refdoctype->getURIID()->value());
@@ -906,4 +906,15 @@
         $this->assertEquals("type", $fincard->getID()->getSchemeID());
         $this->assertEquals("6759 68453", $fincard->getID());
+        $this->assertEquals("name", $fincard->getCardholderName());
+    }
+
+    public function testGetTradeSettlementFinancialCardType4DigitValue(): void
+    {
+        /**
+         * @var \horstoeko\zugferd\entities\en16931\ram\TradeSettlementFinancialCardType
+         */
+        $fincard = self::$objectHelper->getTradeSettlementFinancialCardType("type", "8453", "name");
+        $this->assertEquals("type", $fincard->getID()->getSchemeID());
+        $this->assertEquals("8453", $fincard->getID());
         $this->assertEquals("name", $fincard->getCardholderName());
     }
@@ -1387,5 +1398,5 @@
         $this->assertNotInstanceOf(\DateTime::class, self::$objectHelper->toDateTime("", null));
         $this->assertNotInstanceOf(\DateTime::class, self::$objectHelper->toDateTime(null, ""));
-        $this->assertNull(self::$objectHelper->toDateTime(null, null));
+        $this->assertNotInstanceOf(\DateTime::class, self::$objectHelper->toDateTime(null, null));
         $this->expectException(ZugferdUnknownDateFormatException::class);
         $this->expectExceptionMessage("Invalid date format 999");
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfBuilderEn16931Test.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfBuilderEn16931Test.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfBuilderEn16931Test.php	(revision 8540)
@@ -182,6 +182,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -197,7 +197,7 @@
         $this->assertEquals("Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
     }
 
@@ -560,6 +560,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString('2000-01-01', $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString('2000-01-01', (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -575,7 +575,7 @@
         $this->assertEquals("Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString('2000-01-01', $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString('2000-01-01', $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString('2000-01-01', (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString('2000-01-01', (string) $pdfDetails["xmp:modifydate"]);
     }
 
@@ -610,6 +610,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -625,7 +625,7 @@
         $this->assertEquals("Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
 
         $pdfBuilder = new ZugferdDocumentPdfBuilder(self::$document, self::$sourcePdfFilename);
@@ -658,6 +658,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -673,7 +673,7 @@
         $this->assertEquals("Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
 
         $pdfBuilder = new ZugferdDocumentPdfBuilder(self::$document, self::$sourcePdfFilename);
@@ -707,6 +707,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -722,7 +722,7 @@
         $this->assertEquals("Issued by seller with name Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("FacturX/ZUGFeRD Invoice 471102 dated 2018-03-05 issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
 
         $pdfBuilder = new ZugferdDocumentPdfBuilder(self::$document, self::$sourcePdfFilename);
@@ -757,6 +757,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("Invoice-Document, Issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -772,7 +772,7 @@
         $this->assertEquals("Issued by seller with name Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("Invoice-Document, Issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
 
         $whichArray = [];
@@ -832,6 +832,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("DummyTitle", $pdfDetails["Title"]);
         $this->assertEquals("DummySubject", $pdfDetails["Subject"]);
@@ -847,7 +847,7 @@
         $this->assertEquals("DummyAuthor", $pdfDetails["dc:creator"]);
         $this->assertEquals("DummySubject", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
 
         $pdfBuilder = new ZugferdDocumentPdfBuilder(self::$document, self::$sourcePdfFilename);
@@ -897,6 +897,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("Invoice-Document, Issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -912,7 +912,7 @@
         $this->assertEquals("Issued by seller with name Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("Invoice-Document, Issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
 
         $pdfBuilder = new ZugferdDocumentPdfBuilder(self::$document, self::$sourcePdfFilename);
@@ -948,6 +948,6 @@
         $this->assertArrayHasKey("xmp:createdate", $pdfDetails);
         $this->assertArrayHasKey("xmp:modifydate", $pdfDetails);
-        $this->assertStringContainsString('FPDF', $pdfDetails["Producer"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["CreationDate"]);
+        $this->assertStringContainsString('FPDF', (string) $pdfDetails["Producer"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["CreationDate"]);
         $this->assertEquals("Lieferant GmbH : Invoice 471102", $pdfDetails["Title"]);
         $this->assertEquals("Invoice-Document, Issued by Lieferant GmbH", $pdfDetails["Subject"]);
@@ -963,7 +963,7 @@
         $this->assertEquals("Issued by seller with name Lieferant GmbH", $pdfDetails["dc:creator"]);
         $this->assertEquals("Invoice-Document, Issued by Lieferant GmbH", $pdfDetails["dc:description"]);
-        $this->assertStringContainsString('Factur-X PHP library', $pdfDetails["xmp:creatortool"]);
-        $this->assertStringContainsString("2018-03-05", $pdfDetails["xmp:createdate"]);
-        $this->assertStringContainsString(date("Y-m-d"), $pdfDetails["xmp:modifydate"]);
+        $this->assertStringContainsString('Factur-X PHP library', (string) $pdfDetails["xmp:creatortool"]);
+        $this->assertStringContainsString("2018-03-05", (string) $pdfDetails["xmp:createdate"]);
+        $this->assertStringContainsString(date("Y-m-d"), (string) $pdfDetails["xmp:modifydate"]);
     }
 }
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderEn16931AllowanceChargeTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderEn16931AllowanceChargeTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderEn16931AllowanceChargeTest.php	(revision 8540)
@@ -73,16 +73,16 @@
         $this->assertEquals("", $notes[0]["contentcode"]);
         $this->assertEquals("", $notes[0]["subjectcode"]);
-        $this->assertStringContainsString("Rechnung gemÃ€Ã Bestellung Nr. 2018-471331 vom 01.03.2018.", $notes[0]["content"]);
+        $this->assertStringContainsString("Rechnung gemÃ€Ã Bestellung Nr. 2018-471331 vom 01.03.2018.", (string) $notes[0]["content"]);
         $this->assertEquals("", $notes[1]["contentcode"]);
         $this->assertEquals("AAK", $notes[1]["subjectcode"]);
-        $this->assertStringContainsString("Es bestehen Rabatt- und Bonusvereinbarungen.", $notes[1]["content"]);
+        $this->assertStringContainsString("Es bestehen Rabatt- und Bonusvereinbarungen.", (string) $notes[1]["content"]);
         $this->assertEquals("", $notes[2]["contentcode"]);
         $this->assertEquals("REG", $notes[2]["subjectcode"]);
-        $this->assertStringContainsString("Lieferant GmbH", $notes[2]["content"]);
-        $this->assertStringContainsString("LieferantenstraÃe 20", $notes[2]["content"]);
-        $this->assertStringContainsString("80333 MÃŒnchen", $notes[2]["content"]);
-        $this->assertStringContainsString("Deutschland", $notes[2]["content"]);
-        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrer: Hans Muster", $notes[2]["content"]);
-        $this->assertStringContainsString("Handelsregisternummer: H A 123", $notes[2]["content"]);
+        $this->assertStringContainsString("Lieferant GmbH", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("LieferantenstraÃe 20", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("80333 MÃŒnchen", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Deutschland", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrer: Hans Muster", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Handelsregisternummer: H A 123", (string) $notes[2]["content"]);
     }
 
@@ -1261,5 +1261,5 @@
 
         self::$document->getDocumentPositionProductDetails($prodname, $proddesc, $prodsellerid, $prodbuyerid, $prodglobalidtype, $prodglobalid);
-        $this->assertStringContainsString("Mineralwasser Medium 12 x 1,0l PET", $prodname);
+        $this->assertStringContainsString("Mineralwasser Medium 12 x 1,0l PET", (string) $prodname);
         $this->assertSame("", $proddesc);
         $this->assertSame("GTRWA5", $prodsellerid);
@@ -1374,5 +1374,5 @@
 
         self::$document->getDocumentPositionProductDetails($prodname, $proddesc, $prodsellerid, $prodbuyerid, $prodglobalidtype, $prodglobalid);
-        $this->assertStringContainsString("Pfand", $prodname);
+        $this->assertStringContainsString("Pfand", (string) $prodname);
         $this->assertSame("", $proddesc);
         $this->assertSame("PFA5", $prodsellerid);
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderExtended2Test.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderExtended2Test.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderExtended2Test.php	(revision 8540)
@@ -849,5 +849,5 @@
     {
         $this->assertTrue(self::$document->firstDocumentAdditionalReferencedDocument());
-        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename);
+        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename, $binarymimecode, $binaryfilename);
         $this->assertSame("SUPPort doc", $issuerassignedid);
         $this->assertSame("916", $typecode);
@@ -860,4 +860,6 @@
         $this->assertNotInstanceOf(\DateTime::class, $issueddate);
         $this->assertSame("", $binarydatafilename);
+        $this->assertNull($binarymimecode);
+        $this->assertNull($binaryfilename);
     }
 
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderExtendedTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderExtendedTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/PdfReaderExtendedTest.php	(revision 8540)
@@ -79,15 +79,15 @@
         $this->assertEquals("", $notes[2]["contentcode"]);
         $this->assertEquals("REG", $notes[2]["subjectcode"]);
-        $this->assertStringContainsString("MUSTERLIEFERANT GMBH", $notes[2]["content"]);
-        $this->assertStringContainsString("BAHNHOFSTRASSE 99", $notes[2]["content"]);
-        $this->assertStringContainsString("99199 MUSTERHAUSEN", $notes[2]["content"]);
-        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrung:", $notes[2]["content"]);
-        $this->assertStringContainsString("Max Mustermann", $notes[2]["content"]);
-        $this->assertStringContainsString("USt-IdNr: DE123456789", $notes[2]["content"]);
-        $this->assertStringContainsString("Telefon: +49 932 431 0", $notes[2]["content"]);
-        $this->assertStringContainsString("www.musterlieferant.de", $notes[2]["content"]);
-        $this->assertStringContainsString("HRB Nr. 372876", $notes[2]["content"]);
-        $this->assertStringContainsString("Amtsgericht Musterstadt", $notes[2]["content"]);
-        $this->assertStringContainsString("GLN 4304171000002", $notes[2]["content"]);
+        $this->assertStringContainsString("MUSTERLIEFERANT GMBH", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("BAHNHOFSTRASSE 99", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("99199 MUSTERHAUSEN", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrung:", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Max Mustermann", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("USt-IdNr: DE123456789", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Telefon: +49 932 431 0", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("www.musterlieferant.de", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("HRB Nr. 372876", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Amtsgericht Musterstadt", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("GLN 4304171000002", (string) $notes[2]["content"]);
     }
 
@@ -860,5 +860,5 @@
     {
         $this->assertTrue(self::$document->firstDocumentAdditionalReferencedDocument());
-        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename);
+        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename, $binarymimecode, $binaryfilename);
         $this->assertSame("A777123", $issuerassignedid);
         $this->assertSame("130", $typecode);
@@ -869,4 +869,6 @@
         $this->assertNotInstanceOf(\DateTime::class, $issueddate);
         $this->assertSame("", $binarydatafilename);
+        $this->assertNull($binarymimecode);
+        $this->assertNull($binaryfilename);
     }
 
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderEn16931AllowanceChargeTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderEn16931AllowanceChargeTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderEn16931AllowanceChargeTest.php	(revision 8540)
@@ -89,16 +89,16 @@
         $this->assertEquals("", $notes[0]["contentcode"]);
         $this->assertEquals("", $notes[0]["subjectcode"]);
-        $this->assertStringContainsString("Rechnung gemÃ€Ã Bestellung Nr. 2018-471331 vom 01.03.2018.", $notes[0]["content"]);
+        $this->assertStringContainsString("Rechnung gemÃ€Ã Bestellung Nr. 2018-471331 vom 01.03.2018.", (string) $notes[0]["content"]);
         $this->assertEquals("", $notes[1]["contentcode"]);
         $this->assertEquals("AAK", $notes[1]["subjectcode"]);
-        $this->assertStringContainsString("Es bestehen Rabatt- und Bonusvereinbarungen.", $notes[1]["content"]);
+        $this->assertStringContainsString("Es bestehen Rabatt- und Bonusvereinbarungen.", (string) $notes[1]["content"]);
         $this->assertEquals("", $notes[2]["contentcode"]);
         $this->assertEquals("REG", $notes[2]["subjectcode"]);
-        $this->assertStringContainsString("Lieferant GmbH", $notes[2]["content"]);
-        $this->assertStringContainsString("LieferantenstraÃe 20", $notes[2]["content"]);
-        $this->assertStringContainsString("80333 MÃŒnchen", $notes[2]["content"]);
-        $this->assertStringContainsString("Deutschland", $notes[2]["content"]);
-        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrer: Hans Muster", $notes[2]["content"]);
-        $this->assertStringContainsString("Handelsregisternummer: H A 123", $notes[2]["content"]);
+        $this->assertStringContainsString("Lieferant GmbH", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("LieferantenstraÃe 20", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("80333 MÃŒnchen", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Deutschland", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrer: Hans Muster", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Handelsregisternummer: H A 123", (string) $notes[2]["content"]);
     }
 
@@ -1277,5 +1277,5 @@
 
         self::$document->getDocumentPositionProductDetails($prodname, $proddesc, $prodsellerid, $prodbuyerid, $prodglobalidtype, $prodglobalid);
-        $this->assertStringContainsString("Mineralwasser Medium 12 x 1,0l PET", $prodname);
+        $this->assertStringContainsString("Mineralwasser Medium 12 x 1,0l PET", (string) $prodname);
         $this->assertSame("", $proddesc);
         $this->assertSame("GTRWA5", $prodsellerid);
@@ -1390,5 +1390,5 @@
 
         self::$document->getDocumentPositionProductDetails($prodname, $proddesc, $prodsellerid, $prodbuyerid, $prodglobalidtype, $prodglobalid);
-        $this->assertStringContainsString("Pfand", $prodname);
+        $this->assertStringContainsString("Pfand", (string) $prodname);
         $this->assertSame("", $proddesc);
         $this->assertSame("PFA5", $prodsellerid);
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderExtended2Test.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderExtended2Test.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderExtended2Test.php	(revision 8540)
@@ -866,5 +866,5 @@
     {
         $this->assertTrue(self::$document->firstDocumentAdditionalReferencedDocument());
-        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename);
+        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename, $binarymimecode, $binaryfilename);
         $this->assertSame("SUPPort doc", $issuerassignedid);
         $this->assertSame("916", $typecode);
@@ -877,4 +877,6 @@
         $this->assertNotInstanceOf(\DateTime::class, $issueddate);
         $this->assertSame("", $binarydatafilename);
+        $this->assertNull($binarymimecode);
+        $this->assertNull($binaryfilename);
     }
 
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderExtendedTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderExtendedTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderExtendedTest.php	(revision 8540)
@@ -95,15 +95,15 @@
         $this->assertEquals("", $notes[2]["contentcode"]);
         $this->assertEquals("REG", $notes[2]["subjectcode"]);
-        $this->assertStringContainsString("MUSTERLIEFERANT GMBH", $notes[2]["content"]);
-        $this->assertStringContainsString("BAHNHOFSTRASSE 99", $notes[2]["content"]);
-        $this->assertStringContainsString("99199 MUSTERHAUSEN", $notes[2]["content"]);
-        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrung:", $notes[2]["content"]);
-        $this->assertStringContainsString("Max Mustermann", $notes[2]["content"]);
-        $this->assertStringContainsString("USt-IdNr: DE123456789", $notes[2]["content"]);
-        $this->assertStringContainsString("Telefon: +49 932 431 0", $notes[2]["content"]);
-        $this->assertStringContainsString("www.musterlieferant.de", $notes[2]["content"]);
-        $this->assertStringContainsString("HRB Nr. 372876", $notes[2]["content"]);
-        $this->assertStringContainsString("Amtsgericht Musterstadt", $notes[2]["content"]);
-        $this->assertStringContainsString("GLN 4304171000002", $notes[2]["content"]);
+        $this->assertStringContainsString("MUSTERLIEFERANT GMBH", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("BAHNHOFSTRASSE 99", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("99199 MUSTERHAUSEN", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("GeschÃ€ftsfÃŒhrung:", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Max Mustermann", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("USt-IdNr: DE123456789", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Telefon: +49 932 431 0", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("www.musterlieferant.de", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("HRB Nr. 372876", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("Amtsgericht Musterstadt", (string) $notes[2]["content"]);
+        $this->assertStringContainsString("GLN 4304171000002", (string) $notes[2]["content"]);
     }
 
@@ -903,5 +903,5 @@
     {
         $this->assertTrue(self::$document->firstDocumentAdditionalReferencedDocument());
-        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename);
+        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename, $binarymimecode, $binaryfilename);
         $this->assertSame("A777123", $issuerassignedid);
         $this->assertSame("130", $typecode);
@@ -912,4 +912,6 @@
         $this->assertNotInstanceOf(\DateTime::class, $issueddate);
         $this->assertSame("", $binarydatafilename);
+        $this->assertNull($binarymimecode);
+        $this->assertNull($binaryfilename);
     }
 
Index: /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderXRechnungAttachedBinaryObjectTest.php
===================================================================
--- /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderXRechnungAttachedBinaryObjectTest.php	(revision 8539)
+++ /mods/mod_rechnungen/lib/vendor/horstoeko/zugferd/tests/testcases/ReaderXRechnungAttachedBinaryObjectTest.php	(revision 8540)
@@ -72,5 +72,5 @@
     public function testGetDocumentAdditionalReferencedDocumentNoDirectorySet(): void
     {
-        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename);
+        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename, $binarymimecode, $binaryfilename);
         $this->assertSame("01_15_Anhang_01.pdf", $issuerassignedid);
         $this->assertSame("916", $typecode);
@@ -80,4 +80,6 @@
         $this->assertSame("", $binarydatafilename);
         $this->assertFileDoesNotExist($binarydatafilename);
+        $this->assertSame("application/pdf", $binarymimecode);
+        $this->assertSame("01_15_Anhang_01.pdf", $binaryfilename);
     }
 
@@ -85,5 +87,5 @@
     {
         self::$document->setBinaryDataDirectory(__DIR__);
-        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename);
+        self::$document->getDocumentAdditionalReferencedDocument($issuerassignedid, $typecode, $uriid, $name, $reftypecode, $issueddate, $binarydatafilename, $binarymimecode, $binaryfilename);
         $this->assertSame("01_15_Anhang_01.pdf", $issuerassignedid);
         $this->assertSame("916", $typecode);
@@ -96,4 +98,6 @@
         $this->assertSame(150128, filesize($binarydatafilename));
         $this->assertSame("%PDF", substr(file_get_contents($binarydatafilename), 0, 4));
+        $this->assertSame("application/pdf", $binarymimecode);
+        $this->assertSame("01_15_Anhang_01.pdf", $binaryfilename);
         @unlink($binarydatafilename);
     }
Index: /mods/wpsg_mod_rechnungen.class.php
===================================================================
--- /mods/wpsg_mod_rechnungen.class.php	(revision 8539)
+++ /mods/wpsg_mod_rechnungen.class.php	(revision 8540)
@@ -1333,5 +1333,5 @@
 
 			}
-			
+				
 			// $oCalculation->addCountry($oDefaultCountry->id, $oDefaultCountry->mwst, $oDefaultCountry->mwst_a,$oDefaultCountry->mwst_b, $oDefaultCountry->mwst_c, $oDefaultCountry->mwst_d, true);
 			
@@ -1641,5 +1641,8 @@
 			$this->shop->view['storno'] = false;
 			$this->shop->view['invoice'] = true;
-	 
+
+			//error_reporting(E_ALL);
+			//header('Content-Type: application/json');
+
 			$this->shop->render(WPSG_PATH_VIEW.'/mods/mod_rechnungen/invoice_pdf.phtml');
  
@@ -1662,5 +1665,5 @@
 					
 				}
-				
+			
 				if (@$_REQUEST['wpsg_rechnungen_sendmail'] == "1") {
 					
@@ -1887,15 +1890,23 @@
 					
 					foreach ($oOrder->getOrderProducts() as $oOrderProduct) {
-						
+
 						$invoice_data = json_decode($oOrderProduct->getMeta('wpsg_mod_rechnungen_data', false, 'null'), true);
 						if (!is_array($invoice_data)) $invoice_data = [];
-						
+
 						$invoice_data[] = [
 							'amount' => $oOrderProduct->getAmount(),
 							'invoice_id' => $oInvoice->getId()
 						];
-						
+
 						$oOrderProduct->setMeta('wpsg_mod_rechnungen_data', json_encode($invoice_data));
-						
+
+						$oInvoice->addProduct(
+							$oOrderProduct->getId(),
+							$oOrderProduct->getAmount(),
+							$oOrderProduct->getPrice(WPSG_NETTO),
+							$oOrderProduct->getPrice(WPSG_BRUTTO),
+							$oOrder->getInvoiceCountry()->getTax($oOrderProduct->getTaxKey())
+						);
+
 					}
 
@@ -2248,5 +2259,5 @@
 			$file_path = $oInvoice->getFilePath(true);
 			$file_name_raw = basename($file_path);
-			
+
 			if (!file_exists($file_path)) {
 			
@@ -2259,5 +2270,6 @@
 			}
 			
-			$file_path = \wpsg\mod_invoice\eInvoice::writeEInvoice($oInvoice->getOrder()->getId(), $oInvoice->getId(), $profil_id);
+			if ($oInvoice->isMultiInvoice()) $file_path = \wpsg\mod_invoice\eInvoice::writeMultiEInvoice($oInvoice, $profil_id); 
+			else $file_path = \wpsg\mod_invoice\eInvoice::writeEInvoice($oInvoice->getOrder()->getId(), $oInvoice->getId(), $profil_id);
 			
 			header('Content-Disposition: inline; filename="'.$file_name_raw.'"');
Index: /mods/wpsg_mod_revocation.class.php
===================================================================
--- /mods/wpsg_mod_revocation.class.php	(revision 8539)
+++ /mods/wpsg_mod_revocation.class.php	(revision 8540)
@@ -26,6 +26,6 @@
 			$this->desc = __('', 'wpsgRevocation');
 	
-			define('WPSG_MOD_REVOCATION__FILE__', __FILE__);
-			define('WPSG_MOD_REVOCATION__DIR__', dirname(__FILE__));
+			if (!defined('WPSG_MOD_REVOCATION__FILE__')) define('WPSG_MOD_REVOCATION__FILE__', __FILE__);
+			if (!defined('WPSG_MOD_REVOCATION__DIR__')) define('WPSG_MOD_REVOCATION__DIR__', dirname(__FILE__));
 			
 			require_once implode(DIRECTORY_SEPARATOR, [dirname(__FILE__), 'mod_revocation', 'Action.php']);
Index: /views/mods/mod_revocation/wpsg_revocation.css
===================================================================
--- /views/mods/mod_revocation/wpsg_revocation.css	(revision 8539)
+++ /views/mods/mod_revocation/wpsg_revocation.css	(revision 8540)
@@ -28,5 +28,5 @@
 .wpsg_revocation_product_button {
 	flex-shrink:0; display:inline-flex; align-items:center; gap:0.5rem;
-	width:100%; min-height:35px; padding:0.25rem 0.5rem;
+	width:auto; min-height:35px; padding:0.25rem 0.5rem;
 	border:1px solid black; cursor:pointer;
 }
Index: /views/order/index.phtml
===================================================================
--- /views/order/index.phtml	(revision 8539)
+++ /views/order/index.phtml	(revision 8540)
@@ -523,30 +523,56 @@
 
                 <div class="multiRechnung_tab" id="multiRechnung_inform" style="padding: 15px 0 15px 0; display:none;">
-
+ 
+						<div class="multiinvoice_form">
+							
+							<?php $oCustomer = wpsg_customer::getInstance(intval($this->view['arFilter']['k_id'])); ?>
+
+							<div class="row">
+								<input type="checkbox" name="wpsg_Multirechnung_sendmail" value="1" id="invoice_sendmail" />
+								<label for="invoice_sendmail"><?php echo __('E-Mail an Kunden senden', 'wpsg'); ?></label>
+								<input type="email" name="wpsg_Multirechnung_email" value="<?php echo $oCustomer->getEMailEInvoice();  ?>" />
+							</div>
+							
+							<div class="row">
+								<input type="checkbox" name="wpsg_Multirechnung_faelligkeit" value="1" id="invoice_faelligkeit" />
+								<label for="invoice_faelligkeit"><?php echo __('FÃ€lligkeit anzeigen', 'wpsg'); ?></label>
+								<input type="date" name="wpsg_Multirechnung_faelligkeitsdatum" value="<?php echo date('Y-m-d', strtotime('+'.intval($this->get_option("wpsg_rechnungen_faelligkeit")).' day')); ?>" />
+							</div>
+							
+							<div class="row">
+								<input type="checkbox" name="wpsg_Multirechnung_url" value="1" id="invoice_url" />
+								<label for="invoice_url"><?php echo __('URL Benachrichtigung', 'wpsg'); ?></label>
+								<span></span>
+							</div>
+							
+							<div class="row">
+								<span></span>
+								<label for="invoice_date"><?php echo __('Rechnungsdatum', 'wpsg') ;?></label>
+								<input type="date" value="<?php echo date('Y-m-d'); ?>" name="wpsg_Multirechnung_datum" id="invoice_date" />
+							</div>
+								
+							<span class="row" style="margin-top:0.5rem">
+								<input type="hidden" name="preview" id="wpsg_mod_rechnungen_preview" />
+								<input type="submit" name="wpsg_order_doaction" value="<?php echo _('Vorschau'); ?>" id="wpsg_mod_rechnungen_button_preview" />                    
+								<input type="submit" name="wpsg_order_doaction" value="<?php echo _('Erstellen'); ?>" id="wpsg_mod_rechnungen_button_submit"  />
+							</span>
+							
+						</div>
+						<style>
+							
+							.multiinvoice_form { border:1px solid black; padding:1rem 0.5rem; display:flex; flex-direction:column; gap:1rem; width:500px; user-select:none;
+								.row { margin:0; display:flex; justify-content:flex-start; gap:0.5rem; align-items:center; min-height:26px;
+								  	& > * { margin:0; }
+									& > *:first-child { width:16px; min-width:16px; flex-shrink:0; }
+								  input[type="text"], input[type="date"], input[type="email"] { height:26px; min-height:26px; }
+								}
+							}
+							
+						</style>
+						 
+						 
                     <div style="width: 100%; padding: 1rem; display: grid; row-gap: 0.5rem; column-gap: 0.5rem; grid-template-columns: 25px 1fr 150px; align-items: center; grid-auto-rows: 30px; padding-bottom: 0.5rem;" >
                         
-                        <?php $oCustomer = wpsg_customer::getInstance(intval($this->view['arFilter']['k_id'])); ?>
-
-                        <input type="checkbox" name="wpsg_Multirechnung_sendmail" value="1" id="invoice_sendmail" />
-                        <label for="invoice_sendmail"><?php echo __('E-Mail an Kunden senden', 'wpsg'); ?></label>
-                        <input type="email" name="wpsg_Multirechnung_email" value="<?php echo $oCustomer->getEMailEInvoice();  ?>" />
-                    
-                        <input type="checkbox" name="wpsg_Multirechnung_faelligkeit" value="1" id="invoice_faelligkeit" />
-                        <label for="invoice_faelligkeit"><?php echo __('FÃ€lligkeit anzeigen', 'wpsg'); ?></label>
-                        <input type="date" name="wpsg_Multirechnung_faelligkeitsdatum" value="<?php echo date('Y-m-d', strtotime('+'.intval($this->get_option("wpsg_rechnungen_faelligkeit")).' day')); ?>" />
-
-                        <input type="checkbox" name="wpsg_Multirechnung_url" value="1" id="invoice_url" />
-                        <label for="invoice_url"><?php echo __('URL Benachrichtigung', 'wpsg'); ?></label>
-                        <span></span>
-
-                        <span></span>
-                        <label for="invoice_date"><?php echo __('Rechnungsdatum', 'wpsg') ;?></label>
-                        <input type="date" value="<?php echo date('Y-m-d'); ?>" name="wpsg_Multirechnung_datum" id="invoice_date" />
-
-                        <span style="display:flex; justify-content:flex-start; gap:0.5rem; grid-column:1/span 3;">
-                            <input type="hidden" name="preview" id="wpsg_mod_rechnungen_preview" />
-                            <input type="submit" name="wpsg_order_doaction" value="<?php echo _('Vorschau'); ?>" id="wpsg_mod_rechnungen_button_preview" />                    
-                            <input type="submit" name="wpsg_order_doaction" value="<?php echo _('Erstellen'); ?>" id="wpsg_mod_rechnungen_button_submit"  />
-                        </span>
+                       
 
                     </div>
