[IMP] stock, mrp, purchase: default value for cancel propagation

cancelling propagation in a move chain was True be default. That means,
without any configuration, a cancel move will always cancel its next ones

This commit change the default to allow only cancelation of move chain
until the stock location. Here are 2 examples :
 1. Reception and delivery in 3 steps. The moves chain is the following:
    Vendor -> Input -> Quality -> Stock -> Pack -> Output -> Customer
  In case the Purchase order is cancelled, we want to move from Vendor to
  Stock are cancelled but not the ones from Stock.

  2. pbm + sam. The manufacturing process is the following;
    Stock -> Pre-prod -> Production -> Post-prod -> Stock
  cancelling the first move should cancelled until Production and not after

Task : 1913297
This commit is contained in:
Dhaval Panchal
2019-06-11 07:56:11 +00:00
committed by William Henrotin
parent 1ccca8d267
commit a580538e98
5 changed files with 68 additions and 9 deletions
+2 -3
View File
@@ -116,7 +116,8 @@ class StockWarehouse(models.Model):
'active': self.manufacture_to_resupply,
'name': self._format_rulename(location_id, False, 'Production'),
'location_id': location_id.id,
}
'propagate_cancel': self.manufacture_steps == 'pbm_sam'
},
},
'pbm_mto_pull_id': {
'depends': ['manufacture_steps', 'manufacture_to_resupply'],
@@ -125,7 +126,6 @@ class StockWarehouse(models.Model):
'company_id': self.company_id.id,
'action': 'pull',
'auto': 'manual',
'propagate_cancel': True,
'route_id': self._find_global_route('stock.route_warehouse0_mto', _('Make To Order')).id,
'name': self._format_rulename(self.lot_stock_id, self.pbm_loc_id, 'MTO'),
'location_id': self.pbm_loc_id.id,
@@ -149,7 +149,6 @@ class StockWarehouse(models.Model):
'company_id': self.company_id.id,
'action': 'pull',
'auto': 'manual',
'propagate_cancel': True,
'route_id': self._find_global_route('mrp.route_warehouse0_manufacture', _('Manufacture')).id,
'name': self._format_rulename(self.sam_loc_id, self.lot_stock_id, False),
'location_id': self.lot_stock_id.id,
@@ -203,3 +203,53 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
('picking_type_id', '=', self.warehouse.pick_type_id.id)
]).picking_id
self.assertEqual(picking_stock_pick.move_lines.move_orig_ids.picking_id, picking_stock_postprod)
def test_cancel_propagation(self):
""" Test cancelling moves in a 'picking before
manufacturing' and 'store after manufacturing' process. The propagation of
cancel depends on the default values on each rule of the chain.
"""
self.warehouse.manufacture_steps = 'pbm_sam'
self.env['stock.quant']._update_available_quantity(self.raw_product, self.warehouse.lot_stock_id, 4.0)
picking_customer = self.env['stock.picking'].create({
'location_id': self.warehouse.lot_stock_id.id,
'location_dest_id': self.customer_location,
'partner_id': self.env['ir.model.data'].xmlid_to_res_id('base.res_partner_4'),
'picking_type_id': self.warehouse.out_type_id.id,
})
self.env['stock.move'].create({
'name': self.finished_product.name,
'product_id': self.finished_product.id,
'product_uom_qty': 2,
'picking_id': picking_customer.id,
'product_uom': self.uom_unit.id,
'location_id': self.warehouse.lot_stock_id.id,
'location_dest_id': self.customer_location,
'procure_method': 'make_to_order',
})
picking_customer.action_confirm()
production_order = self.env['mrp.production'].search([('product_id', '=', self.finished_product.id)])
self.assertTrue(production_order)
move_stock_preprod = self.env['stock.move'].search([
('product_id', '=', self.raw_product.id),
('location_id', '=', self.warehouse.lot_stock_id.id),
('location_dest_id', '=', self.warehouse.pbm_loc_id.id),
('picking_type_id', '=', self.warehouse.pbm_type_id.id)
])
move_stock_postprod = self.env['stock.move'].search([
('product_id', '=', self.finished_product.id),
('location_id', '=', self.warehouse.sam_loc_id.id),
('location_dest_id', '=', self.warehouse.lot_stock_id.id),
('picking_type_id', '=', self.warehouse.sam_type_id.id)
])
self.assertTrue(move_stock_preprod)
self.assertTrue(move_stock_postprod)
self.assertEqual(move_stock_preprod.state, 'confirmed')
self.assertEqual(move_stock_postprod.state, 'waiting')
move_stock_preprod._action_cancel()
self.assertEquals(production_order.state, 'confirmed')
production_order.action_cancel()
self.assertTrue(move_stock_postprod.state, 'cancel')
@@ -70,7 +70,6 @@ class StockWarehouse(models.Model):
'company_id': self.company_id.id,
'action': 'pull',
'auto': 'manual',
'propagate_cancel': True,
'route_id': self._find_global_route('stock.route_warehouse0_mto', _('Make To Order')).id,
'name': self._format_rulename(self.lot_stock_id, subcontract_location_id, 'MTO'),
'location_id': subcontract_location_id.id,
@@ -88,7 +87,6 @@ class StockWarehouse(models.Model):
'company_id': self.company_id.id,
'action': 'pull',
'auto': 'manual',
'propagate_cancel': True,
'route_id': self._find_global_route('mrp_subcontracting.route_resupply_subcontractor_mto',
_('Resupply Subcontractor on Order')).id,
'name': self._format_rulename(self.lot_stock_id, subcontract_location_id, False),
+3 -1
View File
@@ -119,12 +119,14 @@ class StockWarehouse(models.Model):
'picking_type_id': self.in_type_id.id,
'group_propagation_option': 'none',
'company_id': self.company_id.id,
'route_id': self._find_global_route('purchase_stock.route_warehouse0_buy', _('Buy')).id
'route_id': self._find_global_route('purchase_stock.route_warehouse0_buy', _('Buy')).id,
'propagate_cancel': self.reception_steps != 'one_step',
},
'update_values': {
'active': self.buy_to_resupply,
'name': self._format_rulename(location_id, False, 'Buy'),
'location_id': location_id.id,
'propagate_cancel': self.reception_steps != 'one_step',
}
}
})
+13 -3
View File
@@ -338,7 +338,6 @@ class Warehouse(models.Model):
'company_id': self.company_id.id,
'action': 'pull',
'auto': 'manual',
'propagate_cancel': True,
'route_id': self._find_global_route('stock.route_warehouse0_mto', _('Make To Order')).id
},
'update_values': {
@@ -434,7 +433,8 @@ class Warehouse(models.Model):
},
'rules_values': {
'active': True,
'procure_method': 'make_to_order'
'procure_method': 'make_to_order',
'propagate_cancel': True,
}
},
'delivery_route_id': {
@@ -675,11 +675,21 @@ class Warehouse(models.Model):
'procure_method': first_rule and 'make_to_stock' or 'make_to_order',
'warehouse_id': self.id,
'company_id': self.company_id.id,
'propagate_cancel': routing.picking_type != self.pick_type_id,
}
route_rule_values.update(values or {})
rules_list.append(route_rule_values)
first_rule = False
if values.get('propagate_cancel') and rules_list:
# In case of rules chain with cancel propagation set, we need to stop
# the cancellation for the last step in order to avoid cancelling
# any other move after the chain.
# Example: In the following flow:
# Input -> Quality check -> Stock -> Customer
# We want that cancelling I->GC cancel QC -> S but not S -> C
# which means:
# Input -> Quality check should have propagate_cancel = True
# Quality check -> Stock should have propagate_cancel = False
rules_list[-1]['propagate_cancel'] = False
return rules_list
def _get_supply_pull_rules_values(self, route_values, values=None):