Socle multi-transporteurs — expéditions, colis, points relais (gratuit)
Multi-Carrier Shipping Base for Odoo Community — shipment, parcels, packaging, pickup points, per-service weight and size limits, and a documented extension point for carrier operators. No network calls.
Captures d'écran
Socle multi-transporteurs
Expéditions, colis, points relais et règles de refus — gratuit, LGPL-3
Multi-Carrier Shipping Base for Odoo Community. Ce module pose, une fois pour toutes, ce dont tous les transporteurs ont besoin. Et il ne parle à aucun d'entre eux.
Aucun appel réseau. C'est la propriété principale.
Le socle n'ouvre jamais une socket. Il n'achète pas d'étiquette, ne calcule pas de tarif, ne cherche pas de point relais, n'interroge personne. Il prépare, il contrôle, il consigne — et il refuse quand ça ne va pas.
Pour qu'Odoo se mette à parler à un transporteur, il faut lui adjoindre le module opérateur correspondant, qui se greffe dessus sans rien y changer. Ce socle est le produit d'appel d'une famille dont les opérateurs sont payants.
Ce qu'il refuse
C'est là que le module vaut quelque chose. Une expédition qui part avec un colis trop lourd, une adresse incomplète ou une déclaration douanière absente revient — après avoir été payée. Le mieux qu'un logiciel puisse faire, c'est refuser avant.
- le poids d'un colis dépasse le plus contraignant des deux plafonds déclarés — celui du type de colis et celui du service ;
- une dimension dépasse le maximum, colis par colis ;
- longueur + circonférence dépasse la limite du transporteur ;
- l'adresse manque un champ obligatoire pour le pays de destination ;
- un envoi hors Union européenne manque sa déclaration douanière ;
- un point relais est exigé par le service et n'est pas choisi.
Chaque refus nomme ce qui manque et la valeur en cause. Jamais « expédition invalide » :
Colis COLIS-0001 : poids de 12,000 kg pour un maximum de 8,000 kg imposé par le type de colis « Carton 30 × 20 × 15 ». Dépassement de 4,000 kg.
Déclaration douanière incomplète pour Suisse, hors Union européenne : il manque le motif d'exportation, le code SH, le pays d'origine des marchandises, la valeur douanière.
Et tous les motifs à la fois, pas le premier : corriger une erreur pour en découvrir une autre à l'essai suivant, c'est trois allers-retours au lieu d'un.
Les plafonds ne sont pas dans le code
Aucun chiffre de transporteur n'est écrit en dur. Les limites de poids et de dimensions sont des champs paramétrables par service, accompagnés d'un champ « Source des plafonds » pour noter d'où vient le chiffre et quand il a été relevé.
Un chiffre dans le code serait faux le jour où le transporteur le change, et personne ne s'en apercevrait : le module continuerait d'accepter ce que le transporteur refuse désormais. Le socle n'a pas à connaître les limites d'un transporteur — il doit seulement savoir les faire respecter.
Et ils se combinent avec ce qu'Odoo sait déjà : le poids maximal du type de colis dit ce que l'emballage supporte, celui du service ce que le transporteur accepte. Le plus bas des deux gagne, et le refus dit lequel a mordu — sans cela, vous corrigeriez le mauvais.
Ce qu'il porte
L'expédition
Greffée sur le bon de livraison : transporteur, service, poids et dimensions consolidés depuis les colis, valeur assurée, incoterm, numéro et URL de suivi, et le coût réel facturé en regard du coût estimé.
Les colis — sans rien redoubler
Le module n'ajoute aucun champ que vous auriez déjà. Les dimensions, la tare et le poids maximal viennent du type de colis natif d'Odoo ; le poids déclaré suit l'idiome d'Odoo — poids pesé s'il existe, sinon contenu + tare, qu'Odoo additionne déjà tout seul. Un second écran sur les mêmes données les aurait fait diverger au premier oubli. Le socle n'ajoute qu'une mesure : la longueur + circonférence, qu'Odoo ne calcule nulle part.
Les points relais
Stockés, choisis sur la commande, repris sur le bon de livraison et imprimés dessus. Jamais cherchés : le socle ne fait aucun appel réseau.
Le journal d'expédition
Chaque tentative, réussie ou non, laisse une ligne datée avec son opérateur, sa demande résumée et sa réponse. C'est ce qui permettra de déboguer un opérateur le jour où il sera branché. On n'efface pas une tentative, on en ajoute une autre.
La file
Odoo tient la file, un processus externe la consomme et vient consigner son résultat. Odoo n'appelle personne lui-même : un Odoo qui lance des appels transporteurs tombe avec eux.
Un point d'extension documenté
Cinq méthodes nommées — tarifer, étiqueter, suivre, annuler, chercher des points relais — dont le socle définit le contrat exact : ce qu'elles reçoivent, ce qu'elles doivent rendre, ce qu'elles ont le droit de lever.
La file ne se relance jamais toute seule
Une tâche prise porte son horodatage de prise. Sans lui, impossible de distinguer une tâche en cours d'une tâche dont le consommateur est mort.
« Relancer » est le seul chemin de retour d'une tâche échouée, et il est manuel. Une reprise automatique transformerait une erreur permanente — un jeton expiré, une adresse que le transporteur refusera toujours — en boucle infinie, silencieuse, et facturée à chaque tour.
Une tâche orpheline depuis plus de trente minutes est signalée, pas relancée. L'opération a peut-être abouti chez le transporteur sans que le consommateur ait pu le consigner ; la relancer coûterait une seconde étiquette. On la montre à un humain, qui décide.
Ce que le module ne fait pas
Il n'appelle aucun transporteur. Il ne calcule aucun tarif, n'achète aucune étiquette, ne rafraîchit aucun suivi et ne cherche aucun point relais. Installé seul, ses cinq méthodes d'extension refusent avec un message qui dit quel module opérateur installer. Ce n'est pas une panne : c'est l'état normal du socle.
Il ne redouble aucun champ d'Odoo : pas de modèle d'emballage parallèle, pas de dimensions ni de poids en double sur le colis. Il ne devine aucun plafond de transporteur et n'en propose aucun. Il n'analyse pas les horaires d'un point relais et ne vérifie jamais qu'un point est ouvert. Il ne valide pas un code SH — il vérifie seulement qu'il est là quand la destination l'exige.
L’application en mouvement
Le module en marche, enregistré dans le vrai client Odoo 19 : expedition, expedition (fiche), tache puis journal. Ce n’est pas un montage — ce sont les trames du navigateur sur le module livré, pris sur sa propre base.
Vidéo MP4 — 265 ko, 1280 px, 3.3 s, 4 écrans. Une amorce animée est aussi livrée en GIF (215 ko, 560 px) pour les contextes qui n’affichent pas la balise vidéo.
Compatibilité
Odoo 20 Community. Dépend de stock_delivery et
sale_management, tous deux dans Community.
Multi-société. Licence LGPL-3. Gratuit.
DYONYSOS — welcome@dyonysos.fr
Ce que l'application ne fait pas
- Il n'appelle aucun transporteur. Il ne calcule aucun tarif, n'achète aucune étiquette, ne rafraîchit aucun suivi et ne cherche aucun point relais. Installé seul, ses cinq méthodes d'extension refusent avec un message qui dit quel module opérateur installer. Ce n'est pas une panne : c'est l'état norm
- Il ne redouble aucun champ d'Odoo : pas de modèle d'emballage parallèle, pas de dimensions ni de poids en double sur le colis. Il ne devine aucun plafond de transporteur et n'en propose aucun. Il n'analyse pas les horaires d'un point relais et ne vérifie jamais qu'un point est ouvert. Il ne valide p
Applications du magasin nécessaires
Aucune.
Modules Odoo Community utilisés
sale_managementstock_delivery
| Série | Version | État | Publiée le |
|---|---|---|---|
| 20.0 | 20.0.1.0.0 | Disponible | 02/10/2026 |
| 19.0 | 19.0.1.0.0 | Disponible |
Fiche générée depuis le code de l'éditeur (dépôt privé, branche 20.0) : le code source n'est pas publié.
Contrôle automatique du magasin (distinct de l'éditeur), appliqué à toutes les applications. Conforme.
| Contrôle | Résultat | Effet si absent |
|---|---|---|
| Manifeste lisible sans exécution | conforme | bloquant |
| Licence reconnue (LGPL-3) | conforme | bloquant |
| Aucune dépendance vers Odoo Enterprise | conforme | bloquant |
| Aucun import de code Enterprise | conforme | bloquant |
| Aucun en-tête de licence Enterprise | conforme | bloquant |
| Icône static/description/icon.png | conforme | déclasse |
| Description (static/description/index.html ou README) | conforme | déclasse |
| Tests automatisés (tests/test_*.py) | conforme | déclasse |
| Traduction française (i18n/fr.po) | conforme | info |
| Section « Ce que le module ne fait pas » | conforme | info |
| Titre de 70 caractères au plus (71 actuellement) | absent | info |
| Résumé en français | absent | info |
Guide d'utilisation — Socle multi-transporteurs
Ce que ce module fait, et ce qu'il ne fait pas
Il ne parle à aucun transporteur. Il n'achète pas d'étiquette, ne calcule pas de tarif, ne cherche pas de point relais et n'interroge personne. Installé seul, il prépare et il refuse — et quand il refuse, il dit pourquoi.
Pour qu'Odoo se mette à parler à un transporteur, il faut lui adjoindre le module opérateur correspondant. Celui-ci se greffe sur le socle sans rien y changer.
1. Décrire vos emballages — dans l'écran d'Odoo, pas dans un second
Inventaire → Expéditions → Paramétrage → Types de colis
Ce menu ouvre l'écran natif d'Odoo. Le module n'en crée pas un deuxième : vous saisiriez deux fois les mêmes mesures, et elles divergeraient au premier oubli.
Un type de colis porte déjà tout ce qu'un transporteur demande :
- Taille (
Longueur × Largeur × Hauteur) — les dimensions du colis ; - Poids (la tare) — le poids de l'emballage vide. Odoo l'ajoute tout seul au poids du contenu, et c'est ce total que le transporteur facture ;
- Poids max — ce que l'emballage supporte, indépendamment de ce que le transporteur accepte.
Le module y ajoute une seule ligne : Longueur + circonférence, calculée pour vous depuis les trois dimensions. Ce n'est pas une mesure de plus à saisir — c'est le chiffre que les transporteurs plafonnent et qu'Odoo ne calcule nulle part.
Et le poids d'un colis ?
Vous n'avez rien à saisir. Odoo additionne le poids des articles
(product.template.weight) et la tare du type de colis. Si vous posez le colis
sur une balance, renseignez Poids d'expédition sur le colis : le poids pesé
prime alors sur le calcul — une balance a toujours raison contre une fiche
produit.
2. Déclarer vos services et leurs plafonds
Inventaire → Expéditions → Paramétrage → Services et plafonds, ou l'onglet « Services et plafonds » d'un mode de livraison.
C'est l'étape qui fait tout le reste. Sans service sur une expédition, aucun plafond n'est contrôlé : le module laissera passer un colis de 300 kg.
Pour chaque service, vous saisissez :
| Champ | Sens |
|---|---|
| Poids maximal | Par colis, tare comprise. Se combine avec le poids max du type de colis : le plus bas des deux s'applique |
| Longueur / largeur / hauteur maximales | Arête par arête |
| Longueur + circonférence maximale | longueur + 2 × (largeur + hauteur) |
| Point relais obligatoire | Le service ne livre qu'en relais |
| Contrôler la déclaration douanière | À décocher pour un service strictement national |
| Contrôler l'adresse du destinataire | À décocher pour un retrait en entrepôt |
Zéro signifie « aucun plafond déclaré », donc aucun contrôle. Ce n'est pas un oubli du module : c'est la seule façon honnête de dire qu'on ne sait pas.
Pourquoi le module ne vous propose aucun chiffre
Les limites d'un transporteur changent d'un pays à l'autre, d'un service à l'autre et d'une année sur l'autre. Un chiffre écrit dans le code serait faux le jour où le transporteur le change, et personne ne s'en apercevrait — le module continuerait d'accepter ce que le transporteur refuse désormais.
Le champ Source des plafonds est là pour cela. Écrivez-y d'où vous tenez le chiffre et quand vous l'avez relevé :
Grille tarifaire 2026 du transporteur, page 4, relevée le 12/01/2026
Sans cette ligne, personne ne saura dans six mois si le plafond est encore juste.
3. Les exigences d'adresse par pays
Inventaire → Expéditions → Paramétrage → Exigences d'adresse par pays
Vous pouvez ne rien saisir ici : le module s'appuie alors sur ce qu'Odoo sait déjà de chaque pays (code postal et province obligatoires ou non).
Ajoutez une ligne quand une destination réclame davantage — un téléphone joignable à l'arrivée, un numéro de TVA pour dédouaner un envoi professionnel.
Le nom, la rue, la ville et le pays sont exigés partout : sans eux, aucun transporteur ne sait où aller.
4. Les points relais
Inventaire → Expéditions → Paramétrage → Points relais
Le socle ne cherche aucun point relais. Saisissez ceux que vous utilisez, ou laissez un module opérateur venir les y déposer.
Le point relais se choisit sur la commande, et suit automatiquement jusqu'au bon de livraison — sans ressaisie, parce que c'est exactement le genre de ressaisie qui envoie un colis au mauvais relais. Il s'imprime sur le bon de livraison, sous les informations de l'en-tête.
5. Préparer une expédition
Depuis un bon de livraison confirmé, bouton Créer l'expédition. Le transporteur, le point relais et — s'il n'y en a qu'un — le service sont repris.
Renseignez les colis : chaque colis porte son poids pesé, ses dimensions et son emballage. L'expédition consolide le tout.
Puis Préparer. Deux issues :
- tout est cohérent → l'expédition passe à Prête ;
- quelque chose bloque → le module refuse, en nommant ce qui manque et la valeur en cause.
À quoi ressemble un refus
Colis COLIS-0003 : hauteur de 82,0 cm pour un maximum de 60,0 cm sur le service « Domicile ».
Colis COLIS-0001 : poids de 12,000 kg pour un maximum de 8,000 kg imposé par le type de colis « Carton 30 × 20 × 15 ». Dépassement de 4,000 kg.
Adresse incomplète pour France : il manque la rue, le code postal sur le destinataire « Client Lille ».
Déclaration douanière incomplète pour Suisse, hors Union européenne : il manque le motif d'exportation, le code SH, le pays d'origine des marchandises, la valeur douanière.
Point relais non choisi : le service « Relais » du transporteur « ... » ne livre qu'en point relais.
Jamais « expédition invalide ». Un message qui n'apprend rien fait perdre dix minutes à chaque fois.
Le bandeau rouge du formulaire affiche ces motifs en direct, sans qu'il soit nécessaire de cliquer sur Préparer. Et le filtre Bloquées de la liste montre d'un coup d'œil toutes les expéditions qui attendent une correction.
Le module rend tous les motifs à la fois, pas le premier : corriger une erreur pour en découvrir une autre à l'essai suivant, c'est trois allers-retours au lieu d'un.
6. Les six règles de refus
- Poids — le poids d'un colis dépasse le plus contraignant des deux plafonds : celui du type de colis et celui du service. Le refus dit lequel a mordu, sinon vous corrigez le mauvais.
- Dimensions — une arête dépasse son maximum, colis par colis.
- Longueur + circonférence — la somme dépasse la limite. C'est la règle qui attrape le colis dont chaque arête est pourtant conforme.
- Adresse — un champ exigé par le pays de destination manque.
- Douane — un envoi hors Union européenne manque sa déclaration : motif d'exportation, code SH, pays d'origine, valeur douanière.
- Point relais — le service l'exige et aucun n'est choisi.
7. Le journal
Inventaire → Expéditions → Journal, ou l'onglet « Journal » d'une expédition.
Chaque tentative — réussie ou non — y laisse une ligne datée avec son opérateur, sa demande résumée, sa réponse et sa durée. On n'efface pas une tentative, on en ajoute une autre.
Le journal est un outil de diagnostic, pas une archive comptable : une tâche planifiée hebdomadaire purge ce qui a plus de six mois.
Le socle ne consigne jamais d'identifiants ni de jetons — seulement un résumé de ce qui a été demandé.
8. La file
Inventaire → Expéditions → File d'expédition
Odoo tient la file, un processus externe la consomme. Odoo n'appelle personne lui-même : un Odoo qui lance des appels transporteurs tombe avec eux, et bloque un worker HTTP pendant que le transporteur réfléchit.
Les trois règles de la file
Une tâche prise porte son horodatage de prise. Sans lui, impossible de distinguer une tâche en cours d'une tâche dont le consommateur est mort.
« Relancer » est le seul chemin de retour d'une tâche échouée. Il est manuel, et c'est le point. Une reprise automatique transformerait une erreur permanente — un jeton expiré, une adresse que le transporteur refusera toujours — en boucle infinie, silencieuse, et facturée à chaque tour.
Une tâche orpheline est signalée, jamais relancée. Au-delà de 30 minutes (réglable), une tâche encore « en cours » passe en orange avec un message. Elle n'est pas remise dans la file : l'opération a peut-être abouti chez le transporteur sans que le consommateur ait eu le temps de le consigner, et la relancer coûterait une seconde étiquette. Allez vérifier chez le transporteur, puis décidez : « Relancer » ou « Annuler ».
9. Brancher un opérateur
Tant qu'aucun module opérateur n'est installé, les boutons Tarifer, Étiqueter, Suivre, Annuler et Chercher des points relais existent mais refusent, avec un message qui dit quoi installer :
Le mode de livraison « ... » ne sait pas exécuter l'opération « Tarifer » : aucun module opérateur ne la prend en charge. Le socle multi-transporteurs ne parle à aucun transporteur, par construction. Installez le module opérateur correspondant à ce transporteur pour que cette opération devienne disponible.
Ce n'est pas une panne. C'est l'état normal du socle installé seul.
Questions fréquentes
Pourquoi mon colis de 300 kg passe-t-il ? Ni le type de colis ni le service ne déclarent de poids maximal — zéro des deux côtés signifie « aucun plafond déclaré », pas « zéro kilo ». Le module ne devine aucune limite. Renseignez Poids max sur le type de colis, sur le service, ou sur les deux.
J'ai mis 10 kg sur le service et 8 kg sur le type de colis. Lequel gagne ? Le plus bas : 8 kg. Ils ne disent pas la même chose — le type de colis dit ce que le carton supporte, le service ce que le transporteur accepte. Dépasser l'un ou l'autre se paie, l'un par un carton qui cède, l'autre par un colis refusé.
Cinq colis de 2 kg avec un plafond de 5 kg : pourquoi ça passe ? Parce qu'un plafond de service est un plafond par colis, pas sur le total. Contrôler la somme refuserait une expédition parfaitement acceptable.
Pourquoi deux colis conformes déclenchent-ils un refus de dimensions ? Ils ne devraient pas : le contrôle se fait colis par colis, et le refus nomme le colis fautif. Si vous n'avez pas encore constitué de colis, le contrôle porte sur les mesures saisies à la main sur l'expédition.
Le point relais ne s'imprime pas. Vérifiez qu'il est bien renseigné sur le bon de livraison et pas seulement sur la commande. La reprise se fait à la confirmation de la commande ; un bon de livraison créé autrement ne l'a pas.
Une tâche est bloquée « en cours » depuis ce matin. Elle sera signalée orpheline au plus tard dans les 30 minutes. Elle ne sera pas relancée : allez vérifier chez le transporteur si l'opération a abouti, puis « Relancer » ou « Annuler ».
Avis des clients connectés. Un avis noté par client ; l'éditeur peut y répondre. Connectez-vous pour laisser un avis.
- Éditeur
- DYONYSOS
- contact@omnifloo.com
- Clients Omnifloo
- Support inclus selon votre formule : centre d'aide.
