summaryrefslogtreecommitdiff
path: root/addons/stock_picking_batch
diff options
context:
space:
mode:
authorTiffany Chang (tic) <tic@odoo.com>2020-06-12 15:01:53 +0000
committersvs-odoo <svs@odoo.com>2020-08-20 15:06:08 +0000
commit58316d1546420d72642a13d9648b323f4b1dfd59 (patch)
tree197c6fc469a589950161c5e8de2ce5494b22c755 /addons/stock_picking_batch
parentd8cd37fc7261daaf2d71756ceb85c758d2460744 (diff)
[IMP] delivery, stock(_picking_batch): add "Put In Pack" button
This commit sets up the logic and adds the button for "Put in Pack" action that already exists in stock.picking. Reuse/extension of logic from stock.picking reused where possible, including extension of pack wizard to handle products with different destination. Note that logic to handle "Delivery Packaging" wizard when "Delivery Methods" is active was purposely not extended to work correctly in batch pickings due to complexity of adding in a new module just to handle conflicting carrier_ids across pickings in the same batch. It is expected that this use case will not occur except in case of user error. Additionally, stock.picking implementation of 'put_in_pack' method has been renamed to 'action_put_in_pack' to have consistent naming (and support enterprise level code). Part of "1. Improve Batch Pickings" specification of overall barcode improvements task. Task: 1884520 Enterprise PR: odoo/enterprise#12086 Closes: odoo/odoo#55096
Diffstat (limited to 'addons/stock_picking_batch')
-rw-r--r--addons/stock_picking_batch/models/stock_picking_batch.py26
-rw-r--r--addons/stock_picking_batch/tests/test_batch_picking.py40
-rw-r--r--addons/stock_picking_batch/views/stock_picking_batch_views.xml1
-rw-r--r--addons/stock_picking_batch/wizard/__init__.py1
-rw-r--r--addons/stock_picking_batch/wizard/stock_package_destination.py25
5 files changed, 92 insertions, 1 deletions
diff --git a/addons/stock_picking_batch/models/stock_picking_batch.py b/addons/stock_picking_batch/models/stock_picking_batch.py
index 696c67eabc5..df23497e58a 100644
--- a/addons/stock_picking_batch/models/stock_picking_batch.py
+++ b/addons/stock_picking_batch/models/stock_picking_batch.py
@@ -3,7 +3,7 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError
-
+from odoo.tools.float_utils import float_compare, float_is_zero, float_round
class StockPickingBatch(models.Model):
_inherit = ['mail.thread', 'mail.activity.mixin']
@@ -198,6 +198,30 @@ class StockPickingBatch(models.Model):
self.ensure_one()
self.picking_ids.action_assign()
+ def action_put_in_pack(self):
+ """ Action to put move lines with 'Done' quantities into a new pack
+ This method follows same logic to stock.picking.
+ """
+ self.ensure_one()
+ if self.state not in ('done', 'cancel'):
+ picking_move_lines = self.move_line_ids
+
+ move_line_ids = picking_move_lines.filtered(lambda ml:
+ float_compare(ml.qty_done, 0.0, precision_rounding=ml.product_uom_id.rounding) > 0
+ and not ml.result_package_id
+ )
+ if not move_line_ids:
+ move_line_ids = picking_move_lines.filtered(lambda ml: float_compare(ml.product_uom_qty, 0.0,
+ precision_rounding=ml.product_uom_id.rounding) > 0 and float_compare(ml.qty_done, 0.0,
+ precision_rounding=ml.product_uom_id.rounding) == 0)
+ if move_line_ids:
+ res = self.picking_ids[0]._pre_put_in_pack_hook(move_line_ids)
+ if not res:
+ res = self.picking_ids[0]._put_in_pack(move_line_ids, False)
+ return res
+ else:
+ raise UserError(_("Please add 'Done' quantities to the batch picking to create a new pack."))
+
# -------------------------------------------------------------------------
# Miscellaneous
# -------------------------------------------------------------------------
diff --git a/addons/stock_picking_batch/tests/test_batch_picking.py b/addons/stock_picking_batch/tests/test_batch_picking.py
index c7352699439..ecf50379002 100644
--- a/addons/stock_picking_batch/tests/test_batch_picking.py
+++ b/addons/stock_picking_batch/tests/test_batch_picking.py
@@ -325,3 +325,43 @@ class TestBatchPicking(TransactionCase):
# ensure that quantity for picking has been moved
self.assertFalse(sum(quant_A.mapped('quantity')))
self.assertFalse(sum(quant_B.mapped('quantity')))
+
+ def test_put_in_pack(self):
+ self.env['stock.quant']._update_available_quantity(self.productA, self.stock_location, 10.0)
+ self.env['stock.quant']._update_available_quantity(self.productB, self.stock_location, 10.0)
+
+ # Confirm batch, pickings should not be automatically assigned.
+ self.batch.action_confirm()
+ self.assertEqual(self.picking_client_1.state, 'confirmed', 'Picking 1 should be confirmed')
+ self.assertEqual(self.picking_client_2.state, 'confirmed', 'Picking 2 should be confirmed')
+ # Ask to assign, so pickings should be assigned now.
+ self.batch.action_assign()
+ self.assertEqual(self.picking_client_1.state, 'assigned', 'Picking 1 should be ready')
+ self.assertEqual(self.picking_client_2.state, 'assigned', 'Picking 2 should be ready')
+
+ # only do part of pickings + assign different destinations + try to pack (should get wizard to correct destination)
+ self.batch.move_line_ids.qty_done = 5
+ self.batch.move_line_ids[0].location_dest_id = self.stock_location.id
+ wizard_values = self.batch.action_put_in_pack()
+ wizard = self.env[(wizard_values.get('res_model'))].browse(wizard_values.get('res_id'))
+ wizard.location_dest_id = self.customer_location.id
+ package = wizard.action_done()
+
+ # a new package is made and done quantities should be in same package
+ self.assertTrue(package)
+ done_qty_move_lines = self.batch.move_line_ids.filtered(lambda ml: ml.qty_done == 5)
+ self.assertEqual(done_qty_move_lines[0].result_package_id.id, package.id)
+ self.assertEqual(done_qty_move_lines[1].result_package_id.id, package.id)
+
+ # not done quantities should be split into separate lines
+ self.assertEqual(len(self.batch.move_line_ids), 4)
+
+ # confirm w/ backorder
+ back_order_wizard_dict = self.batch.action_done()
+ self.assertTrue(back_order_wizard_dict)
+ back_order_wizard = Form(self.env[(back_order_wizard_dict.get('res_model'))].with_context(back_order_wizard_dict['context'])).save()
+ self.assertEqual(len(back_order_wizard.pick_ids), 2)
+ back_order_wizard.process()
+
+ # final package location should be correctly set based on wizard
+ self.assertEqual(package.location_id.id, self.customer_location.id)
diff --git a/addons/stock_picking_batch/views/stock_picking_batch_views.xml b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
index 97378a93a2c..d1eec150b9f 100644
--- a/addons/stock_picking_batch/views/stock_picking_batch_views.xml
+++ b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
@@ -111,6 +111,7 @@
<notebook>
<page string="Detailed Operations" attrs="{'invisible': [('state', '=', 'draft')]}">
<field name="move_line_ids" context="{'tree_view_ref': 'stock_picking_batch.view_move_line_tree'}"/>
+ <button class="oe_highlight" name="action_put_in_pack" type="object" string="Put in Pack" attrs="{'invisible': [('state', 'in', ('draft', 'done', 'cancel'))]}" groups="stock.group_tracking_lot"/>
</page>
<page string="Operations" attrs="{'invisible': [('state', '=', 'draft')]}">
<field name="move_ids" context="{'tree_view_ref': 'stock_picking_batch.view_picking_move_tree_inherited'}"/>
diff --git a/addons/stock_picking_batch/wizard/__init__.py b/addons/stock_picking_batch/wizard/__init__.py
index 063ece3795c..cfb88076d83 100644
--- a/addons/stock_picking_batch/wizard/__init__.py
+++ b/addons/stock_picking_batch/wizard/__init__.py
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import stock_picking_to_batch
+from . import stock_package_destination
diff --git a/addons/stock_picking_batch/wizard/stock_package_destination.py b/addons/stock_picking_batch/wizard/stock_package_destination.py
new file mode 100644
index 00000000000..05b60cf0ad8
--- /dev/null
+++ b/addons/stock_picking_batch/wizard/stock_package_destination.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models
+
+
+class ChooseDestinationLocation(models.TransientModel):
+ _inherit = "stock.package.destination"
+
+ def _compute_move_line_ids(self):
+ destination_without_batch = self.env['stock.package.destination']
+ for destination in self:
+ if not destination.picking_id.batch_id:
+ destination_without_batch |= destination
+ continue
+ destination.move_line_ids = destination.picking_id.batch_id.move_line_ids.filtered(lambda l: l.qty_done > 0 and not l.result_package_id)
+ super(ChooseDestinationLocation, destination_without_batch)._compute_move_line_ids()
+
+ def action_done(self):
+ if self.picking_id.batch_id:
+ # set the same location on each move line and pass again in action_put_in_pack
+ self.move_line_ids.location_dest_id = self.location_dest_id
+ return self.picking_id.batch_id.action_put_in_pack()
+ else:
+ return super().action_done()