Le projet en un coup d’œil
Les ventes professionnelles devaient devenir comparables et consultables sans réduire Odoo à un simple export de chiffre d’affaires.
Ciama sélectionne les ventes confirmées, charge leurs relations, crée ou actualise commandes et lignes, puis les rattache au référentiel commercial.
Recherche, statut de livraison, client, commercial, TVA, achats, coûts et marge sont réunis sans confondre valeur réelle et estimation.
Une commande professionnelle ne se résume pas à un montant et à une date. Pour la piloter, il faut retrouver la société cliente, le commercial responsable, les produits commandés, ce qui reste à livrer, la TVA applicable, le coût d’achat retenu et la part de marge qui repose encore sur une estimation. Dans l’ERP, ces éléments existent, mais leur lecture transversale demande du temps et leur comparaison avec les autres univers de vente reste difficile.
Dawap a construit dans Ciama une chaîne dédiée aux commandes B2B issues d’Odoo 19. Elle sélectionne les ventes confirmées du périmètre professionnel, charge les commandes avec leurs lignes, partenaires et commerciaux, puis alimente un modèle commun de commandes, clients, produits et offres. Le cockpit restitue ensuite chaque vente avec son état logistique et son équation financière.
La version fonctionnelle cohérente a été finalisée le 18 mars 2026, après l’enrichissement des coûts, de la TVA et des interfaces de contrôle. Ce chantier forme une preuve concrète de Ciama B2B : faire dialoguer l’ERP et le pilotage commercial sans masquer les données absentes, sans inventer une marge certaine et sans transformer un indicateur de stock en mécanisme de réservation.
1. Un cockpit B2B relié au système de gestion qui porte la vente
Conserver la richesse d’Odoo tout en donnant une vue exploitable aux équipes
Le périmètre concernait des commandes professionnelles gérées dans Odoo 19. Une commande pouvait associer une société, des adresses de facturation et de livraison différentes, un commercial, plusieurs produits, des quantités commandées puis livrées et une devise de vente.
Le besoin n’était pas de remplacer l’ERP. Odoo reste la source des ventes et de leurs relations. Ciama devait organiser ces données dans un univers B2B distinct, les rapprocher des référentiels déjà utilisés pour les produits, les achats et les entrepôts, puis offrir une lecture conçue pour le suivi quotidien.
Cette position évite deux écueils. Le premier aurait été de copier uniquement le total TTC, sans pouvoir expliquer le reste à livrer ni la marge. Le second aurait été de mêler automatiquement les règles B2B aux offres marketplace, alors que les canaux, les prix et les engagements ne suivent pas le même fonctionnement.
Le projet a donc traité la commande comme un objet de liaison. Elle part d’un flux ERP, identifie les acteurs et les articles, alimente les calculs financiers, puis devient consultable dans un écran B2B. Les autres canaux peuvent réutiliser le même socle analytique sans perdre leur propre périmètre.
2. Sélectionner, charger, normaliser puis rendre chaque calcul vérifiable
Une progression depuis le flux source jusqu’à la décision commerciale
Le socle OMS a d’abord apporté la commande, la ligne et le canal. La verticalisation B2B a ensuite isolé le type de canal, ajouté la collecte par connexion ERP et construit une recherche spécifique. Les derniers lots ont consolidé les devises, la TVA, les coûts d’achat, les marges estimées et les vues de détail.
La collecte récurrente relit une fenêtre de deux heures à partir de la date de dernière modification dans Odoo. Une reprise historique indépendante travaille sur la date de commande et découpe la période en intervalles configurables, d’un jour par défaut. Cette séparation répond à deux besoins différents : suivre les changements récents et reconstruire une période connue.
Chaque vente collectée emprunte ensuite un chemin d’ajout ou de mise à jour. Les traitements sont distribués de manière asynchrone afin qu’une commande complexe ne bloque pas la lecture du lot complet. Le journal d’exécution conserve le compte, la connexion, la période, le mode et l’état du passage.
Le périmètre livré reste volontairement précis : support Odoo 19, règles de sélection explicites et effets sur le stock limités aux indicateurs réellement recalculés. Cette définition donne aux équipes un fonctionnement prévisible et laisse chaque extension future faire l’objet de ses propres règles.
3. Avant le projet : l’ERP enregistrait la vente, mais le pilotage restait fragmenté
Suivre la livraison et expliquer la marge imposaient plusieurs lectures
La liste des ventes dans un ERP répond d’abord à une logique de gestion. Pour un responsable commercial, la question est plus immédiate : quelles commandes restent à livrer, quels comptes sont concernés, quelles références concentrent le revenu et quelle marge peut réellement être défendue ?
Une extraction aplatie n’aurait pas suffi. Elle aurait perdu la relation entre commande, lignes, société cliente, adresse, vendeur, devise et produit. Elle aurait aussi figé le statut au moment de l’export, alors qu’une livraison partielle doit rester révisable.
Le calcul financier posait une difficulté supplémentaire. Le chiffre TTC ne donne ni le revenu hors taxes ni le coût complet. Une commission, un transport ou un achat peuvent être connus, estimés ou absents ; les additionner sans origine aurait produit une marge apparemment précise mais impossible à justifier.
Enfin, le B2B devait rester identifiable comme univers. Une vente professionnelle peut nourrir une vision globale du commerce, mais elle ne doit pas devenir une commande marketplace par simple rapprochement technique.
4. Définir précisément les commandes Odoo qui appartiennent au cockpit B2B
Société cliente, vente confirmée et convention de numérotation
Le lecteur Odoo 19 ne récupère pas toutes les lignes de vente du système. Il retient les commandes dont le partenaire est une société, dont l’état est sale ou done et dont le numéro respecte le préfixe VSO. Cette règle fermée matérialise le périmètre commercial attendu.
Pour une collecte récurrente, la période s’applique à la dernière modification : une commande ancienne modifiée récemment peut donc être relue. Pour une reprise historique, elle s’applique à la date de commande. Le même connecteur distingue ainsi l’activité courante de la reconstruction du passé.
Les commandes sont parcourues par pages de cent. Lors du passage récurrent, les plus récemment modifiées sont lues en premier ; lors de l’historique, le tri repose sur la date de commande. Une page vide ou incomplète termine proprement le parcours.
Cette sélection ne constitue pas un connecteur Odoo universel. Elle correspond à Odoo 19 et à la convention de vente du périmètre livré. Une autre version, un autre préfixe ou une autre qualification client demanderait une adaptation explicite.
5. Relire les deux dernières heures sans dupliquer les commandes
Une fenêtre glissante transformée en ajouts ou mises à jour
À chaque déclenchement planifié, Ciama inspecte les connexions actives dont les informations d’accès sont valides. Le fournisseur doit lui aussi être actif, disponible et déclaré comme ERP. La synchronisation des commandes B2B doit enfin être activée pour cette connexion.
La période va de l’instant du passage jusqu’à deux heures en arrière. Ce chevauchement accepte de revoir une commande déjà connue : l’identité associe son canal et son numéro, ce qui oriente ensuite la vente vers une mise à jour plutôt que vers un doublon.
Avant l’appel, un suivi d’exécution est ouvert avec le compte, la connexion, la fenêtre, le mode récurrent et un état en attente. La collecte elle-même est confiée à un message ; elle ne monopolise pas la commande planifiée pendant le traitement de toutes les ventes.
Une fois le lot reçu, chaque commande absente déclenche un ajout et chaque commande existante une actualisation. Les compteurs collectés, ajoutés et mis à jour donnent au run une sortie exploitable sans faire croire qu’une absence de nouveauté constitue un échec.
6. Reconstruire une période historique par intervalles contrôlés
Un chemin volontaire, distinct du cycle courant
La reprise historique demande un compte actif, puis une date de début, une date de fin et un intervalle. L’intervalle proposé est d’un jour, mais il peut être adapté à la profondeur et au volume de la période à récupérer.
Seuls les canaux B2B actifs avec des informations d’accès valides participent à cette reprise. Une date de début postérieure à la date de fin ou un intervalle invalide arrête la demande avant toute diffusion.
Le découpage protège la chaîne contre une extraction monolithique. Chaque intervalle peut être envoyé et suivi séparément ; une période dense ne force pas à charger tout l’historique dans une seule exécution.
Ce mécanisme rend également la reprise reproductible. Une équipe peut cibler une plage connue après une migration ou une interruption, sans modifier le comportement de la collecte récurrente des deux dernières heures.
7. Charger en lot les sociétés, adresses et commerciaux associés
Éviter un appel relationnel pour chaque commande
Pour chaque page de commandes, Ciama rassemble les identifiants des partenaires principal, de facturation et de livraison ainsi que ceux des utilisateurs commerciaux. Les partenaires et utilisateurs sont ensuite lus par groupes, puis indexés avant la transformation des ventes.
La société cliente conserve son identifiant externe, son nom, son email, son téléphone, son pays, son numéro de TVA et, lorsqu’elle existe, sa raison sociale. Elle est enregistrée dans l’univers et le segment B2B, puis reliée à la commande.
L’utilisateur Odoo affecté à la vente devient le commercial de la commande lorsqu’un identifiant et un nom sont disponibles. Son nom et son email sont conservés. Les compteurs du client et du commercial sont rafraîchis après un ajout ou un changement de rattachement.
Les adresses de facturation et de livraison restent séparées sous leur forme source. La vue de commande peut donc restituer le nom, la rue, le code postal, la ville, le pays et le téléphone de chaque destination sans supposer qu’elles sont identiques.
8. Transformer les lignes Odoo en produits et offres B2B identifiables
Conserver uniquement les articles physiques ou consommables du périmètre
Les lignes sont chargées par lots pouvant atteindre mille éléments pour les commandes de la page. Les types product et consu sont retenus ; une ligne sans produit exploitable est écartée. Ce choix évite de traiter une note ou une ligne de service comme un article de stock.
Le SKU provient en priorité du code placé entre crochets dans le libellé du produit Odoo. Si cette convention n’est pas disponible, le libellé du produit sert de repli ; en dernier recours, un identifiant construit à partir de l’identifiant Odoo empêche la disparition silencieuse de la ligne.
Dans Ciama, ce SKU recherche d’abord un alias du compte, puis un produit portant directement cet identifiant. Si aucun produit n’existe, le flux OMS peut créer une fiche minimale. L’offre B2B du canal est retrouvée avec le SKU et l’état de stock, ou créée lorsque nécessaire.
Le rapprochement alimente ensuite les quantités vendues du produit et de l’offre sur 90, 180 et 360 jours. Il ne transforme pas l’offre B2B en offre marketplace : seuls les canaux de type marketplace déclenchent le rafraîchissement spécialisé de diffusion.
9. Lire ce qui est commandé, livré et encore à expédier
Une traduction simple des états logistiques Odoo
Pour chaque ligne, Ciama conserve la quantité commandée et la quantité livrée. La quantité restant à expédier correspond à leur différence. Une livraison complète devient shipped, une livraison partielle partially_shipped et une ligne non livrée reste to_ship.
Le statut global suit le delivery_status de la commande Odoo : full devient expédiée, partial partiellement expédiée et les autres valeurs restent à expédier. Le cockpit ne déduit donc pas un état commercial à partir du seul montant facturé.
La commande B2B est marquée comme traitée par le vendeur. Lorsqu’une ligne dispose d’un entrepôt de livraison, celui-ci est rattaché à la ligne et permet de replacer les ventes dans leur contexte logistique.
Le résultat est une lecture progressive : la recherche montre l’état de la commande, puis sa fiche détaille les quantités par article. Une équipe peut ainsi distinguer une commande totalement ouverte d’une commande dont seul un reliquat reste à livrer.
10. Normaliser revenu, devise, TVA et coûts à la date de vente
Construire une équation financière avant de calculer la marge
La commande conserve son montant TTC et sa devise source. Lorsque la devise cible du compte est disponible, Ciama convertit le montant avec le taux correspondant à la date de commande. La monnaie d’affichage reste ainsi cohérente sans effacer la monnaie d’origine.
Pour chaque ligne, le taux de TVA est résolu à partir du compte, du produit et du pays de livraison. Le TTC est alors séparé entre revenu hors taxes et TVA, dans la devise source puis dans la devise cible lorsque la conversion est possible.
Les commissions sont normalisées en hors taxes et TTC selon la forme reçue. Le coût d’achat recherche une réception fournisseur exploitable pour le produit à la date de vente et enregistre sa provenance. Les agrégats de la ligne sont ensuite calculés de manière asynchrone.
Une donnée manquante reste manquante. L’écran affiche un tiret lorsque le revenu, le taux ou un coût ne peut pas être déterminé ; il ne remplit pas automatiquement le vide avec zéro lorsque ce zéro changerait le sens financier.
11. Distinguer la marge calculée de la marge estimée
Afficher la provenance de chaque composante avant le résultat
La recherche présente le revenu TTC, la TVA, le revenu HT, les frais, le transport, l’achat, le bénéfice et son taux. Les couleurs ne suffisent pas : chaque coût cliquable indique aussi s’il repose sur une valeur réelle ou estimée et expose son origine.
La marge est considérée comme réelle lorsque le bénéfice, son taux et les trois familles de coûts requises sont effectivement renseignés. Sinon, l’interface utilise la variante estimée lorsqu’elle existe. Le même principe s’applique au détail des lignes.
Une fenêtre décompose le calcul entre revenu hors taxes, commission, transport, achat et résultat net. Si le calcul est bloqué, son erreur est conservée et affichable. L’utilisateur ne voit donc pas seulement un pourcentage ; il peut retrouver pourquoi ce pourcentage existe ou pourquoi il manque.
Cette transparence rejoint le projet de marge par commande marketplace, mais le présent chantier l’applique à l’univers B2B et à ses ventes issues de l’ERP.
12. Installer un radar B2B pour les opérations quotidiennes
Canal, statut, mode et période dans une recherche paginée
La recherche est limitée au compte connecté et impose le type de canal B2B. Cinquante commandes sont présentées par défaut, de la plus récente à la plus ancienne selon leur date d’achat. La pagination conserve les filtres actifs.
Le texte libre permet de retrouver une commande ; le canal, le statut et le mode de traitement affinent ensuite la liste. Le mode distingue FBM, lorsque le vendeur gère la livraison, et FBP, lorsque la plateforme en porte la responsabilité.
L’année courante est sélectionnée par défaut. L’utilisateur peut choisir une année depuis 2019 puis, lorsqu’une année est active, limiter la vue à un mois. Les facettes rappellent les critères appliqués pour éviter une lecture erronée d’un sous-ensemble.
La table rapproche enfin logistique et finance : canal, numéro et date, statut, mode, pays de livraison, revenus, coûts, marge et date de dernière mise à jour. Une commande à risque n’est plus séparée de son impact économique.
13. Ouvrir la commande sans perdre ses relations métier
Adresses, client, articles et finance dans une même fiche
La fiche de commande vérifie d’abord que la vente appartient au compte de l’utilisateur. Elle vérifie ensuite que son canal appartient bien à l’univers B2B ; une commande d’un autre univers est renvoyée vers sa vue générale plutôt que présentée sous la mauvaise navigation.
L’en-tête synthétise la commande et son résultat. Les blocs d’adresse distinguent facturation et livraison, tandis que le client relié peut être ouvert depuis la fiche. Ces relations donnent un contexte que la table de recherche ne peut pas contenir sans devenir illisible.
Chaque ligne affiche le SKU, la quantité, les montants TTC, TVA et HT, les coûts, la marge nette et son taux. Lorsque le produit ou l’offre sont reliés, l’utilisateur peut rejoindre leurs vues pour poursuivre le diagnostic.
Les coûts réels et estimés restent différenciés au niveau de la ligne comme au niveau de la commande. Le détail ne sert donc pas seulement à additionner : il permet d’identifier l’article ou la composante responsable d’une marge incomplète ou négative.
14. Mettre à jour la vitesse de vente sans réserver le stock
Un effet analytique, pas une écriture d’inventaire
Lorsqu’une ligne de commande possède un entrepôt de livraison et qu’une parcelle de stock correspondante existe, Ciama recalcule trois informations : le stock de l’entrepôt par défaut, la quantité vendue sur 90 jours depuis cet entrepôt et la date de rupture estimée.
Les quantités vendues sur 90, 180 et 360 jours sont également rafraîchies pour le produit et l’offre concernés. La commande B2B contribue ainsi à la lecture de la demande réelle et à la couverture du catalogue.
Aucune instruction de ce chemin ne retire directement la quantité commandée de la parcelle, ne crée une réservation et n’envoie un stock cible à une marketplace. L’inventaire reste alimenté par ses propres sources ; la vente enrichit ses indicateurs de consommation.
Cette séparation protège les décisions de stock par entrepôt. Une commande explique pourquoi la couverture évolue, mais une règle logistique dédiée doit décider ce qui est disponible, engagé ou diffusable.
15. Cloisonner les données par compte, connexion et univers
Une vente ne doit jamais traverser le mauvais périmètre
La collecte exige une connexion active avec des informations d’accès valides. Lorsqu’un canal est imposé, son compte et son fournisseur doivent correspondre à ceux de la connexion. Sans canal explicite, un canal actif unique doit pouvoir être résolu ; une ambiguïté arrête le passage.
La recherche applique systématiquement l’identifiant du compte connecté et le type btob. Les listes de canaux, clients, produits, alias et achats utilisent la même frontière. Un SKU identique dans deux comptes ne constitue pas une correspondance partagée.
La fiche commande contrôle à nouveau le propriétaire avant le rendu. Une vente absente produit une erreur de ressource ; une vente d’un autre compte produit un refus d’accès. La route B2B ne devient donc pas un raccourci vers une commande devinée par son identifiant.
Le type de canal sert aussi de garde-fou fonctionnel. Les commandes professionnelles participent aux agrégats communs, mais les traitements réservés aux offres marketplace restent conditionnés à leur propre univers.
16. Les arbitrages qui rendent le cockpit crédible
Préférer une donnée expliquée à une promesse trop large
Le premier arbitrage consiste à sélectionner un périmètre Odoo explicite plutôt qu’à annoncer toutes les commandes professionnelles possibles. Les sociétés, les états confirmés et le préfixe VSO rendent la règle contrôlable et adaptable.
Le deuxième sépare collecte récurrente et historique. La date de modification capte les changements récents ; la date de commande reconstruit une période commerciale. Utiliser un seul repère aurait soit manqué des mises à jour, soit relu inutilement une grande profondeur.
Le troisième conserve les variantes réelle et estimée des coûts. Une estimation peut aider à prioriser, mais elle ne prend pas la place d’un coût certifié. Son origine et les causes de blocage restent visibles.
Le quatrième limite l’effet stock aux recalculs observés. Le projet fournit de la demande et de la couverture ; il ne s’attribue ni réservation, ni allocation, ni synchronisation d’offre. Cette frontière est plus utile qu’une fausse promesse de stock partagé en temps réel.
17. Rendre visibles les limites de la version livrée
Un connecteur spécialisé et des calculs dépendants de leurs sources
Le flux B2B livré repose sur Odoo 19. Sa règle de sélection attend des sociétés, des commandes confirmées ou terminées et un numéro VSO. Ce comportement ne garantit pas une compatibilité automatique avec toutes les versions et configurations Odoo.
Les lignes de service sont exclues ; seules les lignes product et consu portant un produit exploitable deviennent des lignes de commande Ciama. Une commande sans ligne retenue est signalée dans le suivi au lieu d’être silencieusement considérée comme complète.
Le revenu hors taxes dépend d’un taux de TVA résolu. La conversion dépend d’une devise et d’un taux disponibles à la date de vente. La marge dépend enfin de coûts exploitables. Lorsqu’une précondition manque, le cockpit expose le vide ou l’estimation.
Les adresses, clients et commerciaux proviennent des relations Odoo disponibles au moment de la lecture. Leur rattachement améliore le contexte commercial, mais ne constitue pas un CRM complet ni une preuve de qualité absolue du référentiel source.
18. Ce qui change après la livraison
La commande B2B devient suivable, explicable et comparable
L’équipe commerciale dispose d’une liste B2B stable plutôt que d’une extraction ponctuelle. Elle filtre la période, le canal, le statut et le mode de livraison, puis ouvre la commande qui demande une relance ou une vérification.
Le suivi logistique descend jusqu’à la ligne. Quantité commandée, livrée et restante permettent d’identifier un reliquat sans interpréter manuellement plusieurs écrans ERP. Les adresses et la société restent disponibles dans la même fiche.
La finance retrouve l’équation du résultat. Revenu HT, commission, transport et achat sont séparés ; réel, estimé et bloqué ne sont pas confondus. Une marge négative ou absente devient un diagnostic à conduire, pas seulement une couleur dans un tableau.
Le catalogue bénéficie d’une demande consolidée. Les produits et offres reçoivent leurs quantités vendues récentes ; lorsqu’un entrepôt est relié, la couverture peut être recalculée à partir des ventes qui y ont réellement été livrées.
Enfin, le pilotage global peut comparer le B2B aux marketplaces et à l’e-commerce grâce au dashboard de ventes multicanal. La comparaison devient possible parce que chaque univers a d’abord été structuré sans perdre ses règles.
19. Le scénario terrain qui résume le projet
Expliquer une commande partiellement livrée dont la marge reste estimée
Un responsable ouvre la recherche B2B sur le mois courant et filtre les commandes partiellement expédiées. Une vente importante apparaît avec son canal, son pays de livraison, son revenu et une marge affichée comme estimée.
Dans la fiche, il constate qu’un article est totalement livré et qu’un second possède encore un reliquat. L’adresse de livraison et la société cliente sont immédiatement disponibles ; le commercial rattaché peut reprendre le suivi avec le bon contexte.
Il ouvre ensuite la décomposition financière. Le revenu hors taxes et l’achat sont présents, mais un coût de transport manque encore. Le système conserve la marge estimée et son origine au lieu de la présenter comme un résultat réel.
Le produit a bien reçu ses quantités vendues récentes. Si la ligne est rattachée à un entrepôt, sa consommation des 90 derniers jours et sa rupture estimée sont recalculées. Aucune unité n’a cependant été réservée par cette vue : l’équipe logistique garde la décision d’inventaire.
La commande peut alors être traitée sur deux axes distincts : achever la livraison du reliquat et fiabiliser le coût manquant. Ciama relie les deux lectures sans les confondre, ce qui était précisément l’objectif du chantier.
20. Relier ce cockpit aux briques voisines sans raconter deux fois le même projet
ERP, finance, stock et reporting interviennent à des étapes différentes
Le connecteur ERP et référentiel métier raconte la fondation d’intégration qui permet à Odoo d’alimenter Ciama. La présente fiche se concentre sur ce que devient une commande B2B une fois ce lien opérationnel.
La marge par commande marketplace approfondit l’équation financière des ventes marketplace. Ici, la même exigence de traçabilité sert les ventes professionnelles et leurs coûts issus du contexte ERP.
Le stock par entrepôt porte la quantité d’inventaire, sa composition et sa couverture. Le projet B2B lui fournit une consommation récente lorsqu’un entrepôt de livraison est connu, sans prendre la main sur l’allocation.
Le dashboard de ventes multicanal réunit enfin B2B, marketplaces et e-commerce pour la comparaison de direction. Il s’appuie sur les univers structurés par des projets comme celui-ci.
21. Conclusion
Une vente professionnelle devient pilotable quand son origine, son état et son résultat restent explicables
Ce projet a transformé un flux de commandes Odoo 19 en un véritable univers B2B dans Ciama. La sélection des ventes, la pagination, les relations clients et commerciaux, les lignes produit puis les ajouts et mises à jour asynchrones forment une chaîne cohérente.
Le cockpit rapproche ensuite suivi et finance : livraison totale ou partielle, adresses, quantités, TVA, achats, autres coûts et marge. Surtout, il conserve la frontière entre une valeur réelle, une estimation et une donnée indisponible.
Cette discipline résume la valeur de Ciama B2B : prolonger l’ERP par une lecture commerciale actionnable, nourrir le stock et le reporting avec des faits, puis laisser chaque décision — livraison, marge, allocation ou diffusion — au bon niveau.