Prevent doing moves in the future

issue9355
review327351002
This commit is contained in:
Sergi Almacellas Abellana
2020-10-04 23:57:37 +02:00
parent c539c5c42b
commit 90f34e0f37
6 changed files with 108 additions and 1 deletions
+1
View File
@@ -1,3 +1,4 @@
* Add warning to prevent move in the future
* Add relate to open inventory lines
* Use simplified view for moves list on shipments
* Add a relate from product to its moves
+4
View File
@@ -28,5 +28,9 @@ class MoveOriginWarning(UserWarning):
pass
class MoveFutureWarning(UserWarning):
pass
class ProductCostPriceError(ValidationError):
pass
+3
View File
@@ -86,5 +86,8 @@ because the type does not support moves and location has existing moves.</field>
<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">
<field name="text">The moves "%(moves)s" have effective dates in the future.</field>
</record>
</data>
</tryton>
+24 -1
View File
@@ -21,7 +21,7 @@ from trytond.pool import Pool
from trytond.modules.product import price_digits, round_price
from .exceptions import MoveOriginWarning
from .exceptions import MoveOriginWarning, MoveFutureWarning
STATES = {
'readonly': Eval('state').in_(['cancelled', 'assigned', 'done']),
@@ -616,6 +616,29 @@ class Move(Workflow, ModelSQL, ModelView):
def do(cls, moves):
pool = Pool()
Product = pool.get('product.product')
Date = pool.get('ir.date')
Warning = pool.get('res.user.warning')
today_cache = {}
def in_future(move):
if move.company not in today_cache:
with Transaction().set_context(company=move.company.id):
today_cache[move.company] = Date.today()
today = today_cache[move.company]
if move.effective_date and move.effective_date > today:
return move
future_moves = list(filter(in_future, moves))
if future_moves:
names = ', '.join(m.rec_name for m in future_moves[:5])
if len(future_moves) > 5:
names += '...'
warning_name = (
'%s.effective_date_future' % hashlib.md5(
str(future_moves).encode('utf-8')).hexdigest())
if Warning.check(warning_name):
raise MoveFutureWarning(warning_name,
gettext('stock.msg_effective_date_in_the_future',
moves=names))
def set_cost_values(cost_values):
Value = Product.multivalue_model('cost_price')
+71
View File
@@ -0,0 +1,71 @@
=============================
Stock Move In Future Scenario
=============================
Imports::
>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import (
... create_company, get_company)
>>> today = datetime.date.today()
>>> tomorrow = today + relativedelta(days=1)
Activate modules::
>>> config = activate_modules('stock')
Create company::
>>> _ = create_company()
>>> company = get_company()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
>>> Product = Model.get('product.product')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('20')
>>> template.save()
>>> product, = template.products
>>> product.cost_price = Decimal('1')
>>> product.save()
Get stock locations::
>>> Location = Model.get('stock.location')
>>> supplier_loc, = Location.find([('code', '=', 'SUP')])
>>> storage_loc, = Location.find([('code', '=', 'STO')])
A warning is raised when doing a move in the future::
>>> Move = Model.get('stock.move')
>>> move = Move()
>>> move.product = product
>>> move.quantity = 1
>>> move.from_location = supplier_loc
>>> move.to_location = storage_loc
>>> move.currency = company.currency
>>> move.effective_date = tomorrow
>>> move.quantity = 2
>>> move.unit_price = Decimal('1')
>>> move.save()
>>> move.click('do') # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
MoveFutureWarning: ...
But it can be done for today::
>>> move.effective_date = today
>>> move.click('do')
>>> move.state
'done'
+5
View File
@@ -1552,4 +1552,9 @@ def suite():
tearDown=doctest_teardown, encoding='utf-8',
checker=doctest_checker,
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
suite.addTests(doctest.DocFileSuite(
'scenario_stock_move_in_future.rst',
tearDown=doctest_teardown, encoding='utf-8',
checker=doctest_checker,
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite