diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 5b61eba3d3fce3e9d8cf2328e987522072046011..1bb5da96cdbd053f2f7858ea6e843bdc7255d511 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -947,7 +947,7 @@ class Picking(models.Model): 'view_id': view.id, 'target': 'new', 'res_id': wiz.id, - 'context': self.env.context, + 'context': dict(self.env.context), } def action_toggle_is_locked(self): diff --git a/addons/stock_picking_batch/models/stock_picking_batch.py b/addons/stock_picking_batch/models/stock_picking_batch.py index e8316cffcc61e188463e570d4ef9154f988e96fd..d3edc5e0824f5c1649c13a0c2048a599aad43bc9 100644 --- a/addons/stock_picking_batch/models/stock_picking_batch.py +++ b/addons/stock_picking_batch/models/stock_picking_batch.py @@ -83,7 +83,7 @@ class StockPickingBatch(models.Model): picking_to_backorder |= picking else: picking.action_done() - if picking_without_qty_done: + if len(picking_without_qty_done) == len(pickings): view = self.env.ref('stock.view_immediate_transfer') wiz = self.env['stock.immediate.transfer'].create({ 'pick_ids': [(4, p.id) for p in picking_without_qty_done], @@ -100,8 +100,12 @@ class StockPickingBatch(models.Model): 'res_id': wiz.id, 'context': self.env.context, } - if picking_to_backorder: - return picking_to_backorder.action_generate_backorder_wizard() + if picking_to_backorder or picking_without_qty_done: + res = picking_to_backorder.action_generate_backorder_wizard() + if picking_without_qty_done and 'context' in res: + res['context']['pickings_to_detach'] = picking_without_qty_done.ids + return res + # Change the state only if there is no other action (= wizard) waiting. self.write({'state': 'done'}) return True diff --git a/addons/stock_picking_batch/tests/test_batch_picking.py b/addons/stock_picking_batch/tests/test_batch_picking.py index 0c477f88dc072e1c23ae94e8600524f88e201ba7..ae96f6941b28732aaa14a1b07d79580648933b1c 100644 --- a/addons/stock_picking_batch/tests/test_batch_picking.py +++ b/addons/stock_picking_batch/tests/test_batch_picking.py @@ -188,10 +188,10 @@ class TestBatchPicking(TransactionCase): self.assertFalse(sum(quant_B.mapped('quantity'))) def test_batch_with_immediate_transfer_and_backorder_wizard_with_manual_operations(self): - """ Test a simple batch picking with only one quantity fully available. - The user set the quantity done only for the partially available picking. - The test should run the immediate transfer for the first picking and then - the backorder wizard for the second picking. + """ When validating a batch picking where some pickings have no quantities done + some + do, then avoid immediate transfers wizard and remove pickings with no quantities done + from the batch picking. This will make it so users can validate a partially done batch + picking in this case. """ self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 5.0) self.env['stock.quant']._update_available_quantity(self.productB, self.stock_location, 10.0) @@ -202,24 +202,16 @@ class TestBatchPicking(TransactionCase): self.assertEqual(self.picking_client_2.state, 'assigned', 'Picking 2 should be ready') self.picking_client_1.move_lines.quantity_done = 5 - # There should be a wizard asking to process picking without quantity done - immediate_transfer_wizard_dict = self.batch.done() - self.assertTrue(immediate_transfer_wizard_dict) - immediate_transfer_wizard = self.env[(immediate_transfer_wizard_dict.get('res_model'))].browse(immediate_transfer_wizard_dict.get('res_id')) - self.assertEqual(len(immediate_transfer_wizard.pick_ids), 1) - back_order_wizard_dict = immediate_transfer_wizard.process() + # There should be a wizard asking to make a backorder + back_order_wizard_dict = self.batch.done() self.assertTrue(back_order_wizard_dict) + self.assertEqual(back_order_wizard_dict.get('res_model'), 'stock.backorder.confirmation') back_order_wizard = self.env[(back_order_wizard_dict.get('res_model'))].browse(back_order_wizard_dict.get('res_id')) + back_order_wizard = back_order_wizard.with_context(back_order_wizard_dict.get('context')) self.assertEqual(len(back_order_wizard.pick_ids), 1) back_order_wizard.process() self.assertEqual(self.picking_client_1.state, 'done', 'Picking 1 should be done') self.assertEqual(self.picking_client_1.move_lines.product_uom_qty, 5, 'initial demand should be 5 after picking split') - self.assertTrue(self.env['stock.picking'].search([('backorder_id', '=', self.picking_client_1.id)]), 'no back order created') - - quant_A = self.env['stock.quant']._gather(self.productA, self.stock_location) - quant_B = self.env['stock.quant']._gather(self.productB, self.stock_location) - # ensure that quantity for picking has been moved - self.assertFalse(sum(quant_A.mapped('quantity'))) - self.assertFalse(sum(quant_B.mapped('quantity'))) + self.assertFalse(self.picking_client_2.batch_id, 'The picking should be removed from the batch') diff --git a/addons/stock_picking_batch/wizard/__init__.py b/addons/stock_picking_batch/wizard/__init__.py index 92e3d6e014e1181b5869ed4aaf202bc83551cf3a..294c4323c494ab2b3cd54137007dacd270d79fa2 100644 --- a/addons/stock_picking_batch/wizard/__init__.py +++ b/addons/stock_picking_batch/wizard/__init__.py @@ -3,3 +3,4 @@ from . import stock_picking_to_batch from . import stock_immediate_transfer +from . import stock_backorder_confirmation diff --git a/addons/stock_picking_batch/wizard/stock_backorder_confirmation.py b/addons/stock_picking_batch/wizard/stock_backorder_confirmation.py new file mode 100644 index 0000000000000000000000000000000000000000..ba587e08ce6c7ea597285e4734259dcb9ff77165 --- /dev/null +++ b/addons/stock_picking_batch/wizard/stock_backorder_confirmation.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class StockBackorderConfirmation(models.TransientModel): + _inherit = 'stock.backorder.confirmation' + + def process(self): + res = super().process() + if self.env.context.get('pickings_to_detach'): + self.env['stock.picking'].browse(self.env.context['pickings_to_detach']).batch_id = False + return res + + def process_cancel_backorder(self): + res = super().process_cancel_backorder() + if self.env.context.get('pickings_to_detach'): + self.env['stock.picking'].browse(self.env.context['pickings_to_detach']).batch_id = False + return res