NXL Forge.Pendant que le marché rédige — nous livrons
Technique Odoo··4 min de lecture

Odoo 19 : product_uom devient product_uom_id, mais pas partout

Odoo 19 renomme product_uom en product_uom_id pour respecter la convention de l'ORM. Mais le changement n'est pas uniforme selon les modèles. Voici la carte exacte des champs concernés et ce qui casse sans prévenir dans vos modules sur mesure.

Odoo 19migrationORMdéveloppementproduct_uom

Odoo 19 poursuit un travail de normalisation des noms de champs commencé depuis plusieurs versions. Les champs relationnels doivent se terminer par le suffixe _id, conformément à la convention de l'ORM. Le champ d'unité de mesure historique, appelé product_uom sur de nombreux modèles, devient donc product_uom_id. Le problème pour les équipes qui maintiennent des modules sur mesure ne vient pas du renommage lui-même. Il vient du fait que ce renommage n'est pas appliqué de façon uniforme, et qu'un champ qui change de nom sans alias de compatibilité casse le code qui le référence, souvent sans lever d'erreur immédiate au chargement.

Ce que dit le code source

En comparant directement les définitions de champs entre la branche 18.0 et la branche 19.0 du dépôt Odoo, le tableau se précise. Sur sale.order.line, le champ passe de product_uom en version 18 à product_uom_id en version 191. Même changement sur purchase.order.line. Sur account.move.line, le champ s'appelait déjà product_uom_id en version 18, il ne bouge donc pas. Et sur stock.move, le champ reste product_uom en version 19, exactement comme avant.

ModèleOdoo 18Odoo 19Statut
sale.order.lineproduct_uomproduct_uom_idrenommé
purchase.order.lineproduct_uomproduct_uom_idrenommé
account.move.lineproduct_uom_idproduct_uom_iddéjà aligné
stock.moveproduct_uomproduct_uominchangé

La logique devient lisible une fois posée ainsi. La comptabilité servait déjà de référence avec product_uom_id. Les ventes et les achats s'alignent sur cette convention en version 19. Le module stock, lui, garde son ancien nom. Un développeur qui suppose que « tout est passé en product_uom_id » et remplace mécaniquement toutes les occurrences va casser son code sur les mouvements de stock. À l'inverse, celui qui n'adapte rien va casser ses surcharges de vente et d'achat.

Ce qui casse concrètement

Le champ renommé n'a pas d'alias de repli. Sur sale.order.line en version 19, il n'existe plus aucun attribut product_uom. Toute référence directe déclenche une erreur, mais pas toujours au même moment. Une vue XML qui cite product_uom dans un attribut <field> ou un domain échoue au chargement du module. Une expression Python comme line.product_uom.name lève une AttributeError seulement à l'exécution, c'est à dire quand un utilisateur ouvre le bon écran. Un champ related déclaré sur product_uom casse à la définition du modèle. Les appels mapped('product_uom'), filtered, ou les décorateurs @api.depends('product_uom') tombent dans la même catégorie de rupture différée.

Les filtres de recherche stockés en base et les actions serveur écrites dans l'interface sont un angle mort supplémentaire, car ils ne passent pas par la revue de code habituelle. Un domaine sauvegardé qui référence product_uom sur une ligne de vente renverra une erreur à la première utilisation après migration.

Le domaine de sélection a aussi bougé

Le renommage s'accompagne d'un second changement moins visible. En version 18, le domaine du champ sur sale.order.line limitait le choix aux unités de la même catégorie que le produit, via [('category_id', '=', product_uom_category_id)]. En version 19, ce domaine devient [('id', 'in', allowed_uom_ids)] et s'appuie sur un champ calculé allowed_uom_ids2. Si vos modules surchargeaient le domaine ou recalculaient les unités autorisées, cette logique est à revoir en parallèle du renommage.

Comment sécuriser la migration

La première étape reste une recherche exhaustive de la chaîne product_uom dans tout le code métier, les vues, et les données exportées. Un grep distingue rapidement les occurrences légitimes sur stock.move de celles à corriger sur les ventes et les achats. Un environnement de préproduction avec les vrais modules installés reste le seul moyen fiable de faire remonter les ruptures différées, celles que le simple chargement des modules ne révèle pas. Les tests unitaires qui exercent la création de commandes et de factures attrapent une bonne partie des AttributeError avant la mise en production.

Sur le plan de l'environnement, Odoo 19 demande Python 3.10 ou plus récent, et relève le minimum PostgreSQL de la version 12 à la version 133. Ces prérequis conditionnent la préparation du serveur avant même de toucher au code, et ils sont documentés officiellement.

Pour un panorama plus large des ajustements ORM de cette version, voir notre article sur les changements ORM qui touchent vos modules.

Notre lecture

Ce type de renommage partiel est typique des migrations Odoo. La convention est saine sur le long terme, mais l'absence d'alias de compatibilité et l'application inégale entre modules transforment une bonne intention en source de régressions silencieuses. Notre conseil de praticien est de ne jamais traiter product_uom comme un remplacement global. Le bon réflexe consiste à établir, modèle par modèle, la liste des champs réellement renommés dans les modules que vous utilisez, puis à corriger en s'appuyant sur des tests qui ouvrent effectivement les écrans concernés. Le coût d'une migration Odoo se joue rarement sur les grandes fonctionnalités annoncées. Il se joue sur ces détails de schéma qui ne préviennent pas.

Sources

Footnotes

  1. Un champ fields.Many2one établit une relation « plusieurs vers un » vers un autre modèle, ici uom.uom. La convention Odoo impose le suffixe _id sur ce type de champ relationnel.

  2. allowed_uom_ids est un champ calculé qui liste les unités de mesure autorisées pour une ligne donnée, en fonction du produit sélectionné. Le domaine du champ d'unité s'appuie sur cette liste en version 19.

  3. Prérequis relevés dans la documentation officielle d'installation depuis les sources d'Odoo 19.0.

Sur le même thème

Votre idée mérite un vrai logiciel

Une question, un projet Odoo ?

Modules préconfigurés, intégration, sur-mesure — parlons-en sans engagement.