# Copyright 2019 Creu Blanca # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import base64 import binascii import json import re from flectra import _, api, fields, models from flectra.exceptions import UserError class DocumentQuickAccessRule(models.Model): _name = "document.quick.access.rule" _description = "Document Quick Access Rule" _order = "priority,model_id" name = fields.Char(required=True) priority = fields.Integer(default=16, required=True) barcode_format = fields.Selection( [("standard", "Standard"), ("b64_standard", "Base64")], required=True, default="standard", ) # All formats must have a function to determine the code from a record and # get the record from the code model_id = fields.Many2one("ir.model", required=True, ondelete="cascade") active = fields.Boolean(default=True) def get_code(self, record): self.ensure_one() return getattr(self, "_get_code_%s" % self.barcode_format)(record) def _get_code_b64_standard(self, record): return base64.b64encode(self._get_code_standard(record).encode("utf-8")).decode( "utf-8" ) def _get_code_standard(self, record): return "{},{}".format(record._name, record.id) def _check_code_b64_standard(self, code): try: aux_code = base64.b64decode(code.encode("utf-8"), validate=True) except binascii.Error: return False return self._check_code_standard(aux_code.decode("utf-8")) def _check_code_standard(self, code): return re.match("^[a-zA-Z0-9\\.]*,[0-9]*$", code) def _read_code_b64_standard(self, code): aux_code = base64.b64decode(code.encode("utf-8")).decode("utf-8") return self._read_code_standard(aux_code) def _read_code_standard(self, code): params = code.split(",") return self.env[params[0]].browse(int(params[1])).exists() def read_code_action(self, code): try: record = self.read_code(code) except UserError: return { "type": "ir.actions.act_window", "name": "Search QR", "res_model": "barcode.action", "views": [[False, "form"]], "target": "new", "context": json.dumps( { "default_model": "document.quick.access.rule", "default_method": "read_code_action", "default_state": "warning", "default_status": _("Document cannot be found"), } ), } record.check_access_rights("read") result = { "type": "ir.actions.act_window", "res_model": record._name, "views": [[record.get_formview_id(), "form"]], "res_id": record.id, "target": "main", } return result @api.model def read_code(self, code): formats = self._fields["barcode_format"].selection for barcode_format, _format_name in formats: if getattr(self, "_check_code_%s" % barcode_format)(code): record = getattr(self, "_read_code_%s" % barcode_format)(code) if record and self.search( [ ("model_id.model", "=", record._name), ("barcode_format", "=", barcode_format), ] ): return record raise UserError(_("No format has been found for this record"))