[FIX] stock: duplicating warehouse dependencies

Before this commit when duplicating a warehouse, its operation types (picking.type)
wouldn't get copied. This commit ensures that new picking.types are created for
the duplicate warehouse.

[Reproduce]
- run odoo 17 with -i stock,mrp_subcontracting
- in Inventory/Configuration/Warehouses Duplicate a Warehouse
- Bug: in  Inventory/Configuration/OperationTypes picking types aren't duplicated
opw-3674614

closes odoo/odoo#151769

Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
Andrzej(pian)
2024-03-05 12:46:09 +00:00
parent a69c944789
commit c8dd587c28
6 changed files with 60 additions and 23 deletions
+5 -5
View File
@@ -13,13 +13,13 @@ class StockWarehouse(models.Model):
'Manufacture to Resupply', default=True,
help="When products are manufactured, they can be manufactured in this warehouse.")
manufacture_pull_id = fields.Many2one(
'stock.rule', 'Manufacture Rule')
'stock.rule', 'Manufacture Rule', copy=False)
manufacture_mto_pull_id = fields.Many2one(
'stock.rule', 'Manufacture MTO Rule')
'stock.rule', 'Manufacture MTO Rule', copy=False)
pbm_mto_pull_id = fields.Many2one(
'stock.rule', 'Picking Before Manufacturing MTO Rule')
'stock.rule', 'Picking Before Manufacturing MTO Rule', copy=False)
sam_rule_id = fields.Many2one(
'stock.rule', 'Stock After Manufacturing Rule')
'stock.rule', 'Stock After Manufacturing Rule', copy=False)
manu_type_id = fields.Many2one(
'stock.picking.type', 'Manufacturing Operation Type',
domain="[('code', '=', 'mrp_operation'), ('company_id', '=', company_id)]", check_company=True)
@@ -37,7 +37,7 @@ class StockWarehouse(models.Model):
the components from the Stock to Input location first, and then\
transfer it to the Production location.")
pbm_route_id = fields.Many2one('stock.route', 'Picking Before Manufacturing Route', ondelete='restrict')
pbm_route_id = fields.Many2one('stock.route', 'Picking Before Manufacturing Route', ondelete='restrict', copy=False)
pbm_loc_id = fields.Many2one('stock.location', 'Picking before Manufacturing Location', check_company=True)
sam_loc_id = fields.Many2one('stock.location', 'Stock after Manufacturing Location', check_company=True)
@@ -10,19 +10,19 @@ class StockWarehouse(models.Model):
subcontracting_to_resupply = fields.Boolean(
'Resupply Subcontractors', default=True)
subcontracting_mto_pull_id = fields.Many2one(
'stock.rule', 'Subcontracting MTO Rule')
'stock.rule', 'Subcontracting MTO Rule', copy=False)
subcontracting_pull_id = fields.Many2one(
'stock.rule', 'Subcontracting MTS Rule'
'stock.rule', 'Subcontracting MTS Rule', copy=False
)
subcontracting_route_id = fields.Many2one('stock.route', 'Resupply Subcontractor', ondelete='restrict')
subcontracting_route_id = fields.Many2one('stock.route', 'Resupply Subcontractor', ondelete='restrict', copy=False)
subcontracting_type_id = fields.Many2one(
'stock.picking.type', 'Subcontracting Operation Type',
domain=[('code', '=', 'mrp_operation')])
domain=[('code', '=', 'mrp_operation')], copy=False)
subcontracting_resupply_type_id = fields.Many2one(
'stock.picking.type', 'Subcontracting Resupply Operation Type',
domain=[('code', '=', 'outgoing')])
domain=[('code', '=', 'outgoing')], copy=False)
@api.model_create_multi
def create(self, vals_list):
@@ -21,6 +21,43 @@ class TestSubcontractingBasic(TransactionCase):
self.assertTrue(company2.subcontracting_location_id)
self.assertTrue(self.env.company.subcontracting_location_id != company2.subcontracting_location_id)
def test_duplicating_warehouses_recreates_their_routes_and_operation_types(self):
""" Duplicating a warehouse should result in the creation of new routes and operation types.
Not reusing the existing routes and operation types"""
wh_original = self.env['stock.warehouse'].search([], limit=1)
wh_copy = wh_original.copy(default={'name': 'Dummy Warehouse (copy)', 'code': 'Dummy'})
# Check if warehouse routes got RECREATED (instead of reused)
route_types = [
"route_ids",
"pbm_route_id",
"subcontracting_route_id",
"crossdock_route_id",
"reception_route_id",
"delivery_route_id"
]
for route_type in route_types:
original_route_set = wh_original[route_type]
copy_route_set = wh_copy[route_type]
error_message = f"At least one {route_type} (route) got reused on duplication (should have been recreated)"
self.assertEqual(len(original_route_set & copy_route_set), 0, error_message)
# Check if warehouse operation types (picking.type) got RECREATED (instead of reused)
operation_types = [
"subcontracting_type_id",
"subcontracting_resupply_type_id",
"pick_type_id",
"pack_type_id",
"out_type_id",
"in_type_id",
"int_type_id"
]
for operation_type in operation_types:
original_type_set = wh_original[operation_type]
copy_type_set = wh_copy[operation_type]
error_message = f"At least one {operation_type} (operation_type) got reused on duplication (should have been recreated)"
self.assertEqual(len(original_type_set & copy_type_set), 0, error_message)
@tagged('post_install', '-at_install')
class TestSubcontractingFlows(TestMrpSubcontractingCommon):
@@ -12,7 +12,7 @@ class StockWarehouse(models.Model):
help="Dropship subcontractors with components")
subcontracting_dropshipping_pull_id = fields.Many2one(
'stock.rule', 'Subcontracting-Dropshipping MTS Rule'
'stock.rule', 'Subcontracting-Dropshipping MTS Rule', copy=False
)
@api.model_create_multi
+1 -1
View File
@@ -19,7 +19,7 @@ class StockWarehouse(models.Model):
buy_to_resupply = fields.Boolean('Buy to Resupply', default=True,
help="When products are bought, they can be delivered to this warehouse")
buy_pull_id = fields.Many2one('stock.rule', 'Buy rule')
buy_pull_id = fields.Many2one('stock.rule', 'Buy rule', copy=False)
def _generate_global_route_rules_values(self):
rules = super()._generate_global_route_rules_values()
+11 -11
View File
@@ -53,7 +53,7 @@ class Warehouse(models.Model):
'stock.route', 'stock_route_warehouse', 'warehouse_id', 'route_id',
'Routes',
domain="[('warehouse_selectable', '=', True), '|', ('company_id', '=', False), ('company_id', '=', company_id)]",
help='Defaults routes through the warehouse', check_company=True)
help='Defaults routes through the warehouse', check_company=True, copy=False)
reception_steps = fields.Selection([
('one_step', 'Receive goods directly (1 step)'),
('two_steps', 'Receive goods in input and then stock (2 steps)'),
@@ -70,21 +70,21 @@ class Warehouse(models.Model):
wh_qc_stock_loc_id = fields.Many2one('stock.location', 'Quality Control Location', check_company=True)
wh_output_stock_loc_id = fields.Many2one('stock.location', 'Output Location', check_company=True)
wh_pack_stock_loc_id = fields.Many2one('stock.location', 'Packing Location', check_company=True)
mto_pull_id = fields.Many2one('stock.rule', 'MTO rule')
pick_type_id = fields.Many2one('stock.picking.type', 'Pick Type', check_company=True)
pack_type_id = fields.Many2one('stock.picking.type', 'Pack Type', check_company=True)
out_type_id = fields.Many2one('stock.picking.type', 'Out Type', check_company=True)
in_type_id = fields.Many2one('stock.picking.type', 'In Type', check_company=True)
int_type_id = fields.Many2one('stock.picking.type', 'Internal Type', check_company=True)
crossdock_route_id = fields.Many2one('stock.route', 'Crossdock Route', ondelete='restrict')
reception_route_id = fields.Many2one('stock.route', 'Receipt Route', ondelete='restrict')
delivery_route_id = fields.Many2one('stock.route', 'Delivery Route', ondelete='restrict')
mto_pull_id = fields.Many2one('stock.rule', 'MTO rule', copy=False)
pick_type_id = fields.Many2one('stock.picking.type', 'Pick Type', check_company=True, copy=False)
pack_type_id = fields.Many2one('stock.picking.type', 'Pack Type', check_company=True, copy=False)
out_type_id = fields.Many2one('stock.picking.type', 'Out Type', check_company=True, copy=False)
in_type_id = fields.Many2one('stock.picking.type', 'In Type', check_company=True, copy=False)
int_type_id = fields.Many2one('stock.picking.type', 'Internal Type', check_company=True, copy=False)
crossdock_route_id = fields.Many2one('stock.route', 'Crossdock Route', ondelete='restrict', copy=False)
reception_route_id = fields.Many2one('stock.route', 'Receipt Route', ondelete='restrict', copy=False)
delivery_route_id = fields.Many2one('stock.route', 'Delivery Route', ondelete='restrict', copy=False)
resupply_wh_ids = fields.Many2many(
'stock.warehouse', 'stock_wh_resupply_table', 'supplied_wh_id', 'supplier_wh_id',
'Resupply From', help="Routes will be created automatically to resupply this warehouse from the warehouses ticked")
resupply_route_ids = fields.One2many(
'stock.route', 'supplied_wh_id', 'Resupply Routes',
help="Routes will be created for these resupply warehouses and you can select them on products and product categories")
help="Routes will be created for these resupply warehouses and you can select them on products and product categories", copy=False)
sequence = fields.Integer(default=10,
help="Gives the sequence of this line when displaying the warehouses.")
_sql_constraints = [