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