Académique Documents
Professionnel Documents
Culture Documents
Julie NUGUET
2
I. Remerciements
Je tiens à remercier M. Maurice MORETTI, mon responsable de stage, de m'avoir confié la
réalisation du projet et d'avoir été réactif et disponible pour répondre à mes questions.
Je suis reconnaissante envers toute l'équipe de l'ENI, et en particulier Mme Céline BRAUD, du
service Relations Entreprises, pour son suivi sérieux. Je remercie également tous les formateurs
pour leurs enseignements et leur pédagogie, et en particulier mon responsable de formation
M. Bruno MARTIN pour ses conseils.
Enfin, un grand merci à toute l'équipe de TeMPO Consulting pour leur accueil.
II. Lexique
Base 64 : codage utilisant un alphabet de 64 caractères ASCII (choisis pour être universellement
lisibles), notamment utilisé afin de transporter facilement des données binaires, comme des images
ou fichiers PDF par exemple.
Corbeille : dans l'application Maarch, une corbeille désigne un endroit dans lequel les fichiers sont
regroupés selon des critères définis. Par exemple une corbeille peut regrouper les courriers
provenant de scans, une autre les courriers à valider, etc.
ERP : un ERP (pour Enterprise Resource Planning) parfois désigné en français par l'expression
« progiciel de gestion intégré », est une application permettant de centraliser la gestion des
différentes activités d'une même entreprise.
Logiciel libre : un logiciel est dit « libre » lorsque qu'on peut l'exécuter comme on le souhaite, que
son code source est consultable et modifiable, et qu'il peut être redistribué. Il s'oppose à la notion de
logiciel « propriétaire ».
maarchconnector : module Odoo codé lors de mon stage. Il permet d'enregistrer une pièce jointe à
la fois dans Odoo et dans Maarch, et de rechercher dans Odoo un document Maarch à ajouter.
3
MVC : motif de conception reposant, comme ses initiales l'indiquent, sur une séparation entre les
différents éléments du code. Le Modèle concerne le cœur du métier, il interagit avec la base de
données et traite les données pour fournir de l'information aux contrôleurs. Le Contrôleur va
déclencher une action ou une autre en fonction des informations reçues. La Vue concerne tout ce qui
a trait à la présentation.
Pièce jointe : dans Odoo, document relié à n'importe quelle entité ou fiche (ex. facture N°12, client
N°ABC ou article N°AZ3).
Serveur activé : dans le contexte du module maarchconnector, un serveur Maarch est dit « activé »
lorsque la case correspondante est cochée. Cela signifie que l'interfaçage de ce serveur Maarch avec
Odoo est effectif. Les pièces jointes enregistrées dans Odoo seront automatiquement enregistrées
dans Maarch, et il sera possible de rechercher un document dans Maarch pour l'ajouter dans Odoo.
SOAP : SOAP, signifiant au départ Simple Object Access Protocol est un format d'échange de
messages sérialisés basé sur XML. C'est désormais un standard reconnu par le W3C.
Web service : API disponible via le web, utilisant un format d'échange SOAP et auquel on accède
via des requêtes HTTP. Il permet de communiquer avec des applications distantes, indépendamment
du langage de programmation utilisé.
Wizard : dans Odoo, les wizards font référence aux fenêtres de formulaire proposées à l'utilisateur,
dont les données sont utilisées immédiatement et ne sont pas conservées en base par la suite.
WSDL : Web Services Description Language est un standard qui se base sur XML. Il permet de
décrire un web service, en exposant les méthodes accessibles par celui-ci.
Lorsque ces termes sont employés au sein du présent document, ils sont mentionnés sous cette
forme.
4
III. Abstract (in English)
At the end of 2015 I carried out a 2-month internship in the firm TeMPO Consulting which is an IT
society specialized in free softwares. They sell, among others, an ERP (Enterprise Resource
Planning) called Odoo and a DMS software (Document Management System) called Maarch, which
manages in particular mails.
During my internship I was in charge of interfacing these 2 softwares. The idea was to make visible
in one application the documents that were visible in the other.
To achieve this goal I had to understand the mechanisms of both programs. It was not an easy task
since I was not used to working with applications so big (several thousand of files each). What's
more, both were written in a different language. Maarch is written in PHP with a dedicated
framework I didn't know before. Odoo is written in Python which is a programming language I
didn't know at all before my internship.
After having studied both programs I decided to use the web services to make the link between
them. I used the already existing web service that enables to add a document remotely into Maarch.
I also coded a new web service which aims at searching a mail stored in Maarch by its subject, its
date, its sender or its addressee.
On the Odoo side I coded a new module that can be installed by the user. A module is an
independent part of the ERP that you can combine with the application core and/or with other
modules to add functionalities. The one I have developed uses the functionalities of the Maarch web
services. It adds the possibility to add a document into Maarch from Odoo, and to make the reverse
operation, that is to say to search a document in Maarch and add it into Odoo.
Vous trouverez à la page suivante la liste des compétences couvertes durant mon stage.
Concernant les 4 compétences non mises en œuvre, je vous remercie de vous reporter sur mon
DSPP (Dossier de Synthèse de Pratique Professionnelle) dans lequel je présente des projets où j'ai
mis en application ces compétences.
5
(Note : j’ai retiré la partie basse du document
qui contenait des signatures)
6
V. La société
TeMPO Consulting est une société de services en informatique fondée en 1997 et basée à
Strasbourg (67). C'est une entreprise à taille humaine spécialisée dans la mise en place de solutions
à base de logiciels libres. Elle est l'un des membres fondateurs de Rhénalibre, un regroupement des
sociétés d'Alsace bénéficiant d’une expertise reconnue dans le domaine du libre. Elle fait ainsi
partie du pôle de compétences numérique « Rhénatic » qui vise à promouvoir les usages des
technologies numériques auprès des entreprises d'Alsace.
A. La demande
TeMPO Consulting a exprimé le besoin d'interfacer deux logiciels qu'ils commercialisent, à savoir
l'ERP Odoo et la plateforme documentaire Maarch. Un des modules de Odoo nommé « document »
permet d'ajouter des pièces jointes (des fichiers en local) dans Odoo et de les lier à n'importe quelle
entité existante, par exemple une pièce jointe peut être liée à une facture, à un client, à un article,
etc. TeMPO Consulting souhaiterait que ces pièces jointes :
- puissent provenir de Maarch,
- puissent être envoyées vers Maarch afin d'être visibles depuis la plateforme documentaire.
Exemple : un utilisateur d'Odoo saisit une facture, et il souhaite lier un document complémentaire à
cette facture (des informations reçues par courrier et disponibles sur Maarch). Il a donc besoin de
récupérer des documents Maarch depuis Odoo.
À l'inverse, une personne reçoit une demande de devis. Elle saisit ce devis dans Odoo, et va vouloir
d'une part mettre la demande en pièce jointe du devis dans Odoo, et d'autre part rendre visible cette
demande par courrier dans Maarch.
Pour mener à bien le projet, il faudra s'intéresser au fonctionnement de Maarch et à celui d'Odoo, et
en particulier au module « document ».
7
1. Odoo
Odoo, connu auparavant sous le nom OpenERP, est un ERP créé en 2005. C'est un logiciel libre
écrit en Python qui repose sur un framework de type MVC ainsi qu'une base de données
PostgreSQL.
Les fonctionnalités présentes peuvent être personnalisées et enrichies via l'installation de modules
supplémentaires à disposition. Un module est une portion de code indépendante qui peut être
combinée avec le cœur de l'application ou avec un autre module en vue d'ajouter une ou plusieurs
fonctionnalité(s). Au final de nombreux aspects de la vie d'une entreprise sont gérés : comptabilité,
gestion des ventes et des achats, suivi du stock, gestion de projets (planning avec diagramme de
Gant…), suivi des congés, du parc automobile, etc.
La dernière version d'Odoo est la version 9 sortie en octobre 2015 soit juste avant le début de mon
stage. Il a été décidé que mon développement se baserait sur la version précédente (V8), qui a fait
ses preuves et est encore fortement utilisée.
2. Maarch
Maarch est une plateforme de gestion documentaire ou GED. Elle comprend notamment Maarch
Courrier, logiciel sur lequel j'ai travaillé qui, comme son nom l'indique, est axé plus
particulièrement sur la gestion des courriers. C'est une application libre codée en PHP, elle utilise un
framework qui lui est propre, ainsi qu'une base de données PostgreSQL. Elle permet de traiter et
conserver les courriers reçus ou émis. L'idée est que chaque document s'inscrit dans un
« processus » ou « circuit » préalablement défini. Par exemple, un courrier va être enregistré par
une personne donnée. Puis, en fonction de son type par exemple, il sera transmis aux personnes
appropriées qui le traiteront. Le document sera alors transféré aux interlocuteurs suivants, et ainsi de
suite. Au final, le document sera archivé.
Fin 2015, une version spécifique de Maarch a été déployée dans les préfectures, dans le cadre de la
mise en place du SVE (Saisine de l’administration par Voie Électronique), permettant aux usagers
d'adresser leurs demandes en ligne et plus sous forme de dossier papier.
La version de Maarch utilisée lors de mon stage est la 1.5, qui était alors la dernière version en date.
La nouvelle version 1.5.1 est sortie le 15/12/2015, soit 10 jours avant la fin de mon stage.
A. Diagrammes UML
Le besoin a été modélisé et synthétisé grâce à différents diagrammes UML, que vous trouverez dans
les pages qui suivent.
8
Le diagramme de cas d'utilisation suivant permet de donner une vision globale des fonctionnalités
que le logiciel doit fournir.
Utilisateur
ajouter dans Odoo «includes» rechercher un document
un document Maarch dans Maarch
Administrateur
- soit un document local, c'est-à-dire qui se trouve sur son disque. Il peut également ajouter ce
même document dans Maarch (cette action peut donc « étendre » la première).
- soit un document qui provient de Maarch. Pour cela, il doit impérativement passer par l'étape de
recherche d'un document Maarch (d'où le mot-clé « include »).
L'administrateur hérite de l'utilisateur classique. Il a les mêmes droits, et il peut en plus gérer les
configurations des serveurs Maarch utilisés : les consulter, ajouter, modifier ou supprimer
(méthodes CRUD), et les activer ou désactiver.
9
Ce diagramme d'activité illustre l'enchaînement des actions dans le cas de l'ajout d'un document
local.
Utilisateur Système
contrôler si un serveur
Maarch est activé
vériier si la
coniguration est OK
sélectionner le sélectionner le
document à ajouter document à ajouter
aicher un message
d'erreur explicite
indiquer l'objet du
document pour Maarch
rafraîchir la liste
des pièces jointes
Lorsqu'aucun serveur Maarch n'est activé, le comportement est le même que si le module
« maarchconnector » n'était pas installé : la pièce jointe s'enregistre dans Odoo uniquement.
Lorsqu'un serveur Maarch est activé, la pièce jointe est enregistrée « simultanément » dans les 2
applications. Dans le cas où un serveur Maarch est activé mais que celui-ci est inaccessible (serveur
indisponible, mauvais mot de passe, etc), un message d'erreur apparaît et la pièce jointe n'est pas
enregistrée dans Maarch ni dans Odoo.
10
Le diagramme de séquence suivant permet de représenter les échanges de messages selon un axe
temporel, pour le cas d'ajout dans Odoo d'un document provenant de Maarch.
1: demandeListeDocuments
2: demandeServeurActivé
3: serveurActivé
4: rechercheDocuments
5: listeDocuments
opt
6: changeNomDesDocuments
7: sélectionneDocumentsÀAjouter
8: demandeAjout
loop[document à
ajouter]
9: ajouteDansOdoo
10: listePiècesJointesRafraichie
Via une fenêtre de recherche, l'utilisateur va demander la liste des documents de Maarch
correspondant aux critères qu'il aura indiqués. Pour que les documents puissent être récupérés, il
faut d'abord que la classe Configuration fournisse les informations sur le serveur Maarch
actuellement activé.
On notera que l'étape de renommage des documents par l'utilisateur est optionnelle, et que l'étape
d'ajout d'un document dans Odoo se répète autant de fois qu'il y a de documents à ajouter.
Remarque : les noms utilisés ici ne sont pas ceux des noms de méthodes définitifs (ils sont d'ailleurs
en français alors que le code de l'application sera en anglais).
11
B. IHM
J'ai maquetté les différentes IHM (Interfaces Homme / Machine) en vue de définir clairement le
résultat attendu.
Pour la partie « configuration » du module Odoo, consistant à définir le ou les serveurs Maarch à
utiliser, j'ai choisi de me conformer au rendu classique d'un module Odoo. Ainsi, l'utilisateur saura
facilement « où cliquer » puisqu'il est familier de l'interface.
Image 1
Une fois le module installé, le menu horizontal d'Odoo en haut de page a désormais une entrée
« Connecteur Maarch ».
Au premier clic dessus, on nous invite à créer une nouvelle configuration de serveur Maarch.
12
Image 2
Une fois que des configurations sont créées (au moins une), on arrive sur cette vue « liste . Elle
permet de visualiser l'ensemble des serveurs Maarch enregistrés. Ici, le « serveur principal » est
activé, et les 2 autres serveurs ne le sont pas. Il est à noter que dans l'application finale, j'ai rajouté
un code couleur pour distinguer visuellement les 2 états : les serveurs non activés apparaissent en
grisé.
Sur la maquette, le « serveur Paris » est coché (à gauche). Cela provoque l'apparition du bouton
« autres options » qui va notamment permettre de « modifier » ou « supprimer » ce serveur.
L'input « search » permet de rechercher ou filtrer une configuration par nom (par défaut) ou par
adresse du serveur.
13
Image 3
Cette vue « formulaire » apparaît lorsqu'on sélectionne une configuration dans la liste précédente.
Un clic sur « Modifier » nous fait passer en mode Édition de la configuration affichée, tandis qu'un
clic sur « Créer » nous amène sur un formulaire vierge. Dans les deux cas, tous les champs sont
obligatoires. Les caractères saisis dans le champ « mot de passe » sont masqués par des astérisques.
Les flèches permettent de naviguer d'une configuration à une autre sans repasser par la vue « liste ».
Image 4
Les 2 actions principales du module : Ajouter (un document local) et Ajouter un document
provenant de Maarch sont proposées via un menu dédié aux pièces jointes qui est placé juste à côté
du menu « Autres options ». Ces menus sont visibles sur tous les éléments de chaque module.
On y visualise également le nombre de pièces jointes actuellement associées à la fiche ainsi que leur
nom. Un clic sur une pièce jointe permet de l'ouvrir.
14
Image 5
Lorsqu'on choisit « Ajouter... » dans le menu présenté précédemment, la fenêtre ci-dessus s'affiche.
Elle nous invite à préciser sous quel nom (« objet » de courrier) le document sera enregistré dans
Maarch. Par défaut, c'est le nom du fichier qui est proposé, ici facture_durand.pdf.
Image 6
Lorsqu'on choisit « Ajouter depuis Maarch... » dans le menu présenté précédemment, la fenêtre de
recherche d'un document dans Maarch apparaît.
L'utilisateur commence par rechercher un document par son objet, sa date, et éventuellement son
type et son contact (expéditeur ou destinataire).
Le type de courrier proposé respecte la sémantique utilisée dans Maarch : courrier interne, courrier
départ (expédié) ou courrier arrivée (reçu). La date proposée par défaut est « un an auparavant ». Ce
critère permet de ne pas traiter un volume de fichiers trop important dans le cas où Maarch est mis
15
en place depuis longtemps dans la structure.
Une fois les critères renseignés, l'utilisateur clique sur « rechercher », et la liste des fichiers
correspondants s'affiche dans la liste en-dessous. Par défaut, ils sont triés par date. Un clic sur une
autre colonne permet de trier selon un autre critère.
Il suffit ensuite de cocher le ou les fichier(s) à ajouter, de modifier éventuellement leur intitulé (en
plaçant le curseur sur le texte à modifier), et enfin de cliquer sur « ajouter ».
J'ai synthétisé l'enchaînement entre les IHM via le diagramme d'états-transitions suivant :
Visualisation d'une Clic sur une Visualisation des Clic sur "Connecteur Maarch" Visualisation page
coniguration coniguration conigurations [ nombreConigurationsExistantes > 0 ] d'accueil de l'ERP
On note la présence d'une condition de garde, puisqu'au clic sur « Connecteur Maarch » dans le
menu, on arrive soit sur la liste des configurations (Image 2), soit sur une invitation à créer une
nouvelle configuration si aucune n'existe déjà (Image 1).
On peut réaliser les actions classiques de visualisation, création et modification d'une configuration
(Image 3). L'état de « suppression d'une configuration » n’apparaît pas sur le schéma car il n'a pas
de vue associée. Pour supprimer une configuration, il faut simplement sélectionner l'entrée
correspondante dans le menu « Autres options » accessible via la liste des configurations ou via la
fiche de la configuration concernée. On revient alors vers la liste des configurations restantes s'il y
en a, ou à défaut vers la page invitant à créer une nouvelle configuration.
16
Concernant le « cœur » de l'application, tout part de la consultation d'une fiche dans l'ERP (facture,
avoir, fiche client)…
De là, on a accès au menu (Image 4) qui nous permet de :
- cliquer sur « Ajouter ». On choisit alors le document à ajouter dans Odoo et Maarch et on précise
l'objet du document pour Maarch (Image 5).
- cliquer sur « Ajouter depuis Maarch ». On passe alors à l'état « recherche » d'un document Maarch
(Image 6) dans lequel on reste tant qu'on affine sa recherche en saisissant les critères qui nous
intéressent dans le formulaire. Une fois les documents à ajouter trouvés, on les sélectionne et on
valide.
Dans les deux cas, on revient ensuite à l'état de consultation d'une fiche, et on peut voir dans le
menu que la liste des pièces jointes a été rafraîchie (Image 4).
Il faut utiliser les bases de données existantes sous PostgreSQL, version 9.1.12 pour Maarch et 9.4.5
pour Odoo.
S'agissant de deux applications distinctes à faire communiquer, il faut s'intéresser aux protocoles de
communication ainsi qu'aux standards de description de données.
Au final : la première technologie envisagée a été CMIS, puis il a été convenu d'utiliser WSDL.
17
Format de description WSDL
WSDL, Web Services Description Language, décrit les fonctions disponibles sur un serveur distant
par l'intermédiaire d'un web service. Il utilise comme protocole de communication SOAP (RPC ou
orienté messages) dont le format se base sur XML.
X. Normes et conventions
Le code du module maarchconnector respecte les normes d'Odoo, pour plus de lisibilité et de
maintenance.
Les noms des classes sont écrits en CamelCase, qui est la norme depuis Odoo 8, ex :
DocumentWizard
18
De même, les méthodes de vérification déclenchées à la validation d'un formulaire commencent par
_check_, ex :
_check_server_address_format()
qui vérifie que l'adresse du serveur Maarch saisie commence par « http:// » ou « https:// » ou rajoute
cet élément le cas échéant.
Les attributs liés à un autre modèle par une relation « Many2Many » ou « One2Many » ont le
suffixe _ids, par exemple :
document_ids = fields.One2many('maarch.document', 'documentwizard_id', string=u"Liste des
documents")
Il est à noter qu'en Python, le principe d'encapsulation diffère des autres langages. On considère,
lorsqu'il n'y a pas de vérifications particulières à faire sur les attributs, qu'on peut y accéder
directement via la notation « point », comme ceci : activated_conf.server_address
On ne retrouve pas clairement la notion de visibilité (cf les mot-clés « public », « private » ou
« protected » notamment qu'on a dans des langages comme Java ou PHP).
Par convention, les attributs et méthodes qui ne sont utilisés qu'au sein de la classe commencent par
un underscore. J'ai choisi de suivre ce principe. Cela permet d'alerter le développeur qu'il va réaliser
une action non prévue lorsqu’il s’apprête à manipuler un élément préfixé d'un underscore en dehors
de la classe. Cependant, rien ne l'empêche de le faire, cette notation n'est qu'informative.
Conformément aux spécifications techniques, j'ai utilisé PHP 5.4 pour la partie Maarch et Python
2.7 pour la partie Odoo.
Pour gérer les bibliothèques Python, j'ai utilisé le gestionnaire de paquets « pip » (signifiant Pip
Installs Packages ou Pip Installs Python).
J'ai également utilisé les outils suivants pour mener à bien le projet :
- le gestionnaire de versions Git, afin de garder un historique du travail produit, et de gérer une
sauvegarde des données. Mon code a été placé sur la plateforme GitHub.
19
- différents outils pour manipuler les machines virtuelles : Virtualbox, ssh et sshfs.
- les environnements de développement intégrés PyCharm (pour le code en Python d'Odoo) et
NetBeans (pour le code en PHP de Maarch).
- phpPgAdmin, application web pour gérer les bases de données sous PostgreSQL.
- Wireshark, visualiseur de trames réseaux, pour vérifier le format et le contenu des messages
échangés sur le réseau.
- différents navigateurs web afin de tester la compatibilité.
- Pencil, logiciel de maquettage, pour réaliser les maquettes des IHM.
- UMLet, outil destiné à la conception de diagrammes UML, que j'ai utilisé pour mes diagrammes.
- GanttProject, logiciel libre de gestion de projet, pour planifier mon projet grâce à un diagramme
de Gantt.
XII. Réalisation
A. Etude de l'existant
Au début de mon stage j'ai dû comprendre et étudier les protocoles de communications disponibles
pour récupérer et envoyer des fichiers dans Maarch. La première idée a été de s'orienter vers le
protocole CMIS, qui est présent dans la documentation technique de Maarch. Un connecteur Odoo
déjà existant est disponible pour gérer ce type d'échange de messages. Après quelques essais sur
l'API CMIS de Maarch et en vérifiant les spécifications en ligne du protocole CMIS, il s'est avéré
que l'implémentation disponible n'était pas fonctionnelle. Cette constatation a été par la suite
confirmée par Maarch via un échange d'e-mails.
J'ai alors cherché une alternative au protocole CMIS. La documentation de Maarch fait référence à
des « web services » permettant de dialoguer avec ce dernier et de manipuler des documents. Un
exemple qui est donné sur leur wiki est l'enregistrement de factures pour un programme de
comptabilité de test. Cela correspondait à mes attentes, j'ai donc choisi d'utiliser le web service
existant d'enregistrement d'un document et par la suite de créer un nouveau web service permettant
de récupérer un document selon différents critères.
J'ai également dû comprendre Odoo et Maarch sur le plan fonctionnel, afin d’appréhender leur
fonctionnement et leur sémantique.
Dans Maarch, j'ai par exemple vu la notion de corbeille, ainsi que la notion de filtres qui y est
associée. Les filtres permettent de définir des règles qui s'appliquent sur une corbeille, faisant ainsi
apparaître les documents répondant aux critères souhaités. Par exemple, les courriers retournés au
service Courrier ont le statut « RET ». Le filtre associé sera donc : STATUS='RET'
En arrière-plan, c'est du code SQL qui est exécuté.
20
Dans Odoo, j'ai par exemple dû m'intéresser à la notion de wizard qui désigne à la fois une classe
qui hérite de TransientModel (manipulant des données qui ne seront pas persistées en base) et la
fenêtre correspondante qui s'affiche pour l'utilisateur.
Enfin, j'ai dû appréhender les deux applications sur le plan technique. Mon application n'étant pas
générique mais répondant à un besoin spécifique, j'ai choisi d'en faire un module à part. J'ai donc dû
apprendre comment les modules Odoo étaient construits.
L'étude technique a été la partie la plus chronophage, en particulier car Odoo et Maarch
représentent une énorme base de code.
Maarch compte plus de 6 000 fichiers dont 2 000 en PHP. La base de données comporte 123 tables.
Pour Odoo, si on considère une version basique permettant de gérer la comptabilité de l'entreprise,
on dénombre déjà plus de 20 000 fichiers dont plus de 1 800 sont écrits en Python. Quant à la base
de données, elle compte près de 400 tables.
L'étude des deux logiciels m'a appris leur fonctionnement, comment les enrichir (créer un module
pour Odoo, un web service pour Maarch) ainsi que leur gestion de la base de données. Les deux
sections suivantes présentent ces aspects et ma contribution.
1. Mécanismes d'Odoo
Dans Odoo, les entités « métier » sont gérées dans des classes « Model ». Ces classes sont
directement liées à la base de données puisque :
- une table SQL correspondant à la classe est automatiquement créée
- les attributs de la classe sont automatiquement « mappés » avec les champs de la table.
21
Prenons un exemple pour illustrer.
Dans le module « maarchconnector » que j'ai créé, la classe « Configuration » hérite de la classe
openerp.models.Model, ainsi ses données sont persistantes en base. Les attributs utilisés pour cette
classe sont de type « fields.type ». La simple déclaration d'un attribut conditionne le type de champ
dans la base de données, ainsi d'ailleurs que la vue qui y sera associée (un champ fields.Boolean
sera une case à cocher, un champ fields.Char sera une entrée de chaîne de caractères, etc). Voici un
extrait de la classe « Configuration » qui montre les attributs utilisés :
Lors de la création de cette classe héritant de openerp.models.Model, une table est créée
automatiquement par Odoo et a la forme suivante :
La table est nommée du nom du modèle avec le point remplacé par un underscore. On retrouve tous
les champs définis dans la classe « Configuration » mais également le champ « id » qui est la clé
primaire, « create_uid » et « create_date » qui indiquent respectivement quel est l'utilisateur qui a
créé l'entrée et à quelle date, ainsi que « write_uid » et « write_date » qui indiquent respectivement
qui a modifié l'entrée et à quelle date.
22
Au sein du code Python de la classe, on peut manipuler les données, comme dans la méthode
suivante :
Le premier élément de cet exemple est « @api.multi » qui est un décorateur en Python. Un
décorateur permet d'exécuter du code qui se chargera d'appeler la fonction, pour insérer du code qui
s'exécutera avant et/ou après la fonction, son but ici est de redéfinir « self ». La fonction
get_the_activated_configuration() permet de faire une recherche dans toutes les entrées de la table
créée par la définition de la classe Configuration. « @api.multi » redéfinit donc « self » pour que
ses fonctions soient liées à l'ensemble des entrées de la table « maarchconnector_configuration ».
Par exemple ici le « search » remplace une requête de type « select » sur l'ensemble des éléments de
la table. Cela permet de s'abstraire de la saisie de requêtes SQL, en utilisant un ORM.
Il est également possible d'utiliser du SQL classique, par exemple ici pour compter le nombre de
configurations activées :
Une contrainte SQL est définie par un nom et la contrainte elle-même. La syntaxe Odoo pour créer
des contraintes SQL est minimaliste, et se fait en définissant une liste de tuples représentant ces
deux éléments ainsi qu'un message d'erreur en cas de non respect de cette contrainte.
Exemple :
23
2. Base de données Odoo
Pour réaliser mon projet, j'ai dû comprendre certaines parties de la base de données Odoo mise en
place, et en particulier celle liée au module « document ». Ce module permet de lier un document
(une pièce jointe) à n'importe quel élément de l'ERP, aussi bien pour les modules déjà en place lors
de l'installation de « document » que pour ceux qui seront installés par la suite.
Cela se fait en base de donnée de la manière suivante. Deux colonnes sont créées dans la table des
pièces jointes (ir_attachment). La première est « res_model » pour stocker le nom du modèle
concerné (ex. « account.invoice » pour indiquer que la pièce jointe est liée à une « facture »). La
seconde est « res_id » pour stocker l'identifiant de l'élément concerné. Par exemple, si une pièce
jointe est reliée au modèle « account.invoice » et à l'id « 12 », alors le document concerne la facture
N°12.
Il n'aurait pas été faisable d'utiliser une simple clé étrangère ou une table de jointure car il aurait
fallu que l'identifiant de la clé étrangère puisse faire référence à des tables différentes.
Dans la table ir_attachment, l'élément « res_model » indique quelle est la table référencée par
« res_id », qui peut être une clé étrangère de « account_invoice » (une facture), une
« product_pricelist » (une liste de tarifs), une « project_task » (une tâche d'un projet), etc. Les autres
colonnes rassemblent des informations diverses sur le document, comme son nom, sa taille, le type
de fichier et son lieu de stockage.
24
- le type de courrier (interne, …) ;
- le contact, c'est à dire l'expéditeur ou le destinataire du courrier.
J'ai étudié la base de données existante, et ai repéré les différentes tables impliquées pour mener à
bien cette recherche :
Il n'existe aucune contrainte de clé étrangère sur ces tables. Les courriers sont stockés dans la table
« res_letterbox », c'est dans cette table qu'on récupère leur objet et leur date.
La table « mlb_coll_ext », qui ne comporte pas de clé primaire, permet d'établir le lien entre le
courrier et son contact. C'est aussi dans cette table qu'on récupère la catégorie du courrier.
La colonne « res_id » de la table « mlb_coll_ext » correspond à l'identifiant du courrier dans
« res_letterbox ».
– soit le contact est interne à la société, alors « dest_user_id » (s'il s'agit du destinataire) ou
« exp_user_id » (s'il s'agit de l'expéditeur) comportera l'identifiant de l'utilisateur, correspondant à
« user_id » de la table « users ». Cette table est celle des utilisateurs de Maarch, on en extrait le
prénom et nom de la personne via les colonnes « firstname » et « lastname ».
On notera que dans Maarch les informations sur le document sont stockées en base (table
« res_letterbox »), alors que le document lui-même est stocké sur le disque (cf l'emplacement
indiqué dans la colonne « path »).
25
C. Code source de l'application
Pour définir un web service dans Maarch, il faut modifier le fichier ws.php qui contient la définition
de toutes les fonctions accessibles à distance, ainsi que le type des paramètres attendus et renvoyés.
Cela permet une sérialisation et une désérialisation des éléments sans ambiguïté.
La date est de type « string » car elle sera manipulée ainsi dans le code. Maarch fait une surcouche à
la classe PDO, dans laquelle il n'est pas prévu d'avoir de type « date » (cela entraîne une erreur si
utilisé), c'est pourquoi je convertis par la suite ce paramètre en date lors de la requête SQL (voir
l'extrait de code suivant pour l'exemple).
26
La fonction de recherche de documents dans le web service est implémentée comme suit :
Le nom de la fonction est celui donné dans le WSDL précédemment, et nous avons les critères de la
recherche en paramètre, dans un tableau associatif dont les clés sont données par le WSDL.
Ensuite, nous avons une première requête SQL. Cette requête permet de récupérer l'identifiant du
courrier, son sujet, sa date, sa catégorie ainsi que des identifiants qui, lorsqu'ils ne sont pas vides,
nous indiquent quel est le destinataire ou l'expéditeur. Cette dernière information conditionne la
prochaine requête, pour récupérer le reste des informations nécessaires qui sont situées dans d'autres
tables.
Une simple jointure ne serait pas possible, car on ne peut savoir sur quelle table elle s'appliquerait
(cf section « Base de données Maarch »).
27
Le code qui suit est une exécution de la requête. La surcouche à la classe « PDO » de Maarch y est
utilisée, afin de permettre l'utilisation de requêtes préparées.
Une fois la requête effectuée, on crée la structure de données que nous allons renvoyer et on la
remplie avec les informations voulues.
28
Le fil d'exécution est conditionné par la présence de données dans les champs « dest_user_id »,
« exp_user_id », « dest_contact_id » ou « exp_contact_id », comme présenté précédemment. Les
fonctions appelées ici prennent en paramètre un handler de la connexion à la base de données ainsi
qu'une référence à une entrée du résultat de notre précédente requête.
Avant de remplir la structure de résultats, on supprime avec unset les informations qui ne sont plus
utiles et ne sont pas attendues par le type de retour défini dans le WSDL.
Ainsi la partie « Modèle » de mon application se compose de classes que j'ai représentées avec le
diagramme de classes suivant :
BaseModel
Model TransientModel
Coniguration SearchWizard
DocumentWizard
- _name : String - _name : String
+ name : String + ilesubject : String - _name: String
+ server_address : String + min_date : Date + maarch_id: Int
+ maarch_user_login : String + category : List + subject: String
est composé de + doc_date: Date
+ maarch_user_password : String + contact_name : String
+ activated : Boolean 1 0..* + category: String
+ search_docs() : dict
- _sql_constraints : List + contact: String
- _treeview_line_construction() : None
+ to_add: Boolean
- _count_activated_conigurations() : Int - _get_category_designation() : String
- _check_server_address_format() : None - _onchange_min_date() : dict + onchange_subject() : None
- _check_activated_coniguration() : None + add_maarchdoc_into_odoo() : None
+ get_activated_coniguration() : Coniguration
- _onchange_activated() : dict
+ get_maarch_client() : suds.Client
La classe BaseModel, ainsi que les classes Model et TransientModel qui en héritent, sont des
classes de base dans Odoo.
« Model » correspond aux données persistantes en bases de données, comme vu précédemment. La
classe Configuration que j'ai créée en hérite : les configurations des serveurs Maarch utilisés
29
doivent être sauvegardées.
La classe TransientModel concerne les données dites « transientes », qui ne sont pas conservées
durablement en base. J'ai créé deux classes qui en héritent, SearchWizard et DocumentWizard. La
première correspond à la fenêtre de recherche d'un document Maarch depuis Odoo, qui nous permet
de sélectionner plusieurs critères avant d'effectuer une recherche. DocumentWizard est la classe qui
représente un document trouvé, qui constitue chaque entrée dans la liste des documents trouvés au
sein de la fenêtre de recherche (cf la maquette présentée à la section « IHM » du présent rapport).
On a une relation d'agrégation, symbolisée par un losange, entre ces deux classes. Un
« SearchWizard » est composé de 0 (aucun document trouvé) à plusieurs « DocumentWizard »
(cardinalité 0..*). À l'inverse, un DocumentWizard ne se trouve que dans un seul SearchWizard.
Dans le code, cela s'est traduit par une relation « one2many » et « many2one » mise en place en
utilisant l'ORM intégré dans Odoo.
Les modèles développés sont pensés en respectant la norme des modèles « Odoo ». La séparation
MVC n'est pas aussi nette qu'elle pourrait l'être dans d'autres applications. Comme expliqué
brièvement à la section « Mécanismes d'Odoo », le modèle comporte des attributs qui sont de type
« champ » (champ de type Date ou champ de type Chaîne par exemple) ce qui conditionne
directement les éléments de la vue. Le modèle et la vue sont donc en partie confondus. Par souci de
simplicité, sur le diagramme j'ai décidé de n'indiquer que le type intuitif des attributs des classes du
modèle (ex : Date au lieu de openerp.fields.Date).
Chaque instance d'un modèle a un identifiant unique implicite (qui n'est donc pas représenté sur le
diagramme).
Lorsqu'une méthode ne renvoie rien, j'ai employé le terme Python « None » en lieu et place de
« Void » sur le diagramme.
Les visibilités indiquées (- et +) ne sont que symboliques, cette notion n'existant pas clairement en
Python (cf section « Normes et conventions » de ce présent document).
Enfin, on notera que le diagramme ne représente ici qu'une partie de l'application. À ces classes
s'ajoutent un contrôleur en Python, des vues en XML, ainsi que du code JavaScript.
Nous allons justement voir maintenant l'arborescence des fichiers constituant mon module
« maarchconnector ».
30
On constate que les fichiers sont séparés dans différents dossiers :
- models :
correspond à la partie « M » de l'architecture « MVC ». Conformément aux principes d'Odoo, c'est
dans ce répertoire que sont placés les objets métiers qui sont automatiquement sauvegardés en base
de données. On y trouve la classe « Configuration » qui va permettre de créer au sein de
l'application un ensemble d'objets partageant les mêmes caractéristiques : par exemple chaque
configuration possède un nom et une adresse de serveur.
- views :
correspond à la partie « V » de l'architecture « MVC ». On trouve dans ce dossier les vues définies
via des fichiers XML.
- controllers :
correspond à la partie « C » de l'architecture « MVC ». Au sein du contrôleur on trouve les
vérifications nécessaires en fonction desquelles l'une ou l'autre action va être déclenchée. Les
contrôleurs mettent également en œuvre le mécanisme des « routes » : en associant une méthode à
une route, ils permettent son utilisation côté JavaScript via un appel Ajax.
Exemple :
- wizard
Un wizard se comporte comme un « Model » classique, à la différence que les données sont
« transientes », c'est-à-dire qu'elles ne sont stockées que temporairement et ne sont pas gardées en
base de données.
31
Par exemple : lorsqu'un utilisateur souhaite ajouter dans Odoo un document Maarch, il cherche
d'abord le document à ajouter selon des critères donnés. Une liste de documents correspondants lui
est alors proposée. Les documents de cette liste sont « transients », ils doivent être manipulables
temporairement mais n'ont aucune raison d'être conservés en base par la suite (seuls les documents
qui seront effectivement ajoutés en tant que pièces jointes seront mémorisés).
- static/src/js et static/src/xml
Toujours selon les conventions d'Odoo, on place dans ces sous-dossiers les parties de code
JavaScript ou XML qui redéfinissent l'existant. Ainsi, le fichier XML présent ici nous sert à
surcharger le menu d'ajout d'une pièce jointe fournie par le module « document » pour lui rajouter
l'option « ajouter depuis Maarch... »
Au sein du code JavaScript, on trouve différentes méthodes comme celle permettant à l'utilisateur
de définir l'objet du courrier associé à un fichier avant de l'enregistrer dans Maarch.
On y trouve des appels Ajax qui, via les routes que l'on a évoquées, font appel aux méthodes Python
et exploitent le résultat obtenu.
- __init__.py et __openerp__.py contiennent la liste des imports à faire et des fichiers à charger.
Dans __openerp__.py, on trouve également des éléments définissant le module, comme le nom sous
lequel il va apparaître aux utilisateurs (« Module d'interface avec Maarch »), et également les
modules dont il dépend (ou hérite), ici « document ». En d'autres termes, lorsqu'un utilisateur
installera le module « maarchconnector » dans Odoo, le module « document » sera
automatiquement installé s'il ne l'est pas déjà. L'option « installable » permet au module de pouvoir
être installé, tandis que l'option « auto_install » placée à False indique que le module n'est pas
activé automatiquement lors de l'installation d'Odoo.
- le fichier README permet de donner des indications, notamment sur les modifications à
apporter dans Maarch pour qu'il puisse s'interfacer correctement avec le module Odoo.
- le fichier « .gitignore » est présent car mon application a été versionnée en utilisant Git. J'ai
notamment indiqué via ce fichier de ne pas suivre les modifications sur les fichiers se terminant par
« .pyc » qui correspondent au « bytecode » Python.
J'ai commenté toutes mes méthodes avec une brève description et des indications sur les paramètres
attendus et le type de retour s'il y en a.
32
Voici un extrait de la méthode appelant le web service pour ajouter un fichier dans Maarch.
On commence par définir les données attendues par le web service conformément à la description
de la méthode storeResource dans le WSDL que voici :
33
La définition des données attendues se fait sous forme de tableaux de données, en précisant à
chaque fois le nom de la colonne, sa valeur, et son type, qui seront par la suite sérialisés en XML.
Par exemple la colonne « typist » (désignant celui qui « saisit » le document dans Maarch) est de
type Chaîne et aura pour valeur « odoo ». Ainsi, le document arrivera dans la corbeille Maarch
« odooBasket » regroupant les documents provenant d'Odoo. Le paramètre « subject » a pour valeur
une chaîne de caractères qui est décodée en UTF-8, permettant une prise en compte correcte des
caractères accentués notamment.
Une fois les paramètres définis, on appelle la méthode. Celle-ci lèvera une Exception si le fichier est
mal formé ou vide :
On remarque que le contenu du fichier a été encodé en base 64 pour être manipulé.
Comme indiqué dans la partie « Architecture logicielle d'Odoo », l'une des caractéristiques du
contrôleur dans Odoo est qu'il met en œuvre le mécanisme des « routes », qui permettent aux
méthodes d'être appelées par de l'Ajax. Voici un exemple avec la méthode set_subject() :
34
Cette méthode définit l'objet du courrier à enregistrer dans Maarch et peut être appelée côté
JavaScript via la route /tempo/maarchconnector/set_subject. C'est le cas une fois que l'utilisateur a
renseigné l'objet choisi dans ce prompt JavaScript :
On remarque au sein de la méthode qu'on utilise les fonctionnalités d'une classe MLStripper pour
retirer les balises XML/HTML éventuellement saisies. Cela évite les injections de code JavaScript
(balises <script>) par exemple.
Cet extrait de code intervient lorsque l'utilisateur souhaite ajouter un document dans Odoo et dans
Maarch. On vérifie que la configuration du serveur Maarch est OK. Si ce n'est pas le cas, un
message d'erreur est affiché. Sinon, on demande à l'utilisateur d'indiquer l'objet du document pour
Maarch. On retrouve l'appel à la méthode Python présentée juste avant via la route
« /tempo/maarchconnector/set_subject ». Le paramètre « subject » est passé via un tableau
associatif.
35
Voici un autre extrait du code :
Ci-dessous, la méthode est décorée par « @api.onchange('subject') », cela signifie qu'elle est
appelée à chaque fois que le champ « subject » est modifié dans le formulaire concerné. Elle enlève
à la volée les caractères non acceptables pour un nom de fichier. La dernière ligne est typique du
langage de programmation Python, qui par souci de concision place dans la même ligne une boucle
et des instructions conditionnées :
36
La méthode ci-dessous a pour but d'ajouter dans Odoo les fichiers Maarch sélectionnés :
On trouve l'appel à une méthode d'un autre modèle, ici pour récupérer le client Maarch par la
méthode get_maarch_client(). Le client est une instance de la classe « suds » qui est un module
pour dialoguer en SOAP.
Pour rappel, lorsque l'utilisateur récupère des fichiers de Maarch dans Odoo, le fichier est enregistré
dans Odoo sous le nom d'objet du courrier Maarch. Il faut que le navigateur comprenne quel est le
type de fichier pour pouvoir le manipuler (exemple : visualiser un document PDF). Pour cela, lors
de la récupération du fichier nous allons le renommer s'il ne possède pas déjà l'extension
appropriée. L'extension est récupérée via la fonction viewResource du web service Maarch.
Pour savoir à quelle entité la pièce jointe doit être rattachée, on récupère le modèle concerné et l'ID
via le « contexte » (self.env.context). C'est un mécanisme utilisé dans Odoo pour transporter des
informations.
37
Les vues sont gérées via des fichiers XML, comme on peut le voir sur les deux exemples suivants,
correspondants aux vues de la configuration des serveurs Maarch.
Voici la portion de code XML construisant la vue « formulaire » pour la création ou l'édition d'une
configuration :
On remarque que l'on peut conditionner l'affichage. Par exemple ici, les serveurs non activés sont en
gris.
38
D. Rendu
Voici quelques extraits du rendu final pour donner un bref aperçu des différentes vues.
Nous voyons ici une facture enregistrée dans l'ERP (les données sont fictives).
Sous le curseur, on voit le menu déroulant permettant d'accéder aux différentes options d'ajout d'une
pièce jointe. Ici deux documents sont déjà ajoutés à la facture.
On notera que les pièces jointes peuvent être de types différent : on voit ici un fichier PDF et une
image de type JPEG.
39
Ci-dessus une capture issue de Maarch. Lorsqu'un document est ajouté via le module
« maarchconnector », il devient visible dans Maarch dans la « corbeille Odoo ». Ici, on voit qu'il y
a 1 document à traiter.
Lorsqu'on clique sur le document, on peut le traiter comme n'importe quel autre document arrivé
dans Maarch :
L'objet est prérempli, ainsi que la date, et l'utilisateur peut compléter les informations manquantes.
On retrouve sur cet écran la « catégorie » du courrier (ici Courrier Arrivée) et l'expéditeur (ici
Bernard BLIER) qu'on peut utiliser comme critères de recherche depuis Odoo.
40
Ci-dessus on observe la fenêtre ou wizard de recherche d'un document Maarch, dans Odoo.
L'utilisateur a renseigné ses critères puis cliqué sur « rechercher ». Les fichiers trouvés sont
maintenant listés.
La catégorie « courrier arrivée » reprend la sémantique utilisée dans Maarch.
Les documents apparaissent par défaut triés par date dans l'ordre anti-chronologique, ainsi les plus
récents sont accessibles en premier. Un clic sur une en-tête de colonne permet de trier selon un
critère différent.
Sur cette capture, aucun fichier n'a été sélectionné pour l'ajout, les lignes sont donc grisées.
Lorsqu'un fichier est coché en vue d'être ajouté, la ligne concernée devient noire.
Il est possible de cocher plusieurs lignes, et donc d'ajouter plusieurs fichiers en une seule fois.
J'ai géré de nombreux cas d'erreurs dans l'application, faisant en sorte que celle-ci ne « plante » pas
mais indique à l'utilisateur quel est le problème à résoudre.
Quelques exemples :
… au clic sur « ajouter depuis Maarch » alors qu'aucun serveur Maarch n'est activé. Un message
d'erreur s'affiche en lieu et place de la fenêtre de recherche.
41
… lorsqu'on tente d'interagir avec le serveur Maarch alors qu'il est inaccessible.
… lorsqu'un formulaire n'est pas rempli correctement (ici les deux champs obligatoires ont été
laissés vides), j'ai utilisé le message d'erreur fourni de base dans Odoo, à savoir « Les champs
suivants sont incorrects » suivi de la liste des champs concernés.
Comme indiqué dans la section « IHM », j'ai également utilisé les vues traditionnelles d'Odoo pour
la partie « Configuration des serveurs Maarch », comme on peut le voir sur cette capture :
On voit la liste des serveurs disponibles, le « serveur Nantes » en noir étant activé.
42
E. Architecture de l'application
J'ai modélisé l'organisation du système à l'aide du diagramme de composants ci-dessous :
Module Odoo
BDD Maarch
maarchconnector
BDD Odoo
Stockage et récupération
de données WebService Maarch
searchDocuments Récup. informations sur les documents
Recherche informations sur documents Maarch
WebService Maarch
storeResource
Accès données Maarch en écriture
Enregistrement données
WebService Maarch
viewResource
Récupération de documents Maarch par id
Récup. informations sur les documents
Remarque : dans Odoo, selon les versions et la configuration choisie, les documents s'enregistrent
soit sur le disque soit dans la base en tant que données binaires. Le schéma représente ici le cas où
le stockage se fait dans la base de données directement.
43
L'application a été testée, son déploiement s'est fait selon le diagramme de déploiement suivant.
Maarch
HTTP
BDD PostgreSQL
Clients web
WSDL (SOAP) (Firefox, Internet Explorer,
Chrome, Opera, Safari, etc)
HTTP
Linux Ubuntu Server
Odoo
BDD PostgreSQL
Odoo et Maarch sont sur deux machines distinctes, tournant chacune sous Linux. On voit que les
applications communiquent entre elles via WSDL. Les clients web peuvent interroger l'une ou
l'autre des applications via HTTP.
Les bases de données se situent sur les mêmes serveurs, le volume de données étant suffisamment
faible pour que cela soit acceptable en terme de réactivité et de capacité de stockage.
F. Tests
J'ai testé mon application :
- tout au long de la phase de codage, à chaque nouvelle fonctionnalité développée
- une fois l'application terminée.
44
J'ai réalisé des scénarios de test que j'ai exécutés, par exemple :
J'ai également fait de l'automatisation via des tests unitaires avec la bibliothèque Python
« unittest ».
On voit ici un test vérifiant que la méthode pour enlever les balises XML/HTML au sein d'une
chaîne fonctionne :
On utilise les assertions, ici assertEqual pour comparer 2 chaînes (le 3ème paramètre étant le
message d'erreur affiché en cas d'échec).
Ici le test est lancé via l'interface de Pycharm. La barre verte indique que le test s'est bien déroulé.
L'intérêt de ces tests est qu'on peut les relancer régulièrement, vérifiant ainsi que les modifications
qu'on apporte au code ne « cassent » pas l'existant. Ce faisant, on teste la non-régression du code.
45
J'ai testé la sécurité de mon application : tentatives d'insertion de code JavaScript ou d'injections
SQL, d'utilisation de caractères interdits dans les noms de fichiers, d'ajout de fichiers très
volumineux, etc.
Par ailleurs, j'ai également testé le rendu de mon module Odoo, en m'assurant qu'il était correct quel
que soit le navigateur utilisé : Firefox, Chrome / Chromium, Internet Explorer, Opera et Safari.
L'application peut être testée en utilisant le jeu d'essai fourni lors de la création d'une nouvelle base
de données dans Odoo, en cochant la case « Charger les données de démonstration ».
46
Quelques précisions :
- l'installation de l'environnement réalisée le premier jour comprend l'installation et la configuration
de ma propre machine, mes machines virtuelles de test, ainsi que l'installation d'Odoo et de Maarch.
- aucune tâche n'a été programmée le 11 novembre qui est un jour férié.
- la partie « codage d'un client de test en Python » a consisté en la création d'un outil pour moi-
même qui me permettait de tester l'interaction avec les web services Maarch, tout en faisant
abstraction de la complexité d'Odoo.
Mon stage a été réalisé en autonomie. À chaque fin de semaine, j'ai rendu compte de mon travail à
mon tuteur, afin qu'il soit informé de l'avancée du projet d'une part, et qu'on puisse convenir
ensemble de la suite à donner la semaine suivante d'autre part. Cela a permis également d'être
toujours en phase sur les objectifs attendus d'un point de vue fonctionnel. Les différents jalons
symbolisés sur le diagramme par des losanges coïncident d'ailleurs avec ces réunions
hebdomadaires.
J'ai fait ressortir sur le planning deux phases majeures classiques : « analyse et conception » et
« développement ».
La phase de développement inclut les tests, réalisés en parallèle. Ainsi, chaque nouvelle
fonctionnalité implémentée était testée dans la foulée.
La phase d'analyse et conception comprend, de par la nature même de mon stage, un temps
important consacré à l'étude, la compréhension et l'apprentissage de l'existant. En effet, j'ai dû
découvrir les deux applications sur le plan fonctionnel. D'un point de vue technique, j'ai dû étudier
leur construction et leur logique et comprendre comment m'y intégrer intelligemment (coder un
module pour Odoo, ajouter un nouveau web service dans Maarch…). J'ai dû m'intéresser aussi aux
protocoles de communications existants : CMIS, SOAP… Enfin, à tout cela s'est ajouté
l'apprentissage du langage Python.
Au final le planning présenté ici a été respecté, même si certaines tâches n'ont pas été aussi
« figées » que le diagramme de Gantt le montre. Ainsi par exemple, l'apprentissage d'Odoo et
Maarch sur le plan technique s'est en réalité poursuivi tout au long du stage en fonction des besoins
ponctuels que j'ai eus.
XIV. Langues
Il a été décidé que le module serait développé en français uniquement. En effet le logiciel Maarch
est purement francophone, aussi un module non francophone pour s'interfacer avec Maarch aurait
peu d'intérêt.
En revanche, le code a été écrit en anglais, aussi bien d'un point de vue du nom des variables,
classes et méthodes que des commentaires explicatifs au sein du code.
Par ailleurs, la documentation technique que j'ai consultée tout au long du stage était principalement
en anglais, en particulier les documentations officielles de Python et de Odoo, qui n'ont pour
l'instant pas été traduites.
47
XV. Présentation et documentation
Une fois le module Odoo opérationnel, je l'ai présenté à l'équipe. Il est ressorti de la discussion que
son fonctionnement était simple et intuitif, ne nécessitant pas de documentation fonctionnelle
particulière (pour guider l'utilisateur, j'ai utilisé des placeholders sur les champs des formulaires et
des infobulles pour aider à la navigation).
J'ai en revanche consigné dans une documentation technique les ajustements à faire dans Maarch
pour que l'application puisse fonctionner, à savoir :
- les fichiers PHP à modifier
- les filtres de corbeilles à mettre en place.
XVI. Licence
Le code source a été placé sous licence AGPLv3 (Affero General Public License) pour le module
Odoo 8, et GPLv3 (GNU General Public License) pour le web service Maarch.
Ces 2 licences libres sont celles de Odoo 8 et Maarch respectivement. Elles mettent en œuvre le
principe du « copyleft », c'est-à-dire que les versions modifiées du programmes doivent être
également libres. La licence AGPL exige en plus que, si un programme modifié est exécuté sur un
serveur, celui-ci doit permettre de télécharger le code source de la version modifiée en
fonctionnement.
Ainsi chacun peut voir comment le code a été réalisé et peut s'en inspirer pour son propre projet. Le
code source est donc accessible à l'adresse :
https://github.com/kimory/maarchconnector
Les difficultés pour appréhender le code ont été particulièrement vraies pour celui de Maarch et ce
pour diverses raisons. Tout d'abord, il n'y a pas de séparation du code et de l'affichage : les balises
HTML, le CSS, le JavaScript ainsi que des images encodées en base 64 se retrouvent directement
au milieu des instructions dans les fichiers PHP. Cela rend la lecture du code lente et confuse, ce qui
est renforcé par des commentaires parfois peu présents, et un manque de cohérence jusque dans les
noms de fichiers (parfois en camelCase, parfois avec des underscores).
48
Les commentaires présents (certains en français, certains en anglais) n'aident pas forcément à la
compréhension du code :
Deux fonctions dans le même fichier peuvent avoir la même description, ce qui oblige à lire le code,
peu factorisé. Au-delà de ces aspects qui empêchent une compréhension intuitive du code, d'autres
éléments sont à déplorer, comme des requêtes SQL non préparées, du code de test à base de
var_dump non mis en commentaire dans le produit final, etc.
XVIII. Perspectives
Le module maarchconnector pourrait être amélioré en permettant que la taille maximale des fichiers
acceptée soit configurable, laissant le soin à l'entreprise d'ajuster cette taille selon ses besoins.
Actuellement, le mot de passe de connexion à Maarch est stocké en clair dans Odoo. Garder en
mémoire le mot de passe et pas seulement son empreinte est nécessaire car il est requis pour utiliser
les web services de Maarch. De plus lors de la connexion à Odoo, il serait assez contraignant pour
l'utilisateur de devoir saisir deux mots de passe.
Cependant il serait envisageable de chiffrer le mot de passe Maarch. Si chaque utilisateur du
module maarchconnector possède à terme un compte dans Maarch, on pourra par exemple étudier
les possibilités pour chiffrer le mot de passe Maarch avec le mot de passe du compte utilisateur
d'Odoo.
Enfin, il faudrait effectuer quelques ajustements pour rendre mon module compatible avec les
nouvelles versions des logiciels sorties tout récemment : la version 9 d'Odoo et la version 1.5.1 de
Maarch.
XIX. Bilan
Ce stage a été une expérience positive ! Ces quelques semaines m'ont donné l'occasion d'enrichir
mes compétences techniques, notamment en découvrant Python et les mécaniques d'un ERP.
Travailler sur des programmes existants aussi grands était une expérience nouvelle pour moi et je
suis contente d'avoir relevé le défi en produisant une application fonctionnelle, répondant au besoin
exprimé.
Le code étant libre, je pense continuer à travailler sur mon module par la suite pour l'enrichir,
comme indiqué dans la section « perspectives » notamment. De plus, le délai de 8 semaines étant
très court pour appréhender les deux applications, je ne peux pas prétendre aujourd'hui en avoir
saisi tous les mécanismes dans le détail. Je vais donc continuer à m'y intéresser, pour peut-être
optimiser encore mon application en conséquence.
49
XX. Références
J'ai consulté différents sites web en français et en anglais pour m'aider dans mon projet, parmi
lesquels :
Wikipédia, pour des informations diverses, sur les protocoles de communication notamment
https://en.wikipedia.org
50