Skip to content

[19.0][MIG] base_name_search_improved: Migration to 19.0#3381

Open
bizzappdev wants to merge 39 commits into
OCA:19.0from
bizzappdev:19.0-mig-base_name_search_improved-BAD
Open

[19.0][MIG] base_name_search_improved: Migration to 19.0#3381
bizzappdev wants to merge 39 commits into
OCA:19.0from
bizzappdev:19.0-mig-base_name_search_improved-BAD

Conversation

@bizzappdev

Copy link
Copy Markdown
Contributor

No description provided.

@bizzappdev bizzappdev force-pushed the 19.0-mig-base_name_search_improved-BAD branch from f88ae89 to 56e83be Compare September 24, 2025 07:50
@bizzappdev bizzappdev marked this pull request as ready for review September 24, 2025 07:52

@baf-adhoc baf-adhoc left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functional review ok

@lef-adhoc

Copy link
Copy Markdown
Contributor

@bizzappdev Could you check this PR #3357 ?

@bizzappdev bizzappdev force-pushed the 19.0-mig-base_name_search_improved-BAD branch from 56e83be to bdeac98 Compare November 5, 2025 06:29

@lef-adhoc lef-adhoc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@OCA-git-bot

Copy link
Copy Markdown
Contributor

This PR has the approved label and has been created more than 5 days ago. It should therefore be ready to merge by a maintainer (or a PSC member if the concerned addon has no declared maintainer). 🤖

@mav-adhoc

Copy link
Copy Markdown

LGTM

@ced-adhoc ced-adhoc left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

seen_ids = {res[0] for res in original_results}
remaining_limit = limit - len(original_results) if limit else None
smart_results = Base.name_search(
self, name=name, args=args, operator=operator, limit=remaining_limit

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be

def _register_hook(self):
    def make_smart_name_search(original_name_search):
        def wrapper(
            self, name="", domain=None, operator="ilike", limit=100, **kwargs
        ):
            original_results = original_name_search(
                self, name, domain, operator, limit, **kwargs
            )
            if not name or (limit and len(original_results) >= limit):
                return original_results
            seen_ids = {res[0] for res in original_results}
            remaining_limit = limit - len(original_results) if limit else None
            smart_results = Base.name_search(
                self, name=name, domain=domain, operator=operator, limit=remaining_limit
            )
            additional_results = [
                (res_id, res_name)
                for res_id, res_name in smart_results
                if res_id not in seen_ids
            ]
            return original_results + additional_results

Odoo 19.0 introduced a breaking change in the name_search() method signature across all models:

Odoo ≤18.0: name_search(self, name="", args=None, operator="ilike", limit=100)
Odoo 19.0: name_search(self, name="", domain=None, operator="ilike", limit=100)
The parameter args was renamed to domain for consistency with other Odoo API methods.

The module fails in Odoo 19.0 with the error:
TypeError: Base.name_search() got an unexpected keyword argument 'domain'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bizzappdev Hi! I just want to ask you if you could see my review.
Thanks in advance!

@bizzappdev bizzappdev force-pushed the 19.0-mig-base_name_search_improved-BAD branch from bdeac98 to ebda477 Compare December 18, 2025 07:11

@ced-adhoc ced-adhoc left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

):
original_results = original_name_search(
self, name, domain, operator, limit, **kwargs
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:
original_results = original_name_search(
self, name=name, domain=domain, operator=operator, limit=limit, **kwargs
)

In Odoo 19, name_search signature changed from args to domain. Using named arguments ensures parameters are passed correctly regardless of the method signature and how Python unpacks arguments internally. This makes the code more robust and compatible across different Odoo versions and decorators.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bizzappdev Hi! I want to ask you if you have seen my review. Thanks!

@bizzappdev bizzappdev force-pushed the 19.0-mig-base_name_search_improved-BAD branch from ebda477 to b4dea29 Compare January 20, 2026 13:12
jjscarafia and others added 26 commits January 20, 2026 19:13
Currently translated at 94.4% (17 of 18 strings)

Translation: server-tools-14.0/server-tools-14.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-base_name_search_improved/it/
Translate Spanish texts to English
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: server-tools-16.0/server-tools-16.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-base_name_search_improved/
Currently translated at 100.0% (25 of 25 strings)

Translation: server-tools-16.0/server-tools-16.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-base_name_search_improved/es/
Currently translated at 36.0% (9 of 25 strings)

Translation: server-tools-16.0/server-tools-16.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-base_name_search_improved/it/
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: server-tools-16.0/server-tools-16.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-base_name_search_improved/
When applying monkey patches, we want to skip abstract models because patching
those may mess up the inheritance. An example of this is ir.model which is
assigned the studio mixin using inherit = ['studio.mixin', 'ir.model'].
If the mixin itself is patched, and the method is overridden once again (in,
say, enterprise 15's documents_spreadsheet), the super() method called in that
override is the patched version of studio.mixin rather than the override of
ir.model in the base module, which is now skipped entirely.
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: server-tools-18.0/server-tools-18.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-base_name_search_improved/
… wrapper

This refactor ensures the smart search functionality works reliably across
all models, including those with custom search logic like `product.product`.

Instead of being overridden, this module now uses a startup hook to wrap
the existing `name_search`. This new approach merges results from the
original search with the smart search, providing a richer, more
consistent user experience.
Currently translated at 96.0% (24 of 25 strings)

Translation: server-tools-18.0/server-tools-18.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-base_name_search_improved/tr/
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translation: server-tools-18.0/server-tools-18.0-base_name_search_improved
Translate-URL: https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-base_name_search_improved/
…t_search

In v18 `_search_smart_search` was delegating to `name_search`.
This introduces an artificial limit (100 records) before other
domain filters are applied, leading to incomplete results.

This PR restores the original behavior from v16:
- Build the domain directly in `_search_smart_search`.

This makes smart search consistent again with standard search
and avoids missing records.
@bizzappdev bizzappdev force-pushed the 19.0-mig-base_name_search_improved-BAD branch from b4dea29 to 5ed79ca Compare January 20, 2026 13:52

@gdgellatly gdgellatly left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static Code Review only LGTM and seems comments dealt to

@gdgellatly gdgellatly left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further review

# Try ordered word search on each of the search fields
for rec_name in all_names:
domain = Domain.AND(
[base_domain, [(rec_name, operator, name.replace(" ", "%"))]]

@gdgellatly gdgellatly Mar 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In testing we get a weird error here. This is clicking through from a partner on a sale order with Smart Name Search enabled. The error is when smart search is on the fields complete_name, normalized email and phone and it reads

File "/odoo/src/server-tools/base_name_search_improved/models/ir_model.py", line 119, in name_search
    [base_domain, [(rec_name, operator, name.replace(" ", "%"))]]
                                        ^^^^^^^^^^^^
AttributeError: 'list' object has no attribute 'replace'

Unfortunately runboat not working so couldn't reproduce. The only special thing going on is there is a name_search super call intervening, however in this case it is a straight passthrough to super

Note it does not fail when using standard search in a list view

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this is my workaround to get things running, however it is not the fix

diff --git a/base_name_search_improved/models/ir_model.py b/base_name_search_improved/models/ir_model.py
index 5f14d449..78792c01 100644
--- a/base_name_search_improved/models/ir_model.py
+++ b/base_name_search_improved/models/ir_model.py
@@ -96,7 +96,7 @@ class Base(models.AbstractModel):
 
     @api.model
     def name_search(self, name="", domain=None, operator="ilike", limit=100):
-        if not name or not (
+        if not name or not isinstance(name, str) or not (
             self.env.context.get("force_smart_name_search", False)
             or _get_use_smart_name_search(self.sudo())
         ):
@@ -236,7 +236,7 @@ class IrModel(models.Model):
                     limit=limit,
                     **kwargs,
                 )
-                if not name or (limit and len(original_results) >= limit):
+                if not name or not isinstance(name, str) or (limit and len(original_results) >= limit):
                     return original_results
                 seen_ids = {res[0] for res in original_results}
                 remaining_limit = limit - len(original_results) if limit else None

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.