Search code examples
odooopenerp-7

Domain in read_group method


There is standard method

 def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False)

I'm calling a super on it and passing a domain like this

[('end_date', '>=', '2019-05-01'), ('end_date', '<=', '2019-05-30'), ('employee', 'in', [49]), ('state', 'in', ['done'])]

and it works.

but when I try to append

domain.append(('&'))
domain.append(('state', 'in', ['progress']))

I get

File "/home/www/workspace/openerp-7.0-20140804-231303/openerp/osv/expression.py", line 201, in normalize_domain
    assert expected == 0, 'This domain is syntactically not correct: %s' % (domain)
AssertionError: This domain is syntactically not correct: [('end_date', '>=', '2019-05-01'), ('end_date', '<=', '2019-05-30'), ('employee', 'in', [49]), ('state', 'in', ['done']), '&', ('state', 'in', ['progress'])]

basically, need to filter all records by dates and in state 'done' and on top of that all records in state 'progress'.

UPDATE.

if I user domain

domain = [('end_date', '>=', '2019-05-01'), ('end_date', '<=', '2019-05-30'), ('employee', 'in', [49]),
         ('state', 'in', ['done'])]

i get 3 records,

and if I use

domain = [('employee', 'in', [49]), ('state', 'in', ['progress'])]

I get result with 2 records,

but if I combine these domains like this I get 0 records

domain = [('state', 'in', ['progress']),('end_date', '>=', '2019-05-01'), ('end_date', '<=', '2019-05-30'), ('employee', 'in', [49]),
         ('state', 'in', ['done'])]

how my domain should look that i would get 5 records?

probably problem is that records that in 'progress' doesnt have end_date


Solution

  • The logical operators '&' and '|' have arity 2, that means 2 triples ("normal" domain tuples with 3 entries) must follow them. You append only one triple. In your case you can just remove the append of '&' because without using any logical operator, everything/every triple will be combined with AND per default.

    The logical operator '!' has arity 1, btw.

    You can find enough information about it in the official documentation.

    A domain is a list of criteria, each criterion being a triple (either a list or a tuple) of (field_name, operator, value) where:

    field_name (str) a field name of the current model, or a relationship traversal through a Many2one using dot-notation e.g. 'street' or 'partner_id.country' operator (str) an operator used to compare the field_name with the value. Valid operators are:

    = equals to != not equals to

    > greater than

    >= greater than or equal to

    < less than

    <= less than or equal to

    =? unset or equals to (returns true if value is either None or False, otherwise behaves like =)

    =like matches field_name against the value pattern. An underscore _ in the pattern stands for (matches) any single character; a percent sign % matches any string of zero or more characters.

    like matches field_name against the %value% pattern. Similar to =like but wraps value with ‘%’ before matching

    not like doesn’t match against the %value% pattern

    ilike case insensitive like

    not ilike case insensitive not like

    =ilike case insensitive =like

    in is equal to any of the items from value, value should be a list of items

    not in is unequal to all of the items from value

    child_of is a child (descendant) of a value record. Takes the semantics of the model into account (i.e following the relationship field named by _parent_name).

    Domain criteria can be combined using logical operators in prefix form:

    '&' logical AND, default operation to combine criteria following one another. Arity 2 (uses the next 2 criteria or combinations).

    '|' logical OR, arity 2.

    '!' logical NOT, arity 1.

    Edit: Even if it should be another question, i'll try to solve your special domain problem:

    [('employee_id', 'in', [49]),
    '|',
        ('state', 'in', ['progress']),
        '&', ('state', 'in', ['done']),
            '&', ('end_date', '>=', '2019-05-01'), ('end_date', '<=', '2019-05-30')]
    

    That should outcome as (pseudo):

    EMPLOYEE with ID 49 AND
    (STATE is progress OR (STATE is done AND END_DATE is between ...))