Se rendre au contenu

Odoo 19 CE — Socle technique validé terrain

Cette page rassemble les faits techniques universels sur Odoo 19 Community Edition, tels qu'ils ont été validés sur du code réel testé de bout en bout. Elle couvre les douze zones où Odoo 19 diverge le plus souvent des habitudes héritées des versions précédentes — ou de la documentation officielle elle-même.

Chaque règle présentée ici a transité par un cycle PDCA complet (hypothèse écrite, application, test avec critères de succès définis à l'avance, inscription). Les identifiants entre parenthèses (F001, B006…) renvoient aux fiches de validation correspondantes — l'index complet figure en bas de page. La méthode qui garantit la fiabilité de ces informations est décrite sur la page PDCA & Ishikawa.

1. Cron et actions planifiées (ir.cron)

Les actions planifiées ont changé de contrat en Odoo 19 : un champ historique a disparu et la façon de renseigner l'activation a évolué. Un fichier de données XML écrit « comme avant » provoque une erreur d'installation.

  • Champ numbercall : n'existe pas en Odoo 19 (F001). Toute référence dans un data/*.xml provoque une erreur d'installation. Ne pas l'utiliser.
  • Champ active : à renseigner via eval="True" (ou eval="False"), pas via True — la forme texte n'est plus interprétée (F001).
  • Champ model_id : obligatoire, sous la forme ref="model_" (avec souligné, pas point).
  • Champ state : "code" pour exécuter du Python via .
  • interval_number + interval_type : périodicité ; interval_type accepte minutes, hours, days, weeks, months.

Déclaration correcte d'un cron en Odoo 19 :


    Nom lisible du cron
    
    code
    model._my_cron_method()
    1
    days
    

2. Vues de recherche (vue search)

Les vues de recherche restent le point d'entrée du filtrage et du regroupement dans les listes Odoo. Le piège d'Odoo 19 se cache dans l'élément qui structure les filtres de regroupement.

  • dans une vue search : n'accepte aucun attribut en Odoo 19 (F002). expand="0" comme string="..." provoquent une erreur de chargement de vue. Utiliser simple, sans attribut.
  • À l'intérieur du , placer les avec context="{'group_by': '...'}".
  • Le libellé (string) est porté par chaque , pas par le parent.
  • Pour structurer la barre de recherche, utiliser plusieurs consécutifs.


    




    

3. Controllers HTTP — décorateur @route

Les controllers exposent des routes HTTP côté serveur : API, formulaires, pages publiques. En Odoo 19, le type de route JSON a changé de nom — et l'ancien nom ne fonctionne plus correctement.

  • type : utiliser type='jsonrpc' pour les routes JSON-RPC (B003). type='json' est deprecated et ne fonctionne pas correctement en Odoo 19.
  • auth : "public" (visiteur non loggué), "user" (connexion requise), "none" (sans authentification, pour les webhooks).
  • methods : ["GET"], ["POST"] ou ["GET", "POST"].
  • csrf : False pour API/AJAX, True (défaut) pour les formulaires HTML classiques.
  • website : True si la route hérite du contexte website (cookies, langue).
  • Accès à la session via request.env, request.session, request.httprequest.
# ❌ Deprecated en Odoo 19
@http.route("/my/endpoint", type="json", auth="public", methods=["POST"], csrf=False)

# ✅ Correct
@http.route("/my/endpoint", type="jsonrpc", auth="public", methods=["POST"], csrf=False)

4. Sécurité — ACL et groupes

4.1 ACL (ir.model.access.csv)

Les listes de contrôle d'accès définissent qui peut lire, écrire, créer ou supprimer les enregistrements d'un modèle. Odoo 19 durcit une pratique autrefois tolérée : la ligne d'accès « sans groupe ».

  • group_id:id est obligatoire en Odoo 19 (B004). Toute ligne sans group_id explicite est deprecated et génère des warnings bloquants.
  • Groupes natifs courants : base.group_public (visiteur), base.group_portal (client externe loggué), base.group_user (utilisateur interne), base.group_system (super-admin).
  • Pour donner accès « à tous » : créer plusieurs lignes (une par groupe), jamais une ligne avec le groupe vide.
# ❌ Deprecated — warning bloquant en Odoo 19
access_my_model_all,my.model all,model_my_model,,1,1,1,1

# ✅ Correct
access_my_model_public,my.model public,model_my_model,base.group_public,1,0,0,0
access_my_model_user,my.model user,model_my_model,base.group_user,1,1,1,0

4.2 Groupes (res.groups)

La définition de groupes de sécurité custom perd un champ historique en Odoo 19 : la catégorie de module ne se rattache plus au groupe.

  • category_id n'existe plus sur res.groups (B005). Son usage provoque une ValueError: Invalid field 'category_id' in 'res.groups'.
  • Le modèle ir.module.category existe encore, mais la liaison via category_id est rompue — ne pas en créer dans les modules custom.
  • Nommage : préfixer par le nom du module, par exemple "Mon Module / Administrateur".
  • implied_ids reste la méthode valide pour l'héritage de groupe.


    




    Mon Module / Administrateur
    

5. Modèles ORM

La zone des modèles ORM (models.Model, AbstractModel, TransientModel) est en cours d'enrichissement par cycles PDCA : champs, méthodes ORM, décorateurs (@api.model, @api.depends, @api.constrains…), champs calculés, champs related et héritage (_inherit, _inherits) y seront consignés au fur et à mesure des validations terrain. Les faits déjà validés touchant l'ORM figurent en sections 8 et 9.

6. Vues XML — form, list, kanban, calendar, pivot, graph

C'est dans les vues métier que les migrations Odoo cassent le plus de code hérité. Quatre ruptures validées concentrent l'essentiel des erreurs rencontrées en Odoo 19.

B016 — attrs={} supprimé depuis Odoo 17

La syntaxe attrs="{'invisible': [...], 'readonly': [...], 'required': [...]}" n'existe plus. Les conditions deviennent des expressions Python évaluées contre l'enregistrement courant (et non plus des domaines) : invisible="state not in ('draft', 'done')", readonly="partner_id != False", required="parent_id == False". La règle s'applique à ,