Introduction
Dans Odoo, les « modèles » dictent la manière dont les informations sont organisées et conservées dans la base de données. Tout élément métier — devis, factures, contacts, commandes — trouve sa place dans un modèle dédié.
Maîtriser les modèles Odoo est indispensable, que vous soyez consultant fonctionnel ou développeur. Ils constituent l'ossature des données : définition des champs, relations entre objets et logique métier reposent dessus.
Cet article se concentre sur un modèle central : sales.order. Que vous configuriez des workflows commerciaux, développiez des modules sur mesure ou raccordiez des systèmes externes, vous serez amené à travailler avec lui.
Qu'est-ce que le modèle sales.order
Le modèle sales.order regroupe les devis et les commandes clients. C'est le point de collecte des transactions commerciales avant leur facturation ou livraison.
Ce modèle est utilisé par le module Ventes d'Odoo.
Un commercial crée un devis qui devient un enregistrement sales.order en brouillon ; une confirmation par le client le bascule en commande confirmée. Le même modèle contient donc à la fois les devis et les commandes, et le champ d'état (state) suit cette évolution.
D'autres modules viennent enrichir ce modèle via l'héritage : le CRM rattache opportunités et commandes, la comptabilité ajoute des données de facturation, l'inventaire apporte des dates de livraison et d'engagement. Chaque module complète le cœur sans le dupliquer.
Champs clés du modèle
Voici les champs essentiels du modèle sales.order à connaître pour manipuler correctement devis et commandes.
1. name
Type : Char. Référence visible de la commande ou du devis (ex. S00042). Souvent générée automatiquement et utilisée comme identifiant principal sur les listes et documents.
2. state
Type : Selection. Indique la phase du document (draft, sent, sale, done, cancel). Ce champ conditionne les actions possibles et le comportement des boutons.
3. partner_id
Type : Many2one (res.partner). Le client lié à la commande. Champ obligatoire qui sert de point d'ancrage pour la logique commerciale et les rapports.
4. partner_invoice_id
Type : Many2one (res.partner). Adresse de facturation. Par défaut reprise depuis partner_id mais utile quand la facture doit être envoyée ailleurs (ex. centralisation comptable).
5. partner_shipping_id
Type : Many2one (res.partner). Adresse de livraison. Utilisée pour générer les bons de livraison et calculer les frais d'expédition.
6. user_id
Type : Many2one (res.users). Le commercial ou l'utilisateur responsable. Sert pour le suivi, les commissions et l'attribution d'activités.
7. team_id
Type : Many2one (crm.team). L'équipe commerciale en charge. Pratique pour regrouper les performances et piloter les objectifs.
8. date_order
Type : Datetime. Date de l'ordre : date de création pour un brouillon, date de confirmation pour une commande. Utile pour le reporting et le tri.
9. validity_date
Type : Date. Date d'expiration du devis. Permet de gérer des offres à durée limitée.
10. commitment_date
Type : Datetime. Date promise pour la livraison. Si renseignée, les livraisons se planifient autour de cette date plutôt que des délais produits.
11. order_line
Type : One2many (sale.order.line). Les lignes de commande : produit, quantité, prix, taxes. Cœur du détail commercial.
12. amount_untaxed
Type : Float. Sous-total hors taxes, calculé depuis les lignes. Affiché pour information et reporting.
13. amount_tax
Type : Float. Montant total des taxes, calculé selon la configuration fiscale des lignes.
14. amount_total
Type : Float. Montant TTC de la commande, valeur clé pour la facturation et les comptes.
15. currency_id
Type : Many2one (res.currency). Devise utilisée pour la commande. Héritée du prix ou de la société, et appliquée à tous les montants.
16. pricelist_id
Type : Many2one (product.pricelist). La grille tarifaire utilisée pour déterminer les prix unitaires sur les lignes.
17. payment_term_id
Type : Many2one (account.payment.term). Conditions de paiement (ex. Net 30). Transmises lors de la création de la facture.
18. fiscal_position_id
Type : Many2one (account.fiscal.position). Position fiscale utilisée pour adapter les taxes selon le pays ou les régimes particuliers.
19. client_order_ref
Type : Char. Référence client ou n° de bon de commande fourni par le client, affichée sur les documents.
20. origin
Type : Char. Document source (ex. opportunité CRM) permettant la traçabilité entre enregistrements.
21. create_date
Type : Datetime. Date et heure de création de l'enregistrement, gérée automatiquement par Odoo.
22. write_date
Type : Datetime. Date et heure de la dernière modification, utile pour l'audit.
23. note
Type : Text. Cahier des charges, conditions générales ou notes internes affichables sur le devis ou la facture.
24. require_signature
Type : Boolean. Si activé, la signature en ligne du client est requise avant confirmation — utile pour le e‑commerce et le portail client.
25. require_payment
Type : Boolean. Si activé, un paiement est exigé avant confirmation (pré‑paiement, dépôt).
26. invoice_status
Type : Selection. Indique l'état de facturation : non facturé, à facturer, facturé, ou complément à facturer.
27. locked
Type : Boolean. Si vrai, la commande ne peut plus être modifiée — souvent verrouillée après confirmation ou lors de la publication de documents liés.
28. company_id
Type : Many2one (res.company). Dans un environnement multi‑sociétés, indique l'entité à laquelle appartient la commande.
29. tag_ids
Type : Many2many (crm.tag). Étiquettes de catégorisation pour filtres, rapports et segmentation métier.
30. signed_by
Type : Char. Nom de la personne ayant signé lorsque la signature est requise, conservé pour l'audit.
31. signed_on
Type : Datetime. Date et heure de la signature électronique.
32. prepayment_percent
Type : Float. Pourcentage à verser en avance lorsque require_payment est activé.
Comment ce modèle s'insère dans les processus métiers
1. Devis vers commande
Le commercial crée un devis, complète les lignes et envoie au client. Après confirmation, le devis passe en commande (state = sale) ; factures et bons de livraison peuvent alors être générés.
2. E‑commerce et portail client
Les commandes passées depuis le site web créent des enregistrements sales.order. Les options require_signature et require_payment permettent d'exiger paiement ou signature avant confirmation.
3. Du CRM vers les ventes
Lorsqu'une opportunité est gagnée, on génère un devis lié par le champ origin. user_id et team_id alimentent ensuite les rapports et calculs de commission.
4. Facturation
À partir d'une commande confirmée, on crée des factures dont les lignes reprennent les order_line. Les termes de paiement et la position fiscale proviennent de la commande.
5. Livraison et date d'engagement
La commitment_date sert à planifier les livraisons : si renseignée, les mouvements logistiques se caleront sur cette date. partner_shipping_id définit l'adresse de livraison.
Comment les développeurs étendent ce modèle
Les développeurs enrichissent sales.order via plusieurs approches, l'héritage de modèle restant la méthode la plus utilisée.
Héritage de modèle
Déclarez _inherit = 'sale.order' dans votre module pour ajouter des champs, redéfinir des méthodes ou poser des contraintes. L'héritage permet d'isoler vos modifications sans toucher au cœur, facilitant les mises à jour.
Ajout de champs
Déclarez de nouveaux champs dans le modèle hérité en choisissant le type adapté (Char, Many2one, Boolean, Integer, Text, Selection). Pensez aux champs dépendants de la société pour les environnements multi‑sociétés.
Extensions Python
Surchargez des méthodes comme action_confirm, create ou write pour injecter de la logique métier. Appelez systématiquement super() pour préserver le comportement existant, et soyez attentif aux champs calculés et à leurs dépendances.
Odoo Studio
Odoo Studio permet d'ajouter des champs et vues sans code — pratique pour des ajustements rapides. Pour des besoins complexes ou maintenables à long terme, privilégiez un module custom.
Bonnes pratiques
- Utilisez toujours l'état adéquat pour chaque étape : ne sautez pas d'étape ni ne contournez la logique de confirmation.
- Renseignez commitment_date quand vous avez un engagement de livraison client : cela améliore la planification logistique.
- Pour regrouper au niveau de la société mère (ex. gestion du crédit), utilisez commercial_partner_id plutôt que partner_id seul.
- Pour les intégrations API, préférez XML‑RPC ou JSON‑RPC : le modèle sales.order est pleinement exposé. Gérez soigneusement la correspondance des identifiants externes.
- Pour les champs personnalisés, préfixez par x_ ou par le préfixe de votre module afin d'éviter les collisions lors d'évolutions d'Odoo.
Pièges fréquents
- Ne modifiez pas une commande confirmée sans vérifier le champ locked : si elle est verrouillée, créez une révision ou suivez le workflow approprié.
- Ne confondez pas partner_id, partner_invoice_id et partner_shipping_id : chacun sert un usage précis — renseignez les trois si les adresses diffèrent.
- N'overridiez pas action_confirm sans appeler super() : cela peut casser des modules tiers ou compliquer les mises à jour.
- N'ajoutez pas de champs requis sans prévoir de valeurs par défaut : sinon, les anciennes commandes échoueront lors d'une montée de version.
- Pensez à définir pricelist_id lorsque la devise ou les tarifs diffèrent du paramétrage par défaut, sous peine d'erreurs de tarification ou de facturation.
Conclusion
Le modèle sales.order est le pilier du module Ventes : il centralise devis et commandes. Savoir quels champs existent et comment le modèle peut être étendu facilite la configuration, la personnalisation et l'intégration d'Odoo.
Que vous cartographiez des processus commerciaux ou développiez des modules sur mesure, bien comprendre sales.order évite beaucoup d'erreurs et fait gagner du temps.
Besoin d'aide pour votre projet Odoo ?
Dasolo accompagne les entreprises pour implémenter, personnaliser et optimiser Odoo. Nous sommes spécialisés en intégration API et développement Odoo, avec une expertise poussée des modèles comme sales.order.
Besoin d'assistance pour votre implémentation Odoo, vos modules personnalisés ou vos intégrations ? Nous pouvons vous accompagner. Demandez une démo pour échanger sur votre projet.