[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:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user