Guide pratique pour enrichir votre ERP/CRM sans compromettre la stabilité
1. Introduction
Dolibarr est un ERP/CRM open‑source particulièrement apprécié pour sa simplicité d’utilisation et son architecture modulaire.
Pourtant, dès que la petite entreprise commence à ajouter des modules, à créer des champs personnalisés ou à automatiser des processus, le risque de « casser » la configuration existante devient réel.
Ce guide vous montre comment étendre les fonctionnalités de Dolibarr de façon sûre, en conservant l’intégrité du système déjà mis en production. Nous détaillons les principes, les méthodes et les outils qui permettent une personnalisation avancée sans toucher au cœur du code source, tout en limitant les risques de régression.
2. Comprendre la structure de Dolibarr
| Élément | Description | Points de vigilance |
|---|---|---|
| Modules (modules/) | Fonctionnalités de base (Produits, Contacts, Factures, Locations, …) | Chaque module possède son propre cache et ses tables. |
| Plugins (plugins/) | Extensions communautaires (ex. : paiement, Facturation électronique) | Méthodes « hook » bien documentées, mais dépendent de la version de Dolibarr. |
| sauvegardes et snapshots | Sauvegardes SQL + export de fichiers | Critique pour revenir en arrière rapidement. |
| Base de données | Tables llx_* (llx_contract, llx_product, …) |
Toute modification directe des tables doit être évitée. |
| Front‑office | Templates Smarty (templates/default) |
Les thèmes personnalisés doivent rester dans un répertoire dédié. |
Le mantra : Ne jamais modifier les fichiers du répertoire
htdocsou les tables système sans passer par les mécanismes de hook / API de Dolibarr.
3. Les principes de personnalisation sûre
3.1 Utiliser les hooks et les plugins officiels
Dolibarr expose plus d’une vingtaine de hooks (ex. : actionObjectCommit, hookPostUpdate, hookHeader) qui permettent d’intercepter des événements sans toucher aux classes métier.
- Créer un petit plugin (ex. :
my_custom_plugin) qui s’abonne aux hooks nécessaires. – Implémenter uniquement le code indispensable (validation, log, mise à jour d’un champ).
3.2 Préferer les champs personnalisés ($fields array)
- $fields est l’endroit où les modules déclarent leurs champs.
- Ajouter un champ via le tableau
$fields['myfield'][] = array(...);dans un fichierllx_myplugin.php. - Aucun SQL n’est requis ; les champs sont ajoutés dynamiquement à la table concernée.
3.3 Utiliser le API Object ($object->fetch, $object->add, $object->update)
- Toutes les opérations CRUD passent par les méthodes de l’objet. – Cela garantit que les contraintes (chains, triggers, permissions) sont respectées.
- Exemple :
$product->setPrice(12.5);utilise la logique de prix (remise, TVA, etc.) sans toucher la tablellx_product.
3.4 Centraliser les modifications dans un module dédié – Créez votre propre module (ex. : myadvanced) qui regroupe :
- Le fichier
myadvanced.class.php(classe du plugin) - Le répertoire
myadvanced/htdocs/(templates, scripts) - Le répertoire
myadvanced/lang/xx/(traductions)- Ainsi, chaque évolution est contenue dans un namespace isolé, ce qui facilite le déploiement et le rollback.
3.5 Versionner les changements
- Utilisez Git (ou tout autre VCS) pour versionner le répertoire du plugin.
- Taggez chaque version majeure (
v1.0,v1.1) afin de repérer rapidement l’état du code lorsqu’un bug apparaît. - Exportez les squelettes de tables (DDL) avec
SHOW CREATE TABLE llx_...;avant toute modification manuelle.
4. Techniques avancées sans toucher au code existant | Technique | Quand l’utiliser | Étapes clés |
|———–|——————|————-|
| DXL (Dolibarr eXtended Language) | Automatiser des tâches récurrentes (import/export, génération de rapports) | 1. Créez un fichier .dxl
2. Utilisez les fonctions $object->...
3. Testez sur une copie de prod |
| Configuración via conf/ | Modifier les paramètres globaux (ex. : préfixe de factures, catégories de produits) | Modifier le fichier conf/ → llx_conf.php
→ Versionner le fichier modifié |
| Modules de paiement | Ajouter un nouveau mode de paiement sans toucher aux historiques | Installer le module, configurer les paramètres via l’interface « Paramètres de paiement » |
| Workflows (BPMN) via la fonction workflow | Automatiser l’avancement des tickets ou des commandes | Créer une règle dans Configuration → Workflows et l’associer à l’objet concerné |
| Sauvegarde incrémentale (MySQL dump + rsync) | Garantir la récupération en cas d’erreur de mise à jour | Scheduled backup → script mysqldump -u ... -p dbname > backup.sql |
5. Checklist « personnalisation sans casse »
| ✅ | Action |
|---|---|
| 1 | Cloner l’environnement de production (sandbox) avant toute modification. |
| 2 | Identifier les hooks nécessaires (listés dans docs/hooks.md). |
| 3 | Créer un plugin dédié au besoin (ne pas éditer les modules core). |
| 4 | Tester chaque modification unitaires avec phpunit (ou script de test manuel). |
| 5 | Vérifier les permissions (permissions/ → pas de changement inutile). |
| 6 | Exécuter les migrations SQL via le script upgrade/upgrade.php du plugin. |
| 7 | Faire un commit Git avec message descriptif (feat(myadvanced): add price rounding hook). |
| 8 | Déployer sur staging → vérifier la logique métier, les rapports et les performances. |
| 9 | Effectuer une sauvegarde complète (DB + fichiers) avant le passage en production. |
| 10 | Mettre à jour la documentation interne (README, diagramme d’architecture). |
6. Exemple pratique : Ajouter une règle de déduplication des contacts
Supposons que votre entreprise veut éviter la création de doublons lors de la saisie d’un nouveau contact. 1. Créer le plugin duplicatecontact :
duplicatecontact.class.phpavec méthodehookFormphiconCreateContactAfter(hook reçu via$hook=).- Implémenter la logique :
« `php function hookFormphiconCreateContactAfter($hook) {
$form = $hook->getFunctionConfArray()[‘form’];
$email = $_POST[’email’] ?? »;
$sql = "SELECT rowid FROM llx_contact WHERE email = ‘$email’ LIMIT 1";
$res = picturadol::fetch($sql);
if($res) {
$msg = "Un contact avec cet e‑mail existe déjà (rowid ".$res[‘rowid’].").";
setEventMessage($msg, null, ‘error’);
$hook->abort = true;
}
} - Tester dans le sandbox → vérifier que le message apparaît et que le formulaire bloque la création.
- Versionner → commit
git add duplicatecontact/et tagv1.0-duplicate-contact. - Déployer →Copier le répertoire dans
custom/plugins/du serveur de prod, activer le plugin (via le menu Extensions). > Aucun changement dans les classesllx_contactni aucune modification manuelle de la tablellx_contactn’a été réalisée. Tout est géré via le hook existant.
- Implémenter la logique :
7. Conclusion
La personnalisation de Dolibarr est extrêmement puissante lorsqu’on sait exploiter les mécanismes intégrés (hooks, API, plugins, champs dynamiques) sans toucher directement aux tables de la base ni modifier les classes du core.
En suivant les bonnes pratiques présentées :
- Isolation des ajouts dans un module dédié,
- Utilisation des hooks et de l’API au lieu de requêtes SQL brutes,
- Versionning rigoureux (Git + tags), – Tests systématiques en environnement sandbox,
- Sauvegardes automatisées,
vous pouvez élargir les capacités de Dolibarr (déduplication, workflows spécifiques, intégrations tierces) sans jamais compromettre la stabilité de l’instance déjà déployée.
Cette approche garantit une évolutivité durable, facilite la maintenance et assure aux équipes internes (ou aux partenaires externes) une transition fluide vers les futures versions de Dolibarr, tout en conservant la richesse fonctionnelle de la plateforme.
À retenir : Personnaliser sans casser = exploiter l’architecture ouverte de Dolibarr, jamais le forcer à sortir de son cadre. Bonnes personnalisations ! 🚀