def search_active(self, active=True): if active and not self.parent: if not self.fields_view_tree: try: self.fields_view_tree = RPCExecute('model', self.model_name, 'fields_view_get', False, 'tree', context=self.context) except RPCException: return if not self.domain_parser: fields = copy.deepcopy(self.fields_view_tree['fields']) for name, props in fields.iteritems(): if props['type'] not in ('selection', 'reference'): continue if isinstance(props['selection'], (tuple, list)): continue props['selection'] = self.get_selection(props) # Filter only fields in XML view xml_dom = xml.dom.minidom.parseString( self.fields_view_tree['arch']) root_node, = xml_dom.childNodes xml_fields = [ node_attributes(node).get('name') for node in root_node.childNodes if node.nodeName == 'field' ] if hasattr(collections, 'OrderedDict'): odict = collections.OrderedDict else: odict = dict fields = odict((name, fields[name]) for name in xml_fields) for name, string, type_ in ( ('id', _('ID'), 'integer'), ('create_uid', _('Creation User'), 'many2one'), ('create_date', _('Creation Date'), 'datetime'), ('write_uid', _('Modification User'), 'many2one'), ('write_date', _('Modification Date'), 'datetime'), ): if name not in fields: fields[name] = { 'string': string.decode('utf-8'), 'name': name, 'type': type_, } if type_ == 'datetime': fields[name]['format'] = '"%H:%M:%S"' self.domain_parser = DomainParser(fields) self.screen_container.set_screen(self) self.screen_container.show_filter() else: self.screen_container.hide_filter()
def domain_parser(self): view_id = self.current_view.view_id if self.current_view else None if view_id in self._domain_parser: return self._domain_parser[view_id] if view_id not in self.fields_view_tree: try: self.fields_view_tree[view_id] = view_tree = RPCExecute( 'model', self.model_name, 'fields_view_get', False, 'tree', context=self.context) except RPCException: view_tree = { 'fields': {}, } else: view_tree = self.fields_view_tree[view_id] fields = copy.deepcopy(view_tree['fields']) for name, props in fields.iteritems(): if props['type'] not in ('selection', 'reference'): continue if isinstance(props['selection'], (tuple, list)): continue props['selection'] = self.get_selection(props) if 'arch' in view_tree: # Filter only fields in XML view xml_dom = xml.dom.minidom.parseString(view_tree['arch']) root_node, = xml_dom.childNodes xml_fields = [node_attributes(node).get('name') for node in root_node.childNodes if node.nodeName == 'field'] fields = collections.OrderedDict( (name, fields[name]) for name in xml_fields) # Add common fields for name, string, type_ in ( ('id', _('ID'), 'integer'), ('create_uid', _('Creation User'), 'many2one'), ('create_date', _('Creation Date'), 'datetime'), ('write_uid', _('Modification User'), 'many2one'), ('write_date', _('Modification Date'), 'datetime'), ): if name not in fields: fields[name] = { 'string': string.decode('utf-8'), 'name': name, 'type': type_, } if type_ == 'datetime': fields[name]['format'] = '"%H:%M:%S"' context = rpc.CONTEXT.copy() context.update(self.context) domain_parser = DomainParser(fields, context) self._domain_parser[view_id] = domain_parser return domain_parser
def test_stringable(self): "Test stringable" dom = DomainParser({ 'name': { 'string': 'Name', 'type': 'char', }, 'multiselection': { 'string': "MultiSelection", 'type': 'multiselection', 'selection': [ ('foo', "Foo"), ('bar', "Bar"), ('baz', "Baz"), ], }, 'relation': { 'string': 'Relation', 'type': 'many2one', 'relation_fields': { 'name': { 'string': "Name", 'type': 'char', }, }, }, 'relations': { 'string': 'Relations', 'type': 'many2many', }, }) valid = ('name', '=', 'Doe') invalid = ('surname', '=', 'John') self.assertTrue(dom.stringable([valid])) self.assertFalse(dom.stringable([invalid])) self.assertTrue(dom.stringable(['AND', valid])) self.assertFalse(dom.stringable(['AND', valid, invalid])) self.assertTrue(dom.stringable([[valid]])) self.assertFalse(dom.stringable([[valid], [invalid]])) self.assertTrue(dom.stringable([('multiselection', '=', None)])) self.assertTrue(dom.stringable([('multiselection', '=', '')])) self.assertFalse(dom.stringable([('multiselection', '=', 'foo')])) self.assertTrue(dom.stringable([('multiselection', '=', ['foo'])])) self.assertTrue(dom.stringable([('relation', '=', None)])) self.assertTrue(dom.stringable([('relation', '=', "Foo")])) self.assertTrue(dom.stringable([('relation.rec_name', '=', "Foo")])) self.assertFalse(dom.stringable([('relation', '=', 1)])) self.assertTrue(dom.stringable([('relations', '=', "Foo")])) self.assertTrue(dom.stringable([('relations', 'in', ["Foo"])])) self.assertFalse(dom.stringable([('relations', 'in', [42])])) self.assertTrue(dom.stringable([('relation.name', '=', "Foo")]))
def test_completion_char(self): "Test completion char" dom = DomainParser({ 'name': { 'string': 'Name', 'name': 'name', 'type': 'char', }, }) self.assertEqual(list(dom.completion('Nam')), ['Name: ']) self.assertEqual(list(dom.completion('Name:')), ['Name: ']) self.assertEqual(list(dom.completion('Name: foo')), []) self.assertEqual(list(dom.completion('Name: !=')), []) self.assertEqual(list(dom.completion('Name: !=foo')), []) self.assertEqual(list(dom.completion('')), ['Name: ']) self.assertEqual(list(dom.completion(' ')), ['', 'Name: '])
def test_completion_boolean(self): "Test completion boolean" dom = DomainParser({ 'name': { 'string': "Active", 'name': 'active', 'type': 'boolean', }, }) self.assertEqual(list(dom.completion("Act")), ["Active: "]) self.assertEqual(list(dom.completion("Active:")), ["Active: ", "Active: True", "Active: False"]) self.assertEqual(list(dom.completion("Active: t")), ["Active: True", "Active: False"]) self.assertEqual(list(dom.completion("Active: f")), ["Active: False", "Active: True"])
def test_completion_many2one(self): "Test completion many2one" dom = DomainParser({ 'relation': { 'name': 'relation', 'string': "Relation", 'type': 'many2one', 'relation_fields': { 'name': { 'name': 'name', 'string': "Name", 'type': 'char', }, }, }, }) self.assertEqual(list(dom.completion('Relatio')), ['Relation: ', 'Relation.Name: '])
def invalid_message(self, record=None): if record is None: record = self.current_record domain_string = _('"%s" is not valid according to its domain') domain_parser = DomainParser( {n: f.attrs for n, f in record.group.fields.iteritems()}) fields = [] for field, invalid in sorted(record.invalid_fields.items()): string = record.group.fields[field].attrs['string'] if invalid == 'required' or invalid == [[field, '!=', None]]: fields.append(_('"%s" is required') % string) elif invalid == 'domain': fields.append(domain_string % string) elif invalid == 'children': fields.append(_('The values of "%s" are not valid') % string) else: if domain_parser.stringable(invalid): fields.append(domain_parser.string(invalid)) else: fields.append(domain_string % string) if len(fields) > 5: fields = fields[:5] + ['...'] return '\n'.join(fields)
def domain_parser(self): view_id = self.current_view.view_id if self.current_view else None if view_id in self._domain_parser: return self._domain_parser[view_id] if view_id not in self.fields_view_tree: try: self.fields_view_tree[view_id] = view_tree = RPCExecute( 'model', self.model_name, 'fields_view_get', False, 'tree', context=self.context) except RPCException: view_tree = { 'fields': {}, } else: view_tree = self.fields_view_tree[view_id] fields = copy.deepcopy(view_tree['fields']) for name, props in fields.items(): if props['type'] not in ('selection', 'reference'): continue if isinstance(props['selection'], (tuple, list)): continue props['selection'] = self.get_selection(props) if 'arch' in view_tree: # Filter only fields in XML view xml_dom = xml.dom.minidom.parseString(view_tree['arch']) root_node, = xml_dom.childNodes ofields = collections.OrderedDict() for node in root_node.childNodes: if node.nodeName != 'field': continue attributes = node_attributes(node) name = attributes['name'] # If a field is defined multiple times in the XML, # take only the first definition if name in ofields: continue ofields[name] = fields[name] for attr in ['string', 'factor']: if attributes.get(attr): ofields[name][attr] = attributes[attr] fields = ofields if 'active' in view_tree['fields']: self.screen_container.but_active.show() else: self.screen_container.but_active.hide() # Add common fields for name, string, type_ in ( ('id', _('ID'), 'integer'), ('create_uid', _('Create by'), 'many2one'), ('create_date', _('Created at'), 'datetime'), ('write_uid', _('Edited by'), 'many2one'), ('write_date', _('Edited at'), 'datetime'), ): if name not in fields: fields[name] = { 'string': string, 'name': name, 'type': type_, } if type_ == 'datetime': fields[name]['format'] = '"%H:%M:%S"' domain_parser = DomainParser(fields, self.context) self._domain_parser[view_id] = domain_parser return domain_parser
def test_parse_clause(self): "Test parse clause" dom = DomainParser({ 'name': { 'string': 'Name', 'name': 'name', 'type': 'char', }, 'integer': { 'string': 'Integer', 'name': 'integer', 'type': 'integer', }, 'selection': { 'string': 'Selection', 'name': 'selection', 'type': 'selection', 'selection': [ ('male', 'Male'), ('female', 'Female'), ], }, 'multiselection': { 'string': "MultiSelection", 'name': 'multiselection', 'type': 'multiselection', 'selection': [ ('foo', "Foo"), ('bar', "Bar"), ('baz', "Baz"), ], }, 'reference': { 'string': 'Reference', 'name': 'reference', 'type': 'reference', 'selection': [ ('spam', 'Spam'), ('ham', 'Ham'), ] }, 'many2one': { 'string': 'Many2One', 'name': 'many2one', 'type': 'many2one', }, 'relation': { 'string': "Relation", 'relation': 'relation', 'name': 'relation', 'relation_fields': { 'name': { 'string': "Name", 'name': 'name', 'type': 'char', }, }, }, }) self.assertEqual( rlist(dom.parse_clause([('John',)])), [ ('rec_name', 'ilike', '%John%'), ]) self.assertEqual( rlist(dom.parse_clause([('Name', None, None)])), [ ('name', 'ilike', '%'), ]) self.assertEqual( rlist(dom.parse_clause([('Name', '', None)])), [ ('name', 'ilike', '%'), ]) self.assertEqual( rlist(dom.parse_clause([('Name', '=', None)])), [ ('name', '=', None), ]) self.assertEqual( rlist(dom.parse_clause([('Name', '=', '')])), [ ('name', '=', ''), ]) self.assertEqual( rlist(dom.parse_clause([('Name', None, 'Doe')])), [ ('name', 'ilike', '%Doe%'), ]) self.assertEqual( rlist(dom.parse_clause([('Name', '!', 'Doe')])), [ ('name', 'not ilike', '%Doe%'), ]) self.assertEqual( rlist(dom.parse_clause([('Name', None, ['John', 'Jane'])])), [ ('name', 'in', ['John', 'Jane']), ]) self.assertEqual( rlist(dom.parse_clause([('Name', '!', ['John', 'Jane'])])), [ ('name', 'not in', ['John', 'Jane']), ]) self.assertEqual( rlist(dom.parse_clause([('Selection', None, None)])), [ ('selection', '=', None), ]) self.assertEqual( rlist(dom.parse_clause([('Selection', None, '')])), [ ('selection', '=', ''), ]) self.assertEqual( rlist(dom.parse_clause([('Selection', None, ['Male', 'Female'])])), [('selection', 'in', ['male', 'female'])]) self.assertEqual( rlist(dom.parse_clause([('MultiSelection', None, None)])), [ ('multiselection', '=', None), ]) self.assertEqual( rlist(dom.parse_clause([('MultiSelection', None, '')])), [ ('multiselection', 'in', ['']), ]) self.assertEqual( rlist(dom.parse_clause([('MultiSelection', '=', '')])), [ ('multiselection', '=', ['']), ]) self.assertEqual( rlist(dom.parse_clause([('MultiSelection', '!', '')])), [ ('multiselection', 'not in', ['']), ]) self.assertEqual( rlist(dom.parse_clause([('MultiSelection', '!=', '')])), [ ('multiselection', '!=', ['']), ]) self.assertEqual( rlist(dom.parse_clause( [('MultiSelection', None, ['Foo', 'Bar'])])), [ ('multiselection', 'in', ['foo', 'bar']), ]) self.assertEqual( rlist(dom.parse_clause( [('MultiSelection', '=', ['Foo', 'Bar'])])), [ ('multiselection', '=', ['foo', 'bar']), ]) self.assertEqual( rlist(dom.parse_clause( [('MultiSelection', '!', ['Foo', 'Bar'])])), [ ('multiselection', 'not in', ['foo', 'bar']), ]) self.assertEqual( rlist(dom.parse_clause( [('MultiSelection', '!=', ['Foo', 'Bar'])])), [ ('multiselection', '!=', ['foo', 'bar']), ]) self.assertEqual( rlist(dom.parse_clause([('Integer', None, None)])), [ ('integer', '=', None), ]) self.assertEqual( rlist(dom.parse_clause([('Integer', None, '3..5')])), [[ ('integer', '>=', 3), ('integer', '<=', 5), ]]) self.assertEqual( rlist(dom.parse_clause([('Reference', None, 'foo')])), [ ('reference', 'ilike', '%foo%'), ]) self.assertEqual( rlist(dom.parse_clause([('Reference', None, 'Spam')])), [ ('reference', 'ilike', '%spam%'), ]) self.assertEqual( rlist(dom.parse_clause([('Reference', None, 'Spam,bar')])), [ ('reference.rec_name', 'ilike', '%bar%', 'spam'), ]) self.assertEqual( rlist(dom.parse_clause([('Reference', None, ['foo', 'bar'])])), [ ('reference', 'in', ['foo', 'bar']), ]) self.assertEqual( rlist(dom.parse_clause(['OR', ('Name', None, 'John'), ('Name', None, 'Jane')])), ['OR', ('name', 'ilike', '%John%'), ('name', 'ilike', '%Jane%'), ]) self.assertEqual( rlist(dom.parse_clause([('Many2One', None, 'John')])), [ ('many2one', 'ilike', '%John%'), ]) self.assertEqual( rlist(dom.parse_clause([('Many2One', None, ['John', 'Jane'])])), [ ('many2one.rec_name', 'in', ['John', 'Jane']), ]) self.assertEqual( rlist(dom.parse_clause(iter([iter([['John']])]))), [ [('rec_name', 'ilike', '%John%')]]) self.assertEqual( rlist(dom.parse_clause(iter([['Relation.Name', None, "Test"]]))), [('relation.name', 'ilike', "%Test%")]) self.assertEqual( rlist(dom.parse_clause(iter([['OR']]))), [('rec_name', 'ilike', "%OR%")]) self.assertEqual( rlist(dom.parse_clause(iter([['AND']]))), [('rec_name', 'ilike', "%AND%")])
def test_group(self): "Test group" dom = DomainParser({ 'name': { 'string': 'Name', }, 'firstname': { 'string': 'First Name', }, 'surname': { 'string': '(Sur)Name', }, 'relation': { 'string': "Relation", 'relation': 'relation', 'relation_fields': { 'name': { 'string': "Name", }, }, }, }) self.assertEqual( rlist(dom.group(udlex('Name: Doe'))), [('Name', None, 'Doe')]) self.assertEqual( rlist(dom.group(udlex('"(Sur)Name": Doe'))), [ ('(Sur)Name', None, 'Doe'), ]) self.assertEqual( rlist(dom.group(udlex('Name: Doe Name: John'))), [ ('Name', None, 'Doe'), ('Name', None, 'John'), ]) self.assertEqual( rlist(dom.group(udlex('Name: Name: John'))), [ ('Name', None, None), ('Name', None, 'John')]) self.assertEqual( rlist(dom.group(udlex('First Name: John'))), [ ('First Name', None, 'John'), ]) self.assertEqual( rlist(dom.group(udlex('Name: Doe First Name: John'))), [ ('Name', None, 'Doe'), ('First Name', None, 'John'), ]) self.assertEqual( rlist(dom.group(udlex('First Name: John Name: Doe'))), [ ('First Name', None, 'John'), ('Name', None, 'Doe'), ]) self.assertEqual( rlist(dom.group(udlex('First Name: John First Name: Jane'))), [ ('First Name', None, 'John'), ('First Name', None, 'Jane'), ]) self.assertEqual( rlist(dom.group(udlex('Name: John Doe'))), [ ('Name', None, 'John'), ('Doe',), ]) self.assertEqual( rlist(dom.group(udlex('Name: "John Doe"'))), [ ('Name', None, 'John Doe'), ]) self.assertEqual( rlist(dom.group(udlex('Doe Name: John'))), [ ('Doe',), ('Name', None, 'John'), ]) self.assertEqual( rlist(dom.group(udlex('Name: =Doe'))), [('Name', '=', 'Doe')]) self.assertEqual( rlist(dom.group(udlex('Name: =Doe Name: >John'))), [ ('Name', '=', 'Doe'), ('Name', '>', 'John'), ]) self.assertEqual( rlist(dom.group(udlex('First Name: =John First Name: =Jane'))), [ ('First Name', '=', 'John'), ('First Name', '=', 'Jane'), ]) self.assertEqual( rlist(dom.group(udlex('Name: John;Jane'))), [ ('Name', None, ['John', 'Jane']) ]) self.assertEqual( rlist(dom.group(udlex('Name: John;'))), [ ('Name', None, ['John']) ]) self.assertEqual( rlist(dom.group(udlex('Name: John;Jane Name: Doe'))), [ ('Name', None, ['John', 'Jane']), ('Name', None, 'Doe'), ]) self.assertEqual( rlist(dom.group(udlex('Name: John; Name: Doe'))), [ ('Name', None, ['John']), ('Name', None, 'Doe'), ]) self.assertEqual( rlist(dom.group(udlex('Name:'))), [ ('Name', None, None), ]) self.assertEqual( rlist(dom.group(udlex('Name: ='))), [ ('Name', '=', None), ]) self.assertEqual( rlist(dom.group(udlex('Name: =""'))), [ ('Name', '=', ''), ]) self.assertEqual( rlist(dom.group(udlex('Name: = ""'))), [ ('Name', '=', ''), ]) self.assertEqual( rlist(dom.group(udlex('Name: = Name: Doe'))), [ ('Name', '=', None), ('Name', None, 'Doe'), ]) self.assertEqual( rlist(dom.group(udlex('Name: \\"foo\\"'))), [ ('Name', None, '"foo"'), ]) self.assertEqual( rlist(dom.group(udlex('Name: "" <'))), [ ('Name', '', '<'), ]) self.assertEqual( rlist(dom.group(udlex('Relation.Name: Test'))), [ ('Relation.Name', None, "Test"), ])
def test_string(self): dom = DomainParser({ 'name': { 'string': 'Name', 'type': 'char', }, 'surname': { 'string': '(Sur)Name', 'type': 'char', }, 'date': { 'string': 'Date', 'type': 'date', }, 'selection': { 'string': 'Selection', 'type': 'selection', 'selection': [ ('male', 'Male'), ('female', 'Female'), ('', ''), ], }, 'multiselection': { 'string': "MultiSelection", 'type': 'multiselection', 'selection': [ ('foo', "Foo"), ('bar', "Bar"), ('baz', "Baz"), ], }, 'reference': { 'string': 'Reference', 'type': 'reference', 'selection': [ ('spam', 'Spam'), ('ham', 'Ham'), ] }, 'many2one': { 'string': 'Many2One', 'name': 'many2one', 'type': 'many2one', 'relation_fields': { 'name': { 'string': "Name", 'type': 'char', }, }, }, }) self.assertEqual(dom.string([('name', '=', 'Doe')]), 'Name: =Doe') self.assertEqual(dom.string([('name', '=', None)]), 'Name: =') self.assertEqual(dom.string([('name', '=', '')]), 'Name: =""') self.assertEqual(dom.string([('name', 'ilike', '%')]), 'Name: ') self.assertEqual(dom.string([('name', 'ilike', '%Doe%')]), 'Name: Doe') self.assertEqual( dom.string([('name', 'ilike', '%<%')]), 'Name: "" "<"') self.assertEqual(dom.string([('name', 'ilike', 'Doe')]), 'Name: =Doe') self.assertEqual(dom.string([('name', 'ilike', 'Doe%')]), 'Name: Doe%') self.assertEqual( dom.string([('name', 'ilike', 'Doe%%')]), 'Name: =Doe%') self.assertEqual( dom.string([('name', 'not ilike', '%Doe%')]), 'Name: !Doe') self.assertEqual( dom.string([('name', 'in', ['John', 'Jane'])]), 'Name: John;Jane') self.assertEqual( dom.string([('name', 'not in', ['John', 'Jane'])]), 'Name: !John;Jane') self.assertEqual( dom.string([ ('name', 'ilike', '%Doe%'), ('name', 'ilike', '%Jane%')]), 'Name: Doe Name: Jane') self.assertEqual( dom.string(['AND', ('name', 'ilike', '%Doe%'), ('name', 'ilike', '%Jane%')]), 'Name: Doe Name: Jane') self.assertEqual( dom.string(['OR', ('name', 'ilike', '%Doe%'), ('name', 'ilike', '%Jane%')]), 'Name: Doe or Name: Jane') self.assertEqual( dom.string([ ('name', 'ilike', '%Doe%'), ['OR', ('name', 'ilike', '%John%'), ('name', 'ilike', '%Jane%')]]), 'Name: Doe (Name: John or Name: Jane)') self.assertEqual(dom.string([]), '') self.assertEqual( dom.string([('surname', 'ilike', '%Doe%')]), '"(Sur)Name": Doe') self.assertEqual( dom.string([('date', '>=', dt.date(2012, 10, 24))]), dt.date(2012, 10, 24).strftime('Date: >=%x')) self.assertEqual(dom.string([('selection', '=', '')]), 'Selection: ') self.assertEqual(dom.string([('selection', '=', None)]), 'Selection: ') self.assertEqual( dom.string([('selection', '!=', '')]), 'Selection: !""') self.assertEqual( dom.string([('selection', '=', 'male')]), 'Selection: Male') self.assertEqual( dom.string([('selection', '!=', 'male')]), 'Selection: !Male') self.assertEqual( dom.string([('multiselection', '=', None)]), "MultiSelection: =") self.assertEqual( dom.string([('multiselection', '=', '')]), "MultiSelection: =") self.assertEqual( dom.string([('multiselection', '!=', '')]), "MultiSelection: !=") self.assertEqual( dom.string([('multiselection', '=', ['foo'])]), "MultiSelection: =Foo") self.assertEqual( dom.string([('multiselection', '!=', ['foo'])]), "MultiSelection: !=Foo") self.assertEqual( dom.string([('multiselection', '=', ['foo', 'bar'])]), "MultiSelection: =Foo;Bar") self.assertEqual( dom.string([('multiselection', '!=', ['foo', 'bar'])]), "MultiSelection: !=Foo;Bar") self.assertEqual( dom.string([('multiselection', 'in', ['foo'])]), "MultiSelection: Foo") self.assertEqual( dom.string([('multiselection', 'not in', ['foo'])]), "MultiSelection: !Foo") self.assertEqual( dom.string([('multiselection', '=', ['foo', 'bar'])]), "MultiSelection: =Foo;Bar") self.assertEqual( dom.string([('multiselection', '!=', ['foo', 'bar'])]), "MultiSelection: !=Foo;Bar") self.assertEqual( dom.string([('multiselection', 'in', ['foo', 'bar'])]), "MultiSelection: Foo;Bar") self.assertEqual( dom.string([('multiselection', 'not in', ['foo', 'bar'])]), "MultiSelection: !Foo;Bar") self.assertEqual( dom.string([('reference', 'ilike', '%foo%')]), 'Reference: foo') self.assertEqual( dom.string([('reference.rec_name', 'ilike', '%bar%', 'spam')]), 'Reference: Spam,bar') self.assertEqual( dom.string([('reference', 'in', ['foo', 'bar'])]), 'Reference: foo;bar') self.assertEqual( dom.string([('many2one', 'ilike', '%John%')]), 'Many2One: John') self.assertEqual( dom.string([('many2one.rec_name', 'in', ['John', 'Jane'])]), 'Many2One: John;Jane') self.assertEqual( dom.string([('many2one.name', 'ilike', '%Foo%')]), "Many2One.Name: Foo")