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.

100 lines
3.4 KiB

  1. # Copyright 2019 Creu Blanca
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. import base64
  4. import json
  5. import binascii
  6. from odoo import api, fields, models, _
  7. from odoo.exceptions import UserError
  8. import re
  9. class DocumentQuickAccessRule(models.Model):
  10. _name = 'document.quick.access.rule'
  11. _description = 'Document Quick Access Rule'
  12. _order = 'priority,model_id'
  13. name = fields.Char(required=True)
  14. priority = fields.Integer(default=16, required=True)
  15. barcode_format = fields.Selection([
  16. ('standard', 'Standard'),
  17. ('b64_standard', 'Base64'),
  18. ], required=True, default='standard')
  19. # All formats must have a function to determine the code from a record and
  20. # get the record from the code
  21. model_id = fields.Many2one(
  22. 'ir.model',
  23. required=True,
  24. )
  25. active = fields.Boolean(
  26. default=True,
  27. )
  28. def get_code(self, record):
  29. self.ensure_one()
  30. return getattr(self, '_get_code_%s' % self.barcode_format)(record)
  31. def _get_code_b64_standard(self, record):
  32. return base64.b64encode(
  33. self._get_code_standard(record).encode('utf-8')).decode('utf-8')
  34. def _get_code_standard(self, record):
  35. return '%s,%s' % (record._name, record.id)
  36. def _check_code_b64_standard(self, code):
  37. try:
  38. aux_code = base64.b64decode(code.encode('utf-8'), validate=True)
  39. except binascii.Error:
  40. return False
  41. return self._check_code_standard(aux_code.decode('utf-8'))
  42. def _check_code_standard(self, code):
  43. return re.match("^[a-zA-Z0-9\\.]*,[0-9]*$", code)
  44. def _read_code_b64_standard(self, code):
  45. aux_code = base64.b64decode(code.encode('utf-8')).decode('utf-8')
  46. return self._read_code_standard(aux_code)
  47. def _read_code_standard(self, code):
  48. params = code.split(',')
  49. return self.env[params[0]].browse(int(params[1])).exists()
  50. def read_code_action(self, code):
  51. try:
  52. record = self.read_code(code)
  53. except UserError:
  54. return {
  55. 'type': 'ir.actions.act_window',
  56. 'name': 'Search QR',
  57. 'res_model': 'barcode.action',
  58. 'views': [[False, 'form']],
  59. 'target': 'new',
  60. 'context': json.dumps({
  61. 'default_model': 'document.quick.access.rule',
  62. 'default_method': 'read_code_action',
  63. 'default_state': 'warning',
  64. 'default_status': _('Document cannot be found')
  65. })
  66. }
  67. record.check_access_rights('read')
  68. result = {
  69. "type": "ir.actions.act_window",
  70. "res_model": record._name,
  71. "views": [[record.get_formview_id(), "form"]],
  72. "res_id": record.id,
  73. "target": "main",
  74. }
  75. return result
  76. @api.model
  77. def read_code(self, code):
  78. formats = self._fields['barcode_format'].selection
  79. for barcode_format, format_name in formats:
  80. if getattr(self, '_check_code_%s' % barcode_format)(code):
  81. record = getattr(self, '_read_code_%s' % barcode_format)(code)
  82. if record and self.search([
  83. ('model_id.model', '=', record._name),
  84. ('barcode_format', '=', barcode_format)
  85. ]):
  86. return record
  87. raise UserError(_('No format has been found for this record'))