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.3 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. try:
  8. from stdnum.iso7064 import mod_97_10
  9. from stdnum.iso7064 import mod_37_2, mod_37_36
  10. from stdnum.iso7064 import mod_11_2, mod_11_10
  11. from stdnum import luhn, damm, verhoeff
  12. except(ImportError, IOError) as err:
  13. logging.info(err)
  14. class IrSequence(models.Model):
  15. _inherit = "ir.sequence"
  16. check_digit_formula = fields.Selection(
  17. selection=[
  18. ('none', 'None'),
  19. ('luhn', 'Luhn'),
  20. ('damm', 'Damm'),
  21. ('verhoeff', 'Verhoeff'),
  22. ('ISO7064_11_2', 'ISO 7064 Mod 11, 2'),
  23. ('ISO7064_11_10', 'ISO 7064 Mod 11, 10'),
  24. ('ISO7064_37_2', 'ISO 7064 Mod 37, 2'),
  25. ('ISO7064_37_36', 'ISO 7064 Mod 37, 36'),
  26. ('ISO7064_97_10', 'ISO 7064 Mod 97, 10'),
  27. ], default='none'
  28. )
  29. @api.constrains('check_digit_formula', 'prefix', 'suffix')
  30. def check_check_digit_formula(self):
  31. try:
  32. self.get_next_char(0)
  33. except Exception:
  34. raise ValidationError(_('Format is not accepted'))
  35. def get_check_digit(self, code):
  36. try:
  37. return self.get_formula_map()[self.check_digit_formula](code)
  38. except KeyError:
  39. raise ValidationError(_('%s is not an implemented function'
  40. % self.check_digit_formula))
  41. except Exception:
  42. raise ValidationError(_('Format is not accepted'))
  43. def get_formula_map(self):
  44. return {
  45. 'none': lambda _: '',
  46. 'luhn': luhn.calc_check_digit,
  47. 'damm': damm.calc_check_digit,
  48. 'verhoeff': verhoeff.calc_check_digit,
  49. 'ISO7064_11_2': mod_11_2.calc_check_digit,
  50. 'ISO7064_11_10': mod_11_10.calc_check_digit,
  51. 'ISO7064_37_2': mod_37_2.calc_check_digit,
  52. 'ISO7064_37_36': mod_37_36.calc_check_digit,
  53. 'ISO7064_97_10': mod_97_10.calc_check_digits
  54. }
  55. def get_next_char(self, number_next):
  56. code = super(IrSequence, self).get_next_char(number_next)
  57. if not self.check_digit_formula:
  58. return code
  59. return '%s%s' % (code, self.get_check_digit(code))