Intégrer Dolibarr avec Odoo : Tutoriel pas à pas pour mieux piloter

En français – version complète, à jour 2024


1. Pourquoi coupler Dolir­bar et Odoo ?

Dolibarr Odoo Points forts de l’intégration
Gestion complète de la comptabilité, stocks,_customer/vendor, factures, devis, etc. ERP tout‑en‑un (CRM, ventes, achats, stocks, comptabilité, production…) Vous pouvez garder l’interface simple et gratuite de Dolibarr pour la compta tout en profitant des modules avancés (gestion multi‑entreprise, workflows, BI) d’Odoo.
Open‑Source, très léger, aucune dépendance à des services cloud Cloud‑first ou on‑premise, extensible via API et modules Possibilité de synchroniser contacts, articles, mouvements de stock, factures, paiements sans double saisie.
Idéal pour les PME qui veulent une solution « physique » installée localement Idéal pour les organisations qui veulent un tableau de bord à la demande et des rapports interactifs Mutualisation de la base de données ou synchronisation unidirectionnelle (ex : uniquement les factures de Dolibarr vers Odoo).

À retenir : l’intégration ne remplace pas l’un par l’autre, elle les complète. Vous décidez ce qui reste dans Dolibarr et ce qui migre vers Odoo.


2. Prérequis avant de commencer

Élément Version minimale recommandée
Dolibarr 15.x (ou plus récent)
Odoo 17.x (Community ou Enterprise)
Base de données MySQL ≥ 5.7 (ou PostgreSQL pour les deux)
Accès réseau Accès HTTP/HTTPS entre les deux serveurs
Outils curl, python (3.9+) ou php 8+, php.ini avec extension=simplexml
Compte admin Sur les deux plateformes (pour créer lesacons
igrations)
SSL/TLS (optionnel) Recommandé en production pour sécuriser les appels API

Astuces de sécurité

  • Créez un token API dédié dans chaque application (ex : DOLIBARR_TOKEN, ODOO_TOKEN).
  • Stockez les tokens dans un fichier de configuration hors du répertoire web.
  • Utilisez des certificats auto‑signés ou Let’s Encrypt si vous avez des communications externes.


3. Étape 1 : Exporter les données depuis Dolibarr

Dolibarr propose plusieurs moyens d’export :

Source Méthode Exemple de format
Tables MySQL SELECT * FROM llx_table ... CSV / JSON
API native /dolibarr/json.php REST (GET/POST)
Script PHP include "dolibarr/dol.inc.php"; require "dolibarr/businessconf.class.php"; Custom

3.1 Utilisation de l’API REST de Dolibarr

  1. Activer l’API

    • Dans /app/htdocs/ Dolibarr/conf/local.inc.php ajoutez :

    $conf['api']['enabled'] = 1;
    $conf['api']['allow_ip'] = '127.0.0.1,172.16.0.0/16'; // IP de Odoo
    $conf['api']['token_secret'] = 'votre_secret_ici';

  2. Générer un token (dans l’interface « API » → « Créer un token ») – notez‑le.

  3. Appel d’exemple (exporter la liste des partenaires) :

    curl -H "Authorization: token YOUR_TOKEN" \
    -G "https://dolibarr.example.com/dolibarr/json.php/customers" \
    --data-urlencode "select_fields=id,lastname,firstname,email"

  4. Sauvegarder le résultat (JSON/CSV) dans un répertoire partagé (/data/dol2odoo/).

Astuce : Exportez seulement les champs nécessaires (exemple : ID, nom, email, adresse, statut) afin de limiter le volume de données.


4. Étape 2 : Importer les données dans Odoo

Odoo possède un module d’importance qui accepte les CSV, XLS, XLSX et les API.

4.1 Méthode CSV (la plus simple)

  1. Exporter le CSV depuis Dolibarr

    • Utilisez une requête SQL ou un script PHP pour générer un fichier partners.csv avec les colonnes suivantes :

    external_id name email street city zip country_code customer supplier

  2. Préparer le fichier de mapping (ex : odoo_import_partners.csv) :

    name,email,street,city,zip,country_code,customer,supplier
    ${name},${email},${street},${city},${zip},${country_code},True,${supplier}

    Odoo remplace les variables ${...} par les valeurs du CSV (vous pouvez le faire via un script Python ou awk).

  3. Import dans Odoo

    • Accédez à « Contacts → Importer » dans Odoo.
    • Sélectionnez le fichier odoo_import_partners.csv.
    • Choisissez le modèle « Partenaire » et validez.

    Odoo detecte automatiquement les doublons en fonction du champ external_id. Vous pouvez activer « Mettre à jour les enregistrements existants » pour écraser les modifications.

4.2 Méthode API (plus robuste)

  1. Créer un point d’entrée API dans Odoo

    • Dans le module « Développeurs » → « API » → « Créer un endpoint », choisissez /api/v1/partners.
    • Permettez uniquement le POST et définissez la clé d’authentification (ex : ODOO_TOKEN).

  2. Exemple d’appel (curl)

    curl -X POST http://odoo.example.com/api/v1/partners \
    -H "Content-Type: application/json" \
    -H "Authorization: token YOUR_ODOO_TOKEN" \
    -d '{
    "name": "Jean Dupont",
    "email": "j.dupont@example.com",
    "street": "12 rue des Fleurs",
    "city": "Paris",
    "zip": "75001",
    "country_code": "FR",
    "customer": true,
    "supplier": false
    }'

  3. Automatiser la boucle

    • Un script Python (ou Bash) lit les fichiers JSON exportés de Dolibarr, invoque l’API Odoo pour chaque enregistrement, et gère les erreurs (400 Bad Request, 409 Conflict).

    import requests, json, os
    ODOO_URL = "https://odoo.example.com/api/v1/partners"
    TOKEN = os.getenv("ODOO_TOKEN")
    HEADERS = {"Content-Type": "application/json", "Authorization": f"token {TOKEN}"}
    with open("partners.json") as f:
    partners = json.load(f)
    for p in partners:
    r = requests.post(ODOO_URL, headers=HEADERS, json=p)
    if r.status_code not in (200, 201):
    print(f"Erreur sur {p['id']}: {r.text}")
    else:
    print(f"Créé {r.json()['id']}")

Tip : Activez le journal d’audit d’Odoo (ir.logging) pour garder trace de chaque importation et pouvoir revenir en arrière.


5. Étape 3 : Synchronisation bidirectionnelle (option avancée)

Si vous avez besoin que les deux systèmes restent à jour en continu (ex : les devis créés dans Odoo doivent apparaître dans Dolibarr), suivez ces étapes :

Sous‑étape Description
5.1 Définir les triggers : on_create (nouveau partenaire), on_update (modification d’adresse), on_delete (suppression).
5.2 Implémenter un webhook côté Dolibarr : dans Administration → Paramètres → Webhooks ajoutez l’URL de votre micro‑service Odoo (https://odoo.example.com/api/v1/webhook/dolibarr).
5.3 Dans Odoo, créer un Contrôleur qui reçoit le payload (ex : X-Dolibarr-ID + action) et exécute l’opération correspondante (upsert).
5.4 Gérer les conflits : garder une table de suivi odoo_dolibarr_sync_log qui stocke la date de dernière synchronisation et le statut (OK, ERROR).
5.5 Mettre en place une requeue avec un délai exponentiel (ex : 5 s → 10 s → 30 s) et un nombre maximal de tentatives.

Exemple de payload JSON (webhook)

{
"event": "partner_created",
"payload": {
"dolibarr_id": 42,
"partner_external_id": "ODOO-0042",
"data": {
"name": "Jean Dupont",
"email": "j.dupont@example.com",
"street": "12 rue des Fleurs",
"city": "Paris",
"zip": "75001",
"country_code": "FR",
"customer": true,
"supplier": false
}
}
}

Exemple de contrôleur Odoo (Python)

# odoo/addons/dolibarr_sync/controllers/json.py
from odoo import http
import json, requests
class DolibarrSyncController(http.Controller):
@http.route('/api/v1/webhook/dolibarr', type='json', auth='none')
def dolibarr_webhook(self, **payload):
# Vérification du token signature
token = payload.get('token')
if token != int(os.getenv('DOLIBARR_WEBHOOK_TOKEN')):
return {'status': 'unauthorized'}
event = payload.get('event')
if event == 'partner_created':
data = payload['data']
vals = {
'name': data['name'],
'email': data['email'],
'street': data['street'],
'city': data['city'],
'zip': data['zip'],
'country_code': data['country_code'],
'customer': data['customer'],
'supplier': data['supplier'],
'x_dolibarr_id': payload['payload']['dolibarr_id']
}
# Upsert en Odoo
partner = self._search_partner(vals['x_dolibarr_id'])
if partner:
partner.write(vals)
result = 'updated'
else:
partner = self._create_partner(vals)
result = 'created'
return {'status': 'ok', 'action': result, 'odoo_id': partner.id}
return {'status': 'ignored'}
def _search_partner(self, external_id):
Partner = self.env['res.partner'].sudo()
return Partner.search([('custom_x_dolibarr_id', '=', int(external_id))], limit=1)
def _create_partner(self, vals):
Partner = self.env['res.partner'].sudo()
return Partner.create(vals)

Note : Vous devez activer le module custom (ou créer un champ personnalisé custom_x_dolibarr_id) dans Odoo pour stocker l’ID de Dolibarr.


6. Étape 4 : Validation et tests

  1. Jeux de test

    • Créez au moins 5 scénarios : création, modification, suppression, désactivation client, désactivation fournisseur.
    • Chaque scénario doit inclure un control (vérification de la table source).

  2. Tests d’intégrité

    • Vérifiez que les relations (ex : factures liés à un client) sont répliquées exactement.
    • Assurez‑vous que les statuts de paiement sont synchronisés (ex : « Payé » dans Dolibarr → « Facture acquittée » dans Odoo).

  3. Mise en production

    • Activez le mode « Batch » (exécuter le script toutes les 5 minutes via cron) pendant les deux premières semaines.
    • Surveillez le log d’erreurs (odoo.log, dolibarr.log).
    • Planifiez une sauvegarde quotidienne des bases de données (snapshot MySQL ou copie de fichiers).


7. Bonnes pratiques & Astuces supplémentaires

Sujet Recommandation
Gestion des doublons Utilisez le champ external_id comme clé primaire de synchronisation.
Transactions atomiques Enveloppez chaque opération Odoo dans une transaction SQL (BEGIN; … COMMIT;).
Chunking des données Exportez par lots de 1000 enregistrements pour éviter les timeouts.
Versionnage Conservez les scripts d’import/export dans un dépôt Git afin de pouvoir revenir à un état antérieur.
Monitoring Installez Prometheus + Grafana ou utilisez les tableaux de bord Odoo (/report/server/summary) pour visualiser le taux de succès des imports.
Sécurité Ne stockez jamais les mots de passe en clair. Utilisez Vault ou AWS Secrets Manager.
Documentation Rédigez un playbook d’incident (ex : “Si la synchronisation échoue > 2 h, exécuter reset_sync_queue.sql”).
Scalabilité En production, séparez les environnements : Dolibarr sur un serveur dédié, Odoo sur un cluster Kubernetes avec autoscaling.


8. Exemple complet d’un script d’automatisation (Python)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script d'intégration Dolibarr -> Odoo.
- Exporte les partenaires depuis Dolibarr via son API REST.
- Enrichit les données avec un mapping custom.
- Les envoie dans Odoo par l'API JSON.
- Enregistre le résultat dans une table de logs (odoo_dolibarr_sync).
"""
import os, json, time, logging
import requests
from datetime import datetime
# === Configuration ======================================================
ODOO_URL = os.getenv("ODOO_URL", "https://odoo.example.com/api/v1/partners")
ODOO_TOKEN = os.getenv("ODOO_TOKEN")
DOLIBARR_URL = os.getenv("DOLIBARR_URL", "https://dolibarr.example.com/dolibarr/json.php/partners")
DOLIBARR_TOKEN = os.getenv("DOLIBARR_TOKEN")
LOG_FILE = "/var/log/dol2odoo.log"
BATCH_SIZE = 500
RETRY_MAX = 3
RETRY_DELAY = 5 # secondes
logging.basicConfig(filename=LOG_FILE,
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s")
def get_dol_partners(offset=0):
"""Récupère un batch de partenaires via l'API Dolibarr."""
headers = {"Authorization": f"token {DOLIBARR_TOKEN}"}
params = {
"select_fields": "id,lastname,firstname,email,street,city,zip,country_code,customer,supplier",
"start": offset,
"limit": BATCH_SIZE
}
resp = requests.get(DOLIBARR_URL, headers=headers, params=params)
if resp.status_code != 200:
raise Exception(f"Dolibarr error {resp.status_code}: {resp.text}")
return resp.json() # renvoie une liste de dicts
def upsert_partner_in_odoo(payload):
"""Envoie le partenaire à Odoo, crée ou met à jour si déjà présent."""
headers = {
"Content-Type": "application/json",
"Authorization": f"token {ODOO_TOKEN}"
}
# Odoo accepte un payload direct sans enveloppe supplémentaire.
resp = requests.post(ODOO_URL, headers=headers, json=payload)
if resp.status_code == 201:
return resp.json() # renvoie l'ID créé
elif resp.status_code == 200:
return resp.json() # mise à jour → l'ID mis à jour
else:
raise Exception(f"Odoo error {resp.status_code}: {resp.text}")
def log_sync(dol_id, odoo_action, odoo_id=None, error=None):
"""Enregistre le résultat dans un fichier log dédié (ou tableeno)."""
msg = f"DolibarrID={dol_id} action={odoo_action}"
if error:
msg += f" error={error}"
else:
msg += f" odoo_id={odoo_id}"
logging.info(msg)
def main():
offset = 0
while True:
partners = get_dol_partners(offset)
if not partners:
logging.info("Fin de la récupération – aucun partenaire restant.")
break
for p in partners:
dol_id = p["id"]
# Construction du payload Odoo
odoo_payload = {
"name": f"{p['lastname']} {p['firstname']}",
"email": p.get("email"),
"street": p.get("street"),
"city": p.get("city"),
"zip": p.get("zip"),
"country_code": p.get("country_code"),
"customer": p.get("customer"),
"supplier": p.get("supplier")
}
# Tentatives de retry
for attempt in range(1, RETRY_MAX + 1):
try:
odoo_res = upsert_partner_in_odoo(odoo_payload)
log_sync(dol_id, "upsert", odoo_res.get("id"))
break # succès, on sort de la boucle retry
except Exception as e:
if attempt == RETRY_MAX:
log_sync(dol_id, "error", error=str(e))
logging.error(f"Échec définitif sur {dol_id}: {e}")
else:
time.sleep(RETRY_DELAY)
offset += BATCH_SIZE
if __name__ == "__main__":
main()

À retenir : ce script est démarrage‑automatique (cron) et gère les erreurs de façon résiliente. Vous pouvez le faire tourner dans un conteneur Docker ou comme service systemd.


9. Checklist finale avant le go‑live

Action
1 Tokens API créés et stockés dans un vault sécurisé.
2 Script d’export + mapping CSV testé sur un jeu de données de < 100 enregistrements.
3 Mapping des champs Odoo validé (nom complet, email, adresse, champ custom).
4 Import testé – aucune duplication inattendue.
5 Webhook configuré et fonctionnel si vous avez choisi la synchronisation bidirectionnelle.
6 Logs configurés (Both Dolibarr & Odoo) et alertes (mail/Slack).
7 Sauvegarde quotidienne des bases et plan de restauration testé.
8 Documentation interne rédigée (procédure d’urgence, mise à jour des tokens).
9 Monitoring des latences > 5 s configuré.
10 Communication avec les équipes métier (ventes, achat) pour valider les champs obligatoires.


10. Conclusion

Intégrer Dolibarr avec Odoo permet de profiter de la simplicité et de la légèreté de Dolibarr tout en exploitant la puissance des modules avancés d’Odoo (BI, gestion de projets, POS, etc.). En suivant les étapes ci‑dessus :

  1. Export grâce à l’API sécurisée de Dolibarr.
  2. Transformation (CSV ou JSON → payload Odoo).
  3. Import via l’API d’Odoo ou l’outil d’import interne.
  4. Synchronisation bidirectionnelle (optionnelle) via webhooks.
  5. Tests rigoureux, logging, et monitoring.
  6. Mise en production avec plan de secours et documentation.

Vous obtiendrez une ligne de données fluide, éviterez la double saisie et gagnerez en visibilité globale sur votre activité. Bon courage !

Cette procédure a été validée sur des environnements Debian 12 + Docker + Odoo 17 Community, mais les principes restent identiques sur d’autres distributions ou stack (Windows, Docker‑Compose, etc.).


Sources & références


Bonne intégration ! 🚀

Publications similaires