mikrowerk-edi-invoicing 0.5.0__tar.gz → 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mikrowerk_edi_invoicing-0.5.0/mikrowerk_edi_invoicing.egg-info → mikrowerk_edi_invoicing-0.6.1}/PKG-INFO +1 -1
- mikrowerk_edi_invoicing-0.6.1/edi_invoice_parser/__init__.py +19 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/xml_cii_dom_parser.py +39 -38
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cross_industry_invoice_mapper.py +21 -5
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/__init__.py +3 -5
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/trade_document_types.py +60 -40
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/xml_abstract_x_rechnung_parser.py +2 -2
- mikrowerk_edi_invoicing-0.6.1/edi_invoice_parser/tests/__init__.py +3 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/tests/test_parse_x_rechnung.py +5 -5
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/ubl_sax_parser/xml_ubl_sax_parser.py +45 -45
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1/mikrowerk_edi_invoicing.egg-info}/PKG-INFO +1 -1
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/SOURCES.txt +0 -10
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/setup.py +1 -1
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/__init__.py +0 -34
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/model/x_rechnung.py +0 -265
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/parse_plain_pdf_file.py +0 -5
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/pdf_llm_parser/__init__.py +0 -5
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/pdf_llm_parser/google_gemini_parser.py +0 -145
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/tests/__init__.py +0 -3
- mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/tests/test_parse_plain_pdf_invoice.py +0 -71
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/LICENSE +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/README.md +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/__init__.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/dom_elements_helper.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/__init__.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/accounting.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/container.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/delivery.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/document.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/elements.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/fields.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/note.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/party.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/payment.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/product.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/references.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/trade.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/tradelines.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/pdf.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/utils.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/xmp_schema.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/tests/test_iban_handling.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/ubl_sax_parser/__init__.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/util/__init__.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/util/file_helper.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/util/timer_helper.py +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/dependency_links.txt +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/requires.txt +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/top_level.txt +0 -0
- {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/setup.cfg +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from .cross_industry_invoice_mapper import parse_and_map_x_rechnung
|
|
2
|
+
from .model.trade_document_types import TradeDocument, TradeParty, TradePartyAddress, TradeCurrency, TradePartyContact, \
|
|
3
|
+
TradeLine, TradePaymentMeans, AppliedTradeTax, BankAccount, FinancialCard, ubl_doc_codes
|
|
4
|
+
|
|
5
|
+
__all__ = ["parse_and_map_x_rechnung",
|
|
6
|
+
"TradeDocument",
|
|
7
|
+
"TradeParty",
|
|
8
|
+
"TradePartyAddress",
|
|
9
|
+
"TradeCurrency",
|
|
10
|
+
"TradePartyContact",
|
|
11
|
+
"TradeLine",
|
|
12
|
+
"TradePaymentMeans",
|
|
13
|
+
"AppliedTradeTax",
|
|
14
|
+
"BankAccount",
|
|
15
|
+
"FinancialCard",
|
|
16
|
+
"ubl_doc_codes"
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
version = "0.6.1"
|
|
@@ -4,46 +4,46 @@ This implements a mapper from a drafthorse parsed x-rechnung-xml to the internal
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
|
|
6
6
|
from .models.document import Document
|
|
7
|
-
|
|
7
|
+
from ..model.trade_document_types import (TradeDocument, TradeParty, TradeCurrency, TradeLine, TradePaymentMeans,
|
|
8
|
+
AppliedTradeTax, TradePartyAddress, TradePartyContact, BankAccount,
|
|
9
|
+
FinancialCard)
|
|
8
10
|
from ..model.xml_abstract_x_rechnung_parser import XMLAbstractXRechnungParser
|
|
9
|
-
from ..model.x_rechnung import (XRechnung, XRechnungCurrency, XRechnungTradeParty, XRechnungTradeAddress,
|
|
10
|
-
XRechnungTradeContact, XRechnungPaymentMeans, XRechnungFinancialCard,
|
|
11
|
-
XRechnungTradeLine, XRechnungAppliedTradeTax, XRechnungBankAccount)
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
15
14
|
|
|
16
15
|
@classmethod
|
|
17
|
-
def parse_and_map_x_rechnung(cls, _xml: any) ->
|
|
16
|
+
def parse_and_map_x_rechnung(cls, _xml: any) -> TradeDocument:
|
|
18
17
|
doc = Document.parse(_xml)
|
|
19
18
|
return cls().map_to_x_rechnung(doc)
|
|
20
19
|
|
|
21
20
|
@classmethod
|
|
22
|
-
def map_to_x_rechnung(cls, doc: any) ->
|
|
21
|
+
def map_to_x_rechnung(cls, doc: any) -> TradeDocument:
|
|
23
22
|
"""
|
|
24
23
|
:param doc: Element, the parsed dom root element
|
|
25
24
|
:return:
|
|
26
25
|
"""
|
|
27
26
|
|
|
28
|
-
return
|
|
27
|
+
return TradeDocument(
|
|
29
28
|
name=f"{cls().TYPE_CODES.get(doc.header.type_code.get_string(), 'Unknown doc type ')} {doc.header.id.get_string()}",
|
|
29
|
+
doc_type_name=f"{cls().TYPE_CODES.get(doc.header.type_code.get_string(), 'Unknown doc type ')}",
|
|
30
30
|
doc_id=doc.header.id.get_string(),
|
|
31
31
|
doc_type_code=doc.header.type_code.get_string(),
|
|
32
32
|
issued_date_time=doc.header.issue_date_time.get_value(),
|
|
33
33
|
notes=doc.header.notes.get_string_elements("\n"),
|
|
34
34
|
languages=doc.header.languages.get_string_elements(";"),
|
|
35
|
-
|
|
35
|
+
receiver_reference=doc.trade.agreement.buyer_reference.get_string(),
|
|
36
36
|
order_reference=doc.trade.agreement.buyer_order.issuer_assigned_id.get_string(),
|
|
37
37
|
currency_code=doc.trade.settlement.currency_code.get_string(),
|
|
38
38
|
line_total_amount=doc.trade.settlement.monetary_summation.line_total.get_value(),
|
|
39
39
|
charge_total_amount=doc.trade.settlement.monetary_summation.charge_total.get_value(),
|
|
40
40
|
allowance_total_amount=doc.trade.settlement.monetary_summation.allowance_total.get_value(),
|
|
41
|
-
tax_basis_total_amount=
|
|
41
|
+
tax_basis_total_amount=TradeCurrency.from_currency_tuple(
|
|
42
42
|
doc.trade.settlement.monetary_summation.tax_basis_total.get_currency()),
|
|
43
|
-
tax_total_amount=[
|
|
43
|
+
tax_total_amount=[TradeCurrency.from_currency_tuple(tpl) for tpl in
|
|
44
44
|
doc.trade.settlement.monetary_summation.tax_total_other_currency.get_currencies()],
|
|
45
45
|
# list of currency
|
|
46
|
-
grand_total_amount=
|
|
46
|
+
grand_total_amount=TradeCurrency.from_currency_tuple(
|
|
47
47
|
doc.trade.settlement.monetary_summation.grand_total.get_currency()),
|
|
48
48
|
total_prepaid_amount=doc.trade.settlement.monetary_summation.prepaid_total.get_value(),
|
|
49
49
|
due_payable_amount=doc.trade.settlement.monetary_summation.due_amount.get_value(),
|
|
@@ -51,11 +51,12 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
51
51
|
payment_means=cls().map_payment_means(
|
|
52
52
|
doc.trade.settlement.payment_means) if doc.trade.settlement.payment_means else None,
|
|
53
53
|
payment_terms=doc.trade.settlement.terms.get_string_elements("\n"),
|
|
54
|
-
|
|
54
|
+
sender=cls().map_trade_party(doc.trade.agreement.seller) if hasattr(doc.trade.agreement,
|
|
55
55
|
"seller") else None,
|
|
56
56
|
invoicee=cls().map_trade_party(doc.trade.agreement.invoicee) if hasattr(doc.trade.agreement,
|
|
57
57
|
"invoicee") else None,
|
|
58
|
-
|
|
58
|
+
receiver=cls().map_trade_party(doc.trade.agreement.buyer) if hasattr(doc.trade.agreement,
|
|
59
|
+
"buyer") else None,
|
|
59
60
|
payee=cls().map_trade_party(doc.trade.agreement.payee) if hasattr(doc.trade.agreement, "payee") else None,
|
|
60
61
|
trade_line_items=cls().map_trade_line_items(doc.trade.items) if hasattr(doc.trade, "items") else None,
|
|
61
62
|
applicable_trade_taxes=cls().map_trade_taxes(doc.trade.settlement.trade_tax) if hasattr(
|
|
@@ -64,9 +65,9 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
64
65
|
)
|
|
65
66
|
|
|
66
67
|
@classmethod
|
|
67
|
-
def map_trade_party(cls, trade_party: any) ->
|
|
68
|
+
def map_trade_party(cls, trade_party: any) -> TradeParty:
|
|
68
69
|
_global_id_schema, _global_id = cls().map_first_id(trade_party.global_id)
|
|
69
|
-
return
|
|
70
|
+
return TradeParty(
|
|
70
71
|
name=trade_party.name.get_string(),
|
|
71
72
|
description=trade_party.description.get_string(),
|
|
72
73
|
global_id=_global_id,
|
|
@@ -77,8 +78,8 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
77
78
|
trade_party, 'tax_registrations') else None,
|
|
78
79
|
fiscal_registration_number=cls().map_tax_registration(trade_party.tax_registrations, 'FC') if hasattr(
|
|
79
80
|
trade_party, 'tax_registrations') else None,
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
address=cls().map_trade_address(trade_party.address) if hasattr(trade_party, 'address') else None,
|
|
82
|
+
contact=cls().map_trade_contact(trade_party.contact) if hasattr(trade_party, 'contact') else None,
|
|
82
83
|
id=trade_party.id.get_string() if hasattr(trade_party, 'id') else None,
|
|
83
84
|
)
|
|
84
85
|
|
|
@@ -111,8 +112,8 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
111
112
|
return None
|
|
112
113
|
|
|
113
114
|
@staticmethod
|
|
114
|
-
def map_trade_address(trade_address: any) ->
|
|
115
|
-
return
|
|
115
|
+
def map_trade_address(trade_address: any) -> TradePartyAddress:
|
|
116
|
+
return TradePartyAddress(
|
|
116
117
|
city_name=trade_address.city_name.get_string(),
|
|
117
118
|
country_id=trade_address.country_id.get_string(),
|
|
118
119
|
country_subdivision_id=trade_address.country_subdivision.get_string(),
|
|
@@ -123,8 +124,8 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
123
124
|
)
|
|
124
125
|
|
|
125
126
|
@staticmethod
|
|
126
|
-
def map_trade_contact(trade_contact: any) ->
|
|
127
|
-
return
|
|
127
|
+
def map_trade_contact(trade_contact: any) -> TradePartyContact:
|
|
128
|
+
return TradePartyContact(
|
|
128
129
|
name=trade_contact.person_name.get_string(),
|
|
129
130
|
email=trade_contact.email.get_string(),
|
|
130
131
|
telephone=trade_contact.telephone.get_string(),
|
|
@@ -133,8 +134,8 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
133
134
|
)
|
|
134
135
|
|
|
135
136
|
@staticmethod
|
|
136
|
-
def map_bank_account(payment_means: any) ->
|
|
137
|
-
return
|
|
137
|
+
def map_bank_account(payment_means: any) -> BankAccount:
|
|
138
|
+
return BankAccount(
|
|
138
139
|
iban="".join(payment_means.payee_account.iban.get_string().split()) if (hasattr(payment_means,
|
|
139
140
|
'payee_account')
|
|
140
141
|
and payment_means.payee_account.iban.get_string()) else None,
|
|
@@ -144,15 +145,15 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
144
145
|
)
|
|
145
146
|
|
|
146
147
|
@staticmethod
|
|
147
|
-
def map_financial_card(financial_card: any) ->
|
|
148
|
-
return
|
|
148
|
+
def map_financial_card(financial_card: any) -> FinancialCard:
|
|
149
|
+
return FinancialCard(
|
|
149
150
|
id=financial_card.id.get_string(),
|
|
150
151
|
cardholder_name=financial_card.cardholder_name.get_string(),
|
|
151
152
|
)
|
|
152
153
|
|
|
153
154
|
@classmethod
|
|
154
|
-
def map_payment_means(cls, payment_means: any) ->
|
|
155
|
-
return
|
|
155
|
+
def map_payment_means(cls, payment_means: any) -> TradePaymentMeans:
|
|
156
|
+
return TradePaymentMeans(
|
|
156
157
|
information=payment_means.information.get_string(),
|
|
157
158
|
type_code=payment_means.type_code.get_string(),
|
|
158
159
|
payee_account=cls().map_bank_account(payment_means) if hasattr(payment_means, 'payee_account') else None,
|
|
@@ -161,8 +162,8 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
161
162
|
)
|
|
162
163
|
|
|
163
164
|
@staticmethod
|
|
164
|
-
def map_trade_tax(trade_tax: any) ->
|
|
165
|
-
return
|
|
165
|
+
def map_trade_tax(trade_tax: any) -> AppliedTradeTax:
|
|
166
|
+
return AppliedTradeTax(
|
|
166
167
|
type_code=trade_tax.type_code.get_string(),
|
|
167
168
|
name=f"{trade_tax.type_code.get_string()} {trade_tax.rate_applicable_percent.get_value()}",
|
|
168
169
|
category_code=trade_tax.category_code.get_string(),
|
|
@@ -172,33 +173,33 @@ class XRechnungCIIXMLParser(XMLAbstractXRechnungParser):
|
|
|
172
173
|
)
|
|
173
174
|
|
|
174
175
|
@classmethod
|
|
175
|
-
def map_trade_taxes(cls, trade_taxes: any) -> [
|
|
176
|
+
def map_trade_taxes(cls, trade_taxes: any) -> [TradeLine]:
|
|
176
177
|
res = []
|
|
177
178
|
for child in trade_taxes.children:
|
|
178
179
|
res.append(cls().map_trade_tax(child))
|
|
179
180
|
return res
|
|
180
181
|
|
|
181
182
|
@classmethod
|
|
182
|
-
def map_trade_line(cls, trade_line: any) ->
|
|
183
|
-
return
|
|
183
|
+
def map_trade_line(cls, trade_line: any) -> TradeLine:
|
|
184
|
+
return TradeLine(
|
|
184
185
|
name=trade_line.product.name.get_string(),
|
|
185
186
|
description=trade_line.product.description.get_string(),
|
|
186
187
|
line_id=trade_line.document.line_id.get_string(),
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
unit_price=trade_line.agreement.net.amount.get_value(),
|
|
189
|
+
unit_price_gross=trade_line.agreement.gross.amount.get_value(),
|
|
190
|
+
quantity=trade_line.delivery.billed_quantity.get_value(),
|
|
190
191
|
global_product_id=trade_line.product.global_id.get_string(),
|
|
191
|
-
|
|
192
|
+
total_amount=trade_line.settlement.monetary_summation.total_amount.get_value(),
|
|
192
193
|
total_allowance_charge=trade_line.settlement.monetary_summation.total_allowance_charge.get_value(),
|
|
193
194
|
quantity_unit_code=trade_line.delivery.billed_quantity._unit_code,
|
|
194
195
|
seller_assigned_id=trade_line.product.seller_assigned_id.get_string(),
|
|
195
196
|
buyer_assigned_id=trade_line.product.buyer_assigned_id.get_string(),
|
|
196
197
|
global_product_scheme_id=trade_line.product.global_id._scheme_id,
|
|
197
|
-
|
|
198
|
+
tax=cls().map_trade_tax(trade_line.settlement.trade_tax)
|
|
198
199
|
)
|
|
199
200
|
|
|
200
201
|
@classmethod
|
|
201
|
-
def map_trade_line_items(cls, trade_line_items: any) -> [
|
|
202
|
+
def map_trade_line_items(cls, trade_line_items: any) -> [TradeLine]:
|
|
202
203
|
res = []
|
|
203
204
|
for child in trade_line_items.children:
|
|
204
205
|
res.append(cls().map_trade_line(child))
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"""
|
|
2
2
|
This implements a mapper from a drafthorse parsed x-rechnung-xml to the internal XRechnung object
|
|
3
3
|
"""
|
|
4
|
+
import logging
|
|
4
5
|
from lxml import etree
|
|
5
6
|
|
|
6
|
-
from .model.
|
|
7
|
+
from .model.trade_document_types import TradeDocument
|
|
7
8
|
from .cii_dom_parser import XRechnungCIIXMLParser
|
|
8
9
|
from .ubl_sax_parser.xml_ubl_sax_parser import XRechnungUblXMLParser
|
|
10
|
+
from .model.xml_abstract_x_rechnung_parser import XMLAbstractXRechnungParser
|
|
9
11
|
|
|
12
|
+
_logger = logging.getLogger(__name__)
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
|
|
15
|
+
def parse_and_map_x_rechnung(_xml: bytes) -> TradeDocument:
|
|
12
16
|
"""
|
|
13
17
|
|
|
14
18
|
Args:
|
|
@@ -17,12 +21,24 @@ def parse_and_map_x_rechnung(_xml: bytes) -> XRechnung:
|
|
|
17
21
|
Returns: XRechnung
|
|
18
22
|
|
|
19
23
|
"""
|
|
24
|
+
_parser = get_xml_parser_for_doc_type(_xml)
|
|
25
|
+
if _parser is None:
|
|
26
|
+
raise ValueError('xml format not supported for any parser"')
|
|
27
|
+
return _parser.parse_and_map_x_rechnung(_xml)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_xml_parser_for_doc_type(_xml: bytes) -> XMLAbstractXRechnungParser:
|
|
20
31
|
_parser = None
|
|
21
32
|
tree = etree.fromstring(_xml)
|
|
22
33
|
if tree.tag == '{urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100}CrossIndustryInvoice':
|
|
23
34
|
_parser = XRechnungCIIXMLParser()
|
|
24
35
|
elif tree.tag == '{urn:oasis:names:specification:ubl:schema:xsd:Invoice-2}Invoice':
|
|
25
36
|
_parser = XRechnungUblXMLParser()
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return _parser
|
|
37
|
+
else:
|
|
38
|
+
_logger.warning(f'No parser found, unsupported XML tag: {tree.tag}')
|
|
39
|
+
return _parser
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def check_if_parser_is_available(_xml: bytes) -> bool:
|
|
43
|
+
return get_xml_parser_for_doc_type(_xml) is not None
|
|
44
|
+
|
{mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/__init__.py
RENAMED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
from .x_rechnung import XRechnung
|
|
2
1
|
from .trade_document_types import TradeDocument, TradeParty, TradePartyAddress, TradeCurrency, TradePartyContact, \
|
|
3
|
-
TradeLine,
|
|
2
|
+
TradeLine, TradePaymentMeans, AppliedTradeTax, BankAccount, FinancialCard, ubl_doc_codes
|
|
4
3
|
from .xml_abstract_x_rechnung_parser import XMLAbstractXRechnungParser
|
|
5
4
|
|
|
6
|
-
__all__ = ["
|
|
7
|
-
"XMLAbstractXRechnungParser",
|
|
5
|
+
__all__ = ["XMLAbstractXRechnungParser",
|
|
8
6
|
"TradeDocument",
|
|
9
7
|
"TradeParty",
|
|
10
8
|
"TradePartyAddress",
|
|
11
9
|
"TradeCurrency",
|
|
12
10
|
"TradePartyContact",
|
|
13
11
|
"TradeLine",
|
|
14
|
-
"
|
|
12
|
+
"TradePaymentMeans",
|
|
15
13
|
"AppliedTradeTax",
|
|
16
14
|
"BankAccount",
|
|
17
15
|
"FinancialCard",
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from decimal import Decimal
|
|
3
2
|
import datetime
|
|
4
3
|
|
|
5
4
|
"""
|
|
@@ -38,7 +37,7 @@ class TradePartyAddress:
|
|
|
38
37
|
|
|
39
38
|
@dataclass
|
|
40
39
|
class TradePartyContact:
|
|
41
|
-
name: str
|
|
40
|
+
name: str = None
|
|
42
41
|
department_name: str = None
|
|
43
42
|
telephone: str = None
|
|
44
43
|
fax: str = None
|
|
@@ -47,47 +46,62 @@ class TradePartyContact:
|
|
|
47
46
|
|
|
48
47
|
@dataclass
|
|
49
48
|
class TradeParty:
|
|
50
|
-
name: str
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
name: str= None
|
|
50
|
+
description: str = None # 'Description'
|
|
51
|
+
global_id: int = 0 # 'Global ID'
|
|
52
|
+
global_id_schema: str = None # 'Global Schema'
|
|
53
|
+
id: str = None # 'id'
|
|
54
|
+
address: TradePartyAddress | None = None
|
|
55
|
+
contact: TradePartyContact | None = None
|
|
56
|
+
email: str = None # 'Email'
|
|
57
|
+
vat_registration_number: str | None = None
|
|
58
|
+
fiscal_registration_number: str | None = None
|
|
59
|
+
legal_registration_number: str | None = None
|
|
56
60
|
|
|
57
61
|
|
|
58
62
|
@dataclass
|
|
59
63
|
class AppliedTradeTax:
|
|
60
|
-
name: str
|
|
64
|
+
name: str = None
|
|
61
65
|
type_code: str = None
|
|
62
66
|
category_code: str = None
|
|
63
|
-
applicable_percent:
|
|
64
|
-
basis_amount:
|
|
65
|
-
calculated_amount:
|
|
67
|
+
applicable_percent: float = None
|
|
68
|
+
basis_amount: float = None
|
|
69
|
+
calculated_amount: float = None
|
|
66
70
|
|
|
67
71
|
|
|
68
72
|
@dataclass
|
|
69
73
|
class TradeLine:
|
|
70
|
-
|
|
71
|
-
article_code: str = None
|
|
72
|
-
name: str = None
|
|
73
|
-
description: str = None
|
|
74
|
-
quantity:
|
|
75
|
-
|
|
76
|
-
unit_price:
|
|
77
|
-
|
|
78
|
-
tax: AppliedTradeTax = None
|
|
79
|
-
|
|
74
|
+
line_id: int = 0
|
|
75
|
+
article_code: str | None = None
|
|
76
|
+
name: str | None = None
|
|
77
|
+
description: str | None = None
|
|
78
|
+
quantity: float = None
|
|
79
|
+
quantity_unit_code: str = None
|
|
80
|
+
unit_price: float = None
|
|
81
|
+
unit_price_gross: float = None
|
|
82
|
+
tax: AppliedTradeTax | None = None
|
|
83
|
+
total_amount_net: float = None
|
|
84
|
+
total_amount: float = None
|
|
85
|
+
total_allowance_charge: float = None
|
|
86
|
+
global_product_id: str = None # 'Global Product ID')
|
|
87
|
+
global_product_scheme_id: str = None # 'Global Product Scheme ID')
|
|
88
|
+
seller_assigned_id: str = None # 'Seller Assigned ID')
|
|
89
|
+
buyer_assigned_id: str = None # 'Buyer Assigned ID')
|
|
80
90
|
|
|
81
91
|
|
|
82
92
|
@dataclass
|
|
83
93
|
class TradeCurrency:
|
|
84
|
-
amount:
|
|
94
|
+
amount: float
|
|
85
95
|
currency_code: str
|
|
86
96
|
|
|
97
|
+
@staticmethod
|
|
98
|
+
def from_currency_tuple(currency_tuple: tuple) -> 'TradeCurrency':
|
|
99
|
+
return TradeCurrency(*currency_tuple)
|
|
100
|
+
|
|
87
101
|
|
|
88
102
|
@dataclass
|
|
89
103
|
class BankAccount:
|
|
90
|
-
iban: str
|
|
104
|
+
iban: str | None = None
|
|
91
105
|
bic: str = None
|
|
92
106
|
name: str = None
|
|
93
107
|
|
|
@@ -99,7 +113,7 @@ class FinancialCard:
|
|
|
99
113
|
|
|
100
114
|
|
|
101
115
|
@dataclass
|
|
102
|
-
class
|
|
116
|
+
class TradePaymentMeans:
|
|
103
117
|
id: str = None
|
|
104
118
|
type_code: str = None
|
|
105
119
|
information: str = None
|
|
@@ -112,28 +126,34 @@ class TradeDocument:
|
|
|
112
126
|
"""
|
|
113
127
|
Model of a Trade Document
|
|
114
128
|
"""
|
|
115
|
-
name: str
|
|
116
|
-
doc_type_code:
|
|
129
|
+
name: str = None
|
|
130
|
+
doc_type_code: int = 0 # Document Type Code: ubl_doc_codes
|
|
131
|
+
doc_type_name: str = None
|
|
117
132
|
doc_id: str = None
|
|
133
|
+
project: str = None
|
|
118
134
|
issued_date_time: datetime = None # 'Date'
|
|
135
|
+
delivered_date_time: datetime = None # 'Delivered Date'
|
|
119
136
|
languages: str = None # 'Languages'
|
|
120
137
|
notes: str = None # 'Notes'
|
|
121
138
|
sender_reference: str = None # 'Buyer Reference'
|
|
122
|
-
receiver_reference: str = None
|
|
123
|
-
dispatch_reference: str = None
|
|
124
|
-
|
|
139
|
+
receiver_reference: str | None = None
|
|
140
|
+
dispatch_reference: str | None = None
|
|
141
|
+
order_reference: str | None = None
|
|
125
142
|
sender: TradeParty = None
|
|
126
143
|
receiver: TradeParty = None
|
|
144
|
+
payee: TradeParty = None
|
|
145
|
+
invoicee: TradeParty = None
|
|
127
146
|
currency_code: str = None # 'Currency Code'
|
|
128
|
-
payment_means:
|
|
129
|
-
payment_terms: str = None # 'Payment Terms'
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
payment_means: TradePaymentMeans = None
|
|
148
|
+
payment_terms: str | None = None # 'Payment Terms'
|
|
149
|
+
due_date_time: datetime = None
|
|
150
|
+
line_total_amount: float = None # 'Line Total Amount'
|
|
151
|
+
charge_total_amount: float = None # 'Charge Total Amount'
|
|
152
|
+
allowance_total_amount: float = None # 'Allowance Total Amount'
|
|
153
|
+
tax_basis_total_amount: TradeCurrency = None
|
|
154
|
+
tax_total_amount: [TradeCurrency] = None # 'Tax Grand Total Amount'
|
|
155
|
+
grand_total_amount: TradeCurrency = None # 'Grand Total Amount'
|
|
156
|
+
total_prepaid_amount: float = None # 'Total Prepaid Amount'
|
|
157
|
+
due_payable_amount: float = None # 'Due Payable Amount'
|
|
138
158
|
trade_line_items: [TradeLine] = None
|
|
139
159
|
applicable_trade_taxes: [AppliedTradeTax] = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
|
|
3
|
-
from ..model.
|
|
3
|
+
from ..model.trade_document_types import TradeDocument
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class XMLAbstractXRechnungParser(ABC):
|
|
@@ -17,5 +17,5 @@ class XMLAbstractXRechnungParser(ABC):
|
|
|
17
17
|
|
|
18
18
|
@staticmethod
|
|
19
19
|
@abstractmethod
|
|
20
|
-
def parse_and_map_x_rechnung(_xml: any) ->
|
|
20
|
+
def parse_and_map_x_rechnung(_xml: any) -> TradeDocument:
|
|
21
21
|
pass
|
|
@@ -6,7 +6,7 @@ from facturx import get_facturx_xml_from_pdf
|
|
|
6
6
|
|
|
7
7
|
from . import get_checked_file_path
|
|
8
8
|
from edi_invoice_parser.cross_industry_invoice_mapper import parse_and_map_x_rechnung
|
|
9
|
-
from . import
|
|
9
|
+
from . import TradeDocument
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class XRechnungEinfachTestCase(unittest.TestCase):
|
|
@@ -51,10 +51,10 @@ class XRechnungEinfachTestCase(unittest.TestCase):
|
|
|
51
51
|
else:
|
|
52
52
|
raise AssertionError(f'File type {file_type} not supported')
|
|
53
53
|
assert _parsed is not None
|
|
54
|
-
res_dict = _parsed.map_to_dict()
|
|
55
|
-
print(jsonpickle.dumps(
|
|
54
|
+
# res_dict = _parsed.map_to_dict()
|
|
55
|
+
print(jsonpickle.dumps(_parsed))
|
|
56
56
|
|
|
57
|
-
def _parse_xml(self, filepath) ->
|
|
57
|
+
def _parse_xml(self, filepath) -> TradeDocument:
|
|
58
58
|
_file_path, _exists, _is_dir = get_checked_file_path(filepath, __file__)
|
|
59
59
|
self.assertTrue(_exists)
|
|
60
60
|
print(f"\n_parse_xml: file_path={_file_path}")
|
|
@@ -64,7 +64,7 @@ class XRechnungEinfachTestCase(unittest.TestCase):
|
|
|
64
64
|
self.assertIsNotNone(res)
|
|
65
65
|
return res
|
|
66
66
|
|
|
67
|
-
def _parse_pdf(self, filepath) ->
|
|
67
|
+
def _parse_pdf(self, filepath) -> TradeDocument:
|
|
68
68
|
_file_path, _exists, _is_dir = get_checked_file_path(filepath, __file__)
|
|
69
69
|
self.assertTrue(_exists)
|
|
70
70
|
print(f"\n_parse_pdf: file_path={_file_path}")
|