Vous êtes sur la page 1sur 50

RAPPORT D'ACTIVITÉ

Julie NUGUET

Interfaçage des applications


Odoo et Maarch

Titre Professionnel Concepteur Développeur Informatique


(session janvier 2016)
Sommaire
I. Remerciements..................................................................................................................................3
II. Lexique............................................................................................................................................3
III. Abstract (in English).......................................................................................................................5
IV. Liste des compétences....................................................................................................................5
V. La société.........................................................................................................................................7
VI. Expression du besoin......................................................................................................................7
A. La demande.................................................................................................................................7
B. Présentation des 2 applications à interfacer................................................................................7
1. Odoo........................................................................................................................................8
2. Maarch....................................................................................................................................8
VII. Spécifications fonctionnelles........................................................................................................8
A. Diagrammes UML......................................................................................................................8
B. IHM...........................................................................................................................................12
C. Gestion des droits......................................................................................................................17
VIII. Spécifications techniques..........................................................................................................17
IX. Contraintes et règles métier..........................................................................................................18
X. Normes et conventions..................................................................................................................18
XI. Outils et environnement de travail...............................................................................................19
XII. Réalisation...................................................................................................................................20
A. Etude de l'existant.....................................................................................................................20
B. Manipulation des données.........................................................................................................21
1. Mécanismes d'Odoo..............................................................................................................21
2. Base de données Odoo..........................................................................................................24
3. Base de données Maarch.......................................................................................................24
C. Code source de l'application......................................................................................................26
1. Web service Maarch..............................................................................................................26
2. Architecture logicielle d'Odoo..............................................................................................29
3. Extraits du module Odoo......................................................................................................32
D. Rendu........................................................................................................................................39
E. Architecture de l'application......................................................................................................43
F. Tests...........................................................................................................................................44
XIII. Gestion de projet........................................................................................................................46
XIV. Langues......................................................................................................................................47
XV. Présentation et documentation....................................................................................................48
XVI. Licence......................................................................................................................................48
XVII. Difficultés rencontrées.............................................................................................................48
XVIII. Perspectives............................................................................................................................49
XIX. Bilan..........................................................................................................................................49
XX. Références...................................................................................................................................50

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.

GED : Gestion Électronique de documents. Système permettant de gérer numériquement le


stockage, le classement et la consultation des documents, facilitant ainsi la recherche
d'informations. Les documents traités peuvent provenir de documents « électroniques » (fichiers
PDF, e-mails...), ou de documents « papiers » via un scanner par exemple.

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.

IV. Liste des compétences

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.

TeMPO Consulting commercialise notamment le système de gestion de courriers Maarch, et l'ERP


Odoo qu'ils personnalisent avec des développements spécifiques en fonction des demandes des
clients. Parmi eux, on compte l'Ecole Nationale d'Administration, le Pôle d'Archéologie
interdépartemental rhénan, ou encore Médecins sans frontières.
Le fonctionnement de TeMPO se base sur une méthodologie Agile. Ainsi, le développement des
solutions se décomposent en plusieurs phases permettant d'atteindre l'objectif défini de manière
itérative et progressive, en impliquant fortement le client.

VI. Expression du besoin

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 ».

B. Présentation des 2 applications à interfacer


Afin de comprendre l'objectif de mon stage, il est nécessaire de s'intéresser au fonctionnement
d'Odoo et de Maarch. C'est pourquoi vous trouverez dans cette section une brève présentation des
deux outils.

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.

VII. Spécifications fonctionnelles


Vous trouverez dans cette section les spécifications fonctionnelles définies en amont de la phase de
la codage.

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.

L'ensemble des cas d'utilisation présentés se passent « côté Odoo ».

Note : tous ces cas


d'utilisation impliquent
d'être authentiié

ajouter dans Odoo


un document local «extends» ajouter le document
dans Maarch

Utilisateur
ajouter dans Odoo «includes» rechercher un document
un document Maarch dans Maarch

gérer les conigurations

Administrateur

L'utilisateur peut ajouter dans Odoo :

- 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

* une iche peut être de n'importe


quelle nature (ex. facture N°XYZ ou se rendre sur
article N°1234) une iche*

cliquer sur ajouter


une pièce jointe

contrôler si un serveur
Maarch est activé

[pas de serveur Maarch activé]

[serveur Maarch activé]

vériier si la
coniguration est OK

[coniguration OK] [coniguration erronée]

sélectionner le sélectionner le
document à ajouter document à ajouter

aicher un message
d'erreur explicite
indiquer l'objet du
document pour Maarch

ajouter dans Odoo


et dans Maarch

ajouter dans Odoo


uniquement

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.

:Utilisateur :Recherche :Coniguration

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 :

Toutes les actions (Création ou Édition


d'une coniguration, Recherche...) peuvent
être "annulées", impliquant un retour à
Clic sur "Créer" Invitation à créer l'état précédent.
une coniguration

Création d'une Le clic sur "Connecteur Maarch"


coniguration Clic sur "Créer" dans le menu principal peut se
faire à tout moment du processus.
Clic sur "Connecteur Maarch"
[ nombreConigurationsExistantes = 0 ]
Validation

Visualisation d'une Clic sur une Visualisation des Clic sur "Connecteur Maarch" Visualisation page
coniguration coniguration conigurations [ nombreConigurationsExistantes > 0 ] d'accueil de l'ERP

Validation Clic sur "Modiier"


Sélection d'une iche
Validation

Édition d'une Choix de l'objet Clic sur "Ajouter..."


coniguration du document pour Maarch
Consultation de iche

  Sélection des documents Clic sur "Ajouter depuis Maarch..."


  à ajouter depuis Maarch

  Recherche sur le serveur


Recherche

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).

C. Gestion des droits


Les utilisateurs doivent avoir un accès en lecture seule au module. En effet, ils doivent pouvoir
utiliser les fonctionnalités apportées. En revanche, ils n'ont pas de raison de devoir ajouter, modifier
ou supprimer une nouvelle configuration de serveur Maarch.

Les autres droits : écriture, création et suppression sont réservés à l'administrateur.

VIII. Spécifications techniques


Le projet se basant sur des applications déjà existantes, les langages utilisés pour le réaliser sont
ceux des deux logiciels concernés :
- Python 2.7 pour la partie « Odoo »
- PHP 5.4 pour la partie « Maarch ».
Du JavaScript est utilisé en complément.

Il faut utiliser les bases de données existantes sous PostgreSQL, version 9.1.12 pour Maarch et 9.4.5
pour Odoo.

Les applications doivent fonctionner sous Linux.

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.

Format de description CMIS


CMIS, Content Management Interoperability Services, désigne un standard de description de
données disponibles sur un serveur, permettant à deux serveurs d'échanger du contenu.
Le modèle de données décrit les différents types de contenus accessibles sur un serveur : les
répertoires et les fichiers, ainsi que leurs attributs.

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.

IX. Contraintes et règles métier


L'application devra respecter la charge graphique d'Odoo.

Par ailleurs, on appliquera les règles suivantes :


– une seule configuration de serveur Maarch peut être activée à la fois.
– chaque configuration de serveur doit avoir un nom unique.
– l’adresse du serveur Maarch doit être une URL commençant par http ou https.
– lors de la recherche d'un document Maarch, l'utilisateur doit visualiser un message d'avertissement
s’il tente de rechercher un document émis dans le futur. On souhaite rester « souples », aussi le
message aura un simple but d'alerte, il n'empêchera pas d'effectuer la recherche.
– la date proposée par défaut lors de la recherche doit être « un an avant » afin d'éviter de charger
un trop grand nombre de résultats alors que les documents à ajouter en pièces jointes sont souvent
récents.
- la taille maximum de fichiers acceptée est de 20 Mio.

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

Les noms de fonctions sont en minuscules et utilisent l'underscore comme séparateur, ex :


get_maarch_client()

Les noms de variables sont en minuscules avec underscores, ex :


maarch_client
Les variables désignant un modèle font exception et sont construites en CamelCase, ex :
IrAttachment = self.env['ir.attachment'];

Les méthodes sont également en minuscules avec underscores.


De plus, les méthodes appelées à la modification d'un champ de formulaire commencent par le
préfixe _on_change, ex :
_on_change_min_date()
qui vérifie que la date à partir de laquelle le document a été émis ne se situe pas dans le futur.

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")

Enfin, les champs « Many2One » ont le suffixe _id, par exemple :


documentwizard_id = fields.Many2one('maarch.search', readonly=True)

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.

XI. Outils et environnement de travail


J'ai réalisé l'application dans un environnement Linux. J'ai installé moi-même mon environnement
de travail : une machine locale sous Xubuntu 14.04, qui est un dérivé de la distribution Ubuntu
(l'environnement graphique par défaut est différent). Il s'agit de la dernière version « Long Term
Support » qui était déjà sortie depuis un an et demi ce qui permet d'être plus confiant sur sa stabilité,
les différents problèmes liés au lancement d'une version ayant été corrigés depuis. De plus, Odoo
est principalement déployé sous l'OS Ubuntu chez les clients.
J'ai également configuré des machines virtuelles de test sous Debian notamment, sur lesquelles j'ai
installé Odoo, Maarch, et PostgreSQL. J'ai placé ces machines sur un SSD pour améliorer la
réactivité de mon environnement de test.

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.

B. Manipulation des données


Cette section regroupe tout ce qui à trait au SQL dans Odoo et dans Maarch. J'y présente les
mécanismes d'interaction avec les bases de données que j'ai utilisés, ainsi que les relations entre les
tables que j'ai dû appréhender.

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.

Voici une modélisation simplifiée des tables :

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.

3. Base de données Maarch


Pour rechercher une pièce jointe à ajouter sur une entité Odoo, il faut pouvoir effectuer une
recherche de documents côté Maarch, ce qui implique l'étude de la base de données de Maarch.
Les critères de recherche retenus sont :
- l'objet du courrier ;
- la date à partir de laquelle il a été émis ;

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 ».

Nous avons ensuite deux cas de figure :

– 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 ».

– soit le contact est externe, alors « dest_contact_id » ou « exp_contact_id » comportera


l'identifiant du contact externe : celui de la table « contact_v2 ». Dans cette table, si
« is_corporate_person » vaut « Y » alors il s'agit d'une entreprise, on récupérera son nom et
acronyme éventuel via les colonnes « society » et « society_short ». À l'inverse, si
« is_corporate_person » vaut « N », il s'agit alors d'un particulier et on récupérera son prénom et son
nom 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

1. Web service Maarch


Cette section présente le code réalisé pour créer le web service de recherche d'un document dans
Maarch.

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 fonction créée « searchDocuments » est définie comme suit :

Les paramètres en entrée (« in ») sont de type « searchDocumentsParams », un type complexe que


j'ai défini, de même pour le résultat (« out ») qui est de type « searchDocumentsResults ».
Les paramètres sont définis dans un tableau associatif représentant le nom du paramètre et son type,
voici par exemple les paramètres d'entrée :

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.

Enfin, on filtre le résultat par contact avant de le renvoyer :

2. Architecture logicielle d'Odoo


J'ai codé mon module Odoo en respectant les normes de cet ERP.

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).

De même, les conventions d'Odoo impliquent que l'on retrouve :


- un attribut _name (préfixé d'un underscore) qui correspond au nom du modèle lui-même. C'est ce
nom qui identifie de manière unique le modèle, lui permettant d'être utilisé ailleurs dans le code.
- l'attribut name (sans underscore) qui désigne le nom de l'objet lui-même, par exemple ici le nom
de la configuration. La recherche d'un élément dans Odoo se fait par défaut sur ce champ « name ».
- sql_constraints qui est une liste contenant les contraintes SQL que le champ doit respecter (ici le
nom de la configuration doit être unique).
- les méthodes commençant par « _onchange » et « _check » correspondant à des vérifications
effectuées sur les champs : dès qu'une valeur est modifiée pour l'un, à la validation du formulaire
pour l'autre. On constate là aussi que le modèle MVC n'est pas totalement respecté, les tests à la
validation du formulaire étant effectués dans le modèle et non dans le contrôleur.

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.

- le dossier security contient un fichier csv définissant la politique de sécurité du module.


J'y ai indiqué que tous (all) avait le droit de lecture (« perm_read » à « 1 »), les autres droits étant
réservés uniquement à l'administrateur.

On trouve également les fichiers suivants :

- __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.

3. Extraits du module Odoo

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.

Voici un exemple d'appel Ajax côté JavaScript :

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 :

Le langage Python ne possède pas d'instruction « switch ». Pour récupérer la dénomination de la


catégorie je simule le comportement d'un switch en utilisant un dictionnaire, la clé correspondant au
code Maarch, et la valeur à la description sémantique. Le deuxième paramètre passé à « get » (ici
« - ») est la valeur par défaut si la clé (short_name) n'est pas trouvée, ce qui correspond au
« default » pour un switch.

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 indique le modèle utilisé « maarchconnector.configuration », ce qui fait référence à la classe


Python qui hérite de openerp.models.Model, ainsi que le nom des champs. Le type de champ n'est
pas requis puisqu'il est déjà indiqué dans le modèle. On peut cependant personnaliser le rendu, en y
ajoutant des attributs comme « password » pour que les caractères saisis ne soient pas affichés ou
« colspan » pour positionner les éléments.

Voici la vue correspondant à la liste des différentes configurations disponibles de Maarch :

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

Stockage des documents Système de ichiers


Côté Maarch

Récupération des documents

WebService Maarch
viewResource
Récupération de documents Maarch par id
Récup. informations sur les documents

Chaque rond symbolise un service fourni.

Trois web services Maarch sont utilisés :


- searchDocuments permet de lire en base de données pour faire la recherche de documents selon
différents critères,
- storeResource enregistre les données sur le disque (système de fichiers) et les métadonnées dans la
base de données Maarch,
- viewResource récupère, à partir de son id, le fichier lui-même sur le disque et les informations sur
le fichier dans la base de données.

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.

Linux Ubuntu Server

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.

Si le test se passe mal, on verra alors ceci :

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 ».

XIII. Gestion de projet


Une contrainte importante pour le projet a été le temps disponible pour le réaliser : 8 semaines.
Dès le début, j'ai défini un planning afin d'avoir des repères. Voici mon planning sous forme de
diagramme de Gantt. Il a été scindé en trois uniquement par souci de lisibilité pour ce rapport, il
s'agit bien d'un seul et même projet de 8 semaines.

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

XVII. Difficultés rencontrées


La difficulté principale de mon stage est liée à sa courte durée (8 semaines), ce qui a impliqué de
devoir comprendre rapidement Odoo et Maarch sur le plan technique, en appréhendant notamment
les frameworks qui leur sont propres. Comme indiqué auparavant, ces deux applications ont une
base de code importante, et je n'étais pas habituée à travailler sur des programmes de cette taille. De
plus, j'ai dû apprendre le langage Python que je ne connaissais pas du tout.

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.

C'est en tout cas avec plaisir que je replongerai dans le projet !

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 :

python.org, le site officiel du langage Python


https://www.python.org

PHP.net, le site de référence sur le langage PHP


http://php.net

Odoo doc, la documentation officielle d'Odoo


https://www.odoo.com/documentation/8.0

Maarch wiki, le wiki officiel de Maarch


http://wiki.maarch.org

Les spécifications du protocole CMIS


http://docs.oasis-open.org/cmis/CMIS/v1.1/CMIS-v1.1.pdf

stackoverflow.com, une plateforme d'échanges sur des questions de programmation


http://stackoverflow.com

Wikipédia, pour des informations diverses, sur les protocoles de communication notamment
https://en.wikipedia.org

50

Vous aimerez peut-être aussi