Réalisations
Captures et démonstrations issues des projets réels.

Liste de modules métier développés
Vue d'ensemble de modules Odoo réalisés pour couvrir des besoins comptables, commerciaux, logistiques et B2B.
01
Cette réalisation regroupe les 16 modules Odoo que j'ai développés en interne chez 1UP Distribution. Les présenter comme 16 réalisations indépendantes multiplierait artificiellement les projets alors qu'ils appartiennent au même ensemble : ils prolongent l'ERP pour lui permettre de représenter les règles, les données et les automatisations propres à l'entreprise. Un module Odoo est une extension logicielle installable qui peut ajouter des modèles de données, modifier des écrans, introduire des traitements Python ou dépendre d'autres applications. Les modules ne sont donc pas isolés. Certains héritent des fonctions d'un autre module, partagent des champs ou se combinent pour former un processus plus large. Leur valeur se comprend à l'échelle de cette couche métier commune plutôt qu'en comptant chaque dossier de code comme un projet séparé.
Avant ces développements, les équipes essayaient de résoudre une partie de leurs problèmes directement dans Odoo Studio. Cet outil permet de créer des champs, de modifier une vue ou d'ajouter certaines automatisations depuis une interface visuelle. Il convient aux adaptations simples, mais les besoins non triviaux atteignaient rapidement ses limites. Un besoin est non trivial lorsqu'il impose des règles conditionnelles complexes, des calculs, des échanges entre plusieurs applications ou un comportement que la configuration standard ne sait pas exprimer. Ces situations nécessitaient du Python sur mesure pour la logique exécutée par le serveur et du XML pour décrire ou étendre les écrans, les données de configuration et les rapports. Mon travail a consisté à transformer ces problèmes métier en extensions intégrées au fonctionnement normal d'Odoo, plutôt qu'en solutions extérieures difficiles à relier à l'ERP.
Les modules peuvent concerner tous les services selon le besoin : comptabilité, ventes, administration des ventes, achats, logistique, inventaire ou direction. Leur effet dépasse parfois le demandeur initial. Une donnée produit ajoutée pour la logistique peut ensuite être utilisée par un rapport commercial, envoyée au site B2B ou intégrée dans un calcul de stock. Cette propagation vient du mécanisme d'héritage d'Odoo : un module peut compléter un modèle ou une application existante, puis d'autres composants réutilisent le résultat. Il faut donc comprendre les dépendances fonctionnelles et techniques avant de modifier une information. Une évolution apparemment locale peut améliorer plusieurs processus, mais elle peut aussi produire une régression dans un service qui n'a pas participé à la demande initiale.
Ce module répond à un besoin de la comptabilité : repérer les factures dont la date d'échéance est dépassée et organiser leur relance. Une facture impayée est une facture arrivée à échéance sans que le règlement attendu ait été enregistré. La première version notifiait les utilisateurs internes d'Odoo afin qu'ils puissent intervenir. À partir des retours du service, le fonctionnement a évolué vers l'envoi automatisé de courriels de relance, ce qui remplace une partie des vérifications et messages manuels auparavant réalisés par la comptabilité. Le module illustre la nature évolutive de cette réalisation : le développement initial ne fige pas le processus, il fournit une base versionnée qui peut être adaptée lorsque l'usage réel révèle un besoin plus efficace.
Ce module centralise notamment des adaptations de documents PDF utilisés dans les applications Ventes, Comptabilité et Inventaire. Odoo produit ces documents avec QWeb, un moteur de modèles qui combine une structure HTML/XML avec les données de l'ERP avant de générer le PDF. Les documents concernés comprennent par exemple les factures pro forma et les bons de livraison. Une facture pro forma est un document commercial provisoire qui présente les conditions d'une vente avant la facture comptable définitive ; un bon de livraison décrit les produits remis ou expédiés au client. Les rapports standard ne contenaient pas toutes les informations nécessaires aux clients ou aux équipes internes. J'ai donc ajouté les champs, conditions d'affichage et mises en page adaptés afin que les documents imprimés deviennent réellement exploitables dans les opérations quotidiennes.
L'application Inventaire standard ne représentait pas toutes les caractéristiques nécessaires à l'activité de l'entreprise. Ce module ajoute des données et des automatisations autour des produits : poids, dimensions, conditionnement, gamme, présence d'une batterie ou de piles et informations utilisées pour le colisage. Le colisage décrit la manière dont les produits sont répartis dans un ou plusieurs colis pour leur préparation et leur expédition ; le conditionnement décrit la forme sous laquelle un produit est regroupé ou emballé. Ces informations peuvent influencer la logistique, les documents, les règles de transport et les systèmes connectés. Les centraliser dans Odoo évite que chaque service maintienne sa propre version de la donnée et permet aux automatisations de travailler à partir d'une référence commune.
Ma règle de décision commence par vérifier si Odoo propose déjà la configuration nécessaire. Lorsque c'est le cas, je l'utilise et je ne développe pas une seconde solution. Si le besoin exige une personnalisation, j'évalue ensuite ce que Studio enregistrerait dans la base. Modifier une vue avec Studio crée par exemple une vue héritée et une expression XPath chargée de cibler la partie modifiée. Pour les adaptations durables de l'entreprise, je préfère déclarer cet héritage dans un module et le versionner dans le dépôt GitHub. Le versionnement conserve l'historique des changements, rend les différences relisibles, permet de reproduire la personnalisation dans plusieurs environnements et facilite son analyse lors d'une migration. Ce choix demande plus de rigueur au moment du développement, mais il est nettement plus maintenable qu'une accumulation de changements techniques dispersés dans la base.
J'ai commencé à développer ces modules trois à quatre mois après le début de mon alternance et je les ai maintenus sur toutes les versions d'Odoo traversées, y compris après la migration vers Odoo 19. Le point de départ est généralement une discussion avec un service qui souhaite améliorer ou automatiser un processus. Je reformule le besoin, vérifie les fonctions déjà présentes dans Odoo et détermine si un développement est justifié. Lorsque la demande touche à la sécurité ou aux droits d'accès, je demande d'abord la validation de ma responsable directe. Une fois ce cadre confirmé, je travaille en autonomie complète : conception, développement en Python et XML, tests, documentation, mise en production puis maintenance à partir des retours utilisateurs. La réalisation désigne ainsi autant les modules produits que la capacité à gérer leur cycle de vie dans la durée.
02
Le premier objectif était de rendre Odoo plus adapté au travail réel des équipes. L'expérience utilisateur, souvent abrégée UX pour User Experience, désigne la facilité avec laquelle une personne comprend l'interface, trouve l'information utile et accomplit sa tâche sans friction inutile. Une fonctionnalité pouvait déjà exister dans l'ERP tout en restant peu efficace si les données importantes étaient absentes, dispersées ou présentées sur un écran différent. Les modules devaient donc enrichir les vues, les documents et les traitements avec des informations directement pertinentes pour le service concerné. L'objectif n'était pas d'ajouter le plus grand nombre possible de champs, mais de montrer la bonne donnée au bon moment et d'éviter aux utilisateurs de la rechercher dans plusieurs écrans ou fichiers.
Le deuxième objectif était de supprimer les opérations répétitives qui pouvaient être réalisées sans jugement humain. Un processus entièrement automatisable est une suite d'actions dont les règles, les données d'entrée et le résultat attendu peuvent être définis suffisamment précisément pour être exécutés par le logiciel. L'automatisation devait libérer du temps sans retirer aux équipes les décisions qui nécessitent une appréciation métier. Elle pouvait détecter une situation, calculer une valeur, préparer une information ou envoyer un message lorsque toutes les conditions étaient vérifiées. Cette frontière était importante : automatiser une règle claire améliore la régularité, tandis qu'automatiser une décision encore ambiguë risque seulement de reproduire plus vite une mauvaise interprétation.
Avant le module 1up_invoice_overdue_alert, la comptabilité devait parcourir les factures clients et examiner leurs conditions de paiement afin de déterminer lesquelles étaient réellement en retard. Les conditions de paiement précisent notamment la ou les dates auxquelles le montant d'une facture devient exigible. L'identification des impayés puis la préparation des relances étaient donc entièrement manuelles. Cette méthode consommait du temps et dépendait de la régularité avec laquelle une personne reprenait la liste. Une facture pouvait ne pas être relancée au moment prévu simplement parce qu'elle n'avait pas été repérée au cours de la vérification. Le module devait transformer ces données déjà présentes dans Odoo en un processus de suivi systématique.
Pour la comptabilité, le résultat attendu était double. Le premier gain concernait le temps : l'identification et l'envoi des relances représentaient plusieurs heures de travail chaque semaine. Le second concernait la régularité : une automatisation applique les mêmes critères à toutes les factures et ne dépend pas de la mémoire ou de la disponibilité ponctuelle d'un utilisateur. En réduisant les oublis, l'entreprise cherchait aussi à diminuer les retards de paiement. Le module ne garantit pas qu'un client règlera sa facture, car cette décision reste extérieure à l'ERP, mais il garantit que les situations correspondant aux règles définies sont détectées et prises en charge de manière plus constante.
Les documents imprimés devaient contenir toutes les informations nécessaires sans obliger les équipes à effectuer une recherche complémentaire. Il manquait notamment des données liées aux taxes et aux transporteurs, des notes destinées aux équipes logistiques ainsi que des consignes relatives aux conditions de livraison chez le client. Avant l'adaptation des rapports, une personne devait retrouver ces informations ailleurs puis, dans certains cas, les noter manuellement sur le document. Ce fonctionnement augmentait le temps de préparation et le risque d'oubli ou de transcription incorrecte. Le module 1up_specifique devait faire du PDF une représentation complète et directement exploitable de l'opération, aussi bien pour le client que pour les équipes internes.
Les objectifs de 1up_product_extension étaient centrés sur le travail de la logistique. Les poids, dimensions, conditionnements, règles de colisage et informations relatives aux piles ou aux batteries participent à la manière dont un produit doit être préparé, regroupé et expédié. Lorsque ces données ne sont pas structurées dans l'ERP, l'équipe doit les connaître de mémoire, les rechercher ou les recalculer. Les champs ajoutés créent une référence commune et les automatisations utilisent cette référence pour réduire les manipulations. Le module devait ainsi simplifier les opérations de préparation, améliorer la cohérence des données produit et limiter les écarts entre la fiche gérée dans Odoo et la réalité du colis traité par l'équipe.
Les demandes provenant de plusieurs services ne pouvaient pas toutes être développées immédiatement. J'évaluais leur priorité à partir de quatre critères principaux : le caractère bloquant du problème, le temps perdu dans l'état actuel, l'existence d'un quick win et l'impact financier. Un quick win est une amélioration rapide à mettre en œuvre par rapport au bénéfice qu'elle apporte. Une demande courte pouvait donc passer avant un chantier plus vaste si elle supprimait immédiatement une tâche répétitive importante. À l'inverse, un problème qui empêchait un service de travailler ou qui faisait perdre de l'argent devenait prioritaire même si sa résolution était plus complexe. Cette méthode reliait l'ordre du développement à la valeur attendue pour l'entreprise plutôt qu'à la seule date de la demande.
03
Le risque le plus sensible concernait les droits d'accès. Un commercial m'a par exemple demandé de consulter les factures de ses clients ainsi que l'application Achats. Une facture peut contenir des prix, des conditions commerciales, des coordonnées et d'autres informations qui ne doivent pas être ouvertes à tous les utilisateurs. L'application Achats donne également accès à des données concernant les fournisseurs et les coûts de l'entreprise. Comme les droits Odoo se combinent par groupes et peuvent être affinés par des règles d'enregistrement, une autorisation trop large pouvait exposer beaucoup plus de données que celles nécessaires à la demande. J'ai donc demandé la validation de ma responsable avant de mettre en place un accès strictement limité au périmètre autorisé par la direction.
L'automatisation des impayés pouvait produire un effet négatif si les règles étaient inexactes. Une facture déjà réglée, faisant l'objet d'un litige ou associée à un contact incorrect ne devait pas déclencher le même message qu'un retard confirmé. Une relance erronée pouvait dégrader la relation commerciale et transmettre des informations comptables à une personne non concernée. Les conditions de déclenchement, le destinataire, le contenu du courriel et l'état de la facture après traitement devaient donc être vérifiés avec la comptabilité. Le gain de temps n'était acceptable que si l'automatisation restait plus fiable que la tâche manuelle qu'elle remplaçait.
Les rapports QWeb affichent des données qui peuvent influencer la compréhension d'une vente, d'une taxe, d'un transport ou d'une livraison. Un mauvais champ, une condition d'affichage incorrecte ou un calcul mal repris pouvait créer un document incohérent avec l'enregistrement Odoo. Le client ou l'équipe interne risquait alors de prendre une décision à partir d'une information fausse. Les factures et les données fiscales exigeaient une vigilance particulière, car une erreur ne relevait plus seulement de la présentation du PDF. La maîtrise du risque consistait à comparer le document généré avec les données sources et à faire valider le résultat par les utilisateurs qui connaissent le processus concerné.
Une donnée produit incorrecte dans 1up_product_extension pouvait conduire à un mauvais colisage, à l'oubli d'une contrainte liée à une batterie ou à une préparation inadaptée. Comme ces informations peuvent être réutilisées par des automatisations et des outils externes, une seule erreur de référence pouvait se propager au-delà de l'écran où elle avait été saisie. Les champs devaient donc être définis sans ambiguïté, leurs valeurs contrôlées sur des produits représentatifs et leurs effets vérifiés jusqu'à l'opération logistique. Le module devait simplifier le travail de l'équipe sans remplacer un problème manuel par une erreur automatisée plus difficile à repérer.
Un module personnalisé s'exécute dans la même application que les fonctions standard d'Odoo. Une recherche trop large, un calcul répété inutilement ou une automatisation déclenchée sur un grand nombre d'enregistrements pouvait ralentir un écran, une tâche planifiée ou l'ensemble du serveur. Ce risque augmente lorsqu'un traitement paraît rapide sur quelques données de test mais doit ensuite parcourir le volume réel de la production. Je devais donc vérifier le comportement fonctionnel tout en restant attentif au nombre d'enregistrements traités, à la fréquence d'exécution et aux opérations de base de données. Une fonctionnalité correcte mais trop coûteuse aurait dégradé l'expérience de tous les utilisateurs.
Les extensions reposent sur l'héritage et partagent certains modèles. Une modification développée pour un service pouvait donc changer le comportement d'une vue, d'une méthode ou d'un champ utilisé ailleurs. Le risque ne se limitait pas au nouveau code : il fallait aussi vérifier que les processus existants continuaient à fonctionner. Le versionnement permettait d'identifier précisément les changements, mais il ne remplaçait pas les essais. Avant chaque mise en production, je testais le module sur une instance dédiée, c'est-à-dire un environnement séparé de la production dans lequel les erreurs n'affectent pas le travail réel des équipes.
Une solution peut fonctionner sans répondre correctement au problème initial. Le demandeur peut omettre une exception, employer un terme différent de celui utilisé dans Odoo ou découvrir son véritable besoin seulement en manipulant une première version. Pour limiter ce risque, les utilisateurs concernés devaient tester la fonctionnalité et confirmer que le comportement correspondait à leurs attentes. Cette validation ne portait pas uniquement sur l'absence d'erreur : elle vérifiait que l'information était compréhensible, que le processus était réellement plus simple et que les exceptions importantes avaient été prises en compte.
Je considérais un module prêt lorsque trois niveaux de validation étaient réunis. Premièrement, le build de préproduction devait se terminer sans erreur : le build est la construction et le démarrage de l'application avec la nouvelle version du code. Deuxièmement, aucune erreur d'exécution, ou erreur runtime, ne devait apparaître pendant l'utilisation ; une erreur runtime survient lorsque le programme démarre correctement mais échoue au moment d'une action précise. Troisièmement, les utilisateurs concernés devaient avoir testé la fonctionnalité et confirmé qu'elle répondait au besoin. La réunion de ces critères techniques et métier réduisait le risque de déployer une solution installable mais inutilisable dans les conditions réelles.
04
Le module de relance des impayés est parti d'une demande directe du service comptable. Les utilisateurs m'ont expliqué ce qu'ils souhaitaient améliorer, mais aussi la manière dont ils travaillaient avant toute automatisation : consultation des factures, lecture des conditions de paiement, identification des échéances dépassées puis relance manuelle. Cet échange était indispensable, car une demande formulée uniquement comme « automatiser les relances » aurait masqué les nombreuses exceptions du processus. La comptabilité m'a notamment signalé que certains clients ou certaines factures ne devaient pas être relancés par l'entreprise lorsqu'ils relevaient de l'affacturage. L'affacturage consiste à céder une créance à un organisme financier, appelé factor, qui peut avancer les fonds et prendre en charge tout ou partie du recouvrement. Envoyer en parallèle une relance standard aurait donc pu être incohérent avec ce circuit.
À partir des explications de la comptabilité, j'ai repris le déroulement étape par étape : quelles factures étaient examinées, comment leur date d'échéance était déterminée, quels contacts devaient recevoir un message et quelles situations imposaient au contraire de ne rien envoyer. Cette analyse du fonctionnement réel m'a permis de distinguer la règle générale des cas particuliers. Elle évitait de reproduire automatiquement une vision trop simplifiée du processus. Mon rôle ne consistait donc pas uniquement à écrire du code, mais à traduire un raisonnement comptable en conditions suffisamment précises pour qu'un programme puisse l'exécuter sans interprétation humaine à chaque facture.
J'ai retranscrit les explications dans un ticket Jira, c'est-à-dire une fiche de suivi centralisant le problème, le travail à réaliser et son état d'avancement. J'y ai ajouté des sous-tâches pour découper le développement, les processus de test à reproduire et les critères d'acceptation. Un critère d'acceptation décrit un résultat observable qui doit être vérifié pour considérer la fonctionnalité comme conforme. Cette formalisation me servait de référence pendant le développement et limitait le risque d'oublier une exception mentionnée oralement. Elle permettait également à la comptabilité de comparer le comportement livré avec ce qui avait été convenu.
J'ai recensé les informations qui déterminent si une relance doit être déclenchée : les conditions de paiement, le type de client, le compte bancaire destinataire du règlement et les choix définis par la comptabilité. Les conditions de paiement fixent la date ou les différentes dates auxquelles une facture devient exigible ; elles permettent donc de calculer le nombre de jours de retard. La configuration générale précise notamment les délais de relance, les modèles de courriel à employer et le rapport de facture à joindre. Des réglages propres au client complètent ces règles : destinataires supplémentaires, exclusion explicite des relances, facture liée à l'affacturage ou utilisation d'un compte bancaire pour lequel le traitement doit être différent. Ce recensement a constitué la matrice fonctionnelle du module.
Dans la première version, une action planifiée était exécutée chaque jour. Une action planifiée, souvent appelée cron, est une tâche lancée automatiquement par le serveur selon une fréquence définie, sans qu'un utilisateur ait besoin de cliquer sur un bouton. Le traitement parcourait les factures concernées, calculait leur position par rapport à l'échéance et repérait les paliers du jour de l'échéance, puis de trois, sept ou quatorze jours de retard. Lorsqu'une situation correspondait aux règles, le module notifiait les membres du groupe Comptabilité ainsi que le commercial rattaché à la facture. Cette première étape automatisait la détection tout en conservant une intervention humaine pour la relance adressée au client.
Les retours d'usage ont montré que la logique devait être plus configurable et aller au-delà d'une notification interne. J'ai donc fait évoluer le module afin que la comptabilité puisse déterminer directement dans Odoo les personnes à notifier, les délais à appliquer, le modèle de courriel utilisé et le document de facture joint au message. Elle peut également définir après combien de jours un client doit être bloqué, afin d'empêcher la poursuite normale de certaines opérations lorsque le retard devient trop important. La majorité de ces valeurs était auparavant codée en dur, ou hardcoded : toute modification exigeait alors de changer le code et de redéployer le module. Leur déplacement vers les paramètres de l'ERP a rendu le comportement adaptable par les utilisateurs autorisés sans intervention technique pour chaque changement de règle.
Un module Odoo comporte toujours un fichier « __manifest__.py », appelé manifeste, qui le déclare auprès de l'ERP et décrit notamment son nom, sa version, ses dépendances et les fichiers de données à charger. Comme le module est aussi un paquet Python, les fichiers « __init__.py » servent à importer les sous-paquets contenant du code. Le reste de la structure dépend du besoin. Le dossier « models » contient la logique Python et les objets métier enregistrés dans la base ; « views » décrit en XML les formulaires, listes et écrans ; « security » déclare les droits d'accès ; « data » peut créer des paramètres, modèles de courriel ou actions planifiées ; « report » contient les rapports QWeb ; des assistants, contrôleurs web ou tests peuvent être ajoutés si la fonctionnalité l'exige. Enfin, des scripts de migration ne sont nécessaires que lorsqu'une nouvelle version doit transformer des données ou adapter une structure déjà installée. Je n'ajoute donc pas tous ces dossiers mécaniquement : je sélectionne les composants qui matérialisent réellement le besoin métier.
La partie Python portait la logique de sélection des factures et l'application des conditions de relance, tandis que les déclarations XML rendaient disponibles les paramètres, les écrans et l'action planifiée nécessaires. J'ai séparé autant que possible les valeurs configurables de l'algorithme : le code définit comment appliquer une règle, tandis que la comptabilité décide par exemple du délai ou du modèle de message. Cette séparation réduit le nombre de modifications techniques et évite de dupliquer une version du programme pour chaque cas. Elle facilite aussi la maintenance, car une évolution de politique comptable peut souvent être appliquée dans l'interface sans altérer le mécanisme central.
J'ai vérifié sur la préproduction les différents embranchements du processus : facture qui n'a pas encore atteint son échéance, facture correspondant à chacun des paliers, client explicitement ignoré, facture relevant de l'affacturage, compte bancaire particulier, destinataires additionnels, modèle de courriel sélectionné, pièce jointe attendue et seuil de blocage. Le staging est une copie isolée servant à tester le nouveau code avec des données représentatives sans modifier la production. Odoo.sh y neutralise les courriels sortants et les intercepte avec un mail catcher. Cet outil permet de consulter le destinataire, l'objet, le contenu et les pièces jointes du message comme s'il avait été envoyé, tout en empêchant qu'un vrai client reçoive une relance issue d'un test.
La comptabilité a testé le module, car elle était la mieux placée pour détecter une règle techniquement valide mais incorrecte dans la pratique. Ses retours ont notamment confirmé la nécessité de rendre le fonctionnement configurable et de traiter les cas limites, ou edge cases. Un cas limite est une situation moins fréquente située en dehors du parcours habituel, mais dont le mauvais traitement peut avoir des conséquences importantes. Les échanges ont conduit à reprendre les paramètres, à ajuster les exceptions puis à rejouer les scénarios concernés. La validation ne se limitait donc pas à l'absence d'erreur : elle portait sur la justesse de la décision prise pour chaque facture.
Une fois le build de préproduction sans erreur, les tests terminés et la validation métier obtenue, la branche de staging était fusionnée avec la branche de production. Odoo.sh lançait alors un rebuild : la plateforme reconstruisait l'environnement avec la nouvelle révision du dépôt Git, redémarrait Odoo et mettait à jour le code exécuté en production. Lorsque la version du module ou la transformation des données le nécessitait, les scripts de migration associés étaient également exécutés. Ce processus rend le déploiement reproductible : la production reçoit le code versionné et testé, plutôt qu'une succession de modifications manuelles impossibles à retracer.
Après le déploiement, j'ai documenté les changements au moyen de guides et de notes de version. Une note de version, ou release note, résume les nouvelles fonctions, les corrections et les éventuels changements d'utilisation d'une livraison. J'ai également présenté au service comptable la manière de paramétrer le module et d'utiliser ses différentes fonctionnalités. Le passage d'une simple notification interne à des relances automatisées et configurables illustre ensuite la maintenance continue : le premier développement répondait au besoin initial, puis l'observation de l'usage et les retours de la comptabilité ont permis d'en faire un outil plus autonome. Cette évolution conserve une responsabilité humaine sur les règles tout en supprimant l'essentiel du travail répétitif.
05
Pour le module de relance des factures impayées, les acteurs métier étaient les membres du service comptable. Ils maîtrisaient le processus existant, les conditions de paiement appliquées aux clients, les exceptions liées à l'affacturage et les conséquences d'une relance incorrecte. Leur participation ne consistait pas seulement à demander une automatisation : ils apportaient les règles nécessaires pour décider si une facture devait être relancée, à quel moment et auprès de quelle personne. Sans cette connaissance, un traitement techniquement fonctionnel aurait pu prendre des décisions comptables inadaptées.
Mon interlocutrice principale était l'assistante de direction, qui exerce également des missions de comptabilité. Cette double position lui donnait une compréhension à la fois opérationnelle et organisationnelle du besoin. Elle pouvait expliquer le travail quotidien de la comptabilité, confirmer les règles de relance et mesurer les conséquences du module pour l'entreprise. Elle assurait ainsi le lien entre les utilisateurs concernés, les décisions de la direction et mon travail technique.
La comptabilité avait pour responsabilité de décrire son besoin, le processus actuel, les conditions de relance et les situations particulières à préserver. Ma responsabilité consistait à transformer ces informations en une solution compatible avec le fonctionnement d'Odoo. Je devais reformuler le problème, identifier les données disponibles dans l'ERP, proposer un comportement réalisable puis concevoir, développer, tester et déployer le module. Cette répartition évitait deux écueils : demander aux comptables de concevoir eux-mêmes la solution technique ou, à l'inverse, laisser le développeur inventer seul des règles comptables qu'il ne maîtrise pas.
Les commerciaux pouvaient recevoir une notification lorsqu'ils étaient rattachés à une facture en retard, mais ils n'ont pas participé à la définition ni aux tests du module de relance. Le fait d'être destinataire d'une information ne signifiait donc pas qu'ils portaient la responsabilité du processus. Les règles, la configuration et la validation restaient pilotées par la comptabilité. Cette distinction permettait de conserver un décideur métier clairement identifié et d'éviter que plusieurs services définissent séparément des comportements contradictoires.
L'assistante de direction était également ma N+1, c'est-à-dire ma responsable hiérarchique directe. Elle validait les règles métier, les conditions de relance, les droits attribués aux utilisateurs, l'accès aux fonctionnalités et l'accès aux écrans de configuration. Cette validation était particulièrement importante pour les paramètres capables de modifier automatiquement le comportement envers un client. Elle permettait de vérifier qu'une possibilité technique, par exemple bloquer un client ou autoriser un utilisateur à changer les délais, correspondait bien à une décision assumée par l'entreprise.
Les besoins et les ajustements étaient discutés lors de réunions ou par messages directs. Les réunions permettaient de reprendre un processus complet et de lever les ambiguïtés ; les messages facilitaient les confirmations rapides ou le traitement d'une question précise. Lorsqu'une première version était disponible, j'en faisais une démonstration et je donnais à la comptabilité un accès à l'environnement de staging. Cet environnement de préproduction lui permettait de manipuler la fonctionnalité sans agir sur les vraies opérations. Après la mise en production, je complétais cette validation par une formation consacrée au paramétrage et à l'utilisation du module.
Les utilisateurs n'avaient pas besoin de connaître le code ou l'architecture de l'ERP pour exprimer leur difficulté. J'écoutais leur processus et l'objectif recherché, puis je leur présentais les solutions qu'Odoo permettait réellement de mettre en place. Ce travail de traduction rendait visibles les possibilités du logiciel, mais aussi ses contraintes. Il permettait aux utilisateurs de choisir en connaissance de cause, plutôt que de valider une solution dont ils ne découvriraient les limites qu'après le développement.
Des demandes contradictoires pouvaient apparaître entre services ou entre plusieurs manières de traiter un même cas. Dans cette situation, je pouvais expliquer les conséquences techniques et proposer les options disponibles, mais je ne décidais pas seul de la priorité métier. L'arbitrage revenait à ma N+1. Lorsque la décision dépassait son périmètre ou engageait plus largement l'entreprise, elle pouvait être portée au N+2, c'est-à-dire au responsable situé un niveau hiérarchique au-dessus. Cette organisation distinguait la recommandation technique, qui relevait de mon expertise, de la décision d'entreprise, qui relevait de la hiérarchie.
Le module de relance a surtout mobilisé la comptabilité, mais l'ensemble des 16 modules a nécessité des échanges avec d'autres services. Les commerciaux apportaient leur connaissance de la relation client et des processus de vente. L'ADV, ou administration des ventes, suivait le traitement administratif des commandes, depuis leur enregistrement jusqu'à leur livraison et leur facturation. La logistique maîtrisait les contraintes de préparation, de colisage et d'expédition. Ces équipes, directement engagées dans les processus concernés, pouvaient décrire les informations manquantes, tester les écrans ou documents et confirmer qu'une automatisation simplifiait réellement leur travail.
Il arrivait qu'un besoin ne puisse pas être reproduit exactement de la manière imaginée par l'utilisateur en raison d'une contrainte technique d'Odoo. Dans ce cas, je n'essayais pas de masquer l'écart. J'expliquais ce qui empêchait la solution initiale, la différence entre le résultat souhaité et les possibilités réelles, puis je proposais l'alternative qui répondait le mieux à l'objectif. L'échange se concentrait ainsi sur le problème à résoudre plutôt que sur une forme de solution devenue irréalisable. Cette transparence évitait de créer une attente que le module ne pourrait pas satisfaire.
L'accord final était donné par ma N+1 après les démonstrations et les tests sur le staging. Une fois la fonctionnalité déployée, j'étais responsable d'en informer les utilisateurs. Je préparais des notes de version et des guides, puis j'organisais selon le besoin une formation ou des explications ciblées. Cette communication permettait de présenter non seulement ce qui avait changé, mais aussi la manière d'utiliser les nouveaux réglages et les responsabilités associées.
Sur les développements courants, j'étais autonome et libre de faire preuve de créativité pour construire la solution : choix de l'architecture, organisation du code, méthode de test et proposition fonctionnelle. Une validation devenait en revanche obligatoire dès que le sujet touchait à la sécurité ou produisait un impact direct sur un client. La sécurité comprend notamment l'accès à des données confidentielles et l'attribution de droits dans l'ERP ; l'impact client direct comprend par exemple l'envoi automatique d'un courriel, le blocage d'un compte ou la génération d'un document qui lui est destiné. Cette limite me permettait d'agir rapidement sur les choix techniques tout en laissant les décisions sensibles à une personne disposant de l'autorité nécessaire.
06
Le module de relance ne travaille pas sur un échantillon choisi manuellement. Chaque jour, il examine toutes les factures clients comptabilisées qui ne sont pas encore totalement payées. Une facture comptabilisée est une facture sortie de l'état de brouillon, confirmée dans Odoo et associée à une écriture comptable. Elle est considérée comme intégralement payée lorsque les paiements enregistrés couvrent le montant attendu et sont rapprochés de cette écriture. Le nombre de relances varie donc selon l'activité et le volume d'impayés du moment, mais le périmètre analysé reste systématique. Cette couverture réduit le risque qu'une facture soit absente de la vérification simplement parce qu'un utilisateur ne l'a pas ouverte.
Avant l'automatisation, la comptabilité devait rechercher les factures à contrôler, lire leurs conditions de paiement, identifier celles qui dépassaient leur échéance puis préparer les relances. Le module représente un gain d'au moins une demi-journée de travail par semaine. Ce temps n'est pas seulement déplacé vers une autre tâche de saisie : la détection, l'application des paliers et l'envoi des messages configurés sont réalisés par l'ERP. La comptabilité peut ainsi consacrer davantage de temps aux situations qui nécessitent réellement une analyse ou un échange humain.
Le traitement quotidien réduit mécaniquement la dépendance à la mémoire ou à la disponibilité ponctuelle d'une personne. Les factures correspondant aux règles sont repérées selon le même processus et au même rythme. Cette régularité doit limiter les oublis et peut contribuer à réduire la durée de certains retards de paiement. Cette dernière conséquence n'a toutefois pas encore été mesurée avec un indicateur avant-après. Je ne présente donc pas une baisse chiffrée des impayés comme un résultat acquis : le gain actuellement démontrable porte sur le temps économisé, la couverture systématique des factures et la fiabilité du déclenchement lorsque les données sont correctement configurées.
L'automatisation ne supprime pas toutes les vérifications de la comptabilité. Les factures de clients relevant de l'affacturage continuent notamment de nécessiter une attention particulière. Dans ce dispositif, une créance peut être cédée à un organisme financier qui intervient dans son financement ou son recouvrement. Une relance envoyée directement par l'entreprise peut alors ne pas correspondre au circuit prévu. Le résultat recherché n'était donc pas de retirer toute intervention humaine, mais de concentrer cette intervention sur les exceptions pendant que les cas standards sont traités automatiquement.
Une relance a été envoyée à tort pour un client qui relevait de l'affacturage. L'analyse a montré que le client n'avait pas été configuré comme tel par la comptabilité dans l'ERP. Le programme avait appliqué la règle correspondant aux informations disponibles, mais ces informations ne représentaient pas la situation réelle. Cet incident montre qu'une automatisation ne peut pas compenser seule une donnée métier absente ou incorrecte. La qualité du résultat dépend à la fois de la logique du module et de la qualité de sa configuration. Il justifie le maintien de contrôles, la formation des utilisateurs responsables des données et la prise en compte explicite des exceptions.
Les utilisateurs autorisés peuvent modifier les délais de relance, les modèles de courriel et les exclusions sans demander une modification du code. Cette autonomie constitue un résultat important : la règle reste pilotée par le service qui la connaît, tandis que le module garantit son exécution. Un changement de politique de relance ne nécessite plus systématiquement mon intervention ni un nouveau déploiement. Le délai entre la décision métier et son application est réduit, et le code contient moins de valeurs figées susceptibles de devenir obsolètes.
Le module peut empêcher la confirmation d'une nouvelle commande lorsqu'un client cumule trop d'impayés par rapport à son encours autorisé. L'encours représente ici le montant total que l'entreprise accepte de laisser dû par ce client à un instant donné. La décision tient également compte du montant couvert par l'assurance contre le risque d'impayé. Selon les conditions du contrat, cette assurance peut couvrir une partie de la perte lorsqu'un client devient incapable de payer, par exemple en cas de défaillance de son entreprise. Le blocage évite donc d'augmenter automatiquement l'exposition financière au-delà des limites définies. Il transforme une information comptable en mesure de prévention directement appliquée au processus commercial.
Les adaptations QWeb ont réduit les annotations ajoutées à la main sur les documents. Les taxes, les informations de transport, les consignes logistiques ou les conditions particulières de livraison peuvent être récupérées depuis l'ERP et présentées dans le rapport prévu. Les clients reçoivent ainsi des documents contenant davantage d'informations nécessaires à leur compréhension. L'entreprise reçoit moins de demandes de clarification ou de réclamations provoquées uniquement par une donnée absente du PDF. Pour les équipes internes, le gain porte à la fois sur le temps de préparation et sur la diminution du risque de recopier incorrectement une information.
Le module 1up_product_extension structure dans Odoo les informations relatives au poids, aux dimensions, au conditionnement et aux autres caractéristiques nécessaires à la préparation. Ces données ne restent plus dispersées ou implicites : elles peuvent être affichées dans les vues, reprises dans les documents et utilisées par les traitements qui en ont besoin. Le résultat ne se résume donc pas à l'ajout de champs à un écran. Le module fournit une référence commune sur laquelle la logistique peut s'appuyer pour préparer et expédier les produits avec des informations plus pertinentes.
Le module 1up_margin calcule et présente une marge réellement exploitable au niveau des factures clients. La marge rapproche le revenu généré par une vente des coûts qui lui sont associés selon les règles de l'entreprise ; elle permet d'évaluer ce que l'opération contribue effectivement à la performance. Avant ce module, le directeur général devait attendre la clôture de l'exercice et les résultats préparés par l'expert-comptable pour disposer d'une vision complète. Il peut désormais suivre cet indicateur à partir des factures au cours de l'année et analyser plus rapidement les performances de l'entreprise. Le module transforme ainsi des données opérationnelles de l'ERP en information de pilotage.
Le module 1up_b2b_specifique permet au site B2B de synchroniser correctement les données dont il a besoin avec Odoo. Une API est une interface qui permet à deux logiciels d'échanger des informations selon des règles définies ; une route API est un point d'entrée exposé par le serveur pour lire, créer ou mettre à jour une donnée déterminée. Certaines opérations nécessaires au site n'existaient pas dans l'API standard d'Odoo. J'ai donc développé des routes adaptées au processus de l'entreprise. Le site B2B peut ainsi obtenir ou transmettre les informations attendues sans contourner l'ERP ni dupliquer manuellement les données.
Tous les utilisateurs de l'entreprise bénéficient des modules, même lorsqu'ils n'ouvrent pas eux-mêmes l'écran concerné. La comptabilité utilise directement les relances et les informations de marge ; l'ADV, les commerciaux et la logistique travaillent avec des vues, des documents ou des données enrichies ; les utilisateurs du site B2B dépendent indirectement des synchronisations. Cette diffusion montre que les modules forment une couche métier commune. Une amélioration réalisée dans Odoo peut produire son résultat dans un autre service, un document envoyé au client ou une application externe.
Les modules internes nécessaires ont été maintenus pendant la migration de l'ERP. Ce résultat confirme que les personnalisations n'étaient pas de simples corrections temporaires attachées à une seule version. Leur code versionné, leur séparation en modules et le travail de migration ont permis de préserver les fonctions utiles tout en supprimant une partie de la dette technique. La dette technique désigne les choix ou accumulations de code qui rendent les évolutions futures plus coûteuses, plus lentes ou plus risquées. Sa réduction facilite désormais la maintenance et les prochaines adaptations.
Pour l'entreprise, la valeur produite se répartit sur plusieurs niveaux. La stabilité vient de fonctionnalités intégrées à l'ERP et testées avant leur mise en production. L'efficacité vient de la réduction des actions manuelles, notamment pour les relances et la préparation des documents. Le pilotage vient de données plus pertinentes, comme la marge accessible au directeur général. Ces résultats sont complémentaires : automatiser sans fiabiliser les données aurait accéléré les erreurs, tandis qu'ajouter des indicateurs sans simplifier les processus n'aurait pas réduit le travail quotidien.
Pour mon évolution professionnelle, cette réalisation démontre ma capacité à écouter plusieurs services, comprendre leurs contraintes puis construire une réponse compatible avec les spécificités d'un framework complexe comme Odoo. Un framework fournit une architecture, des mécanismes et des conventions que le développement doit respecter pour rester intégré et maintenable. J'ai appris à ne pas opposer besoin métier et contrainte technique : je recherche une solution qui produit la valeur attendue sans fragiliser le fonctionnement de l'ERP. Cette compétence me permet d'intervenir au-delà de l'écriture de code, jusque dans l'analyse, l'arbitrage technique, le déploiement et l'accompagnement des utilisateurs.
Certaines versions simplifiées et génériques des modules sont déjà disponibles sur mon GitHub, dont le lien figure dans ce portfolio. Elles ont été détachées des données et règles confidentielles propres à l'entreprise afin d'illustrer publiquement une partie du travail. Les captures d'écran internes, les notes de version et de futurs extraits de code ou de configuration restent en revanche soumis à l'accord du directeur général lorsqu'ils peuvent révéler un processus métier. L'anonymisation consiste à retirer ou remplacer les informations permettant d'identifier un client, un fournisseur, un utilisateur ou une donnée commerciale confidentielle. Je distingue ainsi les modules génériques déjà publiables du code interne complet, qui n'est pas présenté comme intégralement open source.
07
Le module de relance est actuellement exécuté chaque jour en production par son action planifiée. Le traitement ne demande pas mon intervention pour rechercher les factures, appliquer les règles ou envoyer les messages configurés. Cette autonomie constitue l'aboutissement opérationnel du projet : la fonctionnalité n'est plus un prototype dépendant de son développeur, mais un composant régulier du travail comptable. Mon absence ponctuelle n'empêche donc pas les relances standards de fonctionner.
Les personnes de la comptabilité qui réalisaient manuellement les relances avant le module disposent maintenant des droits nécessaires pour administrer les délais, les modèles de courriel, les exclusions et les autres paramètres métier. Elles n'ont pas besoin de me solliciter pour adapter ces valeurs. Cette continuité est importante : la responsabilité du processus reste entre les mains des utilisateurs qui connaissent les clients et les règles comptables, tandis que le code automatise leur application.
À ce jour, le module ne demande pas de correction ni d'intervention régulière. Son comportement a atteint un niveau de stabilité suffisant pour rester en production sans modification immédiate. Stabilisé ne signifie pas définitivement achevé : de nouvelles règles, une future version d'Odoo ou un changement du processus comptable pourront justifier une évolution. Cela signifie qu'aucun problème actuel ne nécessite de toucher au code uniquement pour maintenir son fonctionnement quotidien.
Lorsqu'un utilisateur rencontre une anomalie ou souhaite proposer une évolution, il me le signale par message direct ou vient m'en parler dans mon bureau. Ce canal facilite une première compréhension rapide, particulièrement lorsqu'il faut montrer un écran ou expliquer une situation concrète. Je peux ensuite analyser si le comportement vient du code, de la configuration ou des données. La proximité avec les utilisateurs reste ainsi un moyen de maintenance, même lorsque le module lui-même fonctionne sans intervention.
La prochaine évolution identifiée concerne la manière dont le module interprète les conditions de paiement. Une condition de paiement peut fixer une échéance unique ou répartir un montant selon plusieurs dates. Le calcul des jours de retard doit donc tenir compte de la structure réelle de l'échéancier et pas seulement appliquer une date uniforme à toutes les situations. Le fonctionnement actuel est utilisable, mais une prise en compte plus précise rendrait les paliers de relance plus fidèles à la dette effectivement exigible.
Je ne prévois pas d'ajouter à court terme un nouveau mécanisme de détection des clients relevant de l'affacturage. Le système actuel est considéré comme suffisant lorsque les données sont correctement renseignées. L'incident déjà constaté venait d'une configuration absente, pas d'une incapacité du module à reconnaître une information enregistrée. Ajouter un second mécanisme sans besoin démontré risquerait d'augmenter la complexité sans apporter de garantie supplémentaire. La priorité reste donc la qualité des données et l'utilisation correcte de la configuration existante.
Il serait pertinent de mesurer plus précisément l'effet du module sur le temps de travail, la régularité des relances et les personnes indirectement concernées. Ce chantier n'est toutefois pas prioritaire actuellement, car d'autres sujets sont déjà en cours dans l'entreprise. Le gain d'une demi-journée par semaine repose aujourd'hui sur l'estimation opérationnelle disponible. Une étude future pourrait comparer les délais moyens de paiement, le nombre de factures relancées, les oublis constatés et le temps consacré au processus avant et après l'automatisation.
Le module 1up_margin fournit une estimation proche de la réalité et déjà utile au directeur général, mais son calcul n'est pas encore parfaitement fidèle dans toutes les situations. Une évolution future devra mieux prendre en compte les composantes qui expliquent l'écart entre l'indicateur actuel et la marge comptable définitive. L'objectif n'est pas de remplacer l'expert-comptable ni la clôture annuelle, mais d'améliorer la précision de l'indicateur opérationnel disponible pendant l'année. Cette limite est explicitement reconnue afin que la direction interprète correctement la donnée.
Une piste d'optimisation de 1up_b2b_specifique consiste à créer des routes API plus granulaires. Une route granulaire répond à un besoin plus limité et ne transfère que les données utiles à l'opération demandée, au lieu de regrouper un volume important d'informations dans un seul appel. Des charges utiles plus petites peuvent réduire le temps de transfert et le travail de traitement de part et d'autre. Le code sous-jacent aux appels peut également être revu pour limiter les lectures ou transformations inutiles. Ces optimisations devront être mesurées afin de vérifier qu'elles produisent un gain réel sans multiplier excessivement les points d'entrée à maintenir.
Les tests automatisés peuvent sécuriser certaines règles techniques déterministes, mais leur intégration ne couvre pas fidèlement tous les usages dans le contexte actuel d'Odoo.sh. Les branches de staging, les données neutralisées et les services externes rendent certains scénarios difficiles à reproduire de bout en bout. Les tests manuels réalisés avec les utilisateurs restent donc aujourd'hui le moyen principal de valider les parcours métier. À l'avenir, des tests automatisés ciblés pourraient compléter cette démarche sur les calculs, les permissions ou les conditions de déclenchement, sans prétendre remplacer les essais humains sur les processus transversaux.
Lorsque le code source de la version suivant Odoo 19 sera disponible, je pourrai comparer les modèles, les méthodes et les vues utilisés par mes modules avec leur nouvelle implémentation. Je préparerai les adaptations sur une branche dédiée, puis je testerai la migration dans un environnement de staging avant toute modification de la production. Cette méthode reprend celle appliquée lors du passage d'Odoo 16 à Odoo 19 : identifier les ruptures en amont, corriger le code progressivement et vérifier les processus métier sur une copie réaliste. La prochaine migration devient ainsi un travail anticipable plutôt qu'une découverte au moment de la bascule.
Un autre développeur pourrait aujourd'hui reprendre les modules. Les parties de code les plus complexes sont commentées et chaque module dispose d'un fichier README. Un README est un document placé avec le code pour expliquer le but du module, les fonctionnalités disponibles, les raisons de certains choix, la manière de l'utiliser et les procédures de test. Cette documentation ne remplace pas toute transmission humaine, notamment pour les règles propres à l'entreprise, mais elle fournit une base structurée permettant de comprendre le périmètre et de commencer une maintenance sans repartir de zéro.
Certains modules pouvant répondre à un besoin générique existent déjà dans des versions simplifiées sur mon GitHub, accessible depuis le portfolio. Leur publication impose de retirer les dépendances propres à l'entreprise, les données confidentielles et les règles trop spécifiques. D'autres modules pourraient suivre après anonymisation et autorisation. Cette démarche produit un double bénéfice : elle fournit des preuves consultables de mon travail et oblige à clarifier le code pour qu'il puisse fonctionner en dehors de son environnement d'origine.
Mon projet personnel de Business Intelligence connecté à Odoo repose actuellement sur le code et les données standard de l'ERP, sans dépendre directement de ces modules métier. Cette séparation permet de construire un socle compatible avec une installation générique. Je tiens néanmoins compte du fait qu'une entreprise peut ajouter ses propres champs et modèles. L'architecture doit donc laisser des points d'extension permettant d'intégrer ultérieurement de nouvelles données issues de modules personnalisés, sans réécrire tout le système de synchronisation et d'analyse.
À partir de ces perspectives, l'état cible peut être défini comme une couche de modules stable en production, configurable par les services responsables, documentée pour être reprise, optimisée lorsque les mesures le justifient et préparée aux futures versions d'Odoo. Tous les modules n'ont pas vocation à évoluer constamment. La priorité est qu'ils continuent à répondre au besoin avec le moins de travail manuel possible, sans accumuler une nouvelle dette technique. Cette cible donne un critère concret pour décider entre maintenir, améliorer, généraliser ou supprimer une personnalisation.
08
Le principal défaut de mes premiers modules était la présence de valeurs codées en dur alors qu'elles auraient dû être configurables. Une valeur hardcodée est inscrite directement dans le programme : pour la modifier, il faut changer le code puis redéployer le module. Ce choix peut convenir à une constante véritablement universelle, mais pas à un délai, un identifiant, un modèle de document ou une règle qui dépend de l'entreprise et de sa base de données. Les fonctionnalités produisaient le résultat attendu, mais leur adaptation à un autre contexte demandait davantage de travail qu'elle n'aurait dû.
Ces choix ne venaient pas d'une volonté de négliger la qualité. Lorsque j'ai commencé, je connaissais moins bien l'architecture d'Odoo, les mécanismes de configuration et les conventions permettant de rendre une extension réutilisable. La solution la plus directe consistait alors à placer la valeur là où elle était utilisée. Avec une meilleure compréhension du framework, j'ai appris à distinguer ce qui appartient à l'algorithme de ce qui appartient aux données administrées par l'entreprise. Cette progression est caractéristique de mes premiers mois de développement sur l'ERP.
Les parties codées en dur n'ont pas provoqué de panne ou d'impact métier identifié. Cela ne les transforme pas pour autant en bonne pratique. Le problème apparaît surtout lors d'une évolution, d'une installation sur une autre base ou d'un changement de politique interne : une donnée cachée dans le code est plus difficile à retrouver, à expliquer et à modifier qu'un paramètre explicite. Mon autocritique porte donc sur la qualité et la capacité d'évolution du logiciel, pas sur un dommage que je chercherais à attribuer après coup à ces choix.
Si je devais reprendre un module en priorité, je choisirais 1up_specifique. Il centralise plusieurs adaptations de rapports et conserve encore quelques valeurs figées. Une refactorisation consiste à réorganiser le code sans supprimer la valeur fonctionnelle déjà fournie. Ici, elle viserait à identifier les valeurs propres à l'entreprise, à déterminer lesquelles doivent devenir des paramètres et à conserver dans le code uniquement la logique de génération des documents. Le module gagnerait ainsi en lisibilité, en portabilité et en facilité de migration.
J'applique maintenant le principe suivant : lorsqu'un détail de l'implémentation correspond en réalité à une donnée propre à une base précise, il doit être configurable. Deux bases Odoo peuvent partager la même structure et installer le même module tout en utilisant des clients, des modèles de courriel, des délais ou des références différents. Le code doit porter le comportement commun ; la configuration doit fournir les valeurs qui varient. Cette séparation permet au module de fonctionner dans un autre environnement similaire sans modifier son code source.
La principale limite de ma méthode actuelle est le temps nécessaire pour rejouer manuellement les parcours. Une personne doit préparer les données, effectuer les actions, observer le résultat puis recommencer après chaque correction. Un test automatisé peut répéter rapidement une règle précise et signaler une régression dès qu'elle apparaît. Les tests manuels restent indispensables pour juger un processus complet et son ergonomie, mais leur lenteur limite la fréquence et le nombre de variantes qu'il est réaliste d'exécuter avant chaque livraison.
Même avec une analyse détaillée, je ne maîtrise pas le quotidien de la comptabilité, de l'ADV ou de la logistique aussi finement que les personnes qui réalisent ces tâches. Un scénario peut me sembler secondaire alors qu'il est fréquent ou critique pour leur activité. Cette limite renforce l'importance des tests métier : le développeur vérifie la cohérence technique, mais les utilisateurs valident que le comportement correspond à la réalité. Avec le recul, impliquer davantage de personnes dans les essais augmente les chances de découvrir une exception et de croiser plusieurs usages du même écran ou de la même donnée.
Le type de régression qui risque encore de passer concerne principalement les performances. Un traitement peut sembler rapide avec un volume limité, puis ralentir lorsqu'il parcourt davantage de factures, de produits ou de relations entre modèles. Les tests fonctionnels confirment que le résultat est correct, mais ils ne mesurent pas automatiquement le nombre de requêtes, le temps d'exécution ou la consommation de ressources. Je dois donc compléter progressivement la validation par des jeux de données représentatifs et, pour les traitements sensibles, par des mesures ciblées plutôt que par une simple impression de rapidité.
Après la relance envoyée au client relevant de l'affacturage, il aurait été possible d'ajouter une règle supplémentaire dans le code. Je considère néanmoins que la configuration reste la protection la plus adaptée lorsque les critères d'exclusion ne sont pas tous connus à l'avance ou peuvent changer rapidement. Un algorithme ne peut pas deviner de manière fiable une décision commerciale ou comptable absente des données. Le meilleur compromis est donc de rendre l'exclusion explicite, accessible aux utilisateurs autorisés et suffisamment visible pour être correctement renseignée, plutôt que d'accumuler des exceptions implicites difficiles à maintenir.
Les utilisateurs peuvent me signaler une évolution oralement ou par message, mais je ne laisse pas la demande uniquement dans ce canal. Je la documente et je crée le ticket correspondant immédiatement. Cette habitude réduit le risque d'oubli et conserve une trace du besoin, des critères et de l'avancement. Le contact direct reste utile pour comprendre le contexte ; le ticket devient ensuite la référence durable. L'enjeu n'est donc pas d'interdire les échanges informels, mais de les convertir sans délai en information exploitable pour le développement et les tests.
Plus le nombre de personnes concernées qui testent une fonctionnalité est important, plus les usages représentés sont variés. Cette participation doit rester organisée afin d'éviter des retours contradictoires ou sans priorité, mais elle permet de détecter des cas que le demandeur principal ne rencontre pas. Si je reprenais certains développements, je solliciterais plus largement les profils réellement touchés avant la mise en production, en gardant un responsable métier chargé de l'arbitrage final.
L'écart encore présent dans 1up_margin ne vient pas uniquement d'un calcul à corriger. Les règles permettant d'attribuer précisément tous les coûts à une facture peuvent être complexes, et les données ou mécanismes standard d'Odoo ne représentent pas toujours directement l'indicateur attendu par la direction. Améliorer la précision demande donc de traduire les règles comptables, d'identifier les données fiables et de composer avec les limites techniques du framework. Reconnaître cette limite évite de présenter l'indicateur opérationnel comme une marge comptable définitive.
Les premières routes de 1up_b2b_specifique transfèrent parfois plus de données que nécessaire parce que j'ai privilégié une solution complète disponible rapidement. Ce compromis a permis de rendre la synchronisation fonctionnelle et de répondre au besoin métier sans attendre une optimisation parfaite. Il crée cependant un travail futur : mesurer les charges utiles, séparer les opérations qui gagnent à devenir plus granulaires et améliorer le code sous-jacent. Cette décision était acceptable pour débloquer le processus, à condition de ne pas confondre la première version fonctionnelle avec l'architecture définitive.
Je ne considère pas avoir personnalisé Odoo sans raison lorsqu'une fonction standard suffisait. Une personnalisation ajoute pourtant presque toujours un coût futur de test, de maintenance et de migration. Mon arbitrage consiste à comparer ce coût au temps économisé et à la valeur métier produite. Lorsque le gain quotidien dépasse largement l'effort futur prévisible, accepter une dette technique limitée peut être rationnel. Cette dette doit néanmoins rester visible, documentée et maîtrisée ; sinon, l'accumulation de gains rapides finit par rendre l'ERP trop difficile à faire évoluer.
Je me situe à un niveau élevé en développement Odoo parce que je parviens désormais à construire des solutions complexes en explorant profondément les mécanismes du framework. Un exemple récent est ma capacité à réaliser des patches JavaScript sur des composants OWL. OWL est le framework de composants utilisé par le client web d'Odoo. Un patch modifie ou étend le comportement d'un objet, d'une classe ou d'un composant existant lorsque les points d'extension habituels ne suffisent pas. Je n'osais pas intervenir à ce niveau auparavant en raison de la difficulté et du risque de régression. Le passage à cette maîtrise montre ma progression. Le point restant correspond notamment aux marges d'amélioration déjà identifiées sur les performances, l'automatisation des tests et certaines conventions de conception.
Mon principal conseil à un développeur débutant sur Odoo est de consulter le code source aussi souvent que possible, même si sa lecture paraît difficile au départ. La documentation développeur présente de nombreux concepts, mais elle ne détaille pas chaque interaction interne, chaque héritage ni tous les comportements des applications. Le code montre les conventions réellement appliquées, les méthodes disponibles et les solutions déjà utilisées par le framework. Il faut donc apprendre à suivre un appel, rechercher les héritages et comparer plusieurs modules. Cette exploration demande du temps, mais elle évite de recréer un mécanisme existant et permet progressivement de développer des extensions qui s'intègrent réellement à Odoo.