| errors |
| Failed to load YAML frontmatter: Tried to load unspecified class: Date |
|
Référence API Odoo — Documentation Complète
Base URL : https://sarl-le-relais-de-louest.odoo.com/jsonrpc
Protocole : JSON-RPC 2.0
Auth : common.login + API Key
1. Authentification
1.1 Obtenir un UID
POST /jsonrpc
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "common",
"method": "login",
"args": ["<db_name>", "<email>", "<api_key>"]
},
"id": 1
}
Réponse : {"jsonrpc": "2.0", "id": 1, "result": 2}
1.2 Helper Python
import requests
DB, UID, PWD = "sarl-le-relais-de-louest", None, None
URL = f"https://{DB}.odoo.com/jsonrpc"
def odoo_call(model, method, *args):
payload = {
"jsonrpc": "2.0", "method": "call",
"params": {
"service": "object", "method": "execute_kw",
"args": [DB, UID, PWD, model, method] + list(args)
}, "id": 1
}
r = requests.post(URL, json=payload, timeout=30).json()
if "error" in r:
raise Exception(r["error"]["data"]["message"])
return r.get("result")
2. Méthodes génériques
Tous les modèles supportent : search, search_read, search_count, read, create, write, unlink, fields_get.
Syntaxe des domaines
["field", "=", value] # égalité
["field", "!=", value] # différent
["field", ">=", value] # supérieur ou égal
["field", "=like", "xxx%"] # LIKE
["field", "in", [v1, v2]] # IN
[["f1", "=", v1], ["f2", "=", v2]] # AND
[["f1", "=", v1], "|", ["f1", "=", v2]] # OR
Commandes relationnelles
# Many2one → int
"partner_id": 42
# Many2many
"taxes_id": [(6, 0, [id1, id2])] # remplacer
"taxes_id": [(4, id3)] # ajouter
"taxes_id": [(3, id3)] # supprimer
"taxes_id": [(5, 0, 0)] # vider
# One2many
"order_line": [(0, 0, {vals})] # créer + lier
"order_line": [(1, id, {vals})] # modifier
"order_line": [(2, id)] # supprimer
3. Catalogue complet des modèles Odoo 19
Chaque modèle est documenté avec son rôle, ses particularités et ses pièges.
⚠️ = piège connu | 📖 = détaillé plus bas (section 4)
3.0 Technique / Base (ir.*)
| Modèle |
Description |
ir.model |
Registre central de tous les modèles Odoo. Stocke chaque modèle installé avec son nom technique, son nom affiché, son module propriétaire et ses méta-données. Utilisable pour découvrir les modèles disponibles : search_read([], {"fields": ["model", "name"]})
|
ir.model.fields |
Méta-données complètes de chaque champ : nom, type (char, m2o, int…), relation, taille, aide, obligatoire. Base de fields_get(). Permet d'explorer la structure d'un modèle sans y accéder directement |
ir.module.module |
Modules Odoo installés ou disponibles. Champs clés : name (nom technique), display_name, state (installed/uninstalled/to install). Permet d'installer des modules : button_immediate_install([[id]])
|
ir.ui.view |
Vues XML qui définissent l'interface utilisateur : formulaires, listes, kanban, graphiques, calendriers. Héritage via inherit_id. La clé arch_base contient le XML. Chaque vue est liée à un modèle spécifique |
ir.ui.menu |
Menus de navigation de l'interface Odoo. Structure arborescente via parent_id. Lié à une action (action). Définit l'ordre d'affichage (sequence), les icônes, et les groupes d'accès |
ir.actions.act_window |
Action la plus courante : ouvre une fenêtre (liste/formulaire) pointant vers un modèle (res_model). Définit les vues à utiliser (view_mode : tree,form,kanban,calendar,graph) et les filtres par défaut |
ir.actions.server |
Actions serveur exécutant du code Python côté backend. Utilisé pour les automatisations, les boutons intelligents, les actions planifiées. Le code est stocké dans code et exécuté via eval()
|
ir.actions.report |
Rapports PDF (factures, devis, tickets…). Lié à un template QWeb. Définit le type de papier, le nom du fichier généré, et si le rapport est attachable aux emails |
ir.actions.url |
Actions qui redirigent vers une URL externe. Utile pour les liens vers des dashboards externes, des contrôleurs custom, ou des sites tiers |
ir.cron |
Tâches planifiées (cron jobs). Exécute une méthode à intervalle régulier. Champs : interval_number, interval_type (minutes/hours/days/weeks/months), active, numbercall (-1 = infini). Désactiver : write([id], {"active": False})
|
ir.mail_server |
Serveurs SMTP sortants. Définit le relais email : smtp_host, smtp_port, smtp_user, smtp_encryption (ssl/tls). Pour bloquer tous les emails sortants : write([ids], {"active": False})
|
ir.config_parameter |
Paramètres de configuration clé/valeur globaux. Stocke les webhooks URLs, les clés API tiers, les seuils. Lecture : get_param("web.base.url"). Écriture : set_param("key", "value")
|
ir.sequence |
Séquences de numérotation automatique (SO-XXX, INV-XXX, POS/2026/…). Définit le préfixe, suffixe, padding (padding), prochain numéro (number_next). Une séquence par type de document |
ir.translation |
Traductions de l'interface. Stocke la source, la langue (lang), et la valeur (value). Permet d'exporter/importer les traductions pour personnaliser les termes |
ir.attachment |
Pièces jointes et documents. Stockage binaire (datas en base64) ou fichiers. Lié à n'importe quel enregistrement via res_model + res_id. ⚠️ Utiliser plutôt que product.image (obsolète) |
ir.qweb |
Templates QWeb pour le rendu HTML/PDF. Syntaxe XML avec directives : <t t-foreach>, <t t-if>, <t t-esc>. Utilisé par les rapports, emails, et le frontend website |
ir.filters |
Filtres sauvegardés personnels. Chaque utilisateur peut créer ses propres filtres sur une vue liste. Stocke le domain, le context, et le sort
|
ir.default |
Valeurs par défaut des champs par utilisateur. Quand un champ est pré-rempli automatiquement, la valeur vient d'ici. Accessible via ir.default.get(model, field)
|
ir.logging |
Logs applicatifs. Niveau (level : info/warning/error/critical), message (message), traceback (path). Utile pour le débogage. ⚠️ Volumineux en production |
ir.property |
Propriétés de champ multi-entreprise. Permet des valeurs différentes par société pour un même champ. Principalement utilisé en comptabilité pour les comptes par défaut |
3.1 Contacts (res.*)
| Modèle |
Description |
res.partner |
Le modèle central de tous les contacts Odoo : clients, fournisseurs, prospects, employés, sociétés. Champs clés : name, email, phone, customer_rank (1 = client), supplier_rank (1 = fournisseur), is_company (True = société morale), parent_id (contacts liés à une société). Modèle le plus utilisé de tout l'écosystème Odoo |
res.partner.category |
Étiquettes/tags pour catégoriser les contacts. Exemples : "VIP", "Prospect chaud", "Revendeur agréé". Relation Many2many avec res.partner via category_id
|
res.partner.bank |
Comptes bancaires des contacts : IBAN (acc_number), code BIC, banque (bank_id). Un contact peut avoir plusieurs comptes. Utilisé pour les prélèvements SEPA et les virements |
res.partner.title |
Titres de civilité configurables : M., Mme, Dr, Pr, Mlle. Utilisé dans les formulaires de contact et les adresses de facturation/formulaires |
res.partner.industry |
Secteurs d'activité : Agriculture, Industrie, Services, Retail, Santé… Aide à la segmentation client et aux rapports par secteur |
res.company |
Sociétés de l'instance Odoo. Contient la raison sociale, l'adresse, le n° TVA (vat), le logo, la devise par défaut, le pays. En multi-entreprise, chaque entité a sa propre res.company avec sa comptabilité séparée |
res.users |
Utilisateurs du système. Hérite de res.partner (chaque utilisateur est aussi un contact). Champs : login (email), password, groups_id (droits), company_id. ⚠️ Ne pas confondre avec res.partner qui stocke tous les contacts externes |
res.groups |
Groupes de sécurité / droits d'accès. Chaque utilisateur appartient à un ou plusieurs groupes qui définissent ce qu'il peut voir et faire. Exemples : base.group_user (tout utilisateur), sales_team.group_sale_manager (manager ventes) |
res.lang |
Langues disponibles. Définit les traductions chargées et le format des dates/nombres. Code ISO : fr_FR, en_US. active=True = langue activée |
res.country |
Pays. Champs : name, code (ISO 3166), currency_id, phone_code. ⚠️ Attention : Réunion = ID 187 (pas 75, qui est la France métropolitaine) |
res.country.state |
Régions, états, départements. Lié à res.country. Pour la France : Île-de-France, Auvergne-Rhône-Alpes, La Réunion… |
res.currency |
Devises : EUR, USD, GBP… Champs : name, symbol (€, $, £), rounding (0.01 pour EUR, 1 pour JPY), position (before/after). La devise de la société détermine la comptabilité |
res.currency.rate |
Taux de change par devise et par date. Permet la comptabilité multi-devises. Un taux est toujours exprimé par rapport à la devise de référence de l'entreprise |
res.bank |
Institutions financières : "BNP Paribas", "Crédit Agricole"… Champs : name, bic (code SWIFT/BIC). Distinct de res.partner.bank qui stocke les comptes individuels |
res.config.settings |
Configuration générale de l'instance. Interface unique pour tous les paramètres système (durée de validité des devis, devise par défaut…). Les valeurs sont stockées dans ir.config_parameter
|
3.2 Ventes (sale.*)
| Modèle |
Description |
sale.order |
Devis et commandes clients. Cycle : draft (devis) → sent (envoyé) → sale (commandé) → done (livré) → cancel. ⚠️ 7 champs obligatoires pour create : name, partner_id, partner_invoice_id, partner_shipping_id, company_id, date_order, picking_policy. Utiliser client_order_ref pour stocker une référence externe |
sale.order.line |
Lignes de commande. Contient le produit (product_id), la quantité (product_uom_qty), le prix unitaire (price_unit), la remise (discount), les taxes. Peut être lié à un billet événement (event_ticket_id) et des inscriptions (registration_ids) |
sale.order.template |
Modèles de devis réutilisables. Prédéfinit un panier de produits/services pour créer des devis en un clic. Contient des lignes via sale.order.template.line
|
sale.order.template.line |
Lignes des modèles de devis. Mêmes champs que sale.order.line mais liées à un template plutôt qu'à une commande réelle |
sale.order.template.option |
Options de modèle de devis : produits optionnels présentés comme cases à cocher dans le formulaire de création de devis |
sale.advance.payment.inv |
Assistant de facture d'acompte (wizard). Depuis un devis, génère une facture pour un pourcentage du montant total avant livraison |
sale.order.cancel |
Assistant d'annulation de commande. Propose des raisons et gère le retour en stock automatique des produits livrés |
sale.payment.provider.onboarding.wizard |
Assistant de configuration des fournisseurs de paiement en ligne (Stripe, PayPal, etc.) |
sale.order.line.margin |
Marge calculée par ligne : prix de vente - prix de revient. Lecture seule, calculé automatiquement à partir du standard_price du produit |
3.3 PDV / Point de Vente (pos.*)
| Modèle |
Description |
pos.order |
Commandes PDV / tickets de caisse. Créé automatiquement à chaque vente. Cycle : draft → paid → done → invoiced. Contient le total TTC (amount_total), les taxes, le rendu monnaie (amount_return). Lié à une session via session_id
|
pos.order.line |
Lignes de ticket PDV : produit, quantité (qty), prix unitaire, remise, taxes. Lié à pos.order. Créées en temps réel pendant l'encaissement |
pos.session |
Session de caisse. Cycle : opening_control (ouverture) → opened → closing_control (clôture) → closed. Contient le solde d'ouverture (cash_register_balance_start) et de clôture, l'écart, et le détail par mode de paiement |
pos.config |
Configuration du PDV : nom, modes de paiement disponibles, catégories affichées dans la grille, imprimante connectée, comportement (standard/restaurant/bar). Le champ iface_print_via_proxy active l'impression ticket |
pos.payment |
Enregistrement individuel d'un paiement dans le PDV. Lié à une commande et un mode de paiement. Contient le montant, le rendu monnaie, et le statut |
pos.payment.method |
Modes de paiement du PDV : Espèces, Carte bancaire, Chèque, Bon cadeau. Définit le journal comptable associé. Configurable par session |
pos.category |
Catégories de produits affichées comme onglets dans la grille du PDV. Permet d'organiser les boutons produits (Billetterie, Snack, Boissons…) |
pos.bill |
Tickets/reçus de caisse. Stocke le PDF et les métadonnées d'impression pour réimpression ultérieure |
pos.session.statement |
Relevé de session : synthèse des paiements par mode. Généré automatiquement à la clôture |
pos.cash.box.in |
Entrée d'argent dans la caisse hors vente (ex: apport de monnaie en cours de session, remise de fonds). Justification obligatoire |
pos.cash.box.out |
Sortie d'argent de la caisse (ex: prélèvement pour dépôt en banque). Justification obligatoire |
pos.order.return |
Remboursement / retour PDV. Crée un avoir lié à la commande d'origine. Gère la remise en stock si applicable |
pos.discount |
Remises PDV prédéfinies (-10%, -20%…) applicables en un clic depuis l'interface de caisse |
pos.combo |
Combos / menus groupés : "Menu Enfant" = Luge + Snack + Boisson à prix forfaitaire |
pos.combo.line |
Lignes des combos : chaque produit inclus avec sa quantité et son prix dans le combo |
pos.close.session.wizard |
Assistant de fermeture de session : étape 1 (compter les espèces), étape 2 (saisir totaux), étape 3 (confirmer) |
pos.printer |
Imprimantes connectées au PDV (ticket client, cuisine, bar). Géré via IoT Box Odoo ou connexion IP directe |
pos.pack.operation.lot |
N° de lot/série pour les produits tracés vendus en PDV. Obligatoire si le produit a tracking != "none"
|
3.4 Produits (product.*)
| Modèle |
Description |
product.template |
Modèle de produit générique : nom, description, catégorie, prix par défaut, taxes. Si le produit n'a pas de variantes, Odoo crée automatiquement un product.product correspondant |
product.product |
Variante spécifique d'un produit. C'est CE modèle qui est utilisé dans les commandes, le PDV, l'inventaire. Champs propres : barcode, default_code. ⚠️ Utiliser type (consu/service/product), pas detailed_type qui n'existe pas sur SaaS |
product.category |
Catégories de produits hiérarchiques (parent_id). Utilisées pour organiser les produits, appliquer des comptes comptables par défaut, structurer les grilles PDV |
product.attribute |
Attributs de variante : Taille, Couleur, Matière. Chaque attribut a des valeurs (product.attribute.value) qui se combinent pour générer les variantes |
product.attribute.value |
Valeurs d'attribut : "Rouge", "XL", "42", "Cuir". Lié à un attribut. Utilisé pour générer les combinaisons de variantes |
product.template.attribute.line |
Ligne liant un attribut à un modèle de produit. Définit quelles valeurs d'attribut sont disponibles pour ce produit spécifique |
product.template.attribute.value |
Association valeur → produit avec prix supplémentaire éventuel (ex: +5€ pour XL, +10€ pour Cuir) |
product.packaging |
Colisage : carton de 12, palette de 48… Utilisé pour les achats en gros et les propositions de quantité dans les commandes |
product.supplierinfo |
Infos fournisseur par produit : prix d'achat, délai (jours), quantité minimum, référence chez le fournisseur. Un produit peut avoir plusieurs entrées (une par fournisseur) |
product.pricelist |
Listes de prix / tarifs. Permet des prix différents par client, période, devise. Contient des règles (product.pricelist.item) |
product.pricelist.item |
Règle de prix dans une liste : produit ou catégorie cible, calcul (fixe/pourcentage/formule), période de validité, quantité minimum |
product.uom |
Unités de mesure : unité, kg, litre, mètre, boîte, palette… Avec facteur de conversion (1 boîte = 12 unités). Lié à une catégorie |
product.uom.categ |
Catégories d'unités : Volume, Poids, Longueur, Unité. Les unités d'une même catégorie sont convertibles entre elles |
product.image |
⚠️ Obsolète. Remplacé par ir.attachment. Stockait les images produits en base64 |
product.label.layout |
Assistant de mise en page pour impression d'étiquettes produits (format, quantité) |
product.replenish |
Assistant de réapprovisionnement : depuis la fiche produit, génère un ordre de réappro directement |
3.5 Inventaire / Stock (stock.*)
| Modèle |
Description |
stock.picking |
Transferts / bons de livraison. Déplace des produits entre emplacements. Types : livraison client, réception fournisseur, transfert interne. Cycle : draft → waiting → confirmed → assigned → done → cancel
|
stock.move |
Mouvement de stock planifié : quel produit, de quel emplacement source, vers quel emplacement destination, quelle quantité. Créés par les commandes et les pickings. Cycle : draft → confirmed → assigned → done → cancel
|
stock.move.line |
Ligne de mouvement exécutée physiquement. Spécifie le lot/série, l'emplacement précis, la quantité prélevée. Créé au moment de la réservation ou du transfert réel |
stock.quant |
Quantité physique en stock. Combinaison unique : produit × emplacement × lot/série × quantité. C'est LA source de vérité de l'inventaire. Le stock total d'un produit = somme de ses quants |
stock.location |
Emplacements de stockage hiérarchiques (location_id = emplacement parent). Types via usage : internal (stock), supplier (fournisseurs), customer (clients), inventory (pertes), production, transit |
stock.warehouse |
Entrepôts. Un entrepôt crée 3 emplacements par défaut : stock, entrée, sortie. Plusieurs entrepôts possibles par société |
stock.inventory.adjustment.name |
Inventaire physique. Compare les quantités théoriques (quants) avec les quantités comptées. Génère automatiquement les ajustements d'écart |
stock.rule |
Règles de réapprovisionnement automatique : quand et comment réapprovisionner (quantité min/max, délai, méthode MTS/MTO) |
stock.picking.type |
Types d'opération : Livraison client, Réception fournisseur, Transfert interne. Définit emplacements source/destination par défaut et la séquence de numérotation |
stock.package.type |
Types de colis : boîte, palette, conteneur. Définit dimensions, poids, et éventuellement le nombre de produits par colis |
stock.package.destination |
Destination d'un colis entier (adresse de livraison). Évite de renseigner l'adresse produit par produit |
stock.package.level |
Hiérarchie des colis : palette contient des boîtes, conteneur contient des palettes |
stock.lot |
Lots et numéros de série. Traçabilité : date de fabrication, péremption, fournisseur. Obligatoire si tracking = "lot" ou "serial" sur le produit |
stock.storage.category |
Catégories de stockage restreignant quels produits vont où : température contrôlée, dangereux, fragile, zone sécurisée |
stock.putaway.rule |
Règle de rangement automatique : quand le produit X arrive, le mettre dans l'emplacement Y. Lié à une catégorie + emplacement destination |
stock.scrap |
Mise au rebut : produits endommagés, périmés, perdus. Déplace vers un emplacement "Rebuts" et sort de l'inventaire utilisable |
stock.warn.insufficient.qty |
Assistant d'avertissement quand on essaie de livrer plus que le stock disponible (wizard bloquant) |
stock.quantity.history |
Historique des quantités en stock à une date donnée. Permet de voir l'état du stock à n'importe quelle date passée |
stock.track.confirmation |
Assistant vérifiant que tous les lots/séries obligatoires sont renseignés avant de finaliser un transfert |
stock.track.line |
Ligne de suivi traçabilité : fait le lien entre un mouvement et son lot/série d'origine |
stock.assign.serial |
Assistant d'assignation de n° de série. Permet de générer ou sélectionner des numéros pour les produits suivis |
stock.scheduler.compute |
Déclencheur du calcul MRP complet. Analyse tous les besoins (commandes clients, réappro) et génère les ordres de fabrication/réappro |
stock.change.product.qty |
Assistant de modification manuelle de quantité (correction de stock sans inventaire complet) |
stock.return.picking |
Assistant de retour : crée un transfert inverse pour retourner des produits au fournisseur ou reprendre une livraison client |
3.6 Comptabilité (account.*)
| Modèle |
Description |
account.move |
Écritures comptables ET factures. Modèle central. Une facture client = move_type: "out_invoice", un avoir = "out_refund", facture fournisseur = "in_invoice". États : draft → posted → cancel. Contient totaux, devise, partenaire, date d'échéance |
account.move.line |
Lignes d'écriture comptable. Chaque ligne débite ou crédite un compte. Contient : compte (account_id), débit, crédit, partenaire, date d'échéance, statut de rapprochement (reconciled). Base du lettrage et du reporting |
account.journal |
Journaux comptables : Ventes, Achats, Banque, Caisse, Opérations diverses. Chaque pièce comptable est rattachée à un journal. Définit séquence de numérotation, devise, comptes par défaut |
account.tax |
Taxes/TVA. Taux via amount (8.5, 2.1, 20…), type de calcul (amount_type : percent/fixed/group), utilisation (type_tax_use : sale/purchase/none). Pour La Réunion : créer 8.5% et 2.1%, désactiver les taux métropole (20%/10%/5.5%) |
account.tax.group |
Groupe de taxes : réunit vente et achat d'un même taux. ⚠️ DOM : ne pas mettre country_id (erreur mismatch Réunion ID 187 ≠ France ID 75). Créer le groupe sans contrainte pays |
account.fiscal.position |
Position fiscale : mapping automatique taxes/comptes selon le pays ou le client. Exemple : position "DOM" mappant 20% → 8.5% |
account.fiscal.position.tax |
Ligne de mapping : taxe source → taxe destination. "Quand la taxe 20% est appliquée, utiliser 8.5% à la place" |
account.fiscal.position.account |
Ligne de mapping : compte source → compte destination. Change le compte de produit selon la position fiscale |
account.payment |
Paiement enregistré. Type : inbound (reçu) / outbound (envoyé). Lié à des factures, un journal, un mode de paiement. Montant, date, référence |
account.payment.register |
Assistant wizard de paiement : crée un account.payment et lettre automatiquement avec les factures ouvertes du partenaire |
account.payment.term |
Conditions de paiement : "30 jours fin de mois", "45 jours net", "à réception". Contient des lignes d'échéance |
account.payment.term.line |
Ligne de condition : pourcentage dû, nombre de jours, jour du mois. Exemple : 50% à J+30, 50% à J+60 |
account.chart.template |
Modèle de plan comptable standard (PCG France, US GAAP…). ⚠️ SaaS : installation via API restreinte, passer par l'interface web |
account.account |
Comptes comptables. Plan de comptes : 707000 Ventes, 401000 Fournisseurs, 512000 Banque… Type de compte, code, devise, réconciliable ou non |
account.account.type |
Types de comptes : Actif, Passif, Produits, Charges, Capitaux propres. Définit le comportement (débit/crédit par défaut, sens du solde) |
account.account.tag |
Étiquettes comptes pour reporting fiscal : "TVA déductible", "Charges déductibles", "Produits imposables" |
account.group |
Groupes de comptes pour présentation du bilan et compte de résultat. Structure hiérarchique (comptes de bilan, comptes de résultat…) |
account.bank.statement |
Relevé bancaire importé (CSV, OFX, CODA) ou saisi. Contient des lignes à rapprocher avec les écritures comptables |
account.bank.statement.line |
Ligne de relevé : date, libellé, montant, contrepartie suggérée. À lettrer avec les account.move.line
|
account.reconcile.model |
Modèle de lettrage automatique : règles pour rapprocher les lignes de relevé avec les écritures (ex: si libellé contient "FACT" → chercher la facture) |
account.reconcile.model.line |
Ligne de modèle : compte de contrepartie, pourcentage, montant fixe pour répartition automatique |
account.analytic.account |
Comptes analytiques / Centres de coûts. Suivi coûts/revenus par projet, département, client. Ventilation obligatoire ou optionnelle selon config |
account.analytic.line |
Lignes analytiques : temps passé, coûts, revenus par compte analytique. Utilisé par timesheets, notes de frais, ventilation factures |
account.analytic.plan |
Plans analytiques : regroupements de comptes pour analyses multi-axes (projet × département × client) |
account.analytic.tag |
Étiquettes analytiques pour catégorisation des lignes |
account.analytic.distribution.model |
Modèle de répartition analytique automatique (ex: 60% département A, 40% département B) |
account.asset |
Immobilisations : machines, véhicules, bâtiments. Gère l'amortissement automatique (durée, méthode linéaire/dégressif, valeur résiduelle) |
account.asset.category |
Catégories d'immobilisation : comptes de dotation, amortissement, sortie par défaut |
account.budget.post |
Postes budgétaires : Salaires, Marketing, IT… Liés aux comptes comptables pour analyse |
account.cash.rounding |
Arrondi espèces : règle d'arrondi aux 5 centimes (Suisse) ou suppression centimes. Appliqué en PDV et facturation |
account.financial.year.op |
Assistant ouverture exercice : génère les écritures d'à-nouveaux de clôture |
account.aged.trial.balance |
Balance âgée : créances/dettes ventilées par échéance (0-30j, 30-60j, 60-90j, >90j). Rapport de recouvrement |
account.general.ledger |
Grand livre : toutes les écritures d'un compte sur une période avec débit, crédit, cumul progressif |
account.trial.balance |
Balance générale : par compte, total débit, total crédit, solde. Doit être équilibrée (total débit = total crédit) |
account.tax.report |
Rapport de TVA / déclaration fiscale : TVA collectée, TVA déductible, montant à payer ou crédit |
account.report |
Rapports financiers configurables : bilan, compte de résultat. Lié à account.report.line
|
account.report.line |
Ligne de rapport : nom, formule (somme de comptes, opérations), niveau hiérarchique |
account.accrued.orders.wizard |
Assistant OD (Opérations Diverses) : écritures de régularisation |
account.automatic.entry.wizard |
Assistant d'écritures récurrentes automatiques (loyers, abonnements…) |
wizard.multi.charts.accounts |
Assistant d'installation du plan comptable. ⚠️ SaaS : API restreinte, à faire via Paramètres → Comptabilité → Localisation fiscale |
3.7 Événements (event.*)
| Modèle |
Description |
event.event |
Événement : nom, dates, lieu, places max, responsable. Contient billets (event_ticket_ids) et inscriptions (registration_ids). ⚠️ Désactiver auto_confirm pour éviter l'envoi d'emails en masse à chaque inscription |
event.event.ticket |
Type de billet. Lié à un produit (product_id) — la vente du produit génère automatiquement l'inscription. Définit le prix et le nombre de places disponibles. Utilisé pour la billetterie et les inscriptions en ligne |
event.registration |
Inscription / Participant. Nom, email, code-barres (barcode pour QR code externe), état (draft/open/done/cancel), billet, commande liée. ⚠️ description n'existe pas → utiliser barcode pour les références externes |
event.type |
Catégories d'événements : Conférence, Salon, Formation, Concert… Paramètres par défaut (durée, modèle email) |
event.tag |
Étiquettes événement pour filtrage et recherche : "Annuel", "Scolaire", "Entreprise" |
event.mail |
Emails planifiés liés à un événement (quel template, envoyé quand : X jours avant/après). Utilise mail.template
|
event.mail.registration |
Emails planifiés spécifiques aux inscriptions ("rappel 2 jours avant l'événement", "remerciement après") |
event.track |
Programme/Sessions : "10h - Keynote", "14h - Workshop". Lieu, durée, speaker, description |
event.track.location |
Lieux de session : Salle A, Auditorium, Stand 12. Lié à l'événement |
event.track.tag |
Étiquettes session : "Technique", "Débutant", "Avancé" |
event.sponsor |
Sponsors : nom, logo, niveau, URL, description. Affiché sur la page événement |
event.sponsor.type |
Niveaux de sponsoring (Platinum, Gold, Silver, Bronze) avec ordre d'affichage |
event.registration.cancel |
Assistant annulation inscription avec raison et email optionnel |
3.8 CRM (crm.*)
| Modèle |
Description |
crm.lead |
Piste / Lead / Opportunité. Pipeline : étapes (stage_id), contact, entreprise, montant attendu, probabilité, date de clôture. Une piste gagnée peut créer un devis automatiquement |
crm.team |
Équipe commerciale : vendeurs, pipeline dédié, règles d'assignation auto, alias email. ⚠️ Pas de licence utilisateur requise pour les membres (gratuit) |
crm.stage |
Étape du pipeline : Nouveau, Qualifié, Proposition, Négociation, Gagné, Perdu. Probabilité, actions auto, si étape gagnante/perdante |
crm.tag |
Étiquettes pistes : "Urgent", "Grand compte", "Salon 2024", "Webinar" |
crm.lead.lost |
Assistant perte de piste : oblige à choisir une raison pour analyse des causes |
crm.lead.to.opportunity |
Conversion lead → opportunité qualifiée avec fusion des doublons |
crm.merge.opportunity |
Fusion de plusieurs pistes en une seule (garde le contact le plus pertinent) |
crm.iap.lead.mining.request |
Lead Mining : génération de pistes selon critères (pays, secteur, taille). Service payant IAP |
crm.iap.lead.role |
Rôles pour lead mining : CEO, CTO, Marketing Manager, CFO… |
crm.iap.lead.seniority |
Séniorité : Junior, Senior, Director, VP, C-Level |
crm.quotation.partner |
Partenaire de devis CRM : lie un contact à un template de devis pour envoi rapide |
3.9 Ressources Humaines (hr.*)
| Modèle |
Description |
hr.employee |
Employé. Lié à res.users (accès système) ou res.partner. Nom, poste (job_id), département, manager, coach, date d'entrée |
hr.employee.category |
Catégories : CDI, CDD, Stagiaire, Cadre, Non-cadre. Filtrage et regroupement |
hr.department |
Départements : Commercial, Technique, RH, Finance. Hiérarchique via parent_id
|
hr.job |
Postes / Fiches de poste : titre, description, compétences, fourchette de salaire. Utilisé en recrutement |
hr.contract |
Contrats de travail : type, dates, salaire, temps de travail, avantages. Génère les éléments de paie |
hr.leave |
Congés / Absences. Employé fait une demande → validée par le manager. Consomme le solde d'allocations |
hr.leave.type |
Types de congés : CP, RTT, Maladie, Maternité, Sans solde. Règles de validation, responsable |
hr.leave.allocation |
Allocation de jours : "25 jours de CP par an". Période d'acquisition, report possible |
hr.expense |
Note de frais : date, description, montant, catégorie, justificatif. Regroupée en feuille |
hr.expense.sheet |
Feuille de frais : regroupe plusieurs notes. Cycle : draft → submitted → approved → posted → paid |
hr.expense.category |
Catégories : Transport, Hébergement, Repas. Compte comptable et TVA par défaut |
hr.attendance |
Pointages : heure arrivée/départ. Calcul automatique du temps travaillé |
hr.applicant |
Candidats : CV, coordonnées, poste visé, étapes de recrutement. Lié à hr.job
|
hr.recruitment.stage |
Étapes recrutement : CV reçu, Entretien tel, Entretien technique, Offre, Accepté, Refusé |
hr.plan |
Plans RH : prévisions effectifs, recrutements, départs par département |
hr.plan.activity.type |
Types d'activité plan RH : Recrutement, Formation, Mobilité |
hr.work.entry.type |
Types d'entrée travail : Présent, Absent, Congé payé, Heures sup. Base de la paie |
3.10 Projets (project.*)
| Modèle |
Description |
project.project |
Projet. Tâches, jalons, documents. Lié à un compte analytique pour suivi coûts. Définit les étapes par défaut |
project.task |
Tâche. Cœur du module : titre, description, assigné (user_id), échéance (date_deadline), priorité, kanban state. Sous-tâches via parent_id
|
project.task.type |
Étapes : À faire, En cours, En attente, Terminé, Annulé. Configurable par projet |
project.tags |
Étiquettes : "Urgent", "Client", "Bug", "Amélioration". Filtres et vue Kanban |
project.milestone |
Jalons : dates clés avec livrables. Suivi d'avancement projet |
project.task.recurrence |
Tâche récurrente : "Tous les lundis", "1er du mois". Génération automatique |
project.update |
Mise à jour statut projet : "Fait", "Bloque", "Prochaine étape". Compte-rendu périodique |
project.share.wizard |
Assistant partage projet avec client/partenaire via portail |
project.delete.wizard |
Assistant suppression projet (avec ou sans les tâches) |
3.11 Achats (purchase.*)
| Modèle |
Description |
purchase.order |
Commande fournisseur. Mêmes principes que sale.order côté achat. Cycle : draft → sent → purchase → done → cancel |
purchase.order.line |
Ligne de commande fournisseur : produit, quantité, prix unitaire, date de livraison prévue |
purchase.requisition |
Appel d'offres : demande de prix à plusieurs fournisseurs avant de passer commande |
purchase.requisition.line |
Ligne d'appel d'offres : produit demandé, quantité |
purchase.bill.union |
Assistant regroupement de factures fournisseur en une seule |
purchase.bill.line.union |
Ligne de regroupement : associe chaque ligne de facture à la commande |
3.12 Abonnements (sale.subscription.*)
| Modèle |
Description |
sale.subscription |
Abonnement récurrent. Génère automatiquement des commandes à intervalle régulier. Champs : date début/fin, période, template |
sale.subscription.line |
Ligne d'abonnement : produit, quantité, prix, facturée à chaque renouvellement |
sale.subscription.template |
Modèle d'abonnement prédéfini : "Maintenance Mensuelle", "Support Annuel" |
sale.subscription.alert |
Alertes : "Arrive à échéance", "Paiement en retard". Déclenche des actions |
sale.subscription.close.reason |
Raisons clôture : Résiliation client, Fin de contrat, Impayé |
sale.subscription.recurrence.period |
Périodes : Hebdomadaire, Mensuel, Trimestriel, Annuel |
3.13 E-commerce (website., payment., product.public.*)
| Modèle |
Description |
website |
Site web Odoo. Un par base (ou multi-site). Domaine, langue, thème, menus, pages. Point d'entrée du e-commerce |
website.page |
Pages : contenu HTML, URL (url), indexation (website_indexed), visibilité. Éditable via builder |
website.menu |
Menus de navigation hiérarchiques. Liés à une URL ou page |
website.rewrite |
Redirections 301/302. Préserve le SEO quand une URL change |
website.visitor |
Visiteurs traqués par cookie. Pays, langue, nombre de visites, temps passé. Base du marketing automation |
website.track |
Tracking pages : URL vue, temps, source (SEO, campagne, réseau social) |
product.public.category |
Catégories e-commerce visibles sur le site. Distinct de product.category (interne) |
product.ribbon |
Rubans visuels produits : "Nouveau", "Promo -20%", "Épuisé", "Coup de cœur" |
website.sale.extra.field |
Champs supplémentaires checkout : "N° TVA", "Nom entreprise", "Instructions livraison" |
website.sale.extra.line |
Frais supplémentaires panier : livraison, assurance, emballage cadeau |
payment.provider |
Fournisseurs de paiement en ligne : Stripe, PayPal, Ogone, Adyen. Configuré pour e-commerce et factures |
payment.token |
Token de paiement sauvegardé. Permet le paiement en 1 clic sans ressaisir la carte |
payment.transaction |
Transaction : cycle draft → pending → authorized → done → error → cancel. Liée à facture/commande |
payment.link.wizard |
Assistant lien de paiement : génère une URL à envoyer au client pour qu'il paie en ligne |
3.14 Messagerie (mail., fetchmail.)
| Modèle |
Description |
mail.message |
Messages du chatter. Lié à tout enregistrement (res_model + res_id). Corps HTML, auteur, pièces jointes. Supporte les notes internes et les emails entrants |
mail.activity |
Activités planifiées (to-do). "Appeler ce client dans 3 jours". Apparaît dans le planning. Cycle : planifié → fait → annulé |
mail.activity.type |
Types d'activité : Appel, Email, Réunion, Upload document, À faire. Icône, catégorie, actions par défaut |
mail.template |
Modèles d'email avec placeholders ${object.name}. Utilisé pour confirmations, factures, rappels. ⚠️ auto_delete=True pour désactiver |
mail.mail |
Emails en file d'attente à envoyer. États : outgoing, sent, exception (erreur), cancel. Les emails bloqués restent en exception
|
mail.compose.message |
Assistant composition d'email depuis n'importe quelle fiche (wizard) |
mail.channel |
Canaux de discussion (chat). Publics, privés, directs. Module Discuss |
mail.channel.member |
Membres d'un canal avec droits lecture/écriture |
mail.followers |
Abonnés d'un enregistrement. Reçoivent des notifications aux modifications |
mail.notification |
Notifications envoyées : email, in-app, push. Statut : ready, sent, exception, bounced |
mail.tracking.value |
Suivi des modifications : "Champ X changé de A à B le JJ/MM par Untel". Affiché dans le chatter |
mail.alias |
Alias email : quand un email arrive sur ventes@, crée automatiquement une piste CRM |
mail.alias.domain |
Domaines autorisés pour les alias (@odoo.com, domaine personnalisé) |
mail.shortcode |
Codes courts pour réponses rapides : "#merci" insère un message prédéfini |
mail.link.preview |
Aperçus de lien automatiques dans le chatter (carte de preview URL) |
fetchmail.server |
Serveur email entrant (IMAP/POP). Relève une boîte et transforme les emails en enregistrements. ⚠️ active=False pour désactiver la relève |
3.15 Marketing Email (mailing., link.tracker.)
| Modèle |
Description |
mailing.mailing |
Campagne d'emailing. Destinataires (liste ou domaine M2O), template, date envoi, stats (envoyés, ouverts, cliqués, rebonds) |
mailing.list |
Liste de diffusion contenant des contacts. Peut être générée dynamiquement via un domaine |
mailing.contact |
Contact d'une liste : email, nom, date opt-in/opt-out. Respecte RGPD |
mailing.trace |
Traces de campagne : ouvertures, clics, rebonds, désabonnements. Statistiques détaillées |
link.tracker |
Traqueur générant une URL courte pour mesurer les clics. Utilisé en emailing et e-commerce |
link.tracker.click |
Clic enregistré : IP, date, pays, navigateur |
link.tracker.code |
Code promo lié à un traqueur : "BIENVENUE10" → -10% |
3.16 Sondages (survey.*)
| Modèle |
Description |
survey.survey |
Sondage / Formulaire. Questions, mise en page, scoring, tentatives autorisées, certificat |
survey.question |
Question : type (QCM, texte libre, matrice, échelle), obligatoire, image, condition d'affichage |
survey.question.answer |
Réponse possible à une question QCM avec valeur, score, message conditionnel |
survey.user_input |
Réponse d'un participant : score total, temps passé, date début/fin |
survey.user_input.line |
Ligne de réponse : question + réponse donnée + score. Analyse détaillée |
survey.invite |
Invitation par email avec lien unique pour éviter les doublons |
3.17 Autres modules (event.booth, forum, knowledge, planning, documents, approvals)
| Modèle |
Description |
event.booth |
Stand d'exposition dans un salon. Réservable par sponsors avec services associés |
event.booth.category |
Catégorie stand : Standard, Premium, Gold. Prix et services inclus |
forum.forum |
Forum de discussion : catégories, sujets, posts. Support communautaire et FAQ |
forum.post |
Message forum : lié à un sujet, votable, signalable |
forum.tag |
Étiquettes : "Bug", "Question", "Tutoriel", "Annonce" |
knowledge.article |
Article base connaissance : hiérarchique, markdown, propriétés, favoris |
knowledge.article.favorite |
Article en favori d'un utilisateur |
knowledge.article.member |
Membres avec accès à un article restreint |
knowledge.cover |
Image de couverture d'article |
planning.slot |
Créneau planning : employé, date/heure début, durée, rôle. Shifts |
planning.slot.template |
Modèle créneau récurrent : "Lundi 8h-12h chaque semaine" |
planning.role |
Rôle planning : "Caissier", "Agent d'accueil", "Technicien" |
planning.calendar |
Calendrier regroupant créneaux avec horaires d'ouverture |
documents.document |
Document : fichier + métadonnées + tags + dossier |
documents.folder |
Dossier hiérarchique avec droits d'accès |
documents.tag |
Étiquette document pour catégorisation |
documents.share |
Lien de partage document(s) avec externes |
approval.request |
Demande d'approbation : congés, achat, validation devis |
approval.category |
Catégorie avec workflow : qui approuve, dans quel ordre |
approval.approver |
Approbateur dans une demande. Statut : en attente, approuvé, refusé |
4. Modèles détaillés (les plus utilisés)
4.1 sale.order — Commande
| Champ |
Type |
Obligatoire |
Description |
name |
char |
✅ |
Référence commande |
partner_id |
m2o → res.partner |
✅ |
Client |
partner_invoice_id |
m2o |
✅ |
Adresse facturation |
partner_shipping_id |
m2o |
✅ |
Adresse livraison |
company_id |
m2o |
✅ |
Société (1) |
date_order |
datetime |
✅ |
Date |
picking_policy |
selection |
✅ |
direct ou one
|
state |
selection |
|
draft/sent/sale/done/cancel
|
client_order_ref |
char |
|
Réf externe |
team_id |
m2o → crm.team |
|
Équipe |
user_id |
m2o |
|
Vendeur |
note |
text |
|
Notes |
4.2 product.product — Produit
| Champ |
Type |
Description |
name |
char ✅ |
Nom |
type |
selection |
consu/service/product ⚠️ pas detailed_type
|
list_price |
float |
Prix vente TTC |
barcode |
char |
Code-barres |
categ_id |
m2o |
Catégorie |
sale_ok |
bool |
Vente |
available_in_pos |
bool |
Visible en PDV |
taxes_id |
m2m |
Taxes |
active |
bool |
Actif |
4.3 event.registration — Inscription
| Champ |
Type |
Description |
event_id |
m2o |
Événement |
name |
char |
Nom participant |
email |
char |
Email |
barcode |
char |
QR/Barcode externe |
state |
selection |
draft/open/done/cancel
|
event_ticket_id |
m2o |
Type billet |
sale_order_id |
m2o |
Commande liée |
sale_order_line_id |
m2o |
Ligne liée |
⚠️ description n'existe pas → utiliser barcode.
5. Patterns d'intégration
5.1 Créer une commande avec inscription événement
# Ordre : partenaire → commande → ligne → inscription → lien
pid = odoo_call("res.partner", "create", [{"name": "Client", "email": "x@y.com", "customer_rank": 1}])
so = odoo_call("sale.order", "create", [{"name": "CMD-001", "partner_id": pid, "partner_invoice_id": pid, "partner_shipping_id": pid, "company_id": 1, "date_order": "2026-01-01 10:00:00", "picking_policy": "direct"}])
line = odoo_call("sale.order.line", "create", [{"order_id": so, "product_id": prod_id, "product_uom_qty": 1, "price_unit": 11.00}])
reg = odoo_call("event.registration", "create", [{"event_id": 1, "name": "Client", "email": "x@y.com", "barcode": "1234567890", "state": "open"}])
odoo_call("sale.order.line", "write", [[line], {"registration_ids": [(6, 0, [reg])]}])
5.2 Anti-doublon générique
existing = odoo_call("model.name", "search_read", [[]], {"fields": ["field_key"]})
done = {r["field_key"] for r in existing if r.get("field_key")}
if key in done: continue
5.3 Pagination
all_records, offset = [], 0
while True:
batch = odoo_call("model.name", "search_read",
[[["field", "=", value]]],
{"fields": ["id", "name"], "offset": offset, "limit": 100})
if not batch: break
all_records.extend(batch)
offset += 100
5.4 Désactiver les emails (avant import massif)
# 1. Vider la file d'attente
for mid in odoo_call("mail.mail", "search", [[["state", "in", ["outgoing", "exception"]]]]):
odoo_call("mail.mail", "unlink", [[mid]])
# 2. Désactiver serveur SMTP
for s in odoo_call("ir.mail_server", "search_read", [], {"fields": ["id"]}):
odoo_call("ir.mail_server", "write", [[s["id"]], {"active": False}])
# 3. Désactiver serveur entrant
for s in odoo_call("fetchmail.server", "search_read", [], {"fields": ["id"]}):
odoo_call("fetchmail.server", "write", [[s["id"]], {"active": False}])
# 4. Désactiver templates
for t in odoo_call("mail.template", "search_read", [], {"fields": ["id"]}):
odoo_call("mail.template", "write", [[t["id"]], {"auto_delete": True}])
# 5. Désactiver cron jobs email
for c in odoo_call("ir.cron", "search_read", [], {"fields": ["id", "name"]}):
if any(kw in c["name"].lower() for kw in ["mail", "email", "send", "notification"]):
odoo_call("ir.cron", "write", [[c["id"]], {"active": False}])
# 6. Désactiver confirmation auto
for ev in event_ids:
odoo_call("event.event", "write", [[ev], {"auto_confirm": False}])
6. TVA Réunion (DOM)
| Taux |
Vente ID |
Achat ID |
| 8,5% |
79 |
32 |
| 2,1% |
80 |
35 |
| 0% |
61-70 |
50 |
grp = odoo_call("account.tax.group", "create", [{"name": "TVA 8.5%"}]) # sans country_id !
odoo_call("account.tax", "create", [{"name": "8.5% S", "amount": 8.5, "type_tax_use": "sale", ...}])
7. Pièges
| N° |
Erreur |
Solution |
| 1 |
AccessDenied |
common.login pas /web/session/authenticate
|
| 2 |
create retourne None |
champs obligatoires manquants → fields_get
|
| 3 |
create prend UN dict |
[{...}] pas [[{...}]]
|
| 4 |
detailed_type |
Ne pas utiliser → type
|
| 5 |
Taxe country_id mismatch |
Groupe sans country_id
|
| 6 |
auto_confirm envoie emails |
Désactiver avant import |
| 7 |
unlink échoue |
{"active": False} |
| 8 |
search_read limit=80 |
limit=0 pour tout |
| 9 |
API externe 403 |
Vérifier User-Agent et les headers HTTP requis par l'API tierce |
| 10 |
sale.order 7 champs requis |
name, partner_id ×3, company_id, date_order, picking_policy |
8. Limites SaaS
| ✅ |
❌ |
| API JSON-RPC |
SSH |
| CRUD tous modèles standards |
Modules Python customs |
| Modules Studio |
Accès PostgreSQL |
| Webhooks sortants |
Core mods |
| Extensions Chrome |
Packages Python |
9. Exemples
Créer un client
pid = odoo_call("res.partner", "create", [{"name": "Dupont", "email": "d@mail.com", "customer_rank": 1}])
Créer un produit
prod_id = odoo_call("product.product", "create", [{"name": "Service Conseil", "type": "service", "list_price": 100.00, "sale_ok": True}])
Créer une commande complète
so = odoo_call("sale.order", "create", [{"name": "CMD-001", "partner_id": pid, "partner_invoice_id": pid, "partner_shipping_id": pid, "company_id": 1, "date_order": "2026-01-01 10:00:00", "picking_policy": "direct", "state": "draft"}])
line = odoo_call("sale.order.line", "create", [{"order_id": so, "product_id": prod_id, "product_uom_qty": 2, "price_unit": 100.00}])
odoo_call("sale.order", "write", [[so], {"state": "sale"}]) # confirmer
Créer une facture depuis une commande
# Odoo gère automatiquement la création de facture via le bouton "Créer une facture"
# En API, on peut créer manuellement :
invoice_id = odoo_call("account.move", "create", [{"move_type": "out_invoice", "partner_id": pid, "invoice_date": "2026-01-01", "invoice_line_ids": [(0, 0, {"product_id": prod_id, "quantity": 2, "price_unit": 100.00})]}])
odoo_call("account.move", "write", [[invoice_id], {"state": "posted"}])
Rechercher avec filtres
# Commandes confirmées > 100€ du mois
orders = odoo_call("sale.order", "search_read",
[[["state", "=", "sale"], ["amount_total", ">", 100], ["date_order", ">=", "2026-01-01"]]],
{"fields": ["name", "partner_id", "amount_total"], "order": "date_order desc", "limit": 50})