Files
odoo_source/addons/l10n_ec/models/res_partner.py
T
Xavier Morel 9ebbfdac73 [FIX] *: incorrect translations markings
Fixes a large number of cases where strings are translated then
formatted, instead of letting `_()` do the formatting internally,
which allows it to recover from incorrect translations (missing,
broken, or extra placeholders).

Also

- removes translation markers entirely when there's nothing to
  translate e.g. `_("%s - %s")` is not useful
- fixes a few messes which lead to only partial translatability
  (DRY is generally a bad idea when translations are involved, even
  more so when you don't make the variable part translatable)
- fixes a few nearby issues noticed at the same time
- replaces a few `"%s"` by `%r`, which should automatically quote
  strings relatively appropriately
- fixes translated strings which use `\` to escape a newline (in order
  to fill-paragraph): `\` escapes only the newline, if the
  continuation string is indented this results in a bunch of spaces
  ending in the string to translate, which is pretty garbage for the
  translator, using implicit concatenation works much better

Note: some of the updates revert f-string parameters to %, because
babel (2.9) apparently has trouble with f-strings and blows up trying
to extract them.

Not in scope:

Helping translators fix translatable strings e.g. any translation
string with more than one placeholder probably should use keyword
placeholders

- Provides more context / data to the translator to make sense of the
  sentence.
- Allows reordering the translated terms, which can be necessary
  depending on the sentence and language.

closes odoo/odoo#139314

Related: odoo/enterprise#49311
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-10-23 16:45:09 +00:00

116 lines
5.1 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import enum
import stdnum
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
def verify_final_consumer(vat):
return vat == '9' * 13 # final consumer is identified with 9999999999999
class PartnerIdTypeEc(enum.Enum):
"""
Ecuadorian partner identification type/code for ATS and SRI.
"""
IN_RUC = '01'
IN_CEDULA = '02'
IN_PASSPORT = '03'
OUT_RUC = '04'
OUT_CEDULA = '05'
OUT_PASSPORT = '06'
FINAL_CONSUMER = '07'
FOREIGN = '08'
@classmethod
def get_ats_code_for_partner(cls, partner, move_type):
"""
Returns ID code for move and partner based on subset of Table 2 of SRI's ATS specification
"""
partner_id_type = partner._l10n_ec_get_identification_type()
if move_type.startswith('in_'):
if partner_id_type == 'ruc': # includes final consumer
return cls.IN_RUC
elif partner_id_type == 'cedula':
return cls.IN_CEDULA
elif partner_id_type in ['foreign', 'passport']:
return cls.IN_PASSPORT
elif move_type.startswith('out_'):
if partner_id_type == 'ruc': # includes final consumer
return cls.OUT_RUC
elif partner_id_type == 'cedula':
return cls.OUT_CEDULA
elif partner_id_type in ['foreign', 'passport']:
return cls.OUT_PASSPORT
class ResPartner(models.Model):
_inherit = "res.partner"
l10n_ec_vat_validation = fields.Char(
string="VAT Error message validation",
compute="_compute_l10n_ec_vat_validation",
help="Error message when validating the Ecuadorian VAT",
)
@api.constrains("vat", "country_id", "l10n_latam_identification_type_id")
def check_vat(self):
it_ruc = self.env.ref("l10n_ec.ec_ruc", False)
it_dni = self.env.ref("l10n_ec.ec_dni", False)
ecuadorian_partners = self.filtered(
lambda x: x.country_id == self.env.ref("base.ec")
)
for partner in ecuadorian_partners:
if partner.vat:
if partner.l10n_latam_identification_type_id.id in (
it_ruc.id,
it_dni.id,
):
if partner.l10n_latam_identification_type_id.id == it_dni.id and len(partner.vat) != 10:
raise ValidationError(_('If your identification type is %s, it must be 10 digits',
it_dni.display_name))
if partner.l10n_latam_identification_type_id.id == it_ruc.id and len(partner.vat) != 13:
raise ValidationError(_('If your identification type is %s, it must be 13 digits',
it_ruc.display_name))
return super(ResPartner, self - ecuadorian_partners).check_vat()
@api.depends("vat", "country_id", "l10n_latam_identification_type_id")
def _compute_l10n_ec_vat_validation(self):
it_ruc = self.env.ref("l10n_ec.ec_ruc", False)
it_dni = self.env.ref("l10n_ec.ec_dni", False)
ruc = stdnum.util.get_cc_module("ec", "ruc")
ci = stdnum.util.get_cc_module("ec", "ci")
for partner in self:
partner.l10n_ec_vat_validation = False
if partner and partner.l10n_latam_identification_type_id in (it_ruc, it_dni) and partner.vat:
final_consumer = verify_final_consumer(partner.vat)
if not final_consumer:
if partner.l10n_latam_identification_type_id.id == it_dni.id and not ci.is_valid(partner.vat):
partner.l10n_ec_vat_validation = _("The VAT %s seems to be invalid as the tenth digit doesn't comply with the validation algorithm "
"(could be an old VAT number)", partner.vat)
if partner.l10n_latam_identification_type_id.id == it_ruc.id and not ruc.is_valid(partner.vat):
partner.l10n_ec_vat_validation = _("The VAT %s seems to be invalid as the tenth digit doesn't comply with the validation algorithm "
"(SRI has stated that this validation is not required anymore for some VAT numbers)", partner.vat)
def _l10n_ec_get_identification_type(self):
"""Maps Odoo identification types to Ecuadorian ones.
Useful for document type domains, electronic documents, ats, others.
"""
self.ensure_one()
def id_type_in(*args):
return any([self.l10n_latam_identification_type_id == self.env.ref(arg) for arg in args])
if id_type_in('l10n_ec.ec_dni'):
return 'cedula' # DNI
elif id_type_in('l10n_ec.ec_ruc'):
return 'ruc' # RUC
elif id_type_in('l10n_latam_base.it_pass'):
return 'passport' # Pasaporte
elif id_type_in('l10n_latam_base.it_fid', 'l10n_latam_base.it_vat') \
or self.l10n_latam_identification_type_id.country_id != self.env.ref('base.ec'):
return 'foreign' # Identificacion del exterior