You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.4 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2017 Creu Blanca
  3. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
  4. from odoo import fields, models, api, _
  5. from odoo.exceptions import ValidationError
  6. import logging
  7. _logger = logging.getLogger(__name__)
  8. try:
  9. from stdnum.iso7064 import mod_97_10
  10. from stdnum.iso7064 import mod_37_2, mod_37_36
  11. from stdnum.iso7064 import mod_11_2, mod_11_10
  12. from stdnum import luhn, damm, verhoeff
  13. except(ImportError, IOError) as err:
  14. _logger.debug(err)
  15. class IrSequence(models.Model):
  16. _inherit = "ir.sequence"
  17. check_digit_formula = fields.Selection(
  18. selection=[
  19. ('none', 'None'),
  20. ('luhn', 'Luhn'),
  21. ('damm', 'Damm'),
  22. ('verhoeff', 'Verhoeff'),
  23. ('ISO7064_11_2', 'ISO 7064 Mod 11, 2'),
  24. ('ISO7064_11_10', 'ISO 7064 Mod 11, 10'),
  25. ('ISO7064_37_2', 'ISO 7064 Mod 37, 2'),
  26. ('ISO7064_37_36', 'ISO 7064 Mod 37, 36'),
  27. ('ISO7064_97_10', 'ISO 7064 Mod 97, 10'),
  28. ], default='none'
  29. )
  30. @api.constrains('check_digit_formula', 'prefix', 'suffix')
  31. def check_check_digit_formula(self):
  32. try:
  33. self.get_next_char(0)
  34. except Exception:
  35. raise ValidationError(_('Format is not accepted'))
  36. def get_check_digit(self, code):
  37. try:
  38. return self.get_formula_map()[self.check_digit_formula](code)
  39. except KeyError:
  40. raise ValidationError(_('%s is not an implemented function'
  41. % self.check_digit_formula))
  42. except Exception:
  43. raise ValidationError(_('Format is not accepted'))
  44. def get_formula_map(self):
  45. return {
  46. 'none': lambda _: '',
  47. 'luhn': luhn.calc_check_digit,
  48. 'damm': damm.calc_check_digit,
  49. 'verhoeff': verhoeff.calc_check_digit,
  50. 'ISO7064_11_2': mod_11_2.calc_check_digit,
  51. 'ISO7064_11_10': mod_11_10.calc_check_digit,
  52. 'ISO7064_37_2': mod_37_2.calc_check_digit,
  53. 'ISO7064_37_36': mod_37_36.calc_check_digit,
  54. 'ISO7064_97_10': mod_97_10.calc_check_digits
  55. }
  56. def get_next_char(self, number_next):
  57. code = super(IrSequence, self).get_next_char(number_next)
  58. if not self.check_digit_formula:
  59. return code
  60. return '%s%s' % (code, self.get_check_digit(code))