From 2d81191cd01a5a3faf5345c756cb6ed511595536 Mon Sep 17 00:00:00 2001 From: Iryna Vushnevska Date: Thu, 16 Apr 2020 22:00:04 +0300 Subject: [PATCH] [ADD] stock_picking_fillwithstock --- stock_move_location/__init__.py | 4 - stock_move_location/__manifest__.py | 8 +- stock_move_location/i18n/fr_BE.po | 44 +++++++++++ stock_move_location/models/__init__.py | 1 + stock_move_location/models/stock_picking.py | 46 ++++++++++++ stock_move_location/readme/CONTRIBUTORS.rst | 2 + stock_move_location/readme/USAGE.rst | 10 +++ stock_move_location/tests/__init__.py | 5 +- .../tests/test_stock_fillwithstock.py | 73 +++++++++++++++++++ stock_move_location/views/stock_picking.xml | 15 ++++ 10 files changed, 198 insertions(+), 10 deletions(-) create mode 100644 stock_move_location/i18n/fr_BE.po create mode 100644 stock_move_location/models/stock_picking.py create mode 100644 stock_move_location/tests/test_stock_fillwithstock.py create mode 100644 stock_move_location/views/stock_picking.xml diff --git a/stock_move_location/__init__.py b/stock_move_location/__init__.py index d1dcf0d2a..76d87ae8c 100644 --- a/stock_move_location/__init__.py +++ b/stock_move_location/__init__.py @@ -1,7 +1,3 @@ -# Copyright (C) 2011 Julius Network Solutions SARL -# Copyright 2018 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - from . import wizard from . import models from .init_hook import enable_multi_locations diff --git a/stock_move_location/__manifest__.py b/stock_move_location/__manifest__.py index b4e70c6a4..d5bbe1a87 100644 --- a/stock_move_location/__manifest__.py +++ b/stock_move_location/__manifest__.py @@ -6,7 +6,10 @@ { "name": "Move Stock Location", "version": "15.0.1.0.0", - "author": "Julius Network Solutions, Odoo Community Association (OCA)", + "author": "Julius Network Solutions, " + "BCIM," + "Camptocamp," + "Odoo Community Association (OCA)", "summary": "This module allows to move all stock " "in a stock location to an other one.", "website": "https://github.com/OCA/stock-logistics-warehouse", @@ -17,7 +20,8 @@ "data/stock_quant_view.xml", "security/ir.model.access.csv", "views/stock_picking_type_views.xml", - "wizard/stock_move_location.xml", + 'views/stock_picking.xml', + 'wizard/stock_move_location.xml', ], "post_init_hook": "enable_multi_locations", } diff --git a/stock_move_location/i18n/fr_BE.po b/stock_move_location/i18n/fr_BE.po new file mode 100644 index 000000000..b53f5b505 --- /dev/null +++ b/stock_move_location/i18n/fr_BE.po @@ -0,0 +1,44 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_picking_fillwithstock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-01-22 08:26+0000\n" +"PO-Revision-Date: 2017-01-22 08:26+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: stock_picking_fillwithstock +#: model:ir.ui.view,arch_db:stock_picking_fillwithstock.view_picking_form +msgid "Fill with stock" +msgstr "Remplir avec le stock" + +#. module: stock_picking_fillwithstock +#: code:addons/stock_picking_fillwithstock/models/stock.py:35 +#, python-format +msgid "Moves lines already exsits" +msgstr "Des lignes existent déjà" + +#. module: stock_picking_fillwithstock +#: code:addons/stock_picking_fillwithstock/models/stock.py:60 +#, python-format +msgid "Nothing to move" +msgstr "Rien à déplacer" + +#. module: stock_picking_fillwithstock +#: code:addons/stock_picking_fillwithstock/models/stock.py:33 +#, python-format +msgid "Please choose a source end location" +msgstr "Veuillez choisir un emplacement source physique" + +#. module: stock_picking_fillwithstock +#: model:ir.model,name:stock_picking_fillwithstock.model_stock_picking +msgid "Transfer" +msgstr "Transfert" diff --git a/stock_move_location/models/__init__.py b/stock_move_location/models/__init__.py index 58ff9b56b..a44310781 100644 --- a/stock_move_location/models/__init__.py +++ b/stock_move_location/models/__init__.py @@ -3,3 +3,4 @@ from . import stock_move from . import stock_picking_type +from . import stock_picking diff --git a/stock_move_location/models/stock_picking.py b/stock_move_location/models/stock_picking.py new file mode 100644 index 000000000..3b8733472 --- /dev/null +++ b/stock_move_location/models/stock_picking.py @@ -0,0 +1,46 @@ +# Copyright Jacques-Etienne Baudoux 2016 Camptocamp +# Copyright Iryna Vyshnevska 2020 Camptocamp +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import _, models +from odoo.exceptions import UserError +from itertools import groupby + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + def button_fillwithstock(self): + # check source location has no children, i.e. we scanned a bin + + self.ensure_one() + self._validate_picking() + context = { + 'active_ids': self._get_movable_quants().ids, + 'active_model': 'stock.quant', + 'only_reserved_qty': True, + 'planned': True, + } + move_wizard = self.env['wiz.stock.move.location'].with_context(context).create({ + 'destination_location_id' : self.location_dest_id.id, + 'origin_location_id': self.location_id.id, + 'picking_type_id': self.picking_type_id.id, + 'picking_id': self.id, + }) + move_wizard._onchange_destination_location_id() + move_wizard.action_move_location() + return True + + def _validate_picking(self): + if self.location_id.child_ids: + raise UserError(_('Please choose a source end location')) + if self.move_lines: + raise UserError(_('Moves lines already exists')) + + def _get_movable_quants(self): + return self.env['stock.quant'].search( + [ + ('location_id', '=', self.location_id.id), + ('quantity', '>', 0.0), + ] + ) diff --git a/stock_move_location/readme/CONTRIBUTORS.rst b/stock_move_location/readme/CONTRIBUTORS.rst index d20d856f0..24f9bbc22 100644 --- a/stock_move_location/readme/CONTRIBUTORS.rst +++ b/stock_move_location/readme/CONTRIBUTORS.rst @@ -8,3 +8,5 @@ * Sergio Teruel * João Marques +* Jacques-Etienne Baudoux +* Iryna Vyshnevska diff --git a/stock_move_location/readme/USAGE.rst b/stock_move_location/readme/USAGE.rst index c565d0a04..4b5fa5ef9 100644 --- a/stock_move_location/readme/USAGE.rst +++ b/stock_move_location/readme/USAGE.rst @@ -20,3 +20,13 @@ If you want to transfer a full quant: If you go to the Inventory Dashboard you can see the button "Move from location" in each of the picking types (only applicable to internal transfers). Press it and you will be directed to the wizard. + +If you want transfer everything from stock.location + +On a draft picking, add a button to fill with moves lines for all products in +the source destination. This allows to create a picking to move all the content +of a location. If some quants are not available (i.e. reserved) the picking +will be in partially available state and reserved moves won't be listed in the +operations. +Use barcode interface to scan a location and create an empty picking. Then use +the fill with stock button. diff --git a/stock_move_location/tests/__init__.py b/stock_move_location/tests/__init__.py index 00527a8b0..315ff5109 100644 --- a/stock_move_location/tests/__init__.py +++ b/stock_move_location/tests/__init__.py @@ -1,6 +1,3 @@ -# Copyright (C) 2011 Julius Network Solutions SARL -# Copyright 2018 Camptocamp SA -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) - from . import test_common from . import test_move_location +from . import test_stock_fillwithstock diff --git a/stock_move_location/tests/test_stock_fillwithstock.py b/stock_move_location/tests/test_stock_fillwithstock.py new file mode 100644 index 000000000..5546daa2b --- /dev/null +++ b/stock_move_location/tests/test_stock_fillwithstock.py @@ -0,0 +1,73 @@ +# Copyright Iryna Vyshnevska 2020 Camptocamp +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +import odoo.tests.common as common + + +class TestFillwithStock(common.TransactionCase): + + def setUp(self): + super(TestFillwithStock, self).setUp() + self.env = self.env(context=dict( + self.env.context, + tracking_disable=True, + )) + + self.stock_location = self.env.ref('stock.stock_location_stock') + self.pack_location = self.env.ref('stock.location_pack_zone') + + self.shelf1_location = self.env["stock.location"].create({ + "name": "Test location", + "usage": "internal", + "location_id": self.stock_location.id + }) + + self.product1 = self.env['product.product'].create({ + 'name': 'Product A', + 'type': 'product', + }) + self.product2 = self.env['product.product'].create({ + 'name': 'Product B', + 'type': 'product', + }) + + self.env['stock.quant'].create({ + 'product_id': self.product1.id, + 'location_id': self.shelf1_location.id, + 'quantity': 5.0, + 'reserved_quantity': 0.0, + }) + self.env['stock.quant'].create({ + 'product_id': self.product1.id, + 'location_id': self.shelf1_location.id, + 'quantity': 10.0, + 'reserved_quantity': 5.0, + }) + self.env['stock.quant'].create({ + 'product_id': self.product2.id, + 'location_id': self.shelf1_location.id, + 'quantity': 5.0, + 'reserved_quantity': 0.0, + }) + + def test_fillwithstock(self): + picking_stock_pack = self.env['stock.picking'].create({ + 'location_id': self.shelf1_location.id, + 'location_dest_id': self.pack_location.id, + 'picking_type_id': self.env.ref('stock.picking_type_internal').id, + }) + self.assertFalse(picking_stock_pack.move_lines) + picking_stock_pack.button_fillwithstock() + # picking filled with quants in bin + self.assertEqual(len(picking_stock_pack.move_lines), 2) + self.assertEqual( + picking_stock_pack.move_lines.filtered( + lambda m: m.product_id == self.product1).product_uom_qty, + 10.0 + ) + self.assertEqual( + picking_stock_pack.move_lines.filtered( + lambda m: m.product_id == self.product2).product_uom_qty, + 5.0 + ) diff --git a/stock_move_location/views/stock_picking.xml b/stock_move_location/views/stock_picking.xml new file mode 100644 index 000000000..052a76184 --- /dev/null +++ b/stock_move_location/views/stock_picking.xml @@ -0,0 +1,15 @@ + + + + + stock.picking.form.fillwithstock + stock.picking + + + + + + +