Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions stock_ux/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,34 @@ def _trigger_assign(self):
return super().with_context(trigger_assign=True)._trigger_assign()
return super()._trigger_assign()

def _prepare_procurement_values(self):
values = super()._prepare_procurement_values()
physical_warehouse = self.location_id.warehouse_id
propagated_warehouse = values.get("warehouse_id")
is_subcontracting_move = (
"raw_material_production_id" in self._fields
and "subcontractor_id" in self.raw_material_production_id._fields
and bool(self.raw_material_production_id.subcontractor_id)
)

# In some multi-warehouse MTO chains the move keeps the commercial
# warehouse in `warehouse_id` even when the real source location belongs
# to another warehouse. If we propagate that stale warehouse to the next
# procurement, Odoo may reuse a draft RFQ from the wrong warehouse and
# end up mixing destinations across warehouses in the same PO.
# Scope the correction to MTO moves only so other procurement flows can
# keep their intentional warehouse propagation.
if (
self.procure_method == "make_to_order"
and not is_subcontracting_move
and physical_warehouse
and propagated_warehouse
and propagated_warehouse != physical_warehouse
):
values["warehouse_id"] = physical_warehouse

return values

@api.ondelete(at_uninstall=False)
def _unlink_if_not_from_order(self):
"""
Expand Down
1 change: 1 addition & 0 deletions stock_ux/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_mto_warehouse_propagation
56 changes: 56 additions & 0 deletions stock_ux/tests/test_mto_warehouse_propagation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from odoo.addons.stock.tests.common import TestStockCommon
from odoo.tests import tagged


@tagged("stock_ux_mto")
class TestMtoWarehousePropagation(TestStockCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.warehouse_2 = cls.env["stock.warehouse"].create(
{
"name": "Secondary Warehouse",
"code": "SWH",
"company_id": cls.env.company.id,
"partner_id": cls.env.company.partner_id.id,
"reception_steps": "one_step",
"delivery_steps": "ship_only",
}
)
cls.customer_location_rec = cls.env["stock.location"].browse(cls.customer_location)

def test_prepare_procurement_values_uses_physical_warehouse_for_mto(self):
move = self._create_move(
self.productA,
self.warehouse_2.lot_stock_id,
self.customer_location_rec,
picking_type_id=self.warehouse_1.out_type_id.id,
procure_method="make_to_order",
warehouse_id=self.warehouse_1.id,
)

values = move._prepare_procurement_values()

self.assertEqual(
values["warehouse_id"],
self.warehouse_2,
"MTO procurements must use the physical warehouse of the source location.",
)

def test_prepare_procurement_values_keeps_non_mto_warehouse(self):
move = self._create_move(
self.productA,
self.warehouse_2.lot_stock_id,
self.customer_location_rec,
picking_type_id=self.warehouse_1.out_type_id.id,
procure_method="make_to_stock",
warehouse_id=self.warehouse_1.id,
)

values = move._prepare_procurement_values()

self.assertEqual(
values["warehouse_id"],
self.warehouse_1,
"Non-MTO procurements should keep their propagated warehouse untouched.",
)
Loading