From 0486e2e58ab75c7f6d3ab7d65fba9467216b1468 Mon Sep 17 00:00:00 2001 From: "Adrien Widart (awt)" <awt@odoo.com> Date: Mon, 7 Nov 2022 13:54:19 +0000 Subject: [PATCH] [FIX] mrp_subcontracting_dropshipping: return to stock location When returning a dropshipped and subcontracted product to an internal location, the received quantity of the PO line will be incorrect To reproduce the issue: 1. In Settings, enable "Storage Locations" 2. Create two storable products P_compo, P_Finished 3. Create a BoM: - Product: P_finished - Type: Subcontracting - Subcontractors: a subcontractor S - Components: 1 x P_compo 4. In Locations, edit WH/Stock: - Return location: True 5. Create and confirm a PO: - Vendor: S - Deliver To: Dropship - Drop Ship Address: a partner P - Products: 1 x P_finished 6. Validate the receipt 7. Create a return with 1 x P_finished: - Update SO/PO quantities: True - Return Location: WH/Stock 8. Validate the return 9. Go back to the PO Error: The qty received is 2, it should be 1 (it should not be 0 since the product has been returned to an internal location) In `/purchase_stock._compute_qty_received`, there is already a code to anticipate such a situation (i.e., a user who returns a dropshipped product to his stock location): https://github.com/odoo/odoo/blob/bf3c398f0644f690c64815b2b6e298aed7bedd70/addons/purchase_stock/models/purchase.py#L300-L305 However, the methods `_is_dropshipped` and `_is_dropshipped_returned` do not include the feature subcontracting + dropshipping. This is the reason why, in `_compute_qty_received`, the above condition is not respected and why we add the return stock move to the received qty. OPW-3030895 Part-of: odoo/odoo#105185 --- .../models/__init__.py | 1 + .../models/stock_move.py | 24 +++++++++++++++++++ .../tests/test_purchase_subcontracting.py | 18 +++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 addons/mrp_subcontracting_dropshipping/models/stock_move.py diff --git a/addons/mrp_subcontracting_dropshipping/models/__init__.py b/addons/mrp_subcontracting_dropshipping/models/__init__.py index ac9517445aee..b8548572ee3f 100644 --- a/addons/mrp_subcontracting_dropshipping/models/__init__.py +++ b/addons/mrp_subcontracting_dropshipping/models/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import stock_move from . import stock_picking diff --git a/addons/mrp_subcontracting_dropshipping/models/stock_move.py b/addons/mrp_subcontracting_dropshipping/models/stock_move.py new file mode 100644 index 000000000000..fd507f22b192 --- /dev/null +++ b/addons/mrp_subcontracting_dropshipping/models/stock_move.py @@ -0,0 +1,24 @@ +# -*- 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_dropshipped(self): + res = super()._is_dropshipped() + return res or ( + self.partner_id.property_stock_subcontractor.parent_path + and self.partner_id.property_stock_subcontractor.parent_path in self.location_id.parent_path + and self.location_dest_id.usage == 'customer' + ) + + def _is_dropshipped_returned(self): + res = super()._is_dropshipped_returned() + return res or ( + self.location_id.usage == 'customer' + and self.partner_id.property_stock_subcontractor.parent_path + and self.partner_id.property_stock_subcontractor.parent_path in self.location_dest_id.parent_path + ) diff --git a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py index 9145bbbd7649..5d7e0d485e60 100644 --- a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py +++ b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py @@ -138,7 +138,8 @@ class TestSubcontractingDropshippingFlows(TestMrpSubcontractingCommon): def test_po_to_customer(self): """ Create and confirm a PO with a subcontracted move. The picking type of - the PO is 'Dropship' and the delivery address a customer. + the PO is 'Dropship' and the delivery address a customer. Then, process + a return with the stock location as destination """ subcontractor, client = self.env['res.partner'].create([ {'name': 'SuperSubcontractor'}, @@ -193,6 +194,21 @@ class TestSubcontractingDropshippingFlows(TestMrpSubcontractingCommon): self.assertEqual(mo.state, 'done') self.assertEqual(po.order_line.qty_received, 1) + stock_location = self.warehouse.lot_stock_id + stock_location.return_location = True + return_form = Form(self.env['stock.return.picking'].with_context(active_ids=delivery.ids, active_id=delivery.id, active_model='stock.picking')) + return_form.location_id = stock_location + return_wizard = return_form.save() + return_picking_id, _pick_type_id = return_wizard._create_returns() + + delivery_return = self.env['stock.picking'].browse(return_picking_id) + delivery_return.move_line_ids.qty_done = 1.0 + delivery_return.button_validate() + + self.assertEqual(delivery_return.state, 'done') + self.assertEqual(p_finished.qty_available, 1, 'One product has been returned to the stock location, so it should be available') + self.assertEqual(po.order_line.qty_received, 1, 'One product has been returned to the stock location, so we should still consider it as received') + def test_po_to_subcontractor(self): """ Create and confirm a PO with a subcontracted move. The bought product is -- GitLab