diff --git a/addons/mrp_subcontracting/models/stock_move.py b/addons/mrp_subcontracting/models/stock_move.py index 5492302a221..87f2b3ef3d6 100644 --- a/addons/mrp_subcontracting/models/stock_move.py +++ b/addons/mrp_subcontracting/models/stock_move.py @@ -320,3 +320,12 @@ class StockMove(models.Model): if self.env.user.has_group('base.group_portal') and not self.env.su: if vals.get('state') == 'done': raise AccessError(_("Portal users cannot create a stock move with a state 'Done' or change the current state to 'Done'.")) + + def _is_subcontract_return(self): + self.ensure_one() + subcontracting_location = self.picking_id.partner_id.with_company(self.company_id).property_stock_subcontractor + return ( + not self.is_subcontract + and self.origin_returned_move_id.is_subcontract + and self.location_dest_id.id == subcontracting_location.id + ) diff --git a/addons/mrp_subcontracting_purchase/models/__init__.py b/addons/mrp_subcontracting_purchase/models/__init__.py index 6576bfb375b..59cbd6c77d3 100644 --- a/addons/mrp_subcontracting_purchase/models/__init__.py +++ b/addons/mrp_subcontracting_purchase/models/__init__.py @@ -3,6 +3,7 @@ from . import account_move_line from . import purchase_order +from . import stock_move from . import stock_picking from . import stock_rule from . import stock_valuation_layer diff --git a/addons/mrp_subcontracting_purchase/models/stock_move.py b/addons/mrp_subcontracting_purchase/models/stock_move.py new file mode 100644 index 00000000000..2fd9b630007 --- /dev/null +++ b/addons/mrp_subcontracting_purchase/models/stock_move.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class StockMove(models.Model): + _inherit = 'stock.move' + + def _is_purchase_return(self): + res = super()._is_purchase_return() + return res or self._is_subcontract_return() diff --git a/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py index f255094108d..b29548e5589 100644 --- a/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py +++ b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py @@ -251,6 +251,54 @@ class MrpSubcontractingPurchaseTest(TestMrpSubcontractingCommon): self.assertTrue(orderpoint) self.assertEqual(orderpoint.warehouse_id, self.warehouse) + def test_purchase_and_return03(self): + """ + With 2 steps receipt and an input location child of Physical Location (instead of WH) + The user buys 10 x a subcontracted product P. He receives the 10 + products and then does a return with 3 x P. The test ensures that the + final received quantity is correctly computed + """ + # Set 2 steps receipt + self.warehouse.write({"reception_steps": "two_steps"}) + # Set 'Input' parent location to 'Physical locations' + physical_locations = self.env.ref("stock.stock_location_locations") + input_location = self.warehouse.wh_input_stock_loc_id + input_location.write({"location_id": physical_locations.id}) + + # Create Purchase + po = self.env['purchase.order'].create({ + 'partner_id': self.subcontractor_partner1.id, + 'order_line': [(0, 0, { + 'name': self.finished2.name, + 'product_id': self.finished2.id, + 'product_uom_qty': 10, + 'product_uom': self.finished2.uom_id.id, + 'price_unit': 1, + })], + }) + po.button_confirm() + + # Receive Products + receipt = po.picking_ids + receipt.move_lines.quantity_done = 10 + receipt.button_validate() + + self.assertEqual(po.order_line.qty_received, 10.0) + + # Return Products + return_form = Form(self.env['stock.return.picking'].with_context(active_id=receipt.id, active_model='stock.picking')) + with return_form.product_return_moves.edit(0) as line: + line.quantity = 3 + line.to_refund = True + return_wizard = return_form.save() + return_id, _ = return_wizard._create_returns() + + return_picking = self.env['stock.picking'].browse(return_id) + return_picking.move_lines.quantity_done = 3 + return_picking.button_validate() + + self.assertEqual(po.order_line.qty_received, 7.0) + def test_subcontracting_resupply_price_diff(self): """Test that the price difference is correctly computed when a subcontracted product is resupplied. diff --git a/addons/purchase_stock/models/stock_move.py b/addons/purchase_stock/models/stock_move.py index b65e7b3a81b..5859b998376 100644 --- a/addons/purchase_stock/models/stock_move.py +++ b/addons/purchase_stock/models/stock_move.py @@ -201,12 +201,7 @@ class StockMove(models.Model): def _is_purchase_return(self): self.ensure_one() - return self.location_dest_id.usage == "supplier" or ( - self.location_dest_id.usage == "internal" - and self.location_id.usage != "supplier" - and self.warehouse_id - and self.location_dest_id not in self.env["stock.location"].search([("id", "child_of", self.warehouse_id.view_location_id.id)]) - ) + return self.location_dest_id.usage == "supplier" def _get_all_related_aml(self): # The back and for between account_move and account_move_line is necessary to catch the