diff --git a/addons/mrp/views/stock_picking_views.xml b/addons/mrp/views/stock_picking_views.xml
index 7f2f8612502..f211caf3105 100644
--- a/addons/mrp/views/stock_picking_views.xml
+++ b/addons/mrp/views/stock_picking_views.xml
@@ -109,6 +109,9 @@
+
+ {"invisible": [("code", "=", "mrp_operation")]}
+
diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py
index 4ace4e4f4f5..2bdaaff386a 100644
--- a/addons/point_of_sale/models/pos_order.py
+++ b/addons/point_of_sale/models/pos_order.py
@@ -506,7 +506,7 @@ class PosOrder(models.Model):
'lot_id': lot_id,
})
if not pack_lots and not float_is_zero(qty_done, precision_rounding=move.product_uom.rounding):
- if len(move.move_line_ids) < 2:
+ if len(move._get_move_lines()) < 2:
move.quantity_done = qty_done
else:
move._set_quantity_done(qty_done)
diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py
index fbb309fd089..c251d0ac163 100644
--- a/addons/stock/models/stock_move.py
+++ b/addons/stock/models/stock_move.py
@@ -135,6 +135,7 @@ class StockMove(models.Model):
picking_type_id = fields.Many2one('stock.picking.type', 'Operation Type')
inventory_id = fields.Many2one('stock.inventory', 'Inventory')
move_line_ids = fields.One2many('stock.move.line', 'move_id')
+ move_line_nosuggest_ids = fields.One2many('stock.move.line', 'move_id', domain=[('product_qty', '=', 0.0)])
origin_returned_move_id = fields.Many2one('stock.move', 'Origin return move', copy=False, help='Move that created the return move')
returned_move_ids = fields.One2many('stock.move', 'origin_returned_move_id', 'All returned moves', help='Optional: all returned moves created from this move')
reserved_availability = fields.Float(
@@ -258,7 +259,13 @@ class StockMove(models.Model):
move.product_qty = move.product_uom._compute_quantity(
move.product_uom_qty, move.product_id.uom_id, rounding_method=rounding_method)
- @api.depends('move_line_ids.qty_done', 'move_line_ids.product_uom_id')
+ def _get_move_lines(self):
+ """ This will return the move lines to consider when applying _quantity_done_compute on a stock.move.
+ In some context, such as MRP, it is necessary to compute quantity_done on filtered sock.move.line."""
+ self.ensure_one()
+ return self.move_line_ids or self.move_line_nosuggest_ids
+
+ @api.depends('move_line_ids.qty_done', 'move_line_ids.product_uom_id', 'move_line_nosuggest_ids.qty_done')
def _quantity_done_compute(self):
""" This field represents the sum of the move lines `qty_done`. It allows the user to know
if there is still work to do.
@@ -270,14 +277,14 @@ class StockMove(models.Model):
"""
for move in self:
quantity_done = 0
- for move_line in move.move_line_ids:
+ for move_line in move._get_move_lines():
quantity_done += move_line.product_uom_id._compute_quantity(move_line.qty_done, move.product_uom, round=False)
move.quantity_done = quantity_done
def _quantity_done_set(self):
quantity_done = self[0].quantity_done # any call to create will invalidate `move.quantity_done`
for move in self:
- move_lines = move.move_line_ids
+ move_lines = move._get_move_lines()
if not move_lines:
if quantity_done:
# do not impact reservation here
@@ -504,7 +511,14 @@ class StockMove(models.Model):
"""
self.ensure_one()
- view = self.env.ref('stock.view_stock_move_operations')
+ # If "show suggestions" is not checked on the picking type, we have to filter out the
+ # reserved move lines. We do this by displaying `move_line_nosuggest_ids`. We use
+ # different views to display one field or another so that the webclient doesn't have to
+ # fetch both.
+ if self.picking_id.picking_type_id.show_reserved:
+ view = self.env.ref('stock.view_stock_move_operations')
+ else:
+ view = self.env.ref('stock.view_stock_move_nosuggest_operations')
picking_type_id = self.picking_type_id or self.picking_id.picking_type_id
return {
diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py
index b6d3ca552ab..41ede9c0c26 100644
--- a/addons/stock/models/stock_picking.py
+++ b/addons/stock/models/stock_picking.py
@@ -51,6 +51,8 @@ class PickingType(models.Model):
show_operations = fields.Boolean(
'Show Detailed Operations', default=_default_show_operations,
help="If this checkbox is ticked, the pickings lines will represent detailed stock operations. If not, the picking lines will represent an aggregate of detailed stock operations.")
+ show_reserved = fields.Boolean(
+ 'Show Reserved', default=True, help="If this checkbox is ticked, Odoo will show which products are reserved (lot/serial number, source location, source package).")
# Statistics for the kanban view
count_picking_draft = fields.Integer(compute='_compute_picking_count')
@@ -122,6 +124,11 @@ class PickingType(models.Model):
'stock.group_tracking_lot'
)
+ @api.onchange('show_operations')
+ def onchange_show_operations(self):
+ if self.show_operations is True:
+ self.show_reserved = True
+
def _get_action(self, action_xmlid):
action = self.env.ref(action_xmlid).read()[0]
if self:
diff --git a/addons/stock/views/stock_move_views.xml b/addons/stock/views/stock_move_views.xml
index c35a90961c9..e1d4cd806f8 100644
--- a/addons/stock/views/stock_move_views.xml
+++ b/addons/stock/views/stock_move_views.xml
@@ -212,6 +212,19 @@
+
+ stock.move.operations.nosuggest.form
+ stock.move
+ 1000
+ primary
+
+
+
+
+
+
+
+
stock.move.line.operations.tree
stock.move.line
diff --git a/addons/stock/views/stock_picking_views.xml b/addons/stock/views/stock_picking_views.xml
index 2154c22da70..5e426fcf455 100644
--- a/addons/stock/views/stock_picking_views.xml
+++ b/addons/stock/views/stock_picking_views.xml
@@ -48,6 +48,7 @@
+