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.
+
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