diff --git a/modules/purchase/CHANGELOG b/modules/purchase/CHANGELOG index 3316b68938..8c3c61e7de 100644 --- a/modules/purchase/CHANGELOG +++ b/modules/purchase/CHANGELOG @@ -1,3 +1,4 @@ +* Add warning when receiving too much goods from purchase * Require unit price only for confirmed purchase * Do not invoice non purchase line * Rename UOM to Unit for product supplier diff --git a/modules/purchase/exceptions.py b/modules/purchase/exceptions.py index 0ec373886c..4114784c3a 100644 --- a/modules/purchase/exceptions.py +++ b/modules/purchase/exceptions.py @@ -13,5 +13,9 @@ class PurchaseQuotationError(ValidationError): pass +class PurchaseMoveQuantity(UserWarning): + pass + + class PartyLocationError(UserError): pass diff --git a/modules/purchase/message.xml b/modules/purchase/message.xml index a2ffa0e3df..491811d86e 100644 --- a/modules/purchase/message.xml +++ b/modules/purchase/message.xml @@ -27,6 +27,9 @@ this repository contains the full copyright notices and license terms. --> To delete line "%(line)s" you must cancel or reset to draft purchase "%(purchase)s". + + The purchase line "%(line)s" is moving %(extra)s in addition to the %(quantity)s ordered. + To modify the header of purchase "%(purchase)s", it must be in draft state. diff --git a/modules/purchase/purchase.py b/modules/purchase/purchase.py index 90926e4321..c00b5ab8b5 100644 --- a/modules/purchase/purchase.py +++ b/modules/purchase/purchase.py @@ -30,7 +30,8 @@ from trytond.transaction import Transaction from trytond.wizard import ( Button, StateAction, StateTransition, StateView, Wizard) -from .exceptions import PartyLocationError, PurchaseQuotationError +from .exceptions import ( + PartyLocationError, PurchaseMoveQuantity, PurchaseQuotationError) def get_shipments_returns(model_name): @@ -1805,6 +1806,27 @@ class Line(sequence_ordered(), ModelSQL, ModelView): move.unit, move.quantity, self.unit) return quantity + def check_move_quantity(self): + pool = Pool() + Lang = pool.get('ir.lang') + Warning = pool.get('res.user.warning') + lang = Lang.get() + move_type = 'in' if self.quantity >= 0 else 'return' + quantity = ( + self._get_move_quantity(move_type) + - self._get_shipped_quantity(move_type)) + if quantity < 0: + warning_name = Warning.format( + 'check_move_quantity', [self]) + if Warning.check(warning_name): + raise PurchaseMoveQuantity(warning_name, gettext( + 'purchase.msg_purchase_line_move_quantity', + line=self.rec_name, + extra=lang.format_number_symbol( + -quantity, self.unit), + quantity=lang.format_number_symbol( + self.quantity, self.unit))) + def _get_move_invoice_lines(self, move_type): 'Return the invoice lines that should be shipped' if self.purchase.invoice_method in {'order', 'manual'}: diff --git a/modules/purchase/stock.py b/modules/purchase/stock.py index 93d02e39b7..3b6652bea3 100644 --- a/modules/purchase/stock.py +++ b/modules/purchase/stock.py @@ -68,6 +68,12 @@ class ShipmentIn(metaclass=PoolMeta): @Workflow.transition('received') @process_purchase('incoming_moves') def receive(cls, shipments): + pool = Pool() + PurchaseLine = pool.get('purchase.line') + for shipment in shipments: + for move in shipment.incoming_moves: + if isinstance(move.origin, PurchaseLine): + move.origin.check_move_quantity() super(ShipmentIn, cls).receive(shipments) @classmethod