
Child taxes do not respect the setting of the parent 'Override tmeplate', thus can not be configured for unece codes. It is anyway better to allow the code definition on the parent tax.
144 lines
4.7 KiB
Python
144 lines
4.7 KiB
Python
# -*- 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.
|
|
|
|
import genshi.template
|
|
import os
|
|
import html
|
|
from trytond.exceptions import UserError
|
|
from trytond.i18n import gettext
|
|
from trytond.modules.edocument_uncefact.edocument import Invoice
|
|
from decimal import Decimal
|
|
|
|
|
|
class Invoice(Invoice):
|
|
'EDocument XRechnung'
|
|
__name__ = 'edocument.xrechnung.invoice'
|
|
|
|
def sales_order_nums(self):
|
|
""" get string of sale-numbers
|
|
"""
|
|
if getattr(self.invoice, 'sales', None) is not None:
|
|
return ', '.join([x.number for x in self.invoice.sales])
|
|
|
|
def negate_amount(self, amount):
|
|
""" amount * -1.0
|
|
"""
|
|
if amount is not None and amount:
|
|
if isinstance(amount, Decimal):
|
|
return amount.copy_negate()
|
|
elif isinstance(amount, float):
|
|
return -1.0 * amount
|
|
elif isinstance(amount, int):
|
|
return -1 * amount
|
|
else:
|
|
return amount
|
|
|
|
def prepaid_amount(self, invoice):
|
|
""" compute already paid amount
|
|
"""
|
|
return invoice.total_amount - invoice.amount_to_pay
|
|
|
|
def invoice_note(self):
|
|
""" get 'description' + 'comment'
|
|
"""
|
|
notes = []
|
|
if self.invoice.description:
|
|
notes.append(self.invoice.description)
|
|
|
|
if self.invoice.comment:
|
|
notes.extend(self.invoice.comment.split('\n'))
|
|
if len(notes) > 0:
|
|
return '; '.join(notes)
|
|
|
|
def invoice_line_tax(self, line):
|
|
""" get tax of invoice-line,
|
|
fire exception if no/multiple taxes exists
|
|
"""
|
|
if len(line.invoice_taxes) != 1:
|
|
raise UserError(gettext(
|
|
'edocument_xrechnung.msg_linetax_invalid_number',
|
|
linename=line.rec_name,
|
|
numtax=len(line.invoice_taxes)))
|
|
|
|
allowed_cat = ['AE', 'L', 'M', 'E', 'S', 'Z', 'G', 'O', 'K', 'B']
|
|
unece_category_code = self.get_category_code(line.invoice_taxes[0].tax)
|
|
if unece_category_code not in allowed_cat:
|
|
raise UserError(gettext(
|
|
'edocument_xrechnung.msg_linetax_invalid_catcode',
|
|
taxname=line.invoice_taxes[0].tax.rec_name,
|
|
allowed=', '.join(allowed_cat)))
|
|
|
|
return line.invoice_taxes[0].tax
|
|
|
|
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 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 is not None:
|
|
return html.quote(text)
|
|
|
|
def _get_template(self, version):
|
|
""" load our own template if 'version' is ours
|
|
"""
|
|
if version == 'XRechnung-2.2':
|
|
loader = genshi.template.TemplateLoader(
|
|
os.path.join(os.path.dirname(__file__), 'template'),
|
|
auto_reload=True)
|
|
if self.type_code in ['380', '389']:
|
|
return loader.load(os.path.join(
|
|
version, 'XRechnung_invoice.xml'))
|
|
elif self.type_code in ['381', '261']:
|
|
return loader.load(os.path.join(
|
|
version, 'XRechnung_credit.xml'))
|
|
else:
|
|
raise ValueError('invalid type-code "%s"' % self.type_code)
|
|
else:
|
|
return super(Invoice, self)._get_template(version)
|
|
|
|
# end Invoice
|