Se rendre au contenu

Le champ Monetary dans Odoo : fonctionnement et cas d’usage

Guide pratique pour gérer correctement les montants monétaires dans le modèle de données Odoo
6 mars 2026 par
Le champ Monetary dans Odoo : fonctionnement et cas d’usage
Dasolo
| Aucun commentaire pour l'instant

Introduction


Le champ Monetary d'Odoo ressemble à un simple nombre mais cache une logique dédiée aux devises. Il stocke la valeur comme un flottant, mais s'affiche, s'arrondit et se comporte selon des règles monétaires — et non comme un Float classique. Comprendre cette différence évite bien des erreurs quand on manipule des prix, des totaux ou des budgets.


Chaque fois que vous consultez le prix d'un produit, le total d'une commande ou le montant d'une facture dans Odoo, vous voyez un champ Monétaire à l'œuvre. Ces champs sont omniprésents dans les modules standard et prennent en charge automatiquement le formatage, l'affichage du symbole monétaire, la précision décimale et les règles d'arrondi.

Ce guide s'adresse aux développeurs Odoo, consultants et utilisateurs techniques qui veulent saisir le fonctionnement interne du champ Monetary. Que vous construisiez un module, configuriez une personnalisation ou cherchiez pourquoi vos montants s'arrondissent différemment, vous trouverez ici les principes et les motifs à respecter.

Qu'est-ce que le champ Monétaire dans Odoo


Le type fields.Monetary est un type natif d'Odoo pensé pour stocker des valeurs exprimées en monnaie : prix unitaires, montants de factures, totaux, budgets, plafonds, etc. Il est fait pour tout ce qui représente de l'argent.


Sa particularité par rapport à un Float ordinaire est qu'il est lié à une devise. Un champ Monetary connaît la devise associée et s'en sert pour déterminer combien de décimales afficher et comment arrondir les valeurs.


Affichage dans l'interface

Dans l'interface Odoo, un champ Monétaire affiche le montant selon les règles de la devise liée. Par exemple, pour l'euro vous verrez un affichage avec le symbole et la mise en forme locale ; pour le dollar, le sigle approprié et la précision définie sur l'enregistrement monnaie. Le nombre de décimales est contrôlé par la configuration de la devise.


Le champ est modifiable dans les vues formulaire, lisible proprement dans les listes et exploitable dans les tableaux croisés et rapports financiers. Les utilisateurs n'ont pas à gérer le format : Odoo s'en occupe automatiquement.


Le type de donnée sous-jacent

Au niveau base de données, la valeur est stockée comme un flottant (double precision) dans PostgreSQL. L'information sur la devise n'est pas intégrée dans la même colonne : elle provient d'un lien Many2one vers res.currency présent sur le même modèle.


Séparer la valeur et la devise est un choix volontaire. Cela garde les colonnes propres et permet de modifier la devise d'un enregistrement indépendamment du nombre stocké.


Comment fonctionne ce champ


Saisir ces mécanismes vous évitera des problèmes d'affichage ou d'arrondi fréquents lors de développements personnalisés et vous permettra d'utiliser correctement le champ Monetary.


Le paramètre currency_field

Chaque champ Monetary doit être associé à un champ Many2one pointant vers res.currency. Par défaut, Odoo cherche currency_id sur le même modèle, mais on peut préciser un autre nom via currency_field :


amount = fields.Monetary(string='Amount', currency_field='currency_id')

Si le champ de devise est absent ou non renseigné, Odoo retombe sur la devise de la société par défaut. Cela évite des erreurs fatales mais, en environnement multi-devises, fausse le formatage. Déclarez toujours explicitement le champ de devise.


Arrondi et précision

L'une des différences majeures entre Monetary et Float concerne l'arrondi. Le modèle res.currency définit le nombre de décimales et le facteur d'arrondi. Lors de la lecture ou de l'affichage, Odoo applique ces règles automatiquement.

Ainsi, une valeur brute comme 1.2349999 pour un champ en EUR sera affichée conformément à la précision de l'euro (ex. 1,23), évitant des résultats inattendus. Pour les taxes, les totaux de factures ou les rapprochements financiers, cette précision est essentielle — un Float simple finit par introduire des écarts difficiles à traquer.


Interaction avec l'ORM Odoo

Dans l'ORM, la lecture d'un champ Monetary renvoie un float Python. Le contexte de devise vient du champ de devise associé sur l'enregistrement. Pour conserver la précision lors de calculs, utilisez la méthode d'arrondi de la devise :


rounded_value = self.currency_id.round(self.amount)

Cela évite l'accumulation d'erreurs liées aux flottants, notamment lorsqu'on totalise plusieurs lignes ou qu'on effectue des calculs itératifs.


Champs Monétaires dans les rapports QWeb

Dans les templates QWeb, les champs Monetary bénéficient d'un widget dédié qui formate correctement les valeurs dans les PDF et rapports web :


<span t-esc="record.amount"
      t-options='{"widget": "monetary", "display_currency": record.currency_id}'/>

Ce widget garantit l'affichage du bon symbole, des bonnes décimales et du bon séparateur, quel que soit la devise de l'enregistrement.

Cas d'usage en entreprise


Les champs Monétaires interviennent partout dans les modules Odoo standards. Voici cinq exemples concrets où ils sont cruciaux dans des processus métier réels.


1. Ventes : prix produits et totaux de commande

Les champs tels que price_unit, price_subtotal ou amount_total sur les commandes et lignes de vente sont des Monetary. Ils respectent automatiquement la devise choisie par le client, même si elle diffère de celle de l'entreprise.


Quand un commercial saisit une commande en USD pour une société qui travaille en EUR, Odoo gère l'affichage, l'arrondi et la conversion correctement grâce au contexte devise du champ Monetary.


2. Comptabilité : montants de factures et lignes de taxe

En comptabilité, toutes les colonnes de montants sur une facture sont des Monetary : amount_untaxed, amount_tax, amount_total. La devise de la facture détermine l'arrondi de ces valeurs.


Ce n'est pas anecdotal : un mauvais arrondi sur une ligne de taxe génère des écritures déséquilibrées difficiles à corriger. La prise en compte de la devise par le champ Monetary évite ces problèmes.


3. CRM : revenus attendus sur les opportunités

Le champ expected_revenue d'une opportunité CRM est un Monetary. Les équipes commerciales peuvent saisir des montants dans la devise du prospect tandis que les tableaux de bord convertissent ensuite les valeurs en devise société pour l'analyse du pipeline.


Cette méthode fonctionne parce que les Monetary conservent l'information de devise en parallèle du chiffre.


4. Achats : prix fournisseurs et commandes d'achat

Les commandes d'achat utilisent des Monetary pour les prix unitaires et totaux, liés à la devise du fournisseur. Une facture fournisseur en yen suit le même processus qu'une facture en euro : précision et affichage sont gérés automatiquement.


5. Champs personnalisés : budgets et objectifs

Ajouter un budget, un objectif de chiffre d'affaires ou un plafond de dépense sur un projet, un département ou un modèle personnalisé exige l'usage d'un champ Monetary. Il s'intègre naturellement avec la devise de l'entreprise, s'affiche correctement et se comporte de façon prévisible dans rapports et exports.

Techniquement, on pourrait utiliser un Float, mais dès qu'il y a plusieurs devises, cela crée des incohérences d'affichage et des problèmes d'arrondi.


Créer ou personnaliser le champ


Deux méthodes principales existent pour ajouter un champ Monetary : sans code via Odoo Studio, ou avec du code dans un module Python pour un contrôle total.


Utiliser Odoo Studio

Odoo Studio propose un type Monétaire dans son assistant de création de champs. Lorsque vous ajoutez un champ Monétaire avec Studio, il crée automatiquement un currency_id si le modèle n'en possède pas déjà un. C'est la solution la plus rapide pour des besoins simples.


À noter : les champs créés avec Studio reçoivent un préfixe x_ (ex. x_studio_budget). Si le modèle dispose déjà d'un currency_id, le nouvel élément l'utilisera ; sinon Studio en créera un nouveau. Quand plusieurs Monetary coexistent avec des devises différentes, vérifiez la conception du champ de devise partagé avant la mise en production.


Pour des scénarios simples, Studio est l'option la plus rapide et adaptée aux utilisateurs métiers sans accès au développement.


Approche technique : champs en Python

Dans un module personnalisé, il faut déclarer deux éléments : le champ Monetary et le champ Many2one vers la devise. C'est le schéma standard dans le développement Odoo :


from odoo import fields, models

class ProjectTask(models.Model):
    _inherit = 'project.task'

    x_budget = fields.Monetary(
        string='Budget',
        currency_field='x_budget_currency_id',
    )
    x_budget_currency_id = fields.Many2one(
        comodel_name='res.currency',
        string='Budget Currency',
        default=lambda self: self.env.company.currency_id,
    )

Mettre la devise de la société en valeur par défaut est une bonne pratique pour les champs internes : l'utilisateur voit immédiatement un format correct et le champ n'apparaît pas vide à la création.


Champs Monétaires calculés

Les Monetary conviennent parfaitement aux champs calculés. Pour totaliser des lignes ou appliquer une formule qui renvoie un montant, on utilisera un computed Monetary enregistré :


x_total_budget = fields.Monetary(
    string='Total Budget',
    currency_field='currency_id',
    compute='_compute_total_budget',
    store=True,
)

@api.depends('x_line_ids.x_amount')
def _compute_total_budget(self):
    for record in self:
        record.x_total_budget = sum(record.x_line_ids.mapped('x_amount'))

L'attribut store=True est essentiel si vous voulez filtrer, trier ou agréger sur ce champ dans des vues liste ou rapports. Un champ calculé non stocké ne peut pas être utilisé dans des domaines ORM.


Ajouter un champ Monétaire via l'API

Si vous créez des champs à distance via XML-RPC (par exemple dans un script d'installation), il est possible de créer un champ Monétaire en manipulant ir.model.fields :


models.execute_kw(ODOO_DB, uid, ODOO_API_KEY,
    'ir.model.fields', 'create',
    [{
        'name': 'x_budget',
        'field_description': 'Budget',
        'model_id': model_id,
        'ttype': 'monetary',
        'currency_field': 'currency_id',
        'state': 'manual',
    }]
)

C'est une des possibilités offertes par l'API XML-RPC pour automatiser des configurations, sujet traité plus en détail dans d'autres ressources techniques.

Bonnes pratiques


Le champ Monetary est simple à maîtriser si vous respectez quelques règles. Voici les pratiques qui garantissent une implémentation robuste.


1. Ne jamais utiliser Float pour des valeurs monétaires

Règle d'or : si un champ représente de l'argent (prix, montant, total, budget), utilisez fields.Monetary. Un Float n'a pas de notion de devise et n'appliquera pas les règles d'arrondi nécessaires en contexte multi-devises.


2. Toujours déclarer explicitement le champ de devise

Ne comptez pas sur le comportement par défaut d'Odoo si le champ currency_id n'existe pas. Déclarez systématiquement currency_field et créez la Many2one correspondante vers res.currency pour éviter des retours furtifs à la devise société.


3. Définir une devise par défaut

Pour les champs internes majoritairement en devise société, mettez une valeur par défaut : default=lambda self: self.env.company.currency_id. Cela évite l'affichage sans symbole ni format au premier accès.


4. Utiliser store=True sur les computed Monetary recherchés

Si un champ calculé doit servir de filtre ou d'ordre en liste, définissez store=True. Sans cela, il est invisible pour les domaines ORM et les vues SQL, source fréquente de confusion pour les tableaux de bord personnalisés.


5. Appliquer currency.round() pour les calculs intermédiaires

Dans du code Python réalisant plusieurs opérations sur des montants, arrondissez aux étapes importantes avec self.currency_id.round(value) plutôt que seulement à la fin. Les erreurs de flottants se cumulent sinon et provoquent des écarts sur les totaux.


6. Être volontaire sur les rapports multi-devises

Lorsqu'on agrège des Monetary provenant de devises différentes, ne faites pas la somme brute. Convertissez d'abord dans une devise commune via res.currency.compute(), ou créez des rapports par devise. Mélanger des monnaies dans une addition donne des résultats techniquement valides au niveau champ mais sans sens financier.

Pièges fréquents


Même des développeurs chevronnés rencontrent des soucis avec les Monetary. Ci-dessous les erreurs récurrentes et comment les éviter.


Piège 1 : champ de devise manquant

L'oubli le plus fréquent est de ne pas créer la Many2one vers la devise. Si currency_id est absent, Odoo basculera parfois sur la devise société et parfois lèvera une erreur. Toujours créer le champ de devise en même temps que le Monetary.


Piège 2 : plusieurs Monetary partageant une même devise alors qu'elles devraient différer

Si deux Monetary d'un même modèle doivent contenir des montants dans des devises différentes (par ex. prix client en EUR et coût fournisseur en USD), elles ne peuvent pas partager une unique currency_id. Chaque montant exige sa propre référence de devise; sinon l'unique champ de devise écrasera l'autre réglage et corrompra les données.


Piège 3 : écarts d'arrondi lors d'agrégations multi-devises

Sommer des Monetary en devises différentes produit des totaux incohérents puisque l'on additionne des unités différentes. C'est une source classique d'erreurs dans les rapports. Normalisez les valeurs ou convertissez-les avant d'agréger.


Piège 4 : comparaisons exactes sur des flottants dans des recherches ORM

Rechercher une valeur monétaire avec une égalité stricte (par ex. amount = 10.0) peut manquer des enregistrements à cause du stockage en float. Préférez des bornes (>=, <=) avec une tolérance, ou arrondissez avant comparaison en logique Python.


Piège 5 : ignorer l'arrondi de la devise lors d'import de données

Lors d'import CSV ou XML-RPC, les montants sont sauvegardés tels quels sans arrondi automatique. Si la source comporte plus de décimales que la devise cible, l'affichage et les totaux peuvent diverger. Appliquez l'arrondi de la devise dans vos scripts d'import avant d'envoyer les valeurs.


Conclusion


Le champ Monetary paraît simple mais porte des comportements essentiels : relation étroite avec la devise, arrondi cohérent, formatage unifié et prise en charge par le moteur de rapports. C'est une brique fondamentale pour manipuler de l'argent dans Odoo.


L'utiliser correctement — en le liant systématiquement à un champ de devise explicite et en évitant les Float pour l'argent — vous épargne une classe d'erreurs subtiles et coûteuses à corriger en production. Le modèle Odoo est construit autour de ce type pour de bonnes raisons.


Que vous suiviez un guide développeur, adaptiez un module standard ou créiez une solution sur mesure, bien concevoir vos Monetary est une décision structurante pour la fiabilité financière de votre instance Odoo.

Besoin d'aide pour votre déploiement Odoo ?


Chez Dasolo, nous accompagnons les entreprises dans la mise en œuvre, la personnalisation et l'optimisation d'Odoo, quel que soit l'envergure du projet. Modélisation des données, stratégie de champs personnalisés, support multi-devises ou déploiement complet : notre équipe couvre l'ensemble des besoins techniques et fonctionnels.


Si vous avez des questions sur les champs Monétaires ou tout autre aspect de votre implémentation Odoo, nous pouvons vous assister. Contactez-nous et discutons de votre projet.

Le champ Monetary dans Odoo : fonctionnement et cas d’usage
Dasolo 6 mars 2026
Partager cet article
Se connecter pour laisser un commentaire.