def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params =\ where_query.get_sql() where_str =\ where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) query = """SELECT id FROM res_partner {where} ({email} {operator} {percent} OR {display_name} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('email'), display_name=unaccent('display_name'), percent=unaccent('%s')) where_clause_params += [search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) # patch for record from translation translation_obj = self.pool.get('ir.translation') trans_name = '%s,%s' % (self._model, 'name') translation_ids =\ translation_obj.search(cr, uid, [('value', 'ilike', name), ('name', '=', trans_name)], limit=limit, context=context) translations = translation_obj.browse(cr, uid, translation_ids, context=context) record_ids = [t.res_id for t in translations] ids = list(set(ids) | set(record_ids)) # patch over if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(ResPartner, self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql( ) where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) query = """SELECT id FROM res_partner {where} ({email} {operator} {percent} OR {display_name} {operator} {percent} OR {city} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('email'), display_name=unaccent('display_name'), city=unaccent('city'), percent=unaccent('%s')) where_clause_params += [search_name, search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(res_partner, self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search( self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): unaccent = get_unaccent_wrapper(cr) self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params =\ where_query.get_sql() where_str = where_clause\ and (" WHERE %s AND " % where_clause) or ' WHERE ' if "product_product__product_tmpl_id" not in from_clause: from_clause +=\ ',"product_template" as "product_product__product_tmpl_id"' if operator in ('ilike', 'like'): percent = True if operator in ('=ilike', '=like'): operator = operator[1:] names = name.split(self._SEPARATOR) pwc = "" for n in names: search_name = '%%%s%%' % n if percent else n pwc += """ AND ({display_name} {operator} {percent}) """.format( operator=operator, percent=unaccent('%s'), display_name=unaccent( 'product_product__product_tmpl_id.name')) where_clause_params += [search_name] pwc = pwc[5:] query = """SELECT product_product.id FROM {from_clause} {where} ({pwc}) ORDER BY {display_name} """.format( from_clause=from_clause, where=where_str, pwc=pwc, display_name=unaccent( 'product_product__product_tmpl_id.name')) if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(product_product, self).name_search( cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like') and len(name) >= 3: self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql( ) where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name operator = 'like' if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) where_str = where_str.replace('"res_partner"', 'p') query = """SELECT p.id FROM res_partner p {where} (upper(p.{display_name}) {operator} {percent} OR upper(p.{default_code}) {operator} {percent} OR upper(p.{member}) {operator} {percent}) ORDER BY p.{display_name}, p.{default_code} """.format(where=where_str, operator=operator, display_name=unaccent('display_name'), default_code=unaccent('default_code'), member=unaccent('member'), percent=unaccent('%s')) where_clause_params += [ search_name.upper(), search_name.upper(), search_name.upper() ] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return []
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql() where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) # TODO: simplify this in trunk with `display_name`, once it is stored # Perf note: a CTE expression (WITH ...) seems to have an even higher cost # than this query with duplicated CASE expressions. The bulk of # the cost is the ORDER BY, and it is inevitable if we want # relevant results for the next step, otherwise we'd return # a random selection of `limit` results. display_name = """CASE WHEN company.id IS NULL OR res_partner.is_company THEN {partner_name} ELSE {company_name} || ', ' || {partner_name} END""".format(partner_name=unaccent('res_partner.name'), company_name=unaccent('company.name')) query = """SELECT res_partner.id FROM res_partner LEFT JOIN res_partner company ON res_partner.parent_id = company.id {where} ({email} {operator} {percent} OR {display_name} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('res_partner.email'), percent=unaccent('%s'), display_name=display_name) where_clause_params += [search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(res_partner,self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search(self, cr, uid, name, args=None, operator="ilike", context=None, limit=100): if not args: args = [] if name and operator in ("=", "ilike", "=ilike", "like", "=like"): self.check_access_rights(cr, uid, "read") where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, "read", context=context) from_clause, where_clause, where_clause_params = where_query.get_sql() where_str = where_clause and (" WHERE %s AND " % where_clause) or " WHERE " # search on the name of the contacts and of its company search_name = name if operator in ("ilike", "like"): search_name = "%%%s%%" % name if operator in ("=ilike", "=like"): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) query = """SELECT id FROM res_partner {where} ({email} {operator} {percent} OR {display_name} {operator} {percent} OR {reference} {operator} {percent}) -- don't panic, trust postgres bitmap ORDER BY {display_name} {operator} {percent} desc, {display_name} """.format( where=where_str, operator=operator, email=unaccent("email"), display_name=unaccent("display_name"), reference=unaccent("ref"), percent=unaccent("%s"), ) where_clause_params += [search_name] * 4 if limit: query += " limit %s" where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(res_partner, self).name_search( cr, uid, name, args, operator=operator, context=context, limit=limit )
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): unaccent = get_unaccent_wrapper(cr) self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql() where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' if "product_product__product_tmpl_id" not in from_clause: from_clause += ",\"product_template\" as \"product_product__product_tmpl_id\"" if operator in ('ilike', 'like'): percent = True if operator in ('=ilike', '=like'): operator = operator[1:] names = name.split(self._SEPARATOR) pwc = "" for n in names: search_name = '%%%s%%' % n if percent else n pwc += """ AND ({display_name} {operator} {percent}) """.format(operator=operator, percent=unaccent('%s'), display_name=unaccent('product_product__product_tmpl_id.name')) where_clause_params += [search_name] pwc = pwc[5:] query = """SELECT product_product.id FROM {from_clause} {where} ({pwc}) ORDER BY {display_name} """.format(from_clause=from_clause, where=where_str, pwc=pwc, display_name=unaccent('product_product__product_tmpl_id.name')) if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(product_product,self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql() where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) display_name = self._get_display_name(unaccent) query = """SELECT res_partner.id FROM res_partner LEFT JOIN res_partner company ON res_partner.parent_id = company.id {where} ({email} {operator} {percent} OR {display_name} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('res_partner.email'), percent=unaccent('%s'), display_name=display_name) where_clause_params += [search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(res_partner,self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') # 产看当前用户是否有对res.partner的读权限 where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql() where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) query = """SELECT id FROM res_partner {where} ({email} {operator} {percent} OR {display_name} {operator} {percent} OR {py} {operator} {percent} OR {pinyin} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('email'), display_name=unaccent('display_name'), py=unaccent('py'), pinyin=unaccent('pinyin'), percent=unaccent('%s')) where_clause_params += [search_name, search_name, search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) # 根据一个partner所属国家的address格式对该partner的名称进行格式化 else: return [] return super(WithPinyinPartner,self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def name_search(self, name, args=None, operator='ilike', limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights('read') where_query = self._where_calc(args) self._apply_ir_rules(where_query, 'read') from_clause, where_clause, where_clause_params = where_query.get_sql() where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(self.env.cr) query = """SELECT id FROM res_partner {where} ({email} {operator} {percent} OR {display_name} {operator} {percent} OR {comercial} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('email'), display_name=unaccent('display_name'), comercial=unaccent('comercial'), percent=unaccent('%s')) where_clause_params += [search_name, search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) self.env.cr.execute(query, where_clause_params) ids = map(lambda x: x[0], self.env.cr.fetchall()) if ids: return self.browse(ids).name_get() else: return [] return super(ResPartner,self).name_search(name, args, operator=operator, limit=limit)
def extended_init(self, cr, uid, exp, table, context): self._unaccent = expression.get_unaccent_wrapper(cr) self.joins = [] self.root_model = table # normalize and prepare the expression for parsing self.expression = expression.distribute_not( expression.normalize_domain(exp)) # look for real lang from context before parse parse_ctx = context.copy() if parse_ctx.get('lang', False) and exists_short_code(cr): cr.execute("select code from res_lang where short_code = '%s'" % parse_ctx['lang']) res = cr.fetchall() if res and res[0]: parse_ctx.update({'lang': res[0][0]}) # parse the domain expression self.parse(cr, uid, context=parse_ctx)
def __init__(self, cr, uid, exp, table, context): """ Initialize expression object and automatically parse the expression right after initialization. :param exp: expression (using domain ('foo', '=', 'bar' format)) :param table: root model :attr list result: list that will hold the result of the parsing as a list of ExtendedLeaf :attr list joins: list of join conditions, such as (res_country_state."id" = res_partner."state_id") :attr root_model: base model for the query :attr list expression: the domain expression, that will be normalized and prepared """ self._unaccent = get_unaccent_wrapper(cr) self.joins = [] self.root_model = table # normalize and prepare the expression for parsing self.expression = distribute_not(normalize_domain(exp)) # Keep a dict of table aliases to ensure that no alias # of lenght > 64 char are created self.table_aliases = {} # aliases are of the following form # a1, a2, a3 ... a10 ... a999 ... self.next_alias_int = 1 self.cr = cr self.uid = uid self.context = context # parse the domain expression self.parse(cr, uid, context=context)
def test_20_auto_join(self): registry, cr, uid = self.registry, self.cr, self.uid unaccent = get_unaccent_wrapper(cr) # Get models partner_obj = registry('res.partner') state_obj = registry('res.country.state') bank_obj = registry('res.partner.bank') # Get test columns partner_state_id_col = partner_obj._columns.get('state_id') # many2one on res.partner to res.country.state partner_parent_id_col = partner_obj._columns.get('parent_id') # many2one on res.partner to res.partner state_country_id_col = state_obj._columns.get('country_id') # many2one on res.country.state on res.country partner_child_ids_col = partner_obj._columns.get('child_ids') # one2many on res.partner to res.partner partner_bank_ids_col = partner_obj._columns.get('bank_ids') # one2many on res.partner to res.partner.bank category_id_col = partner_obj._columns.get('category_id') # many2many on res.partner to res.partner.category # Get the first bank account type to be able to create a res.partner.bank bank_type = bank_obj._bank_type_get(cr, uid)[0] # Get country/state data country_us_id = registry('res.country').search(cr, uid, [('code', 'like', 'US')])[0] state_ids = registry('res.country.state').search(cr, uid, [('country_id', '=', country_us_id)], limit=2) # Create demo data: partners and bank object p_a = partner_obj.create(cr, uid, {'name': 'test__A', 'state_id': state_ids[0]}) p_b = partner_obj.create(cr, uid, {'name': 'test__B', 'state_id': state_ids[1]}) p_aa = partner_obj.create(cr, uid, {'name': 'test__AA', 'parent_id': p_a, 'state_id': state_ids[0]}) p_ab = partner_obj.create(cr, uid, {'name': 'test__AB', 'parent_id': p_a, 'state_id': state_ids[1]}) p_ba = partner_obj.create(cr, uid, {'name': 'test__BA', 'parent_id': p_b, 'state_id': state_ids[0]}) b_aa = bank_obj.create(cr, uid, {'name': '__bank_test_a', 'state': bank_type[0], 'partner_id': p_aa, 'acc_number': '1234'}) b_ab = bank_obj.create(cr, uid, {'name': '__bank_test_b', 'state': bank_type[0], 'partner_id': p_ab, 'acc_number': '5678'}) b_ba = bank_obj.create(cr, uid, {'name': '__bank_test_b', 'state': bank_type[0], 'partner_id': p_ba, 'acc_number': '9876'}) # -------------------------------------------------- # Test1: basics about the attribute # -------------------------------------------------- category_id_col._auto_join = True self.assertRaises(NotImplementedError, partner_obj.search, cr, uid, [('category_id.name', '=', 'foo')]) category_id_col._auto_join = False # -------------------------------------------------- # Test2: one2many # -------------------------------------------------- name_test = 'test_a' # Do: one2many without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('bank_ids.name', 'like', name_test)]) # Test result self.assertEqual(set(partner_ids), set([p_aa]), "_auto_join off: ('bank_ids.name', 'like', '..'): incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 3, "_auto_join off: ('bank_ids.name', 'like', '..') should produce 3 queries (1 in res_partner_bank, 2 on res_partner)") sql_query = self.query_list[0].get_sql() self.assertIn('res_partner_bank', sql_query[0], "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect main table") expected = "%s::text like %s" % (unaccent('"res_partner_bank"."name"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect where condition") self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect parameter") sql_query = self.query_list[2].get_sql() self.assertIn('res_partner', sql_query[0], "_auto_join off: ('bank_ids.name', 'like', '..') third query incorrect main table") self.assertIn('"res_partner"."id" in (%s)', sql_query[1], "_auto_join off: ('bank_ids.name', 'like', '..') third query incorrect where condition") self.assertEqual(set([p_aa]), set(sql_query[2]), "_auto_join off: ('bank_ids.name', 'like', '..') third query incorrect parameter") # Do: cascaded one2many without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result self.assertEqual(set(partner_ids), set([p_a, p_b]), "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]): incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 5, "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]) should produce 5 queries (1 in res_partner_bank, 4 on res_partner)") # Do: one2many with _auto_join partner_bank_ids_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('bank_ids.name', 'like', 'test_a')]) # Test result self.assertEqual(set(partner_ids), set([p_aa]), "_auto_join on: ('bank_ids.name', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 1, "_auto_join on: ('bank_ids.name', 'like', '..') should produce 1 query") sql_query = self.query_list[0].get_sql() self.assertIn('"res_partner"', sql_query[0], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect main table") self.assertIn('"res_partner_bank" as "res_partner__bank_ids"', sql_query[0], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect join") expected = "%s::text like %s" % (unaccent('"res_partner__bank_ids"."name"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect where condition") self.assertIn('"res_partner"."id"="res_partner__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect join condition") self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect parameter") # Do: one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('bank_ids.id', 'in', [b_aa, b_ab])]) # Test result self.assertEqual(set(partner_ids), set([p_aa, p_ab]), "_auto_join on: ('bank_ids.id', 'in', [..]) incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 1, "_auto_join on: ('bank_ids.id', 'in', [..]) should produce 1 query") sql_query = self.query_list[0].get_sql() self.assertIn('"res_partner"', sql_query[0], "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect main table") self.assertIn('"res_partner__bank_ids"."id" in (%s,%s)', sql_query[1], "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect where condition") self.assertEqual(set([b_aa, b_ab]), set(sql_query[2]), "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect parameter") # Do: 2 cascaded one2many with _auto_join, test final leaf is an id partner_child_ids_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result self.assertEqual(set(partner_ids), set([p_a, p_b]), "_auto_join on: ('child_ids.bank_ids.id', 'not in', [..]): incorrect result") # # Test produced queries self.assertEqual(len(self.query_list), 1, "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) should produce 1 query") sql_query = self.query_list[0].get_sql() self.assertIn('"res_partner"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) incorrect main table") self.assertIn('"res_partner" as "res_partner__child_ids"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join") self.assertIn('"res_partner_bank" as "res_partner__child_ids__bank_ids"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join") self.assertIn('"res_partner__child_ids__bank_ids"."id" in (%s,%s)', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect where condition") self.assertIn('"res_partner"."id"="res_partner__child_ids"."parent_id"', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition") self.assertIn('"res_partner__child_ids"."id"="res_partner__child_ids__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition") self.assertEqual(set([b_aa, b_ba]), set(sql_query[2][-2:]), "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect parameter") # -------------------------------------------------- # Test3: many2one # -------------------------------------------------- name_test = 'US' # Do: many2one without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join off: ('state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 3, "_auto_join off: ('state_id.country_id.code', 'like', '..') should produce 3 queries (1 on res_country, 1 on res_country_state, 1 on res_partner)") # Do: many2one with 1 _auto_join on the first many2one partner_state_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 2, "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') should produce 2 query") sql_query = self.query_list[0].get_sql() self.assertIn('"res_country"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table") expected = "%s::text like %s" % (unaccent('"res_country"."code"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition") self.assertEqual(['%' + name_test + '%'], sql_query[2], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter") sql_query = self.query_list[1].get_sql() self.assertIn('"res_partner"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect main table") self.assertIn('"res_country_state" as "res_partner__state_id"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join") self.assertIn('"res_partner__state_id"."country_id" in (%s)', sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition") self.assertIn('"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join condition") # Do: many2one with 1 _auto_join on the second many2one partner_state_id_col._auto_join = False state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 2, "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') should produce 2 query") # -- first query sql_query = self.query_list[0].get_sql() self.assertIn('"res_country_state"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table") self.assertIn('"res_country" as "res_country_state__country_id"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join") expected = "%s::text like %s" % (unaccent('"res_country_state__country_id"."code"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition") self.assertIn('"res_country_state"."country_id"="res_country_state__country_id"."id"', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join condition") self.assertEqual(['%' + name_test + '%'], sql_query[2], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter") # -- second query sql_query = self.query_list[1].get_sql() self.assertIn('"res_partner"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect main table") self.assertIn('"res_partner"."state_id" in', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition") # Do: many2one with 2 _auto_join partner_state_id_col._auto_join = True state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on: ('state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 1, "_auto_join on: ('state_id.country_id.code', 'like', '..') should produce 1 query") sql_query = self.query_list[0].get_sql() self.assertIn('"res_partner"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect main table") self.assertIn('"res_country_state" as "res_partner__state_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join") self.assertIn('"res_country" as "res_partner__state_id__country_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join") expected = "%s::text like %s" % (unaccent('"res_partner__state_id__country_id"."code"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect where condition") self.assertIn('"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition") self.assertIn('"res_partner__state_id"."country_id"="res_partner__state_id__country_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition") self.assertEqual(['%' + name_test + '%'], sql_query[2], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect parameter") # -------------------------------------------------- # Test4: domain attribute on one2many fields # -------------------------------------------------- partner_child_ids_col._auto_join = True partner_bank_ids_col._auto_join = True partner_child_ids_col._domain = lambda self: ['!', ('name', '=', self._name)] partner_bank_ids_col._domain = [('acc_number', 'like', '1')] # Do: 2 cascaded one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search(cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result: at least one of our added data self.assertTrue(set([p_a]).issubset(set(partner_ids)), "_auto_join on one2many with domains incorrect result") self.assertTrue(set([p_ab, p_ba]) not in set(partner_ids), "_auto_join on one2many with domains incorrect result") # Test produced queries that domains effectively present sql_query = self.query_list[0].get_sql() expected = "%s::text like %s" % (unaccent('"res_partner__child_ids__bank_ids"."acc_number"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on one2many with domains incorrect result") # TDE TODO: check first domain has a correct table name self.assertIn('"res_partner__child_ids"."name" = %s', sql_query[1], "_auto_join on one2many with domains incorrect result") partner_child_ids_col._domain = lambda self: [('name', '=', '__%s' % self._name)] self._reinit_mock() partner_ids = partner_obj.search(cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result: no one self.assertFalse(partner_ids, "_auto_join on one2many with domains incorrect result") # ---------------------------------------- # Test5: result-based tests # ---------------------------------------- partner_bank_ids_col._auto_join = False partner_child_ids_col._auto_join = False partner_state_id_col._auto_join = False partner_parent_id_col._auto_join = False state_country_id_col._auto_join = False partner_child_ids_col._domain = [] partner_bank_ids_col._domain = [] # Do: ('child_ids.state_id.country_id.code', 'like', '..') without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('child_ids.state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue(set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 5, "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect") # Do: ('child_ids.state_id.country_id.code', 'like', '..') with _auto_join partner_child_ids_col._auto_join = True partner_state_id_col._auto_join = True state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('child_ids.state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue(set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result") # Test produced queries self.assertEqual(len(self.query_list), 1, "_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect") # Remove mocks and modifications partner_bank_ids_col._auto_join = False partner_child_ids_col._auto_join = False partner_state_id_col._auto_join = False partner_parent_id_col._auto_join = False state_country_id_col._auto_join = False
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql( ) where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) # TODO: simplify this in trunk with `display_name`, once it is stored # Perf note: a CTE expression (WITH ...) seems to have an even higher cost # than this query with duplicated CASE expressions. The bulk of # the cost is the ORDER BY, and it is inevitable if we want # relevant results for the next step, otherwise we'd return # a random selection of `limit` results. display_name = """CASE WHEN company.id IS NULL OR res_partner.is_company THEN {partner_name} ELSE {company_name} || ', ' || {partner_name} END""".format( partner_name=unaccent('res_partner.name'), company_name=unaccent('company.name')) query = """SELECT res_partner.id FROM res_partner LEFT JOIN res_partner company ON res_partner.parent_id = company.id {where} ({email} {operator} {percent} OR {display_name} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('res_partner.email'), percent=unaccent('%s'), display_name=display_name) where_clause_params += [search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(res_partner, self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit)
def test_20_auto_join(self): registry, cr, uid = self.registry, self.cr, self.uid unaccent = get_unaccent_wrapper(cr) # Get models partner_obj = registry('res.partner') state_obj = registry('res.country.state') bank_obj = registry('res.partner.bank') # Get test columns partner_state_id_col = partner_obj._columns.get( 'state_id') # many2one on res.partner to res.country.state partner_parent_id_col = partner_obj._columns.get( 'parent_id') # many2one on res.partner to res.partner state_country_id_col = state_obj._columns.get( 'country_id') # many2one on res.country.state on res.country partner_child_ids_col = partner_obj._columns.get( 'child_ids') # one2many on res.partner to res.partner partner_bank_ids_col = partner_obj._columns.get( 'bank_ids') # one2many on res.partner to res.partner.bank category_id_col = partner_obj._columns.get( 'category_id') # many2many on res.partner to res.partner.category # Get country/state data country_us_id = registry('res.country').search( cr, uid, [('code', 'like', 'US')])[0] state_ids = registry('res.country.state').search( cr, uid, [('country_id', '=', country_us_id)], limit=2) # Create demo data: partners and bank object p_a = partner_obj.create(cr, uid, { 'name': 'test__A', 'state_id': state_ids[0] }) p_b = partner_obj.create(cr, uid, { 'name': 'test__B', 'state_id': state_ids[1] }) p_aa = partner_obj.create(cr, uid, { 'name': 'test__AA', 'parent_id': p_a, 'state_id': state_ids[0] }) p_ab = partner_obj.create(cr, uid, { 'name': 'test__AB', 'parent_id': p_a, 'state_id': state_ids[1] }) p_ba = partner_obj.create(cr, uid, { 'name': 'test__BA', 'parent_id': p_b, 'state_id': state_ids[0] }) b_aa = bank_obj.create(cr, uid, { 'acc_number': '123', 'acc_type': 'bank', 'partner_id': p_aa }) b_ab = bank_obj.create(cr, uid, { 'acc_number': '456', 'acc_type': 'bank', 'partner_id': p_ab }) b_ba = bank_obj.create(cr, uid, { 'acc_number': '789', 'acc_type': 'bank', 'partner_id': p_ba }) # -------------------------------------------------- # Test1: basics about the attribute # -------------------------------------------------- category_id_col._auto_join = True self.assertRaises(NotImplementedError, partner_obj.search, cr, uid, [('category_id.name', '=', 'foo')]) category_id_col._auto_join = False # -------------------------------------------------- # Test2: one2many # -------------------------------------------------- name_test = '12' # Do: one2many without _auto_join self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('bank_ids.sanitized_acc_number', 'like', name_test)]) # Test result self.assertEqual( set(partner_ids), set([p_aa]), "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..'): incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 3, "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') should produce 3 queries (1 in res_partner_bank, 2 on res_partner)" ) sql_query = self.query_list[0].get_sql() self.assertIn( 'res_partner_bank', sql_query[0], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect main table" ) expected = "%s::text like %s" % (unaccent( '"res_partner_bank"."sanitized_acc_number"'), unaccent('%s')) self.assertIn( expected, sql_query[1], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect where condition" ) self.assertEqual( set(['%' + name_test + '%']), set(sql_query[2]), "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect parameter" ) sql_query = self.query_list[2].get_sql() self.assertIn( 'res_partner', sql_query[0], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect main table" ) self.assertIn( '"res_partner"."id" in (%s)', sql_query[1], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect where condition" ) self.assertEqual( set([p_aa]), set(sql_query[2]), "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect parameter" ) # Do: cascaded one2many without _auto_join self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result self.assertEqual( set(partner_ids), set([p_a, p_b]), "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]): incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 5, "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]) should produce 5 queries (1 in res_partner_bank, 4 on res_partner)" ) # Do: one2many with _auto_join partner_bank_ids_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('bank_ids.sanitized_acc_number', 'like', '12')]) # Test result self.assertEqual( set(partner_ids), set([p_aa]), "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') should produce 1 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect main table" ) self.assertIn( '"res_partner_bank" as "res_partner__bank_ids"', sql_query[0], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join" ) expected = "%s::text like %s" % (unaccent( '"res_partner__bank_ids"."sanitized_acc_number"'), unaccent('%s')) self.assertIn( expected, sql_query[1], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect where condition" ) self.assertIn( '"res_partner"."id"="res_partner__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join condition" ) self.assertEqual( set(['%' + name_test + '%']), set(sql_query[2]), "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect parameter" ) # Do: one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [('bank_ids.id', 'in', [b_aa, b_ab])]) # Test result self.assertEqual( set(partner_ids), set([p_aa, p_ab]), "_auto_join on: ('bank_ids.id', 'in', [..]) incorrect result") # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('bank_ids.id', 'in', [..]) should produce 1 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect main table" ) self.assertIn( '"res_partner__bank_ids"."id" in (%s,%s)', sql_query[1], "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect where condition" ) self.assertEqual( set([b_aa, b_ab]), set(sql_query[2]), "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect parameter" ) # Do: 2 cascaded one2many with _auto_join, test final leaf is an id partner_child_ids_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result self.assertEqual( set(partner_ids), set([p_a, p_b]), "_auto_join on: ('child_ids.bank_ids.id', 'not in', [..]): incorrect result" ) # # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) should produce 1 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) incorrect main table" ) self.assertIn( '"res_partner" as "res_partner__child_ids"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join" ) self.assertIn( '"res_partner_bank" as "res_partner__child_ids__bank_ids"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join" ) self.assertIn( '"res_partner__child_ids__bank_ids"."id" in (%s,%s)', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect where condition" ) self.assertIn( '"res_partner"."id"="res_partner__child_ids"."parent_id"', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition" ) self.assertIn( '"res_partner__child_ids"."id"="res_partner__child_ids__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition" ) self.assertEqual( set([b_aa, b_ba]), set(sql_query[2][-2:]), "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect parameter" ) # -------------------------------------------------- # Test3: many2one # -------------------------------------------------- name_test = 'US' # Do: many2one without _auto_join self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join off: ('state_id.country_id.code', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 3, "_auto_join off: ('state_id.country_id.code', 'like', '..') should produce 3 queries (1 on res_country, 1 on res_country_state, 1 on res_partner)" ) # Do: many2one with 1 _auto_join on the first many2one partner_state_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 2, "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') should produce 2 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_country"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table" ) expected = "%s::text like %s" % (unaccent('"res_country"."code"'), unaccent('%s')) self.assertIn( expected, sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition" ) self.assertEqual( ['%' + name_test + '%'], sql_query[2], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter" ) sql_query = self.query_list[1].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect main table" ) self.assertIn( '"res_country_state" as "res_partner__state_id"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join" ) self.assertIn( '"res_partner__state_id"."country_id" in (%s)', sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition" ) self.assertIn( '"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join condition" ) # Do: many2one with 1 _auto_join on the second many2one partner_state_id_col._auto_join = False state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 2, "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') should produce 2 query" ) # -- first query sql_query = self.query_list[0].get_sql() self.assertIn( '"res_country_state"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table" ) self.assertIn( '"res_country" as "res_country_state__country_id"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join" ) expected = "%s::text like %s" % ( unaccent('"res_country_state__country_id"."code"'), unaccent('%s')) self.assertIn( expected, sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition" ) self.assertIn( '"res_country_state"."country_id"="res_country_state__country_id"."id"', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join condition" ) self.assertEqual( ['%' + name_test + '%'], sql_query[2], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter" ) # -- second query sql_query = self.query_list[1].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect main table" ) self.assertIn( '"res_partner"."state_id" in', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition" ) # Do: many2one with 2 _auto_join partner_state_id_col._auto_join = True state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on: ('state_id.country_id.code', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('state_id.country_id.code', 'like', '..') should produce 1 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect main table" ) self.assertIn( '"res_country_state" as "res_partner__state_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join" ) self.assertIn( '"res_country" as "res_partner__state_id__country_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join" ) expected = "%s::text like %s" % (unaccent( '"res_partner__state_id__country_id"."code"'), unaccent('%s')) self.assertIn( expected, sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect where condition" ) self.assertIn( '"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition" ) self.assertIn( '"res_partner__state_id"."country_id"="res_partner__state_id__country_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition" ) self.assertEqual( ['%' + name_test + '%'], sql_query[2], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect parameter" ) # -------------------------------------------------- # Test4: domain attribute on one2many fields # -------------------------------------------------- partner_child_ids_col._auto_join = True partner_bank_ids_col._auto_join = True partner_child_ids_col._domain = lambda self: [ '!', ('name', '=', self._name) ] partner_bank_ids_col._domain = [('sanitized_acc_number', 'like', '2')] # Do: 2 cascaded one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search( cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result: at least one of our added data self.assertTrue( set([p_a]).issubset(set(partner_ids)), "_auto_join on one2many with domains incorrect result") self.assertTrue( set([p_ab, p_ba]) not in set(partner_ids), "_auto_join on one2many with domains incorrect result") # Test produced queries that domains effectively present sql_query = self.query_list[0].get_sql() expected = "%s::text like %s" % (unaccent( '"res_partner__child_ids__bank_ids"."sanitized_acc_number"'), unaccent('%s')) self.assertIn(expected, sql_query[1], "_auto_join on one2many with domains incorrect result") # TDE TODO: check first domain has a correct table name self.assertIn('"res_partner__child_ids"."name" = %s', sql_query[1], "_auto_join on one2many with domains incorrect result") partner_child_ids_col._domain = lambda self: [('name', '=', '__%s' % self._name)] self._reinit_mock() partner_ids = partner_obj.search( cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])]) # Test result: no one self.assertFalse( partner_ids, "_auto_join on one2many with domains incorrect result") # ---------------------------------------- # Test5: result-based tests # ---------------------------------------- partner_bank_ids_col._auto_join = False partner_child_ids_col._auto_join = False partner_state_id_col._auto_join = False partner_parent_id_col._auto_join = False state_country_id_col._auto_join = False partner_child_ids_col._domain = [] partner_bank_ids_col._domain = [] # Do: ('child_ids.state_id.country_id.code', 'like', '..') without _auto_join self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('child_ids.state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 5, "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect" ) # Do: ('child_ids.state_id.country_id.code', 'like', '..') with _auto_join partner_child_ids_col._auto_join = True partner_state_id_col._auto_join = True state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search( cr, uid, [('child_ids.state_id.country_id.code', 'like', name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect" ) # Remove mocks and modifications partner_bank_ids_col._auto_join = False partner_child_ids_col._auto_join = False partner_state_id_col._auto_join = False partner_parent_id_col._auto_join = False state_country_id_col._auto_join = False
def test_20_auto_join(self): registry, cr, uid = self.registry, self.cr, self.uid unaccent = get_unaccent_wrapper(cr) # Get models partner_obj = registry("res.partner") state_obj = registry("res.country.state") bank_obj = registry("res.partner.bank") # Get test columns partner_state_id_col = partner_obj._columns.get("state_id") # many2one on res.partner to res.country.state partner_parent_id_col = partner_obj._columns.get("parent_id") # many2one on res.partner to res.partner state_country_id_col = state_obj._columns.get("country_id") # many2one on res.country.state on res.country partner_child_ids_col = partner_obj._columns.get("child_ids") # one2many on res.partner to res.partner partner_bank_ids_col = partner_obj._columns.get("bank_ids") # one2many on res.partner to res.partner.bank category_id_col = partner_obj._columns.get("category_id") # many2many on res.partner to res.partner.category # Get country/state data country_us_id = registry("res.country").search(cr, uid, [("code", "like", "US")])[0] state_ids = registry("res.country.state").search(cr, uid, [("country_id", "=", country_us_id)], limit=2) # Create demo data: partners and bank object p_a = partner_obj.create(cr, uid, {"name": "test__A", "state_id": state_ids[0]}) p_b = partner_obj.create(cr, uid, {"name": "test__B", "state_id": state_ids[1]}) p_aa = partner_obj.create(cr, uid, {"name": "test__AA", "parent_id": p_a, "state_id": state_ids[0]}) p_ab = partner_obj.create(cr, uid, {"name": "test__AB", "parent_id": p_a, "state_id": state_ids[1]}) p_ba = partner_obj.create(cr, uid, {"name": "test__BA", "parent_id": p_b, "state_id": state_ids[0]}) b_aa = bank_obj.create(cr, uid, {"acc_number": "123", "acc_type": "bank", "partner_id": p_aa}) b_ab = bank_obj.create(cr, uid, {"acc_number": "456", "acc_type": "bank", "partner_id": p_ab}) b_ba = bank_obj.create(cr, uid, {"acc_number": "789", "acc_type": "bank", "partner_id": p_ba}) # -------------------------------------------------- # Test1: basics about the attribute # -------------------------------------------------- category_id_col._auto_join = True self.assertRaises(NotImplementedError, partner_obj.search, cr, uid, [("category_id.name", "=", "foo")]) category_id_col._auto_join = False # -------------------------------------------------- # Test2: one2many # -------------------------------------------------- name_test = "12" # Do: one2many without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("bank_ids.sanitized_acc_number", "like", name_test)]) # Test result self.assertEqual( set(partner_ids), set([p_aa]), "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..'): incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 3, "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') should produce 3 queries (1 in res_partner_bank, 2 on res_partner)", ) sql_query = self.query_list[0].get_sql() self.assertIn( "res_partner_bank", sql_query[0], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect main table", ) expected = "%s::text like %s" % (unaccent('"res_partner_bank"."sanitized_acc_number"'), unaccent("%s")) self.assertIn( expected, sql_query[1], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect where condition", ) self.assertEqual( set(["%" + name_test + "%"]), set(sql_query[2]), "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect parameter", ) sql_query = self.query_list[2].get_sql() self.assertIn( "res_partner", sql_query[0], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect main table", ) self.assertIn( '"res_partner"."id" in (%s)', sql_query[1], "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect where condition", ) self.assertEqual( set([p_aa]), set(sql_query[2]), "_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect parameter", ) # Do: cascaded one2many without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("child_ids.bank_ids.id", "in", [b_aa, b_ba])]) # Test result self.assertEqual( set(partner_ids), set([p_a, p_b]), "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]): incorrect result" ) # Test produced queries self.assertEqual( len(self.query_list), 5, "_auto_join off: ('child_ids.bank_ids.id', 'in', [..]) should produce 5 queries (1 in res_partner_bank, 4 on res_partner)", ) # Do: one2many with _auto_join partner_bank_ids_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("bank_ids.sanitized_acc_number", "like", "12")]) # Test result self.assertEqual( set(partner_ids), set([p_aa]), "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') should produce 1 query", ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect main table", ) self.assertIn( '"res_partner_bank" as "res_partner__bank_ids"', sql_query[0], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join", ) expected = "%s::text like %s" % (unaccent('"res_partner__bank_ids"."sanitized_acc_number"'), unaccent("%s")) self.assertIn( expected, sql_query[1], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect where condition", ) self.assertIn( '"res_partner"."id"="res_partner__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join condition", ) self.assertEqual( set(["%" + name_test + "%"]), set(sql_query[2]), "_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect parameter", ) # Do: one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("bank_ids.id", "in", [b_aa, b_ab])]) # Test result self.assertEqual( set(partner_ids), set([p_aa, p_ab]), "_auto_join on: ('bank_ids.id', 'in', [..]) incorrect result" ) # Test produced queries self.assertEqual(len(self.query_list), 1, "_auto_join on: ('bank_ids.id', 'in', [..]) should produce 1 query") sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect main table" ) self.assertIn( '"res_partner__bank_ids"."id" in (%s,%s)', sql_query[1], "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect where condition", ) self.assertEqual( set([b_aa, b_ab]), set(sql_query[2]), "_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect parameter" ) # Do: 2 cascaded one2many with _auto_join, test final leaf is an id partner_child_ids_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("child_ids.bank_ids.id", "in", [b_aa, b_ba])]) # Test result self.assertEqual( set(partner_ids), set([p_a, p_b]), "_auto_join on: ('child_ids.bank_ids.id', 'not in', [..]): incorrect result", ) # # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) should produce 1 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) incorrect main table" ) self.assertIn( '"res_partner" as "res_partner__child_ids"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join", ) self.assertIn( '"res_partner_bank" as "res_partner__child_ids__bank_ids"', sql_query[0], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join", ) self.assertIn( '"res_partner__child_ids__bank_ids"."id" in (%s,%s)', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect where condition", ) self.assertIn( '"res_partner"."id"="res_partner__child_ids"."parent_id"', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition", ) self.assertIn( '"res_partner__child_ids"."id"="res_partner__child_ids__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition", ) self.assertEqual( set([b_aa, b_ba]), set(sql_query[2][-2:]), "_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect parameter", ) # -------------------------------------------------- # Test3: many2one # -------------------------------------------------- name_test = "US" # Do: many2one without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("state_id.country_id.code", "like", name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join off: ('state_id.country_id.code', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 3, "_auto_join off: ('state_id.country_id.code', 'like', '..') should produce 3 queries (1 on res_country, 1 on res_country_state, 1 on res_partner)", ) # Do: many2one with 1 _auto_join on the first many2one partner_state_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("state_id.country_id.code", "like", name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 2, "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') should produce 2 query", ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_country"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table", ) expected = "%s::text like %s" % (unaccent('"res_country"."code"'), unaccent("%s")) self.assertIn( expected, sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition", ) self.assertEqual( ["%" + name_test + "%"], sql_query[2], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter", ) sql_query = self.query_list[1].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect main table", ) self.assertIn( '"res_country_state" as "res_partner__state_id"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join", ) self.assertIn( '"res_partner__state_id"."country_id" in (%s)', sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition", ) self.assertIn( '"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join condition", ) # Do: many2one with 1 _auto_join on the second many2one partner_state_id_col._auto_join = False state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("state_id.country_id.code", "like", name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 2, "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') should produce 2 query", ) # -- first query sql_query = self.query_list[0].get_sql() self.assertIn( '"res_country_state"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table", ) self.assertIn( '"res_country" as "res_country_state__country_id"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join", ) expected = "%s::text like %s" % (unaccent('"res_country_state__country_id"."code"'), unaccent("%s")) self.assertIn( expected, sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition", ) self.assertIn( '"res_country_state"."country_id"="res_country_state__country_id"."id"', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join condition", ) self.assertEqual( ["%" + name_test + "%"], sql_query[2], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter", ) # -- second query sql_query = self.query_list[1].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect main table", ) self.assertIn( '"res_partner"."state_id" in', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition", ) # Do: many2one with 2 _auto_join partner_state_id_col._auto_join = True state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("state_id.country_id.code", "like", name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)), "_auto_join on: ('state_id.country_id.code', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('state_id.country_id.code', 'like', '..') should produce 1 query" ) sql_query = self.query_list[0].get_sql() self.assertIn( '"res_partner"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect main table", ) self.assertIn( '"res_country_state" as "res_partner__state_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join", ) self.assertIn( '"res_country" as "res_partner__state_id__country_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join", ) expected = "%s::text like %s" % (unaccent('"res_partner__state_id__country_id"."code"'), unaccent("%s")) self.assertIn( expected, sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect where condition", ) self.assertIn( '"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition", ) self.assertIn( '"res_partner__state_id"."country_id"="res_partner__state_id__country_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition", ) self.assertEqual( ["%" + name_test + "%"], sql_query[2], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect parameter", ) # -------------------------------------------------- # Test4: domain attribute on one2many fields # -------------------------------------------------- partner_child_ids_col._auto_join = True partner_bank_ids_col._auto_join = True partner_child_ids_col._domain = lambda self: ["!", ("name", "=", self._name)] partner_bank_ids_col._domain = [("sanitized_acc_number", "like", "2")] # Do: 2 cascaded one2many with _auto_join, test final leaf is an id self._reinit_mock() partner_ids = partner_obj.search(cr, uid, ["&", (1, "=", 1), ("child_ids.bank_ids.id", "in", [b_aa, b_ba])]) # Test result: at least one of our added data self.assertTrue(set([p_a]).issubset(set(partner_ids)), "_auto_join on one2many with domains incorrect result") self.assertTrue( set([p_ab, p_ba]) not in set(partner_ids), "_auto_join on one2many with domains incorrect result" ) # Test produced queries that domains effectively present sql_query = self.query_list[0].get_sql() expected = "%s::text like %s" % ( unaccent('"res_partner__child_ids__bank_ids"."sanitized_acc_number"'), unaccent("%s"), ) self.assertIn(expected, sql_query[1], "_auto_join on one2many with domains incorrect result") # TDE TODO: check first domain has a correct table name self.assertIn( '"res_partner__child_ids"."name" = %s', sql_query[1], "_auto_join on one2many with domains incorrect result" ) partner_child_ids_col._domain = lambda self: [("name", "=", "__%s" % self._name)] self._reinit_mock() partner_ids = partner_obj.search(cr, uid, ["&", (1, "=", 1), ("child_ids.bank_ids.id", "in", [b_aa, b_ba])]) # Test result: no one self.assertFalse(partner_ids, "_auto_join on one2many with domains incorrect result") # ---------------------------------------- # Test5: result-based tests # ---------------------------------------- partner_bank_ids_col._auto_join = False partner_child_ids_col._auto_join = False partner_state_id_col._auto_join = False partner_parent_id_col._auto_join = False state_country_id_col._auto_join = False partner_child_ids_col._domain = [] partner_bank_ids_col._domain = [] # Do: ('child_ids.state_id.country_id.code', 'like', '..') without _auto_join self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("child_ids.state_id.country_id.code", "like", name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 5, "_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect", ) # Do: ('child_ids.state_id.country_id.code', 'like', '..') with _auto_join partner_child_ids_col._auto_join = True partner_state_id_col._auto_join = True state_country_id_col._auto_join = True self._reinit_mock() partner_ids = partner_obj.search(cr, uid, [("child_ids.state_id.country_id.code", "like", name_test)]) # Test result: at least our added data + demo data self.assertTrue( set([p_a, p_b]).issubset(set(partner_ids)), "_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result", ) # Test produced queries self.assertEqual( len(self.query_list), 1, "_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect", ) # Remove mocks and modifications partner_bank_ids_col._auto_join = False partner_child_ids_col._auto_join = False partner_state_id_col._auto_join = False partner_parent_id_col._auto_join = False state_country_id_col._auto_join = False