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.
Files changed (50) hide show
  1. {mikrowerk_edi_invoicing-0.5.0/mikrowerk_edi_invoicing.egg-info → mikrowerk_edi_invoicing-0.6.1}/PKG-INFO +1 -1
  2. mikrowerk_edi_invoicing-0.6.1/edi_invoice_parser/__init__.py +19 -0
  3. {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
  4. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cross_industry_invoice_mapper.py +21 -5
  5. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/__init__.py +3 -5
  6. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/trade_document_types.py +60 -40
  7. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/model/xml_abstract_x_rechnung_parser.py +2 -2
  8. mikrowerk_edi_invoicing-0.6.1/edi_invoice_parser/tests/__init__.py +3 -0
  9. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/tests/test_parse_x_rechnung.py +5 -5
  10. {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
  11. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1/mikrowerk_edi_invoicing.egg-info}/PKG-INFO +1 -1
  12. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/SOURCES.txt +0 -10
  13. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/setup.py +1 -1
  14. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/__init__.py +0 -34
  15. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/model/x_rechnung.py +0 -265
  16. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/parse_plain_pdf_file.py +0 -5
  17. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/pdf_llm_parser/__init__.py +0 -5
  18. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/pdf_llm_parser/google_gemini_parser.py +0 -145
  19. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/tests/__init__.py +0 -3
  20. mikrowerk_edi_invoicing-0.5.0/edi_invoice_parser/tests/test_parse_plain_pdf_invoice.py +0 -71
  21. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/LICENSE +0 -0
  22. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/README.md +0 -0
  23. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/__init__.py +0 -0
  24. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/dom_elements_helper.py +0 -0
  25. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/__init__.py +0 -0
  26. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/accounting.py +0 -0
  27. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/container.py +0 -0
  28. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/delivery.py +0 -0
  29. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/document.py +0 -0
  30. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/elements.py +0 -0
  31. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/fields.py +0 -0
  32. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/note.py +0 -0
  33. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/party.py +0 -0
  34. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/payment.py +0 -0
  35. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/product.py +0 -0
  36. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/references.py +0 -0
  37. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/trade.py +0 -0
  38. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/models/tradelines.py +0 -0
  39. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/pdf.py +0 -0
  40. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/utils.py +0 -0
  41. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/cii_dom_parser/xmp_schema.py +0 -0
  42. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/tests/test_iban_handling.py +0 -0
  43. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/ubl_sax_parser/__init__.py +0 -0
  44. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/util/__init__.py +0 -0
  45. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/util/file_helper.py +0 -0
  46. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/edi_invoice_parser/util/timer_helper.py +0 -0
  47. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/dependency_links.txt +0 -0
  48. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/requires.txt +0 -0
  49. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/mikrowerk_edi_invoicing.egg-info/top_level.txt +0 -0
  50. {mikrowerk_edi_invoicing-0.5.0 → mikrowerk_edi_invoicing-0.6.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mikrowerk_edi_invoicing
3
- Version: 0.5.0
3
+ Version: 0.6.1
4
4
  Summary: Parser for EDI invoices in CII or UBL format or plain pdf with LLM support
5
5
  Author: Mikrowerk a Gammadata Division
6
6
  Author-email: info@mikrowerk.com
@@ -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) -> XRechnung:
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) -> XRechnung:
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 XRechnung(
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
- buyer_reference=doc.trade.agreement.buyer_reference.get_string(),
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=XRechnungCurrency.from_currency_tuple(
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=[XRechnungCurrency.from_currency_tuple(tpl) for tpl in
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=XRechnungCurrency.from_currency_tuple(
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
- seller=cls().map_trade_party(doc.trade.agreement.seller) if hasattr(doc.trade.agreement,
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
- buyer=cls().map_trade_party(doc.trade.agreement.buyer) if hasattr(doc.trade.agreement, "buyer") else None,
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) -> XRechnungTradeParty:
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 XRechnungTradeParty(
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
- postal_address=cls().map_trade_address(trade_party.address) if hasattr(trade_party, 'address') else None,
81
- trade_contact=cls().map_trade_contact(trade_party.contact) if hasattr(trade_party, 'contact') else None,
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) -> XRechnungTradeAddress:
115
- return XRechnungTradeAddress(
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) -> XRechnungTradeContact:
127
- return XRechnungTradeContact(
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) -> XRechnungBankAccount:
137
- return XRechnungBankAccount(
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) -> XRechnungFinancialCard:
148
- return XRechnungFinancialCard(
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) -> XRechnungPaymentMeans:
155
- return XRechnungPaymentMeans(
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) -> XRechnungAppliedTradeTax:
165
- return XRechnungAppliedTradeTax(
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) -> [XRechnungTradeLine]:
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) -> XRechnungTradeLine:
183
- return XRechnungTradeLine(
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
- price_unit=trade_line.agreement.net.amount.get_value(),
188
- price_unit_gross=trade_line.agreement.gross.amount.get_value(),
189
- quantity_billed=trade_line.delivery.billed_quantity.get_value(),
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
- total_amount_net=trade_line.settlement.monetary_summation.total_amount.get_value(),
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
- trade_tax=cls().map_trade_tax(trade_line.settlement.trade_tax)
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) -> [XRechnungTradeLine]:
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.x_rechnung import XRechnung
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
- def parse_and_map_x_rechnung(_xml: bytes) -> XRechnung:
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
- if _parser is None:
27
- raise ValueError(f'xml format not supported: "{tree.tag}"')
28
- return _parser.parse_and_map_x_rechnung(_xml)
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
+
@@ -1,17 +1,15 @@
1
- from .x_rechnung import XRechnung
2
1
  from .trade_document_types import TradeDocument, TradeParty, TradePartyAddress, TradeCurrency, TradePartyContact, \
3
- TradeLine, PaymentMeans, AppliedTradeTax, BankAccount, FinancialCard, ubl_doc_codes
2
+ TradeLine, TradePaymentMeans, AppliedTradeTax, BankAccount, FinancialCard, ubl_doc_codes
4
3
  from .xml_abstract_x_rechnung_parser import XMLAbstractXRechnungParser
5
4
 
6
- __all__ = ["XRechnung",
7
- "XMLAbstractXRechnungParser",
5
+ __all__ = ["XMLAbstractXRechnungParser",
8
6
  "TradeDocument",
9
7
  "TradeParty",
10
8
  "TradePartyAddress",
11
9
  "TradeCurrency",
12
10
  "TradePartyContact",
13
11
  "TradeLine",
14
- "PaymentMeans",
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
- vat_registration_number: str = None
52
- fiscal_registration_number: str = None
53
- legal_registration_number: str = None
54
- address: TradePartyAddress = None
55
- contact: TradePartyContact = None
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: Decimal = None
64
- basis_amount: Decimal = None
65
- calculated_amount: Decimal = None
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
- pos_number: int
71
- article_code: str = None
72
- name: str = None
73
- description: str = None
74
- quantity: Decimal = None
75
- unit_of_measure: str = None
76
- unit_price: Decimal = None
77
- total_net: Decimal = None
78
- tax: AppliedTradeTax = None
79
- total_amount: Decimal = None
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: Decimal
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 PaymentMeans:
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: tuple # Document Type Code: ubl_doc_codes
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
- sales_order_reference: str = None
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: PaymentMeans = None
129
- payment_terms: str = None # 'Payment Terms'
130
- line_total_amount: Decimal = None # 'Line Total Amount'
131
- charge_total_amount: Decimal = None # 'Charge Total Amount'
132
- allowance_total_amount: Decimal = None # 'Allowance Total Amount'
133
- tax_basis_total_amount: Decimal = None
134
- tax_total_amount: Decimal = None # 'Tax Grand Total Amount'
135
- grand_total_amount: Decimal = None # 'Grand Total Amount'
136
- total_prepaid_amount: Decimal = None # 'Total Prepaid Amount'
137
- due_payable_amount: Decimal = None # 'Due Payable Amount'
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.x_rechnung import XRechnung
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) -> XRechnung:
20
+ def parse_and_map_x_rechnung(_xml: any) -> TradeDocument:
21
21
  pass
@@ -0,0 +1,3 @@
1
+ from ..util.file_helper import get_checked_file_path
2
+ from ..model.trade_document_types import TradeDocument
3
+ __all__ = ["get_checked_file_path", "TradeDocument"]
@@ -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 XRechnung
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(res_dict))
54
+ # res_dict = _parsed.map_to_dict()
55
+ print(jsonpickle.dumps(_parsed))
56
56
 
57
- def _parse_xml(self, filepath) -> XRechnung:
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) -> XRechnung:
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}")