diff --git a/addons/sale_stock/tests/test_sale_stock.py b/addons/sale_stock/tests/test_sale_stock.py index 2857f3caf6f..2b6679a2868 100644 --- a/addons/sale_stock/tests/test_sale_stock.py +++ b/addons/sale_stock/tests/test_sale_stock.py @@ -279,6 +279,10 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): wizard = Form(self.env[(res_dict.get('res_model'))].with_context(res_dict['context'])).save() wizard.process_cancel_backorder() + #Check Exception error is logged on SO + activity = self.env['mail.activity'].search([('res_id', '=', self.so.id), ('res_model', '=', 'sale.order')]) + self.assertEqual(len(activity), 1, 'When no backorder is created for a partial delivery, a warning error should be logged in its origin SO') + # Check quantity delivered del_qty = sum(sol.qty_delivered for sol in self.so.order_line) self.assertEqual(del_qty, 4.0, 'Sale Stock: delivered quantity should be 4.0 after partial delivery') @@ -1408,3 +1412,30 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon): ]) self.assertEqual(ship01.move_ids.move_orig_ids, (pick01 | pick02).move_ids) self.assertEqual(ship02.move_ids.move_orig_ids, (pick01 | pick02).move_ids) + + def test_exception_delivery_partial_multi(self): + """ + When a backorder is cancelled for a picking in multi-picking, + the related SO should have an exception logged + """ + #Create 2 sale orders + so_1 = self._get_new_sale_order() + so_1.action_confirm() + picking_1 = so_1.picking_ids + picking_1.move_ids.write({'quantity_done': 1}) + + so_2 = self._get_new_sale_order() + so_2.action_confirm() + picking_2 = so_2.picking_ids + picking_2.move_ids.write({'quantity_done': 2}) + + #multi-picking validation + pick = picking_1 | picking_2 + res_dict = pick.button_validate() + wizard = Form(self.env[(res_dict.get('res_model'))].with_context(res_dict['context'])).save() + wizard.backorder_confirmation_line_ids[1].write({'to_backorder': False}) + wizard.process() + + #Check Exception error is logged on so_2 + activity = self.env['mail.activity'].search([('res_id', '=', so_2.id), ('res_model', '=', 'sale.order')]) + self.assertEqual(len(activity), 1, 'When no backorder is created for a partial delivery, a warning error should be logged in its origin SO') diff --git a/addons/stock/wizard/stock_backorder_confirmation.py b/addons/stock/wizard/stock_backorder_confirmation.py index 0fc5491e41f..755ac27256b 100644 --- a/addons/stock/wizard/stock_backorder_confirmation.py +++ b/addons/stock/wizard/stock_backorder_confirmation.py @@ -37,6 +37,16 @@ class StockBackorderConfirmation(models.TransientModel): # because of webclient limitations return res + def _check_less_quantities_than_expected(self, pickings): + for pick_id in pickings: + moves_to_log = {} + for move in pick_id.move_ids: + if float_compare(move.product_uom_qty, + move.quantity_done, + precision_rounding=move.product_uom.rounding) > 0: + moves_to_log[move] = (move.quantity_done, move.product_uom_qty) + pick_id._log_less_quantities_than_expected(moves_to_log) + def process(self): pickings_to_do = self.env['stock.picking'] pickings_not_to_do = self.env['stock.picking'] @@ -46,28 +56,21 @@ class StockBackorderConfirmation(models.TransientModel): else: pickings_not_to_do |= line.picking_id - for pick_id in pickings_not_to_do: - moves_to_log = {} - for move in pick_id.move_ids: - if float_compare(move.product_uom_qty, - move.quantity_done, - precision_rounding=move.product_uom.rounding) > 0: - moves_to_log[move] = (move.quantity_done, move.product_uom_qty) - pick_id._log_less_quantities_than_expected(moves_to_log) - pickings_to_validate = self.env.context.get('button_validate_picking_ids') if pickings_to_validate: pickings_to_validate = self.env['stock.picking'].browse(pickings_to_validate).with_context(skip_backorder=True) if pickings_not_to_do: + self._check_less_quantities_than_expected(pickings_not_to_do) pickings_to_validate = pickings_to_validate.with_context(picking_ids_not_to_backorder=pickings_not_to_do.ids) return pickings_to_validate.button_validate() return True def process_cancel_backorder(self): - pickings_to_validate = self.env.context.get('button_validate_picking_ids') - if pickings_to_validate: - return self.env['stock.picking']\ - .browse(pickings_to_validate)\ - .with_context(skip_backorder=True, picking_ids_not_to_backorder=pickings_to_validate)\ + pickings_to_validate_ids = self.env.context.get('button_validate_picking_ids') + if pickings_to_validate_ids: + pickings_to_validate = self.env['stock.picking'].browse(pickings_to_validate_ids) + self._check_less_quantities_than_expected(pickings_to_validate) + return pickings_to_validate\ + .with_context(skip_backorder=True, picking_ids_not_to_backorder=self.pick_ids.ids)\ .button_validate() return True