From 50ddacfe53de16ddeaee913414e52d4bfd4ffb49 Mon Sep 17 00:00:00 2001 From: Joan Sisquella Date: Fri, 10 Jan 2020 12:28:30 +0100 Subject: [PATCH] [IMP] stock_move_location: black, isort --- stock_move_location/__manifest__.py | 17 +- .../models/stock_picking_type.py | 21 +-- stock_move_location/readme/USAGE.rst | 2 +- stock_move_location/tests/test_common.py | 105 +++++------ .../tests/test_move_location.py | 94 ++++------ .../wizard/stock_move_location.py | 167 +++++++++--------- .../wizard/stock_move_location_line.py | 96 +++++----- 7 files changed, 228 insertions(+), 274 deletions(-) diff --git a/stock_move_location/__manifest__.py b/stock_move_location/__manifest__.py index 09274942b..a2c60d32d 100644 --- a/stock_move_location/__manifest__.py +++ b/stock_move_location/__manifest__.py @@ -5,19 +5,16 @@ { "name": "Move Stock Location", "version": "12.0.1.2.0", - "author": "Julius Network Solutions, " - "Odoo Community Association (OCA)", + "author": "Julius Network Solutions, " "Odoo Community Association (OCA)", "summary": "This module allows to move all stock " - "in a stock location to an other one.", + "in a stock location to an other one.", "website": "https://github.com/OCA/stock-logistics-warehouse", - 'license': 'AGPL-3', - "depends": [ - "stock", - ], + "license": "AGPL-3", + "depends": ["stock"], "category": "Stock", "data": [ - 'data/stock_quant_view.xml', - 'views/stock_picking_type_views.xml', - 'wizard/stock_move_location.xml', + "data/stock_quant_view.xml", + "views/stock_picking_type_views.xml", + "wizard/stock_move_location.xml", ], } diff --git a/stock_move_location/models/stock_picking_type.py b/stock_move_location/models/stock_picking_type.py index 9b77f490a..0bb437fd0 100644 --- a/stock_move_location/models/stock_picking_type.py +++ b/stock_move_location/models/stock_picking_type.py @@ -7,19 +7,20 @@ class StockPickingType(models.Model): _inherit = "stock.picking.type" show_move_onhand = fields.Boolean( - string='Show Move On hand stock', + string="Show Move On hand stock", help="Show a button 'Move On Hand' in the Inventory Dashboard " - "to initiate the process to move the products in stock " - "at the origin location.") + "to initiate the process to move the products in stock " + "at the origin location.", + ) def action_move_location(self): action = self.env.ref( - 'stock_move_location.wiz_stock_move_location_action').read()[0] - action['context'] = { - 'default_origin_location_id': self.default_location_src_id.id, - 'default_destination_location_id': - self.default_location_dest_id.id, - 'default_picking_type_id': self.id, - 'default_edit_locations': False, + "stock_move_location.wiz_stock_move_location_action" + ).read()[0] + action["context"] = { + "default_origin_location_id": self.default_location_src_id.id, + "default_destination_location_id": self.default_location_dest_id.id, + "default_picking_type_id": self.id, + "default_edit_locations": False, } return action diff --git a/stock_move_location/readme/USAGE.rst b/stock_move_location/readme/USAGE.rst index 55d8c0b71..99bea2b7e 100644 --- a/stock_move_location/readme/USAGE.rst +++ b/stock_move_location/readme/USAGE.rst @@ -19,4 +19,4 @@ 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. \ No newline at end of file +and you will be directed to the wizard. diff --git a/stock_move_location/tests/test_common.py b/stock_move_location/tests/test_common.py index ee70c0e85..bdb67f3d7 100644 --- a/stock_move_location/tests/test_common.py +++ b/stock_move_location/tests/test_common.py @@ -6,7 +6,6 @@ from odoo.tests import common class TestsCommon(common.SavepointCase): - @classmethod def setUpClass(cls): super().setUpClass() @@ -17,83 +16,65 @@ class TestsCommon(common.SavepointCase): cls.quant_obj = cls.env["stock.quant"] # Enable multi-locations: - wizard = cls.env['res.config.settings'].create({ - 'group_stock_multi_locations': True, - }) + wizard = cls.env["res.config.settings"].create( + {"group_stock_multi_locations": True} + ) wizard.execute() - cls.internal_loc_1 = cls.location_obj.create({ - "name": "INT_1", - "usage": "internal", - "active": True, - }) - cls.internal_loc_2 = cls.location_obj.create({ - "name": "INT_2", - "usage": "internal", - "active": True, - }) - cls.uom_unit = cls.env.ref('uom.product_uom_unit') - cls.product_no_lots = product_obj.create({ - "name": "Pineapple", - "type": "product", - "tracking": "none", - 'category_id': cls.env.ref('product.product_category_all').id, - }) - cls.product_lots = product_obj.create({ - "name": "Pineapple", - "type": "product", - "tracking": "lot", - 'category_id': cls.env.ref('product.product_category_all').id, - }) - cls.lot1 = cls.env['stock.production.lot'].create({ - 'product_id': cls.product_lots.id, - }) - cls.lot2 = cls.env['stock.production.lot'].create({ - 'product_id': cls.product_lots.id, - }) - cls.lot3 = cls.env['stock.production.lot'].create({ - 'product_id': cls.product_lots.id, - }) + cls.internal_loc_1 = cls.location_obj.create( + {"name": "INT_1", "usage": "internal", "active": True} + ) + cls.internal_loc_2 = cls.location_obj.create( + {"name": "INT_2", "usage": "internal", "active": True} + ) + cls.uom_unit = cls.env.ref("uom.product_uom_unit") + cls.product_no_lots = product_obj.create( + { + "name": "Pineapple", + "type": "product", + "tracking": "none", + "category_id": cls.env.ref("product.product_category_all").id, + } + ) + cls.product_lots = product_obj.create( + { + "name": "Pineapple", + "type": "product", + "tracking": "lot", + "category_id": cls.env.ref("product.product_category_all").id, + } + ) + cls.lot1 = cls.env["stock.production.lot"].create( + {"product_id": cls.product_lots.id} + ) + cls.lot2 = cls.env["stock.production.lot"].create( + {"product_id": cls.product_lots.id} + ) + cls.lot3 = cls.env["stock.production.lot"].create( + {"product_id": cls.product_lots.id} + ) def setup_product_amounts(self): + self.set_product_amount(self.product_no_lots, self.internal_loc_1, 123) self.set_product_amount( - self.product_no_lots, - self.internal_loc_1, - 123, + self.product_lots, self.internal_loc_1, 1, lot_id=self.lot1 ) self.set_product_amount( - self.product_lots, - self.internal_loc_1, - 1, - lot_id=self.lot1, + self.product_lots, self.internal_loc_1, 1, lot_id=self.lot2 ) self.set_product_amount( - self.product_lots, - self.internal_loc_1, - 1, - lot_id=self.lot2, - ) - self.set_product_amount( - self.product_lots, - self.internal_loc_1, - 1, - lot_id=self.lot3, + self.product_lots, self.internal_loc_1, 1, lot_id=self.lot3 ) def set_product_amount(self, product, location, amount, lot_id=None): - self.env['stock.quant']._update_available_quantity( - product, - location, - amount, - lot_id=lot_id, + self.env["stock.quant"]._update_available_quantity( + product, location, amount, lot_id=lot_id ) def check_product_amount(self, product, location, amount, lot_id=None): self.assertEqual( - self.env['stock.quant']._get_available_quantity( - product, - location, - lot_id=lot_id, + self.env["stock.quant"]._get_available_quantity( + product, location, lot_id=lot_id ), amount, ) diff --git a/stock_move_location/tests/test_move_location.py b/stock_move_location/tests/test_move_location.py index 4c7f2bb60..120166ad8 100644 --- a/stock_move_location/tests/test_move_location.py +++ b/stock_move_location/tests/test_move_location.py @@ -2,51 +2,37 @@ # Copyright 2018 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) -from .test_common import TestsCommon from odoo.exceptions import ValidationError +from .test_common import TestsCommon + class TestMoveLocation(TestsCommon): - def setUp(self): super().setUp() self.setup_product_amounts() def _create_wizard(self, origin_location, destination_location): - return self.wizard_obj.create({ - "origin_location_id": origin_location.id, - "destination_location_id": destination_location.id, - }) + return self.wizard_obj.create( + { + "origin_location_id": origin_location.id, + "destination_location_id": destination_location.id, + } + ) def test_move_location_wizard(self): """Test a simple move.""" wizard = self._create_wizard(self.internal_loc_1, self.internal_loc_2) wizard.onchange_origin_location() wizard.action_move_location() - self.check_product_amount( - self.product_no_lots, self.internal_loc_1, 0, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_1, 0, self.lot1, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_1, 0, self.lot2, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_1, 0, self.lot3, - ) - self.check_product_amount( - self.product_no_lots, self.internal_loc_2, 123, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_2, 1, self.lot1, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_2, 1, self.lot2, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_2, 1, self.lot3, - ) + self.check_product_amount(self.product_no_lots, self.internal_loc_1, 0) + self.check_product_amount(self.product_lots, self.internal_loc_1, 0, self.lot1) + self.check_product_amount(self.product_lots, self.internal_loc_1, 0, self.lot2) + self.check_product_amount(self.product_lots, self.internal_loc_1, 0, self.lot3) + self.check_product_amount(self.product_no_lots, self.internal_loc_2, 123) + self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot1) + self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot2) + self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot3) def test_move_location_wizard_amount(self): """Can't move more than exists.""" @@ -61,27 +47,16 @@ class TestMoveLocation(TestsCommon): wizard.onchange_origin_location() # reserve some quants self.quant_obj._update_reserved_quantity( - self.product_no_lots, - self.internal_loc_1, - 50, + self.product_no_lots, self.internal_loc_1, 50 ) self.quant_obj._update_reserved_quantity( - self.product_lots, - self.internal_loc_1, - 1, - lot_id=self.lot1, + self.product_lots, self.internal_loc_1, 1, lot_id=self.lot1 ) # doesn't care about reservations, everything is moved wizard.action_move_location() - self.check_product_amount( - self.product_no_lots, self.internal_loc_1, 0, - ) - self.check_product_amount( - self.product_no_lots, self.internal_loc_2, 123, - ) - self.check_product_amount( - self.product_lots, self.internal_loc_2, 1, self.lot1, - ) + self.check_product_amount(self.product_no_lots, self.internal_loc_1, 0) + self.check_product_amount(self.product_no_lots, self.internal_loc_2, 123) + self.check_product_amount(self.product_lots, self.internal_loc_2, 1, self.lot1) def test_wizard_clear_lines(self): """Test lines getting cleared properly.""" @@ -91,7 +66,8 @@ class TestMoveLocation(TestsCommon): wizard._onchange_destination_location_id() self.assertEqual(len(wizard.stock_move_location_line_ids), 4) dest_location_line = wizard.stock_move_location_line_ids.mapped( - 'destination_location_id') + "destination_location_id" + ) self.assertEqual(dest_location_line, wizard.destination_location_id) wizard._onchange_origin_location_id() self.assertEqual(len(wizard.stock_move_location_line_ids), 0) @@ -100,33 +76,33 @@ class TestMoveLocation(TestsCommon): """Test planned transfer.""" wizard = self._create_wizard(self.internal_loc_1, self.internal_loc_2) wizard.onchange_origin_location() - wizard = wizard.with_context({'planned': True}) + wizard = wizard.with_context({"planned": True}) wizard.action_move_location() picking = wizard.picking_id - self.assertEqual(picking.state, 'assigned') + self.assertEqual(picking.state, "assigned") self.assertEqual(len(picking.move_line_ids), 4) self.assertEqual( - sorted(picking.move_line_ids.mapped("product_uom_qty")), - [1, 1, 1, 123], + sorted(picking.move_line_ids.mapped("product_uom_qty")), [1, 1, 1, 123] ) def test_quant_transfer(self): """Test quants transfer.""" quants = self.product_lots.stock_quant_ids wizard = self.wizard_obj.with_context( - active_model='stock.quant', + active_model="stock.quant", active_ids=quants.ids, - origin_location_disable=True - ).create({ - "origin_location_id": quants[:1].location_id.id, - "destination_location_id": self.internal_loc_2.id, - }) + origin_location_disable=True, + ).create( + { + "origin_location_id": quants[:1].location_id.id, + "destination_location_id": self.internal_loc_2.id, + } + ) lines = wizard.stock_move_location_line_ids self.assertEqual(len(lines), 3) wizard.destination_location_id = self.internal_loc_1 wizard._onchange_destination_location_id() - self.assertEqual( - lines.mapped('destination_location_id'), self.internal_loc_1) + self.assertEqual(lines.mapped("destination_location_id"), self.internal_loc_1) wizard.origin_location_id = self.internal_loc_2 wizard._onchange_destination_location_id() self.assertEqual(len(lines), 3) diff --git a/stock_move_location/wizard/stock_move_location.py b/stock_move_location/wizard/stock_move_location.py index d7049fb63..8dac23ce7 100644 --- a/stock_move_location/wizard/stock_move_location.py +++ b/stock_move_location/wizard/stock_move_location.py @@ -9,56 +9,60 @@ from odoo.fields import first class StockMoveLocationWizard(models.TransientModel): _name = "wiz.stock.move.location" - _description = 'Wizard move location' + _description = "Wizard move location" @api.multi def _get_default_picking_type_id(self): - company_id = self.env.context.get('company_id') or \ - self.env.user.company_id.id - return self.env['stock.picking.type'].search( - [('code', '=', 'internal'), - ('warehouse_id.company_id', '=', company_id)], limit=1).id + company_id = self.env.context.get("company_id") or self.env.user.company_id.id + return ( + self.env["stock.picking.type"] + .search( + [ + ("code", "=", "internal"), + ("warehouse_id.company_id", "=", company_id), + ], + limit=1, + ) + .id + ) origin_location_disable = fields.Boolean( compute="_compute_readonly_locations", - help="technical field to disable the edition of origin location." + help="technical field to disable the edition of origin location.", ) origin_location_id = fields.Many2one( - string='Origin Location', - comodel_name='stock.location', + string="Origin Location", + comodel_name="stock.location", required=True, domain=lambda self: self._get_locations_domain(), ) destination_location_disable = fields.Boolean( compute="_compute_readonly_locations", - help="technical field to disable the edition of destination location." + help="technical field to disable the edition of destination location.", ) destination_location_id = fields.Many2one( - string='Destination Location', - comodel_name='stock.location', + string="Destination Location", + comodel_name="stock.location", required=True, domain=lambda self: self._get_locations_domain(), ) stock_move_location_line_ids = fields.Many2many( - string="Move Location lines", - comodel_name="wiz.stock.move.location.line", + string="Move Location lines", comodel_name="wiz.stock.move.location.line" ) picking_type_id = fields.Many2one( - comodel_name='stock.picking.type', - default=_get_default_picking_type_id, + comodel_name="stock.picking.type", default=_get_default_picking_type_id ) picking_id = fields.Many2one( - string="Connected Picking", - comodel_name="stock.picking", + string="Connected Picking", comodel_name="stock.picking" ) - edit_locations = fields.Boolean(string='Edit Locations', - default=True) + edit_locations = fields.Boolean(string="Edit Locations", default=True) - @api.depends('edit_locations') + @api.depends("edit_locations") def _compute_readonly_locations(self): for rec in self: rec.origin_location_disable = self.env.context.get( - 'origin_location_disable', False) + "origin_location_disable", False + ) if not rec.edit_locations: rec.origin_location_disable = True rec.destination_location_disable = True @@ -66,29 +70,37 @@ class StockMoveLocationWizard(models.TransientModel): @api.model def default_get(self, fields): res = super().default_get(fields) - if self.env.context.get('active_model', False) != 'stock.quant': + if self.env.context.get("active_model", False) != "stock.quant": return res # Load data directly from quants - quants = self.env['stock.quant'].browse( - self.env.context.get('active_ids', False)) - res['stock_move_location_line_ids'] = [(0, 0, { - 'product_id': quant.product_id.id, - 'move_quantity': quant.quantity, - 'max_quantity': quant.quantity, - 'origin_location_id': quant.location_id.id, - 'lot_id': quant.lot_id.id, - 'product_uom_id': quant.product_uom_id.id, - 'custom': False, - }) for quant in quants] - res['origin_location_id'] = first(quants).location_id.id + quants = self.env["stock.quant"].browse( + self.env.context.get("active_ids", False) + ) + res["stock_move_location_line_ids"] = [ + ( + 0, + 0, + { + "product_id": quant.product_id.id, + "move_quantity": quant.quantity, + "max_quantity": quant.quantity, + "origin_location_id": quant.location_id.id, + "lot_id": quant.lot_id.id, + "product_uom_id": quant.product_uom_id.id, + "custom": False, + }, + ) + for quant in quants + ] + res["origin_location_id"] = first(quants).location_id.id return res - @api.onchange('origin_location_id') + @api.onchange("origin_location_id") def _onchange_origin_location_id(self): - if not self.env.context.get('origin_location_disable', False): + if not self.env.context.get("origin_location_disable", False): self._clear_lines() - @api.onchange('destination_location_id') + @api.onchange("destination_location_id") def _onchange_destination_location_id(self): for line in self.stock_move_location_line_ids: line.destination_location_id = self.destination_location_id @@ -97,22 +109,23 @@ class StockMoveLocationWizard(models.TransientModel): self.stock_move_location_line_ids = False def _get_locations_domain(self): - return [('usage', '=', 'internal')] + return [("usage", "=", "internal")] def _create_picking(self): - return self.env['stock.picking'].create({ - 'picking_type_id': self.picking_type_id.id, - 'location_id': self.origin_location_id.id, - 'location_dest_id': self.destination_location_id.id, - }) + return self.env["stock.picking"].create( + { + "picking_type_id": self.picking_type_id.id, + "location_id": self.origin_location_id.id, + "location_dest_id": self.destination_location_id.id, + } + ) @api.multi def group_lines(self): lines_grouped = {} for line in self.stock_move_location_line_ids: lines_grouped.setdefault( - line.product_id.id, - self.env["wiz.stock.move.location.line"].browse(), + line.product_id.id, self.env["wiz.stock.move.location.line"].browse() ) lines_grouped[line.product_id.id] |= line return lines_grouped @@ -148,9 +161,7 @@ class StockMoveLocationWizard(models.TransientModel): @api.multi def _create_move(self, picking, lines): self.ensure_one() - move = self.env["stock.move"].create( - self._get_move_values(picking, lines), - ) + move = self.env["stock.move"].create(self._get_move_values(picking, lines)) if not self.env.context.get("planned"): for line in lines: line.create_move_lines(picking, move) @@ -172,18 +183,14 @@ class StockMoveLocationWizard(models.TransientModel): def _get_picking_action(self, pickinig_id): action = self.env.ref("stock.action_picking_tree_all").read()[0] form_view = self.env.ref("stock.view_picking_form").id - action.update({ - "view_mode": "form", - "views": [(form_view, "form")], - "res_id": pickinig_id, - }) + action.update( + {"view_mode": "form", "views": [(form_view, "form")], "res_id": pickinig_id} + ) return action def _get_group_quants(self): location_id = self.origin_location_id.id - company = self.env['res.company']._company_default_get( - 'stock.inventory', - ) + company = self.env["res.company"]._company_default_get("stock.inventory") # Using sql as search_group doesn't support aggregation functions # leading to overhead in queries to DB query = """ @@ -197,44 +204,46 @@ class StockMoveLocationWizard(models.TransientModel): return self.env.cr.dictfetchall() def _get_stock_move_location_lines_values(self): - product_obj = self.env['product.product'] + product_obj = self.env["product.product"] product_data = [] for group in self._get_group_quants(): product = product_obj.browse(group.get("product_id")).exists() # Apply the putaway strategy - location_dest_id = \ - self.destination_location_id.get_putaway_strategy( - product).id or self.destination_location_id.id - product_data.append({ - 'product_id': product.id, - 'move_quantity': group.get("sum"), - 'max_quantity': group.get("sum"), - 'origin_location_id': self.origin_location_id.id, - 'destination_location_id': location_dest_id, - # cursor returns None instead of False - 'lot_id': group.get("lot_id") or False, - 'product_uom_id': product.uom_id.id, - 'custom': False, - }) + location_dest_id = ( + self.destination_location_id.get_putaway_strategy(product).id + or self.destination_location_id.id + ) + product_data.append( + { + "product_id": product.id, + "move_quantity": group.get("sum"), + "max_quantity": group.get("sum"), + "origin_location_id": self.origin_location_id.id, + "destination_location_id": location_dest_id, + # cursor returns None instead of False + "lot_id": group.get("lot_id") or False, + "product_uom_id": product.uom_id.id, + "custom": False, + } + ) return product_data - @api.onchange('origin_location_id') + @api.onchange("origin_location_id") def onchange_origin_location(self): lines = [] if self.origin_location_id: line_model = self.env["wiz.stock.move.location.line"] for line_val in self._get_stock_move_location_lines_values(): - if line_val.get('max_quantity') <= 0: + if line_val.get("max_quantity") <= 0: continue line = line_model.create(line_val) line.max_quantity = line.get_max_quantity() lines.append(line) # self.stock_move_location_line_ids = [(4, line.id)] - self.update({'stock_move_location_line_ids': [ - (6, 0, [line.id for line in lines])]}) + self.update( + {"stock_move_location_line_ids": [(6, 0, [line.id for line in lines])]} + ) def clear_lines(self): self._clear_lines() - return { - "type": "ir.action.do_nothing", - } + return {"type": "ir.action.do_nothing"} diff --git a/stock_move_location/wizard/stock_move_location_line.py b/stock_move_location/wizard/stock_move_location_line.py index 6fc273a37..643dededf 100644 --- a/stock_move_location/wizard/stock_move_location_line.py +++ b/stock_move_location/wizard/stock_move_location_line.py @@ -3,99 +3,88 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from odoo import _, api, fields, models -from odoo.addons import decimal_precision as dp from odoo.exceptions import ValidationError from odoo.tools import float_compare +from odoo.addons import decimal_precision as dp + class StockMoveLocationWizardLine(models.TransientModel): _name = "wiz.stock.move.location.line" - _description = 'Wizard move location line' + _description = "Wizard move location line" product_id = fields.Many2one( - string="Product", - comodel_name="product.product", - required=True, + string="Product", comodel_name="product.product", required=True ) origin_location_id = fields.Many2one( - string='Origin Location', - comodel_name='stock.location', + string="Origin Location", comodel_name="stock.location" ) destination_location_id = fields.Many2one( - string='Destination Location', - comodel_name='stock.location', + string="Destination Location", comodel_name="stock.location" ) product_uom_id = fields.Many2one( - string='Product Unit of Measure', - comodel_name='uom.uom', + string="Product Unit of Measure", comodel_name="uom.uom" ) lot_id = fields.Many2one( - string='Lot/Serial Number', - comodel_name='stock.production.lot', - domain="[('product_id','=',product_id)]" + string="Lot/Serial Number", + comodel_name="stock.production.lot", + domain="[('product_id','=',product_id)]", ) move_quantity = fields.Float( - string="Quantity to move", - digits=dp.get_precision('Product Unit of Measure'), + string="Quantity to move", digits=dp.get_precision("Product Unit of Measure") ) max_quantity = fields.Float( string="Maximum available quantity", - digits=dp.get_precision('Product Unit of Measure'), - ) - custom = fields.Boolean( - string="Custom line", - default=True, + digits=dp.get_precision("Product Unit of Measure"), ) + custom = fields.Boolean(string="Custom line", default=True) @staticmethod def _compare(qty1, qty2, precision_rounding): - return float_compare( - qty1, qty2, - precision_rounding=precision_rounding) + return float_compare(qty1, qty2, precision_rounding=precision_rounding) @api.constrains("max_quantity", "move_quantity") def _constraint_max_move_quantity(self): for record in self: rounding = record.product_uom_id.rounding - move_qty_gt_max_qty = self._compare( - record.move_quantity, record.max_quantity, rounding) == 1 - move_qty_lt_0 = self._compare( - record.move_quantity, 0.0, rounding) == -1 - if (move_qty_gt_max_qty or move_qty_lt_0): - raise ValidationError(_( - "Move quantity can not exceed max quantity or be negative" - )) + move_qty_gt_max_qty = ( + self._compare(record.move_quantity, record.max_quantity, rounding) == 1 + ) + move_qty_lt_0 = self._compare(record.move_quantity, 0.0, rounding) == -1 + if move_qty_gt_max_qty or move_qty_lt_0: + raise ValidationError( + _("Move quantity can not exceed max quantity or be negative") + ) def get_max_quantity(self): self.product_uom_id = self.product_id.uom_id search_args = [ - ('location_id', '=', self.origin_location_id.id), - ('product_id', '=', self.product_id.id), + ("location_id", "=", self.origin_location_id.id), + ("product_id", "=", self.product_id.id), ] if self.lot_id: - search_args.append(('lot_id', '=', self.lot_id.id)) + search_args.append(("lot_id", "=", self.lot_id.id)) else: - search_args.append(('lot_id', '=', False)) - res = self.env['stock.quant'].read_group(search_args, ['quantity'], []) - max_quantity = res[0]['quantity'] + search_args.append(("lot_id", "=", False)) + res = self.env["stock.quant"].read_group(search_args, ["quantity"], []) + max_quantity = res[0]["quantity"] return max_quantity def create_move_lines(self, picking, move): for line in self: values = line._get_move_line_values(picking, move) - if not self.env.context.get("planned") and \ - values.get("qty_done") <= 0: + if not self.env.context.get("planned") and values.get("qty_done") <= 0: continue - self.env["stock.move.line"].create( - values - ) + self.env["stock.move.line"].create(values) return True @api.multi def _get_move_line_values(self, picking, move): self.ensure_one() - location_dest_id = self.destination_location_id.get_putaway_strategy( - self.product_id).id or self.destination_location_id.id + location_dest_id = ( + self.destination_location_id.get_putaway_strategy(self.product_id).id + or self.destination_location_id.id + ) qty_todo, qty_done = self._get_available_quantity() return { "product_id": self.product_id.id, @@ -121,22 +110,23 @@ class StockMoveLocationWizardLine(models.TransientModel): # for planned transfer we don't care about the amounts at all return self.move_quantity, 0 search_args = [ - ('location_id', '=', self.origin_location_id.id), - ('product_id', '=', self.product_id.id), + ("location_id", "=", self.origin_location_id.id), + ("product_id", "=", self.product_id.id), ] if self.lot_id: - search_args.append(('lot_id', '=', self.lot_id.id)) + search_args.append(("lot_id", "=", self.lot_id.id)) else: - search_args.append(('lot_id', '=', False)) - res = self.env['stock.quant'].read_group(search_args, ['quantity'], []) - available_qty = res[0]['quantity'] + search_args.append(("lot_id", "=", False)) + res = self.env["stock.quant"].read_group(search_args, ["quantity"], []) + available_qty = res[0]["quantity"] if not available_qty: # if it is immediate transfer and product doesn't exist in that # location -> make the transfer of 0. return 0 rounding = self.product_uom_id.rounding - available_qty_lt_move_qty = self._compare( - available_qty, self.move_quantity, rounding) == -1 + available_qty_lt_move_qty = ( + self._compare(available_qty, self.move_quantity, rounding) == -1 + ) if available_qty_lt_move_qty: return available_qty return 0, self.move_quantity