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.

80 lines
3.1 KiB

  1. # Copyright 2016 Daniel Reis
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import models, fields, api, tools
  4. # Extended name search is only used on some operators
  5. ALLOWED_OPS = {'ilike', 'like'}
  6. @tools.ormcache(skiparg=0)
  7. def _get_rec_names(self):
  8. "List of fields to search into"
  9. model = self.env['ir.model'].search(
  10. [('model', '=', self._name)])
  11. rec_name = [self._rec_name] if bool(self._rec_name) else []
  12. other_names = model.name_search_ids.mapped('name')
  13. return rec_name + other_names
  14. def _extend_name_results(self, domain, results, limit):
  15. result_count = len(results)
  16. if result_count < limit:
  17. domain += [('id', 'not in', [x[0] for x in results])]
  18. recs = self.search(domain, limit=limit - result_count)
  19. results.extend(recs.name_get())
  20. return results
  21. class IrModel(models.Model):
  22. _inherit = 'ir.model'
  23. name_search_ids = fields.Many2many(
  24. 'ir.model.fields',
  25. string='Name Search Fields')
  26. @api.model_cr
  27. def _register_hook(self):
  28. def make_name_search():
  29. @api.model
  30. def name_search(self, name='', args=None,
  31. operator='ilike', limit=100):
  32. # Perform standard name search
  33. res = name_search.origin(
  34. self, name=name, args=args, operator=operator,
  35. limit=limit)
  36. enabled = self.env.context.get('name_search_extended', True)
  37. # Perform extended name search
  38. # Note: Empty name causes error on
  39. # Customer->More->Portal Access Management
  40. if name and enabled and operator in ALLOWED_OPS:
  41. # Support a list of fields to search on
  42. all_names = _get_rec_names(self)
  43. base_domain = args or []
  44. # Try regular search on each additional search field
  45. for rec_name in all_names[1:]:
  46. domain = [(rec_name, operator, name)]
  47. res = _extend_name_results(
  48. self, base_domain + domain, res, limit)
  49. # Try ordered word search on each of the search fields
  50. for rec_name in all_names:
  51. domain = [
  52. (rec_name, operator, name.replace(' ', '%'))]
  53. res = _extend_name_results(
  54. self, base_domain + domain, res, limit)
  55. # Try unordered word search on each of the search fields
  56. for rec_name in all_names:
  57. domain = [(rec_name, operator, x)
  58. for x in name.split() if x]
  59. res = _extend_name_results(
  60. self, base_domain + domain, res, limit)
  61. return res
  62. return name_search
  63. for model in self.sudo().search(self.ids or []):
  64. Model = self.env.get(model.model)
  65. if Model is not None:
  66. Model._patch_method('name_search', make_name_search())
  67. return super(IrModel, self)._register_hook()