From 0964d97387c89989323e2e527be6357ebef9d032 Mon Sep 17 00:00:00 2001 From: nicolas Date: Thu, 27 Jan 2022 14:12:38 -0300 Subject: [PATCH] [13.0] [IMP] stock_inventory_include_exhausted: Use the locations in the stock inventy for exhausted. Now we consider the locations selected in the inventory when create the lines for the exhausted values. We use an approch similar to odoo in v14 to solve this problem. --- .../models/stock_inventory.py | 55 +++++++++------- .../test_stock_inventory_include_exhausted.py | 65 +++++++++++++++---- 2 files changed, 85 insertions(+), 35 deletions(-) diff --git a/stock_inventory_include_exhausted/models/stock_inventory.py b/stock_inventory_include_exhausted/models/stock_inventory.py index f1b81f789..bcd33eb44 100644 --- a/stock_inventory_include_exhausted/models/stock_inventory.py +++ b/stock_inventory_include_exhausted/models/stock_inventory.py @@ -17,27 +17,38 @@ class StockInventory(models.Model): vals = super()._get_inventory_lines_values() if self.include_exhausted: - domain = [("qty_available", "=", 0), ("type", "=", "product")] - product_ids = [data.get("product_id") for data in vals] - domain.append(("id", "not in", product_ids)) + non_exhausted_set = {(l["product_id"], l["location_id"]) for l in vals} if self.product_ids: - domain.append(("id", "in", self.product_ids.ids)) - exhausted_products = self.env["product.product"].search(domain) - vals_dic = { - "inventory_id": self.id, - "company_id": self.company_id.id, - "product_qty": 0, - "theoretical_qty": 0, - } - vals_dic["location_id"] = ( - self.env["stock.warehouse"] - .search([("company_id", "=", vals_dic["company_id"])], limit=1) - .lot_stock_id.id - ) - for product in exhausted_products: - vals_dic["product_id"] = product.id - vals_dic["product_uom_id"] = product.uom_id.id - - vals.append(vals_dic.copy()) - + product_ids = self.product_ids.ids + else: + product_ids = self.env["product.product"].search_read( + [ + "|", + ("company_id", "=", self.company_id.id), + ("company_id", "=", False), + ("type", "=", "product"), + ("active", "=", True), + ], + ["id"], + ) + product_ids = [p["id"] for p in product_ids] + if self.location_ids: + location_ids = self.location_ids.ids + else: + location_ids = ( + self.env["stock.warehouse"] + .search([("company_id", "=", self.company_id.id)]) + .lot_stock_id.ids + ) + for product in product_ids: + for location_id in location_ids: + if (product, location_id) not in non_exhausted_set: + vals.append( + { + "inventory_id": self.id, + "product_id": product, + "location_id": location_id, + "theoretical_qty": 0, + } + ) return vals diff --git a/stock_inventory_include_exhausted/tests/test_stock_inventory_include_exhausted.py b/stock_inventory_include_exhausted/tests/test_stock_inventory_include_exhausted.py index bfc8d9001..c355ca223 100644 --- a/stock_inventory_include_exhausted/tests/test_stock_inventory_include_exhausted.py +++ b/stock_inventory_include_exhausted/tests/test_stock_inventory_include_exhausted.py @@ -18,9 +18,7 @@ class StockInventoryIncludeExhaustedTest(TransactionCase): # We need this to know how many product with no stock we have on our # database self.quantity_out_of_stock = len( - self.env["product.product"].search( - [("qty_available", "=", 0), ("type", "=", "product")] - ) + self.env["product.product"].search([("type", "=", "product")]) ) self.user = self.res_users_model.create( @@ -48,6 +46,11 @@ class StockInventoryIncludeExhaustedTest(TransactionCase): } ) + self.quantity_out_of_stock_by_product = len( + self.env["product.product"].search( + [("id", "=", self.product1.id), ("type", "=", "product")] + ) + ) self.location = self.location_model.create( {"name": "Inventory tests 1", "usage": "internal"} ) @@ -55,21 +58,26 @@ class StockInventoryIncludeExhaustedTest(TransactionCase): {"name": "Inventory tests 2", "usage": "internal"} ) - def _create_inventory_all_products(self, name, location, include_exhausted): - inventory = self.inventory_model.create( - { - "name": name, - "location_ids": [(4, location.id)], - "include_exhausted": include_exhausted, - } - ) + def _create_inventory_all_products( + self, name, include_exhausted, location=False, product=False + ): + vals = { + "name": name, + "include_exhausted": include_exhausted, + } + if location: + vals["location_ids"] = [(4, location.id)] + if product: + vals["product_ids"] = [(4, product.id)] + + inventory = self.inventory_model.create(vals) return inventory def test_not_including_exhausted(self): """Check if products with no stock are not included into the inventory if the including exhausted option is disabled.""" inventory_not_inc = self._create_inventory_all_products( - "not_included", self.location, False + "not_included", False, self.location ) inventory_not_inc.action_start() inventory_not_inc.action_validate() @@ -83,8 +91,8 @@ class StockInventoryIncludeExhaustedTest(TransactionCase): # The products with no stock don't have a location, # that's why search the non-stocked in all locations "included", - self.location, True, + location=self.location, ) inventory_inc.action_start() @@ -95,3 +103,34 @@ class StockInventoryIncludeExhaustedTest(TransactionCase): self.quantity_out_of_stock + 2, "The products with no stock are not included", ) + + def test_not_including_exhausted_with_product(self): + """Check if products with no stock are not included into the inventory + if the including exhausted option is disabled.""" + inventory_not_inc = self._create_inventory_all_products( + "not_included", False, product=self.product1 + ) + inventory_not_inc.action_start() + inventory_not_inc.action_validate() + lines = inventory_not_inc.line_ids + self.assertEqual(len(lines), 0, "Not all expected products are included") + + def test_including_exhausted_with_product(self): + """Check if products with no stock are included into the inventory + if the including exhausted option is enabled.""" + inventory_inc = self._create_inventory_all_products( + # The products with no stock don't have a location, + # that's why search the non-stocked in all locations + "included", + True, + product=self.product1, + ) + + inventory_inc.action_start() + inventory_inc.action_validate() + lines = inventory_inc.line_ids + self.assertEqual( + len(lines), + self.quantity_out_of_stock_by_product, + "The products with no stock are not included", + )