edocument_xrechnung/mixin.py

193 lines
6 KiB
Python
Raw Normal View History

2024-12-09 12:24:39 +00:00
# -*- coding: utf-8 -*-
# This file is part of the edocument-module for Tryton from m-ds.de.
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
from decimal import Decimal
import html
from trytond.exceptions import UserError
from trytond.i18n import gettext
2024-12-09 14:15:27 +00:00
from trytond.tools import cached_property
2024-12-10 11:59:09 +00:00
from trytond.pool import Pool
2024-12-09 12:24:39 +00:00
class EdocumentMixin(object):
""" functions to get field values for xml
"""
__slots__ = ()
2024-12-10 11:59:09 +00:00
def company_bank_accounts(self):
""" get leist of bank account numbers, defined in config
Returns:
list: records of model bank.account.number
"""
Configuration = Pool().get('account.configuration')
result = []
cfg1 = Configuration.get_singleton()
if cfg1 and cfg1.edocument_bank:
result.extend(list(cfg1.edocument_bank))
else:
result.extend([
y
2024-12-10 12:16:04 +00:00
for x in self.invoice.company.party.bank_accounts
2024-12-10 11:59:09 +00:00
for y in x.numbers])
return result
2024-12-09 14:15:27 +00:00
@cached_property
def seller_trade_address(self):
""" get address of seller, throw exception if incomplete
Raises:
UserError: if no address
UserError: if no country on address
Returns:
record : model party.address
"""
result = super().seller_trade_address
2024-12-09 14:15:27 +00:00
if not result:
raise UserError(gettext(
'edocument_xrechnung.msg_no_seller_address',
sellerparty=self.invoice.company.rec_name
if self.invoice and self.invoice.company
else '-'))
if not result.country:
raise UserError(gettext(
'edocument_xrechnung.msg_no_address_country',
2024-12-11 13:34:10 +00:00
party=result.party.rec_name if result.party else '-'))
2024-12-09 14:15:27 +00:00
return result
@cached_property
def buyer_trade_address(self):
""" exception if no address
Returns:
record: model party.address
"""
if (self.invoice.type == 'out') and (
not self.invoice.invoice_address):
raise UserError(gettext(
'edocument_xrechnung.msg_no_buyer_address',
buyerparty=self.invoice.party.rec_name
if self.invoice and self.invoice.party
else '-'))
result = super().buyer_trade_address
2024-12-09 14:15:27 +00:00
if result and not result.country:
raise UserError(gettext(
'edocument_xrechnung.msg_no_address_country',
2024-12-11 13:34:10 +00:00
party=result.party.rec_name if result.party else '-'))
2024-12-09 14:15:27 +00:00
return result
2024-12-09 12:24:39 +00:00
def get_list_of_comments(self):
""" comment, to export in <ram:IncludedNote/>
Returns:
_type_: _description_
"""
result = []
if self.invoice.comment:
result.append({
'content': self.invoice.comment,
'subject_code': '',
'content_code': ''})
return result
def invoice_line_tax(self, line):
""" get tax of invoice-line,
fire exception if no/multiple taxes exists
"""
2025-01-09 10:50:00 +00:00
Tax = Pool().get('account.tax')
2025-01-03 21:28:58 +00:00
if len(line.taxes) != 1:
2024-12-09 12:24:39 +00:00
raise UserError(gettext(
'edocument_xrechnung.msg_linetax_invalid_number',
linename=line.rec_name,
2025-01-03 21:28:58 +00:00
numtax=len(line.taxes)))
2025-01-09 10:50:00 +00:00
taxlines = Tax.compute(
line.taxes, Decimal('1'), 1.0,
line.invoice.accounting_date or line.invoice.invoice_date)
assert len(taxlines) == 1
tax = taxlines[0]['tax']
2024-12-09 12:24:39 +00:00
allowed_cat = ['AE', 'L', 'M', 'E', 'S', 'Z', 'G', 'O', 'K', 'B']
2025-01-03 21:28:58 +00:00
unece_category_code = self.get_category_code(tax)
2024-12-09 12:24:39 +00:00
if unece_category_code not in allowed_cat:
raise UserError(gettext(
'edocument_xrechnung.msg_linetax_invalid_catcode',
2025-01-03 21:28:58 +00:00
taxname=tax.rec_name,
2024-12-09 12:24:39 +00:00
allowed=', '.join(allowed_cat)))
2025-01-03 21:28:58 +00:00
return tax
2024-12-09 12:24:39 +00:00
def taxident_data(self, tax_identifier):
""" get tax-scheme-id and codes
"""
result = {'code': None, 'id': None}
if tax_identifier:
if tax_identifier.type == 'de_vat':
result['code'] = 'DE%s' % tax_identifier.code
result['id'] = 'VAT'
return result
def tax_rate(self, tax):
""" get tax-rate in procent
"""
return (tax.rate * Decimal('100.0')).quantize(Decimal('0.01'))
def uom_unece_code(self, line):
""" 'line': invoice.line
"""
if len(line.unit.unece_code or '') == 0:
raise UserError(gettext(
'edocument_xrechnung.msg_uom_code_missing',
uomname=line.unit.rec_name))
return line.unit.unece_code
def tax_unece_code(self, tax):
""" 'tax': invoice.line
"""
unece_code = self.get_tax_unece_code(tax)
if not unece_code:
2024-12-09 12:24:39 +00:00
raise UserError(gettext(
'edocument_xrechnung.msg_tax_code_missing',
taxname=tax.rec_name))
return tax.unece_code
def get_tax_unece_code(self, tax):
while tax:
if tax.unece_code:
return tax.unece_code
break
tax = tax.parent
2024-12-09 12:24:39 +00:00
def get_category_code(self, tax):
while tax:
if tax.unece_category_code:
return tax.unece_category_code
break
tax = tax.parent
def tax_category_code(self, tax):
""" read tax-category, fire exception if missing
"""
unece_category_code = self.get_category_code(tax)
if not unece_category_code:
raise UserError(gettext(
'edocument_xrechnung.mds_tax_category_missing',
taxname=tax.rec_name))
return unece_category_code
def quote_text(self, text):
""" replace critical chars
"""
if text:
2024-12-10 11:58:45 +00:00
return html.escape(text)
2024-12-09 12:24:39 +00:00
# end EdocumentMixin