From d43feb008b1b00b3b30457e2b344d5385597f73d Mon Sep 17 00:00:00 2001 From: William Henrotin <whe@odoo.com> Date: Thu, 19 Aug 2021 12:39:24 +0000 Subject: [PATCH] [FIX] stock_picking_batch: remove empty pickings 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. This is an adaptation of [1] (which is already deployed in 15.0) [1] eb0ebc077afed24e8f5c2212f2a216bb1b8e6936 OPW-2711585 closes odoo/odoo#81844 Signed-off-by: Tiffany Chang <tic@odoo.com> Co-authored-by: William Henrotin (whe) <whe@odoo.com> --- addons/stock/models/stock_picking.py | 2 +- .../models/stock_picking_batch.py | 10 ++++--- .../tests/test_batch_picking.py | 26 +++++++------------ addons/stock_picking_batch/wizard/__init__.py | 1 + .../wizard/stock_backorder_confirmation.py | 20 ++++++++++++++ 5 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 addons/stock_picking_batch/wizard/stock_backorder_confirmation.py diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 5b61eba3d3fc..1bb5da96cdbd 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 e8316cffcc61..d3edc5e0824f 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 0c477f88dc07..ae96f6941b28 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 92e3d6e014e1..294c4323c494 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 000000000000..ba587e08ce6c --- /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 -- GitLab