diff --git a/addons/mrp/report/report_stock_forecasted.xml b/addons/mrp/report/report_stock_forecasted.xml index 89e86af793e..01a60762706 100644 --- a/addons/mrp/report/report_stock_forecasted.xml +++ b/addons/mrp/report/report_stock_forecasted.xml @@ -15,11 +15,19 @@ Unreserve + + + + Reserve + - Inventory On Hand + Inventory On Hand + + Reserve + + Free Stock Not Available diff --git a/addons/stock/static/src/js/report_stock_forecasted.js b/addons/stock/static/src/js/report_stock_forecasted.js index bf9ed314372..017fb1e5332 100644 --- a/addons/stock/static/src/js/report_stock_forecasted.js +++ b/addons/stock/static/src/js/report_stock_forecasted.js @@ -227,6 +227,7 @@ const ReplenishReport = clientAction.extend({ rr.on('mouseenter', '.o_report_replenish_change_priority', this._onMouseEnterPriority.bind(this)); rr.on('mouseleave', '.o_report_replenish_change_priority', this._onMouseLeavePriority.bind(this)); rr.on('click', '.o_report_replenish_unreserve', this._onClickUnreserve.bind(this)); + rr.on('click', '.o_report_replenish_reserve', this._onClickReserve.bind(this)); }, //-------------------------------------------------------------------------- @@ -316,13 +317,26 @@ const ReplenishReport = clientAction.extend({ _onClickUnreserve: function(ev) { const model = ev.target.getAttribute('model'); const modelId = parseInt(ev.target.getAttribute('model-id')); - this._rpc( { - model: model, + return this._rpc( { + model, args: [[modelId]], method: 'do_unreserve' - }).then((result) => { - return this._reloadReport(); - }); + }).then(() => this._reloadReport()); + }, + + /** + * Reserve the specified model/id, then reload this report. + * + * @returns {Promise} + */ + _onClickReserve: function(ev) { + const model = ev.target.getAttribute('model'); + const modelId = parseInt(ev.target.getAttribute('model-id')); + return this._rpc( { + model, + args: [[modelId]], + method: 'action_assign' + }).then(() => this._reloadReport()); } }); diff --git a/addons/stock/tests/test_move2.py b/addons/stock/tests/test_move2.py index 98f464573a5..ed1cfec15d3 100644 --- a/addons/stock/tests/test_move2.py +++ b/addons/stock/tests/test_move2.py @@ -3138,6 +3138,7 @@ class TestAutoAssign(TestStockCommon): 4. Check that only the correct outgoing pickings are auto_assigned 5. Additionally check that auto-assignment at confirmation correctly works when products are in stock Note, default reservation method is expected to be covered by other tests. + Also check reservation_dates are as expected """ stock_location = self.env['stock.location'].browse(self.stock_location) @@ -3168,7 +3169,7 @@ class TestAutoAssign(TestStockCommon): # 'by_date' picking w/ 10 days before scheduled date auto-assign setting, set to 5 days in advance => should auto-assign customer_picking3 = customer_picking2.copy({'name': "Delivery 3", 'picking_type_id': picking_type_out3.id}) customer_picking4 = customer_picking3.copy({'name': "Delivery 4", 'picking_type_id': picking_type_out3.id}) - + # 'at_confirm' picking customer_picking5 = customer_picking1.copy({'name': "Delivery 5", 'picking_type_id': picking_type_out4.id}) # create their associated moves (needs to be in form view so compute functions properly trigger) @@ -3209,6 +3210,11 @@ class TestAutoAssign(TestStockCommon): self.assertEqual(customer_picking2.move_lines.reserved_availability, 0, "There should be no products available to reserve yet.") self.assertEqual(customer_picking3.move_lines.reserved_availability, 0, "There should be no products available to reserve yet.") + self.assertFalse(customer_picking1.move_lines.reservation_date, "Reservation Method: 'manual' shouldn't have a reservation_date") + self.assertEqual(customer_picking2.move_lines.reservation_date, (customer_picking2.scheduled_date - timedelta(days=1)).date(), + "Reservation Method: 'by_date' should have a reservation_date = scheduled_date - reservation_days_before") + self.assertFalse(customer_picking5.move_lines.reservation_date, "Reservation Method: 'at_confirm' shouldn't have a reservation_date until confirmed") + # create supplier picking and move supplier_picking = self.env['stock.picking'].create({ 'location_id': self.customer_location, @@ -3232,10 +3238,10 @@ class TestAutoAssign(TestStockCommon): self.assertEqual(customer_picking3.move_lines.reserved_availability, 10, "Reservation Method: 'by_date' should auto-assign when within reservation date range") self.assertEqual(self.env['stock.quant']._get_available_quantity(self.productA, stock_location), 40) - customer_picking4.action_assign() - customer_picking5.action_assign() - self.assertEqual(customer_picking4.move_lines.reserved_availability, 10, "Reservation Method: 'at_confirm' should auto-assign at confirmation") - self.assertEqual(customer_picking5.move_lines.reserved_availability, 10, "Reservation Method: 'by_date' should auto-assign when within reservation date range at confirmation") + customer_picking4.action_confirm() + customer_picking5.action_confirm() + self.assertEqual(customer_picking4.move_lines.reserved_availability, 10, "Reservation Method: 'by_date' should auto-assign when within reservation date range at confirmation") + self.assertEqual(customer_picking5.move_lines.reserved_availability, 10, "Reservation Method: 'at_confirm' should auto-assign at confirmation") def test_serial_lot_ids(self): self.stock_location = self.env.ref('stock.stock_location_stock') diff --git a/addons/stock/views/stock_picking_views.xml b/addons/stock/views/stock_picking_views.xml index 7d167b721f1..700ff8c2990 100644 --- a/addons/stock/views/stock_picking_views.xml +++ b/addons/stock/views/stock_picking_views.xml @@ -44,10 +44,11 @@ - - - - days + + + + days before/ + days before when starred