Architecture d'Odoo
Odoo est un ERP et un framework architecturé sous un modèle 3-tiers client-serveurs:
- le serveur de base de données PostgreSQL
- le serveur d’application Odoo basé sur Werkzeug
- le client web basé sur JavaScript, utilisant les frameworks JQuery et BackboneJS pour les versions inférieures à 13 et l’introduction du nouveau framework frontend OWL depuis la version 14 qui sera entièrement supporté à partir de la version 16
Structure des modules Odoo
Chaque module Odoo dépends d’un ou plusieurs modules et présente une structure qui contient tous les éléments nécessaires à son fonctionnement comme les modèles de base de données, les vues, les droits d’accès, etc... Par exemple, si vous allez dans le module point_of_sale, vous allez constater que ce dernier contient plus ou moins la structure suivante:
Les dossiers:
- data où toutes les données statiques sont conservées (menus, crons jobs, données à exporter, etc...)
- models qui contient toutes les tables de la base de donnée sous formes de modèles basées sur l’ORM d’Odoo
- reports à partir duquel tous les rapports PDF et autres documents à imprimer sont chargés
- security pour la conservation de toutes les règles de sécurité et autres droits d’accès
- views pour les différentes vues écrites en XML
- wizard où ****toutes les fenêtres modales sont répertoriées
- static où les images et autres codes JavaScript et CSS sont répertoriés
Puis les fichiers:
- README.md: un fichier markdown pour la description du projet
- __manifest.py__: un fichier obligatoire pour le chargement et l’installation du module
Les champs dans Odoo
L’ORM d’Odoo est très riche et contient de nombreux champs dont on peut modifier l’aspect en utilisant des widgets précis. En important l’objet odoo.fields vous aurez accès aux champs suivant:
- Char() pour les textes courts. Le Char offre l’équivalent du <input type=”text”/> en HTML
- Text() pour les textes longs, équivalent du <textarea/> en HTML
- Boolean() pour les booléens, équivalent du <input type=”checkbox”/>
- Selection() pour afficher une liste d’éléments à sélectionner, équivalent du <option/> en HTML
- Float() pour les nombres décimaux
- Int() pour les nombres entiers
- Monetary() pour les nombres notamment les montant ou les prix
- Binary() pour le stockages des fichiers comme les images. À noter qu’il y’a aussi Image() réservée uniquement pour les images
- Html() pour afficher un éditeur WYSIWYG
- Date() et Datetime() respectivement pour les dates simples et les dates accompagnées de temps. Ces champs affichent un calendrier dans l’interface via leur widgets respectifs. Je parlerai des widgets dans un autre article.
- Many2one(), One2Many() et Many2many() sont des champs relationnels (n,1), (1,n) et (n,n)
Il existe aussi 2 types de champs particuliers (ou semi-relationnel) qui permettent d’interagir directement avec les données. Ce sont des méthodes qu’on peut ajouter aux champs plus haut via les attributs compute et related.
- L’attribut compute permet d’affecter le résultat d’un calcul à un champs
- L’attribut related permet d’affecter la valeur d’un champs d’un autre modèle à un champs précis
Il existe aussi des formats précis qu’on utilise lors des compute au niveau des champs Many2one(), One2Many() et Many2many(). Ces formats permettent de faire des actions bien précises lors des calculs notamment pour mettre à jour ou modifier des données dans ces champs. Ce sont:
- (0, 0, { values }) lien vers un nouvel enregistrement qui doit être créé avec le dictionnaire de valeurs donné
- (1, ID, { valeurs }) mettre à jour l'enregistrement lié avec id = ID (écrire des valeurs dessus)
- (2, ID) supprimer l'enregistrement lié avec id = ID (appels unlink sur ID, cela supprimera complètement l'objet, ainsi que le lien vers celui-ci)
- (3, ID) coupe le lien vers l'enregistrement lié avec id = ID (supprime la relation entre les deux objets mais ne supprime pas l'objet cible lui-même)
- (4, ID) lien vers un enregistrement existant avec id = ID (ajoute une relation)
- (5) dissocier tout (comme utiliser (3, ID) pour tous les enregistrements liés)
- (6, 0, [IDs]) remplacent la liste des ID liés (comme en utilisant (5) puis (4,ID) pour chaque ID dans la liste des ID)
Je vais revenir en profondeur sur certains de ces champs dans un autres articles.
Utiliser les méthodes de l'ORM
L'ORM d'Odoo présente une cartographie relationnelle des objets c’est-à-dire:
- structure hiérarchique
- cohérence et validation des contraintes
- traitement optimisé par requête complexe (plusieurs actions à la foi)
- valeurs de champ par défaut
- types de champs variés comme vue plus haut (Char(), Boolean(), Selection(), etc..)
En effet, Odoo propose trois mécanismes différents pour étendre les modèles de manière modulaire:
- créer un nouveau modèle à partir d'un modèle existant
- ajouter de nouvelles informations à la copie tout en laissant le module d'origine tel quel
- étendre les modèles définis dans d'autres modules sur place remplaçant la version précédente.
Il est également important de noter ceci:
- le modèle odoo.models.Model permet d'instancier la classe sur la base de données lorsque le module de la classe est installé
- odoo.models.TransientModel permet d'afficher les fenêtre modales (wizard)
- odoo.models.AbstractModel est un modèle abstrait qui permet la création d'une classe abstraite destinées à être héritée par les modèles classiques (Model et TransientModel). Il est très utilisé dans l'édition des rapports (report)
À travers ces modèles, vous pouvez utiliser les décorateurs suivant pour implémenter vos solutions:
- odoo.api.onchange() permet de changer la valeur d’un champs de manière dynamique lorsque la valeur d’un autre champs sur la vue change. Ce décorateur prend en paramètre le ou les champs qui vont déclencher le changement de la valeur de l’autre champs.
- odoo.api.depends() permet de faire un calcul au niveau des champs compute par exemple. Il prend en paramètre les champs qui seront utiliser pour le calcul.
- odoo.api.constrains() pour ajouter une contrainte de validation d’un ou plusieurs champs à partir des champs qui seront en paramètre.
Il existe plusieurs autres décorateurs et autres informations détaillées que vous pouvez obtenir dans la documentation officielle d’Odoo.
Je vous conseille de toujours avoir la documentation officielle prêt de vous pour la consulter lorsque vous codez, parce qu’elle est d’une importance capitale.