diff --git a/addons/product/models/product.py b/addons/product/models/product.py index 1f4ca973217..2067878d70d 100644 --- a/addons/product/models/product.py +++ b/addons/product/models/product.py @@ -383,17 +383,36 @@ class ProductProduct(models.Model): self.check_access_rule("read") result = [] + + # Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields + # Use `load=False` to not call `name_get` for the `product_tmpl_id` + self.sudo().read(['name', 'default_code', 'product_tmpl_id', 'attribute_value_ids'], load=False) + + product_template_ids = self.sudo().mapped('product_tmpl_id').ids + + if partner_ids: + supplier_info = self.env['product.supplierinfo'].sudo().search([ + ('product_tmpl_id', 'in', product_template_ids), + ('name', 'in', partner_ids), + ]) + # Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields + # Use `load=False` to not call `name_get` for the `product_tmpl_id` and `product_id` + supplier_info.sudo().read(['product_tmpl_id', 'product_id', 'product_name', 'product_code'], load=False) + supplier_info_by_template = {} + for r in supplier_info: + supplier_info_by_template.setdefault(r.product_tmpl_id, []).append(r) for product in self.sudo(): # display only the attributes with multiple possible values on the template - variable_attributes = product.attribute_line_ids.filtered(lambda l: len(l.value_ids) > 1).mapped('attribute_id') + variable_attributes = product.attribute_value_ids.filtered(lambda v: len(v.attribute_id.value_ids) > 1).mapped('attribute_id') variant = product.attribute_value_ids._variant_name(variable_attributes) name = variant and "%s (%s)" % (product.name, variant) or product.name sellers = [] if partner_ids: - sellers = [x for x in product.seller_ids if (x.name.id in partner_ids) and (x.product_id == product)] + product_supplier_info = supplier_info_by_template.get(product.product_tmpl_id, []) + sellers = [x for x in product_supplier_info if x.product_id and x.product_id == product] if not sellers: - sellers = [x for x in product.seller_ids if (x.name.id in partner_ids) and not x.product_id] + sellers = [x for x in product_supplier_info if not x.product_id] if sellers: for s in sellers: seller_variant = s.product_name and ( diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py index 602a139bba5..e40525e3933 100644 --- a/addons/product/models/product_template.py +++ b/addons/product/models/product_template.py @@ -332,6 +332,8 @@ class ProductTemplate(models.Model): @api.multi def name_get(self): + # Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields + self.read(['name', 'default_code']) return [(template.id, '%s%s' % (template.default_code and '[%s] ' % template.default_code or '', template.name)) for template in self] diff --git a/odoo/addons/base/res/res_currency_data.xml b/odoo/addons/base/res/res_currency_data.xml index f4028c0b698..1c67808c8a2 100644 --- a/odoo/addons/base/res/res_currency_data.xml +++ b/odoo/addons/base/res/res_currency_data.xml @@ -201,7 +201,7 @@ VND ₫ - 0.01 + 1.00 Dong Xu diff --git a/odoo/addons/base/res/res_partner.py b/odoo/addons/base/res/res_partner.py index 147eed2f95f..e8997e705d1 100644 --- a/odoo/addons/base/res/res_partner.py +++ b/odoo/addons/base/res/res_partner.py @@ -653,6 +653,7 @@ class Partner(models.Model): where_query = self._where_calc(args) self._apply_ir_rules(where_query, 'read') from_clause, where_clause, where_clause_params = where_query.get_sql() + from_str = from_clause if from_clause else 'res_partner' where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company @@ -664,8 +665,8 @@ class Partner(models.Model): unaccent = get_unaccent_wrapper(self.env.cr) - query = """SELECT id - FROM res_partner + query = """SELECT res_partner.id + FROM {from_str} {where} ({email} {operator} {percent} OR {display_name} {operator} {percent} OR {reference} {operator} {percent} @@ -673,13 +674,14 @@ class Partner(models.Model): -- don't panic, trust postgres bitmap ORDER BY {display_name} {operator} {percent} desc, {display_name} - """.format(where=where_str, + """.format(from_str=from_str, + where=where_str, operator=operator, - email=unaccent('email'), - display_name=unaccent('display_name'), - reference=unaccent('ref'), + email=unaccent('res_partner.email'), + display_name=unaccent('res_partner.display_name'), + reference=unaccent('res_partner.ref'), percent=unaccent('%s'), - vat=unaccent('vat'),) + vat=unaccent('res_partner.vat'),) where_clause_params += [search_name]*5 if limit: diff --git a/odoo/addons/base/tests/__init__.py b/odoo/addons/base/tests/__init__.py index 9e1856315cd..e1a9084dd7c 100644 --- a/odoo/addons/base/tests/__init__.py +++ b/odoo/addons/base/tests/__init__.py @@ -31,6 +31,7 @@ from . import test_user_has_group from . import test_view_validation from . import test_views from . import test_xmlrpc +from . import test_res_partner from . import test_res_partner_bank from . import test_reports from . import test_non_regression diff --git a/odoo/addons/base/tests/test_res_partner.py b/odoo/addons/base/tests/test_res_partner.py new file mode 100644 index 00000000000..2a6722553af --- /dev/null +++ b/odoo/addons/base/tests/test_res_partner.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests.common import TransactionCase + + +class TestPartner(TransactionCase): + + def test_name_search(self): + """ Check name_search on partner, especially with domain based on auto_join + user_ids field. Check specific SQL of name_search correctly handle joined tables. """ + test_partner = self.env['res.partner'].create({'name': 'Vlad the Impaler'}) + test_user = self.env['res.users'].create({'name': 'Vlad the Impaler', 'login': 'vlad', 'email': 'vlad.the.impaler@example.com'}) + + ns_res = self.env['res.partner'].name_search('Vlad', operator='ilike') + self.assertEqual(set(i[0] for i in ns_res), set((test_partner | test_user.partner_id).ids)) + + ns_res = self.env['res.partner'].name_search('Vlad', args=[('user_ids.email', 'ilike', 'vlad')]) + self.assertEqual(set(i[0] for i in ns_res), set(test_user.partner_id.ids))