Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions datev_export_xml_nitrokey/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DATEV Export XML Nitrokey customization
---------------------------------------

- DATEV export will contain sales order number instead of invoice number
- check for some UTF8 ranges before export
- suppress lines with a total of 0 entirely
4 changes: 4 additions & 0 deletions datev_export_xml_nitrokey/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# © 2023 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import models
21 changes: 21 additions & 0 deletions datev_export_xml_nitrokey/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# © 2023 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "DATEV Export XML Nitrokey customization",
"version": "18.0.1.0.0",
"category": "Hidden",
"author": "initOS GmbH",
"website": "https://www.initos.com",
"license": "AGPL-3",
"summary": "DATEV export will contain sales order number instead of "
"invoice number.",
"depends": [
"datev_export_xml",
],
"data": [
"templates/export_invoice_line.xml",
],
"auto_install": True,
"installable": True,
}
5 changes: 5 additions & 0 deletions datev_export_xml_nitrokey/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# © 2023 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import account_move
from . import datev_xml_generator
34 changes: 34 additions & 0 deletions datev_export_xml_nitrokey/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# © 2023 initOS GmbH
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class AccountMove(models.Model):
_inherit = "account.move"

def datev_invoice_id(self):
"""Custom overwrite for the NK special case"""
self.ensure_one()

if self.move_type not in (
"in_invoice",
"in_refund",
"out_invoice",
"out_refund",
):
return self.datev_sanitize(self.name or "")

reference = self.name or ""
if self.move_type.startswith("in_") and self.ref:
reference = self.ref
elif self.move_type == "out_invoice" and self.invoice_origin:
reference = self.invoice_origin
elif self.move_type == "out_refund" and self.reversed_entry_id.invoice_origin:
reference = self.reversed_entry_id.invoice_origin

return self.datev_sanitize(reference)

def datev_order_id(self):
self.ensure_one()
return self.datev_sanitize(self.name or "")
72 changes: 72 additions & 0 deletions datev_export_xml_nitrokey/models/datev_xml_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import re

from odoo import _, api, models


class DatevXmlGenerator(models.AbstractModel):
_inherit = "datev.xml.generator"

@api.model
def _check_invoices(self, invoices):
for invoice in invoices:
self._check_partner_data(invoice)
return super()._check_invoices(invoices)

def _check_partner_data(self, invoice):
"""Check partner data for invalid characters that would break XML export."""

# Define control characters and other problematic characters for XML
# This includes ASCII control characters (0x00-0x1F except tab, newline, CR)
# and other characters that can cause XML parsing issues
invalid_chars_pattern = r"[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]"

def check_field(field_value, field_name, partner_name):
if field_value and re.search(invalid_chars_pattern, field_value):
# Find the specific invalid characters for better error reporting
invalid_chars = set(re.findall(invalid_chars_pattern, field_value))
char_codes = [f"U+{ord(char):04X}" for char in invalid_chars]
raise ValueError(
self.env._(
"Partner '%(partner)s' contains invalid characters "
"in %(field)s: %(chars)s. "
"These characters cannot be exported to DATEV XML format.",
partner=partner_name,
field=field_name,
chars=", ".join(char_codes),
)
)

# Check both invoice partner and company partner (supplier)
partners_to_check = []

if invoice.move_type in ["out_invoice", "out_refund"]:
# For outgoing invoices: check customer (invoice_party) and company
# (supplier_party)
partners_to_check.append((invoice.partner_id, _("Customer")))
partners_to_check.append((invoice.company_id.partner_id, _("Company")))
else:
# For incoming invoices: check vendor (supplier_party) and company
# (invoice_party)
partners_to_check.append((invoice.partner_id, _("Vendor")))
partners_to_check.append((invoice.company_id.partner_id, _("Company")))

for partner, partner_type in partners_to_check:
if not partner:
continue

partner_name = (
f"{partner_type} ({partner.display_name or partner.name or 'Unknown'})"
)

# Check the fields that are used in the XML template
check_field(partner.display_name, "name", partner_name)
check_field(partner.name, "name", partner_name)
check_field(partner.street, "street address", partner_name)
check_field(partner.street2, "street address (line 2)", partner_name)
check_field(partner.city, "city", partner_name)
check_field(partner.zip, "postal code", partner_name)

# Also check bank account information if present
for bank in partner.bank_ids:
if bank.bank_id:
check_field(bank.bank_id.name, "bank name", partner_name)
16 changes: 16 additions & 0 deletions datev_export_xml_nitrokey/templates/export_invoice_line.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<odoo>
<template
id="export_invoice_line"
inherit_id="datev_export_xml.export_invoice_line"
>
<invoice_item_list position="before">
<t t-if="prices['total_excluded'] != 0" />
</invoice_item_list>
<xpath expr="./t[@t-if]" position="inside">
<xpath expr="./invoice_item_list" position="move" />
<xpath expr="./invoice_item_list" position="move" />
<xpath expr="./invoice_item_list" position="move" />
<xpath expr="./invoice_item_list" position="move" />
</xpath>
</template>
</odoo>
1 change: 1 addition & 0 deletions datev_export_xml_nitrokey/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_datev_export_xml_nitrokey
Loading