Filtres de recherche d'OpenERP 7 : le comportement logique

Pour comprendre comment appliquer des ET et des OU lors d'une recherche.
par Christophe Combelles, mis à jour le 10/10/2013

Dans la barre de recherche d'OpenERP 7, il est possible de cocher des filtres, permettant d'appliquer chacun un critère de recherche prédéfini (qui s'appelle un domain dans le vocabulaire OpenERP).

Par exemple lorsqu'on se situe dans la liste des clients il existe plusieurs filtres :

Que se passe t-il lorsqu'on coche plusieurs de ces filtres ? Applique t-on un ET logique ou un OU logique ? La réponse tient à peu de choses. Vous pouvez observer que certains de ces filtres sont séparés par un espace plus important, matérialisant trois groupes :

  • Un groupe contenant : Mes partenaires
  • Un groupe contenant : Personnes / Sociétés
  • Un groupe contenant : Clients / Fournisseurs

Et bien l'opérateur appliqué est un OU à l'intérieur d'un groupe, et un ET entre les différents groupe. Ou pour le dire différemment, l'opérateur logique appliqué aux filtres est par défaut un OU, et l'espace situé entre ces groupes représente un ET.

Voici ci-dessous un premier exemple qui correspond donc au critère : Mes partenaires ET Personnes ET Clients. C'est à dire les clients B2C auxquels je suis affecté. On peut voir que ces filtres sont séparés dans la barre de recherche elle-même :

 

Un deuxième exemple plus complexe : (Personnes OU Sociétés) ET (Clients ou Fournisseurs). C'est à dire toutes les personnes ou sociétés qui sont soit cliente soit fournisseur. Ici les filtres sont alors regroupés dans la barre de recherche en 2 blocs :

D'un point de vue technique

Chacun de ces filtres correspond à un « domaine » qui correspondent à un critère de recherche :

Nom du filtreCritère de recherche
Mes partenaires [('user_id','=',uid)]
Personnes [('is_company','=',0)]
Sociétés [('is_company','=',1)]
Clients [('customer','=',1)]
Fournisseurs [('supplier','=',1)]

Le fait de cocher ces filtres permet de construire un domaine qui est l'assemblage des différents domains, selon un ET ou un OU.

Voici à quoi ressemble la définition XML de ces filtres :

<filter help="My Partners" icon="terp-personal+" domain="[('user_id','=',uid)]"/>
<separator/>
<filter string="Persons" name="type_person" domain="[('is_company','=',0)]"/>
<filter string="Companies" name="type_company" domain="[('is_company','=',1)]"/>
<separator/>
<filter string="Customers" name="customer" domain="[('customer','=',1)]" help="Customer Partners"/>
<filter string="Suppliers" name="supplier" domain="[('supplier','=',1)]" help="Supplier Partners"/>

La clé de l'histoire se situe dans le tag <separator/>. Loin de seulement matérialiser une séparation visuelle, le tag <separator/>, qui aurait pu être nommé <and/>, représente un ET logique.

Si on reprend les deux exemples mentionnés plus haut, le premier donne donc ceci :

[('customer', '=', 1), ('is_company', '=', 0), ('user_id', '=', 1)]

tandis que le deuxième donne ceci :

['|', ('customer', '=', 1), ('supplier', '=', 1), '|', ('is_company', '=', 0), ('is_company', '=', 1)]

 

Si jamais on essaye de supprimer ce séparateur pour aboutir à la définition suivante :

<filter help="My Partners" icon="terp-personal+" domain="[('user_id','=',uid)]"/>

<filter string="Persons" name="type_person" domain="[('is_company','=',0)]"/>
<filter string="Companies" name="type_company" domain="[('is_company','=',1)]"/>

<filter string="Customers" name="customer" domain="[('customer','=',1)]" help="Customer Partners"/>
<filter string="Suppliers" name="supplier" domain="[('supplier','=',1)]" help="Supplier Partners"/>

On se retrouve alors avec des filtres non séparés et le résultat sera un OU, ce qui donne un recherche qui ressemble à : Personnes OU Sociétés OU Clients OU Fournisseurs, c'est à dire les partenaires qui sont soit des Personnes, soit des sociétés, soit des clients, soit des fournisseurs.

Le domaine résultant est donc l'assemblage des quatre domaines de chacun des filtres avec un OU :

['|', '|', '|', ('is_company', '=', 0), ('is_company', '=', 1), ('customer', '=', 1), ('supplier', '=', 1)]