details:   https://code.tryton.org/tryton/commit/752835f225ff
branch:    default
user:      Nicolas Évrard <[email protected]>
date:      Mon Jul 27 11:55:35 2026 +0200
description:
        Remove required on resource ID of ir.translation
diffstat:

 trytond/trytond/ir/translation.py      |  53 +++++++++++++++++++++------------
 trytond/trytond/model/fields/field.py  |   6 +-
 trytond/trytond/tests/test_model.py    |   1 -
 trytond/trytond/tests/test_modelsql.py |   4 +-
 4 files changed, 39 insertions(+), 25 deletions(-)

diffs (236 lines):

diff -r 563cb007e55c -r 752835f225ff trytond/trytond/ir/translation.py
--- a/trytond/trytond/ir/translation.py Mon Jan 29 18:47:56 2024 +0100
+++ b/trytond/trytond/ir/translation.py Mon Jul 27 11:55:35 2026 +0200
@@ -78,7 +78,12 @@
     __name__ = "ir.translation"
 
     name = fields.Char("Name", required=True)
-    res_id = fields.Integer('Resource ID', required=True)
+    res_id = fields.Integer(
+        "Resource ID",
+        domain=['OR',
+            ('res_id', '=', None),
+            ('res_id', '>=', 0),
+            ])
     lang = fields.Selection('get_language', string='Language')
     type = fields.Selection(TRANSLATION_TYPE, string='Type',
        required=True)
@@ -150,6 +155,20 @@
                 })
 
     @classmethod
+    def __register__(cls, module_name):
+        table_h = cls.__table_handler__(module_name)
+        cursor = Transaction().connection.cursor()
+        translation = cls.__table__()
+
+        # Migration from 8.0: remove required
+        table_h.not_null_action('res_id', 'remove')
+        cursor.execute(*translation.update(
+                [translation.res_id], [Null],
+                where=(translation.res_id < 0)))
+
+        super().__register__(module_name)
+
+    @classmethod
     def register_model(cls, model, module_name):
         cursor = Transaction().connection.cursor()
         ir_translation = cls.__table__()
@@ -180,7 +199,7 @@
                             'value', 'module', 'fuzzy', 'res_id')],
                     [[
                             name, INTERNAL_LANG, 'model', src,
-                            '', module_name, False, -1]]))
+                            '', module_name, False, Null]]))
         else:
             cursor.execute(*ir_translation.update(
                     [ir_translation.src],
@@ -230,7 +249,7 @@
                     *ir_translation.insert(columns,
                         [[
                                 name, INTERNAL_LANG, type, val,
-                                '', module_name, False, -1]]))
+                                '', module_name, False, Null]]))
                 inserted = True
 
         for field_name, field in model._fields.items():
@@ -276,7 +295,7 @@
                                 trans_name, INTERNAL_LANG,
                                 'wizard_button', button.string,
                                 '', module_name,
-                                False, -1]]))
+                                False, Null]]))
             elif trans_buttons[trans_name] != button.string:
                 cursor.execute(*ir_translation.update(
                         [ir_translation.src],
@@ -294,10 +313,6 @@
     def default_fuzzy():
         return False
 
-    @staticmethod
-    def default_res_id():
-        return -1
-
     def get_model(self, name):
         return self.name.split(',')[0]
 
@@ -553,7 +568,7 @@
                         ('lang', '=', lang),
                         ('type', '=', ttype),
                         ('name', 'in', [get_name(r) for r in records]),
-                        ('res_id', '=', -1),
+                        ('res_id', '=', Null),
                         ]):
                 name2translations[translation.name].append(translation)
 
@@ -697,7 +712,7 @@
                     ('value', '!=', ''),
                     ('value', '!=', None),
                     ('fuzzy', '=', False),
-                    ('res_id', '=', -1),
+                    ('res_id', '=', Null),
                     ]
                 if source is not None:
                     clause.append(('src', '=', source))
@@ -742,7 +757,7 @@
                         ('value', '!=', ''),
                         ('value', '!=', None),
                         ('fuzzy', '=', False),
-                        ('res_id', '=', -1),
+                        ('res_id', '=', Null),
                         ], order=[('module', 'DESC')])
                 for translation in translations:
                     cache.setdefault(
@@ -902,7 +917,7 @@
                         ])
                 res_id = model_data.db_id
             else:
-                res_id = -1
+                res_id = None
             with Transaction().set_context(module=res_id_module):
                 domain = [
                     ('name', '=', new_translation.name),
@@ -969,7 +984,7 @@
                         except ValueError:
                             continue
                     else:
-                        res_id = -1
+                        res_id = None
 
                     translation.res_id = res_id
                     key = translation.unique_key
@@ -1055,7 +1070,7 @@
                 'name': translation.name,
                 }
             res_id = translation.res_id
-            if res_id >= 0:
+            if res_id:
                 model, _ = translation.name.split(',')
                 if model in db_id2fs_id:
                     res_id = db_id2fs_id[model].get(res_id)
@@ -1240,7 +1255,7 @@
                                     string[1], '',
                                     '', '',
                                     '', module,
-                                    False, -1]]))
+                                    False, Null]]))
         for (report_name, module), strings in report_strings.items():
             query = translation.delete(
                 where=(translation.name == report_name)
@@ -1334,7 +1349,7 @@
                                 None, '',
                                 '', '',
                                 '', view.module,
-                                False, -1]]))
+                                False, Null]]))
             if strings:
                 cursor.execute(*translation.delete(
                         where=(translation.name == view.model)
@@ -1404,7 +1419,7 @@
             Model = pool.get(model_name)
         except KeyError:
             return True
-        if translation.res_id >= 0:
+        if translation.res_id:
             if field_name not in Model._fields:
                 return True
             field = Model._fields[field_name]
@@ -1520,7 +1535,7 @@
                     to_delete.append(translation.id)
                 else:
                     keys.add(key)
-                if translation.type == 'model' and translation.res_id >= 0:
+                if translation.type == 'model' and translation.res_id:
                     model_name, _ = translation.name.split(',', 1)
                     records[model_name][translation.res_id].add(translation.id)
 
@@ -1707,7 +1722,7 @@
                     where=(translation.name == row['name'])
                     & (translation.type == row['type'])
                     & (translation.lang == lang)
-                    & (translation.res_id == (row['res_id'] or -1))
+                    & (translation.res_id == row['res_id'])
                     & (translation.module == row['module'])))
 
         cursor.execute(*translation.select(
diff -r 563cb007e55c -r 752835f225ff trytond/trytond/model/fields/field.py
--- a/trytond/trytond/model/fields/field.py     Mon Jan 29 18:47:56 2024 +0100
+++ b/trytond/trytond/model/fields/field.py     Mon Jul 27 11:55:35 2026 +0200
@@ -655,7 +655,7 @@
                         model_data.fs_id) == getattr(model_field, name))
                 .select(
                     msg_trans.id.as_('id'),
-                    Literal(-1).as_('res_id'),
+                    Literal(Null).as_('res_id'),
                     msg_trans.value.as_('value'),
                     Concat(
                         Concat(model_field.model, ','),
@@ -684,14 +684,14 @@
         if Model.__name__ == 'ir.model':
             name_ = Concat(Concat(table.name, ','), name)
             type_ = 'model'
-            res_id = -1
+            res_id = None
         elif Model.__name__ == 'ir.model.field':
             name_ = Concat(Concat(table.model, ','), table.name)
             if name == 'string':
                 type_ = 'field'
             else:
                 type_ = 'help'
-            res_id = -1
+            res_id = None
         else:
             name_ = '%s,%s' % (Model.__name__, name)
             type_ = 'model'
diff -r 563cb007e55c -r 752835f225ff trytond/trytond/tests/test_model.py
--- a/trytond/trytond/tests/test_model.py       Mon Jan 29 18:47:56 2024 +0100
+++ b/trytond/trytond/tests/test_model.py       Mon Jul 27 11:55:35 2026 +0200
@@ -545,7 +545,6 @@
                     'lang': self.other_language,
                     'src': "Name",
                     'name': 'test.model,name',
-                    'res_id': -1,
                     'value': "Nom",
                     'type': 'field',
                     }])
diff -r 563cb007e55c -r 752835f225ff trytond/trytond/tests/test_modelsql.py
--- a/trytond/trytond/tests/test_modelsql.py    Mon Jan 29 18:47:56 2024 +0100
+++ b/trytond/trytond/tests/test_modelsql.py    Mon Jul 27 11:55:35 2026 +0200
@@ -1604,7 +1604,7 @@
         translation, = Translation.search([
                 ('type', '=', 'model'),
                 ('name', '=', 'test.modelsql.name_translated,string'),
-                ('res_id', '=', -1),
+                ('res_id', '=', None),
                 ])
         self.assertEqual(translation.src, "NameTranslated")
         self.assertEqual(translation.value, "NameTranslated")
@@ -1627,7 +1627,7 @@
         translation, = Translation.search([
                 ('type', '=', 'help'),
                 ('name', '=', 'test.modelsql.name_translated,name'),
-                ('res_id', '=', -1),
+                ('res_id', '=', None),
                 ])
         self.assertEqual(translation.src, "Translated help")
         self.assertEqual(translation.value, "Translated help")

Reply via email to