[FIX] mrp_subcontracting_purchase: fix received_qty with return move

Method _is_purchase_return had a complex check intended to detect
subcontract return move. This Check would incorrectly pass for
subcontract move when the destination location (input) does not belong
to the customer warehouse.

To fix this issue, we can check the field StockMove.is_subcontract,
however this field is only available if mrp_subcontracting is installed.
Furthermore, the check itself make no sens in purchase_stock if the
module mrp_subcontracting is not install Hence, we can move this check
to mrp_subcontracting_purchase.

With Purchase & Mrp Subcontracting installed:
- Create Component C, consumable
- Create Product P, storable, Set Vendor V under Purchase Tab
- Create BOM for P, subcontracted with Vendor V, and C as component
- In the Warehouse, set 2 steps reception
- Set Input parent location to 'Physical Location'
- Create PO to vendor V, product P, confirm, receive Product
=> Received Qty for P in PO show 0

OPW-3216011

X-original-commit: bf666d33af4ac32563e159cb6e79483d6f37b3d6
Part-of: odoo/odoo#147344
This commit is contained in:
David (dafr)
2024-01-15 11:11:23 +00:00
parent d0704a19de
commit 5e51ab1f4e
5 changed files with 71 additions and 6 deletions
@@ -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
)
@@ -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
@@ -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()
@@ -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.
+1 -6
View File
@@ -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