]> git.ipfire.org Git - thirdparty/python-drafthorse.git/commitdiff
fixes Issue #20, Issue #22, Issue #26 and Issue #29. It replaces PR #21 and PR #23...
authorMarko Luther <marko.luther@gmx.net>
Sun, 10 Mar 2024 15:28:48 +0000 (16:28 +0100)
committerGitHub <noreply@github.com>
Sun, 10 Mar 2024 15:28:48 +0000 (16:28 +0100)
* - corrects the NS_QDT name according to the zugferd22 specification
- extends elements.py:DateTimeElement to allow the adjustment of the inner DateTimes namespace
- updates references.py:ReferencedDocument to use NS_QDT for its DateTimeElement
- corrects profiles in reference.py for various attributes according to the zugferd22 schemata
- adds test zugferd_2p2_EN16931_ElektronischeAdresse2.xml as a variation of the official zugferd22 sample EN16931_ElektronischeAdresse.xml adding a FormattedIssueDateTime to the BuyerOrderReferencedDocument
- moves SellerOrderReferencedDocument from trade.py to references.py
- fixes DateTimeField namespace of AdvancePayment.received_date

* This commit also adds the class ProductInstance (IndividualTradeProductInstance) to product.py and adds the missing fields "id" (IDField) and "instance" (ProductInstance) to product.py:TradeProduct.

This commit also adds class PayerTradeParty (PayerTradeParty) to party.py and adds the missing field "payer" (PayerTradeParty) to trade.py:TradeSettlement.

This commit also removes the unused (and not needed) party.py:LineApplicableTradeTax class.

This commit also corrects profile and required tags according to the v2.2 specification as follows:

- references.py:LineAdditionalReferencedDocument
  .name profile COMFORT => BASIC (was COMFORT)
- tradelines.py:LineSettlement
  .trade_tax profile COMFORT => BASIC
  .period profile COMFORT => BASIC
  .allowance_charge profile COMFORT => BASIC
  .monetary_summation profile COMFORT => BASIC
  .additional_referenced_document profile EXTENDED => COMFORT
  .accounting_account profile EXTENDED => COMFORT
- product.py:ProductCharacteristic
  .type_code  required => optional
  .description profile EXTENDED => COMFORT
  .value profile EXTENDED => COMFORT
- product.py:ProductClassification
  .class_code required => optional; profile EXTENDED => COMFORT
  .value required => optional
- product.py:TradeProduct
  .name profile COMFORT => BASIC
  .characteristics EXTENDED => COMFORT
  .classifications EXTENDED => COMFORT
  .origins EXTENDED => COMFORT
- trade.py:TradeSettlement
  .tax_currency_code profile COMFORT => BASIC
  .invoicer profile COMFORT => EXTENDED
  .invoicee profile COMFORT => EXTENDED
  .payee profile COMFORT => BASIC
  .allowance_charge profile COMFORT => BASIC
  .service_charge profile COMFORT => EXTENDED
  .terms profile COMFORT => BASIC
  .accounting_account EXTENDED => BASIC
- accounting.py:ApplicableTradeTax
  .exemption_reason COMFORT => BASIC
  .category_code COMFORT => BASIC
  .exemption_reason_code EXTENDED => BASIC

* fixes profile annotations in TradeAllowanceCharge

* SpecifiedTradeAllowanceCharge:ReasonCode in COMFORT

14 files changed:
README.rst
drafthorse/models/__init__.py
drafthorse/models/accounting.py
drafthorse/models/elements.py
drafthorse/models/fields.py
drafthorse/models/party.py
drafthorse/models/product.py
drafthorse/models/references.py
drafthorse/models/trade.py
drafthorse/models/tradelines.py
setup.py
tests/samples/zugferd_2p1_EN16931_Einfach-LineObjectIdentifier.xml [new file with mode: 0644]
tests/samples/zugferd_2p2_EN16931_ElektronischeAdresse2.xml [new file with mode: 0644]
tests/test_mininal.py

index 357809d7b7833a568b4c3773616a95422f730a93..b540a41883f7a69fd9b834d1b049d7c1aef54486 100644 (file)
@@ -66,6 +66,14 @@ Generating::
     doc.trade.settlement.currency_code = "EUR"
     doc.trade.settlement.payment_means.type_code = "ZZZ"
 
+    doc.trade.agreement.seller.address.country_id = "DE"
+    doc.trade.agreement.seller.address.country_subdivision = "Bayern"
+
+    doc.trade.agreement.seller_order.issue_date_time = datetime.now(timezone.utc)
+    doc.trade.agreement.buyer_order.issue_date_time = datetime.now(timezone.utc)
+    doc.trade.settlement.advance_payment.received_date = datetime.now(timezone.utc)
+    doc.trade.agreement.customer_order.issue_date_time = datetime.now(timezone.utc)
+
     li = LineItem()
     li.document.line_id = "1"
     li.product.name = "Rainbow"
index 59a4c23109696a1c43032d42fd64646e4c668e00..b4a25e2702a46e9ca2b40eaa79f9683a711a1fab 100644 (file)
@@ -4,7 +4,7 @@ NS_A = "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
 NS_RAM = (
     "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
 )
-NS_QDT = "urn:un:unece:uncefact:data:standard:QualifiedDataType:10"
+NS_QDT = "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
 BASIC = "BASIC"
 COMFORT = "COMFORT"
 EXTENDED = "EXTENDED"
index 0bae75d37a341dab86820e5dc1ba3dacf5db5be1..0d2aa56162269492db9b809303152a283ee4da2f 100644 (file)
@@ -28,47 +28,6 @@ class BillingSpecifiedPeriod(Element):
         tag = "BillingSpecifiedPeriod"
 
 
-class SellerOrderReferencedDocument(Element):
-    issuer_ID = StringField(NS_RAM, "IssuerAssignedID", profile=COMFORT)
-    issue_date_time = DateTimeField(
-        NS_RAM, "FormattedIssueDateTime", required=True, profile=EXTENDED
-    )
-
-    class Meta:
-        namespace = NS_RAM
-        tag = "SellerOrderReferencedDocument"
-
-
-class LineApplicableTradeTax(Element):
-    calculated_amount = DecimalField(
-        NS_RAM, "CalculatedAmount", required=True, profile=BASIC, _d="Steuerbetrag"
-    )
-    type_code = StringField(
-        NS_RAM, "TypeCode", required=True, profile=BASIC, _d="Steuerart (Code)"
-    )
-    exemption_reason = StringField(
-        NS_RAM,
-        "ExemptionReason",
-        required=False,
-        profile=COMFORT,
-        _d="Grund der Steuerbefreiung (Freitext)",
-    )
-    category_code = StringField(
-        NS_RAM,
-        "CategoryCode",
-        required=False,
-        profile=COMFORT,
-        _d="Steuerkategorie (Wert)",
-    )
-    rate_applicable_percent = DecimalField(
-        NS_RAM, "RateApplicablePercent", required=True, profile=BASIC
-    )
-
-    class Meta:
-        namespace = NS_RAM
-        tag = "ApplicableTradeTax"
-
-
 class ApplicableTradeTax(Element):
     calculated_amount = DecimalField(
         NS_RAM, "CalculatedAmount", required=True, profile=BASIC, _d="Steuerbetrag"
@@ -80,17 +39,8 @@ class ApplicableTradeTax(Element):
         NS_RAM,
         "ExemptionReason",
         required=False,
-        profile=COMFORT,
-        _d="Grund der Steuerbefreiung (Freitext)",
-    )
-    tax_point_date = DateTimeField(
-        NS_RAM, "TaxPointDate", required=False, profile=COMFORT
-    )
-    due_date_type_code = StringField(
-        NS_RAM,
-        "DueDateTypeCode",
-        required=False,
         profile=BASIC,
+        _d="Grund der Steuerbefreiung (Freitext)",
     )
     basis_amount = DecimalField(
         NS_RAM,
@@ -117,16 +67,25 @@ class ApplicableTradeTax(Element):
         NS_RAM,
         "CategoryCode",
         required=False,
-        profile=COMFORT,
+        profile=BASIC,
         _d="Steuerkategorie (Wert)",
     )
     exemption_reason_code = StringField(
         NS_RAM,
         "ExemptionReasonCode",
         required=False,
-        profile=EXTENDED,
+        profile=BASIC,
         _d="Grund der Steuerbefreiung (Code)",
     )
+    tax_point_date = DateTimeField(
+        NS_RAM, "TaxPointDate", required=False, profile=COMFORT
+    )
+    due_date_type_code = StringField(
+        NS_RAM,
+        "DueDateTypeCode",
+        required=False,
+        profile=BASIC,
+    )
     rate_applicable_percent = DecimalField(
         NS_RAM, "RateApplicablePercent", required=True, profile=BASIC
     )
@@ -254,14 +213,14 @@ class TradeAllowanceCharge(Element):
         NS_RAM,
         "CalculationPercent",
         required=False,
-        profile=EXTENDED,
+        profile=COMFORT,
         _d="Rabatt in Prozent",
     )
     basis_amount = DecimalField(  # TODO: Should be deprecated?
         NS_RAM,
         "BasisAmount",
         required=False,
-        profile=EXTENDED,
+        profile=COMFORT,
         _d="Basisbetrag des Rabatts",
     )
     basis_quantity = QuantityField(
@@ -278,7 +237,7 @@ class TradeAllowanceCharge(Element):
         profile=COMFORT,
         _d="Betrag des Zu-/Abschlags",
     )
-    reason_code = StringField(NS_RAM, "ReasonCode", required=False, profile=EXTENDED)
+    reason_code = StringField(NS_RAM, "ReasonCode", required=False, profile=COMFORT)
     reason = StringField(NS_RAM, "Reason", required=False, profile=COMFORT)
     trade_tax = MultiField(CategoryTradeTax, required=False, profile=COMFORT)
 
index 847820886298e437ce0aa7bae61570d8551cdbba..80a68201161114435a79ebbe1d7c16655d9201e5 100644 (file)
@@ -80,7 +80,7 @@ class Element(metaclass=BaseElementMeta):
         if (
             not hasattr(self, key)
             and not key.startswith("_")
-            and not key in ("required",)
+            and key not in ("required",)
         ):
             raise AttributeError(
                 f"Element {type(self)} has no attribute '{key}'. If you set it, it would not be included in the output."
@@ -301,7 +301,8 @@ class IDElement(StringElement):
     def to_etree(self):
         node = self._etree_node()
         node.text = self._text
-        node.attrib["schemeID"] = self._scheme_id
+        if self._scheme_id != "":
+            node.attrib["schemeID"] = self._scheme_id
         return node
 
     def from_etree(self, root):
@@ -319,14 +320,17 @@ class IDElement(StringElement):
 
 
 class DateTimeElement(StringElement):
-    def __init__(self, namespace, tag, value=None, format="102"):
+    def __init__(
+        self, namespace, tag, value=None, format="102", date_time_namespace=NS_UDT
+    ):
         super().__init__(namespace, tag)
         self._value = value
         self._format = format
+        self._date_time_namespace = date_time_namespace
 
     def to_etree(self):
         t = self._etree_node()
-        node = ET.Element("{%s}%s" % (NS_UDT, "DateTimeString"))
+        node = ET.Element("{%s}%s" % (self._date_time_namespace, "DateTimeString"))
         if self._value:
             if self._format == "102":
                 node.text = self._value.strftime("%Y%m%d")
@@ -344,7 +348,7 @@ class DateTimeElement(StringElement):
     def from_etree(self, root):
         if len(root) != 1:
             raise TypeError("Date containers should have one child")
-        if root[0].tag != "{%s}%s" % (NS_UDT, "DateTimeString"):
+        if root[0].tag != "{%s}%s" % (self._date_time_namespace, "DateTimeString"):
             raise TypeError("Tag %s not recognized" % root[0].tag)
         self._format = root[0].attrib["format"]
         if self._format == "102":
index c215a543a567f7fe922811bd15241a28ef8b6f3e..5efed5dfbcebee1bd1f94eb05f51c9d72edcd96f 100644 (file)
@@ -1,6 +1,6 @@
 from decimal import Decimal
 
-from . import BASIC
+from . import BASIC, NS_UDT
 from .container import (
     Container,
     CurrencyContainer,
@@ -119,10 +119,16 @@ class IDField(Field):
         if instance._data.get(self.name, None) is None:
             instance._data[self.name] = self.initialize()
 
-        if not isinstance(value, (tuple, list)):
-            raise TypeError("Please pass a 2-tuple of including scheme ID and ID.")
-        instance._data[self.name]._text = value[1]
-        instance._data[self.name]._scheme_id = value[0]
+        if isinstance(value, (tuple, list)):
+            if len(value) == 2:
+                instance._data[self.name]._text = value[1]
+                instance._data[self.name]._scheme_id = value[0]
+            else:
+                raise TypeError(
+                    "Please pass a 2-tuple of including scheme ID and ID, or just an ID."
+                )
+        else:
+            instance._data[self.name]._text = value
 
 
 class CurrencyField(Field):
@@ -208,7 +214,9 @@ class BinaryObjectField(Field):
             instance._data[self.name] = self.initialize()
 
         if not isinstance(value, (tuple, list)):
-            raise TypeError("Please pass a 2-tuple of including amount and unit code.")
+            raise TypeError(
+                "Please pass a 3-tuple of mimeCode, filename and base64-encoded binary."
+            )
         instance._data[self.name]._text = value[2]
         instance._data[self.name]._mime_code = value[0]
         instance._data[self.name]._filename = value[1]
@@ -238,13 +246,21 @@ class IndicatorField(Field):
 
 class DateTimeField(Field):
     def __init__(
-        self, namespace, tag, default=False, required=False, profile=BASIC, _d=None
+        self,
+        namespace,
+        tag,
+        default=False,
+        required=False,
+        profile=BASIC,
+        _d=None,
+        date_time_namespace=NS_UDT,
     ):
         from .elements import DateTimeElement
 
         super().__init__(DateTimeElement, default, required, profile, _d)
         self.namespace = namespace
         self.tag = tag
+        self._date_time_namespace = date_time_namespace
 
     def __set__(self, instance, value):
         if instance._data.get(self.name, None) is None:
@@ -252,7 +268,9 @@ class DateTimeField(Field):
         instance._data[self.name]._value = value
 
     def initialize(self):
-        return self.cls(self.namespace, self.tag)
+        return self.cls(
+            self.namespace, self.tag, date_time_namespace=self._date_time_namespace
+        )
 
 
 class DirectDateTimeField(Field):
index 415cbac9899085c6df29827dd045e5a3689dc664..efc96bcc928aba60edb064e59a6f1f43b9e30640 100644 (file)
@@ -117,6 +117,12 @@ class PayeeTradeParty(TradeParty):
         tag = "PayeeTradeParty"
 
 
+class PayerTradeParty(TradeParty):
+    class Meta:
+        namespace = NS_RAM
+        tag = "PayerTradeParty"
+
+
 class InvoicerTradeParty(TradeParty):
     class Meta:
         namespace = NS_RAM
index 5a0ff93adb2b89e02bd22609645179c4f8367497..9a49cd525b0b2ab2783c2b6e69aa7c6d5585a048 100644 (file)
@@ -13,11 +13,11 @@ class ProductCharacteristic(Element):
     type_code = StringField(
         NS_RAM,
         "TypeCode",
-        required=True,
+        required=False,
         profile=EXTENDED,
         _d="Art der Produkteigenschaft",
     )
-    description = StringField(NS_RAM, "Description", required=True, profile=EXTENDED)
+    description = StringField(NS_RAM, "Description", required=True, profile=COMFORT)
     value_measure = QuantityField(
         NS_RAM,
         "ValueMeasure",
@@ -25,7 +25,7 @@ class ProductCharacteristic(Element):
         profile=EXTENDED,
         _d="Numerische Messgröße",
     )
-    value = StringField(NS_RAM, "Value", required=False, profile=EXTENDED)
+    value = StringField(NS_RAM, "Value", required=False, profile=COMFORT)
 
     class Meta:
         namespace = NS_RAM
@@ -34,15 +34,26 @@ class ProductCharacteristic(Element):
 
 class ProductClassification(Element):
     class_code = ClassificationField(
-        NS_RAM, "ClassCode", required=True, profile=EXTENDED
+        NS_RAM, "ClassCode", required=False, profile=COMFORT
     )
-    value = StringField(NS_RAM, "ClassName", required=True, profile=EXTENDED)
+    value = StringField(NS_RAM, "ClassName", required=False, profile=EXTENDED)
 
     class Meta:
         namespace = NS_RAM
         tag = "DesignatedProductClassification"
 
 
+class ProductInstance(Element):
+    batch_id = IDField(NS_RAM, "BatchID", required=False, profile=EXTENDED)
+    serial_id = StringField(
+        NS_RAM, "SupplierAssignedSerialID", required=False, profile=EXTENDED
+    )
+
+    class Meta:
+        namespace = NS_RAM
+        tag = "IndividualTradeProductInstance"
+
+
 class OriginCountry(Element):
     id = StringField(
         NS_RAM, "ID", required=True, profile=EXTENDED, _d="Land der Produktherkunft"
@@ -73,22 +84,20 @@ class ReferencedProduct(Element):
 
 
 class TradeProduct(Element):
-    global_id = IDField(NS_RAM, "GlobalID", required=False, profile=COMFORT)
+    id = IDField(NS_RAM, "ID", required=False, profile=EXTENDED)
+    global_id = IDField(NS_RAM, "GlobalID", required=False)
     seller_assigned_id = StringField(
         NS_RAM, "SellerAssignedID", required=False, profile=COMFORT
     )
     buyer_assigned_id = StringField(
         NS_RAM, "BuyerAssignedID", required=False, profile=COMFORT
     )
-    name = StringField(NS_RAM, "Name", required=False, profile=COMFORT)
+    name = StringField(NS_RAM, "Name", required=False)
     description = StringField(NS_RAM, "Description", required=False, profile=COMFORT)
-    characteristics = MultiField(
-        ProductCharacteristic, required=False, profile=EXTENDED
-    )
-    classifications = MultiField(
-        ProductClassification, required=False, profile=EXTENDED
-    )
-    origins = MultiField(OriginCountry, required=False, profile=EXTENDED)
+    characteristics = MultiField(ProductCharacteristic, required=False, profile=COMFORT)
+    classifications = MultiField(ProductClassification, required=False, profile=COMFORT)
+    instance = MultiField(ProductInstance, required=False, profile=EXTENDED)
+    origins = MultiField(OriginCountry, required=False, profile=COMFORT)
     included_products = MultiField(ReferencedProduct, required=False, profile=EXTENDED)
 
     class Meta:
index e1a73a1eca2396030a01ee39bb77f5ac21f123e8..94fef615baa88d9933f9d57135aa259961130a8f 100644 (file)
@@ -1,6 +1,6 @@
-from . import COMFORT, EXTENDED, NS_RAM
+from . import BASIC, COMFORT, NS_RAM, NS_QDT
 from .elements import Element
-from .fields import BinaryObjectField, DirectDateTimeField, StringField
+from .fields import BinaryObjectField, DateTimeField, StringField, IDField
 
 
 class ProcuringProjectType(Element):
@@ -13,14 +13,24 @@ class ProcuringProjectType(Element):
 
 
 class ReferencedDocument(Element):
-    date_time_string = DirectDateTimeField(
-        NS_RAM, "DateTimeString", required=False, profile=COMFORT
+    issuer_assigned_id = IDField(
+        NS_RAM, "IssuerAssignedID", required=False, profile=BASIC
     )
-    issuer_assigned_id = StringField(
-        NS_RAM, "IssuerAssignedID", required=False, profile=COMFORT
+    issue_date_time = DateTimeField(
+        NS_RAM,
+        "FormattedIssueDateTime",
+        required=True,
+        profile=BASIC,
+        date_time_namespace=NS_QDT,
     )
 
 
+class SellerOrderReferencedDocument(ReferencedDocument):
+    class Meta:
+        namespace = NS_RAM
+        tag = "SellerOrderReferencedDocument"
+
+
 class BuyerOrderReferencedDocument(ReferencedDocument):
     class Meta:
         namespace = NS_RAM
@@ -33,18 +43,12 @@ class ContractReferencedDocument(ReferencedDocument):
         tag = "ContractReferencedDocument"
 
 
-class AdditionalReferencedDocument(Element):
-    issuer_assigned_id = StringField(
-        NS_RAM, "IssuerAssignedID", required=False, profile=COMFORT
-    )
-    uri_id = StringField(NS_RAM, "URIID", required=False, profile=EXTENDED)
-    date_time_string = DirectDateTimeField(
-        NS_RAM, "DateTimeString", required=False, profile=COMFORT
-    )
-    type_code = StringField(NS_RAM, "TypeCode", profile=EXTENDED, required=True)
+class AdditionalReferencedDocument(ReferencedDocument):
+    uri_id = StringField(NS_RAM, "URIID", required=False, profile=COMFORT)
+    type_code = StringField(NS_RAM, "TypeCode", profile=COMFORT, required=True)
     name = StringField(NS_RAM, "Name", profile=COMFORT, required=False)
     attached_object = BinaryObjectField(
-        NS_RAM, "AttachmentBinaryObject", required=False, profile=EXTENDED
+        NS_RAM, "AttachmentBinaryObject", required=False, profile=COMFORT
     )
 
     class Meta:
@@ -52,15 +56,8 @@ class AdditionalReferencedDocument(Element):
         tag = "AdditionalReferencedDocument"
 
 
-class InvoiceReferencedDocument(Element):
-    issuer_assigned_id = StringField(
-        NS_RAM, "IssuerAssignedID", required=False, profile=COMFORT
-    )
-
-    date_time_string = DirectDateTimeField(
-        NS_RAM, "DateTimeString", required=True, profile=COMFORT
-    )
-    type_code = StringField(NS_RAM, "TypeCode", profile=EXTENDED, required=False)
+class InvoiceReferencedDocument(ReferencedDocument):
+    type_code = StringField(NS_RAM, "TypeCode", profile=COMFORT, required=False)
 
     class Meta:
         namespace = NS_RAM
@@ -80,7 +77,7 @@ class DespatchAdviceReferencedDocument(ReferencedDocument):
 
 
 class LineUltimateCustomerOrderReferencedDocument(ReferencedDocument):
-    line_id = StringField(NS_RAM, "LineID", required=False, profile=EXTENDED)
+    line_id = StringField(NS_RAM, "LineID", required=False, profile=COMFORT)
 
     class Meta:
         namespace = NS_RAM
@@ -88,7 +85,7 @@ class LineUltimateCustomerOrderReferencedDocument(ReferencedDocument):
 
 
 class LineBuyerOrderReferencedDocument(ReferencedDocument):
-    line_id = StringField(NS_RAM, "LineID", required=False, profile=EXTENDED)
+    line_id = StringField(NS_RAM, "LineID", required=False, profile=COMFORT)
 
     class Meta:
         namespace = NS_RAM
@@ -96,7 +93,7 @@ class LineBuyerOrderReferencedDocument(ReferencedDocument):
 
 
 class LineContractReferencedDocument(ReferencedDocument):
-    line_id = StringField(NS_RAM, "LineID", required=False, profile=EXTENDED)
+    line_id = StringField(NS_RAM, "LineID", required=False, profile=COMFORT)
 
     class Meta:
         namespace = NS_RAM
@@ -104,7 +101,7 @@ class LineContractReferencedDocument(ReferencedDocument):
 
 
 class LineDespatchAdviceReferencedDocument(ReferencedDocument):
-    line_id = StringField(NS_RAM, "LineID", required=False, profile=EXTENDED)
+    line_id = StringField(NS_RAM, "LineID", required=False, profile=COMFORT)
 
     class Meta:
         namespace = NS_RAM
@@ -112,28 +109,24 @@ class LineDespatchAdviceReferencedDocument(ReferencedDocument):
 
 
 class LineReceivingAdviceReferencedDocument(ReferencedDocument):
-    line_id = StringField(NS_RAM, "LineID", required=False, profile=EXTENDED)
+    line_id = StringField(NS_RAM, "LineID", required=False, profile=COMFORT)
 
     class Meta:
         namespace = NS_RAM
         tag = "ReceivingAdviceReferencedDocument"
 
 
-class LineAdditionalReferencedDocument(Element):
-    issuer_assigned_id = StringField(
-        NS_RAM, "IssuerAssignedID", required=False, profile=COMFORT
-    )
-    uri_id = StringField(NS_RAM, "URIID", required=False, profile=EXTENDED)
-    line_id = StringField(NS_RAM, "LineID", required=False, profile=EXTENDED)
-    type_code = StringField(NS_RAM, "TypeCode", required=False, profile=EXTENDED)
-    name = StringField(NS_RAM, "Name", required=False, profile=EXTENDED)
-    date_time_string = DirectDateTimeField(
-        NS_RAM, "FormattedIssueDateTime", required=False, profile=COMFORT
-    )
+class LineAdditionalReferencedDocument(ReferencedDocument):
+    uri_id = StringField(NS_RAM, "URIID", required=False, profile=COMFORT)
+    line_id = StringField(NS_RAM, "LineID", required=False, profile=COMFORT)
+    type_code = StringField(NS_RAM, "TypeCode", required=False, profile=COMFORT)
+    name = StringField(NS_RAM, "Name", required=False, profile=COMFORT)
     reference_type_code = StringField(
-        NS_RAM, "ReferenceTypeCode", profile=EXTENDED, required=True
+        NS_RAM, "ReferenceTypeCode", profile=COMFORT, required=True
+    )
+    attached_object = BinaryObjectField(
+        NS_RAM, "AttachmentBinaryObject", required=False, profile=COMFORT
     )
-    # todo: AttachmentBinaryObject
 
     class Meta:
         namespace = NS_RAM
index 3044dacc96018a7e5bb4034b0737a53e710516b1..99c9302d25755c099a56eacfde8d953bf0a72f17 100644 (file)
@@ -1,11 +1,10 @@
-from . import BASIC, COMFORT, EXTENDED, NS_RAM, NS_RSM
+from . import BASIC, COMFORT, EXTENDED, NS_RAM, NS_RSM, NS_QDT
 from .accounting import (
     ApplicableTradeTax,
     AppliedTradeTax,
     BillingSpecifiedPeriod,
     MonetarySummation,
     ReceivableAccountingAccount,
-    SellerOrderReferencedDocument,
     TradeAllowanceCharge,
 )
 from .delivery import TradeDelivery
@@ -17,6 +16,7 @@ from .party import (
     InvoiceeTradeParty,
     InvoicerTradeParty,
     PayeeTradeParty,
+    PayerTradeParty,
     SellerTaxRepresentativeTradeParty,
     SellerTradeParty,
 )
@@ -28,6 +28,7 @@ from .payment import (
 from .references import (
     AdditionalReferencedDocument,
     BuyerOrderReferencedDocument,
+    SellerOrderReferencedDocument,
     ContractReferencedDocument,
     InvoiceReferencedDocument,
     ProcuringProjectType,
@@ -147,7 +148,9 @@ class IncludedTradeTax(Element):
 
 class AdvancePayment(Element):
     paid_amount = DecimalField(NS_RAM, "PaidAmount")
-    received_date = DateTimeField(NS_RAM, "FormattedReceivedDateTime")
+    received_date = DateTimeField(
+        NS_RAM, "FormattedReceivedDateTime", date_time_namespace=NS_QDT
+    )
     included_trade_tax = MultiField(IncludedTradeTax)
 
     class Meta:
@@ -159,47 +162,52 @@ class TradeSettlement(Element):
     creditor_reference_id = StringField(NS_RAM, "CreditorReferenceID")
     payment_reference = StringField(NS_RAM, "PaymentReference")
     tax_currency_code = StringField(
-        NS_RAM, "TaxCurrencyCode", required=False, profile=COMFORT
+        NS_RAM, "TaxCurrencyCode", required=False, profile=BASIC
     )
     currency_code = StringField(NS_RAM, "InvoiceCurrencyCode")
     issuer_reference = StringField(NS_RAM, "InvoiceIssuerReference", profile=EXTENDED)
     invoicer = Field(
-        InvoicerTradeParty, required=False, profile=COMFORT, _d="Rechnungsaussteller"
+        InvoicerTradeParty, required=False, profile=EXTENDED, _d="Rechnungsaussteller"
     )
     invoicee = Field(
-        InvoiceeTradeParty, required=False, profile=COMFORT, _d="Rechnungsempfänger"
+        InvoiceeTradeParty, required=False, profile=EXTENDED, _d="Rechnungsempfänger"
     )
     payee = Field(
-        PayeeTradeParty, required=False, profile=COMFORT, _d="Zahlungsempfänger"
+        PayeeTradeParty, required=False, profile=BASIC, _d="Zahlungsempfänger"
+    )
+    payer = Field(
+        PayerTradeParty, required=False, profile=EXTENDED, _d="Zahlungspflichtiger"
     )
-    invoice_currency = Field(TaxApplicableTradeCurrencyExchange)
+    invoice_currency = Field(TaxApplicableTradeCurrencyExchange, profile=EXTENDED)
     payment_means = Field(PaymentMeans)
     trade_tax = MultiField(ApplicableTradeTax)
     period = Field(BillingSpecifiedPeriod, required=False, profile=BASIC)
     allowance_charge = MultiField(
         TradeAllowanceCharge,
         required=False,
-        profile=COMFORT,
+        profile=BASIC,
         _d="Schalter für Zu-/Abschlag",
     )
-    service_charge = MultiField(LogisticsServiceCharge, required=False, profile=COMFORT)
-    terms = MultiField(PaymentTerms, required=False, profile=COMFORT)
+    service_charge = MultiField(
+        LogisticsServiceCharge, required=False, profile=EXTENDED
+    )
+    terms = MultiField(PaymentTerms, required=False, profile=BASIC)
     monetary_summation = Field(
         MonetarySummation,
         required=True,
         profile=BASIC,
         _d="Detailinformation zu Belegsummen",
     )
+    invoice_referenced_document = Field(
+        InvoiceReferencedDocument, required=False, profile=BASIC
+    )
     accounting_account = Field(
         ReceivableAccountingAccount,
         required=False,
-        profile=EXTENDED,
+        profile=BASIC,
         _d="Detailinformationen zur Buchungsreferenz",
     )
     advance_payment = MultiField(AdvancePayment, required=False, profile=EXTENDED)
-    invoice_referenced_document = Field(
-        InvoiceReferencedDocument, required=False, profile=BASIC
-    )
 
     class Meta:
         namespace = NS_RAM
index 1e0c121e6604fce182fcc1a53b1a698502e7023e..9b43c9ad97f4f75e9936418eda372490253e0a6a 100644 (file)
@@ -150,25 +150,24 @@ class LineSummation(Element):
 
 
 class LineSettlement(Element):
-    trade_tax = Field(ApplicableTradeTax, required=False, profile=COMFORT)
-    period = Field(BillingSpecifiedPeriod, required=False, profile=COMFORT)
+    trade_tax = Field(ApplicableTradeTax, required=False)
+    period = Field(BillingSpecifiedPeriod, required=False)
     allowance_charge = MultiField(
         TradeAllowanceCharge,
         required=False,
-        profile=COMFORT,
         _d="Schalter für Zu-/Abschlag",
     )
-    monetary_summation = Field(LineSummation, required=False, profile=COMFORT)
+    monetary_summation = Field(LineSummation, required=False, profile=BASIC)
     invoice_referenced_document = Field(
         InvoiceReferencedDocument, required=False, profile=EXTENDED
     )
     additional_referenced_document = Field(
-        LineAdditionalReferencedDocument, required=False, profile=EXTENDED
+        LineAdditionalReferencedDocument, required=False, profile=COMFORT
     )
     accounting_account = Field(
         ReceivableAccountingAccount,
         required=False,
-        profile=EXTENDED,
+        profile=COMFORT,
         _d="Detailinformationen zur Buchungsreferenz",
     )
 
index 3434eaf65f8afc9be7a99717b5ccacf926bea08d..b88013d0712820ab94ee7a65698a4290624bfc1e 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,3 @@
-import sys
 from codecs import open
 from os import path
 from setuptools import find_packages, setup
diff --git a/tests/samples/zugferd_2p1_EN16931_Einfach-LineObjectIdentifier.xml b/tests/samples/zugferd_2p1_EN16931_Einfach-LineObjectIdentifier.xml
new file mode 100644 (file)
index 0000000..cd0f53d
--- /dev/null
@@ -0,0 +1,248 @@
+<?xml version='1.0' encoding='UTF-8' ?>\r
+<!-- English disclaimer below.-->\r
+<!--Nutzungsrechte \r
+ZUGFeRD Datenformat Version 2.1.1, 01.07.2020\r
+Beispiel Version 01.07.2020\r
\r
+Zweck des Forums elektronisch Rechnung Deutschland, welches am 31. März 2010 unter der Arbeitsgemeinschaft für \r
+wirtschaftliche Verwaltung e. V. gegründet wurde, ist u. a. die Schaffung und Spezifizierung eines offenen Datenformats \r
+für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht diskriminierender, standardisierter \r
+Technologien („ZUGFeRD Datenformat“).\r
\r
+Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung \r
+frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine \r
+Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht \r
+diskriminierenden Bedingungen an.\r
\r
+Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung \r
+abrufbar unter www.ferd-net.de.\r
\r
+Im Einzelnen schließt die Nutzungsgewährung ein: \r
+=====================================\r
\r
+FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils \r
+geltenden und akzeptierten Fassung (www.ferd-net.de) ein. \r
+Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, \r
+Weiterbearbeitung und Verbindung mit anderen Produkten.\r
+Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder \r
+anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige \r
+Anwendungen und Dienste. \r
+Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente \r
+und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um \r
+notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch \r
+die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden. \r
+Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares, \r
+unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit \r
+anderen Produkten einzuräumen. \r
\r
+Die Lizenz wird kostenfrei zur Verfügung gestellt. \r
\r
+Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen \r
+Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten, \r
+Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete, \r
+beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der \r
+Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.-->\r
\r
+ <!--Right of use \r
+ZUGFeRD Data format version 2.1.1, July 1, 2020\r
\r
+The purpose of the Forum elektronische Rechnung Deutschland (FeRD), which was founded on March 31, 2010 under the \r
+umbrella of Arbeitsgemeinschaft für wirtschaftliche Verwaltung e. V., is, among other things, to create and specify an \r
+open data format for structured electronic data exchange on the basis of open and non discriminatory, standardised \r
+technologies ("ZUGFeRD data format").\r
\r
+The ZUGFeRD data format is used by both companies and public administration according to the FeRD \r
+made freely accessible. For this purpose FeRD offers all companies and organisations of the public administration a \r
+License to use the copyrighted ZUGFeRD data format in a fair, appropriate and non \r
+discriminatory conditions.\r
\r
+The specification of the FeRD for the implementation of the ZUGFeRD data format is, in its currently valid version \r
+available at www.ferd-net.de.\r
\r
+In detail, the grant of use includes \r
+=====================================\r
\r
+FeRD grants a license for the use of the copyrighted ZUGFeRD data format in the respective \r
+valid and accepted version (www.ferd-net.de). \r
+The license includes an irrevocable right of use including the right of further development, \r
+Further processing and connection with other products.\r
+The license applies in particular to the development, design, production, sale, use or \r
+other use of the ZUGFeRD data format for hardware and/or software products and other \r
+applications and services. \r
+This license does not include the essential patents of the members of FeRD. The essential patents are patents \r
+and patent applications worldwide which contain one or more claims that are \r
+necessary claims. Necessary claims are only those claims of the essential patents which are \r
+the implementation of the ZUGFeRD data format would necessarily be violated. \r
+The Licensee is entitled to provide its respective group companies with an unlimited, worldwide, non-transferable, \r
+irrevocable right of use including the right of further development, further processing and connection with \r
+other products. \r
\r
+The license is provided free of charge. \r
\r
+Except in the case of intentional fault or gross negligence, FeRD is not liable for loss of use, loss of \r
+Profit, loss of data, loss of communication, loss of revenue, loss of contracts, loss of business or for costs \r
+damages, losses or liabilities in connection with an interruption of business, nor for concrete, \r
+incidental, indirect, punitive or consequential damages, even if the possibility of \r
+costs, losses or damages could normally have been foreseen.-->\r
+\r
+<rsm:CrossIndustryInvoice xmlns:a="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:10" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">\r
+  <rsm:ExchangedDocumentContext>\r
+    <ram:GuidelineSpecifiedDocumentContextParameter>\r
+      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>\r
+    </ram:GuidelineSpecifiedDocumentContextParameter>\r
+  </rsm:ExchangedDocumentContext>\r
+  <rsm:ExchangedDocument>\r
+    <ram:ID>471102</ram:ID>\r
+    <ram:TypeCode>380</ram:TypeCode>\r
+    <ram:IssueDateTime>\r
+      <udt:DateTimeString format="102">20180305</udt:DateTimeString>\r
+    </ram:IssueDateTime>\r
+    <ram:IncludedNote>\r
+      <ram:Content>Rechnung gemäß Bestellung vom 01.03.2018.</ram:Content>\r
+    </ram:IncludedNote>\r
+    <ram:IncludedNote>\r
+      <ram:Content>Lieferant GmbH                              \r
+Lieferantenstraße 20                          \r
+80333 München                         \r
+Deutschland                            \r
+Geschäftsführer: Hans Muster\r
+Handelsregisternummer: H A 123\r
+      </ram:Content>\r
+      <ram:SubjectCode>REG</ram:SubjectCode>\r
+    </ram:IncludedNote>\r
+  </rsm:ExchangedDocument>\r
+  <rsm:SupplyChainTradeTransaction>\r
+    <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>1</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:GlobalID schemeID="0160">4012345001235</ram:GlobalID>\r
+        <ram:SellerAssignedID>TB100A4</ram:SellerAssignedID>\r
+        <ram:Name>Trennblätter A4</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:GrossPriceProductTradePrice>\r
+          <ram:ChargeAmount>9.9000</ram:ChargeAmount>\r
+        </ram:GrossPriceProductTradePrice>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>9.9000</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="H87">20.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>198.00</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+    <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>2</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:GlobalID schemeID="0160">4000050986428</ram:GlobalID>\r
+        <ram:SellerAssignedID>ARNR2</ram:SellerAssignedID>\r
+        <ram:Name>Joghurt Banane</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:GrossPriceProductTradePrice>\r
+          <ram:ChargeAmount>5.5000</ram:ChargeAmount>\r
+        </ram:GrossPriceProductTradePrice>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>5.5000</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="H87">50.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>275.00</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+        <ram:AdditionalReferencedDocument>\r
+          <ram:IssuerAssignedID schemeID="SE">D200KKRG</ram:IssuerAssignedID>\r
+          <ram:TypeCode>130</ram:TypeCode>\r
+        </ram:AdditionalReferencedDocument>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+    <ram:ApplicableHeaderTradeAgreement>\r
+      <ram:SellerTradeParty>\r
+               <ram:ID>549910</ram:ID>\r
+        <ram:GlobalID schemeID="0088">4000001123452</ram:GlobalID>\r
+        <ram:Name>Lieferant GmbH</ram:Name>\r
+        <ram:PostalTradeAddress>\r
+          <ram:PostcodeCode>80333</ram:PostcodeCode>\r
+          <ram:LineOne>Lieferantenstraße 20</ram:LineOne>\r
+          <ram:CityName>München</ram:CityName>\r
+          <ram:CountryID>DE</ram:CountryID>\r
+        </ram:PostalTradeAddress>\r
+        <ram:SpecifiedTaxRegistration>\r
+          <ram:ID schemeID="FC">201/113/40209</ram:ID>\r
+        </ram:SpecifiedTaxRegistration>\r
+        <ram:SpecifiedTaxRegistration>\r
+          <ram:ID schemeID="VA">DE123456789</ram:ID>\r
+        </ram:SpecifiedTaxRegistration>\r
+      </ram:SellerTradeParty>\r
+      <ram:BuyerTradeParty>\r
+        <ram:ID>GE2020211</ram:ID>\r
+        <ram:Name>Kunden AG Mitte</ram:Name>\r
+        <ram:PostalTradeAddress>\r
+          <ram:PostcodeCode>69876</ram:PostcodeCode>\r
+          <ram:LineOne>Kundenstraße 15</ram:LineOne>\r
+          <ram:CityName>Frankfurt</ram:CityName>\r
+          <ram:CountryID>DE</ram:CountryID>\r
+        </ram:PostalTradeAddress>\r
+      </ram:BuyerTradeParty>\r
+    </ram:ApplicableHeaderTradeAgreement>\r
+    <ram:ApplicableHeaderTradeDelivery>\r
+      <ram:ActualDeliverySupplyChainEvent>\r
+        <ram:OccurrenceDateTime>\r
+          <udt:DateTimeString format="102">20180305</udt:DateTimeString>\r
+        </ram:OccurrenceDateTime>\r
+      </ram:ActualDeliverySupplyChainEvent>\r
+    </ram:ApplicableHeaderTradeDelivery>\r
+    <ram:ApplicableHeaderTradeSettlement>\r
+      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>\r
+      <ram:ApplicableTradeTax>\r
+        <ram:CalculatedAmount>19.25</ram:CalculatedAmount>\r
+        <ram:TypeCode>VAT</ram:TypeCode>\r
+        <ram:BasisAmount>275.00</ram:BasisAmount>\r
+        <ram:CategoryCode>S</ram:CategoryCode>\r
+        <ram:RateApplicablePercent>7.00</ram:RateApplicablePercent>\r
+      </ram:ApplicableTradeTax>\r
+      <ram:ApplicableTradeTax>\r
+        <ram:CalculatedAmount>37.62</ram:CalculatedAmount>\r
+        <ram:TypeCode>VAT</ram:TypeCode>\r
+        <ram:BasisAmount>198.00</ram:BasisAmount>\r
+        <ram:CategoryCode>S</ram:CategoryCode>\r
+        <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+      </ram:ApplicableTradeTax>\r
+      <ram:SpecifiedTradePaymentTerms>\r
+        <ram:Description>Zahlbar innerhalb 30 Tagen netto bis 04.04.2018, 3% Skonto innerhalb 10 Tagen bis 15.03.2018</ram:Description>\r
+      </ram:SpecifiedTradePaymentTerms>\r
+      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\r
+        <ram:LineTotalAmount>473.00</ram:LineTotalAmount>\r
+        <ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>\r
+        <ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>\r
+        <ram:TaxBasisTotalAmount>473.00</ram:TaxBasisTotalAmount>\r
+               <ram:TaxTotalAmount currencyID="EUR">56.87</ram:TaxTotalAmount>\r
+        <ram:GrandTotalAmount>529.87</ram:GrandTotalAmount>\r
+        <ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>\r
+        <ram:DuePayableAmount>529.87</ram:DuePayableAmount>\r
+      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>\r
+    </ram:ApplicableHeaderTradeSettlement>\r
+  </rsm:SupplyChainTradeTransaction>\r
+</rsm:CrossIndustryInvoice>
\ No newline at end of file
diff --git a/tests/samples/zugferd_2p2_EN16931_ElektronischeAdresse2.xml b/tests/samples/zugferd_2p2_EN16931_ElektronischeAdresse2.xml
new file mode 100644 (file)
index 0000000..a7f2db4
--- /dev/null
@@ -0,0 +1,384 @@
+<?xml version='1.0' encoding='UTF-8' ?>\r
+<!-- English disclaimer below.-->\r
+<!--Nutzungsrechte \r
+ZUGFeRD Datenformat Version 2.2.0, 14.02.2022\r
+Beispiel Version 14.02.2022\r
\r
+Zweck des Forums elektronisch Rechnung Deutschland, welches am 31. März 2010 unter der Arbeitsgemeinschaft für \r
+wirtschaftliche Verwaltung e. V. gegründet wurde, ist u. a. die Schaffung und Spezifizierung eines offenen Datenformats \r
+für strukturierten elektronischen Datenaustausch auf der Grundlage offener und nicht diskriminierender, standardisierter \r
+Technologien („ZUGFeRD Datenformat“).\r
\r
+Das ZUGFeRD Datenformat wird nach Maßgabe des FeRD sowohl Unternehmen als auch der öffentlichen Verwaltung \r
+frei zugänglich gemacht. Hierfür bietet FeRD allen Unternehmen und Organisationen der öffentlichen Verwaltung eine \r
+Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD-Datenformats zu fairen, sachgerechten und nicht \r
+diskriminierenden Bedingungen an.\r
\r
+Die Spezifikation des FeRD zur Implementierung des ZUGFeRD Datenformats ist in ihrer jeweils geltenden Fassung \r
+abrufbar unter www.ferd-net.de.\r
\r
+Im Einzelnen schließt die Nutzungsgewährung ein: \r
+=====================================\r
\r
+FeRD räumt eine Lizenz für die Nutzung des urheberrechtlich geschützten ZUGFeRD Datenformats in der jeweils \r
+geltenden und akzeptierten Fassung (www.ferd-net.de) ein. \r
+Die Lizenz beinhaltet ein unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, \r
+Weiterbearbeitung und Verbindung mit anderen Produkten.\r
+Die Lizenz gilt insbesondere für die Entwicklung, die Gestaltung, die Herstellung, den Verkauf, die Nutzung oder \r
+anderweitige Verwendung des ZUGFeRD Datenformats für Hardware- und/oder Softwareprodukte sowie sonstige \r
+Anwendungen und Dienste. \r
+Diese Lizenz schließt nicht die wesentlichen Patente der Mitglieder von FeRD ein. Als wesentliche Patente sind Patente \r
+und Patentanmeldungen weltweit zu verstehen, die einen oder mehrere Patentansprüche beinhalten, bei denen es sich um \r
+notwendige Ansprüche handelt. Notwendige Ansprüche sind lediglich jene Ansprüche der Wesentlichen Patente, die durch \r
+die Implementierung des ZUGFeRD Datenformats notwendigerweise verletzt würden. \r
+Der Lizenznehmer ist berechtigt, seinen jeweiligen Konzerngesellschaften ein unbefristetes, weltweites, nicht übertragbares, \r
+unwiderrufliches Nutzungsrecht einschließlich des Rechts der Weiterentwicklung, Weiterbearbeitung und Verbindung mit \r
+anderen Produkten einzuräumen. \r
\r
+Die Lizenz wird kostenfrei zur Verfügung gestellt. \r
\r
+Außer im Falle vorsätzlichen Verschuldens oder grober Fahrlässigkeit haftet FeRD weder für Nutzungsausfall, entgangenen \r
+Gewinn, Datenverlust, Kommunikationsverlust, Einnahmeausfall, Vertragseinbußen, Geschäftsausfall oder für Kosten, \r
+Schäden, Verluste oder Haftpflichten im Zusammenhang mit einer Unterbrechung der Geschäftstätigkeit, noch für konkrete, \r
+beiläufig entstandene, mittelbare Schäden, Straf- oder Folgeschäden und zwar auch dann nicht, wenn die Möglichkeit der \r
+Kosten, Verluste bzw. Schäden hätte normalerweise vorhergesehen werden können.-->\r
\r
+ <!--Right of use \r
+ZUGFeRD Data format version 2.2.0, February 14th, 2022\r
\r
+The purpose of the Forum elektronische Rechnung Deutschland (FeRD), which was founded on March 31, 2010 under the \r
+umbrella of Arbeitsgemeinschaft für wirtschaftliche Verwaltung e. V., is, among other things, to create and specify an \r
+open data format for structured electronic data exchange on the basis of open and non discriminatory, standardised \r
+technologies ("ZUGFeRD data format").\r
\r
+The ZUGFeRD data format is used by both companies and public administration according to the FeRD \r
+made freely accessible. For this purpose FeRD offers all companies and organisations of the public administration a \r
+License to use the copyrighted ZUGFeRD data format in a fair, appropriate and non \r
+discriminatory conditions.\r
\r
+The specification of the FeRD for the implementation of the ZUGFeRD data format is, in its currently valid version \r
+available at www.ferd-net.de.\r
\r
+In detail, the grant of use includes \r
+=====================================\r
\r
+FeRD grants a license for the use of the copyrighted ZUGFeRD data format in the respective \r
+valid and accepted version (www.ferd-net.de). \r
+The license includes an irrevocable right of use including the right of further development, \r
+Further processing and connection with other products.\r
+The license applies in particular to the development, design, production, sale, use or \r
+other use of the ZUGFeRD data format for hardware and/or software products and other \r
+applications and services. \r
+This license does not include the essential patents of the members of FeRD. The essential patents are patents \r
+and patent applications worldwide which contain one or more claims that are \r
+necessary claims. Necessary claims are only those claims of the essential patents which are \r
+the implementation of the ZUGFeRD data format would necessarily be violated. \r
+The Licensee is entitled to provide its respective group companies with an unlimited, worldwide, non-transferable, \r
+irrevocable right of use including the right of further development, further processing and connection with \r
+other products. \r
\r
+The license is provided free of charge. \r
\r
+Except in the case of intentional fault or gross negligence, FeRD is not liable for loss of use, loss of \r
+Profit, loss of data, loss of communication, loss of revenue, loss of contracts, loss of business or for costs \r
+damages, losses or liabilities in connection with an interruption of business, nor for concrete, \r
+incidental, indirect, punitive or consequential damages, even if the possibility of \r
+costs, losses or damages could normally have been foreseen.-->\r
+\r
+<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">\r
+  <rsm:ExchangedDocumentContext>\r
+    <ram:GuidelineSpecifiedDocumentContextParameter>\r
+      <ram:ID>urn:cen.eu:en16931:2017</ram:ID>\r
+    </ram:GuidelineSpecifiedDocumentContextParameter>\r
+  </rsm:ExchangedDocumentContext>\r
+  <rsm:ExchangedDocument>\r
+    <ram:ID>9314110911/00/M/00/N</ram:ID>\r
+    <ram:TypeCode>387</ram:TypeCode>\r
+    <ram:IssueDateTime>\r
+      <udt:DateTimeString format="102">20181001</udt:DateTimeString>\r
+    </ram:IssueDateTime>\r
+    <ram:IncludedNote>\r
+      <ram:Content>MUSTER-Autovermietung GMBH\r
+Musterstr. 99\r
+99199 MUSTERHAUSEN\r
+Geschäftsführung:\r
+Maxima Musterfrau\r
+USt-IdNr: DE136695976\r
+Telefon: +49 711-50885524\r
+www.musterlieferant.de\r
+HRB Nr. 372876\r
+Amtsgericht Musterstadt\r
+GLN 4304171000002\r
+      </ram:Content>\r
+      <ram:SubjectCode>REG</ram:SubjectCode>\r
+    </ram:IncludedNote>\r
+    <ram:IncludedNote>\r
+      <ram:Content>Bei Rückfragen:\r
+Telefon: +49 711-50885524\r
+E-Mail : info@muster-autovermietung.de\r
+      </ram:Content>\r
+    </ram:IncludedNote>\r
+    <ram:IncludedNote>\r
+      <ram:Content>Übergabe am 29.09.2018/ 10:35\r
+         Ort: Frankfurt a. M.\r
+         km: 17791\r
+      </ram:Content>\r
+    </ram:IncludedNote>\r
+           <ram:IncludedNote>\r
+      <ram:Content>Rückgabe am 01.10.2018/ 10:19\r
+         Ort: Frankfurt a. M.\r
+         km: 18664\r
+      </ram:Content>\r
+    </ram:IncludedNote>\r
+       <ram:IncludedNote>\r
+      <ram:Content>Übernahme: Frankfurt\r
+         Datum: 01.10.2018\r
+         Zeit: 10:19\r
+         km/out: 177791\r
+         km/in: 18664\r
+         km gefahren: 873\r
+         Kennzeichen: M-MM 0000\r
+         CO2: 150\r
+         Bruttolistenpreis: 68300\r
+      </ram:Content>\r
+    </ram:IncludedNote>\r
+  </rsm:ExchangedDocument>\r
+  <rsm:SupplyChainTradeTransaction>\r
+    <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>1</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:Name>Miettage</ram:Name>\r
+               <ram:ApplicableProductCharacteristic>\r
+               <ram:Description>Fahrzeug-Kennzeichen</ram:Description>\r
+               <ram:Value>M-MM 0000</ram:Value>\r
+               </ram:ApplicableProductCharacteristic>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>86.5500</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="DAY">2.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>173.10</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+    <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>2</ram:LineID>\r
+               <ram:IncludedNote>\r
+          <ram:Content>Inklusiv-Kilometer waren: 873</ram:Content>\r
+        </ram:IncludedNote>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:Name>Navigationssystem - Garantie</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>5.0400</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>10.08</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+           <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>3</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:Name>Vollkasko</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>23.1000</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>46.20</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+       <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>4</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:Name>minimale Selbstbeteiligung</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>15.5500</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>31.10</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+       <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>5</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:Name>Personen-Unfallversicherung</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>7.9800</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>15.96</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+       <ram:IncludedSupplyChainTradeLineItem>\r
+      <ram:AssociatedDocumentLineDocument>\r
+        <ram:LineID>6</ram:LineID>\r
+      </ram:AssociatedDocumentLineDocument>\r
+      <ram:SpecifiedTradeProduct>\r
+        <ram:Name>Choice Upgrade</ram:Name>\r
+      </ram:SpecifiedTradeProduct>\r
+      <ram:SpecifiedLineTradeAgreement>\r
+        <ram:NetPriceProductTradePrice>\r
+          <ram:ChargeAmount>5.0400</ram:ChargeAmount>\r
+        </ram:NetPriceProductTradePrice>\r
+      </ram:SpecifiedLineTradeAgreement>\r
+      <ram:SpecifiedLineTradeDelivery>\r
+        <ram:BilledQuantity unitCode="C62">2.0000</ram:BilledQuantity>\r
+      </ram:SpecifiedLineTradeDelivery>\r
+      <ram:SpecifiedLineTradeSettlement>\r
+        <ram:ApplicableTradeTax>\r
+          <ram:TypeCode>VAT</ram:TypeCode>\r
+          <ram:CategoryCode>S</ram:CategoryCode>\r
+          <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+        </ram:ApplicableTradeTax>\r
+        <ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+          <ram:LineTotalAmount>10.08</ram:LineTotalAmount>\r
+        </ram:SpecifiedTradeSettlementLineMonetarySummation>\r
+      </ram:SpecifiedLineTradeSettlement>\r
+    </ram:IncludedSupplyChainTradeLineItem>\r
+    <ram:ApplicableHeaderTradeAgreement>\r
+      <ram:SellerTradeParty>\r
+               <ram:ID>549910</ram:ID>\r
+        <ram:GlobalID schemeID="0088">4333741000005</ram:GlobalID>\r
+               <ram:Name>MUSTER-Autovermietung</ram:Name>\r
+        <ram:PostalTradeAddress>\r
+          <ram:PostcodeCode>99199</ram:PostcodeCode>\r
+          <ram:LineOne>Musterstr. 99</ram:LineOne>\r
+          <ram:CityName>MUSTERHAUSEN</ram:CityName>\r
+          <ram:CountryID>DE</ram:CountryID>\r
+        </ram:PostalTradeAddress>\r
+               <ram:URIUniversalCommunication>\r
+          <ram:URIID schemeID="0088">1234567890128</ram:URIID>\r
+        </ram:URIUniversalCommunication>\r
+        <ram:SpecifiedTaxRegistration>\r
+          <ram:ID schemeID="VA">DE136695976</ram:ID>\r
+        </ram:SpecifiedTaxRegistration>\r
+      </ram:SellerTradeParty>\r
+      <ram:BuyerTradeParty>\r
+        <ram:ID>9314110911</ram:ID>\r
+        <ram:Name>MUSTER-KUNDE GMBH</ram:Name>\r
+        <ram:PostalTradeAddress>\r
+          <ram:PostcodeCode>40235</ram:PostcodeCode>\r
+          <ram:LineOne>KUNDENWEG 88</ram:LineOne>\r
+          <ram:CityName>DUESSELDORF</ram:CityName>\r
+          <ram:CountryID>DE</ram:CountryID>\r
+        </ram:PostalTradeAddress>\r
+               <ram:URIUniversalCommunication>\r
+          <ram:URIID schemeID="9958">04 0 11 000 - 12345 12345 - 35</ram:URIID>\r
+        </ram:URIUniversalCommunication>\r
+      </ram:BuyerTradeParty>\r
+      <ram:BuyerOrderReferencedDocument>\r
+        <ram:IssuerAssignedID>B123456789</ram:IssuerAssignedID>\r
+        <ram:FormattedIssueDateTime>\r
+            <qdt:DateTimeString format="102">20180204</qdt:DateTimeString>\r
+        </ram:FormattedIssueDateTime>\r
+      </ram:BuyerOrderReferencedDocument>\r
+    </ram:ApplicableHeaderTradeAgreement>\r
+    <ram:ApplicableHeaderTradeDelivery>\r
+      <ram:ActualDeliverySupplyChainEvent>\r
+        <ram:OccurrenceDateTime>\r
+          <udt:DateTimeString format="102">20180929</udt:DateTimeString>\r
+        </ram:OccurrenceDateTime>\r
+      </ram:ActualDeliverySupplyChainEvent>\r
+         <ram:DespatchAdviceReferencedDocument>\r
+        <ram:IssuerAssignedID>L87654321012345</ram:IssuerAssignedID>\r
+      </ram:DespatchAdviceReferencedDocument>\r
+    </ram:ApplicableHeaderTradeDelivery>\r
+    <ram:ApplicableHeaderTradeSettlement>\r
+      <ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>\r
+      <ram:ApplicableTradeTax>\r
+        <ram:CalculatedAmount>54.44</ram:CalculatedAmount>\r
+        <ram:TypeCode>VAT</ram:TypeCode>\r
+        <ram:BasisAmount>286.52</ram:BasisAmount>\r
+        <ram:CategoryCode>S</ram:CategoryCode>\r
+        <ram:RateApplicablePercent>19.00</ram:RateApplicablePercent>\r
+      </ram:ApplicableTradeTax>\r
+         <ram:SpecifiedTradePaymentTerms>\r
+        <ram:Description>\r
+          Die Leistung wurde erbracht im Zeitraum zwischen Übergabe und Rückgabe. Der Rechnungsbetrag wird über Ihre MasterCard-Kreditkarte abgebucht. Dies ist keine Aufforderung zur Zahlung. Rechnung für Ihre Unterlagen.\r
+        </ram:Description>\r
+      </ram:SpecifiedTradePaymentTerms>\r
+         <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\r
+        <ram:LineTotalAmount>286.52</ram:LineTotalAmount>\r
+        <ram:ChargeTotalAmount>0.00</ram:ChargeTotalAmount>\r
+        <ram:AllowanceTotalAmount>0.00</ram:AllowanceTotalAmount>\r
+        <ram:TaxBasisTotalAmount>286.52</ram:TaxBasisTotalAmount>\r
+               <ram:TaxTotalAmount currencyID="EUR">54.44</ram:TaxTotalAmount>\r
+        <ram:GrandTotalAmount>340.96</ram:GrandTotalAmount>\r
+        <ram:TotalPrepaidAmount>0.00</ram:TotalPrepaidAmount>\r
+        <ram:DuePayableAmount>340.96</ram:DuePayableAmount>\r
+      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>\r
+    </ram:ApplicableHeaderTradeSettlement>\r
+  </rsm:SupplyChainTradeTransaction>\r
+</rsm:CrossIndustryInvoice>
\ No newline at end of file
index 0bd7f53c68da56ba3b9ecac6654214f62c8a67b4..aeaa34b1e2667f94b1c0df3909eec8d3aaf86906 100644 (file)
@@ -1,5 +1,5 @@
 import os
-from datetime import date
+from datetime import date, datetime, timezone
 from decimal import Decimal
 
 from drafthorse.models.accounting import ApplicableTradeTax
@@ -36,6 +36,11 @@ def test_readme_construction_example():
     doc.trade.agreement.seller.address.country_id = "DE"
     doc.trade.agreement.seller.address.country_subdivision = "Bayern"
 
+    doc.trade.agreement.seller_order.issue_date_time = datetime.now(timezone.utc)
+    doc.trade.agreement.buyer_order.issue_date_time = datetime.now(timezone.utc)
+    doc.trade.settlement.advance_payment.received_date = datetime.now(timezone.utc)
+    doc.trade.agreement.customer_order.issue_date_time = datetime.now(timezone.utc)
+
     li = LineItem()
     li.document.line_id = "1"
     li.product.name = "Rainbow"