Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package trytond for openSUSE:Factory checked in at 2025-12-22 22:49:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/trytond (Old) and /work/SRC/openSUSE:Factory/.trytond.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "trytond" Mon Dec 22 22:49:16 2025 rev:113 rq:1323913 version:7.0.42 Changes: -------- --- /work/SRC/openSUSE:Factory/trytond/trytond.changes 2025-11-24 14:13:48.912946612 +0100 +++ /work/SRC/openSUSE:Factory/.trytond.new.1928/trytond.changes 2025-12-22 22:51:33.818768505 +0100 @@ -1,0 +2,5 @@ +Sun Dec 21 11:01:37 UTC 2025 - Axel Braun <[email protected]> + +- Version 7.0.42 - Bugfix Release + +------------------------------------------------------------------- Old: ---- trytond-7.0.40.tar.gz New: ---- trytond-7.0.42.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ trytond.spec ++++++ --- /var/tmp/diff_new_pack.GcQdH2/_old 2025-12-22 22:51:34.742806576 +0100 +++ /var/tmp/diff_new_pack.GcQdH2/_new 2025-12-22 22:51:34.742806576 +0100 @@ -30,7 +30,7 @@ ##%%endif Name: trytond -Version: %{majorver}.40 +Version: %{majorver}.42 Release: 0 Summary: An Enterprise Resource Planning (ERP) system License: GPL-3.0-or-later ++++++ trytond-7.0.40.tar.gz -> trytond-7.0.42.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/CHANGELOG new/trytond-7.0.42/CHANGELOG --- old/trytond-7.0.40/CHANGELOG 2025-11-21 01:26:52.000000000 +0100 +++ new/trytond-7.0.42/CHANGELOG 2025-12-20 21:10:33.000000000 +0100 @@ -1,4 +1,14 @@ +Version 7.0.42 - 2025-12-20 +--------------------------- +* Bug fixes (see mercurial logs for details) + + +Version 7.0.41 - 2025-12-17 +--------------------------- +* Bug fixes (see mercurial logs for details) + + Version 7.0.40 - 2025-11-21 --------------------------- * Bug fixes (see mercurial logs for details) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/PKG-INFO new/trytond-7.0.42/PKG-INFO --- old/trytond-7.0.40/PKG-INFO 2025-11-21 01:26:55.732554000 +0100 +++ new/trytond-7.0.42/PKG-INFO 2025-12-20 21:10:36.602672800 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: trytond -Version: 7.0.40 +Version: 7.0.42 Summary: Tryton server Home-page: http://www.tryton.org/ Download-URL: http://downloads.tryton.org/7.0/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/__init__.py new/trytond-7.0.42/trytond/__init__.py --- old/trytond-7.0.40/trytond/__init__.py 2025-11-20 10:32:38.000000000 +0100 +++ new/trytond-7.0.42/trytond/__init__.py 2025-12-17 19:11:29.000000000 +0100 @@ -13,7 +13,7 @@ except ImportError: requests_utils = None -__version__ = "7.0.40" +__version__ = "7.0.42" if not os.environ.get('TRYTOND_APPNAME'): os.environ['TRYTOND_APPNAME'] = os.path.basename( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/backend/postgresql/database.py new/trytond-7.0.42/trytond/backend/postgresql/database.py --- old/trytond-7.0.40/trytond/backend/postgresql/database.py 2025-10-03 17:10:37.000000000 +0200 +++ new/trytond-7.0.42/trytond/backend/postgresql/database.py 2025-12-14 20:18:28.000000000 +0100 @@ -416,27 +416,32 @@ return True def nextid(self, connection, table, count=1): + column = 'id' if not table.endswith('__history') else '__id' cursor = connection.cursor() cursor.execute( "SELECT nextval(pg_get_serial_sequence(format(%s, %s), %s)) " "FROM generate_series(1, %s)", - ('%I', table, 'id', count)) + ('%I', table, column, count)) if count == 1: return cursor.fetchone()[0] else: return [id for id, in cursor] def setnextid(self, connection, table, value): + if self.currid(connection, table) >= value: + return + column = 'id' if not table.endswith('__history') else '__id' cursor = connection.cursor() cursor.execute( "SELECT setval(pg_get_serial_sequence(format(%s, %s), %s), %s)", - ('%I', table, 'id', value)) + ('%I', table, column, value)) def currid(self, connection, table): + column = 'id' if not table.endswith('__history') else '__id' cursor = connection.cursor() cursor.execute( "SELECT pg_get_serial_sequence(format(%s, %s), %s)", - ('%I', table, 'id')) + ('%I', table, column)) sequence_name, = cursor.fetchone() cursor.execute(f"SELECT last_value FROM {sequence_name}") return cursor.fetchone()[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/ir/ui/view.py new/trytond-7.0.42/trytond/ir/ui/view.py --- old/trytond-7.0.40/trytond/ir/ui/view.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/ir/ui/view.py 2025-12-20 21:10:28.000000000 +0100 @@ -286,7 +286,7 @@ position = element.get('position', 'inside') new_tree = getattr(cls, '_inherit_apply_%s' % position)( tree, element, target) - if new_tree: + if new_tree is not None: tree = new_tree return tree diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/model/fields/one2many.py new/trytond-7.0.42/trytond/model/fields/one2many.py --- old/trytond-7.0.40/trytond/model/fields/one2many.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/model/fields/one2many.py 2025-12-14 20:18:28.000000000 +0100 @@ -347,10 +347,11 @@ where &= history_where if origin_where: where &= origin_where - if self.filter: - query = Target.search( - self.filter, order=[], query=True) - where &= origin.in_(query) + if self.filter or hasattr(Target, 'active'): + # Use an empty filter to apply the active test + filter_ = self.filter if self.filter else [] + query = Target.search(filter_, order=[], query=True) + where &= target.id.in_(query) query = target.select(origin, where=where) expression = ~table.id.in_(query) else: @@ -359,12 +360,13 @@ where &= history_where if origin_where: where &= origin_where - if self.filter: + if self.filter or hasattr(Target, 'active'): target_tables = { None: (target, None), } + filter_ = self.filter if self.filter else [] target_tables, clause = Target.search_domain( - self.filter, tables=target_tables) + filter_, tables=target_tables) where &= clause query_table = convert_from(None, target_tables) query = query_table.select(Literal(1), where=where) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/res/user.py new/trytond-7.0.42/trytond/res/user.py --- old/trytond-7.0.40/trytond/res/user.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/res/user.py 2025-12-14 17:59:10.000000000 +0100 @@ -633,16 +633,22 @@ ''' pool = Pool() UserGroup = pool.get('res.user-res.group') + Group = pool.get('res.group') + transaction = Transaction() user = transaction.user groups = cls._get_groups_cache.get(user) if groups is not None: return groups cursor = transaction.connection.cursor() + group = Group.__table__() user_group = UserGroup.user_group_all_table() - cursor.execute(*user_group.select( + cursor.execute(*user_group + .join(group, 'LEFT', user_group.group == group.id) + .select( user_group.group, - where=user_group.user == user, + where=((user_group.user == user) + & (group.active == Literal(True))), order_by=[user_group.group.asc])) groups = tuple(g for g, in cursor) cls._get_groups_cache.set(user, groups) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/tests/field_many2many.py new/trytond-7.0.42/trytond/tests/field_many2many.py --- old/trytond-7.0.40/trytond/tests/field_many2many.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/tests/field_many2many.py 2025-12-14 20:18:28.000000000 +0100 @@ -1,7 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -from trytond.model import ModelSQL, fields +from trytond.model import DeactivableMixin, ModelSQL, fields from trytond.pool import Pool from trytond.transaction import Transaction @@ -203,6 +203,51 @@ return context.get('test') +class Many2ManyActive(ModelSQL): + "Many2Many Active" + __name__ = 'test.many2many_active' + targets = fields.Many2Many( + 'test.many2many_active.relation', 'origin', 'target', 'Targets') + + +class Many2ManyTargetActive(DeactivableMixin, ModelSQL): + "Many2Many Target Active" + __name__ = 'test.many2many_active.target' + name = fields.Char('Name') + + +class Many2ManyRelationActive(ModelSQL): + "Many2Many Relation Active" + __name__ = 'test.many2many_active.relation' + origin = fields.Many2One('test.many2many_active', 'Origin') + target = fields.Many2One('test.many2many_active.target', 'Target') + + +class Many2ManyReferenceActive(ModelSQL): + "Many2Many Reference Active" + __name__ = 'test.many2many_reference.active' + targets = fields.Many2Many( + 'test.many2many_reference.active.relation', 'origin', 'target', + "Targets") + + +class Many2ManyReferenceActiveTarget(DeactivableMixin, ModelSQL): + "Many2Many Reference Active Target" + __name__ = 'test.many2many_reference.active.target' + name = fields.Char('Name') + + +class Many2ManyReferenceActiveRelation(ModelSQL): + "Many2Many Reference Active Relation" + __name__ = 'test.many2many_reference.active.relation' + origin = fields.Reference('Origin', [ + (None, ''), + ('test.many2many_reference.active', 'Many2Many Reference'), + ]) + target = fields.Many2One('test.many2many_reference.active.target', + 'Reference Target') + + def register(module): Pool.register( Many2Many, @@ -231,4 +276,10 @@ Many2ManyContext, Many2ManyContextTarget, Many2ManyContextRelation, + Many2ManyActive, + Many2ManyTargetActive, + Many2ManyRelationActive, + Many2ManyReferenceActive, + Many2ManyReferenceActiveRelation, + Many2ManyReferenceActiveTarget, module=module, type_='model') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/tests/field_one2many.py new/trytond-7.0.42/trytond/tests/field_one2many.py --- old/trytond-7.0.40/trytond/tests/field_one2many.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/tests/field_one2many.py 2025-12-14 20:18:28.000000000 +0100 @@ -1,7 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. -from trytond.model import ModelSQL, fields +from trytond.model import DeactivableMixin, ModelSQL, fields from trytond.pool import Pool from trytond.pyson import Eval from trytond.transaction import Transaction @@ -147,6 +147,37 @@ return context.get('test') +class One2ManyActive(ModelSQL): + "One2Many Active" + __name__ = 'test.one2many.active' + targets = fields.One2Many( + 'test.one2many.active_target', 'origin', "Targets") + + +class One2ManyActiveTarget(DeactivableMixin, ModelSQL): + "One2Many Active Target" + __name__ = 'test.one2many.active_target' + name = fields.Char('Name') + origin = fields.Many2One('test.one2many.active', "Origin") + + +class One2ManyActiveReference(ModelSQL): + "One2Many Active Reference" + __name__ = 'test.one2many_reference.active' + targets = fields.One2Many( + 'test.one2many_reference.active_target', 'origin', "Targets") + + +class One2ManyActiveReferenceTarget(DeactivableMixin, ModelSQL): + "One2Many Active Reference Target" + __name__ = 'test.one2many_reference.active_target' + name = fields.Char('Name') + origin = fields.Reference('Origin', [ + (None, ''), + ('test.one2many_reference.active', 'One2Many Reference'), + ]) + + def register(module): Pool.register( One2Many, @@ -167,4 +198,8 @@ One2ManyFilterDomainTarget, One2ManyContext, One2ManyContextTarget, + One2ManyActive, + One2ManyActiveTarget, + One2ManyActiveReference, + One2ManyActiveReferenceTarget, module=module, type_='model') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/tests/test_access.py new/trytond-7.0.42/trytond/tests/test_access.py --- old/trytond-7.0.40/trytond/tests/test_access.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/tests/test_access.py 2025-12-14 21:34:25.000000000 +0100 @@ -234,6 +234,56 @@ self._assert_raises(record) @with_transaction(context=_context) + def test_no_access_with_inactive_group(self): + "Test no access with inactive group" + pool = Pool() + Group = pool.get('res.group') + ModelAccess = pool.get('ir.model.access') + TestAccess = pool.get(self.model_name) + + inactive_group, = Group.create([{'name': 'Test', 'active': False}]) + record, = TestAccess.create([{}]) + ModelAccess.create([{ + 'model': self.model.id, + 'group': None, + self._perm: False, + }]) + ModelAccess.create([{ + 'model': self.model.id, + 'group': inactive_group.id, + self._perm: True, + }]) + + self._assert_raises(record) + + @with_transaction(context=_context) + def test_no_access_with_member_inactive_group(self): + "Test no access when member of an inactive group" + pool = Pool() + Group = pool.get('res.group') + ModelAccess = pool.get('ir.model.access') + TestAccess = pool.get(self.model_name) + + inactive_group, = Group.create([{ + 'name': 'Test', + 'active': False, + 'users': [('add', [Transaction().user])], + }]) + record, = TestAccess.create([{}]) + ModelAccess.create([{ + 'model': self.model.id, + 'group': None, + self._perm: False, + }]) + ModelAccess.create([{ + 'model': self.model.id, + 'group': inactive_group.id, + self._perm: True, + }]) + + self._assert_raises(record) + + @with_transaction(context=_context) def test_one_access_with_other_group_no_perm(self): "Test one access with other group no perm" pool = Pool() @@ -663,6 +713,58 @@ self._perm: True, }]) + self._assert_raises1(record) + self._assert2(record) + + @with_transaction(context=_context) + def test_no_access_with_inactive_group(self): + "Test no access with inactive group" + pool = Pool() + Group = pool.get('res.group') + FieldAccess = pool.get('ir.model.field.access') + TestAccess = pool.get('test.access') + + inactive_group, = Group.create([{'name': 'Test', 'active': False}]) + record, = TestAccess.create([{}]) + FieldAccess.create([{ + 'field': self.field1.id, + 'group': None, + self._perm: False, + }]) + FieldAccess.create([{ + 'field': self.field1.id, + 'group': inactive_group.id, + self._perm: True, + }]) + + self._assert_raises1(record) + self._assert2(record) + + @with_transaction(context=_context) + def test_no_access_with_member_inactive_group(self): + "Test no access when member of an inactive group" + pool = Pool() + Group = pool.get('res.group') + FieldAccess = pool.get('ir.model.field.access') + TestAccess = pool.get('test.access') + + inactive_group, = Group.create([{ + 'name': 'Test', + 'active': False, + 'users': [('add', [Transaction().user])], + }]) + record, = TestAccess.create([{}]) + FieldAccess.create([{ + 'field': self.field1.id, + 'group': None, + self._perm: False, + }]) + FieldAccess.create([{ + 'field': self.field1.id, + 'group': inactive_group.id, + self._perm: True, + }]) + self._assert_raises1(record) self._assert2(record) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/tests/test_field_many2many.py new/trytond-7.0.42/trytond/tests/test_field_many2many.py --- old/trytond-7.0.40/trytond/tests/test_field_many2many.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/tests/test_field_many2many.py 2025-12-14 20:18:28.000000000 +0100 @@ -101,6 +101,48 @@ self.assertListEqual(many2manys, [many2many1]) @with_transaction() + def test_search_equals_none_inactive(self): + "Test search many2many equals None when the target is inactive" + Many2Many = self.Many2ManyActive() + + many2many1, many2many2, many2many3 = Many2Many.create([{ + 'targets': [('create', [{'name': "Target"}])], + }, { + 'targets': [ + ('create', [{'name': "Target", 'active': False}]) + ], + }, { + 'targets': None, + }]) + + many2manys = Many2Many.search([ + ('targets', '=', None), + ]) + + self.assertListEqual(many2manys, [many2many3]) + + @with_transaction() + def test_search_non_equals_none_inactive(self): + "Test search many2many equals non None when the target is inactive" + Many2Many = self.Many2ManyActive() + + many2many1, many2many2, many2many3 = Many2Many.create([{ + 'targets': [('create', [{'name': "Target"}])], + }, { + 'targets': [ + ('create', [{'name': "Target", 'active': False}]) + ], + }, { + 'targets': None, + }]) + + many2manys = Many2Many.search([ + ('targets', '!=', None), + ]) + + self.assertListEqual(many2manys, [many2many1, many2many2]) + + @with_transaction() def test_search_non_equals_no_link(self): "Test search many2many non equals without link" Many2Many = self.Many2Many() @@ -387,6 +429,9 @@ def Many2ManyTarget(self): return Pool().get('test.many2many.target') + def Many2ManyActive(self): + return Pool().get('test.many2many_active') + @with_transaction() def test_create_required_with_value(self): "Test create many2many required with value" @@ -769,3 +814,6 @@ def Many2ManyTarget(self): return Pool().get('test.many2many_reference.target') + + def Many2ManyActive(self): + return Pool().get('test.many2many_reference.active') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond/tests/test_field_one2many.py new/trytond-7.0.42/trytond/tests/test_field_one2many.py --- old/trytond-7.0.40/trytond/tests/test_field_one2many.py 2025-09-22 21:34:39.000000000 +0200 +++ new/trytond-7.0.42/trytond/tests/test_field_one2many.py 2025-12-14 20:18:28.000000000 +0100 @@ -71,6 +71,46 @@ self.assertListEqual(one2manys, [one2many2]) @with_transaction() + def test_search_equals_none_inactive(self): + "Test search one2many equals None when the target is inactive" + One2Many = self.One2ManyActive() + one2many1, one2many2, one2many3 = One2Many.create([{ + 'targets': [('create', [{'name': "Target1"}])], + }, { + 'targets': [ + ('create', [{'name': "Target2", 'active': False}]), + ], + }, { + 'targets': None, + }]) + + one2manys = One2Many.search([ + ('targets', '=', None), + ]) + + self.assertEqual(one2manys, [one2many2, one2many3]) + + @with_transaction() + def test_search_not_equals_none_inactive(self): + "Test search one2many not equals None when the target is inactive" + One2Many = self.One2ManyActive() + one2many1, one2many2, one2many3 = One2Many.create([{ + 'targets': [('create', [{'name': "Target1"}])], + }, { + 'targets': [ + ('create', [{'name': "Target2", 'active': False}]), + ], + }, { + 'targets': None, + }]) + + one2manys = One2Many.search([ + ('targets', '!=', None), + ]) + + self.assertEqual(one2manys, [one2many1]) + + @with_transaction() def test_search_non_equals_none(self): "Test search one2many non equals None" One2Many = self.One2Many() @@ -464,6 +504,9 @@ def One2ManyTarget(self): return Pool().get('test.one2many.target') + def One2ManyActive(self): + return Pool().get('test.one2many.active') + @with_transaction() def test_create_required_with_value(self): "Test create one2many required with value" @@ -611,6 +654,21 @@ self.assertEqual(filtered_target.value, 3) @with_transaction() + def test_search_equals_filter(self): + "Test search one2many equals with filter" + One2Many = Pool().get('test.one2many_filter') + one2many, = One2Many.create([{ + 'targets': [('create', [{'value': 3}])], + }]) + + one2manys = One2Many.search([('targets', '=', None)]) + one2manys_filtered = One2Many.search( + [('filtered_targets', '=', None)]) + + self.assertListEqual(one2manys, []) + self.assertListEqual(one2manys_filtered, []) + + @with_transaction() def test_search_non_equals_filter(self): "Test search one2many non equals with filter" One2Many = Pool().get('test.one2many_filter') @@ -709,6 +767,9 @@ def One2ManyTarget(self): return Pool().get('test.one2many_reference.target') + def One2ManyActive(self): + return Pool().get('test.one2many_reference.active') + class FieldOne2ManyExistsTestCase(unittest.TestCase, SearchTestCaseMixin): "Test Field One2Many when using EXISTS" @@ -732,6 +793,9 @@ def One2ManyTarget(self): return Pool().get('test.one2many.target') + def One2ManyActive(self): + return Pool().get('test.one2many.active') + class FieldOne2ManyReferenceExistsTestCase( unittest.TestCase, SearchTestCaseMixin): @@ -756,5 +820,8 @@ def One2ManyTarget(self): return Pool().get('test.one2many_reference.target') + def One2ManyActive(self): + return Pool().get('test.one2many_reference.active') + def assert_strategy(self, query): self.assertIn('EXISTS', query) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/trytond-7.0.40/trytond.egg-info/PKG-INFO new/trytond-7.0.42/trytond.egg-info/PKG-INFO --- old/trytond-7.0.40/trytond.egg-info/PKG-INFO 2025-11-21 01:26:55.000000000 +0100 +++ new/trytond-7.0.42/trytond.egg-info/PKG-INFO 2025-12-20 21:10:35.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: trytond -Version: 7.0.40 +Version: 7.0.42 Summary: Tryton server Home-page: http://www.tryton.org/ Download-URL: http://downloads.tryton.org/7.0/
