[FIX] mrp_subcontracting: cancel a PO should cancel delivery

When subcontracting a product via a purchase order and not a simple
receipt. Then the cancelation of the receipt will not only cancel
the receipt of the finished product but not the delivery for the
components.

It happens because button_cancel on purchase order will call
_action_cancel the stock.move linked to purchase order line. It will
not call action_cancel on the stock.picking. However the part
responsible for the cancelation of components delivery is in the
stock.picking action_cancel method.

Move the stock.picking action_cancel logic in the stock.move
_action_cancel method since it's always call for both usecase.

Fixes #42551

closes odoo/odoo#42653

X-original-commit: 841305f271411c3a67af271ac09da9ce0922f100
Signed-off-by: Simon Lejeune (sle) <sle@openerp.com>
This commit is contained in:
Arnold Moyaux
2020-01-02 18:11:33 +00:00
parent 858c9ec394
commit ea340afafa
3 changed files with 41 additions and 5 deletions
@@ -93,6 +93,12 @@ class StockMove(models.Model):
'domain': [('id', 'in', moves.ids)],
}
def _action_cancel(self):
for move in self:
if move.is_subcontract:
move.move_orig_ids.production_id._action_cancel()
return super()._action_cancel()
def _action_confirm(self, merge=True, merge_into=False):
subcontract_details_per_picking = defaultdict(list)
for move in self:
@@ -36,11 +36,6 @@ class StockPicking(models.Model):
# -------------------------------------------------------------------------
# Action methods
# -------------------------------------------------------------------------
def action_cancel(self):
for picking in self:
picking._get_subcontracted_productions()._action_cancel()
return super(StockPicking, self).action_cancel()
def _action_done(self):
res = super(StockPicking, self)._action_done()
productions = self.env['mrp.production']
@@ -540,6 +540,41 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon):
backorder._action_done()
self.assertTrue(picking_receipt.move_lines.move_orig_ids.production_id.state == 'done')
def test_flow_9(self):
"""Ensure that cancel the subcontract moves will also delete the
components need for the subcontractor.
"""
resupply_sub_on_order_route = self.env['stock.location.route'].search([
('name', '=', 'Resupply Subcontractor on Order')
])
(self.comp1 + self.comp2).write({
'route_ids': [(4, resupply_sub_on_order_route.id)]
})
picking_form = Form(self.env['stock.picking'])
picking_form.picking_type_id = self.env.ref('stock.picking_type_in')
picking_form.partner_id = self.subcontractor_partner1
with picking_form.move_ids_without_package.new() as move:
move.product_id = self.finished
move.product_uom_qty = 5
picking_receipt = picking_form.save()
picking_receipt.action_confirm()
picking_delivery = self.env['stock.move'].search([
('product_id', 'in', (self.comp1 | self.comp2).ids)
]).picking_id
self.assertTrue(picking_delivery)
self.assertEqual(picking_delivery.state, 'confirmed')
self.assertEqual(self.comp1.virtual_available, -5)
self.assertEqual(self.comp2.virtual_available, -5)
# action_cancel is not call on the picking in order
# to test behavior from other source than picking (e.g. puchase).
picking_receipt.move_lines._action_cancel()
self.assertEqual(picking_delivery.state, 'cancel')
self.assertEqual(self.comp1.virtual_available, 0.0)
self.assertEqual(self.comp1.virtual_available, 0.0)
class TestSubcontractingTracking(TransactionCase):
def setUp(self):
super(TestSubcontractingTracking, self).setUp()