From 406102a32953e5e001d2c6d5d2c422575afa0c51 Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Fri, 11 Aug 2023 09:33:09 +0000 Subject: [PATCH] [FIX] repair: clean default keys from context before creating stock.move MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Create a storable product “P1” - Create a Transfer: - Operation type: delivery order - Product: “P1” - Validate the delivery - Create a return of the delivery: - Confirm and validate the return - Create a repair order from the delivery - Set the product “P1” - Confirm, start and end the repair Problem: A stock move is created when the repair is completed, but it's linked to the return picking what is wrong. When a 'repair' order is created, the 'default_picking_id' is passed into the context to be set in the 'repair.order'. Consequently, when the repair is completed and the stock move is created, the context isn't cleared, leading to the utilization of the 'default_picking_id': https://github.com/odoo/odoo/blob/5d25900cd88ebc1fd16b0bd6ebba4602a13e9d76/addons/stock/models/stock_move.py#L317 In the button, no context is passed as a parameter: https://github.com/odoo/odoo/blob/86aa7b78aadee5747c93b4bd27046cfaed1e438d/addons/repair/views/repair_views.xml#L36 opw-3269813 closes odoo/odoo#135939 X-original-commit: 558c647d5c70f7729c663ec3d45fb0cae813db04 Signed-off-by: William Henrotin (whe) Signed-off-by: Djamel Touati (otd) --- addons/repair/models/repair.py | 5 +++- addons/repair/tests/test_repair.py | 46 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/addons/repair/models/repair.py b/addons/repair/models/repair.py index 9c168567cd4..c8b47ef2493 100644 --- a/addons/repair/models/repair.py +++ b/addons/repair/models/repair.py @@ -4,7 +4,7 @@ from random import randint from odoo import api, Command, fields, models, _ from odoo.exceptions import UserError, ValidationError -from odoo.tools import float_compare, float_is_zero +from odoo.tools import float_compare, float_is_zero, clean_context from odoo.tools.misc import format_date, groupby MAP_REPAIR_TO_PICKING_LOCATIONS = { @@ -377,6 +377,9 @@ class Repair(models.Model): Writes repair order state to 'Repaired'. @return: True """ + # Clean the context to get rid of residual default_* keys that could cause issues + # during the creation of stock.move. + self = self.with_context(clean_context(self._context)) self._check_product_tracking() precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') diff --git a/addons/repair/tests/test_repair.py b/addons/repair/tests/test_repair.py index 130c71adb58..6a851ab578f 100644 --- a/addons/repair/tests/test_repair.py +++ b/addons/repair/tests/test_repair.py @@ -493,3 +493,49 @@ class TestRepair(common.TransactionCase): repair.action_create_sale_order() self.assertEqual(repair.sale_order_id.order_line.product_id, self.product_product_11) self.assertEqual(repair.sale_order_id.order_line.purchase_price, 10) + + def test_repair_from_return(self): + """ + create a repair order from a return delivery and ensure that the stock.move + resulting from the repair is not associated with the return picking. + """ + + product = self.env['product.product'].create({ + 'name': 'Test Product', + 'type': 'product', + }) + self.env['stock.quant']._update_available_quantity(product, self.stock_location_14, 1) + picking_form = Form(self.env['stock.picking']) + #create a delivery order + picking_form.picking_type_id = self.stock_warehouse.out_type_id + picking_form.partner_id = self.res_partner_1 + with picking_form.move_ids_without_package.new() as move: + move.product_id = product + move.product_uom_qty = 1.0 + picking = picking_form.save() + picking.action_confirm() + picking.action_assign() + res_dict = picking.button_validate() + wizard = Form(self.env[res_dict['res_model']].with_context(res_dict['context'])).save() + wizard.process() + self.assertEqual(picking.state, 'done') + # Create a return + stock_return_picking_form = Form(self.env['stock.return.picking'] + .with_context(active_ids=picking.ids, active_id=picking.ids[0], + active_model='stock.picking')) + stock_return_picking = stock_return_picking_form.save() + stock_return_picking.product_return_moves.quantity = 1.0 + stock_return_picking_action = stock_return_picking.create_returns() + return_picking = self.env['stock.picking'].browse(stock_return_picking_action['res_id']) + return_picking.action_set_quantities_to_reservation() + return_picking.button_validate() + self.assertEqual(return_picking.state, 'done') + + res_dict = return_picking.action_repair_return() + repair_form = Form(self.env[(res_dict.get('res_model'))].with_context(res_dict['context'])) + repair_form.product_id = product + repair = repair_form.save() + repair.action_repair_start() + repair.action_repair_end() + self.assertEqual(repair.state, 'done') + self.assertEqual(len(return_picking.move_ids), 1)