a74b144399a8e2b18590a66f3ebaa56052e8a586
odoo/api-reference.md
| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | --- |
| 2 | 2 | title: Référence API Odoo — Complète |
| 3 | 3 | created: 2026-05-29 |
| 4 | -updated: 2026-05-29 |
|
| 4 | +updated: 2026-05-30 |
|
| 5 | 5 | type: concept |
| 6 | 6 | tags: [odoo, api, json-rpc, reference, developpeur] |
| 7 | 7 | sources: [odoo-online skill, odoo-api skill, odoo.com/documentation] |
| ... | ... | @@ -13,10 +13,11 @@ confidence: high |
| 13 | 13 | > **Base URL** : `https://sarl-le-relais-de-louest.odoo.com/jsonrpc` |
| 14 | 14 | > **Protocole** : JSON-RPC 2.0 |
| 15 | 15 | > **Auth** : `common.login` + API Key |
| 16 | +> **Modèles documentés** : ~250 modèles standards Odoo 19 |
|
| 16 | 17 | |
| 17 | 18 | --- |
| 18 | 19 | |
| 19 | -## 1. Authentification |
|
| 20 | +## 1. Authentification (inchangée) |
|
| 20 | 21 | |
| 21 | 22 | ### 1.1 Obtenir un UID |
| 22 | 23 | |
| ... | ... | @@ -36,746 +37,594 @@ Content-Type: application/json |
| 36 | 37 | } |
| 37 | 38 | ``` |
| 38 | 39 | |
| 39 | -**Réponse** : |
|
| 40 | -```json |
|
| 41 | -{"jsonrpc": "2.0", "id": 1, "result": 2} |
|
| 42 | -``` |
|
| 43 | - |
|
| 44 | -`result` = UID (integer, généralement 2 pour l'admin). |
|
| 45 | - |
|
| 46 | -### 1.2 API Key |
|
| 47 | - |
|
| 48 | -Générée dans Odoo : **Profil → Preferences → Account Security → API Keys → New API Key**. |
|
| 49 | - |
|
| 50 | -⚠️ **Ne pas confondre** avec un token de session navigateur (SHA visible dans l'URL Odoo). |
|
| 40 | +**Réponse** : `{"jsonrpc": "2.0", "id": 1, "result": 2}` |
|
| 51 | 41 | |
| 52 | -### 1.3 Helper Python |
|
| 42 | +### 1.2 Helper Python |
|
| 53 | 43 | |
| 54 | 44 | ```python |
| 55 | 45 | import requests |
| 56 | - |
|
| 57 | -DB = "sarl-le-relais-de-louest" |
|
| 58 | -UID = None |
|
| 59 | -PWD = None # API key |
|
| 46 | +DB, UID, PWD = "sarl-le-relais-de-louest", None, None |
|
| 60 | 47 | URL = f"https://{DB}.odoo.com/jsonrpc" |
| 61 | 48 | |
| 62 | 49 | def odoo_call(model, method, *args): |
| 63 | 50 | payload = { |
| 64 | 51 | "jsonrpc": "2.0", "method": "call", |
| 65 | 52 | "params": { |
| 66 | - "service": "object", |
|
| 67 | - "method": "execute_kw", |
|
| 53 | + "service": "object", "method": "execute_kw", |
|
| 68 | 54 | "args": [DB, UID, PWD, model, method] + list(args) |
| 69 | 55 | }, "id": 1 |
| 70 | 56 | } |
| 71 | - resp = requests.post(URL, json=payload, timeout=30).json() |
|
| 72 | - if "error" in resp: |
|
| 73 | - raise Exception(resp["error"]["data"]["message"]) |
|
| 74 | - return resp.get("result") |
|
| 57 | + r = requests.post(URL, json=payload, timeout=30).json() |
|
| 58 | + if "error" in r: |
|
| 59 | + raise Exception(r["error"]["data"]["message"]) |
|
| 60 | + return r.get("result") |
|
| 75 | 61 | ``` |
| 76 | 62 | |
| 77 | ---- |
|
| 78 | - |
|
| 79 | 63 | ## 2. Méthodes génériques |
| 80 | 64 | |
| 81 | -Tous les modèles supportent ces 7 méthodes : |
|
| 82 | - |
|
| 83 | -### search_read — Rechercher et lire |
|
| 84 | -```python |
|
| 85 | -records = odoo_call("model.name", "search_read", |
|
| 86 | - [domain], # liste de conditions |
|
| 87 | - {kwargs} # fields, offset, limit, order |
|
| 88 | -) |
|
| 89 | -``` |
|
| 90 | - |
|
| 91 | -**Paramètres :** |
|
| 92 | -| Param | Type | Description | |
|
| 93 | -|-------|------|-------------| |
|
| 94 | -| `domain` | `list` | Conditions de filtrage (voir §2.1) | |
|
| 95 | -| `fields` | `list` | Champs à retourner | |
|
| 96 | -| `offset` | `int` | Pagination : sauter N enregistrements | |
|
| 97 | -| `limit` | `int` | Max résultats (défaut: 80) | |
|
| 98 | -| `order` | `str` | Tri : `"date_order desc"` | |
|
| 99 | - |
|
| 100 | -### search — Rechercher (IDs seulement) |
|
| 101 | -```python |
|
| 102 | -ids = odoo_call("model.name", "search", [domain]) |
|
| 103 | -# Retourne [1, 5, 42, ...] |
|
| 104 | -``` |
|
| 65 | +Tous les modèles supportent : `search`, `search_read`, `search_count`, `read`, `create`, `write`, `unlink`, `fields_get`. |
|
| 105 | 66 | |
| 106 | -### search_count — Compter |
|
| 107 | -```python |
|
| 108 | -count = odoo_call("model.name", "search_count", [domain]) |
|
| 109 | -# Retourne int |
|
| 110 | -``` |
|
| 67 | +### Syntaxe des domaines |
|
| 111 | 68 | |
| 112 | -### read — Lire par ID |
|
| 113 | 69 | ```python |
| 114 | -data = odoo_call("model.name", "read", [[id1, id2]], {"fields": ["name", "email"]}) |
|
| 70 | +["field", "=", value] # égalité |
|
| 71 | +["field", "!=", value] # différent |
|
| 72 | +["field", ">=", value] # supérieur ou égal |
|
| 73 | +["field", "=like", "xxx%"] # LIKE |
|
| 74 | +["field", "in", [v1, v2]] # IN |
|
| 75 | +[["f1", "=", v1], ["f2", "=", v2]] # AND |
|
| 76 | +[["f1", "=", v1], "|", ["f1", "=", v2]] # OR |
|
| 115 | 77 | ``` |
| 116 | 78 | |
| 117 | -### create — Créer |
|
| 118 | -```python |
|
| 119 | -new_id = odoo_call("model.name", "create", [{champs}]) |
|
| 120 | -# ⚠️ UN seul dict, pas une liste de dicts |
|
| 121 | -``` |
|
| 79 | +### Commandes relationnelles |
|
| 122 | 80 | |
| 123 | -### write — Modifier |
|
| 124 | 81 | ```python |
| 125 | -odoo_call("model.name", "write", [[id1, id2], {champs}]) |
|
| 126 | -``` |
|
| 127 | - |
|
| 128 | -### unlink — Supprimer |
|
| 129 | -```python |
|
| 130 | -odoo_call("model.name", "unlink", [[id1, id2]]) |
|
| 131 | -``` |
|
| 132 | - |
|
| 133 | -### 2.1 Syntaxe des domaines |
|
| 134 | - |
|
| 135 | -```python |
|
| 136 | -# Égalité |
|
| 137 | -["field", "=", value] |
|
| 138 | - |
|
| 139 | -# Inégalité |
|
| 140 | -["field", "!=", value] |
|
| 141 | -["field", ">", value] |
|
| 142 | -["field", "<", value] |
|
| 143 | -["field", ">=", value] |
|
| 144 | -["field", "<=", value] |
|
| 145 | - |
|
| 146 | -# LIKE / NOT LIKE |
|
| 147 | -["field", "=like", "pattern%"] # % = wildcard |
|
| 148 | -["field", "not like", "xyz"] |
|
| 149 | - |
|
| 150 | -# IN / NOT IN |
|
| 151 | -["field", "in", [val1, val2]] |
|
| 152 | -["field", "not in", [val1, val2]] |
|
| 153 | - |
|
| 154 | -# AND = liste de conditions |
|
| 155 | -[["field1", "=", v1], ["field2", "=", v2]] |
|
| 156 | -# field1 = v1 ET field2 = v2 |
|
| 157 | - |
|
| 158 | -# OR = conditions dans une sous-liste |
|
| 159 | -[["field1", "=", v1], "|", ["field1", "=", v2]] |
|
| 160 | -# field1 = v1 OU field1 = v2 |
|
| 161 | -``` |
|
| 162 | - |
|
| 163 | -### 2.2 Many2one / One2many / Many2many |
|
| 164 | - |
|
| 165 | -```python |
|
| 166 | -# Many2one → integer |
|
| 82 | +# Many2one → int |
|
| 167 | 83 | "partner_id": 42 |
| 168 | 84 | |
| 169 | -# Many2many → commandes spéciales |
|
| 170 | -"taxes_id": [(6, 0, [id1, id2])] # Remplacer par cette liste |
|
| 171 | -"taxes_id": [(4, id3)] # Ajouter un élément |
|
| 172 | -"taxes_id": [(3, id3)] # Supprimer un élément |
|
| 173 | -"taxes_id": [(5, 0, 0)] # Vider tout |
|
| 85 | +# Many2many |
|
| 86 | +"taxes_id": [(6, 0, [id1, id2])] # remplacer |
|
| 87 | +"taxes_id": [(4, id3)] # ajouter |
|
| 88 | +"taxes_id": [(3, id3)] # supprimer |
|
| 89 | +"taxes_id": [(5, 0, 0)] # vider |
|
| 174 | 90 | |
| 175 | -# One2many → commandes identiques |
|
| 176 | -"order_line": [(0, 0, {vals})] # Créer et lier |
|
| 177 | -"order_line": [(1, id, {vals})] # Modifier existant |
|
| 178 | -"order_line": [(2, id)] # Supprimer existant |
|
| 91 | +# One2many |
|
| 92 | +"order_line": [(0, 0, {vals})] # créer + lier |
|
| 93 | +"order_line": [(1, id, {vals})] # modifier |
|
| 94 | +"order_line": [(2, id)] # supprimer |
|
| 179 | 95 | ``` |
| 180 | 96 | |
| 181 | 97 | --- |
| 182 | 98 | |
| 183 | -## 3. Modèles — Référence exhaustive |
|
| 99 | +## 3. Catalogue complet des modèles Odoo 19 |
|
| 100 | + |
|
| 101 | +> Organisé par module. Chaque modèle est accessible via `odoo_call("nom.modele", ...)`. |
|
| 102 | +> ⚠️ = piège connu | 📖 = détaillé plus bas |
|
| 103 | + |
|
| 104 | +### 3.0 Technique / Base (ir.*) |
|
| 105 | + |
|
| 106 | +| Modèle | Description | |
|
| 107 | +|--------|-------------| |
|
| 108 | +| `ir.model` | Registre de tous les modèles | |
|
| 109 | +| `ir.model.fields` | Champs de chaque modèle | |
|
| 110 | +| `ir.module.module` | Modules installés/à installer | |
|
| 111 | +| `ir.ui.view` | Vues XML (form, tree, kanban...) | |
|
| 112 | +| `ir.ui.menu` | Menus | |
|
| 113 | +| `ir.actions.act_window` | Actions fenêtre | |
|
| 114 | +| `ir.actions.server` | Actions serveur / automations | |
|
| 115 | +| `ir.actions.report` | Rapports PDF | |
|
| 116 | +| `ir.actions.url` | Actions URL | |
|
| 117 | +| `ir.cron` | Tâches planifiées | |
|
| 118 | +| `ir.mail_server` | Serveurs SMTP sortants | |
|
| 119 | +| `ir.config_parameter` | Paramètres système (clé/valeur) | |
|
| 120 | +| `ir.sequence` | Séquences de numérotation | |
|
| 121 | +| `ir.translation` | Traductions | |
|
| 122 | +| `ir.attachment` | Pièces jointes / documents | |
|
| 123 | +| `ir.qweb` | Templates QWeb | |
|
| 124 | +| `ir.filters` | Filtres sauvegardés utilisateur | |
|
| 125 | +| `ir.default` | Valeurs par défaut utilisateur | |
|
| 126 | +| `ir.logging` | Logs applicatifs | |
|
| 127 | +| `ir.property` | Propriétés champ | |
|
| 128 | + |
|
| 129 | +### 3.1 Contacts (res.* — resources) |
|
| 130 | + |
|
| 131 | +| Modèle | Description | |
|
| 132 | +|--------|-------------| |
|
| 133 | +| `res.partner` | 📖 Contacts, clients, fournisseurs | |
|
| 134 | +| `res.partner.category` | Étiquettes / tags | |
|
| 135 | +| `res.partner.bank` | Comptes bancaires | |
|
| 136 | +| `res.partner.title` | Titres (M., Mme, Dr...) | |
|
| 137 | +| `res.partner.industry` | Secteurs d'activité | |
|
| 138 | +| `res.company` | Sociétés | |
|
| 139 | +| `res.users` | Utilisateurs | |
|
| 140 | +| `res.groups` | Groupes de sécurité | |
|
| 141 | +| `res.lang` | Langues | |
|
| 142 | +| `res.country` | Pays | |
|
| 143 | +| `res.country.state` | Régions/États | |
|
| 144 | +| `res.currency` | Devises | |
|
| 145 | +| `res.currency.rate` | Taux de change | |
|
| 146 | +| `res.bank` | Banques | |
|
| 147 | +| `res.config.settings` | Configuration générale | |
|
| 148 | + |
|
| 149 | +### 3.2 Ventes (sale.*) |
|
| 150 | + |
|
| 151 | +| Modèle | Description | |
|
| 152 | +|--------|-------------| |
|
| 153 | +| `sale.order` | 📖 Commandes / devis | |
|
| 154 | +| `sale.order.line` | 📖 Lignes de commande | |
|
| 155 | +| `sale.order.template` | Modèles de devis | |
|
| 156 | +| `sale.order.template.line` | Lignes de modèle de devis | |
|
| 157 | +| `sale.order.template.option` | Options de modèles | |
|
| 158 | +| `sale.advance.payment.inv` | Assistant facture d'acompte | |
|
| 159 | +| `sale.order.cancel` | Assistant annulation | |
|
| 160 | +| `sale.payment.provider.onboarding.wizard` | Assistant onboarding paiement | |
|
| 161 | +| `sale.order.line.margin` | Marge par ligne (lecture) | |
|
| 162 | + |
|
| 163 | +### 3.3 PDV / Point de Vente (pos.*) |
|
| 164 | + |
|
| 165 | +| Modèle | Description | |
|
| 166 | +|--------|-------------| |
|
| 167 | +| `pos.order` | 📖 Commandes PDV | |
|
| 168 | +| `pos.order.line` | 📖 Lignes PDV | |
|
| 169 | +| `pos.session` | 📖 Sessions de caisse | |
|
| 170 | +| `pos.config` | 📖 Configuration PDV | |
|
| 171 | +| `pos.payment` | Paiements PDV | |
|
| 172 | +| `pos.payment.method` | Modes de paiement | |
|
| 173 | +| `pos.category` | Catégories de produits PDV | |
|
| 174 | +| `pos.bill` | Tickets/reçus | |
|
| 175 | +| `pos.session.statement` | Relevés de session | |
|
| 176 | +| `pos.cash.box.in` | Entrée caisse | |
|
| 177 | +| `pos.cash.box.out` | Sortie caisse | |
|
| 178 | +| `pos.order.return` | Remboursement PDV | |
|
| 179 | +| `pos.discount` | Remises PDV | |
|
| 180 | +| `pos.combo` | Combos (menus) | |
|
| 181 | +| `pos.combo.line` | Lignes de combo | |
|
| 182 | +| `pos.close.session.wizard` | Assistant fermeture session | |
|
| 183 | +| `pos.printer` | Imprimantes IoT | |
|
| 184 | +| `pos.pack.operation.lot` | N° de lot/série | |
|
| 185 | + |
|
| 186 | +### 3.4 Produits (product.*) |
|
| 187 | + |
|
| 188 | +| Modèle | Description | |
|
| 189 | +|--------|-------------| |
|
| 190 | +| `product.template` | Modèles de produits | |
|
| 191 | +| `product.product` | 📖 Variantes produits | |
|
| 192 | +| `product.category` | 📖 Catégories | |
|
| 193 | +| `product.attribute` | Attributs (taille, couleur...) | |
|
| 194 | +| `product.attribute.value` | Valeurs d'attribut | |
|
| 195 | +| `product.template.attribute.line` | Ligne attribut-modèle | |
|
| 196 | +| `product.template.attribute.value` | Valeur attribut-modèle | |
|
| 197 | +| `product.packaging` | Colisage | |
|
| 198 | +| `product.supplierinfo` | Infos fournisseur par produit | |
|
| 199 | +| `product.pricelist` | Listes de prix | |
|
| 200 | +| `product.pricelist.item` | Règles de prix | |
|
| 201 | +| `product.uom` | Unités de mesure | |
|
| 202 | +| `product.uom.categ` | Catégories d'unités | |
|
| 203 | +| `product.image` | Images (obsolète, utiliser `ir.attachment`) | |
|
| 204 | +| `product.label.layout` | Mise en page étiquettes | |
|
| 205 | +| `product.replenish` | Assistant réapprovisionnement | |
|
| 206 | + |
|
| 207 | +### 3.5 Inventaire / Stock (stock.*) |
|
| 208 | + |
|
| 209 | +| Modèle | Description | |
|
| 210 | +|--------|-------------| |
|
| 211 | +| `stock.picking` | Transferts / bons de livraison | |
|
| 212 | +| `stock.move` | Mouvements de stock | |
|
| 213 | +| `stock.move.line` | Lignes de mouvement | |
|
| 214 | +| `stock.quant` | 📖 Quantités en stock | |
|
| 215 | +| `stock.location` | Emplacements | |
|
| 216 | +| `stock.warehouse` | Entrepôts | |
|
| 217 | +| `stock.inventory.adjustment.name` | Ajustement d'inventaire | |
|
| 218 | +| `stock.rule` | Règles de réapprovisionnement | |
|
| 219 | +| `stock.picking.type` | Types d'opération | |
|
| 220 | +| `stock.package.type` | Types de colis | |
|
| 221 | +| `stock.package.destination` | Destination colis | |
|
| 222 | +| `stock.package.level` | Niveau colis | |
|
| 223 | +| `stock.lot` | Lots / numéros de série | |
|
| 224 | +| `stock.storage.category` | Catégories de stockage | |
|
| 225 | +| `stock.putaway.rule` | Règles de rangement | |
|
| 226 | +| `stock.scrap` | Mise au rebut | |
|
| 227 | +| `stock.warn.insufficient.qty` | Assistant stock insuffisant | |
|
| 228 | +| `stock.quantity.history` | Historique quantités | |
|
| 229 | +| `stock.track.confirmation` | Traçabilité | |
|
| 230 | +| `stock.track.line` | Ligne de traçabilité | |
|
| 231 | +| `stock.assign.serial` | Assignation n° série | |
|
| 232 | +| `stock.scheduler.compute` | Calcul du scheduler MTS/MTO | |
|
| 233 | +| `stock.change.product.qty` | Modification quantité | |
|
| 234 | +| `stock.return.picking` | Retour de transfert | |
|
| 235 | + |
|
| 236 | +### 3.6 Facturation / Comptabilité (account.*) |
|
| 237 | + |
|
| 238 | +| Modèle | Description | |
|
| 239 | +|--------|-------------| |
|
| 240 | +| `account.move` | 📖 Écritures comptables / Factures | |
|
| 241 | +| `account.move.line` | Lignes d'écriture | |
|
| 242 | +| `account.journal` | Journaux (ventes, banque, caisse...) | |
|
| 243 | +| `account.tax` | 📖 Taxes | |
|
| 244 | +| `account.tax.group` | 📖 Groupes de taxes | |
|
| 245 | +| `account.fiscal.position` | Positions fiscales | |
|
| 246 | +| `account.fiscal.position.tax` | Mapping taxes position fiscale | |
|
| 247 | +| `account.fiscal.position.account` | Mapping comptes position fiscale | |
|
| 248 | +| `account.payment` | 📖 Paiements | |
|
| 249 | +| `account.payment.register` | Assistant enregistrement paiement | |
|
| 250 | +| `account.payment.term` | Conditions de paiement | |
|
| 251 | +| `account.payment.term.line` | Lignes conditions de paiement | |
|
| 252 | +| `account.chart.template` | Modèle plan comptable ⚠️ SaaS restreint | |
|
| 253 | +| `account.account` | Comptes comptables | |
|
| 254 | +| `account.account.type` | Types de comptes | |
|
| 255 | +| `account.account.tag` | Étiquettes comptes | |
|
| 256 | +| `account.group` | Groupes de comptes | |
|
| 257 | +| `account.bank.statement` | Relevés bancaires | |
|
| 258 | +| `account.bank.statement.line` | Lignes relevé | |
|
| 259 | +| `account.reconcile.model` | Modèles de lettrage | |
|
| 260 | +| `account.reconcile.model.line` | Lignes modèle | |
|
| 261 | +| `account.analytic.account` | Comptes analytiques | |
|
| 262 | +| `account.analytic.line` | Lignes analytiques | |
|
| 263 | +| `account.analytic.plan` | Plans analytiques | |
|
| 264 | +| `account.analytic.tag` | Étiquettes analytiques | |
|
| 265 | +| `account.asset` | Immobilisations | |
|
| 266 | +| `account.asset.category` | Catégories d'immobilisation | |
|
| 267 | +| `account.budget.post` | Postes budgétaires | |
|
| 268 | +| `account.cash.rounding` | Arrondi espèces | |
|
| 269 | +| `account.financial.year.op` | Ouverture exercice | |
|
| 270 | +| `account.aged.trial.balance` | Balance âgée | |
|
| 271 | +| `account.general.ledger` | Grand livre | |
|
| 272 | +| `account.trial.balance` | Balance | |
|
| 273 | +| `account.tax.report` | Rapport de taxes | |
|
| 274 | +| `account.report` | Rapports comptables | |
|
| 275 | +| `account.report.line` | Lignes de rapport | |
|
| 276 | +| `account.accrued.orders.wizard` | Assistant OD | |
|
| 277 | +| `account.automatic.entry.wizard` | Assistant écritures auto | |
|
| 278 | +| `wizard.multi.charts.accounts` | Assistant plan comptable ⚠️ SaaS restreint | |
|
| 279 | + |
|
| 280 | +### 3.7 Événements (event.*) |
|
| 281 | + |
|
| 282 | +| Modèle | Description | |
|
| 283 | +|--------|-------------| |
|
| 284 | +| `event.event` | 📖 Événements | |
|
| 285 | +| `event.event.ticket` | 📖 Types de billets | |
|
| 286 | +| `event.registration` | 📖 Participants / inscriptions | |
|
| 287 | +| `event.type` | Catégories d'événements | |
|
| 288 | +| `event.tag` | Étiquettes événements | |
|
| 289 | +| `event.mail` | Emails événement planifiés | |
|
| 290 | +| `event.mail.registration` | Emails inscription | |
|
| 291 | +| `event.track` | Programme / sessions | |
|
| 292 | +| `event.track.location` | Lieux de session | |
|
| 293 | +| `event.track.tag` | Étiquettes session | |
|
| 294 | +| `event.sponsor` | Sponsors | |
|
| 295 | +| `event.sponsor.type` | Types de sponsor | |
|
| 296 | +| `event.registration.cancel` | Assistant annulation inscription | |
|
| 297 | + |
|
| 298 | +### 3.8 CRM (crm.*) |
|
| 299 | + |
|
| 300 | +| Modèle | Description | |
|
| 301 | +|--------|-------------| |
|
| 302 | +| `crm.lead` | Pistes / Leads | |
|
| 303 | +| `crm.team` | Équipes commerciales | |
|
| 304 | +| `crm.stage` | Étapes du pipeline | |
|
| 305 | +| `crm.tag` | Étiquettes CRM | |
|
| 306 | +| `crm.lead.lost` | Assistant perte de piste | |
|
| 307 | +| `crm.lead.to.opportunity` | Conversion lead → opportunité | |
|
| 308 | +| `crm.merge.opportunity` | Fusion opportunités | |
|
| 309 | +| `crm.iap.lead.mining.request` | Lead Mining IAP | |
|
| 310 | +| `crm.iap.lead.role` | Rôles IAP | |
|
| 311 | +| `crm.iap.lead.seniority` | Séniorité IAP | |
|
| 312 | +| `crm.quotation.partner` | Partenaire de devis | |
|
| 313 | + |
|
| 314 | +### 3.9 Ressources Humaines (hr.*) |
|
| 315 | + |
|
| 316 | +| Modèle | Description | |
|
| 317 | +|--------|-------------| |
|
| 318 | +| `hr.employee` | Employés | |
|
| 319 | +| `hr.employee.category` | Catégories employés | |
|
| 320 | +| `hr.department` | Départements | |
|
| 321 | +| `hr.job` | Postes | |
|
| 322 | +| `hr.contract` | Contrats | |
|
| 323 | +| `hr.leave` | Congés | |
|
| 324 | +| `hr.leave.type` | Types de congés | |
|
| 325 | +| `hr.leave.allocation` | Allocations de congés | |
|
| 326 | +| `hr.expense` | Notes de frais | |
|
| 327 | +| `hr.expense.sheet` | Feuilles de frais | |
|
| 328 | +| `hr.expense.category` | Catégories de frais | |
|
| 329 | +| `hr.attendance` | Présences/pointages | |
|
| 330 | +| `hr.applicant` | Candidats | |
|
| 331 | +| `hr.recruitment.stage` | Étapes recrutement | |
|
| 332 | +| `hr.plan` | Plans RH | |
|
| 333 | +| `hr.plan.activity.type` | Types d'activité plan RH | |
|
| 334 | +| `hr.work.entry.type` | Types d'entrée de travail | |
|
| 335 | + |
|
| 336 | +### 3.10 Projets (project.*) |
|
| 337 | + |
|
| 338 | +| Modèle | Description | |
|
| 339 | +|--------|-------------| |
|
| 340 | +| `project.project` | Projets | |
|
| 341 | +| `project.task` | Tâches | |
|
| 342 | +| `project.task.type` | Étapes de tâche | |
|
| 343 | +| `project.tags` | Étiquettes projet | |
|
| 344 | +| `project.milestone` | Jalons | |
|
| 345 | +| `project.task.recurrence` | Tâches récurrentes | |
|
| 346 | +| `project.update` | Mises à jour projet | |
|
| 347 | +| `project.share.wizard` | Assistant partage projet | |
|
| 348 | +| `project.delete.wizard` | Assistant suppression projet | |
|
| 349 | + |
|
| 350 | +### 3.11 Facturation / Temps (account.analytic.*) |
|
| 351 | + |
|
| 352 | +| Modèle | Description | |
|
| 353 | +|--------|-------------| |
|
| 354 | +| `account.analytic.account` | Comptes analytiques | |
|
| 355 | +| `account.analytic.line` | Lignes analytiques (timesheet) | |
|
| 356 | +| `account.analytic.plan` | Plans analytiques | |
|
| 357 | +| `account.analytic.tag` | Étiquettes analytiques | |
|
| 358 | +| `account.analytic.distribution.model` | Modèles de distribution | |
|
| 359 | + |
|
| 360 | +### 3.12 Timesheet (hr_timesheet.*) |
|
| 361 | + |
|
| 362 | +| Modèle | Description | |
|
| 363 | +|--------|-------------| |
|
| 364 | +| `account.analytic.line` | Feuilles de temps (même modèle que 3.11) | |
|
| 365 | +| `project.task.create.timesheet` | Assistant création timesheet | |
|
| 366 | +| `timesheet.analysis.report` | Rapport d'analyse | |
|
| 367 | + |
|
| 368 | +### 3.13 Achats (purchase.*) |
|
| 369 | + |
|
| 370 | +| Modèle | Description | |
|
| 371 | +|--------|-------------| |
|
| 372 | +| `purchase.order` | Commandes fournisseur | |
|
| 373 | +| `purchase.order.line` | Lignes commande fournisseur | |
|
| 374 | +| `purchase.requisition` | Appels d'offres | |
|
| 375 | +| `purchase.requisition.line` | Lignes appel d'offres | |
|
| 376 | +| `purchase.bill.union` | Regroupement factures | |
|
| 377 | +| `purchase.bill.line.union` | Lignes regroupement | |
|
| 378 | + |
|
| 379 | +### 3.14 Abonnements (sale.subscription.*) |
|
| 380 | + |
|
| 381 | +| Modèle | Description | |
|
| 382 | +|--------|-------------| |
|
| 383 | +| `sale.subscription` | Abonnements | |
|
| 384 | +| `sale.subscription.line` | Lignes d'abonnement | |
|
| 385 | +| `sale.subscription.template` | Modèles d'abonnement | |
|
| 386 | +| `sale.subscription.alert` | Alertes abonnement | |
|
| 387 | +| `sale.subscription.close.reason` | Raisons clôture | |
|
| 388 | +| `sale.subscription.recurrence.period` | Périodes récurrentes | |
|
| 389 | + |
|
| 390 | +### 3.15 E-commerce (website.* + product.public.*) |
|
| 391 | + |
|
| 392 | +| Modèle | Description | |
|
| 393 | +|--------|-------------| |
|
| 394 | +| `website` | Sites web | |
|
| 395 | +| `website.page` | Pages | |
|
| 396 | +| `website.menu` | Menus du site | |
|
| 397 | +| `website.rewrite` | Redirections | |
|
| 398 | +| `website.visitor` | Visiteurs | |
|
| 399 | +| `website.track` | Tracking | |
|
| 400 | +| `product.public.category` | Catégories e-commerce | |
|
| 401 | +| `product.ribbon` | Rubans produit | |
|
| 402 | +| `website.sale.extra.field` | Champs supplémentaires checkout | |
|
| 403 | +| `website.sale.extra.line` | Lignes frais supplémentaires | |
|
| 404 | +| `payment.provider` | Fournisseurs de paiement | |
|
| 405 | +| `payment.token` | Tokens de paiement sauvegardés | |
|
| 406 | +| `payment.transaction` | Transactions de paiement | |
|
| 407 | +| `payment.link.wizard` | Assistant lien de paiement | |
|
| 408 | + |
|
| 409 | +### 3.16 Messagerie / Emails (mail.*) |
|
| 410 | + |
|
| 411 | +| Modèle | Description | |
|
| 412 | +|--------|-------------| |
|
| 413 | +| `mail.message` | Messages (fil de discussion) | |
|
| 414 | +| `mail.activity` | Activités planifiées | |
|
| 415 | +| `mail.activity.type` | Types d'activité | |
|
| 416 | +| `mail.template` | Modèles d'email | |
|
| 417 | +| `mail.mail` | 📖 Emails en file d'attente | |
|
| 418 | +| `mail.compose.message` | Assistant composition | |
|
| 419 | +| `mail.channel` | Canaux de discussion | |
|
| 420 | +| `mail.channel.member` | Membres du canal | |
|
| 421 | +| `mail.followers` | Abonnés | |
|
| 422 | +| `mail.notification` | Notifications | |
|
| 423 | +| `mail.tracking.value` | Valeurs de suivi | |
|
| 424 | +| `mail.alias` | Alias email | |
|
| 425 | +| `mail.alias.domain` | Domaines alias | |
|
| 426 | +| `mail.shortcode` | Codes courts | |
|
| 427 | +| `mail.link.preview` | Aperçus de lien | |
|
| 428 | +| `fetchmail.server` | Serveur entrant (IMAP/POP) | |
|
| 429 | + |
|
| 430 | +### 3.17 Marketing / Email (mass_mailing.* + link.tracker.*) |
|
| 431 | + |
|
| 432 | +| Modèle | Description | |
|
| 433 | +|--------|-------------| |
|
| 434 | +| `mailing.mailing` | Campagnes email | |
|
| 435 | +| `mailing.list` | Listes de diffusion | |
|
| 436 | +| `mailing.contact` | Contacts liste | |
|
| 437 | +| `mailing.trace` | Traces (ouvertures, clics) | |
|
| 438 | +| `link.tracker` | Traqueurs de lien | |
|
| 439 | +| `link.tracker.click` | Clics sur liens | |
|
| 440 | +| `link.tracker.code` | Codes de lien | |
|
| 441 | + |
|
| 442 | +### 3.18 Sondages (survey.*) |
|
| 443 | + |
|
| 444 | +| Modèle | Description | |
|
| 445 | +|--------|-------------| |
|
| 446 | +| `survey.survey` | Sondages | |
|
| 447 | +| `survey.question` | Questions | |
|
| 448 | +| `survey.question.answer` | Réponses possibles | |
|
| 449 | +| `survey.user_input` | Réponses utilisateur | |
|
| 450 | +| `survey.user_input.line` | Lignes de réponse | |
|
| 451 | +| `survey.invite` | Invitations | |
|
| 452 | + |
|
| 453 | +### 3.19 Événements Live / Forum |
|
| 454 | + |
|
| 455 | +| Modèle | Description | |
|
| 456 | +|--------|-------------| |
|
| 457 | +| `event.booth` | Stands salon | |
|
| 458 | +| `event.booth.category` | Catégories stand | |
|
| 459 | +| `forum.forum` | Forums | |
|
| 460 | +| `forum.post` | Messages forum | |
|
| 461 | +| `forum.tag` | Étiquettes forum | |
|
| 462 | + |
|
| 463 | +### 3.20 Base de connaissances (knowledge.*) |
|
| 464 | + |
|
| 465 | +| Modèle | Description | |
|
| 466 | +|--------|-------------| |
|
| 467 | +| `knowledge.article` | Articles base de connaissance | |
|
| 468 | +| `knowledge.article.favorite` | Favoris article | |
|
| 469 | +| `knowledge.article.member` | Membres article | |
|
| 470 | +| `knowledge.cover` | Couverture | |
|
| 471 | + |
|
| 472 | +### 3.21 Planning (planning.*) |
|
| 473 | + |
|
| 474 | +| Modèle | Description | |
|
| 475 | +|--------|-------------| |
|
| 476 | +| `planning.slot` | Créneaux planning | |
|
| 477 | +| `planning.slot.template` | Modèles de créneau | |
|
| 478 | +| `planning.role` | Rôles planning | |
|
| 479 | +| `planning.calendar` | Calendriers | |
|
| 480 | + |
|
| 481 | +### 3.22 Documents (documents.*) |
|
| 482 | + |
|
| 483 | +| Modèle | Description | |
|
| 484 | +|--------|-------------| |
|
| 485 | +| `documents.document` | Documents | |
|
| 486 | +| `documents.folder` | Dossiers | |
|
| 487 | +| `documents.tag` | Étiquettes document | |
|
| 488 | +| `documents.share` | Partage de documents | |
|
| 489 | + |
|
| 490 | +### 3.23 Approbations (approvals.*) |
|
| 491 | + |
|
| 492 | +| Modèle | Description | |
|
| 493 | +|--------|-------------| |
|
| 494 | +| `approval.request` | Demandes d'approbation | |
|
| 495 | +| `approval.category` | Catégories d'approbation | |
|
| 496 | +| `approval.approver` | Approbateurs | |
|
| 184 | 497 | |
| 185 | -### 3.1 res.partner — Contacts / Clients |
|
| 498 | +--- |
|
| 186 | 499 | |
| 187 | -| Champ | Type | Obligatoire | Description | |
|
| 188 | -|-------|------|:----------:|-------------| |
|
| 189 | -| `name` | char | ✅ | Nom complet | |
|
| 190 | -| `email` | char | | Email | |
|
| 191 | -| `phone` | char | | Téléphone fixe | |
|
| 192 | -| `mobile` | char | | Téléphone mobile | |
|
| 193 | -| `street` | char | | Rue | |
|
| 194 | -| `city` | char | | Ville | |
|
| 195 | -| `zip` | char | | Code postal | |
|
| 196 | -| `country_id` | m2o | | Pays | |
|
| 197 | -| `customer_rank` | int | | 1 = client, 0 = prospect | |
|
| 198 | -| `supplier_rank` | int | | 1 = fournisseur | |
|
| 199 | -| `is_company` | bool | | True = société, False = particulier | |
|
| 200 | -| `company_type` | selection | | `person` ou `company` | |
|
| 201 | -| `vat` | char | | N° TVA intracommunautaire | |
|
| 202 | -| `barcode` | char | | Code-barres client | |
|
| 203 | -| `active` | bool | | False = archivé | |
|
| 204 | -| `comment` | text | | Notes internes | |
|
| 205 | -| `category_id` | m2m | | Étiquettes (tags) | |
|
| 206 | - |
|
| 207 | -**Recherche par email :** |
|
| 208 | -```python |
|
| 209 | -partner = odoo_call("res.partner", "search_read", |
|
| 210 | - [[["email", "=", "jean@email.com"]]], |
|
| 211 | - {"fields": ["id", "name", "email"]}) |
|
| 212 | -``` |
|
| 500 | +## 4. Modèles détaillés (les plus utilisés) |
|
| 213 | 501 | |
| 214 | -### 3.2 sale.order — Commandes / Devis |
|
| 502 | +### 4.1 sale.order — Commande |
|
| 215 | 503 | |
| 216 | 504 | | Champ | Type | Obligatoire | Description | |
| 217 | 505 | |-------|------|:----------:|-------------| |
| 218 | 506 | | `name` | char | ✅ | Référence commande | |
| 219 | 507 | | `partner_id` | m2o → res.partner | ✅ | Client | |
| 220 | -| `partner_invoice_id` | m2o → res.partner | ✅ | Adresse facturation | |
|
| 221 | -| `partner_shipping_id` | m2o → res.partner | ✅ | Adresse livraison | |
|
| 222 | -| `company_id` | m2o → res.company | ✅ | Société (généralement 1) | |
|
| 223 | -| `date_order` | datetime | ✅ | Date commande | |
|
| 224 | -| `picking_policy` | selection | ✅ | `direct` (livraison immédiate) ou `one` | |
|
| 225 | -| `state` | selection | | `draft`, `sent`, `sale`, `done`, `cancel` | |
|
| 226 | -| `client_order_ref` | char | | Référence externe (ex: BilletWeb) | |
|
| 227 | -| `team_id` | m2o → crm.team | | Équipe de vente | |
|
| 228 | -| `user_id` | m2o → res.users | | Vendeur | |
|
| 229 | -| `partner_shipping_id` | m2o | | Adresse livraison | |
|
| 230 | -| `warehouse_id` | m2o | | Entrepôt | |
|
| 231 | -| `payment_term_id` | m2o | | Conditions de paiement | |
|
| 232 | -| `pricelist_id` | m2o | | Liste de prix | |
|
| 233 | -| `currency_id` | m2o | | Devise (automatique) | |
|
| 234 | -| `note` | text | | Notes (visibles sur le PDF) | |
|
| 235 | -| `amount_untaxed` | float | | Total HT (lecture seule) | |
|
| 236 | -| `amount_tax` | float | | Total TVA (lecture seule) | |
|
| 237 | -| `amount_total` | float | | Total TTC (lecture seule) | |
|
| 238 | -| `invoice_status` | selection | | `to invoice`, `invoiced`, `no` | |
|
| 239 | -| `require_signature` | bool | | Signature requise | |
|
| 240 | -| `require_payment` | bool | | Paiement requis avant confirmation | |
|
| 241 | -| `order_line` | o2m | | Lignes de commande | |
|
| 242 | - |
|
| 243 | -**Création minimale :** |
|
| 244 | -```python |
|
| 245 | -so_id = odoo_call("sale.order", "create", [{ |
|
| 246 | - "name": "SO-REF-123", |
|
| 247 | - "partner_id": partner_id, |
|
| 248 | - "partner_invoice_id": partner_id, |
|
| 249 | - "partner_shipping_id": partner_id, |
|
| 250 | - "company_id": 1, |
|
| 251 | - "date_order": "2026-05-29 10:00:00", |
|
| 252 | - "picking_policy": "direct", |
|
| 253 | - "state": "draft", |
|
| 254 | -}]) |
|
| 255 | -``` |
|
| 256 | - |
|
| 257 | -### 3.3 sale.order.line — Lignes de commande |
|
| 258 | - |
|
| 259 | -| Champ | Type | Description | |
|
| 260 | -|-------|------|-------------| |
|
| 261 | -| `order_id` | m2o → sale.order | Commande parente | |
|
| 262 | -| `product_id` | m2o → product.product | Produit | |
|
| 263 | -| `product_uom_qty` | float | Quantité | |
|
| 264 | -| `product_uom` | m2o | Unité de mesure | |
|
| 265 | -| `price_unit` | float | Prix unitaire | |
|
| 266 | -| `discount` | float | Remise (%) | |
|
| 267 | -| `name` | char | Description | |
|
| 268 | -| `event_ticket_id` | m2o → event.event.ticket | Billet lié | |
|
| 269 | -| `registration_ids` | o2m → event.registration | Inscriptions liées | |
|
| 270 | -| `tax_id` | m2m → account.tax | Taxes | |
|
| 271 | -| `customer_lead` | float | Délai de livraison (jours) | |
|
| 272 | -| `state` | selection | `draft`, `sale`, `done`, `cancel` | |
|
| 273 | - |
|
| 274 | -### 3.4 product.product — Produits |
|
| 275 | - |
|
| 276 | -| Champ | Type | Obligatoire | Description | |
|
| 277 | -|-------|------|:----------:|-------------| |
|
| 278 | -| `name` | char | ✅ | Nom du produit | |
|
| 279 | -| `type` | selection | | `consu`, `service`, `product` | |
|
| 280 | -| `list_price` | float | | Prix de vente TTC | |
|
| 281 | -| `standard_price` | float | | Prix de revient | |
|
| 282 | -| `barcode` | char | | Code-barres | |
|
| 283 | -| `categ_id` | m2o → product.category | | Catégorie | |
|
| 284 | -| `sale_ok` | bool | | Disponible à la vente | |
|
| 285 | -| `purchase_ok` | bool | | Disponible à l'achat | |
|
| 286 | -| `available_in_pos` | bool | | Visible dans le PDV | |
|
| 287 | -| `active` | bool | | Actif | |
|
| 288 | -| `taxes_id` | m2m → account.tax | | Taxes à la vente | |
|
| 289 | -| `supplier_taxes_id` | m2m | | Taxes à l'achat | |
|
| 290 | -| `description_sale` | text | | Description sur les devis | |
|
| 291 | -| `default_code` | char | | Référence interne | |
|
| 292 | -| `weight` | float | | Poids (kg) | |
|
| 293 | - |
|
| 294 | -**⚠️** `detailed_type` n'existe pas sur Odoo Online SaaS → utiliser `type`. |
|
| 295 | - |
|
| 296 | -### 3.5 product.category — Catégories |
|
| 508 | +| `partner_invoice_id` | m2o | ✅ | Adresse facturation | |
|
| 509 | +| `partner_shipping_id` | m2o | ✅ | Adresse livraison | |
|
| 510 | +| `company_id` | m2o | ✅ | Société (1) | |
|
| 511 | +| `date_order` | datetime | ✅ | Date | |
|
| 512 | +| `picking_policy` | selection | ✅ | `direct` ou `one` | |
|
| 513 | +| `state` | selection | | `draft`/`sent`/`sale`/`done`/`cancel` | |
|
| 514 | +| `client_order_ref` | char | | Réf externe | |
|
| 515 | +| `team_id` | m2o → crm.team | | Équipe | |
|
| 516 | +| `user_id` | m2o | | Vendeur | |
|
| 517 | +| `note` | text | | Notes | |
|
| 518 | + |
|
| 519 | +### 4.2 product.product — Produit |
|
| 297 | 520 | |
| 298 | 521 | | Champ | Type | Description | |
| 299 | 522 | |-------|------|-------------| |
| 300 | 523 | | `name` | char ✅ | Nom | |
| 301 | -| `parent_id` | m2o | Catégorie parente | |
|
| 302 | -| `complete_name` | char | Chemin complet (lecture seule) | |
|
| 303 | - |
|
| 304 | -### 3.6 product.template — Modèles de produits |
|
| 305 | - |
|
| 306 | -Mêmes champs que `product.product` pour l'essentiel. La différence : |
|
| 307 | -- `product.template` = produit générique |
|
| 308 | -- `product.product` = variante spécifique |
|
| 309 | - |
|
| 310 | -### 3.7 event.event — Événements |
|
| 311 | - |
|
| 312 | -| Champ | Type | Obligatoire | Description | |
|
| 313 | -|-------|------|:----------:|-------------| |
|
| 314 | -| `name` | char | ✅ | Nom de l'événement | |
|
| 315 | -| `date_begin` | datetime | | Date début | |
|
| 316 | -| `date_end` | datetime | | Date fin | |
|
| 317 | -| `seats_max` | int | | Places maximum | |
|
| 318 | -| `seats_limited` | bool | | Limiter les places | |
|
| 319 | -| `seats_available` | int | | Places restantes (lecture seule) | |
|
| 320 | -| `auto_confirm` | bool | | ⚠️ Confirmation auto par email | |
|
| 321 | -| `event_ticket_ids` | o2m | | Types de billets | |
|
| 322 | -| `registration_ids` | o2m | | Inscriptions | |
|
| 323 | -| `state` | selection | | `draft`, `confirm`, `done`, `cancel` | |
|
| 324 | -| `user_id` | m2o | | Responsable | |
|
| 325 | -| `address_id` | m2o | | Lieu | |
|
| 326 | -| `country_id` | m2o | | Pays | |
|
| 327 | - |
|
| 328 | -### 3.8 event.event.ticket — Types de billets |
|
| 329 | - |
|
| 330 | -| Champ | Type | Obligatoire | Description | |
|
| 331 | -|-------|------|:----------:|-------------| |
|
| 332 | -| `name` | char | ✅ | Nom du billet | |
|
| 333 | -| `event_id` | m2o → event.event | ✅ | Événement parent | |
|
| 334 | -| `product_id` | m2o → product.product | ✅ | Produit associé | |
|
| 335 | -| `price` | float | | Prix | |
|
| 336 | -| `seats_limited` | bool | | Nombre limité | |
|
| 337 | -| `seats_max` | int | | Places max | |
|
| 338 | -| `description` | text | | Description | |
|
| 339 | - |
|
| 340 | -### 3.9 event.registration — Participants |
|
| 341 | - |
|
| 342 | -| Champ | Type | Description | |
|
| 343 | -|-------|------|-------------| |
|
| 344 | -| `event_id` | m2o → event.event | Événement | |
|
| 345 | -| `name` | char | Nom du participant | |
|
| 346 | -| `email` | char | Email | |
|
| 347 | -| `phone` | char | Téléphone | |
|
| 348 | -| `barcode` | char | **QR/Barcode** (utilisé pour BilletWeb) | |
|
| 349 | -| `state` | selection | `draft`, `open`, `done`, `cancel` | |
|
| 350 | -| `event_ticket_id` | m2o → event.event.ticket | Type de billet | |
|
| 351 | -| `sale_order_id` | m2o → sale.order | Commande liée | |
|
| 352 | -| `sale_order_line_id` | m2o → sale.order.line | Ligne de commande liée | |
|
| 353 | -| `attendee_partner_id` | m2o → res.partner | Contact participant | |
|
| 354 | -| `date_closed` | datetime | Date de clôture | |
|
| 355 | - |
|
| 356 | -**⚠️** `description` n'existe pas → utiliser `barcode` pour les références externes. |
|
| 357 | - |
|
| 358 | -### 3.10 pos.order — Commandes PDV |
|
| 359 | - |
|
| 360 | -| Champ | Type | Description | |
|
| 361 | -|-------|------|-------------| |
|
| 362 | -| `name` | char | Référence (ex: `POS/2026/05/29/001`) | |
|
| 363 | -| `date_order` | datetime | Date | |
|
| 364 | -| `session_id` | m2o → pos.session | Session PDV | |
|
| 365 | -| `partner_id` | m2o → res.partner | Client (si renseigné) | |
|
| 366 | -| `amount_total` | float | Total TTC | |
|
| 367 | -| `amount_tax` | float | Total TVA | |
|
| 368 | -| `amount_paid` | float | Montant payé | |
|
| 369 | -| `amount_return` | float | Rendu monnaie | |
|
| 370 | -| `state` | selection | `draft`, `paid`, `done`, `invoiced`, `cancel` | |
|
| 371 | -| `lines` | o2m → pos.order.line | Lignes | |
|
| 372 | -| `payment_ids` | o2m → pos.payment | Paiements | |
|
| 373 | - |
|
| 374 | -### 3.11 pos.order.line — Lignes PDV |
|
| 375 | - |
|
| 376 | -| Champ | Type | Description | |
|
| 377 | -|-------|------|-------------| |
|
| 378 | -| `order_id` | m2o → pos.order | Commande parente | |
|
| 379 | -| `product_id` | m2o → product.product | Produit | |
|
| 380 | -| `qty` | float | Quantité | |
|
| 381 | -| `price_unit` | float | Prix unitaire | |
|
| 382 | -| `discount` | float | Remise | |
|
| 383 | -| `price_subtotal` | float | Sous-total | |
|
| 384 | -| `tax_ids` | m2m → account.tax | Taxes | |
|
| 385 | - |
|
| 386 | -### 3.12 pos.session — Sessions PDV |
|
| 387 | - |
|
| 388 | -| Champ | Type | Description | |
|
| 389 | -|-------|------|-------------| |
|
| 390 | -| `name` | char | Nom session | |
|
| 391 | -| `config_id` | m2o → pos.config | Configuration PDV | |
|
| 392 | -| `start_at` | datetime | Ouverture | |
|
| 393 | -| `stop_at` | datetime | Fermeture | |
|
| 394 | -| `state` | selection | `opening_control`, `opened`, `closing_control`, `closed` | |
|
| 395 | -| `cash_register_balance_start` | float | Solde ouverture | |
|
| 396 | -| `cash_register_balance_end` | float | Solde fermeture | |
|
| 397 | -| `order_ids` | o2m → pos.order | Commandes | |
|
| 398 | - |
|
| 399 | -### 3.13 pos.config — Configuration PDV |
|
| 400 | - |
|
| 401 | -| Champ | Type | Description | |
|
| 402 | -|-------|------|-------------| |
|
| 403 | -| `name` | char ✅ | Nom ("Parc de la Luge - Caisse") | |
|
| 404 | -| `iface_cashdrawer` | bool | Tiroir caisse | |
|
| 405 | -| `iface_print_via_proxy` | bool | Impression ticket | |
|
| 406 | -| `iface_scan_via_proxy` | bool | Scanner | |
|
| 407 | -| `module_pos_restaurant` | bool | Mode restaurant | |
|
| 408 | -| `company_id` | m2o | Société | |
|
| 409 | - |
|
| 410 | -### 3.14 account.move — Factures / Écritures comptables |
|
| 411 | - |
|
| 412 | -| Champ | Type | Description | |
|
| 413 | -|-------|------|-------------| |
|
| 414 | -| `name` | char | Numéro de facture | |
|
| 415 | -| `move_type` | selection | `out_invoice`, `out_refund`, `in_invoice`, `in_refund` | |
|
| 416 | -| `partner_id` | m2o → res.partner | Client/Fournisseur | |
|
| 417 | -| `invoice_date` | date | Date facture | |
|
| 418 | -| `invoice_date_due` | date | Date d'échéance | |
|
| 419 | -| `state` | selection | `draft`, `posted`, `cancel` | |
|
| 420 | -| `amount_untaxed` | float | HT | |
|
| 421 | -| `amount_tax` | float | TVA | |
|
| 422 | -| `amount_total` | float | TTC | |
|
| 423 | -| `amount_residual` | float | Restant dû | |
|
| 424 | -| `payment_state` | selection | `not_paid`, `in_payment`, `paid`, `partial`, `reversed` | |
|
| 425 | -| `invoice_line_ids` | o2m | Lignes de facture | |
|
| 426 | -| `ref` | char | Référence externe | |
|
| 427 | - |
|
| 428 | -### 3.15 account.payment — Paiements |
|
| 429 | - |
|
| 430 | -| Champ | Type | Description | |
|
| 431 | -|-------|------|-------------| |
|
| 432 | -| `payment_type` | selection | `inbound` (reçu) / `outbound` (envoyé) | |
|
| 433 | -| `partner_type` | selection | `customer` / `supplier` | |
|
| 434 | -| `partner_id` | m2o | Client | |
|
| 435 | -| `amount` | float | Montant | |
|
| 436 | -| `date` | date | Date | |
|
| 437 | -| `journal_id` | m2o → account.journal | Journal (banque, caisse) | |
|
| 438 | -| `payment_method_id` | m2o | Mode de paiement | |
|
| 439 | -| `state` | selection | `draft`, `posted`, `sent`, `reconciled`, `cancelled` | |
|
| 440 | - |
|
| 441 | -### 3.16 account.tax — Taxes |
|
| 442 | - |
|
| 443 | -| Champ | Type | Description | |
|
| 444 | -|-------|------|-------------| |
|
| 445 | -| `name` | char ✅ | Nom ("TVA 8.5% Réunion") | |
|
| 446 | -| `amount` | float | Taux (8.5, 2.1, 0) | |
|
| 447 | -| `amount_type` | selection | `percent`, `fixed`, `division`, `group` | |
|
| 448 | -| `type_tax_use` | selection | `sale`, `purchase`, `none` | |
|
| 449 | -| `tax_group_id` | m2o | Groupe | |
|
| 524 | +| `type` | selection | `consu`/`service`/`product` ⚠️ pas `detailed_type` | |
|
| 525 | +| `list_price` | float | Prix vente TTC | |
|
| 526 | +| `barcode` | char | Code-barres | |
|
| 527 | +| `categ_id` | m2o | Catégorie | |
|
| 528 | +| `sale_ok` | bool | Vente | |
|
| 529 | +| `available_in_pos` | bool | Visible en PDV | |
|
| 530 | +| `taxes_id` | m2m | Taxes | |
|
| 450 | 531 | | `active` | bool | Actif | |
| 451 | -| `price_include` | bool | Prix TTC | |
|
| 452 | -| `description` | char | Texte sur la facture | |
|
| 453 | - |
|
| 454 | -### 3.17 account.tax.group — Groupes de taxes |
|
| 455 | - |
|
| 456 | -| Champ | Type | Description | |
|
| 457 | -|-------|------|-------------| |
|
| 458 | -| `name` | char ✅ | Nom | |
|
| 459 | -| `country_id` | m2o | Pays (⚠️ ne pas mettre si DOM !) | |
|
| 460 | - |
|
| 461 | -### 3.18 stock.quant — Inventaire |
|
| 462 | - |
|
| 463 | -| Champ | Type | Description | |
|
| 464 | -|-------|------|-------------| |
|
| 465 | -| `product_id` | m2o | Produit | |
|
| 466 | -| `location_id` | m2o | Emplacement | |
|
| 467 | -| `quantity` | float | Quantité | |
|
| 468 | -| `inventory_quantity` | float | Qté comptée | |
|
| 469 | -| `inventory_diff_quantity` | float | Écart | |
|
| 470 | 532 | |
| 471 | -### 3.19 ir.module.module — Modules |
|
| 533 | +### 4.3 event.registration — Inscription |
|
| 472 | 534 | |
| 473 | 535 | | Champ | Type | Description | |
| 474 | 536 | |-------|------|-------------| |
| 475 | -| `name` | char | Nom technique | |
|
| 476 | -| `display_name` | char | Nom affiché | |
|
| 477 | -| `state` | selection | `uninstalled`, `installed`, `to install`, `to upgrade` | |
|
| 478 | - |
|
| 479 | -**Installer un module :** |
|
| 480 | -```python |
|
| 481 | -mid = odoo_call("ir.module.module", "search_read", |
|
| 482 | - [[["name", "=", "point_of_sale"]]], {"fields": ["id"]})[0]["id"] |
|
| 483 | -odoo_call("ir.module.module", "button_immediate_install", [[mid]]) |
|
| 484 | -``` |
|
| 485 | - |
|
| 486 | -### 3.20 mail.mail — Emails en file d'attente |
|
| 487 | - |
|
| 488 | -| Champ | Type | Description | |
|
| 489 | -|-------|------|-------------| |
|
| 490 | -| `state` | selection | `outgoing`, `sent`, `exception`, `cancel` | |
|
| 491 | -| `subject` | char | Sujet | |
|
| 492 | -| `email_to` | char | Destinataires | |
|
| 493 | - |
|
| 494 | -### 3.21 ir.mail_server — Serveur d'envoi |
|
| 495 | - |
|
| 496 | -| Champ | Type | Description | |
|
| 497 | -|-------|------|-------------| |
|
| 498 | -| `name` | char | Nom | |
|
| 499 | -| `smtp_host` | char | Serveur SMTP | |
|
| 500 | -| `active` | bool | `False` pour désactiver | |
|
| 501 | - |
|
| 502 | -### 3.22 ir.cron — Tâches planifiées |
|
| 503 | - |
|
| 504 | -| Champ | Type | Description | |
|
| 505 | -|-------|------|-------------| |
|
| 506 | -| `name` | char | Nom | |
|
| 507 | -| `model_id` | m2o | Modèle | |
|
| 508 | -| `active` | bool | Actif | |
|
| 509 | -| `interval_number` | int | Fréquence | |
|
| 510 | -| `interval_type` | selection | `minutes`, `hours`, `days`, `weeks`, `months` | |
|
| 511 | - |
|
| 512 | -### 3.23 res.company — Société |
|
| 513 | - |
|
| 514 | -| Champ | Type | Description | |
|
| 515 | -|-------|------|-------------| |
|
| 516 | -| `name` | char | Nom | |
|
| 517 | -| `country_id` | m2o | Pays (187 = Réunion) | |
|
| 518 | -| `currency_id` | m2o | Devise (EUR) | |
|
| 519 | -| `phone` | char | Téléphone | |
|
| 537 | +| `event_id` | m2o | Événement | |
|
| 538 | +| `name` | char | Nom participant | |
|
| 520 | 539 | | `email` | char | Email | |
| 521 | -| `street` | char | Adresse | |
|
| 522 | - |
|
| 523 | ---- |
|
| 540 | +| `barcode` | char | QR/Barcode BilletWeb | |
|
| 541 | +| `state` | selection | `draft`/`open`/`done`/`cancel` | |
|
| 542 | +| `event_ticket_id` | m2o | Type billet | |
|
| 543 | +| `sale_order_id` | m2o | Commande liée | |
|
| 544 | +| `sale_order_line_id` | m2o | Ligne liée | |
|
| 524 | 545 | |
| 525 | -## 4. Flux BilletWeb → Odoo |
|
| 526 | - |
|
| 527 | -### 4.1 Ordre des opérations |
|
| 528 | - |
|
| 529 | -``` |
|
| 530 | -① res.partner — find or create (par email) |
|
| 531 | -② product.product — find (par barcode BW-*) |
|
| 532 | -③ event.event.ticket — find or create (produit + event) |
|
| 533 | -④ sale.order — create |
|
| 534 | -⑤ sale.order.line — create (lié au ticket) |
|
| 535 | -⑥ event.registration — create (avec barcode BilletWeb) |
|
| 536 | -⑦ sale.order.line — write registration_ids ← lier |
|
| 537 | -``` |
|
| 538 | - |
|
| 539 | -### 4.2 Anti-doublon |
|
| 540 | - |
|
| 541 | -```python |
|
| 542 | -# Charger TOUS les barcodes existants au démarrage |
|
| 543 | -existing = odoo_call("event.registration", "search_read", |
|
| 544 | - [[]], {"fields": ["barcode"]}) |
|
| 545 | -done = {r["barcode"] for r in existing if r.get("barcode")} |
|
| 546 | - |
|
| 547 | -# Vérifier avant création |
|
| 548 | -if barcode in done: |
|
| 549 | - continue # déjà importé |
|
| 550 | - |
|
| 551 | -# Réutiliser les commandes existantes |
|
| 552 | -existing_so = odoo_call("sale.order", "search_read", |
|
| 553 | - [[["client_order_ref", "=", ref]]], {"fields": ["id"]}) |
|
| 554 | -so_id = existing_so[0]["id"] if existing_so else None |
|
| 555 | -``` |
|
| 556 | - |
|
| 557 | -### 4.3 Désactiver les emails (avant import massif) |
|
| 558 | - |
|
| 559 | -```python |
|
| 560 | -# 1. Vider la file d'attente |
|
| 561 | -stuck = odoo_call("mail.mail", "search", |
|
| 562 | - [[["state", "in", ["outgoing", "exception"]]]]) |
|
| 563 | -for mid in stuck: |
|
| 564 | - odoo_call("mail.mail", "unlink", [[mid]]) |
|
| 565 | - |
|
| 566 | -# 2. Désactiver serveur SMTP |
|
| 567 | -servers = odoo_call("ir.mail_server", "search_read", [], |
|
| 568 | - {"fields": ["id"]}) |
|
| 569 | -for s in servers: |
|
| 570 | - odoo_call("ir.mail_server", "write", [[s["id"]], {"active": False}]) |
|
| 571 | - |
|
| 572 | -# 3. Désactiver fetchmail |
|
| 573 | -for s in odoo_call("fetchmail.server", "search_read", [], |
|
| 574 | - {"fields": ["id"]}): |
|
| 575 | - odoo_call("fetchmail.server", "write", [[s["id"]], {"active": False}]) |
|
| 576 | - |
|
| 577 | -# 4. Désactiver templates d'email |
|
| 578 | -for t in odoo_call("mail.template", "search_read", [], |
|
| 579 | - {"fields": ["id"]}): |
|
| 580 | - odoo_call("mail.template", "write", [[t["id"]], {"auto_delete": True}]) |
|
| 581 | - |
|
| 582 | -# 5. Désactiver cron jobs email |
|
| 583 | -for c in odoo_call("ir.cron", "search_read", [], |
|
| 584 | - {"fields": ["id", "name"]}): |
|
| 585 | - if any(kw in c["name"].lower() for kw in |
|
| 586 | - ["mail", "email", "send", "notification"]): |
|
| 587 | - odoo_call("ir.cron", "write", [[c["id"]], {"active": False}]) |
|
| 588 | - |
|
| 589 | -# 6. Désactiver confirmation auto événements |
|
| 590 | -for ev_id in event_ids: |
|
| 591 | - odoo_call("event.event", "write", [[ev_id], |
|
| 592 | - {"auto_confirm": False}]) |
|
| 593 | -``` |
|
| 546 | +⚠️ `description` n'existe pas → utiliser `barcode`. |
|
| 594 | 547 | |
| 595 | 548 | --- |
| 596 | 549 | |
| 597 | -## 5. TVA Réunion (DOM) |
|
| 598 | - |
|
| 599 | -### 5.1 Taux applicables |
|
| 600 | - |
|
| 601 | -| Taux | Vente (ID) | Achat (ID) | Usage | |
|
| 602 | -|------|:---------:|:---------:|-------| |
|
| 603 | -| 8,5% | 79 | 32 | Taux normal DOM | |
|
| 604 | -| 2,1% | 80 | 35 | Taux réduit | |
|
| 605 | -| 0% | 61-70 | 50 | Exonéré | |
|
| 606 | - |
|
| 607 | -### 5.2 Créer une taxe DOM |
|
| 608 | - |
|
| 609 | -```python |
|
| 610 | -# Groupe (sans country_id !) |
|
| 611 | -grp = odoo_call("account.tax.group", "create", |
|
| 612 | - [{"name": "TVA 8.5%"}]) |
|
| 613 | - |
|
| 614 | -# Taxe vente |
|
| 615 | -odoo_call("account.tax", "create", [{ |
|
| 616 | - "name": "8.5% S (Réunion)", |
|
| 617 | - "amount": 8.5, |
|
| 618 | - "amount_type": "percent", |
|
| 619 | - "type_tax_use": "sale", |
|
| 620 | - "tax_group_id": grp, |
|
| 621 | - "price_include": False, |
|
| 622 | -}]) |
|
| 623 | -``` |
|
| 550 | +## 5. Flux BilletWeb → Odoo |
|
| 624 | 551 | |
| 625 | -### 5.3 Désactiver les taux métropole |
|
| 552 | +Ordre : `res.partner` → `product.product` → `event.event.ticket` → `sale.order` → `sale.order.line` → `event.registration` → lien `registration_ids`. |
|
| 626 | 553 | |
| 554 | +### Anti-doublon |
|
| 627 | 555 | ```python |
| 628 | -# Désactiver 20% |
|
| 629 | -for t in odoo_call("account.tax", "search_read", |
|
| 630 | - [[["amount", "=", 20.0]]], {"fields": ["id"]}): |
|
| 631 | - odoo_call("account.tax", "write", [[t["id"]], {"active": False}]) |
|
| 632 | -# Idem pour 10%, 5.5% |
|
| 556 | +existing = odoo_call("event.registration", "search_read", [[]], {"fields": ["barcode"]}) |
|
| 557 | +done = {r["barcode"] for r in existing if r.get("barcode")} |
|
| 558 | +if barcode in done: continue |
|
| 633 | 559 | ``` |
| 634 | 560 | |
| 635 | -### 5.4 Appliquer une taxe à un produit |
|
| 636 | - |
|
| 561 | +### Désactiver les emails (6 étapes) |
|
| 637 | 562 | ```python |
| 638 | -odoo_call("product.product", "write", |
|
| 639 | - [[product_id], {"taxes_id": [(6, 0, [tax_id])]}]) |
|
| 563 | +# 1. mail.mail → unlink stuck |
|
| 564 | +# 2. ir.mail_server → active=False |
|
| 565 | +# 3. fetchmail.server → active=False |
|
| 566 | +# 4. mail.template → auto_delete=True |
|
| 567 | +# 5. ir.cron → active=False (jobs mail/email/send) |
|
| 568 | +# 6. event.event → auto_confirm=False |
|
| 640 | 569 | ``` |
| 641 | 570 | |
| 642 | 571 | --- |
| 643 | 572 | |
| 644 | -## 6. Modules de localisation française |
|
| 573 | +## 6. TVA Réunion (DOM) |
|
| 645 | 574 | |
| 646 | -| Module | Rôle | |
|
| 647 | -|--------|------| |
|
| 648 | -| `l10n_fr` | Base localisation France | |
|
| 649 | -| `l10n_fr_account` | Plan comptable français + templates taxes | |
|
| 650 | -| `l10n_fr_pos_cert` | Certification **NF 525** (obligatoire) | |
|
| 651 | -| `l10n_fr_reports` | Rapports comptables français | |
|
| 575 | +| Taux | Vente ID | Achat ID | |
|
| 576 | +|------|:-------:|:-------:| |
|
| 577 | +| 8,5% | 79 | 32 | |
|
| 578 | +| 2,1% | 80 | 35 | |
|
| 579 | +| 0% | 61-70 | 50 | |
|
| 652 | 580 | |
| 653 | 581 | ```python |
| 654 | -# Vérifier les modules installés |
|
| 655 | -modules = odoo_call("ir.module.module", "search_read", |
|
| 656 | - [[["name", "in", |
|
| 657 | - ["l10n_fr", "l10n_fr_account", |
|
| 658 | - "l10n_fr_pos_cert", "l10n_fr_reports"]]]], |
|
| 659 | - {"fields": ["name", "state"]}) |
|
| 660 | - |
|
| 661 | -# Installer |
|
| 662 | -for m in modules: |
|
| 663 | - if m["state"] != "installed": |
|
| 664 | - odoo_call("ir.module.module", |
|
| 665 | - "button_immediate_install", [[m["id"]]]) |
|
| 582 | +grp = odoo_call("account.tax.group", "create", [{"name": "TVA 8.5%"}]) # sans country_id ! |
|
| 583 | +odoo_call("account.tax", "create", [{"name": "8.5% S", "amount": 8.5, "type_tax_use": "sale", ...}]) |
|
| 666 | 584 | ``` |
| 667 | 585 | |
| 668 | -⚠️ Le plan comptable (`l10n_fr_account`) doit être installé manuellement via l'interface web (Paramètres → Comptabilité → Localisation fiscale). L'API ne peut pas déclencher l'installation du plan comptable sur SaaS. |
|
| 669 | - |
|
| 670 | 586 | --- |
| 671 | 587 | |
| 672 | -## 7. Pièges et erreurs courantes |
|
| 588 | +## 7. Pièges |
|
| 673 | 589 | |
| 674 | 590 | | N° | Erreur | Solution | |
| 675 | 591 | |----|--------|---------| |
| 676 | -| 1 | `AccessDenied` | Utiliser `common.login` (pas `/web/session/authenticate`) | |
|
| 677 | -| 2 | `create` retourne `None` | Il manque un champ obligatoire → `fields_get` | |
|
| 678 | -| 3 | `create` prend une liste | Non → UN dict. Passer `[{...}]` pas `[[{...}]]` | |
|
| 679 | -| 4 | `detailed_type` introuvable | Ne pas utiliser → `type` uniquement | |
|
| 680 | -| 5 | Taxe "country_id mismatch" | Créer les groupes de taxe sans `country_id` | |
|
| 681 | -| 6 | Taxes écrasées après `l10n_fr_account` | Ré-appliquer après installation | |
|
| 682 | -| 7 | `auto_confirm` envoie des emails | Désactiver avant import massif | |
|
| 683 | -| 8 | `unlink` échoue | Utiliser `write` → `{"active": False}` | |
|
| 684 | -| 9 | `search_read` limit=80 par défaut | Utiliser `limit=0` pour tout récupérer | |
|
| 685 | -| 10 | `barcode` champ inexistant | Vérifier le modèle — `event.registration` l'a, `sale.order` non | |
|
| 686 | -| 11 | BilletWeb 403 Forbidden | Ajouter `User-Agent: Mozilla/5.0` | |
|
| 687 | -| 12 | API key scope événement | La clé doit être créée avec "Tous les événements" | |
|
| 592 | +| 1 | `AccessDenied` | `common.login` pas `/web/session/authenticate` | |
|
| 593 | +| 2 | `create` retourne None | champs obligatoires manquants → `fields_get` | |
|
| 594 | +| 3 | `create` prend UN dict | `[{...}]` pas `[[{...}]]` | |
|
| 595 | +| 4 | `detailed_type` | Ne pas utiliser → `type` | |
|
| 596 | +| 5 | Taxe country_id mismatch | Groupe sans `country_id` | |
|
| 597 | +| 6 | auto_confirm envoie emails | Désactiver avant import | |
|
| 598 | +| 7 | `unlink` échoue | `{"active": False}` | |
|
| 599 | +| 8 | `search_read` limit=80 | `limit=0` pour tout | |
|
| 600 | +| 9 | BilletWeb 403 | `User-Agent: Mozilla/5.0` | |
|
| 601 | +| 10 | `sale.order` 7 champs requis | name, partner_id ×3, company_id, date_order, picking_policy | |
|
| 688 | 602 | |
| 689 | 603 | --- |
| 690 | 604 | |
| 691 | -## 8. Limites Odoo Online (SaaS) |
|
| 605 | +## 8. Limites SaaS |
|
| 692 | 606 | |
| 693 | -| ✅ Possible | ❌ Impossible | |
|
| 694 | -|------------|--------------| |
|
| 695 | -| API JSON-RPC complète | SSH / accès serveur | |
|
| 607 | +| ✅ | ❌ | |
|
| 608 | +|----|-----| |
|
| 609 | +| API JSON-RPC | SSH | |
|
| 696 | 610 | | CRUD tous modèles standards | Modules Python customs | |
| 697 | -| Modules Studio (UI) | Accès direct PostgreSQL | |
|
| 698 | -| Imports CSV/XML | Modification du core Odoo | |
|
| 699 | -| Webhooks sortants | Installation packages Python | |
|
| 700 | -| Extensions Chrome (DOM) | Scripts serveur personnalisés | |
|
| 611 | +| Modules Studio | Accès PostgreSQL | |
|
| 612 | +| Webhooks sortants | Core mods | |
|
| 613 | +| Extensions Chrome | Packages Python | |
|
| 701 | 614 | |
| 702 | 615 | --- |
| 703 | 616 | |
| 704 | -## 9. Exemples pratiques |
|
| 705 | - |
|
| 706 | -### 9.1 Créer un client |
|
| 707 | - |
|
| 708 | -```python |
|
| 709 | -partner_id = odoo_call("res.partner", "create", [{ |
|
| 710 | - "name": "Jean Dupont", |
|
| 711 | - "email": "jean@email.com", |
|
| 712 | - "phone": "+262692123456", |
|
| 713 | - "customer_rank": 1, |
|
| 714 | -}]) |
|
| 715 | -``` |
|
| 716 | - |
|
| 717 | -### 9.2 Créer une commande complète |
|
| 617 | +## 9. Exemples |
|
| 718 | 618 | |
| 619 | +### Créer un client |
|
| 719 | 620 | ```python |
| 720 | -# Étape 1 : créer la commande |
|
| 721 | -so_id = odoo_call("sale.order", "create", [{ |
|
| 722 | - "name": "CMD-2026-001", |
|
| 723 | - "partner_id": partner_id, |
|
| 724 | - "partner_invoice_id": partner_id, |
|
| 725 | - "partner_shipping_id": partner_id, |
|
| 726 | - "company_id": 1, |
|
| 727 | - "date_order": "2026-05-29 10:00:00", |
|
| 728 | - "picking_policy": "direct", |
|
| 729 | - "client_order_ref": "BW-ORDER-456", |
|
| 730 | - "team_id": 4, # BilletWeb |
|
| 731 | -}]) |
|
| 732 | - |
|
| 733 | -# Étape 2 : ajouter une ligne |
|
| 734 | -line_id = odoo_call("sale.order.line", "create", [{ |
|
| 735 | - "order_id": so_id, |
|
| 736 | - "product_id": 13, |
|
| 737 | - "product_uom_qty": 2, |
|
| 738 | - "price_unit": 11.00, |
|
| 739 | - "name": "Luge - Forfait 4 tours", |
|
| 740 | -}]) |
|
| 741 | - |
|
| 742 | -# Étape 3 : confirmer en commande |
|
| 743 | -odoo_call("sale.order", "write", [[so_id], {"state": "sale"}]) |
|
| 621 | +pid = odoo_call("res.partner", "create", [{"name": "Jean", "email": "j@mail.com", "customer_rank": 1}]) |
|
| 744 | 622 | ``` |
| 745 | 623 | |
| 746 | -### 9.3 Créer une inscription événement |
|
| 747 | - |
|
| 748 | -```python |
|
| 749 | -reg_id = odoo_call("event.registration", "create", [{ |
|
| 750 | - "event_id": 1, |
|
| 751 | - "name": "Jean Dupont", |
|
| 752 | - "email": "jean@email.com", |
|
| 753 | - "barcode": "1234567890", |
|
| 754 | - "state": "open", |
|
| 755 | - "event_ticket_id": 8, |
|
| 756 | - "sale_order_id": so_id, |
|
| 757 | -}]) |
|
| 758 | -``` |
|
| 759 | - |
|
| 760 | -### 9.4 Lier inscription → ligne de commande |
|
| 761 | - |
|
| 762 | -```python |
|
| 763 | -odoo_call("sale.order.line", "write", |
|
| 764 | - [[line_id], {"registration_ids": [(6, 0, [reg_id])]}]) |
|
| 765 | -``` |
|
| 766 | - |
|
| 767 | -### 9.5 Rechercher avec pagination |
|
| 768 | - |
|
| 624 | +### Créer une commande + ligne + inscription |
|
| 769 | 625 | ```python |
| 770 | -all_records = [] |
|
| 771 | -offset = 0 |
|
| 772 | -while True: |
|
| 773 | - batch = odoo_call("event.registration", "search_read", |
|
| 774 | - [[["event_id", "=", 1]]], |
|
| 775 | - {"fields": ["id", "name", "barcode", "state"], |
|
| 776 | - "offset": offset, "limit": 100}) |
|
| 777 | - if not batch: |
|
| 778 | - break |
|
| 779 | - all_records.extend(batch) |
|
| 780 | - offset += 100 |
|
| 626 | +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-05-29 10:00:00", "picking_policy": "direct"}]) |
|
| 627 | +line = odoo_call("sale.order.line", "create", [{"order_id": so, "product_id": 13, "product_uom_qty": 1, "price_unit": 11.00}]) |
|
| 628 | +reg = odoo_call("event.registration", "create", [{"event_id": 1, "name": "Jean", "email": "j@mail.com", "barcode": "1234567890", "state": "open"}]) |
|
| 629 | +odoo_call("sale.order.line", "write", [[line], {"registration_ids": [(6, 0, [reg])]}]) |
|
| 781 | 630 | ``` |