index.md
... ...
@@ -3,6 +3,11 @@
3 3
> Mémoire collective partagée entre tous les profils.
4 4
> Dernière mise à jour : 2026-05-29
5 5
6
+## odoo/ — Documentation Odoo (Parc de la Luge)
7
+
8
+- [[odoo/guide-utilisateur]] — Guide complet pour utiliser Odoo au quotidien (ventes, PDV, événements, facturation, produits...)
9
+- [[odoo/api-reference]] — Référence exhaustive de l'API JSON-RPC (tous les modèles, endpoints, patterns)
10
+
6 11
## concepts/ — Savoir durable et contraintes
7 12
8 13
- [[concepts/odoo-saas-limites]] — Ce qui est possible/impossible avec Odoo Online
odoo/api-reference.md
... ...
@@ -0,0 +1,781 @@
1
+---
2
+title: Référence API Odoo — Complète
3
+created: 2026-05-29
4
+updated: 2026-05-29
5
+type: concept
6
+tags: [odoo, api, json-rpc, reference, developpeur]
7
+sources: [odoo-online skill, odoo-api skill, odoo.com/documentation]
8
+confidence: high
9
+---
10
+
11
+# Référence API Odoo — Documentation Complète
12
+
13
+> **Base URL** : `https://sarl-le-relais-de-louest.odoo.com/jsonrpc`
14
+> **Protocole** : JSON-RPC 2.0
15
+> **Auth** : `common.login` + API Key
16
+
17
+---
18
+
19
+## 1. Authentification
20
+
21
+### 1.1 Obtenir un UID
22
+
23
+```http
24
+POST /jsonrpc
25
+Content-Type: application/json
26
+
27
+{
28
+ "jsonrpc": "2.0",
29
+ "method": "call",
30
+ "params": {
31
+ "service": "common",
32
+ "method": "login",
33
+ "args": ["<db_name>", "<email>", "<api_key>"]
34
+ },
35
+ "id": 1
36
+}
37
+```
38
+
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).
51
+
52
+### 1.3 Helper Python
53
+
54
+```python
55
+import requests
56
+
57
+DB = "sarl-le-relais-de-louest"
58
+UID = None
59
+PWD = None # API key
60
+URL = f"https://{DB}.odoo.com/jsonrpc"
61
+
62
+def odoo_call(model, method, *args):
63
+ payload = {
64
+ "jsonrpc": "2.0", "method": "call",
65
+ "params": {
66
+ "service": "object",
67
+ "method": "execute_kw",
68
+ "args": [DB, UID, PWD, model, method] + list(args)
69
+ }, "id": 1
70
+ }
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")
75
+```
76
+
77
+---
78
+
79
+## 2. Méthodes génériques
80
+
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
+```
105
+
106
+### search_count — Compter
107
+```python
108
+count = odoo_call("model.name", "search_count", [domain])
109
+# Retourne int
110
+```
111
+
112
+### read — Lire par ID
113
+```python
114
+data = odoo_call("model.name", "read", [[id1, id2]], {"fields": ["name", "email"]})
115
+```
116
+
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
+```
122
+
123
+### write — Modifier
124
+```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
167
+"partner_id": 42
168
+
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
174
+
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
179
+```
180
+
181
+---
182
+
183
+## 3. Modèles — Référence exhaustive
184
+
185
+### 3.1 res.partner — Contacts / Clients
186
+
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
+```
213
+
214
+### 3.2 sale.order — Commandes / Devis
215
+
216
+| Champ | Type | Obligatoire | Description |
217
+|-------|------|:----------:|-------------|
218
+| `name` | char | ✅ | Référence commande |
219
+| `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
297
+
298
+| Champ | Type | Description |
299
+|-------|------|-------------|
300
+| `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 |
450
+| `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
+
471
+### 3.19 ir.module.module — Modules
472
+
473
+| Champ | Type | Description |
474
+|-------|------|-------------|
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 |
520
+| `email` | char | Email |
521
+| `street` | char | Adresse |
522
+
523
+---
524
+
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
+```
594
+
595
+---
596
+
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
+```
624
+
625
+### 5.3 Désactiver les taux métropole
626
+
627
+```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%
633
+```
634
+
635
+### 5.4 Appliquer une taxe à un produit
636
+
637
+```python
638
+odoo_call("product.product", "write",
639
+ [[product_id], {"taxes_id": [(6, 0, [tax_id])]}])
640
+```
641
+
642
+---
643
+
644
+## 6. Modules de localisation française
645
+
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 |
652
+
653
+```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"]]])
666
+```
667
+
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
+---
671
+
672
+## 7. Pièges et erreurs courantes
673
+
674
+| N° | Erreur | Solution |
675
+|----|--------|---------|
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" |
688
+
689
+---
690
+
691
+## 8. Limites Odoo Online (SaaS)
692
+
693
+| ✅ Possible | ❌ Impossible |
694
+|------------|--------------|
695
+| API JSON-RPC complète | SSH / accès serveur |
696
+| 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 |
701
+
702
+---
703
+
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
718
+
719
+```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"}])
744
+```
745
+
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
+
769
+```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
781
+```
odoo/guide-utilisateur.md
... ...
@@ -0,0 +1,801 @@
1
+---
2
+title: Guide Utilisateur Odoo — Parc de la Luge
3
+created: 2026-05-29
4
+updated: 2026-05-29
5
+type: concept
6
+tags: [odoo, guide, utilisateur, pos, vente, evenement, facturation, inventaire, comptabilite]
7
+sources: [odoo.com/documentation/19.0, odoo-online skill]
8
+confidence: high
9
+---
10
+
11
+# Guide Utilisateur Odoo — Parc de la Luge
12
+
13
+> **Instance** : `sarl-le-relais-de-louest.odoo.com`
14
+> **Version** : Odoo Online 19.x
15
+> **Société** : SARL LE RELAIS DE L'OUEST — La Réunion (DOM, TVA 8,5%)
16
+
17
+---
18
+
19
+## Sommaire
20
+
21
+1. [Premiers pas](#1-premiers-pas)
22
+2. [Ventes — Devis et commandes](#2-ventes--devis-et-commandes)
23
+3. [Point de Vente (PDV) — La caisse](#3-point-de-vente-pdv--la-caisse)
24
+4. [Produits et inventaire](#4-produits-et-inventaire)
25
+5. [Événements et billetterie](#5-événements-et-billetterie)
26
+6. [Facturation et paiements](#6-facturation-et-paiements)
27
+7. [Clients (Contacts)](#7-clients-contacts)
28
+8. [Rapports et analyses](#8-rapports-et-analyses)
29
+9. [Imports et exports](#9-imports-et-exports)
30
+10. [Configuration et réglages](#10-configuration-et-réglages)
31
+11. [Dépannage](#11-dépannage)
32
+12. [Raccourcis et astuces](#12-raccourcis-et-astuces)
33
+
34
+---
35
+
36
+## 1. Premiers pas
37
+
38
+### 1.1 Connexion
39
+
40
+```
41
+1. Navigateur → https://sarl-le-relais-de-louest.odoo.com
42
+2. Saisir email + mot de passe
43
+3. Base : sarl-le-relais-de-louest (sélection automatique)
44
+```
45
+
46
+### 1.2 Interface
47
+
48
+```
49
+┌─────────────────────────────────────────────────────┐
50
+│ 🔍 Recherche rapide (Ctrl+K) 👤 Profil 🔔 │
51
+├──────────┬──────────────────────────────────────────┤
52
+│ 📊 Ventes │ ┌─ Commandes ──────────────────────┐ │
53
+│ 💰 PDV │ │ 🔍 [__________] 🔽 Filtres │ │
54
+│ 🎪 Évén. │ │ │ │
55
+│ 📄 Fact. │ │ 📋 Liste des commandes │ │
56
+│ 📦 Inv. │ │ ├─ SO001 — Dupont — 45,00€ │ │
57
+│ 👥 Cont. │ │ ├─ SO002 — Martin — 22,50€ │ │
58
+│ ⚙️ Config │ │ └─ SO003 — Richard — 11,00€ │ │
59
+└──────────┴──────────────────────────────────────────┘
60
+```
61
+
62
+**Barre de menu** (gauche) : navigation entre applications
63
+**Barre de recherche** (haut) : `Ctrl+K` pour chercher n'importe quoi (client, commande, produit...)
64
+**Favoris** : cliquer l'étoile ⭐ près d'un menu → apparaît en haut du menu
65
+
66
+### 1.3 Vues
67
+
68
+Chaque liste peut être affichée de 4 façons (icônes en haut à droite) :
69
+
70
+| Icône | Vue | Usage |
71
+|-------|-----|-------|
72
+| 📋 | **Liste** | Tableau de données |
73
+| 📊 | **Kanban** | Cartes colorées par étape |
74
+| 📅 | **Calendrier** | Vue temporelle |
75
+| 📈 | **Graphique** | Graphiques (camembert, barres, lignes) |
76
+| 🕐 | **Activité** | Planning des tâches |
77
+
78
+### 1.4 Recherche et filtres
79
+
80
+```
81
+┌─ Filtres ──────────────────────────────┐
82
+│ ★ Mes commandes │
83
+│ ★ À facturer │
84
+│ ★ En retard │
85
+│ ➕ Ajouter un filtre personnalisé │
86
+│ ├─ Client [________▼] │
87
+│ ├─ Date [__/__/____] │
88
+│ ├─ État [________▼] │
89
+│ └─ Montant [____] à [____] │
90
+├─ Grouper par ──────────────────────────┤
91
+│ Vendeur | Client | Date | État │
92
+└────────────────────────────────────────┘
93
+```
94
+
95
+**Sauvegarder une recherche** : Favoris → 💾 Enregistrer la recherche actuelle
96
+
97
+---
98
+
99
+## 2. Ventes — Devis et commandes
100
+
101
+### 2.1 Le cycle de vente
102
+
103
+```
104
+Devis ──→ Commande ──→ Livraison ──→ Facture ──→ Paiement
105
+ │ │ │ │ │
106
+ ↓ ↓ ↓ ↓ ↓
107
+draft sale done posted paid
108
+```
109
+
110
+### 2.2 Créer un devis
111
+
112
+1. **Ventes → Commandes → Nouveau**
113
+2. Remplir l'en-tête :
114
+ - **Client** : taper 2-3 lettres du nom → liste déroulante → sélectionner
115
+ - Si le client n'existe pas : taper le nom complet + **"Créer"**
116
+ - **Date** : automatique (modifiable)
117
+ - **Date d'expiration** (optionnel) : validité du devis
118
+ - **Référence client** (optionnel) : votre référence interne
119
+3. Ajouter des lignes :
120
+ - **Ajouter un produit** → taper le nom ou scanner le code-barre
121
+ - **Quantité** : par défaut 1, modifiable
122
+ - **Prix unitaire** : automatique depuis la fiche produit
123
+ - **Remise** : `%` ou montant (colonne Remise)
124
+ - **Taxe** : automatique (8,5% pour La Réunion)
125
+4. Options de bas de page :
126
+ - **Note** : visible sur le PDF
127
+ - **Conditions** : texte juridique (par défaut depuis la config)
128
+5. Actions :
129
+ - **Confirmer** → le devis devient une commande
130
+ - **Envoyer par email** → envoi du PDF au client (⚠️ limite 5 emails/jour)
131
+ - **Aperçu** → voir le PDF avant envoi
132
+ - **Imprimer** → impression directe
133
+
134
+### 2.3 Transformer un devis en commande
135
+
136
+- Ouvrir le devis → **Confirmer**
137
+- OU : sélection multiple dans la liste → Action → Confirmer les ventes
138
+
139
+### 2.4 Gérer les commandes
140
+
141
+| Action | Comment |
142
+|--------|---------|
143
+| **Modifier** | Cliquer sur une ligne → modifier prix, quantité, produit |
144
+| **Ajouter une ligne** | Bouton "Ajouter un produit" en bas |
145
+| **Supprimer une ligne** | 🗑️ icône corbeille sur la ligne |
146
+| **Annuler** | Action → Annuler (⚠️ irréversible, préférer `Verrouiller`) |
147
+| **Dupliquer** | Action → Dupliquer (pratique pour clients réguliers) |
148
+| **Verrouiller** | Empêche toute modification ultérieure |
149
+
150
+### 2.5 États d'une commande
151
+
152
+| État | Badge | Signification |
153
+|------|-------|-------------|
154
+| Devis | 🟡 | En attente de confirmation |
155
+| Commande | 🟢 | Confirmée |
156
+| Livraison | 🔵 | Produits/services livrés |
157
+| Facturé | 🟣 | Facture(s) générée(s) |
158
+| Annulé | 🔴 | Commande annulée |
159
+
160
+### 2.6 Gestion par Kanban
161
+
162
+La vue Kanban (📊) permet de **glisser-déposer** les commandes entre les colonnes d'état. Très pratique pour suivre l'avancement visuellement.
163
+
164
+### 2.7 Bons de livraison
165
+
166
+Si le module Inventaire est activé :
167
+1. Ouvrir la commande → **Livrer**
168
+2. Ajuster les quantités livrées
169
+3. **Valider** → bon de livraison créé
170
+4. Le stock est décrémenté automatiquement
171
+
172
+---
173
+
174
+## 3. Point de Vente (PDV) — La caisse
175
+
176
+### 3.1 Configuration du PDV
177
+
178
+> **PDV actuel** : "Parc de la Luge - Caisse" (ID 1)
179
+
180
+**Accéder à la config** : PDV → Configuration → Point de Vente
181
+
182
+| Paramètre | Valeur recommandée | Explication |
183
+|-----------|-------------------|-------------|
184
+| Nom | Parc de la Luge - Caisse | Nom visible dans la liste |
185
+| Catégories disponibles | Toutes | Produits visibles dans la grille |
186
+| Modes de paiement | Espèces, CB, Chèque | Boutons de paiement |
187
+| Ticket | Logo + infos légales | Personnaliser le ticket |
188
+| Prix TTC | ✅ | Afficher les prix TTC |
189
+| Remises autorisées | ✅ | Permettre les remises manuelles |
190
+| Prix manuel | ✅ | Saisir un prix libre |
191
+| Code-barre | ✅ | Scanner les produits |
192
+
193
+### 3.2 Ouvrir une session
194
+
195
+```
196
+PDV → Tableau de bord → Nouvelle session
197
+ ┌──────────────────────────┐
198
+ │ Nouvelle session │
199
+ │ PDV : Parc de la Luge │
200
+ │ Solde ouverture : 100,00€ │ ← saisir le fond de caisse
201
+ │ │
202
+ │ [Ouvrir] │
203
+ └──────────────────────────┘
204
+```
205
+
206
+### 3.3 Interface de caisse
207
+
208
+```
209
+┌─ Parc de la Luge - Caisse ──────── 🕐 14:23 ─┐
210
+│ 🔍 [Rechercher...] 👤 [Client] │
211
+├─────────────┬─────────────────────────────────┤
212
+│ Grille │ Panier │
213
+│ Produits │ ┌──────────────────────────┐ │
214
+│ │ │ Luge — 4 tours 1× 11€ │ │
215
+│ [Luge 4t] │ │ Luge — Illimité 2× 14€ │ │
216
+│ [Luge Ill.] │ │ Poney 1× 5€ │ │
217
+│ [Poney] │ │──────────────────────│ │
218
+│ [Snack] │ │ Total : 44,00€ │ │
219
+│ [Boisson] │ │ TVA 8,5% : 0,00€ │ │
220
+│ [Bon Cadeau]│ │ │ │
221
+│ │ │ [💳 Paiement] │ │
222
+│ │ └──────────────────────────┘ │
223
+├─────────────┴─────────────────────────────────┤
224
+│ 1 2 3 ← pavé numérique (quantités) │
225
+│ 4 5 6 │
226
+│ 7 8 9 ⌫ Corbeille │
227
+│ 0 ← │
228
+└───────────────────────────────────────────────┘
229
+```
230
+
231
+### 3.4 Encaisser
232
+
233
+1. **Scanner** le code-barre OU **cliquer** sur le produit → il apparaît dans le panier
234
+2. Ajuster la **quantité** (pavé numérique ou flèches +/-)
235
+3. Cliquer **💳 Paiement** → écran de paiement :
236
+
237
+```
238
+┌─ Paiement ───────────────────────────────┐
239
+│ Total : 44,00€ │
240
+│ │
241
+│ 🟢 Espèces ┌──────┐ │
242
+│ 🔵 CB │ 50€ │ ← montant reçu │
243
+│ 🟡 Chèque └──────┘ │
244
+│ 🟣 Bon cadeau │
245
+│ Rendu : 6,00€ │
246
+│ │
247
+│ [Valider] [Retour] │
248
+└───────────────────────────────────────────┘
249
+```
250
+
251
+4. Sélectionner le mode de paiement
252
+5. Pour les **espèces** : saisir le montant reçu → rendu calculé automatiquement
253
+6. **Valider** → ticket imprimé
254
+
255
+### 3.5 Ajouter un client à une vente
256
+
257
+- Cliquer **👤 Client** → rechercher ou créer
258
+- Pratique pour :
259
+ - Factures nominatives
260
+ - Programme de fidélité
261
+ - Historique d'achats
262
+
263
+### 3.6 Remises
264
+
265
+- **Remise sur ligne** : sélectionner la ligne → saisir `%` ou montant
266
+- **Remise globale** : bouton `%` → saisir le pourcentage → appliqué au total
267
+
268
+### 3.7 Prix manuel
269
+
270
+- Bouton **💰 Prix** → saisir le prix → cliquer sur le produit
271
+- Utile pour les articles sans prix fixe (ex: promotion du jour)
272
+
273
+### 3.8 Corriger une erreur
274
+
275
+- **Avant paiement** : sélectionner la ligne → 🗑️ Corbeille
276
+- **Après paiement** :
277
+ 1. Cliquer l'icône 🕐 (historique)
278
+ 2. Trouver la commande → **Remboursement**
279
+ 3. Sélectionner les produits à rembourser → **Rembourser**
280
+
281
+### 3.9 Fermer la session
282
+
283
+```
284
+PDV → Fermer la session
285
+
286
+┌─ Clôture de session ───────────────────────┐
287
+│ Ouverture : 100,00€ │
288
+│ Transactions : 44,00€ │
289
+│ ──────────────────────────── │
290
+│ Théorique : 144,00€ │
291
+│ Compté : [____,__€] ← saisir │
292
+│ Écart : +1,50€ │
293
+│ │
294
+│ Détail des paiements : │
295
+│ Espèces : 140,00€ │
296
+│ CB : 0,00€ │
297
+│ Chèque : 0,00€ │
298
+│ │
299
+│ [Fermer la session] │
300
+└────────────────────────────────────────────┘
301
+```
302
+
303
+- **Soldes** : ouvrant et compté
304
+- **Écart** : différence entre théorique et compté (normal si < quelques €)
305
+- Si écart important → vérifier les transactions avant de fermer
306
+
307
+### 3.10 Raccourcis clavier PDV
308
+
309
+| Touche | Action |
310
+|--------|--------|
311
+| `F1` | 🔍 Rechercher un produit |
312
+| `F2` | 💳 Paiement |
313
+| `F3` | 👤 Sélectionner le client |
314
+| `F4` | % Remise |
315
+| `F5` | 💰 Prix manuel |
316
+| `F6` | 🗑️ Annuler la dernière ligne |
317
+| `F7` | 📝 Note interne |
318
+| `F8` | 🔒 Fermer la session |
319
+| `Esc` | Retour |
320
+
321
+---
322
+
323
+## 4. Produits et inventaire
324
+
325
+### 4.1 Créer un produit
326
+
327
+```
328
+Ventes → Produits → Nouveau
329
+```
330
+
331
+| Champ | Description | Exemple |
332
+|-------|-------------|---------|
333
+| **Nom** | Affiché sur le ticket PDV | "Luge — Forfait 4 tours" |
334
+| **Type** | `Service` (billets) ou `Article consommable` (snack) | Service |
335
+| **Prix de vente** | TTC | 11,00 € |
336
+| **Code-barre** | Scanné en caisse | `BW-LUGE-4T` |
337
+| **Catégorie** | Groupe dans la grille PDV | Billetterie |
338
+| **Unité** | Unité de vente | Unités |
339
+| **TVA** | Taxe applicable | 8,5% (Réunion) |
340
+
341
+#### Onglet Ventes
342
+
343
+- ✅ **Disponible à la vente** → apparaît dans les commandes
344
+- ✅ **Disponible en PDV** → apparaît dans la grille de caisse
345
+- **Poids / Volume** : pour les frais de port (si applicable)
346
+
347
+#### Onglet Inventaire
348
+
349
+| Champ | Usage |
350
+|-------|-------|
351
+| **Quantité en stock** | Nombre disponible (articles physiques) |
352
+| **Stock minimum** | Alerte si stock < seuil |
353
+| **Réapprovisionnement** | Quantité à commander |
354
+
355
+> ⚠️ **Services** (billets) = pas de stock. **Articles** (snack, goodies) = suivi de stock.
356
+
357
+### 4.2 Modifier un produit
358
+
359
+1. Rechercher par **nom** ou **code-barre**
360
+2. Modifier les champs
361
+3. **Enregistrer**
362
+
363
+### 4.3 Désactiver un produit
364
+
365
+Décocher **Actif** (ne PAS supprimer — cela casse l'historique des ventes passées)
366
+
367
+### 4.4 Catégories de produits
368
+
369
+```
370
+Ventes → Configuration → Catégories de produits
371
+```
372
+
373
+Les catégories structurent la grille du PDV :
374
+
375
+```
376
+┌─ Parc de la Luge ────────────────────────┐
377
+│ [Billetterie] [Snack] [Boissons] │ ← onglets
378
+│ ┌──────┐ ┌────┐ ┌─────┐ │
379
+│ │Luge │ │Soda│ │Eau │ │
380
+│ │4 tours│ │ │ │ │ │
381
+│ └──────┘ └────┘ └─────┘ │
382
+│ ┌──────┐ ┌────┐ │
383
+│ │Luge │ │Chips│ │
384
+│ │Illim.│ │ │ │
385
+│ └──────┘ └────┘ │
386
+└──────────────────────────────────────────┘
387
+```
388
+
389
+### 4.5 Variantes de produits
390
+
391
+Pour un produit avec plusieurs déclinaisons (ex: T-shirt S/M/L/XL) :
392
+
393
+1. Ouvrir le produit → Onglet **Variantes**
394
+2. Ajouter des **attributs** : "Taille" → S, M, L, XL
395
+3. Les variantes sont créées automatiquement
396
+4. Chaque variante peut avoir son propre prix, code-barre, stock
397
+
398
+### 4.6 Réapprovisionnement
399
+
400
+```
401
+Inventaire → Opérations → Réapprovisionnement → Nouveau
402
+```
403
+
404
+- Sélectionner le produit → quantité → date prévue
405
+- Génère un bon de commande fournisseur automatiquement
406
+
407
+---
408
+
409
+## 5. Événements et billetterie
410
+
411
+### 5.1 Structure
412
+
413
+```
414
+Événement : "Parc de la Luge — Billetterie"
415
+ ├── Billet "Journée Luge illimitée" → produit 14€
416
+ ├── Billet "Forfait 4 tours" → produit 11€
417
+ ├── Billet "Poney" → produit 5€
418
+ └── Billet "Bon Cadeau" → produit variable
419
+```
420
+
421
+### 5.2 Créer un événement
422
+
423
+```
424
+Événements → Événements → Nouveau
425
+```
426
+
427
+| Champ | Description |
428
+|-------|-------------|
429
+| **Nom** | "Vacances Juillet 2026" |
430
+| **Date début/fin** | Période de l'événement |
431
+| **Places max** | Limite de participants (optionnel) |
432
+| **Fuseau horaire** | Indian/Reunion |
433
+| **Modèle d'email** | Désactiver (voir 5.4) |
434
+
435
+### 5.3 Créer des billets
436
+
437
+Onglet **Billets** → Ajouter une ligne pour chaque type :
438
+
439
+| Billet | Produit associé | Prix |
440
+|--------|----------------|------|
441
+| Journée Luge illimitée | Luge — Illimité (ID 18) | 14,00€ |
442
+| Forfait 4 tours | Luge — 4 tours (ID 13) | 11,00€ |
443
+| Poney | Poney (ID 15) | 5,00€ |
444
+
445
+### 5.4 ⚠️ Désactiver les emails automatiques
446
+
447
+Odoo envoie un email à chaque inscription. **Limite Odoo Online = 5 emails/jour.**
448
+
449
+1. Ouvrir l'événement → décocher **Confirmation automatique**
450
+2. Si déjà actif : Paramètres → Technique → Automatisation → Actions planifiées → désactiver les jobs "mail"
451
+
452
+### 5.5 Voir les inscriptions
453
+
454
+```
455
+Événements → Événements → cliquer sur l'événement → onglet Participants
456
+```
457
+
458
+| Colonne | Signification |
459
+|---------|-------------|
460
+| Nom | Nom du participant |
461
+| Email | Email du client |
462
+| Code-barre | QR code BilletWeb (10 chiffres) |
463
+| État | `Confirmé`, `Non confirmé`, `Présent`, `Annulé` |
464
+| Billet | Type de billet acheté |
465
+
466
+### 5.6 Scanner un billet (check-in)
467
+
468
+1. Ouvrir `https://sarl-le-relais-de-louest.odoo.com/event/checkin`
469
+2. Scanner le QR code du billet avec la douchette
470
+3. L'inscription passe en état **Présent** ✅
471
+
472
+### 5.7 Inscription manuelle
473
+
474
+Si un client achète sur place (pas via BilletWeb) :
475
+
476
+1. Événement → cliquer sur le nom → **Inscrire**
477
+2. Remplir : nom, email → sélectionner le billet → **Confirmer**
478
+3. L'inscription apparaît dans la liste des participants
479
+
480
+---
481
+
482
+## 6. Facturation et paiements
483
+
484
+### 6.1 Créer une facture
485
+
486
+#### Depuis une commande
487
+
488
+1. Ouvrir la commande (Ventes → Commandes → cliquer)
489
+2. **Créer une facture**
490
+3. Choisir :
491
+ - **Facture normale** : 100% du montant
492
+ - **Acompte** (pourcentage) : ex. 30%
493
+ - **Acompte** (montant fixe) : ex. 50€
494
+4. **Créer et voir la facture**
495
+5. Vérifier les infos
496
+6. **Confirmer** → la facture est comptabilisée
497
+
498
+#### Sans commande préalable
499
+
500
+```
501
+Facturation → Clients → Factures → Nouveau
502
+```
503
+
504
+Remplir les mêmes champs qu'une commande.
505
+
506
+### 6.2 Envoyer une facture
507
+
508
+1. Ouvrir la facture
509
+2. **Envoyer & Imprimer**
510
+3. Vérifier :
511
+ - Email du client
512
+ - Objet et corps du message
513
+ - Pièce jointe PDF
514
+4. **Envoyer**
515
+
516
+### 6.3 Enregistrer un paiement
517
+
518
+```
519
+Ouvrir la facture → Enregistrer un paiement
520
+
521
+┌─ Paiement ────────────────────────────────┐
522
+│ Mode de paiement : [Espèces ▼] │
523
+│ Montant : [44,00€] │
524
+│ Date : [29/05/2026] │
525
+│ Mémo : [CB fin de journée] │
526
+│ Journal : [Banque ▼] │
527
+│ │
528
+│ [Valider] │
529
+└────────────────────────────────────────────┘
530
+```
531
+
532
+- Après paiement : la facture passe en état **Payée** 🟢
533
+
534
+### 6.4 Avoirs
535
+
536
+Pour rembourser ou corriger une facture :
537
+
538
+1. Ouvrir la facture → **Avoir**
539
+2. Choisir :
540
+ - **Remboursement total** : 100%
541
+ - **Remboursement partiel** : sélectionner les lignes
542
+3. **Valider** → l'avoir est créé
543
+
544
+### 6.5 États d'une facture
545
+
546
+| État | Badge |
547
+|------|-------|
548
+| Brouillon | 🟡 |
549
+| Comptabilisée | 🔵 |
550
+| Payée | 🟢 |
551
+| Annulée | 🔴 |
552
+
553
+---
554
+
555
+## 7. Clients (Contacts)
556
+
557
+### 7.1 Créer un client
558
+
559
+```
560
+Contacts → Nouveau
561
+```
562
+
563
+| Champ | Obligatoire | Notes |
564
+|-------|:----------:|-------|
565
+| Nom | ✅ | Raison sociale ou nom complet |
566
+| Type | ✅ | Particulier ou Société |
567
+| Email | | Pour envoi factures |
568
+| Téléphone | | |
569
+| Mobile | | Pour SMS |
570
+| Adresse | | Rue, ville, code postal |
571
+| N° TVA | | Si assujetti |
572
+| Étiquettes | | Pour catégoriser |
573
+
574
+### 7.2 Fiche client
575
+
576
+En cliquant sur un client, on voit :
577
+
578
+- **Onglet Ventes et Achats** : historique, total dépensé, dernier achat
579
+- **Onglet Factures** : factures liées
580
+- **Onglet Commandes** : commandes passées
581
+- **Bouton intelligent** : `💰 Ventes` → toutes les commandes de ce client
582
+
583
+### 7.3 Fusionner des doublons
584
+
585
+1. Sélectionner les contacts à fusionner (☑️)
586
+2. **Action → Fusionner les contacts**
587
+3. Choisir le contact **principal** (garder ses infos)
588
+4. Sélectionner les champs à conserver de chaque doublon
589
+5. **Fusionner**
590
+
591
+### 7.4 Import en masse
592
+
593
+Voir [section 9 — Imports et exports](#9-imports-et-exports)
594
+
595
+---
596
+
597
+## 8. Rapports et analyses
598
+
599
+### 8.1 Analyse des ventes
600
+
601
+```
602
+Ventes → Rapports → Analyse des ventes
603
+```
604
+
605
+**Filtres disponibles** :
606
+- Période : aujourd'hui, semaine, mois, année, personnalisé
607
+- Produit / Catégorie
608
+- Client
609
+- Vendeur
610
+
611
+**Vues** :
612
+- 📈 **Graphique en barres** : CA par jour/semaine/mois
613
+- 🥧 **Camembert** : répartition par produit
614
+- 📋 **Tableau croisé** : détail ligne à ligne
615
+
616
+**Comparaison** : activer "Comparer à" → période précédente / même période N-1
617
+
618
+### 8.2 Rapports PDV
619
+
620
+```
621
+PDV → Tableau de bord → Sessions
622
+```
623
+
624
+- Voir toutes les sessions : date, ouverture, clôture, écart
625
+- Cliquer sur une session → détail des transactions
626
+
627
+```
628
+PDV → Rapports → Détail des ventes
629
+```
630
+
631
+- Toutes les commandes PDV : produit, prix, heure, mode de paiement
632
+
633
+### 8.3 Tableau de bord
634
+
635
+Depuis la page d'accueil Odoo (🏠), des **indicateurs** sont affichés :
636
+- Chiffre d'affaires du mois
637
+- Commandes à facturer
638
+- Factures en retard de paiement
639
+
640
+### 8.4 Exporter un rapport
641
+
642
+1. Sur n'importe quelle vue liste : sélectionner les lignes (☑️)
643
+2. **Action** (⚙️ engrenage) → **Exporter**
644
+3. Choisir le format : **CSV** (tableur) ou **Excel**
645
+4. Cocher les colonnes à exporter
646
+5. **Exporter** → téléchargement automatique
647
+
648
+---
649
+
650
+## 9. Imports et exports
651
+
652
+### 9.1 Importer des données
653
+
654
+Toute donnée peut être importée en masse via CSV/Excel :
655
+
656
+1. Aller dans l'application concernée (ex: Contacts, Produits)
657
+2. **Favoris** → **Importer des enregistrements**
658
+3. Télécharger le **modèle** (pour avoir les bonnes colonnes)
659
+4. Remplir le fichier CSV
660
+5. **Télécharger le fichier** → **Importer**
661
+
662
+### 9.2 Format CSV attendu
663
+
664
+| Modèle | Colonnes minimales |
665
+|--------|-------------------|
666
+| Contacts | `name`, `email` |
667
+| Produits | `name`, `list_price`, `type` |
668
+| Commandes | `name`, `partner_id`, `date_order` |
669
+
670
+### 9.3 Exporter
671
+
672
+Voir [section 8.4](#84-exporter-un-rapport)
673
+
674
+---
675
+
676
+## 10. Configuration et réglages
677
+
678
+### 10.1 Accès à la configuration
679
+
680
+- **Mode normal** : Paramètres → par section
681
+- **Mode développeur** : Paramètres → Activer le mode développeur (en bas à droite)
682
+
683
+### 10.2 Utilisateurs et droits
684
+
685
+```
686
+Paramètres → Utilisateurs → Gérer les utilisateurs
687
+```
688
+
689
+- **Créer un utilisateur** : email + nom + droits
690
+- **Droits** : Administrateur, Ventes seulement, PDV seulement...
691
+- **Désactiver** (ne pas supprimer) un utilisateur qui part
692
+
693
+### 10.3 Taxes (TVA Réunion)
694
+
695
+```
696
+Paramètres → Comptabilité → Taxes
697
+```
698
+
699
+| Taux | Compte vente | Compte achat | Actif |
700
+|------|:----------:|:----------:|:-----:|
701
+| 8,5% | 79 | 32 | ✅ |
702
+| 2,1% | 80 | 35 | ✅ |
703
+| 0% | 61-70 | 50 | ✅ |
704
+| ~~20%~~ | - | - | ❌ désactivée |
705
+| ~~10%~~ | - | - | ❌ désactivée |
706
+| ~~5,5%~~ | - | - | ❌ désactivée |
707
+
708
+### 10.4 Modes de paiement
709
+
710
+```
711
+PDV → Configuration → Modes de paiement
712
+```
713
+
714
+| Mode | Journal |
715
+|------|---------|
716
+| Espèces | Journal de caisse |
717
+| Carte bancaire | Terminal CB |
718
+| Chèque | Banque |
719
+
720
+### 10.5 Séquence de numérotation
721
+
722
+```
723
+Paramètres → Technique → Séquences
724
+```
725
+
726
+- `sale.order` → numéros de commandes
727
+- `account.move` → numéros de factures
728
+- `pos.order` → numéros de tickets PDV
729
+
730
+---
731
+
732
+## 11. Dépannage
733
+
734
+### 11.1 "Produit introuvable dans le PDV"
735
+
736
+- Vérifier **Disponible en PDV** coché dans la fiche produit
737
+- Vérifier que la **catégorie** du produit est incluse dans la config PDV
738
+- Vérifier que le produit est **Actif**
739
+- Rafraîchir la page (F5)
740
+
741
+### 11.2 "Session PDV ne ferme pas"
742
+
743
+- Vérifier qu'il n'y a pas de commande en **brouillon**
744
+- Action → **Forcer la clôture** (en cas de blocage)
745
+- Vérifier les commandes en attente dans l'historique
746
+
747
+### 11.3 "Email non envoyé"
748
+
749
+- Limite Odoo Online : 5 emails/jour (trial/free)
750
+- Voir les emails en file d'attente : Paramètres → Technique → Emails
751
+- Supprimer les emails bloqués : sélectionner → Action → Supprimer
752
+
753
+### 11.4 "Lenteur"
754
+
755
+- Vider le cache du navigateur
756
+- Fermer les onglets inutiles
757
+- Vérifier la connexion internet
758
+
759
+### 11.5 "Erreur d'impression ticket"
760
+
761
+- L'imprimante doit être connectée en **IP** (pas USB)
762
+- Config : PDV → Configuration → PDV → IoT Box
763
+- Alternative : imprimer depuis l'historique → Action → Imprimer
764
+
765
+---
766
+
767
+## 12. Raccourcis et astuces
768
+
769
+### 12.1 Recherche universelle
770
+
771
+`Ctrl+K` → taper n'importe quoi :
772
+- Nom client → fiche client
773
+- Numéro commande → commande
774
+- Nom produit → produit
775
+- `#SO001` → commande SO001
776
+- `+Dupont` → créer un contact "Dupont"
777
+
778
+### 12.2 Actions rapides
779
+
780
+| Raccourci | Action |
781
+|-----------|--------|
782
+| `Ctrl+Enter` | Enregistrer |
783
+| `Ctrl+S` | Enregistrer et rester |
784
+| `Alt+←` | Retour |
785
+| `Échap` | Fermer le popup |
786
+
787
+### 12.3 Astuces quotidiennes
788
+
789
+- **Favoris** : mettre en favori les vues fréquentes (⭐)
790
+- **Filtres sauvegardés** : "À facturer ce mois", "Mes commandes du jour"
791
+- **Dupliquer** : copier une commande récurrente
792
+- **Vue Kanban** : glisser-déposer pour changer l'état
793
+- **Sélection multiple** : ☑️ + Action → appliquer à toutes les lignes
794
+- **Barre de recherche** : `état:commande total:>100` → commandes > 100€
795
+
796
+### 12.4 Pour les débutants
797
+
798
+1. **Premier jour** : ouvrir/fermer une session PDV + encaisser 2-3 ventes test
799
+2. **Première semaine** : créer des produits, des clients, des devis
800
+3. **Premier mois** : générer des factures, consulter les rapports
801
+4. **Régulier** : consulter le tableau de bord chaque matin