78 lines
3.1 KiB
Python
78 lines
3.1 KiB
Python
from stdnum.nl.btw import validate
|
|
|
|
from odoo import models, _
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class VATPayWizard(models.TransientModel):
|
|
_name = 'l10n_nl_reports.vat.pay.wizard'
|
|
_inherit = ['qr.code.payment.wizard']
|
|
_description = "Payment instructions for VAT"
|
|
|
|
def _generate_communication(self):
|
|
company = self.return_id.company_id
|
|
periodicity = self.return_id.type_id._get_periodicity(company)
|
|
try:
|
|
nl_vat = company.l10n_nl_reports_sbr_ob_nummer or company.vat
|
|
vat = validate(nl_vat)
|
|
except Exception as e:
|
|
raise UserError(_(
|
|
"Something went wrong while validating the VAT number: %s. You can modify it in the company settings.",
|
|
nl_vat
|
|
)) from e
|
|
head, tail = vat.split("B")
|
|
date = self.return_id.date_from
|
|
period_code_map = {
|
|
'monthly': f'{date.month:02}',
|
|
'trimester': f'{20 + date.month}',
|
|
'year': '40',
|
|
}
|
|
|
|
if periodicity not in period_code_map:
|
|
raise UserError(_(
|
|
"Invalid tax periodicity. Please use one of the following: %s.",
|
|
', '.join(
|
|
label
|
|
for value, label in self.return_id.type_id._fields['deadline_periodicity']._description_selection(self.env)
|
|
if value in period_code_map
|
|
)
|
|
))
|
|
|
|
block_1 = f"{head[:3]}"
|
|
block_2 = f"{head[3:7]}"
|
|
block_3 = f"{head[7:8]}1{str(date.year)[-1]}{tail[0]}"
|
|
block_4 = f"{tail[1]}{period_code_map[periodicity]}0"
|
|
blocks = [block_1, block_2, block_3, block_4]
|
|
|
|
checksum = self._l10n_nl_get_modulo_11_checksum("".join(blocks))
|
|
return checksum + ".".join(blocks)
|
|
|
|
def _l10n_nl_get_modulo_11_checksum(self, number):
|
|
"""
|
|
Calculates the Modulo 11 checksum for a given numeric string using a predefined set of weights.
|
|
|
|
The function iterates over each digit in the input string from right to left, applying the corresponding weight
|
|
in a cyclic manner. The checksum is computed as the weighted sum of the digits modulo 11.
|
|
|
|
Source: https://www.betaalvereniging.nl/betalingsverkeer/giraal-betalingsverkeer/betalingskenmerken/specificaties-nl-betalingskenmerk/
|
|
|
|
:param str number: A string representing a numeric input for which the checksum needs to be calculated.
|
|
:returns: The Modulo 11 checksum as a string.
|
|
Returns '0' or '1' if the remainder is 0 or 1,
|
|
otherwise returns the complement of the remainder (i.e., 11 - remainder).
|
|
:rtype: str.
|
|
"""
|
|
n = len(number)
|
|
weights = [2, 4, 8, 5, 10, 9, 7, 3, 6, 1]
|
|
remainder = sum(int(number[n - i - 1]) * weights[i % len(weights)] for i in range(n)) % 11
|
|
|
|
if remainder in (0, 1):
|
|
return str(remainder)
|
|
|
|
return str(11 - remainder)
|
|
|
|
def action_send_email_instructions(self):
|
|
self.ensure_one()
|
|
template = self.env.ref('l10n_nl_reports.email_template_vat_payment_instructions', raise_if_not_found=False)
|
|
return self.return_id.action_send_email_instructions(self, template)
|