Translate

Wednesday, April 1, 2015


Odoo(OpenERP) Domains and Polish Notations (Part 3)

It’s good to know that OpenERP uses Polish Notation for Domain filters. And in the previous parts we explained what is notations and how to be used and the conversion process between each other and for more information about the polish notation just click these links:

Domains

A domain is a list of criterion, 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)
-   A comparison operator between the criterion’s field and value.
            - Valid operators are =, !=, >, >=, <, <=, like, ilike, in, not in,
 child_of, parent_left, parent_right (for details go to this file: openerp/osv/expression.py)

value
- Variable type, must be comparable (through operator) to the named field
-  Valid value to compare with the values of field_name, depending on its type
Domain criteria can be combined using logical operators in prefix form:
               '&': logical AND, default operation to combine criteria following one another.
               '|': logical OR
               '!': logical NOT

Tip: Mostly to negate combinations of criteria, Individual criterion generally have a negative form (e.g. = -> !=, < -> >=) which is simpler than negating the positive.

Example
To search for partners named ABC, from belgium or germany, whose language is not english:
[('name','=','ABC'),
 ('language.code','!=','en_US'),
 '|',('country_id.code','=','be'),
     ('country_id.code','=','de')]
This domain is interpreted as:
    (name is 'ABC')
AND (language is NOT english)
AND (country is Belgium OR Germany)

How to write different domain filters:

1-     Simple condition in programming:    

a-      if field1 = 10
will be written in odoo like that:
domain = [(‘field1′,’=’,10)]  # where field1 should be a field in the model and 10 will be the value.
OR domain = [(‘field1′,’=’,field2)]  # where field1 and field2 should be the fields in the model.

b-      Condition AND
if field1 = 5 and field2 = 10
In OpenERP domain filter, it will be written as:
domain = [(‘field1′,’=’,5),(‘field2′,’=’,10)]
OR domain = [(‘field1′,’=’,field3),(‘field1′,’=’,field3)]
Note that if you don’t specify any condition at the beginning and condition will be applied.

c-      Condition OR
if field1 = 5 or field2 = 10
In OpenERP domain filter, it will be written as:
ie, domain = [‘|’, (‘field1′,’=’,5),(‘field2′,’=’,10)]
or domain = [‘|’, (‘field1′,’=’,field3),(‘field1′,’=’,field3)]


2-      Complex Condition

2.1- Simple condition:  
if field1 = 5 or (field2 ! = 10 and field3 = 12)
In OpenERP domain filter, it will be written as:
domain = [‘|’,(‘field1′,’=’,5),(‘&’,(‘field2′,’!=’,10),(‘field3′,’=’,’12’))]

2.2- Complex Condition:
As we known OpenERP uses Polish Notation for Domain filters.
If we have a condition like that: ( A OR B) AND ( C OR D OR E)
should converted to the polish notation as AND OR A B OR OR C D E As follow: 

We should start from the most right character i.e the ‘)’ character.
Input
Prefix_Stack
Stack



)
Empty
)
E
E
)
OR
E
) OR
D
ED
) OR
OR
ED
) OR OR
C
EDC
) OR OR
(
EDC OR OR
Empty
AND
EDC OR OR
AND
)
EDC OR OR
AND )
B
EDC OR OR B
AND )
OR
EDC OR OR B
AND ) OR
A
EDC OR OR B A
AND ) OR
(
EDC OR OR B A OR
AND
Empty
EDC OR OR B A OR AND
Empty

Now by reversing the final result in the prefix_stack we will get
AND OR A B OR OR CDE    ## As we expected

You can also use ‘in’ operator instead of writing three separate tuples with OR operator like
['&',('field2', 'in', ['A', 'B']),('state', 'in', ['open', 'closed', 'draft'])]
And for checking the various use of the domain filters in the actions list from
Settings > Actions > Window Actions (technical features should be on)

The simplest way:
(1)   Start with the outermost operator and move it to the start of the expression.
“(A operator B)” becomes “operator (A B)”
(2)   Repeat step 1 for each sub expression with an operator to move.
“A (B operator C)” becomes “operator A (B operator C)” then “operator A (operator B C)”
(3)   Remove all brackets
“A operator (B operator C)” becomes “operator A operator B C”
      SO for our example: (A OR B) AND (C OR D OR E) we will convert it like that:
-          According to step (1) the expression will be:
AND (A OR B) (C OR D OR E)
-          According to step (2) the expression will be:
Left Side: AND (OR A B) (C OR D OR E)
Right Outer Side: AND (OR A B) (OR C (D OR E))
Right Inner Side: AND (OR A B) (OR C (OR D E))
-          According to step (3) the expression will be (remove brackets):
AND or A B or C or D E
-          According to opener domain syntax this result would be written as:
[ ‘&’,’|’, (A),(B),’|’, (C), ‘|’, (D), (E) ]
Note: OpenERP uses the polish(prefix) notation, And we can also use the reverse(postfix) polish notation for writing domain filters.
For more information: Click here
And just as an example:
The infix expression "(3 + 5) * (7 - 2)" can be written down like this in RPN: 3 5 + 7 2 - *

Note: The reversed notation is exactly the same, but enables you to resolve without going back and forth.

No comments:

Post a Comment