Une commande de vente a une date de livraison. Dans la vraie vie, elle en a plusieurs : l'article en stock part demain, celui qui vient d'Italie dans trois semaines, et le client sait très bien qu'il attend les deux séparément.
Odoo raisonne par commande. Douze modules communautaires font descendre la date, l'état de livraison et l'annulation au niveau de la ligne — là où le métier les décide.
Résumé
sale_order_line_date ajoute une date d'engagement par ligne, propagée aux mouvements de stock, et sale_delivery_split_date en tire la conséquence logistique : une commande dont les lignes portent des dates différentes génère plusieurs bons de livraison, un par date. sale_order_requested_delivery trace en plus la période souhaitée par le client, en-tête et ligne, qui n'est pas la même chose que la date qu'on s'engage à tenir.
sale_order_line_delivery_state affiche un état de livraison détaillé par ligne — rien, non traité, partiel, terminé — là où le standard ne le donne qu'au niveau de la commande, et permet de forcer une ligne à « terminé » quand le client renonce au reste. sale_order_line_cancel annule proprement la quantité restant à livrer en la traçant dans un champ dédié, plutôt qu'en réduisant la quantité commandée — et son module de colle annule effectivement les mouvements de stock correspondants.
Trois modules servent la traçabilité (mouvements chaînés, historique des mouvements du produit, dates effectives de première et dernière livraison), et deux corrigent des comportements gênants : la suppression d'une ligne sur commande confirmée, et le recalcul automatique de la remise quand on change une quantité.
L'essentiel
- Une date d'engagement par ligne, propagée aux mouvements de stock et aux livraisons.
- Un bon de livraison par date demandée — la conséquence logistique, sinon tout repart ensemble.
- La période souhaitée par le client, distincte de la date promise : deux informations, deux champs.
- L'état de livraison ligne par ligne, avec la possibilité de forcer « terminé » quand le client abandonne le reliquat.
- L'annulation du reliquat traçable : une quantité annulée distincte de la quantité commandée, et un réglage de société pour décider si elle réduit aussi la quantité à facturer.
- La remise négociée protégée : empêcher Odoo de la recalculer dès qu'une quantité change.
- La suppression d'une ligne sur commande confirmée, autorisée sous condition et après activation explicite.
Ce que ces modules ajoutent à l'instance
| Module | Rôle | Version | Dépend de |
|---|---|---|---|
sale_order_line_date | Date d'engagement par ligne | 18.0.1.0.2 | sale_stock |
sale_delivery_split_date | Un bon de livraison par date | 18.0.1.0.0 | sale_order_line_date, sale_procurement_group_by_line |
sale_order_requested_delivery | Période souhaitée par le client | 18.0.1.0.0 | sale |
sale_order_line_date_next_reception | Prochaine date de réception sur la ligne | 18.0.1.0.0 | product_next_reception_date, sale |
sale_order_line_effective_date | Dates effectives de première et dernière livraison | 18.0.1.1.0 | sale_stock |
sale_order_line_delivery_state | État de livraison détaillé par ligne | 18.0.1.0.0 | sale |
sale_order_line_cancel | Annulation traçable du reliquat | 18.0.1.1.1 | sale |
sale_order_line_cancel_sale_stock | Colle : annule aussi les mouvements de stock | 18.0.1.1.1 | sale_order_line_cancel, sale_stock |
sale_order_line_chained_move | Mouvements de stock chaînés depuis la ligne | 18.0.1.0.0 | sale_stock |
sale_order_line_stock_move_history | Historique des mouvements du produit | 18.0.1.0.0 | sale_management, sale_stock |
sale_order_line_remove | Supprimer une ligne sur commande confirmée | 18.0.1.0.0 | sale_management, sale_stock |
sale_order_qty_change_no_recompute | Ne pas recalculer la remise sur changement de quantité | 18.0.1.0.0 | sale |
Aucun n'ajoute de menu : tout se joue sur le formulaire de commande, sur ses lignes, et dans les bons de livraison produits.
Trois dates qu'il ne faut pas confondre
| Date | Module | Ce qu'elle dit |
|---|---|---|
| Date d'engagement de ligne | sale_order_line_date | Ce que nous promettons pour cette ligne |
| Période souhaitée | sale_order_requested_delivery | Ce que le client demande, en-tête et ligne |
| Dates effectives | sale_order_line_effective_date | Ce qui s'est réellement passé : première et dernière livraison |
Confondre la date demandée et la date promise est la première source de litige commercial. Les garder dans deux champs distincts permet enfin de mesurer l'écart — et de savoir si l'on tient ses engagements ou si l'on déçoit des attentes qu'on n'avait jamais acceptées.
La troisième ligne du tableau ferme la boucle : avec les dates effectives calculées sur chaque ligne, le taux de service se mesure sans ressaisie. C'est le chiffre que réclament les donneurs d'ordre industriels, et que la plupart des PME fournissent à la main.
Un quatrième module complète le tableau côté approvisionnement : sale_order_line_date_next_reception affiche sur la ligne la prochaine date de réception attendue du produit. Le vendeur au téléphone sait alors quand il pourra livrer, au lieu de promettre et de vérifier après.
La conséquence logistique : plusieurs livraisons
Donner des dates différentes aux lignes ne sert à rien si tout part dans un seul bon de livraison à la date la plus lointaine. C'est pourtant le comportement par défaut.
- Installer
sale_order_line_datepour avoir des dates par ligne. - Installer
sale_delivery_split_date, qui dépend aussi desale_procurement_group_by_line. - À la confirmation, Odoo génère un bon de livraison par date demandée au lieu d'un seul regroupant toutes les lignes.
La dépendance du milieu mérite une explication : le groupe d'approvisionnement est ce qui décide du regroupement des mouvements dans Odoo. Le faire descendre au niveau de la ligne, c'est ce qui permet à deux lignes d'une même commande de suivre deux chemins logistiques distincts.
Ce découpage change la charge de l'entrepôt : plus de bons, donc plus de préparations. À combiner avec la préparation par lots, qui regroupe les transferts au moment de la préparation plutôt qu'au moment de la commande.
Le reliquat : le voir, puis le solder
Une commande partiellement livrée dont le client ne veut plus du reste est une situation hebdomadaire. Odoo standard n'offre pas de geste propre pour la clôturer.
Voir où en est chaque ligne
sale_order_line_delivery_state affiche un état détaillé par ligne : aucune livraison, non traité, partiellement traité, terminé. Le standard ne donne cet indicateur qu'au niveau de la commande entière — ce qui ne dit rien d'utile sur une commande de quinze lignes.
Le module permet aussi de forcer une ligne à « terminé », précisément pour le cas du client qui renonce au reliquat.
Annuler proprement ce qui ne partira pas
sale_order_line_cancelajoute une action pour annuler la quantité restant à livrer, sans toucher à la quantité commandée.- La quantité annulée vit dans un champ dédié et traçable : on sait ce qui a été commandé, ce qui a été livré, ce qui a été annulé.
- Un réglage de société décide si l'annulation réduit aussi la quantité à facturer.
sale_order_line_cancel_sale_stock— module de colle, sans écran — garantit que l'annulation annule effectivement les mouvements de stock correspondants.
La différence entre « réduire la quantité commandée » et « annuler le reliquat » n'est pas cosmétique : la première efface l'histoire commerciale, la seconde la conserve. Pour analyser son taux de service ou négocier avec un fournisseur, c'est la seconde qu'il faut.
Le second module est indispensable dès qu'on vend du stock : sans lui, l'annulation est une écriture commerciale que la logistique ignore, et les préparations restent ouvertes.
Tracer, et deux comportements à corriger
Remonter la chaîne depuis une ligne
| Module | Ce qu'il montre |
|---|---|
sale_order_line_chained_move | Tous les mouvements de stock issus de la ligne, y compris à travers une chaîne — livraison en plusieurs étapes, transferts inter-entrepôts |
sale_order_line_stock_move_history | Un bouton sur la ligne qui ouvre l'historique des mouvements du produit — réceptions, livraisons, transferts |
Le premier répond à « où en est cette ligne ? » dans un flux à plusieurs étapes, le second à « qu'est-ce qui s'est passé sur ce produit ? » sans quitter le devis. Les deux évitent l'aller-retour vers l'application Inventaire, qui est précisément ce qu'un commercial ne fera pas pendant un appel client.
Supprimer une ligne sur une commande confirmée
Odoo l'interdit. sale_order_line_remove l'autorise sous condition et après activation explicite d'un paramètre, en bloquant la suppression des lignes déjà facturées ou livrées.
C'est un assouplissement à manier avec précaution : la règle d'Odoo protège l'intégrité du lien commande-livraison-facture. Le module la lève proprement, mais il faut savoir qui a le droit de s'en servir.
Protéger une remise négociée
sale_order_qty_change_no_recomputeempêche Odoo de recalculer la remise et la règle de liste de prix d'une ligne quand seule la quantité ou l'unité change. Sans lui, une remise négociée à la main est écrasée dès que le client demande deux pièces de plus.
C'est l'un de ces modules dont personne ne demande l'installation, parce que personne ne soupçonne la cause : on croit à une erreur de saisie du vendeur. Il suffit d'avoir vu le problème une fois pour l'installer systématiquement.
La mécanique des remises elle-même est traitée dans les achats et leurs remises, qui expose le même motif côté fournisseur.
Limites connues
- Le découpage par date multiplie les bons de livraison : la charge de préparation augmente, à compenser par la préparation par lots.
sale_delivery_split_datedépend du groupe d'approvisionnement par ligne : c'est un changement structurant du comportement d'approvisionnement, pas un réglage d'affichage.- L'annulation du reliquat sans son module de colle laisse les mouvements de stock ouverts : installer les deux, toujours.
- La suppression d'une ligne confirmée demande une activation explicite et devrait être réservée à un rôle précis.
- Trois dates coexistent — demandée, promise, effective : sans règle d'usage écrite, les équipes remplissent la mauvaise.
sale_order_line_date_next_receptiondépend d'un module produit (product_next_reception_date) qu'il faut installer avec lui.
Identité technique
Les douze modules viennent du dépôt OCA sale-workflow, branche 18.0, en licence AGPL-3 sauf sale_order_line_effective_date (LGPL-3). Huit dépendent de sale_stock : ce sont des modules de vente avec livraison, sans objet sur une activité de service pur.
Le dépôt compte 172 modules au total. Les autres familles sont traitées dans la présentation des lignes et les types de commande et workflows.
Questions fréquentes
Peut-on avoir plusieurs dates de livraison sur une commande ?
Oui : sale_order_line_date ajoute une date d'engagement par ligne, propagée aux mouvements de stock. Pour que cela produise réellement des livraisons séparées, il faut y ajouter sale_delivery_split_date, qui génère un bon de livraison par date demandée au lieu d'un seul regroupant tout.
Quelle différence entre date demandée et date d'engagement ?
La date demandée est ce que le client souhaite (sale_order_requested_delivery, en-tête et ligne) ; la date d'engagement est ce que vous promettez (sale_order_line_date). Les garder distinctes permet de mesurer l'écart entre attente et promesse — et d'éviter le litige où chacun parle d'une date différente.
Comment solder une ligne dont le client ne veut plus ?
Deux gestes complémentaires : sale_order_line_delivery_state permet de forcer la ligne à « terminé », et sale_order_line_cancel annule la quantité restante en la traçant dans un champ dédié, sans toucher à la quantité commandée. Installez aussi sale_order_line_cancel_sale_stock, sans lequel les mouvements de stock resteraient ouverts.
Pourquoi la remise disparaît-elle quand on change une quantité ?
Parce qu'Odoo recalcule la remise et la règle de liste de prix dès que la quantité ou l'unité change — ce qui écrase une remise négociée à la main. sale_order_qty_change_no_recompute supprime ce recalcul. C'est souvent diagnostiqué à tort comme une erreur de saisie du vendeur.
Peut-on supprimer une ligne d'une commande confirmée ?
Pas en standard : Odoo l'interdit pour préserver le lien commande-livraison-facture. sale_order_line_remove l'autorise après activation explicite d'un paramètre, en bloquant les lignes déjà facturées ou livrées. À réserver à un rôle identifié, pas à tous les vendeurs.
Se faire accompagner
Ces douze modules racontent la même histoire : la commande n'est pas l'unité de gestion, la ligne l'est. Les entreprises qui livrent en plusieurs fois le savent, et le compensent avec des tableurs parallèles — ce qui finit par produire deux vérités sur l'état d'une commande.
Nous commençons donc par trancher trois questions : quelles dates l'entreprise suit, qui a le droit d'annuler un reliquat, et à quel moment la commande est considérée close. Le paramétrage découle de ces réponses, pas l'inverse. Voir les prestations d'Atalios Consulting ou demander un rappel.
Pour aller plus loin
- Lignes de commande : présentation et documents
- Préparations : lots, retours et liens facture
- La gestion des stocks et de la traçabilité dans Odoo
En résumé
La date, l'état de livraison et l'annulation descendent au niveau de la ligne — et la logistique suit, avec un bon de livraison par date. Le reliquat s'annule sans effacer l'histoire commerciale, et la remise négociée cesse d'être écrasée au premier changement de quantité. Parlons de vos délais de livraison.