changeset 002b02df04b2 in modules/stock:default details: https://hg.tryton.org/modules/stock?cmd=changeset;node=002b02df04b2 description: Manage move in future at inventory level
As the inventory creates and do the moves in the same transaction, the warning about effective date in future can not be ignored (the ids change). Also the warning name should be based on an ordered list of record to ensure to generate always the same name. issue9707 review328441002 diffstat: exceptions.py | 4 ++++ inventory.py | 36 +++++++++++++++++++++++++++++++++--- message.xml | 5 ++++- move.py | 6 +++--- 4 files changed, 44 insertions(+), 7 deletions(-) diffs (125 lines): diff -r 21b09ae49100 -r 002b02df04b2 exceptions.py --- a/exceptions.py Mon Oct 12 19:20:33 2020 +0200 +++ b/exceptions.py Mon Oct 12 20:31:27 2020 +0200 @@ -32,5 +32,9 @@ pass +class InventoryFutureWarning(UserWarning): + pass + + class ProductCostPriceError(ValidationError): pass diff -r 21b09ae49100 -r 002b02df04b2 inventory.py --- a/inventory.py Mon Oct 12 19:20:33 2020 +0200 +++ b/inventory.py Mon Oct 12 20:31:27 2020 +0200 @@ -1,5 +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. +import hashlib + from sql import Null from trytond.i18n import gettext @@ -10,7 +12,8 @@ from trytond.pool import Pool from trytond.wizard import Wizard, StateView, StateTransition, Button -from .exceptions import InventoryValidationError, InventoryCountWarning +from .exceptions import ( + InventoryValidationError, InventoryCountWarning, InventoryFutureWarning) class Inventory(Workflow, ModelSQL, ModelView): @@ -145,7 +148,32 @@ @ModelView.button @Workflow.transition('done') def confirm(cls, inventories): - Move = Pool().get('stock.move') + pool = Pool() + Move = pool.get('stock.move') + Date = pool.get('ir.date') + Warning = pool.get('res.user.warning') + today_cache = {} + + def in_future(inventory): + if inventory.company not in today_cache: + with Transaction().set_context(company=inventory.company.id): + today_cache[inventory.company] = Date.today() + today = today_cache[inventory.company] + if inventory.date > today: + return inventory + future_inventories = sorted(filter(in_future, inventories)) + if future_inventories: + names = ', '.join(i.rec_name for i in future_inventories[:5]) + if len(future_inventories) > 5: + names + '...' + warning_name = ( + '%s.date_future' % hashlib.md5( + str(future_inventories).encode('utf-8')).hexdigest()) + if Warning.check(warning_name): + raise InventoryFutureWarning(warning_name, + gettext('stock.msg_inventory_date_in_the_future', + inventories=names)) + moves = [] for inventory in inventories: keys = set() @@ -162,7 +190,9 @@ moves.append(move) if moves: Move.save(moves) - Move.do(moves) + # Skip MoveFutureWarning as it is newly created moves + with Transaction().set_user(0): + Move.do(moves) @classmethod @ModelView.button diff -r 21b09ae49100 -r 002b02df04b2 message.xml --- a/message.xml Mon Oct 12 19:20:33 2020 +0200 +++ b/message.xml Mon Oct 12 20:31:27 2020 +0200 @@ -86,8 +86,11 @@ <record model="ir.message" id="msg_move_from_to_location"> <field name="text">The source and destination of stock move must be different.</field> </record> - <record model="ir.message" id="msg_effective_date_in_the_future"> + <record model="ir.message" id="msg_move_effective_date_in_the_future"> <field name="text">The moves "%(moves)s" have effective dates in the future.</field> </record> + <record model="ir.message" id="msg_inventory_date_in_the_future"> + <field name="text">The inventories "%(inventories)s" have dates in the future.</field> + </record> </data> </tryton> diff -r 21b09ae49100 -r 002b02df04b2 move.py --- a/move.py Mon Oct 12 19:20:33 2020 +0200 +++ b/move.py Mon Oct 12 20:31:27 2020 +0200 @@ -627,7 +627,7 @@ today = today_cache[move.company] if move.effective_date and move.effective_date > today: return move - future_moves = list(filter(in_future, moves)) + future_moves = sorted(filter(in_future, moves)) if future_moves: names = ', '.join(m.rec_name for m in future_moves[:5]) if len(future_moves) > 5: @@ -637,7 +637,7 @@ str(future_moves).encode('utf-8')).hexdigest()) if Warning.check(warning_name): raise MoveFutureWarning(warning_name, - gettext('stock.msg_effective_date_in_the_future', + gettext('stock.msg_move_effective_date_in_the_future', moves=names)) def set_cost_values(cost_values): @@ -842,7 +842,7 @@ return ((move.from_location.type in types) ^ (move.to_location.type in types) and not move.origin) - moves = list(filter(no_origin, moves)) + moves = sorted(filter(no_origin, moves)) if moves: names = ', '.join(m.rec_name for m in moves[:5]) if len(moves) > 5: