diff --git a/addons/account/account.py b/addons/account/account.py index 5dce6aae3e7..4ccdac59ee8 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -28,7 +28,7 @@ import time import openerp from openerp import SUPERUSER_ID from openerp import pooler, tools -from openerp.osv import fields, osv +from openerp.osv import fields, osv, expression from openerp.tools.translate import _ from openerp.tools.float_utils import float_round @@ -582,15 +582,18 @@ class account_account(osv.osv): except: pass if name: - ids = self.search(cr, user, [('code', '=like', name+"%")]+args, limit=limit) - if not ids: - ids = self.search(cr, user, [('shortcut', '=', name)]+ args, limit=limit) - if not ids: - ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit) - if not ids and len(name.split()) >= 2: - #Separating code and name of account for searching - operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A. - ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit) + if operator not in expression.NEGATIVE_TERM_OPERATORS: + ids = self.search(cr, user, ['|', ('code', '=like', name+"%"), '|', ('shortcut', '=', name), ('name', operator, name)]+args, limit=limit) + if not ids and len(name.split()) >= 2: + #Separating code and name of account for searching + operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A. + ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit) + else: + ids = self.search(cr, user, ['&','!', ('code', '=like', name+"%"), ('name', operator, name)]+args, limit=limit) + # as negation want to restric, do if already have results + if ids and len(name.split()) >= 2: + operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A. + ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2), ('id', 'in', ids)]+ args, limit=limit) else: ids = self.search(cr, user, args, context=context, limit=limit) return self.name_get(cr, user, ids, context=context) diff --git a/addons/account/tests/__init__.py b/addons/account/tests/__init__.py index 11fe4186db6..02e9677ae03 100644 --- a/addons/account/tests/__init__.py +++ b/addons/account/tests/__init__.py @@ -1,4 +1,7 @@ from . import test_tax +from . import test_search -fast_suite = [test_tax, - ] +fast_suite = [ + test_tax, + test_search, +] diff --git a/addons/account/tests/test_search.py b/addons/account/tests/test_search.py new file mode 100644 index 00000000000..0e93da0c0bc --- /dev/null +++ b/addons/account/tests/test_search.py @@ -0,0 +1,60 @@ +from openerp.tests.common import TransactionCase + +class TestSearch(TransactionCase): + """Tests for search on name_search (account.account) + + The name search on account.account is quite complexe, make sure + we have all the correct results + """ + + def setUp(self): + super(TestSearch, self).setUp() + cr, uid = self.cr, self.uid + self.account_model = self.registry('account.account') + self.account_type_model = self.registry('account.account.type') + ac_ids = self.account_type_model.search(cr, uid, [], limit=1) + self.atax = (int(self.account_model.create(cr, uid, dict( + name="Tax Received", + code="121", + user_type=ac_ids[0], + ))), "121 Tax Received") + + self.apurchase = (int(self.account_model.create(cr, uid, dict( + name="Purchased Stocks", + code="1101", + user_type=ac_ids[0], + ))), "1101 Purchased Stocks") + + self.asale = (int(self.account_model.create(cr, uid, dict( + name="Product Sales", + code="200", + user_type=ac_ids[0], + ))), "200 Product Sales") + + self.all_ids = [self.atax[0], self.apurchase[0], self.asale[0]] + + def test_name_search(self): + cr, uid = self.cr, self.uid + atax_ids = self.account_model.name_search(cr, uid, name="Tax", operator='ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.atax[0]]), set([a[0] for a in atax_ids]), "name_search 'ilike Tax' should have returned Tax Received account only") + + atax_ids = self.account_model.name_search(cr, uid, name="Tax", operator='not ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.apurchase[0], self.asale[0]]), set([a[0] for a in atax_ids]), "name_search 'not ilike Tax' should have returned all but Tax Received account") + + apur_ids = self.account_model.name_search(cr, uid, name='1101', operator='ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.apurchase[0]]), set([a[0] for a in apur_ids]), "name_search 'ilike 1101' should have returned Purchased Stocks account only") + + apur_ids = self.account_model.name_search(cr, uid, name='1101', operator='not ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.atax[0], self.asale[0]]), set([a[0] for a in apur_ids]), "name_search 'not ilike 1101' should have returned all but Purchased Stocks account") + + asale_ids = self.account_model.name_search(cr, uid, name='200 Sales', operator='ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.asale[0]]), set([a[0] for a in asale_ids]), "name_search 'ilike 200 Sales' should have returned Product Sales account only") + + asale_ids = self.account_model.name_search(cr, uid, name='200 Sales', operator='not ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.atax[0], self.apurchase[0]]), set([a[0] for a in asale_ids]), "name_search 'not ilike 200 Sales' should have returned all but Product Sales account") + + asale_ids = self.account_model.name_search(cr, uid, name='Product Sales', operator='ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.asale[0]]), set([a[0] for a in asale_ids]), "name_search 'ilike Product Sales' should have returned Product Sales account only") + + asale_ids = self.account_model.name_search(cr, uid, name='Product Sales', operator='not ilike', args=[('id', 'in', self.all_ids)]) + self.assertEqual(set([self.atax[0], self.apurchase[0]]), set([a[0] for a in asale_ids]), "name_search 'not ilike Product Sales' should have returned all but Product Sales account")