]> git.ipfire.org Git - thirdparty/python-drafthorse.git/commitdiff
Added new fields, added XRECHNUNG samples
authorBen Dangelmayr <dangelmayr@rami.io>
Tue, 31 May 2022 09:41:48 +0000 (11:41 +0200)
committerBen Dangelmayr <dangelmayr@rami.io>
Tue, 31 May 2022 09:41:48 +0000 (11:41 +0200)
drafthorse/models/elements.py
drafthorse/models/fields.py
drafthorse/models/party.py
drafthorse/models/payment.py
drafthorse/models/references.py
drafthorse/models/trade.py
drafthorse/models/tradelines.py
tests/test_roundtrip.py

index 2c95b1821c822625fa680d5413268dff9d5e1923..9b523a444feb03bfdcd37f7db9e347144e426848 100644 (file)
@@ -4,7 +4,8 @@ import xml.etree.cElementTree as ET
 from collections import OrderedDict
 from datetime import datetime
 from decimal import Decimal
-
+#TODO: implement mimeElement and container
+import mimetypes
 from drafthorse.utils import validate_xml
 
 from . import NS_UDT
@@ -202,6 +203,25 @@ class ClassificationElement(StringElement):
     def __str__(self):
         return "{} ({} {})".format(self.text, self.list_id, self.list_version_id)
 
+class BinaryObjectElement(StringElement):
+    def __init__(self, namespace, tag, text="", mime_code=""):
+        super().__init__(namespace, tag)
+        self.text = text
+        self.mime_code = mime_code
+
+    def to_etree(self):
+        node = self._etree_node()
+        node.text = self.text
+        node.attrib['mimeCode'] = self.mime_code
+        return node
+
+    def from_etree(self, root):
+        self.text = root.text
+        self.mime_code = root.attrib['mimeCode']
+        return self
+
+    def __str__(self):
+        return "{} ({} {})".format(self.text, self.mime_code)
 
 class AgencyIDElement(StringElement):
     def __init__(self, namespace, tag, text="", scheme_id=""):
index ca733f2c9368ee945bde74ca18a8bdc98cb05815..4ad8d9eba79bbb3db84982e2fbbda2a3bd64d5f2 100644 (file)
@@ -143,6 +143,24 @@ class QuantityField(Field):
     def initialize(self):
         return self.cls(self.namespace, self.tag)
 
+class BinaryObjectField(Field):
+    def __init__(self, namespace, tag, default=False, required=False, profile=BASIC, _d=None):
+        from .elements import BinaryObjectElement
+        super().__init__(BinaryObjectElement, default, required, profile, _d)
+        self.namespace = namespace
+        self.tag = tag
+
+    def __set__(self, instance, value):
+        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 amount and unit code.")
+        instance._data[self.name].text = value[1]
+        instance._data[self.name].mime_code = value[0]
+
+    def initialize(self):
+        return self.cls(self.namespace, self.tag)
 
 class CurrencyField(Field):
     def __init__(self, namespace, tag, default=False, required=False, profile=BASIC, _d=None):
index 19fdbbf45ea257c2127c0867b9a6c4eb4cfeb87e..7a3aee339171e52baf8c3ecb80f05f07ef5c6ba2 100644 (file)
@@ -75,14 +75,14 @@ class TradeParty(Element):
     global_id = MultiIDField(NS_RAM, "GlobalID", required=False, profile=COMFORT,
                              _d="Globaler Identifier des Verkäufers")
     name = StringField(NS_RAM, "Name", required=False, profile=BASIC)
+    description = StringField(NS_RAM, "Description", required=True, profile=COMFORT,
+                              _d="Freitext der Zahlungsbedingungen")
     contact = Field(TradeContact, required=False, profile=EXTENDED,
                     _d="Ansprechpartner des Käufers")
     address = Field(PostalTradeAddress, required=False, profile=BASIC,
                     _d="Anschrift des Käufers")
-    tax_registrations = MultiField(TaxRegistration, required=False, profile=BASIC)
     electronic_adress = MultiField(URIUniversalCommunication, required=False, profile=BASIC)
-    description = StringField(NS_RAM, "Description", required=True, profile=COMFORT,
-                              _d="Freitext der Zahlungsbedingungen")
+    tax_registrations = MultiField(TaxRegistration, required=False, profile=BASIC)
 
 class SellerTaxRepresentativeTradeParty(TradeParty):
     class Meta:
index 9d1f695d98d6dceb4dc1d309ac119fedd9bd6fee..103859c60aef73c6f75b4d0e597291dd1d38126e 100644 (file)
@@ -1,8 +1,8 @@
 from . import BASIC, COMFORT, EXTENDED, NS_RAM
 from .elements import Element
 from .fields import (
-    AgencyIDField, DecimalField, DateTimeField, DecimalField, Field,
-    MultiDecimalField, MultiStringField, QuantityField, StringField,
+    AgencyIDField, DateTimeField, DecimalField, Field,
+    MultiDecimalField, MultiStringField, QuantityField, StringField, DirectDateTimeField
 )
 
 
@@ -87,6 +87,15 @@ class PaymentDiscountTerms(Element):
         namespace = NS_RAM
         tag = "ApplicableTradePaymentDiscountTerms"
 
+class TaxApplicableTradeCurrencyExchange(Element):
+    source_currency = StringField(NS_RAM, "SourceCurrencyCode", required=False, profile=EXTENDED)
+    target_currency = StringField(NS_RAM, "TargetCurrencyCode", required=False, profile=EXTENDED)
+    conversion_rate = DecimalField(NS_RAM, "ConversionRate", required=False, profile=EXTENDED)
+    date_time_string = DirectDateTimeField(NS_RAM, "ConversionRateDateTime", required=True,
+                                           profile=EXTENDED)
+    class Meta:
+        namespace = NS_RAM
+        tag = "TaxApplicableTradeCurrencyExchange"
 
 class PaymentTerms(Element):
     description = StringField(NS_RAM, "Description", required=True, profile=COMFORT,
index 6e3ca2bc8b99142a246fab60cde74a51c2561656..09fde8a895cbee52bae4d1aecc7f9cf8fd0fe76c 100644 (file)
@@ -1,13 +1,13 @@
-from . import COMFORT, EXTENDED, NS_RAM
+from . import COMFORT, EXTENDED, NS_RAM, NS_RSM
 from .elements import Element
-from .fields import DirectDateTimeField, StringField, Field
+from .fields import DirectDateTimeField, StringField, Field, BinaryObjectField
 
 class ProcuringProjectType(Element):
     id = StringField(NS_RAM, "ID")
     name = StringField(NS_RAM, "Name")
     class Meta:
         namespace = NS_RAM
-        tag = "ProcuringProjectType"
+        tag = "SpecifiedProcuringProject"
 
 class ReferencedDocument(Element):
     date_time_string = DirectDateTimeField(NS_RAM, "DateTimeString", required=False,
@@ -15,7 +15,8 @@ class ReferencedDocument(Element):
     issuer_assigned_id = StringField(NS_RAM, "IssuerAssignedID", required=False,
                                      profile=COMFORT)
 class AttachmentBinaryObject(Element):
-    name = StringField(NS_RAM, "filename", profile=EXTENDED)
+    name = StringField(NS_RAM, "filename", required=False, profile=COMFORT)
+    #mime_code = BinaryObjectField(NS_RAM,"mime_code", profile=COMFORT)
     class Meta:
         namespace = NS_RAM
         tag = "AttachmentBinaryObject"
@@ -41,7 +42,7 @@ class AdditionalReferencedDocument(Element):
                                            profile=COMFORT)
     type_code = StringField(NS_RAM, "TypeCode", profile=EXTENDED, required=True)
     name = StringField(NS_RAM, "Name", profile=COMFORT, required=False)
-    attached_object = Field(AttachmentBinaryObject, required=False, profile=EXTENDED)
+    attached_object = BinaryObjectField(NS_RAM, "AttachmentBinaryObject", required=False, profile=EXTENDED)
     class Meta:
         namespace = NS_RAM
         tag = "AdditionalReferencedDocument"
index ef30cefc04a0673f39a937c3515dc057431bcbd1..c6e122ea5090d2f266f7e5812637af18227a5d1b 100644 (file)
@@ -10,7 +10,7 @@ from .party import (
     BuyerTradeParty, EndUserTradeParty, InvoiceeTradeParty, PayeeTradeParty,
     SellerTradeParty, SellerTaxRepresentativeTradeParty,
 )
-from .payment import PaymentMeans, PaymentTerms
+from .payment import PaymentMeans, PaymentTerms, TaxApplicableTradeCurrencyExchange
 from .references import (
     AdditionalReferencedDocument, BuyerOrderReferencedDocument,
     ContractReferencedDocument, UltimateCustomerOrderReferencedDocument, ProcuringProjectType, InvoiceReferencedDocument
@@ -68,7 +68,9 @@ class TradeSettlement(Element):
     payee = Field(PayeeTradeParty, required=False, profile=COMFORT,
                   _d="Zahlungsempfänger")
     payment_means = Field(PaymentMeans)
+    invoice_currency = Field(TaxApplicableTradeCurrencyExchange)
     trade_tax = MultiField(ApplicableTradeTax)
+    period = Field(BillingSpecifiedPeriod, required=False, profile=BASIC)
     allowance_charge = MultiField(TradeAllowanceCharge, required=False, profile=COMFORT,
                                   _d="Schalter für Zu-/Abschlag")
     service_charge = MultiField(LogisticsServiceCharge, required=False, profile=COMFORT)
@@ -78,7 +80,6 @@ class TradeSettlement(Element):
     accounting_account = Field(ReceivableAccountingAccount, required=False, profile=EXTENDED,
                                _d="Detailinformationen zur Buchungsreferenz")
     creditor_reference_ID = IDField(NS_RAM, "CreditorReferenceID")
-    period = Field(BillingSpecifiedPeriod, required=False, profile=BASIC)
     tax_currency_code = StringField(NS_RAM, "TaxCurrencyCode", required=False, profile=COMFORT)
     invoice_referenced_document = Field(InvoiceReferencedDocument, required=False, profile=BASIC)
     class Meta:
index dfda603565c6e7247c45602c78e66e8c5f46e755..05e4e6120238ba1df24bd4bb520edd48188989a5 100644 (file)
@@ -108,8 +108,8 @@ class LineSettlement(Element):
     trade_tax = Field(ApplicableTradeTax, required=False, profile=COMFORT)
     accounting_account = Field(AccountingAccount, required=False, profile=EXTENDED,
                                _d="Kostenstelle")
-    monetary_summation = Field(LineSummation, required=False, profile=COMFORT)
     period = Field(BillingSpecifiedPeriod, required=False, profile=COMFORT)
+    monetary_summation = Field(LineSummation, required=False, profile=COMFORT)
     allowance_charge = MultiField(TradeAllowanceCharge, required=False, profile=COMFORT,
                                   _d="Schalter für Zu-/Abschlag")
     invoice_referenced_document = Field(InvoiceReferencedDocument, required=False, profile=EXTENDED)
index 22691c03675fe4899e04c86f8456aa4edaa94d97..9acaca1db0d4319fce36af8001f636be1e73b60e 100644 (file)
@@ -22,7 +22,10 @@ def test_sample_roundtrip(filename):
         open(os.path.join(os.path.dirname(__file__), 'samples', filename), 'rb').read(),
         remove_comments=True
     )
-    schema = 'FACTUR-X_' + filename.split('_')[2]
+    if filename.split('_')[2] != "XRECHNUNG":
+        schema = 'FACTUR-X_' + filename.split('_')[2]
+    else:
+        schema = 'FACTUR-X_EN16931'
 
     # Validate that the sample file is valid, otherwise the test is moot
     validate_xml(xmlout=origxml, schema=schema)