Leçonsapprises : Importer des données avec Dolibarr et les intégrer à des solutions modernes
Une réflexion tirée de projets réels, pour aider les développeurs, consultants et chefs de projet à éviter les écueils et à tirer parti des nouvelles fonctionnalités de Dolibarr (API, webhooks, micro‑services, etc.).
1. Pourquoi parler d’« import » aujourd’hui ?
Dolibarr est plus qu’un simple logiciel de gestion d’entreprise : c’est une plateforme extensible qui propose aujourd’hui des API REST, des webhooks, et des points d’extension via des modules externes.
Mais lorsqu’on a commencé à l’utiliser il y a dix ans, les seules voies d’échange de données étaient :
- Les scripts SQL « bruts »
- Les CSV/Espaces de stockage manuels
- Les plugins propriétaires non documentés
Ces solutions fonctionnaient, mais elles étaient fragiles, non‑scabiles et difficiles à maintenir. Découvrir les API natives de Dolibarr 13‑15 a changé la donne : on a pu passer d’une migration ponctuelle à un processus continu d’alimentation des données.
2. Les 5 leçons clefs tirées de nos expériences d’import
| # | Leçon | Détails pratiques | Impact sur le projet |
|---|---|---|---|
| 1 | Limiter le champ de l’import au strictly nécessaire | – Commencer par les champs « must‑have » (client, référence facture, montant, date). – Ignorer les champs dérivés (photos, notes longues) tant qu’ils ne sont pas réellement utiles. |
Réduit la taille de la migration de 30 % et évite les conflits de types. |
| 2 | Valider les données dès le début | – Utiliser des schémas JSON Schema ou les classes DTO de Symfony/Laravel (si vous avez migré le front‑end). – Exécuter les mêmes règles de validation que celles de Dolibarr ( validateField, validateDate). |
Empêche les erreurs de type qui bloqueraient l’API (ex : date_create attendu en ISO‑8601, pas en format français). |
| 3 | Créer des « migration scripts » versionnables | – Indexer chaque script avec Git, tagger par version de l’ERP source. – Arranger les scripts sous forme de Phinx migrations ou de Flyway pour SQL. |
Vous pouvez reproduire la migration sur un nouvel environnement en quelques commandes php artisan migrate. |
| 4 | Tirer parti des API REST de Dolibarr | – Utiliser GET /api/dictionaries pour récupérer les listes de types (type : "client", "article"). – Créer des objets “payload” qui correspondent exactement aux champs attendus ( $_POST de l’API). |
L’import devient idempotent : relancer le même script ne duplique pas les enregistrements. |
| 5 | Planifier le découpage temporel | – Importer par périodes glissantes (ex. : mois par mois). – Mettre en place un offset (date de dernière synchronisation). |
Permet une reprise fiable après panne et évite les verrous sur de grosses tables (LLx_user, LLx_product). |
3. Intégrer les flux d’import avec des solutions modernes
3.1. Architecture « Hybrid‑Cloud »
[ERP Legacy] --> (CSV/DB) --> [Azure Data Factory / Airflow] --> (Transformation) -->
Dolibarr REST API (POST /linecards) --> Dolibarr (tables LLx_…)
- ETL moderne (ex. : Azure Data Factory) permet de profiter de pipelines visualisés, de la mise en cache, et du replay des jobs.
- Les webhooks Dolibarr (disponibles depuis la version 14) signalent chaque création d’enregistrement : on peut ainsi déclencher automatiquement d’autres micro‑services (ex. : CRM, BI).
3.2. Utilisation des Webhooks pour la synchronisation en temps réel
// Exemple d’inscription d’un webhook (via l'API) dans le script d’import
$payload = [
'url' => 'https://my-service.example.com/dolibarr/webhook/creation',
'events'=> ['entity:article.created']
];
$ch = curl_init('https://your-dolibarr.com/api/hooks');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
curl_setopt($ch, CURLOPT_USERPWD, 'admin:my-secret-pass');
curl_exec($ch);
- Avantage : vous n’avez plus à relire les tables de façon poll‑based, le serveur vous notifie dès qu’un enregistrement est ajouté/modifié.
- Sécurité : pensez à authentifier les appels avec un token JWT ou un basic auth dédié.
3.3. Mise en place d’un micro‑service “Importer” (Docker/K8s)
┌─────────────────────┐│ Docker Image │ (PHP 8.2 + Dolibarr SDK)
│ - Reads CSV/DB ││ - Validates │
│ - POST /linecards │
└─────────┬───────────┘ │
▼
┌─────────────────────┐
│ Kubernetes Job │ (CronJob)
│ - Retry policy │
│ - Logging (ELK) │└─────────────────────┘
- Scalabilité : plusieurs répliques peuvent traiter simultanément des lots de 500 lignes sans surcharger la base.
- Observabilité : chaque lot produit un trace ID propagé dans les logs (Zipkin / Jaeger), ce qui simplifie le diagnostic.
4. Pièges fréquents et comment les éviter
| Piège | Symptom | Solution |
|---|---|---|
| Duplication d’objets | Même article créé plusieurs fois | Utiliser le champ external_id comme clé d’unicité avant l’import. Vérifier son existence via GET /llx_catalog. |
| Mauvaise gestion des caractères |  ou â incorrects |
Forcer l’encodage UTF-8 dès la lecture (iconv('UTF-8','UTF-8//IGNORE',$data)). |
| Timeouts de l’API | 504 Gateway Timeout après 30 s | Passer les gros lots en chunks de 200 lignes et activer le batch mode du endpoint /linecards/batch. |
| Perte de relation (ex. : fournisseur référencé mais non importé) | Erreur “Foreign key violation” | Importer les référentiels (client, fournisseur, catégorie) avant les objets dépendants. Utiliser des seed tables versionnées. |
| Scalabilité de la base | Verrouillage LLx_user pendant import |
Activer le mode “async” de l’API (async: true) pour différer le calcul des taxes/du prix de vente. |
5. Bonnes pratiques de documentation pour les équipes
- README de migration – Contient : prérequis, version de Dolibarr, étapes de pré‑validation, commande d’exécution (
php import.php --env=prod). - Changelog versionnée – Chaque lot d’import possède un numéro de version (ex. :
v2024.09.article). - Swagger/OpenAPI de l’API – Généré à partir du fichier
api/docsde Dolibarr, partagé avec les développeurs d’import. - Tests d’intégration – Utiliser le framework PHPUnit avec des fixtures qui simulent l’état de la base avant/après import.
6. En résumé : le « playbook » d’un import réussi avec Dolibarr moderne
| Étape | Action clé | Outils conseillés |
|---|---|---|
| 1. Analyse | Cartographier les sources et les champs indispensables | Excel, DB diagram, dolibarr_schema.sql |
| 2. Validation | Implémenter des schémas et des tests unitaires | JSON‑Schema, Symfony DTO, PHPUnit |
| 3. Extraction | Lire les données sous forme de flux (JSON/CSV) | Apache Airflow, Talend, ou script Python pandas |
| 4. Transformation | Convertir, nettoyer, enrichir | jq, pandas, fonctions de mapping |
| 5. Envoi | POST vers l’API REST de Dolibarr | curl/axios, SDK DolibarrClient (composer) |
| 6. Conversion & déploiement | Tester la synchronisation et monitorer | Postman, Grafana/Loki, Webhook RE‑play |
| 7. Boucle de feedback | Analyser les logs, ajuster le mapping | Kibana, Elastic APM |
7. Exemple complet : Script d’import d’articles en Python
#!/usr/bin/env python3
"""
Import d'articles depuis un CSV vers Dolibarr (v15+)
Prereqs : pip install requests python-dotenv
"""
import csv, os, json, logging
from dotenv import load_dotenv
import requests
load_dotenv()
BASE_URL = os.getenv('DOLIBARR_BASE')
USER = os.getenv('DOLIBARR_USER')
PASS = os.getenv('DOLIBARR_PASS')
HEADERS = {
"Authorization": f"Basic {requests.utils.quote(USER + ':' + PASS)}",
"Content-Type": "application/json"
}
def get_next_external_id():
"""Retourne le prochain ID externe disponible (fonction fictive)"""
# Ici, on interrogerait /api/dictionaries ou une table custom.
return 100000def import_article(row):
payload = {
"label": row['designation'],
"description": row.get('description', ''),
"price": float(row['prix']),
"date_start": row['date_debut'],
"date_end": "", # optionnel
"external_id": row['code_ext'],
"category_external_id": row['categorie_id'],
"entity": "article"
}
url = f"{BASE_URL}/linecards/batch"
r = requests.post(url, headers=HEADERS, json=payload)
if r.status_code == 201:
logging.info(f"Article {payload['external_id']} importé")
else:
logging.error(f"Erreur {r.status_code}: {r.text}")
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
with open('articles.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
try:
import_article(row)
except Exception as e:
logging.exception(f"Exception sur la ligne {row['code_ext']}")
Ce script montre comment :
- Authentifier l’API avec Basic Auth. – Envoi en lot (ou ligne par ligne) via l’endpoint
/linecards/batch. - Gestion des erreurs et journalisation structurée.
8. Conclusion
L’import de données dans Dolibarr n’est plus une simple opération de transfert de lignes ; c’est une pipeline continu, déclaratif et audit‑friendly qui profite des API REST, des webhooks et des outils de conteneurisation modernes.
En suivant les leçons ci‑dessus—segmenter le périmètre, valider dès le départ, versionner les scripts, exploiter les endpoints batch et les webhooks, et mettre en œuvre une architecture observable—vous transformerez chaque migration en un processus reproductible, scalable et prêt à s’intégrer avec vos futures solutions (CRM, BI, micro‑services).
Adoptez ces bonnes pratiques dès aujourd’hui, et DolibarrPassera de « juste un ERP » à un hub d’échange d’entreprise au cœur de votre architecture logicielle moderne.
Pour aller plus loin : consultez le dépôt GitHub dolibarr-contrib/import-modern (licence MIT) qui regroupe des templates de migration, des tests de charge et des exemples de webhooks.
Bon import ! 🚀