From 101eaecb89d6c5205beb401bd6dc6e032bdd2d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 27 Mar 2018 10:51:36 +0200 Subject: [PATCH] Check no stock move also on Product As fields can be redefined on Product, we must check both Models. issue7253 review41981002 --- product.py | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/product.py b/product.py index 25f83b263d..d2cd38fd7a 100644 --- a/product.py +++ b/product.py @@ -1,6 +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 datetime +import functools from decimal import Decimal from collections import defaultdict @@ -25,6 +26,43 @@ __all__ = ['Template', 'Product', 'RecomputeCostPrice'] +def check_no_move(func): + + def find_moves(cls, records): + pool = Pool() + Move = pool.get('stock.move') + if cls.__name__ == 'product.template': + field = 'product.template' + else: + field = 'product' + for sub_records in grouped_slice(records): + moves = Move.search([ + (field, 'in', map(int, sub_records)), + ], + limit=1, order=[]) + if moves: + return True + return False + + @functools.wraps(func) + def decorator(cls, *args): + pool = Pool() + Template = pool.get('product.template') + transaction = Transaction() + if (transaction.user != 0 + and transaction.context.get('_check_access')): + actions = iter(args) + for records, values in zip(actions, actions): + for field, error in Template._modify_no_move: + if field in values: + if find_moves(cls, records): + Template.raise_user_error(error) + # No moves for those records + break + func(cls, *args) + return decorator + + class Template: __metaclass__ = PoolMeta __name__ = "product.template" @@ -61,26 +99,8 @@ class Template: ] @classmethod - def check_no_move(cls, templates, error): - Move = Pool().get('stock.move') - for sub_templates in grouped_slice(templates): - moves = Move.search([ - ('product.template', 'in', [t.id for t in sub_templates]), - ], - limit=1, order=[]) - if moves: - cls.raise_user_error(error) - - @classmethod + @check_no_move def write(cls, *args): - if (Transaction().user != 0 - and Transaction().context.get('_check_access')): - actions = iter(args) - for templates, values in zip(actions, actions): - for field, error in cls._modify_no_move: - if field in values: - cls.check_no_move(templates, error) - break super(Template, cls).write(*args) @classmethod @@ -133,6 +153,11 @@ class Product(StockMixin, object): * product.cost_price) return cost_values + @classmethod + @check_no_move + def write(cls, *args): + super(Product, cls).write(*args) + @classmethod def products_by_location(cls, location_ids, with_childs=False, grouping=('product',), grouping_filter=None):