From e7ef6228be17db112b9eb6c0f7387028fd977426 Mon Sep 17 00:00:00 2001
From: 0xD0M1M0 <76812428+0xD0M1M0@users.noreply.github.com>
Date: Mon, 27 Apr 2026 12:58:42 +0200
Subject: [PATCH 1/3] feat: add BT-120 VAT exemption reason (#247)
(cherry picked from commit cec83b5bf82bcf7415c65828f571179b5fb11ea7)
# Conflicts:
# eu_einvoice/locale/de.po
# eu_einvoice/locale/main.pot
---
.../custom/sales_invoice.py | 15 ++-
.../e_invoice_import/e_invoice_import.py | 3 +
.../e_invoice_settings.json | 15 ++-
.../e_invoice_settings/e_invoice_settings.py | 1 +
.../e_invoice_trade_tax.json | 9 +-
.../e_invoice_trade_tax.py | 1 +
eu_einvoice/locale/de.po | 108 ++++++++++++++----
eu_einvoice/locale/main.pot | 104 +++++++++++++----
8 files changed, 208 insertions(+), 48 deletions(-)
diff --git a/eu_einvoice/european_e_invoice/custom/sales_invoice.py b/eu_einvoice/european_e_invoice/custom/sales_invoice.py
index da4ba878..e57ef6e3 100644
--- a/eu_einvoice/european_e_invoice/custom/sales_invoice.py
+++ b/eu_einvoice/european_e_invoice/custom/sales_invoice.py
@@ -127,6 +127,7 @@ def __init__(
self.doc = None
self.item_tax_rates = set()
self.delivery_dates = []
+ self.vat_exemption_reason_text = ""
def get_einvoice(self) -> Document | None:
"""Return the einvoice document as a Python object."""
@@ -135,6 +136,9 @@ def get_einvoice(self) -> Document | None:
def create_einvoice(self):
"""Create the einvoice document as a Python object."""
self.doc = Document()
+ self.vat_exemption_reason_text = str(
+ frappe.db.get_single_value("E Invoice Settings", "vat_exemption_reason_text") or ""
+ ).strip()
self._set_context()
self._set_header()
@@ -273,7 +277,10 @@ def _set_seller(self):
self._set_seller_address()
def _set_seller_id(self):
- for row in self.customer.supplier_numbers:
+ supplier_numbers = getattr(self.customer, "supplier_numbers", None)
+ if not supplier_numbers:
+ return
+ for row in supplier_numbers:
if row.company == self.invoice.company and row.supplier_number:
self.doc.trade.agreement.seller.id = row.supplier_number
break
@@ -486,6 +493,7 @@ def _add_line_item(self, item: SalesInvoiceItem):
("Sales Taxes and Charges Template", self.invoice.taxes_and_charges),
]
).upper()
+ self._set_optional_vat_exemption_reason_text(li.settlement.trade_tax)
li.settlement.monetary_summation.total_amount = flt(item.net_amount, item.precision("net_amount"))
self.doc.trade.items.add(li)
@@ -614,8 +622,13 @@ def _add_empty_tax(self):
("Sales Taxes and Charges Template", self.invoice.taxes_and_charges),
]
).upper()
+ self._set_optional_vat_exemption_reason_text(trade_tax)
self.doc.trade.settlement.trade_tax.add(trade_tax)
+ def _set_optional_vat_exemption_reason_text(self, trade_tax: ApplicableTradeTax) -> None:
+ if self.vat_exemption_reason_text:
+ trade_tax.exemption_reason = self.vat_exemption_reason_text
+
def _add_delivery_date(self):
if self.delivery_dates:
delivery_date = sorted(self.delivery_dates)[-1]
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py b/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py
index 2a402a74..34d8d8b5 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py
@@ -1,6 +1,7 @@
# Copyright (c) 2024, ALYF GmbH and contributors
# For license information, please see license.txt
+from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING
@@ -279,6 +280,8 @@ def parse_tax(self, tax: "ApplicableTradeTax"):
t.basis_amount = flt_or_none(tax.basis_amount._value)
t.rate_applicable_percent = flt_or_none(tax.rate_applicable_percent._value)
t.calculated_amount = flt_or_none(tax.calculated_amount._value)
+ reason_text = tax.exemption_reason._text
+ t.vat_exemption_reason_text = str(reason_text).strip() if reason_text else None
def parse_payment_term(self, term: "PaymentTerms"):
if not term.partial_amount.children:
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json b/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
index 9b5f467f..d63ab1d8 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
@@ -12,6 +12,8 @@
"error_action_on_save",
"error_action_on_submit",
"sales_invoice_number_field",
+ "section_break_bt120",
+ "vat_exemption_reason_text",
"section_break_yldr",
"auto_attach_xml",
"attach_field_for_xml_file"
@@ -74,13 +76,24 @@
"fieldname": "sales_invoice_number_field",
"fieldtype": "Autocomplete",
"label": "Sales Invoice Number Field"
+ },
+ {
+ "fieldname": "section_break_bt120",
+ "fieldtype": "Section Break",
+ "label": "VAT exemption (e-invoice)"
+ },
+ {
+ "description": "If set, written to BT-120 (ram:ExemptionReason) on VAT breakdowns where an exemption reason code is emitted. Left unset in the XML when empty.",
+ "fieldname": "vat_exemption_reason_text",
+ "fieldtype": "Small Text",
+ "label": "Default VAT exemption reason"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2026-02-06 17:52:09.990716",
+ "modified": "2026-04-21 12:00:00.000000",
"modified_by": "Administrator",
"module": "European e-Invoice",
"name": "E Invoice Settings",
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py b/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py
index f61bdfcf..48197706 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py
@@ -23,6 +23,7 @@ class EInvoiceSettings(Document):
sales_invoice_number_field: DF.Autocomplete | None
validate_sales_invoice_on_save: DF.Check
validate_sales_invoice_on_submit: DF.Check
+ vat_exemption_reason_text: DF.SmallText | None
# end: auto-generated types
def before_validate(self):
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json b/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
index 8a631c44..440d87bf 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
@@ -9,6 +9,7 @@
"basis_amount",
"rate_applicable_percent",
"calculated_amount",
+ "vat_exemption_reason_text",
"tax_account"
],
"fields": [
@@ -35,6 +36,12 @@
"options": "currency",
"read_only": 1
},
+ {
+ "fieldname": "vat_exemption_reason_text",
+ "fieldtype": "Small Text",
+ "label": "VAT exemption reason",
+ "read_only": 1
+ },
{
"fieldname": "tax_account",
"fieldtype": "Link",
@@ -45,7 +52,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2024-09-26 21:18:13.837830",
+ "modified": "2026-04-21 14:00:00.000000",
"modified_by": "Administrator",
"module": "European e-Invoice",
"name": "E Invoice Trade Tax",
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.py b/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.py
index c63ad54f..76032038 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.py
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.py
@@ -21,6 +21,7 @@ class EInvoiceTradeTax(Document):
parenttype: DF.Data
rate_applicable_percent: DF.Percent
tax_account: DF.Link | None
+ vat_exemption_reason_text: DF.SmallText | None
# end: auto-generated types
pass
diff --git a/eu_einvoice/locale/de.po b/eu_einvoice/locale/de.po
index 2442c32b..f294d9fa 100644
--- a/eu_einvoice/locale/de.po
+++ b/eu_einvoice/locale/de.po
@@ -7,7 +7,11 @@ msgid ""
msgstr ""
"Project-Id-Version: European e-Invoice VERSION\n"
"Report-Msgid-Bugs-To: hallo@alyf.de\n"
+<<<<<<< HEAD
"POT-Creation-Date: 2026-02-06 18:13+0053\n"
+=======
+"POT-Creation-Date: 2026-04-21 15:04+0000\n"
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
"PO-Revision-Date: 2026-02-05 11:13+0100\n"
"Last-Translator: hallo@alyf.de\n"
"Language: de\n"
@@ -18,7 +22,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.13.1\n"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:785
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:803
msgid "A document level discount is currently not supported in the e-invoice."
msgstr "Ein Rabatt auf der Dokumentebene wird in der E-Rechnung derzeit nicht unterstützt."
@@ -61,7 +65,7 @@ msgstr "Abschläge gesamt"
msgid "Amended From"
msgstr "Korrektur von"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:105
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:106
msgid "An E Invoice Import with the same Invoice ID and Supplier already exists."
msgstr "Eine E-Rechnung mit der gleichen Rechnungs-ID und Lieferanten existiert bereits."
@@ -170,11 +174,11 @@ msgstr "Berechneter Betrag"
msgid "Calculation Percent"
msgstr "Berechnung Prozentsatz"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:816
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:834
msgid "Cannot create E Invoice."
msgstr "E-Rechnung konnte nicht erstellt werden."
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:830
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:848
msgid "Cannot validate E Invoice schematron."
msgstr "E-Rechnung konnte nicht validiert werden."
@@ -183,6 +187,7 @@ msgstr "E-Rechnung konnte nicht validiert werden."
msgid "Charge Total"
msgstr "Zuschläge gesamt"
+<<<<<<< HEAD
#. Label of a Link in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "Code List"
@@ -202,6 +207,9 @@ msgstr ""
#. Label of a Link field in DocType 'E Invoice Import'
#. Label of a Link field in DocType 'Supplier Number At Customer'
#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
+=======
+#. Label of a Link field in DocType 'E Invoice Import'
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
#: eu_einvoice/european_e_invoice/doctype/supplier_number_at_customer/supplier_number_at_customer.json
msgid "Company"
@@ -213,7 +221,7 @@ msgstr "Unternehmen"
msgid "Configure this if you are storing custom invoice numbers in a field other than name."
msgstr "Konfigurieren Sie dies, wenn Sie benutzerdefinierte Rechnungsnummern in einem anderen Feld als name speichern."
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:211
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:212
msgid "Could not validate E Invoice schematron. See Error Log for details."
msgstr "E-Rechnung konnte nicht validiert werden. Details im Fehlerlog."
@@ -227,7 +235,7 @@ msgid "Create Item"
msgstr "Artikel erstellen"
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.js:93
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:434
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:437
msgid "Create Purchase Invoice"
msgstr "Eingangsrechnung erstellen"
@@ -246,6 +254,7 @@ msgstr "Lieferanten-Adresse erstellen"
msgid "Currency"
msgstr "Währung"
+<<<<<<< HEAD
#. Label of a Data field in DocType 'Customer Number At Supplier'
#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
msgid "Customer Number"
@@ -259,6 +268,12 @@ msgstr "Kundennummer beim Lieferanten"
#: eu_einvoice/custom_fields.py:121
msgid "Customer numbers assigned by the supplier"
msgstr "Kundennummern, die vom Lieferanten zugewiesen wurden"
+=======
+#. Label of a Small Text field in DocType 'E Invoice Settings'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+msgid "Default VAT exemption reason"
+msgstr ""
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Tab Break field in DocType 'E Invoice Import'
#. Label of a Section Break field in DocType 'E Invoice Item'
@@ -308,12 +323,16 @@ msgstr "Fälliger Betrag"
msgid "E Invoice Import"
msgstr "E-Rechnungs-Import"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:650
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:653
msgid "E Invoice Import {0} does not exist"
msgstr "E-Rechnungs-Import {0} existiert nicht"
#. Label of a Check field in DocType 'E Invoice Import'
+<<<<<<< HEAD
#: eu_einvoice/custom_fields.py:181
+=======
+#: eu_einvoice/custom_fields.py:165
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "E Invoice Is Correct"
msgstr "E-Rechnung ist korrekt"
@@ -344,7 +363,7 @@ msgstr "E-Rechnungs-Einstellungen"
msgid "E Invoice Trade Tax"
msgstr "E-Rechnungs-Steuer"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:798
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:816
msgid "E Invoice is not correct"
msgstr "E-Rechnung ist nicht korrekt"
@@ -384,11 +403,11 @@ msgstr "Eingebettetes Dokument"
msgid "Error Message"
msgstr "Fehlermeldung"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:50
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:51
msgid "Field '{0}' does not exist on Sales Invoice doctype"
msgstr "Feld '{0}' existiert nicht im DocType 'Sales Invoice'"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:58
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:59
msgid "Field '{0}' must be of type 'Attach'. Current type: {1}"
msgstr "Feld '{0}' muss vom Typ 'Anhängen' sein. Aktueller Typ: {1}"
@@ -410,8 +429,17 @@ msgstr "Kopfzeile"
#. Label of a Data field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "IBAN"
-msgstr ""
+msgstr "IBAN"
+<<<<<<< HEAD
+=======
+#. Description of the 'Default VAT exemption reason' (Small Text) field in
+#. DocType 'E Invoice Settings'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+msgid "If set, written to BT-120 (ram:ExemptionReason) on VAT breakdowns where an exemption reason code is emitted. Left unset in the XML when empty."
+msgstr "Wenn ausgefüllt, wird der Text als BT-120 (ram:ExemptionReason) in der Steueraufschlüsselung geschrieben, sobald ein Befreiungsgrundcode ausgegeben wird. Bleibt das Feld leer, wird BT-120 im XML nicht gesetzt."
+
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Data field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Invoice ID"
@@ -452,6 +480,7 @@ msgstr "Gesamtbeträge"
msgid "Net Rate"
msgstr "Nettopreis"
+<<<<<<< HEAD
#. Label of a shortcut in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "New E Invoice Import"
@@ -463,10 +492,13 @@ msgid "New Sales Invoice"
msgstr "Neue Ausgangsrechnung"
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:443
+=======
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:446
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
msgid "No machine-readable data was found in the PDF file. You can create a regular Purchase Invoice manually instead."
msgstr "In der PDF-Datei wurden keine maschinenlesbaren Daten gefunden. Sie können stattdessen eine reguläre Eingangsrechnung manuell erstellen."
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:446
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:449
msgid "Not an E-Invoice"
msgstr "Keine E-Rechnung"
@@ -491,11 +523,11 @@ msgstr "Zahlungsmittel"
msgid "Payment Terms"
msgstr "Zahlungsbedingungen"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:119
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:120
msgid "Please create or select a supplier before submitting"
msgstr "Bitte vor dem Buchen einen Lieferanten auswählen oder erstellen."
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:125
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:126
msgid "Please map all invoice lines to an item before submitting"
msgstr "Bitte vor dem Buchen alle Positionen einem Artikel zuordnen."
@@ -503,7 +535,7 @@ msgstr "Bitte vor dem Buchen alle Positionen einem Artikel zuordnen."
msgid "Please note the validation errors of the e-invoice."
msgstr "Bitte beachten Sie die Validierungsfehler der E-Rechnung."
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:122
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:123
msgid "Please select a company before submitting"
msgstr "Bitte vor dem Buchen ein Unternehmen auswählen."
@@ -530,9 +562,15 @@ msgstr "Profil"
#. Linked DocType in E Invoice Import's connections
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Purchase Invoice"
+<<<<<<< HEAD
msgstr ""
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:644
+=======
+msgstr "Eingangsrechnung"
+
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:647
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
msgid "Purchase Invoice {0} is already linked to E Invoice Import {1}"
msgstr "Eingangsrechnung {0} ist bereits mit E-Rechnungs-Import {1} verknüpft"
@@ -561,7 +599,7 @@ msgstr ""
msgid "Rate Applicable Percent"
msgstr "Anwendbarer Prozentsatz"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:670
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:673
msgid "Row {0}"
msgstr "Zeile {0}"
@@ -637,11 +675,14 @@ msgstr "Verkäufer-Steuer-ID"
msgid "Settlement"
msgstr "Ausgleich"
+<<<<<<< HEAD
#. Label of a Card Break in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "Setup"
msgstr ""
+=======
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Link field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Supplier"
@@ -705,11 +746,11 @@ msgstr "Steuer gesamt"
msgid "Taxes"
msgstr "Steuern"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:453
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:456
msgid "The format of the uploaded file ({0}) is not supported for E-Invoices. Please upload a valid E-Invoice file or create a regular Purchase Invoice manually instead."
msgstr "Das Format der hochgeladenen Datei ({0}) wird für E-Rechnungen nicht unterstützt. Bitte laden Sie eine gültige E-Rechnungsdatei hoch oder erstellen Sie stattdessen eine reguläre Eingangsrechnung manuell."
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:160
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:161
msgid "The uploaded file does not contain valid XML data."
msgstr "Die hochgeladene Datei enthält keine gültige XML-Daten."
@@ -733,7 +774,7 @@ msgstr "Einheit"
msgid "Unit Code"
msgstr "Einheits-Code"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:456
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:459
msgid "Unsupported file format"
msgstr "Nicht unterstütztes Dateiformat"
@@ -742,6 +783,19 @@ msgstr "Nicht unterstütztes Dateiformat"
msgid "Upload the .xml or .pdf file provided by your supplier."
msgstr "Laden Sie die von Ihrem Lieferanten bereitgestellte .xml- oder .pdf-Datei hoch."
+<<<<<<< HEAD
+=======
+#. Label of a Section Break field in DocType 'E Invoice Settings'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+msgid "VAT exemption (e-invoice)"
+msgstr "Umsatzsteuerbefreiung (E-Rechnung)"
+
+#. Label of a Small Text field in DocType 'E Invoice Trade Tax'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
+msgid "VAT exemption reason"
+msgstr "Grund für Umsatzsteuerbefreiung"
+
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Check field in DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
msgid "Validate Sales Invoice on Save"
@@ -758,13 +812,21 @@ msgid "Validation Details"
msgstr "Validierungsdetails"
#. Label of a Text field in DocType 'E Invoice Import'
+<<<<<<< HEAD
#: eu_einvoice/custom_fields.py:191
+=======
+#: eu_einvoice/custom_fields.py:175
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Validation Errors"
msgstr "Validierungsfehler"
#. Label of a Text field in DocType 'E Invoice Import'
+<<<<<<< HEAD
#: eu_einvoice/custom_fields.py:201
+=======
+#: eu_einvoice/custom_fields.py:185
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Validation Warnings"
msgstr "Validierungswarnungen"
@@ -780,19 +842,19 @@ msgstr "{0} ansehen"
msgid "Warning Message"
msgstr "Warnung"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:764
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:782
msgid "{0} row #{1}: Discount Date should be after Posting Date"
msgstr "{0} Zeile {1}: Rabatt-Datum sollte nach Buchungsdatum liegen"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:753
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:771
msgid "{0} row #{1}: The charge type 'Actual' is only supported in the eInvoice profiles 'EXTENDED' and 'XRECHNUNG'."
msgstr "Die Gebührenart 'Tatsächlich' wird nur in den E-Rechnungs-Profilen 'EXTENDED' und 'XRECHNUNG' unterstützt."
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:741
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:759
msgid "{0} row #{1}: Type '{2}' is not supported in e-invoice"
msgstr "{0} Zeile #{1}: Typ '{2}' wird in der E-Rechnung nicht unterstützt"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:776
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:794
msgid "{0}: Only one mode of payment will be considered in the e-invoice."
msgstr "{0}: Nur eine Zahlungsart wird in der E-Rechnung berücksichtigt."
diff --git a/eu_einvoice/locale/main.pot b/eu_einvoice/locale/main.pot
index d457dc24..444fdb00 100644
--- a/eu_einvoice/locale/main.pot
+++ b/eu_einvoice/locale/main.pot
@@ -7,8 +7,13 @@ msgid ""
msgstr ""
"Project-Id-Version: European e-Invoice VERSION\n"
"Report-Msgid-Bugs-To: hallo@alyf.de\n"
+<<<<<<< HEAD
"POT-Creation-Date: 2026-02-06 18:13+0053\n"
"PO-Revision-Date: 2026-02-06 18:13+0053\n"
+=======
+"POT-Creation-Date: 2026-04-21 15:04+0000\n"
+"PO-Revision-Date: 2026-04-21 15:04+0000\n"
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
"Last-Translator: hallo@alyf.de\n"
"Language-Team: hallo@alyf.de\n"
"MIME-Version: 1.0\n"
@@ -16,7 +21,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.13.1\n"
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:785
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:803
msgid "A document level discount is currently not supported in the e-invoice."
msgstr ""
@@ -59,7 +64,7 @@ msgstr ""
msgid "Amended From"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:105
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:106
msgid "An E Invoice Import with the same Invoice ID and Supplier already exists."
msgstr ""
@@ -168,11 +173,11 @@ msgstr ""
msgid "Calculation Percent"
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:816
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:834
msgid "Cannot create E Invoice."
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:830
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:848
msgid "Cannot validate E Invoice schematron."
msgstr ""
@@ -181,6 +186,7 @@ msgstr ""
msgid "Charge Total"
msgstr ""
+<<<<<<< HEAD
#. Label of a Link in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "Code List"
@@ -200,6 +206,9 @@ msgstr ""
#. Label of a Link field in DocType 'E Invoice Import'
#. Label of a Link field in DocType 'Supplier Number At Customer'
#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
+=======
+#. Label of a Link field in DocType 'E Invoice Import'
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
#: eu_einvoice/european_e_invoice/doctype/supplier_number_at_customer/supplier_number_at_customer.json
msgid "Company"
@@ -211,7 +220,7 @@ msgstr ""
msgid "Configure this if you are storing custom invoice numbers in a field other than name."
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:211
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:212
msgid "Could not validate E Invoice schematron. See Error Log for details."
msgstr ""
@@ -225,7 +234,7 @@ msgid "Create Item"
msgstr ""
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.js:93
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:434
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:437
msgid "Create Purchase Invoice"
msgstr ""
@@ -244,6 +253,7 @@ msgstr ""
msgid "Currency"
msgstr ""
+<<<<<<< HEAD
#. Label of a Data field in DocType 'Customer Number At Supplier'
#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
msgid "Customer Number"
@@ -256,6 +266,11 @@ msgstr ""
#: eu_einvoice/custom_fields.py:121
msgid "Customer numbers assigned by the supplier"
+=======
+#. Label of a Small Text field in DocType 'E Invoice Settings'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+msgid "Default VAT exemption reason"
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
msgstr ""
#. Label of a Tab Break field in DocType 'E Invoice Import'
@@ -306,12 +321,16 @@ msgstr ""
msgid "E Invoice Import"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:650
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:653
msgid "E Invoice Import {0} does not exist"
msgstr ""
#. Label of a Check field in DocType 'E Invoice Import'
+<<<<<<< HEAD
#: eu_einvoice/custom_fields.py:181
+=======
+#: eu_einvoice/custom_fields.py:165
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "E Invoice Is Correct"
msgstr ""
@@ -342,7 +361,7 @@ msgstr ""
msgid "E Invoice Trade Tax"
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:798
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:816
msgid "E Invoice is not correct"
msgstr ""
@@ -383,11 +402,11 @@ msgstr ""
msgid "Error Message"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:50
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:51
msgid "Field '{0}' does not exist on Sales Invoice doctype"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:58
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:59
msgid "Field '{0}' must be of type 'Attach'. Current type: {1}"
msgstr ""
@@ -411,6 +430,15 @@ msgstr ""
msgid "IBAN"
msgstr ""
+<<<<<<< HEAD
+=======
+#. Description of the 'Default VAT exemption reason' (Small Text) field in
+#. DocType 'E Invoice Settings'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+msgid "If set, written to BT-120 (ram:ExemptionReason) on VAT breakdowns where an exemption reason code is emitted. Left unset in the XML when empty."
+msgstr ""
+
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Data field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Invoice ID"
@@ -451,6 +479,7 @@ msgstr ""
msgid "Net Rate"
msgstr ""
+<<<<<<< HEAD
#. Label of a shortcut in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "New E Invoice Import"
@@ -462,10 +491,13 @@ msgid "New Sales Invoice"
msgstr ""
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:443
+=======
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:446
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
msgid "No machine-readable data was found in the PDF file. You can create a regular Purchase Invoice manually instead."
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:446
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:449
msgid "Not an E-Invoice"
msgstr ""
@@ -490,11 +522,11 @@ msgstr ""
msgid "Payment Terms"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:119
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:120
msgid "Please create or select a supplier before submitting"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:125
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:126
msgid "Please map all invoice lines to an item before submitting"
msgstr ""
@@ -502,7 +534,7 @@ msgstr ""
msgid "Please note the validation errors of the e-invoice."
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:122
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:123
msgid "Please select a company before submitting"
msgstr ""
@@ -531,7 +563,11 @@ msgstr ""
msgid "Purchase Invoice"
msgstr ""
+<<<<<<< HEAD
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:644
+=======
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:647
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
msgid "Purchase Invoice {0} is already linked to E Invoice Import {1}"
msgstr ""
@@ -560,7 +596,7 @@ msgstr ""
msgid "Rate Applicable Percent"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:670
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:673
msgid "Row {0}"
msgstr ""
@@ -636,11 +672,14 @@ msgstr ""
msgid "Settlement"
msgstr ""
+<<<<<<< HEAD
#. Label of a Card Break in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "Setup"
msgstr ""
+=======
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Link field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Supplier"
@@ -704,11 +743,11 @@ msgstr ""
msgid "Taxes"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:453
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:456
msgid "The format of the uploaded file ({0}) is not supported for E-Invoices. Please upload a valid E-Invoice file or create a regular Purchase Invoice manually instead."
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:160
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:161
msgid "The uploaded file does not contain valid XML data."
msgstr ""
@@ -732,7 +771,7 @@ msgstr ""
msgid "Unit Code"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:456
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:459
msgid "Unsupported file format"
msgstr ""
@@ -741,6 +780,19 @@ msgstr ""
msgid "Upload the .xml or .pdf file provided by your supplier."
msgstr ""
+<<<<<<< HEAD
+=======
+#. Label of a Section Break field in DocType 'E Invoice Settings'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+msgid "VAT exemption (e-invoice)"
+msgstr ""
+
+#. Label of a Small Text field in DocType 'E Invoice Trade Tax'
+#: eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
+msgid "VAT exemption reason"
+msgstr ""
+
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#. Label of a Check field in DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
msgid "Validate Sales Invoice on Save"
@@ -757,13 +809,21 @@ msgid "Validation Details"
msgstr ""
#. Label of a Text field in DocType 'E Invoice Import'
+<<<<<<< HEAD
#: eu_einvoice/custom_fields.py:191
+=======
+#: eu_einvoice/custom_fields.py:175
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Validation Errors"
msgstr ""
#. Label of a Text field in DocType 'E Invoice Import'
+<<<<<<< HEAD
#: eu_einvoice/custom_fields.py:201
+=======
+#: eu_einvoice/custom_fields.py:185
+>>>>>>> cec83b5 (feat: add BT-120 VAT exemption reason (#247))
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Validation Warnings"
msgstr ""
@@ -780,19 +840,19 @@ msgstr ""
msgid "Warning Message"
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:764
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:782
msgid "{0} row #{1}: Discount Date should be after Posting Date"
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:753
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:771
msgid "{0} row #{1}: The charge type 'Actual' is only supported in the eInvoice profiles 'EXTENDED' and 'XRECHNUNG'."
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:741
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:759
msgid "{0} row #{1}: Type '{2}' is not supported in e-invoice"
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:776
+#: eu_einvoice/european_e_invoice/custom/sales_invoice.py:794
msgid "{0}: Only one mode of payment will be considered in the e-invoice."
msgstr ""
From 009c0d04098157306a799edc2fe38a6554c566fd Mon Sep 17 00:00:00 2001
From: Daniel Rose <26166128+dafrose@users.noreply.github.com>
Date: Fri, 5 Jun 2026 10:27:31 +0200
Subject: [PATCH 2/3] fix: satisfy pre-commit and regenerate locale for bt-120
backport
Remove unnecessary quoted forward-reference annotations in E Invoice
Import (UP037). Regenerate de.po and main.pot so catalogs respect
ignore_translatable_strings_from while preserving BT-120 translations
from develop.
---
.../e_invoice_import/e_invoice_import.py | 22 ++---
eu_einvoice/locale/de.po | 89 ++-----------------
eu_einvoice/locale/main.pot | 84 +----------------
3 files changed, 18 insertions(+), 177 deletions(-)
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py b/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py
index 34d8d8b5..903c9a73 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py
@@ -224,7 +224,7 @@ def _validate_schematron(self, xml_bytes):
if any(validation_warnings):
self.validation_warnings += "\n".join(validation_warnings)
- def parse_seller(self, seller: "TradeParty"):
+ def parse_seller(self, seller: TradeParty):
self.seller_name = str(seller.name)
self.seller_tax_id = (
seller.tax_registrations.children[0].id._text if seller.tax_registrations.children else None
@@ -233,13 +233,13 @@ def parse_seller(self, seller: "TradeParty"):
self.seller_electronic_address_scheme = str(seller.electronic_address.uri_ID._scheme_id)
self.parse_address(seller.address, "seller")
- def parse_buyer(self, buyer: "TradeParty"):
+ def parse_buyer(self, buyer: TradeParty):
self.buyer_name = str(buyer.name)
self.buyer_electronic_address = str(buyer.electronic_address.uri_ID._text)
self.buyer_electronic_address_scheme = str(buyer.electronic_address.uri_ID._scheme_id)
self.parse_address(buyer.address, "buyer")
- def parse_address(self, address: "PostalTradeAddress", prefix: str) -> _dict:
+ def parse_address(self, address: PostalTradeAddress, prefix: str) -> _dict:
country = frappe.db.get_value("Country", {"code": str(address.country_id).lower()}, "name")
self.set(f"{prefix}_city", str(address.city_name))
@@ -248,7 +248,7 @@ def parse_address(self, address: "PostalTradeAddress", prefix: str) -> _dict:
self.set(f"{prefix}_postcode", str(address.postcode))
self.set(f"{prefix}_country", str(country))
- def parse_line_item(self, li: "LineItem"):
+ def parse_line_item(self, li: LineItem):
item = self.append("items")
net_rate = float(li.agreement.net.amount._value)
@@ -275,7 +275,7 @@ def parse_line_item(self, li: "LineItem"):
item.tax_rate = flt_or_none(li.settlement.trade_tax.rate_applicable_percent._value)
item.total_amount = flt_or_none(li.settlement.monetary_summation.total_amount._value)
- def parse_tax(self, tax: "ApplicableTradeTax"):
+ def parse_tax(self, tax: ApplicableTradeTax):
t = self.append("taxes")
t.basis_amount = flt_or_none(tax.basis_amount._value)
t.rate_applicable_percent = flt_or_none(tax.rate_applicable_percent._value)
@@ -283,7 +283,7 @@ def parse_tax(self, tax: "ApplicableTradeTax"):
reason_text = tax.exemption_reason._text
t.vat_exemption_reason_text = str(reason_text).strip() if reason_text else None
- def parse_payment_term(self, term: "PaymentTerms"):
+ def parse_payment_term(self, term: PaymentTerms):
if not term.partial_amount.children:
self.due_date = term.due._value
return
@@ -312,7 +312,7 @@ def parse_payment_term(self, term: "PaymentTerms"):
if term.discount_terms.actual_amount._value:
t.discount_actual_amount = float(term.discount_terms.actual_amount._value)
- def parse_monetary_summation(self, summation: "MonetarySummation"):
+ def parse_monetary_summation(self, summation: MonetarySummation):
self.line_total = flt_or_none(summation.line_total._value)
self.allowance_total = flt_or_none(summation.allowance_total._value)
self.charge_total = flt_or_none(summation.charge_total._value)
@@ -325,14 +325,14 @@ def parse_monetary_summation(self, summation: "MonetarySummation"):
self.total_prepaid = flt_or_none(summation.prepaid_total._value)
self.due_payable = flt_or_none(summation.due_amount._value)
- def parse_bank_details(self, payment_means: "PaymentMeans"):
+ def parse_bank_details(self, payment_means: PaymentMeans):
self.payee_iban = payment_means.payee_account.iban._text or None
if EInvoiceProfile(self.profile) >= EInvoiceProfile.EN16931:
self.payee_account_name = payment_means.payee_account.account_name._text or None
self.payee_bic = payment_means.payee_institution.bic._text or None
- def parse_billing_period(self, period: "BillingSpecifiedPeriod"):
+ def parse_billing_period(self, period: BillingSpecifiedPeriod):
self.billing_period_start = period.start._value
self.billing_period_end = period.end._value
@@ -469,8 +469,8 @@ def relative_url_to_path(url: str) -> Path:
@frappe.whitelist()
-def create_purchase_invoice(source_name, target_doc=None):
- def post_process(source, target: "PurchaseInvoice"):
+def create_purchase_invoice(source_name: str, target_doc: Document | None = None):
+ def post_process(source, target: PurchaseInvoice):
target.set_missing_values()
def process_item_row(source, target, source_parent) -> None:
diff --git a/eu_einvoice/locale/de.po b/eu_einvoice/locale/de.po
index 1c4cdce1..91c2a2ee 100644
--- a/eu_einvoice/locale/de.po
+++ b/eu_einvoice/locale/de.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: European e-Invoice VERSION\n"
"Report-Msgid-Bugs-To: hallo@alyf.de\n"
-"POT-Creation-Date: 2026-05-12 20:03+0000\n"
+"POT-Creation-Date: 2026-06-05 10:01+0053\n"
"PO-Revision-Date: 2026-02-05 11:13+0100\n"
"Last-Translator: hallo@alyf.de\n"
"Language: de\n"
@@ -56,11 +56,6 @@ msgstr "Vereinbarung"
msgid "Allowance Total"
msgstr "Abschläge gesamt"
-#. Label of a Link field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Amended From"
-msgstr "Korrektur von"
-
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:106
msgid "An E Invoice Import with the same Invoice ID and Supplier already exists."
msgstr "Eine E-Rechnung mit der gleichen Rechnungs-ID und Lieferanten existiert bereits."
@@ -198,15 +193,6 @@ msgstr "Code-Listen sind in der Regel öffentliche Listen von häufig verwendete
msgid "Common Code"
msgstr "Common Code"
-#. Label of a Link field in DocType 'Customer Number At Supplier'
-#. Label of a Link field in DocType 'E Invoice Import'
-#. Label of a Link field in DocType 'Supplier Number At Customer'
-#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-#: eu_einvoice/european_e_invoice/doctype/supplier_number_at_customer/supplier_number_at_customer.json
-msgid "Company"
-msgstr "Unternehmen"
-
#. Description of the 'Sales Invoice Number Field' (Autocomplete) field in
#. DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
@@ -217,10 +203,6 @@ msgstr "Konfigurieren Sie dies, wenn Sie benutzerdefinierte Rechnungsnummern in
msgid "Could not validate E Invoice schematron. See Error Log for details."
msgstr "E-Rechnung konnte nicht validiert werden. Details im Fehlerlog."
-#: eu_einvoice/european_e_invoice/custom/purchase_order.js:12
-msgid "Create"
-msgstr ""
-
#. Label of a Button field in DocType 'E Invoice Item'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_item/e_invoice_item.json
msgid "Create Item"
@@ -241,11 +223,6 @@ msgstr "Lieferant erstellen"
msgid "Create Supplier Address"
msgstr "Lieferanten-Adresse erstellen"
-#. Label of a Link field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Currency"
-msgstr "Währung"
-
#. Label of a Data field in DocType 'Customer Number At Supplier'
#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
msgid "Customer Number"
@@ -258,7 +235,7 @@ msgstr "Kundennummer beim Lieferanten"
#: eu_einvoice/custom_fields.py:121
msgid "Customer numbers assigned by the supplier"
-msgstr "Kundennummern, die vom Lieferanten zugewiesen wurden"
+msgstr "Vom Lieferanten zugewiesene Kundennummern"
#. Label of a Small Text field in DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
@@ -277,11 +254,6 @@ msgstr "Lieferung"
msgid "Discount"
msgstr "Rabatt"
-#. Label of a Tab Break field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Document"
-msgstr "Dokument"
-
#. Label of a shortcut in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "Documentation"
@@ -296,11 +268,6 @@ msgstr "E-Rechnung herunterladen"
msgid "Due"
msgstr "Fällig"
-#. Label of a Date field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Due Date"
-msgstr "Fälligkeitsdatum"
-
#. Label of a Currency field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Due Payable"
@@ -382,13 +349,6 @@ msgstr "Schema der elektronischen Adresse"
msgid "Embedded Document"
msgstr "Eingebettetes Dokument"
-#. Option for the 'Action on Validation Error during Save' (Select) field in
-#. DocType 'E Invoice Settings'
-#. Option for the 'Action on Validation Error during Submit' (Select) field in
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
-msgid "Error Message"
-msgstr "Fehlermeldung"
-
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:51
msgid "Field '{0}' does not exist on Sales Invoice doctype"
msgstr "Feld '{0}' existiert nicht im DocType 'Sales Invoice'"
@@ -407,11 +367,6 @@ msgstr "Datei-Abschnitt"
msgid "Grand Total"
msgstr "Gesamtbetrag"
-#. Label of a Section Break field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Header"
-msgstr "Kopfzeile"
-
#. Label of a Data field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "IBAN"
@@ -533,11 +488,6 @@ msgstr "Produktbeschreibung"
msgid "Product Name"
msgstr "Produktname"
-#. Label of a Read Only field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Profile"
-msgstr "Profil"
-
#. Linked DocType in E Invoice Import's connections
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Purchase Invoice"
@@ -547,11 +497,6 @@ msgstr "Eingangsrechnung"
msgid "Purchase Invoice {0} is already linked to E Invoice Import {1}"
msgstr "Eingangsrechnung {0} ist bereits mit E-Rechnungs-Import {1} verknüpft"
-#. Name of a role
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Purchase Manager"
-msgstr ""
-
#. Label of a Link field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Purchase Order"
@@ -562,20 +507,11 @@ msgstr "Lieferantenauftrag"
msgid "Purchase Order Row"
msgstr "Bestellposition"
-#. Name of a role
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Purchase User"
-msgstr ""
-
#. Label of a Percent field in DocType 'E Invoice Trade Tax'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
msgid "Rate Applicable Percent"
msgstr "Anwendbarer Prozentsatz"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:673
-msgid "Row {0}"
-msgstr "Zeile {0}"
-
#. Label of a Section Break field in DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
msgid "Sales Invoice"
@@ -648,11 +584,6 @@ msgstr "Verkäufer-Steuer-ID"
msgid "Settlement"
msgstr "Ausgleich"
-#. Label of a Card Break in the E-Invoicing Workspace
-#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
-msgid "Setup"
-msgstr ""
-
#. Label of a Link field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Supplier"
@@ -685,16 +616,10 @@ msgstr "Lieferantennummern"
msgid "Supplier numbers assigned by the customer"
msgstr "Vom Kunden zugewiesene Lieferantennummern"
-#. Name of a role
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
-msgid "System Manager"
-msgstr ""
-
#. Label of a Link field in DocType 'E Invoice Trade Tax'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
msgid "Tax Account"
-msgstr "Konto für Steuern"
+msgstr "Steuer-Konto"
#. Label of a Currency field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
@@ -727,7 +652,7 @@ msgstr "Die hochgeladene Datei enthält keine gültige XML-Daten."
#. Label of a Currency field in DocType 'E Invoice Item'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_item/e_invoice_item.json
msgid "Total Amount"
-msgstr ""
+msgstr "Gesamtbetrag"
#. Label of a Currency field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
@@ -737,7 +662,7 @@ msgstr "Vorausbezahlt"
#. Label of a Link field in DocType 'E Invoice Item'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_item/e_invoice_item.json
msgid "UOM"
-msgstr ""
+msgstr "Einheit"
#. Label of a Data field in DocType 'E Invoice Item'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_item/e_invoice_item.json
@@ -790,10 +715,6 @@ msgstr "Validierungsfehler"
msgid "Validation Warnings"
msgstr "Validierungswarnungen"
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.js:75
-msgid "View {0}"
-msgstr ""
-
#. Option for the 'Action on Validation Error during Save' (Select) field in
#. DocType 'E Invoice Settings'
#. Option for the 'Action on Validation Error during Submit' (Select) field in
diff --git a/eu_einvoice/locale/main.pot b/eu_einvoice/locale/main.pot
index f57fe9dd..c60088c0 100644
--- a/eu_einvoice/locale/main.pot
+++ b/eu_einvoice/locale/main.pot
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: European e-Invoice VERSION\n"
"Report-Msgid-Bugs-To: hallo@alyf.de\n"
-"POT-Creation-Date: 2026-05-12 20:03+0000\n"
-"PO-Revision-Date: 2026-05-12 20:03+0000\n"
+"POT-Creation-Date: 2026-06-05 10:01+0053\n"
+"PO-Revision-Date: 2026-06-05 10:01+0053\n"
"Last-Translator: hallo@alyf.de\n"
"Language-Team: hallo@alyf.de\n"
"MIME-Version: 1.0\n"
@@ -54,11 +54,6 @@ msgstr ""
msgid "Allowance Total"
msgstr ""
-#. Label of a Link field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Amended From"
-msgstr ""
-
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:106
msgid "An E Invoice Import with the same Invoice ID and Supplier already exists."
msgstr ""
@@ -196,15 +191,6 @@ msgstr ""
msgid "Common Code"
msgstr ""
-#. Label of a Link field in DocType 'Customer Number At Supplier'
-#. Label of a Link field in DocType 'E Invoice Import'
-#. Label of a Link field in DocType 'Supplier Number At Customer'
-#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-#: eu_einvoice/european_e_invoice/doctype/supplier_number_at_customer/supplier_number_at_customer.json
-msgid "Company"
-msgstr ""
-
#. Description of the 'Sales Invoice Number Field' (Autocomplete) field in
#. DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
@@ -215,10 +201,6 @@ msgstr ""
msgid "Could not validate E Invoice schematron. See Error Log for details."
msgstr ""
-#: eu_einvoice/european_e_invoice/custom/purchase_order.js:12
-msgid "Create"
-msgstr ""
-
#. Label of a Button field in DocType 'E Invoice Item'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_item/e_invoice_item.json
msgid "Create Item"
@@ -239,11 +221,6 @@ msgstr ""
msgid "Create Supplier Address"
msgstr ""
-#. Label of a Link field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Currency"
-msgstr ""
-
#. Label of a Data field in DocType 'Customer Number At Supplier'
#: eu_einvoice/european_e_invoice/doctype/customer_number_at_supplier/customer_number_at_supplier.json
msgid "Customer Number"
@@ -275,11 +252,6 @@ msgstr ""
msgid "Discount"
msgstr ""
-#. Label of a Tab Break field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Document"
-msgstr ""
-
#. Label of a shortcut in the E-Invoicing Workspace
#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
msgid "Documentation"
@@ -294,11 +266,6 @@ msgstr ""
msgid "Due"
msgstr ""
-#. Label of a Date field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Due Date"
-msgstr ""
-
#. Label of a Currency field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Due Payable"
@@ -380,14 +347,6 @@ msgstr ""
msgid "Embedded Document"
msgstr ""
-#. Option for the 'Action on Validation Error during Save' (Select) field in
-#. DocType 'E Invoice Settings'
-#. Option for the 'Action on Validation Error during Submit' (Select) field in
-#. DocType 'E Invoice Settings'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
-msgid "Error Message"
-msgstr ""
-
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.py:51
msgid "Field '{0}' does not exist on Sales Invoice doctype"
msgstr ""
@@ -406,11 +365,6 @@ msgstr ""
msgid "Grand Total"
msgstr ""
-#. Label of a Section Break field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Header"
-msgstr ""
-
#. Label of a Data field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "IBAN"
@@ -532,11 +486,6 @@ msgstr ""
msgid "Product Name"
msgstr ""
-#. Label of a Read Only field in DocType 'E Invoice Import'
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Profile"
-msgstr ""
-
#. Linked DocType in E Invoice Import's connections
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Purchase Invoice"
@@ -546,11 +495,6 @@ msgstr ""
msgid "Purchase Invoice {0} is already linked to E Invoice Import {1}"
msgstr ""
-#. Name of a role
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Purchase Manager"
-msgstr ""
-
#. Label of a Link field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Purchase Order"
@@ -561,20 +505,11 @@ msgstr ""
msgid "Purchase Order Row"
msgstr ""
-#. Name of a role
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-msgid "Purchase User"
-msgstr ""
-
#. Label of a Percent field in DocType 'E Invoice Trade Tax'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
msgid "Rate Applicable Percent"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.py:673
-msgid "Row {0}"
-msgstr ""
-
#. Label of a Section Break field in DocType 'E Invoice Settings'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
msgid "Sales Invoice"
@@ -647,11 +582,6 @@ msgstr ""
msgid "Settlement"
msgstr ""
-#. Label of a Card Break in the E-Invoicing Workspace
-#: eu_einvoice/european_e_invoice/workspace/e_invoicing/e_invoicing.json
-msgid "Setup"
-msgstr ""
-
#. Label of a Link field in DocType 'E Invoice Import'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
msgid "Supplier"
@@ -684,12 +614,6 @@ msgstr ""
msgid "Supplier numbers assigned by the customer"
msgstr ""
-#. Name of a role
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.json
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
-msgid "System Manager"
-msgstr ""
-
#. Label of a Link field in DocType 'E Invoice Trade Tax'
#: eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
msgid "Tax Account"
@@ -789,10 +713,6 @@ msgstr ""
msgid "Validation Warnings"
msgstr ""
-#: eu_einvoice/european_e_invoice/doctype/e_invoice_import/e_invoice_import.js:75
-msgid "View {0}"
-msgstr ""
-
#. Option for the 'Action on Validation Error during Save' (Select) field in
#. DocType 'E Invoice Settings'
#. Option for the 'Action on Validation Error during Submit' (Select) field in
From 447e69a2b9748465474c711a235cd448ce792e64 Mon Sep 17 00:00:00 2001
From: barredterra <14891507+barredterra@users.noreply.github.com>
Date: Mon, 8 Jun 2026 13:04:51 +0200
Subject: [PATCH 3/3] chore: save doctype defs through ORM
---
.../doctype/e_invoice_settings/e_invoice_settings.json | 2 +-
.../doctype/e_invoice_trade_tax/e_invoice_trade_tax.json | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json b/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
index d63ab1d8..1a69a724 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_settings/e_invoice_settings.json
@@ -93,7 +93,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2026-04-21 12:00:00.000000",
+ "modified": "2026-06-08 13:02:59.672943",
"modified_by": "Administrator",
"module": "European e-Invoice",
"name": "E Invoice Settings",
diff --git a/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json b/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
index 440d87bf..f0fbc8ff 100644
--- a/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
+++ b/eu_einvoice/european_e_invoice/doctype/e_invoice_trade_tax/e_invoice_trade_tax.json
@@ -52,12 +52,13 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2026-04-21 14:00:00.000000",
+ "modified": "2026-06-08 13:04:01.003993",
"modified_by": "Administrator",
"module": "European e-Invoice",
"name": "E Invoice Trade Tax",
"owner": "Administrator",
"permissions": [],
+ "row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": []