details:   https://code.tryton.org/tryton/commit/9cf089215d53
branch:    default
user:      Maxime Richez <[email protected]>
date:      Mon Oct 05 12:54:17 2026 +0200
description:
        Allow draft and staging moves to be created and modified in the closed 
period

        Closes #15056
diffstat:

 modules/stock/move.py                         |  14 ++++++++++----
 modules/stock/tests/scenario_stock_period.rst |  14 ++++++++++++--
 modules/stock/tests/test_module.py            |  26 --------------------------
 3 files changed, 22 insertions(+), 32 deletions(-)

diffs (112 lines):

diff -r 41ca943f0f6b -r 9cf089215d53 modules/stock/move.py
--- a/modules/stock/move.py     Sun Oct 04 16:48:54 2026 +0200
+++ b/modules/stock/move.py     Mon Oct 05 12:54:17 2026 +0200
@@ -724,9 +724,15 @@
 
     @classmethod
     @without_check_access
-    def check_period_closed(cls, moves):
-        Period = Pool().get('stock.period')
-        for company, moves in groupby(moves, lambda m: m.company):
+    def check_period_closed(cls, moves, state=None):
+        pool = Pool()
+        Period = pool.get('stock.period')
+
+        def exclude_draft_staging(move):
+            return (state if state else move.state) not in {'draft', 'staging'}
+
+        for company, moves in groupby(
+                filter(exclude_draft_staging, moves), lambda m: m.company):
             periods = Period.search([
                     ('state', '=', 'closed'),
                     ('company', '=', company.id),
@@ -1068,7 +1074,7 @@
             cls.check_period_closed(moves)
         elif mode == 'write':
             if values.keys() - cls._allow_modify_closed_period:
-                cls.check_period_closed(moves)
+                cls.check_period_closed(moves, state=values.get('state'))
             if values.keys() & cls._deny_modify_assigned:
                 for move in moves:
                     if move.state == 'assigned':
diff -r 41ca943f0f6b -r 9cf089215d53 
modules/stock/tests/scenario_stock_period.rst
--- a/modules/stock/tests/scenario_stock_period.rst     Sun Oct 04 16:48:54 
2026 +0200
+++ b/modules/stock/tests/scenario_stock_period.rst     Mon Oct 05 12:54:17 
2026 +0200
@@ -71,7 +71,7 @@
     >>> period, = Period.find([])
     >>> assertEqual(period.state, 'closed')
 
-Try to create a move::
+Create a draft move in closed period::
 
     >>> move = Move()
     >>> move.product = product
@@ -82,6 +82,17 @@
     >>> move.unit_price = Decimal('42.0000')
     >>> move.currency = currency
     >>> move.save()
+
+Update draft move in closed period::
+
+    >>> move.quantity = 2
+    >>> move.save()
+
+Try to update a draft move in closed period::
+
+    >>> Move.write(
+    ...     [move], {'state': 'assigned'},
+    ...     {**config._context, '_check_access': False})
     Traceback (most recent call last):
         ...
     AccessError: ...
@@ -94,7 +105,6 @@
 
 Close the period with draft move::
 
-    >>> move.save()
     >>> period.click('close')
     >>> period.state
     'closed'
diff -r 41ca943f0f6b -r 9cf089215d53 modules/stock/tests/test_module.py
--- a/modules/stock/tests/test_module.py        Sun Oct 04 16:48:54 2026 +0200
+++ b/modules/stock/tests/test_module.py        Mon Oct 05 12:54:17 2026 +0200
@@ -8,7 +8,6 @@
 
 from dateutil.relativedelta import relativedelta
 
-from trytond.model.exceptions import AccessError
 from trytond.modules.company.tests import (
     CompanyTestMixin, PartyCompanyCheckEraseMixin, create_company, set_company)
 from trytond.modules.party.tests import PartyCheckReplaceMixin
@@ -974,31 +973,6 @@
                         }])
             Move.do(moves)
 
-            self.assertRaises(AccessError, Move.create, [{
-                        'product': product.id,
-                        'unit': unit.id,
-                        'quantity': 10,
-                        'from_location': supplier.id,
-                        'to_location': storage.id,
-                        'planned_date': today + relativedelta(days=-5),
-                        'effective_date': today + relativedelta(days=-5),
-                        'company': company.id,
-                        'unit_price': Decimal('1'),
-                        'currency': currency.id,
-                        }])
-            self.assertRaises(AccessError, Move.create, [{
-                        'product': product.id,
-                        'unit': unit.id,
-                        'quantity': 10,
-                        'from_location': supplier.id,
-                        'to_location': storage.id,
-                        'planned_date': today + relativedelta(days=-3),
-                        'effective_date': today + relativedelta(days=-3),
-                        'company': company.id,
-                        'unit_price': Decimal('1'),
-                        'currency': currency.id,
-                        }])
-
             # Test close period check
             period, = Period.create([{
                         'date': today,

Reply via email to