diff --git a/stock_inventory_preparation_filter/__init__.py b/stock_inventory_preparation_filter/__init__.py index a9e337226..0650744f6 100644 --- a/stock_inventory_preparation_filter/__init__.py +++ b/stock_inventory_preparation_filter/__init__.py @@ -1,2 +1 @@ - from . import models diff --git a/stock_inventory_preparation_filter/__manifest__.py b/stock_inventory_preparation_filter/__manifest__.py index cc130eedf..af798d608 100644 --- a/stock_inventory_preparation_filter/__manifest__.py +++ b/stock_inventory_preparation_filter/__manifest__.py @@ -6,19 +6,12 @@ { "name": "Extended Inventory Preparation Filters", "version": "12.0.1.1.0", - "depends": [ - "stock", - ], - "author": "AvanzOSC," - "Tecnativa," - "Odoo Community Association (OCA)", + "depends": ["stock"], + "author": "AvanzOSC," "Tecnativa," "Odoo Community Association (OCA)", "category": "Inventory, Logistic, Storage", "website": "http://github.com/OCA/stock-logistics-warehouse", "summary": "More filters for inventory adjustments", - "data": [ - "views/stock_inventory_view.xml", - "security/ir.model.access.csv", - ], - 'installable': True, - "license": 'AGPL-3', + "data": ["views/stock_inventory_view.xml", "security/ir.model.access.csv"], + "installable": True, + "license": "AGPL-3", } diff --git a/stock_inventory_preparation_filter/models/__init__.py b/stock_inventory_preparation_filter/models/__init__.py index 5f81629c4..35536816e 100644 --- a/stock_inventory_preparation_filter/models/__init__.py +++ b/stock_inventory_preparation_filter/models/__init__.py @@ -1,2 +1 @@ - from . import stock_inventory diff --git a/stock_inventory_preparation_filter/models/stock_inventory.py b/stock_inventory_preparation_filter/models/stock_inventory.py index 17a42d1fb..adb19e4ba 100644 --- a/stock_inventory_preparation_filter/models/stock_inventory.py +++ b/stock_inventory_preparation_filter/models/stock_inventory.py @@ -3,34 +3,32 @@ # 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.tools.safe_eval import safe_eval +from odoo.addons import decimal_precision as dp + class StockInventoryEmptyLines(models.Model): - _name = 'stock.inventory.line.empty' - _description = 'Inventory Line Empty' + _name = "stock.inventory.line.empty" + _description = "Inventory Line Empty" - product_code = fields.Char( - string='Product Code', - required=True, - ) + product_code = fields.Char(string="Product Code", required=True) product_qty = fields.Float( - string='Quantity', + string="Quantity", required=True, default=1.0, - digits=dp.get_precision('Product Unit of Measure'), + digits=dp.get_precision("Product Unit of Measure"), ) inventory_id = fields.Many2one( - comodel_name='stock.inventory', - string='Inventory', + comodel_name="stock.inventory", + string="Inventory", required=True, ondelete="cascade", ) class StockInventory(models.Model): - _inherit = 'stock.inventory' + _inherit = "stock.inventory" @api.model def _selection_filter(self): @@ -40,90 +38,105 @@ class StockInventory(models.Model): :return: list of tuple """ res_filters = super(StockInventory, self)._selection_filter() - res_filters.append(('categories', _('Selected Categories'))) - res_filters.append(('products', _('Selected Products'))) - res_filters.append(('domain', _('Filtered Products'))) + res_filters.append(("categories", _("Selected Categories"))) + res_filters.append(("products", _("Selected Products"))) + res_filters.append(("domain", _("Filtered Products"))) for res_filter in res_filters: - if res_filter[0] == 'lot': - res_filters.append(('lots', _('Selected Lots'))) + if res_filter[0] == "lot": + res_filters.append(("lots", _("Selected Lots"))) break - res_filters.append(('empty', _('Empty list'))) + res_filters.append(("empty", _("Empty list"))) return res_filters categ_ids = fields.Many2many( - comodel_name='product.category', relation='rel_inventories_categories', - column1='inventory_id', column2='category_id', string='Categories') + comodel_name="product.category", + relation="rel_inventories_categories", + column1="inventory_id", + column2="category_id", + string="Categories", + ) product_ids = fields.Many2many( - comodel_name='product.product', relation='rel_inventories_products', - column1='inventory_id', column2='product_id', string='Products') + comodel_name="product.product", + relation="rel_inventories_products", + column1="inventory_id", + column2="product_id", + string="Products", + ) lot_ids = fields.Many2many( - comodel_name='stock.production.lot', relation='rel_inventories_lots', - column1='inventory_id', column2='lot_id', string='Lots') + comodel_name="stock.production.lot", + relation="rel_inventories_lots", + column1="inventory_id", + column2="lot_id", + string="Lots", + ) empty_line_ids = fields.One2many( - comodel_name='stock.inventory.line.empty', inverse_name='inventory_id', - string='Capture Lines') - product_domain = fields.Char('Domain', default=[('name', 'ilike', '')]) + comodel_name="stock.inventory.line.empty", + inverse_name="inventory_id", + string="Capture Lines", + ) + product_domain = fields.Char("Domain", default=[("name", "ilike", "")]) @api.model def _get_inventory_lines_values(self): self.ensure_one() vals = [] - product_obj = self.env['product.product'] + product_obj = self.env["product.product"] inventory = self.new(self._convert_to_write(self.read()[0])) - if self.filter in ('categories', 'products'): - if self.filter == 'categories': - products = product_obj.search([ - ('product_tmpl_id.categ_id', 'in', self.categ_ids.ids) - ]) + if self.filter in ("categories", "products"): + if self.filter == "categories": + products = product_obj.search( + [("product_tmpl_id.categ_id", "in", self.categ_ids.ids)] + ) else: # filter = 'products' products = self.product_ids - inventory.filter = 'product' + inventory.filter = "product" for product in products: inventory.product_id = product - vals += super(StockInventory, - inventory)._get_inventory_lines_values() - elif self.filter == 'lots': - inventory.filter = 'lot' + vals += super(StockInventory, inventory)._get_inventory_lines_values() + elif self.filter == "lots": + inventory.filter = "lot" for lot in self.lot_ids: inventory.lot_id = lot - vals += super(StockInventory, - inventory)._get_inventory_lines_values() - elif self.filter == 'domain': + vals += super(StockInventory, inventory)._get_inventory_lines_values() + elif self.filter == "domain": domain = safe_eval(self.product_domain) - products = self.env['product.product'].search(domain) - inventory.filter = 'product' + products = self.env["product.product"].search(domain) + inventory.filter = "product" for product in products: inventory.product_id = product - vals += super( - StockInventory, inventory)._get_inventory_lines_values() - elif self.filter == 'empty': + vals += super(StockInventory, inventory)._get_inventory_lines_values() + elif self.filter == "empty": tmp_lines = {} for line in self.empty_line_ids: tmp_lines.setdefault(line.product_code, 0) tmp_lines[line.product_code] += line.product_qty self.empty_line_ids.unlink() - inventory.filter = 'product' + inventory.filter = "product" # HACK: Make sure location is preserved inventory.location_id = self.location_id for product_code in tmp_lines.keys(): - product = product_obj.search([ - '|', - ('default_code', '=', product_code), - ('barcode', '=', product_code), - ], limit=1) + product = product_obj.search( + [ + "|", + ("default_code", "=", product_code), + ("barcode", "=", product_code), + ], + limit=1, + ) if not product: continue inventory.product_id = product - values = super(StockInventory, - inventory)._get_inventory_lines_values() + values = super(StockInventory, inventory)._get_inventory_lines_values() if values: - values[0]['product_qty'] = tmp_lines[product_code] + values[0]["product_qty"] = tmp_lines[product_code] else: - vals += [{ - 'product_id': product.id, - 'product_qty': tmp_lines[product_code], - 'location_id': self.location_id.id, - }] + vals += [ + { + "product_id": product.id, + "product_qty": tmp_lines[product_code], + "location_id": self.location_id.id, + } + ] vals += values else: vals = super()._get_inventory_lines_values() diff --git a/stock_inventory_preparation_filter/tests/__init__.py b/stock_inventory_preparation_filter/tests/__init__.py index 76616c897..2b1fb0a23 100644 --- a/stock_inventory_preparation_filter/tests/__init__.py +++ b/stock_inventory_preparation_filter/tests/__init__.py @@ -1,2 +1 @@ - from . import test_stock_inventory_preparation_filter diff --git a/stock_inventory_preparation_filter/tests/test_stock_inventory_preparation_filter.py b/stock_inventory_preparation_filter/tests/test_stock_inventory_preparation_filter.py index cbdf51c1c..99d3d27c0 100644 --- a/stock_inventory_preparation_filter/tests/test_stock_inventory_preparation_filter.py +++ b/stock_inventory_preparation_filter/tests/test_stock_inventory_preparation_filter.py @@ -10,88 +10,105 @@ from odoo.tests import common class TestStockInventoryPreparationFilterCategories(common.TransactionCase): def setUp(self): super(TestStockInventoryPreparationFilterCategories, self).setUp() - self.inventory_model = self.env['stock.inventory'] + self.inventory_model = self.env["stock.inventory"] # Create some categories - self.category = self.env['product.category'].create({ - 'name': 'Category for inventory', - }) - self.category2 = self.env['product.category'].create({ - 'name': 'Category for inventory 2', - }) + self.category = self.env["product.category"].create( + {"name": "Category for inventory"} + ) + self.category2 = self.env["product.category"].create( + {"name": "Category for inventory 2"} + ) # Create some products in the category - self.product1 = self.env['product.product'].create({ - 'name': 'Product for inventory 1', - 'type': 'product', - 'categ_id': self.category.id, - 'default_code': 'PROD1-TEST', - }) - self.product2 = self.env['product.product'].create({ - 'name': 'Product for inventory 2', - 'type': 'product', - 'categ_id': self.category.id, - 'default_code': 'PROD2-TEST', - }) - self.product3 = self.env['product.product'].create({ - 'name': 'Product for inventory 3', - 'type': 'product', - 'categ_id': self.category.id, - 'default_code': 'PROD3-TEST', - }) - self.product_lot = self.env['product.product'].create({ - 'name': 'Product for inventory with lots', - 'type': 'product', - 'categ_id': self.category2.id, - }) - self.lot = self.env['stock.production.lot'].create({ - 'name': 'Lot test', - 'product_id': self.product_lot.id, - }) + self.product1 = self.env["product.product"].create( + { + "name": "Product for inventory 1", + "type": "product", + "categ_id": self.category.id, + "default_code": "PROD1-TEST", + } + ) + self.product2 = self.env["product.product"].create( + { + "name": "Product for inventory 2", + "type": "product", + "categ_id": self.category.id, + "default_code": "PROD2-TEST", + } + ) + self.product3 = self.env["product.product"].create( + { + "name": "Product for inventory 3", + "type": "product", + "categ_id": self.category.id, + "default_code": "PROD3-TEST", + } + ) + self.product_lot = self.env["product.product"].create( + { + "name": "Product for inventory with lots", + "type": "product", + "categ_id": self.category2.id, + } + ) + self.lot = self.env["stock.production.lot"].create( + {"name": "Lot test", "product_id": self.product_lot.id} + ) # Add user to lot tracking group - self.env.user.groups_id = [ - (4, self.env.ref('stock.group_production_lot').id), - ] + self.env.user.groups_id = [(4, self.env.ref("stock.group_production_lot").id)] # And have some stock in a location - self.location = self.env['stock.location'].create({ - 'name': 'Inventory tests', - 'usage': 'internal', - }) - inventory = self.inventory_model.create({ - 'name': 'Product1 inventory', - 'filter': 'product', - 'line_ids': [ - (0, 0, { - 'product_id': self.product1.id, - 'product_uom_id': self.env.ref( - "uom.product_uom_unit").id, - 'product_qty': 2.0, - 'location_id': self.location.id, - }), - (0, 0, { - 'product_id': self.product2.id, - 'product_uom_id': self.env.ref( - "uom.product_uom_unit").id, - 'product_qty': 4.0, - 'location_id': self.location.id, - }), - (0, 0, { - 'product_id': self.product_lot.id, - 'product_uom_id': self.env.ref( - "uom.product_uom_unit").id, - 'product_qty': 6.0, - 'location_id': self.location.id, - 'prod_lot_id': self.lot.id, - }), - ], - }) + self.location = self.env["stock.location"].create( + {"name": "Inventory tests", "usage": "internal"} + ) + inventory = self.inventory_model.create( + { + "name": "Product1 inventory", + "filter": "product", + "line_ids": [ + ( + 0, + 0, + { + "product_id": self.product1.id, + "product_uom_id": self.env.ref("uom.product_uom_unit").id, + "product_qty": 2.0, + "location_id": self.location.id, + }, + ), + ( + 0, + 0, + { + "product_id": self.product2.id, + "product_uom_id": self.env.ref("uom.product_uom_unit").id, + "product_qty": 4.0, + "location_id": self.location.id, + }, + ), + ( + 0, + 0, + { + "product_id": self.product_lot.id, + "product_uom_id": self.env.ref("uom.product_uom_unit").id, + "product_qty": 6.0, + "location_id": self.location.id, + "prod_lot_id": self.lot.id, + }, + ), + ], + } + ) inventory._action_done() def test_inventory_category_filter(self): - inventory = self.inventory_model.create({ - 'name': 'Category inventory', - 'filter': 'categories', - 'location_id': self.location.id, - 'categ_ids': [(6, 0, [self.category.id])], - }) + inventory = self.inventory_model.create( + { + "name": "Category inventory", + "filter": "categories", + "location_id": self.location.id, + "categ_ids": [(6, 0, [self.category.id])], + } + ) inventory.action_start() self.assertEqual(len(inventory.line_ids), 2) line1 = inventory.line_ids[0] @@ -104,12 +121,14 @@ class TestStockInventoryPreparationFilterCategories(common.TransactionCase): self.assertEqual(line2.location_id, self.location) def test_inventory_products_filter(self): - inventory = self.inventory_model.create({ - 'name': 'Products inventory', - 'filter': 'products', - 'location_id': self.location.id, - 'product_ids': [(6, 0, [self.product1.id, self.product2.id])], - }) + inventory = self.inventory_model.create( + { + "name": "Products inventory", + "filter": "products", + "location_id": self.location.id, + "product_ids": [(6, 0, [self.product1.id, self.product2.id])], + } + ) inventory.action_start() self.assertEqual(len(inventory.line_ids), 2) line1 = inventory.line_ids[0] @@ -122,12 +141,14 @@ class TestStockInventoryPreparationFilterCategories(common.TransactionCase): self.assertEqual(line2.location_id, self.location) def test_inventory_domain_filter(self): - inventory = self.inventory_model.create({ - 'name': 'Domain inventory', - 'filter': 'domain', - 'location_id': self.location.id, - 'product_domain': [('id', '=', self.product1.id)], - }) + inventory = self.inventory_model.create( + { + "name": "Domain inventory", + "filter": "domain", + "location_id": self.location.id, + "product_domain": [("id", "=", self.product1.id)], + } + ) inventory.action_start() self.assertEqual(len(inventory.line_ids), 1) line1 = inventory.line_ids[0] @@ -138,10 +159,10 @@ class TestStockInventoryPreparationFilterCategories(common.TransactionCase): def test_inventory_lots_filter(self): inventory = self.inventory_model.create( { - 'name': 'Products inventory', - 'filter': 'lots', - 'location_id': self.location.id, - 'lot_ids': [(6, 0, [self.lot.id, ])], + "name": "Products inventory", + "filter": "lots", + "location_id": self.location.id, + "lot_ids": [(6, 0, [self.lot.id])], } ) inventory.action_start() @@ -153,29 +174,19 @@ class TestStockInventoryPreparationFilterCategories(common.TransactionCase): self.assertEqual(line1.location_id, self.location) def test_inventory_empty_filter(self): - inventory = self.inventory_model.create({ - 'name': 'Products inventory', - 'filter': 'empty', - 'location_id': self.location.id, - 'empty_line_ids': [ - (0, 0, { - 'product_code': 'PROD1-TEST', - 'product_qty': 3.0, - }), - (0, 0, { - 'product_code': 'PROD2-TEST', - 'product_qty': 7.0, - }), - (0, 0, { - 'product_code': 'PROD3-TEST', - 'product_qty': 5.0, - }), - (0, 0, { - 'product_code': 'UNEXISTING-CODE', - 'product_qty': 0.0, - }), - ], - }) + inventory = self.inventory_model.create( + { + "name": "Products inventory", + "filter": "empty", + "location_id": self.location.id, + "empty_line_ids": [ + (0, 0, {"product_code": "PROD1-TEST", "product_qty": 3.0}), + (0, 0, {"product_code": "PROD2-TEST", "product_qty": 7.0}), + (0, 0, {"product_code": "PROD3-TEST", "product_qty": 5.0}), + (0, 0, {"product_code": "UNEXISTING-CODE", "product_qty": 0.0}), + ], + } + ) inventory.action_start() self.assertEqual(len(inventory.line_ids), 3) line1 = inventory.line_ids[0]