Skip to content

Commit

Permalink
[MIG] base_name_search_improved: Migration to 17.0
Browse files Browse the repository at this point in the history
  • Loading branch information
rov-adhoc committed Feb 7, 2024
1 parent 12d7dc9 commit 7b24e72
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 34 deletions.
2 changes: 1 addition & 1 deletion base_name_search_improved/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Improved Name Search",
"summary": "Friendlier search when typing in relation fields",
"version": "16.0.1.0.0",
"version": "17.0.1.0.0",
"category": "Uncategorized",
"website": "https://github.com/OCA/server-tools",
"author": "Daniel Reis, Odoo Community Association (OCA), ADHOC SA",
Expand Down
39 changes: 21 additions & 18 deletions base_name_search_improved/models/ir_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import logging
from ast import literal_eval
from collections import defaultdict

from lxml import etree

Expand Down Expand Up @@ -55,12 +56,13 @@ def _get_name_search_domain(self):
return []


def _extend_name_results(self, domain, results, limit, name_get_uid):
def _extend_name_results(self, domain, results, limit):
result_count = len(results)
if result_count < limit:
domain += [("id", "not in", results)]
rec_ids = self._search(
domain, limit=limit - result_count, access_rights_uid=name_get_uid
domain,
limit=limit - result_count,
)
results.extend(rec_ids)
return results
Expand All @@ -69,40 +71,35 @@ def _extend_name_results(self, domain, results, limit, name_get_uid):
def patch_name_search():
@api.model
def _name_search(
self, name="", args=None, operator="ilike", limit=100, name_get_uid=None
self, name="", domain=None, operator="ilike", limit=100, order=None
):
# Perform standard name search
res = _name_search.origin(
self,
name=name,
args=args,
operator=operator,
domain=domain,
limit=limit,
name_get_uid=name_get_uid,
order=order,
)
if name and _get_use_smart_name_search(self.sudo()) and operator in ALLOWED_OPS:
# _name_search.origin is a query, we need to convert it to a list
res = self.browse(res).ids
limit = limit or 0

# we add domain
args = args or [] + _get_name_search_domain(self.sudo())
args = domain or [] + _get_name_search_domain(self.sudo())

# Support a list of fields to search on
all_names = _get_rec_names(self.sudo())
base_domain = args or []
# Try regular search on each additional search field
for rec_name in all_names[1:]:
domain = [(rec_name, operator, name)]
res = _extend_name_results(
self, base_domain + domain, res, limit, name_get_uid
)
res = _extend_name_results(self, base_domain + domain, res, limit)
# Try ordered word search on each of the search fields
for rec_name in all_names:
domain = [(rec_name, operator, name.replace(" ", "%"))]
res = _extend_name_results(
self, base_domain + domain, res, limit, name_get_uid
)
res = _extend_name_results(self, base_domain + domain, res, limit)
# Try unordered word search on each of the search fields
# we only perform this search if we have at least one
# separator character
Expand All @@ -116,9 +113,7 @@ def _name_search(
word_domain and ["|"] + word_domain or word_domain
) + [(rec_name, operator, word)]
domain = (domain and ["&"] + domain or domain) + word_domain
res = _extend_name_results(
self, base_domain + domain, res, limit, name_get_uid
)
res = _extend_name_results(self, base_domain + domain, res, limit)

return res

Expand Down Expand Up @@ -214,7 +209,7 @@ def _compute_smart_search_warning(self):

@api.constrains("name_search_ids", "name_search_domain", "add_smart_search")
def update_search_wo_restart(self):
self.clear_caches()
self.env.registry.clear_cache()

@api.constrains("name_search_domain")
def check_name_search_domain(self):
Expand All @@ -238,9 +233,17 @@ def check_name_search_domain(self):
def _register_hook(self):
_logger.info("Patching BaseModel for Smart Search")

patched_models = defaultdict(set)

def patch(model, name, method):
if model not in patched_models[name]:
ModelClass = type(model)
method.origin = getattr(ModelClass, name)
setattr(ModelClass, name, method)

for model in self.sudo().search(self.ids or []):
Model = self.env.get(model.model)
if Model is not None:
Model._patch_method("_name_search", patch_name_search())
patch(Model, "_name_search", patch_name_search())

return super()._register_hook()
22 changes: 10 additions & 12 deletions base_name_search_improved/tests/test_name_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@tagged("post_install", "-at_install")
class NameSearchCase(TransactionCase):
def setUp(self):
super(NameSearchCase, self).setUp()
super().setUp()
phone_field = self.env.ref("base.field_res_partner__phone")
model_partner = self.env.ref("base.model_res_partner")
model_partner.name_search_ids = phone_field
Expand Down Expand Up @@ -35,37 +35,35 @@ def setUp(self):

def test_RelevanceOrderedResults(self):
"""Return results ordered by relevance"""
res = self.Partner.name_search("555 777")
res = self.Partner._name_search("555 777")
self.assertEqual(res[0], self.partner1.id, "Match full string honoring spaces")
self.assertEqual(
res[0][0], self.partner1.id, "Match full string honoring spaces"
res[1], self.partner2.id, "Match words honoring order of appearance"
)
self.assertEqual(
res[1][0], self.partner2.id, "Match words honoring order of appearance"
)
self.assertEqual(
res[2][0],
res[2],
self.partner3.id,
"Match all words, regardless of order of appearance",
)

def test_NameSearchMustMatchAllWords(self):
"""Must Match All Words"""
res = self.Partner.name_search("ulm aaa 555 777")
res = self.Partner._name_search("ulm aaa 555 777")
self.assertFalse(res)

def test_NameSearchDifferentFields(self):
"""Must Match All Words"""
res = self.Partner.name_search("ulm 555 777")
res = self.Partner._name_search("ulm 555 777")
self.assertEqual(len(res), 1)

def test_NameSearchDomain(self):
"""Must not return a partner with parent"""
res = self.Partner.name_search("Edward Foster")
res = self.Partner._name_search("Edward Foster")
self.assertFalse(res)

def test_MustHonorDomain(self):
"""Must also honor a provided Domain"""
res = self.Partner.name_search("+351", args=[("vat", "=", "3333")])
res = self.Partner._name_search("+351", domain=[("vat", "=", "3333")])
gambulputty = self.partner3.id
self.assertEqual(len(res), 1)
self.assertEqual(res[0][0], gambulputty)
self.assertEqual(res[0], gambulputty)
6 changes: 3 additions & 3 deletions base_name_search_improved/views/ir_model_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@
<!-- TODO use new odoo domain widget -->
<field
name="name_search_domain"
attrs="{'invisible': [('use_smart_name_search', '=', False), ('add_smart_search', '=', False)]}"
invisible="not use_smart_name_search and not add_smart_search"
/>
</group>
</group>
<notebook
colspan="4"
attrs="{'invisible': [('use_smart_name_search', '=', False), ('add_smart_search', '=', False)]}"
invisible="not use_smart_name_search and not add_smart_search"
>
<page string="Smart Search Fields">
<!-- we use default m2m widget and not tags widget so that is clearer the technical name of the field added -->
Expand All @@ -97,7 +97,7 @@
<field name="model">ir.model</field>
<field name="arch" type="xml">
<tree>
<field name="id" invisible="1" />
<field name="id" column_invisible="True" />
<field name="name" readonly="1" />
<field
name="name_search_ids"
Expand Down

0 comments on commit 7b24e72

Please sign in to comment.