add stock_inventory_product_exhausted: prevent for removing zero quantity stock quants. Add exhausted products to inventory adjustments

This commit is contained in:
Luis 2025-10-01 13:27:34 +02:00
parent e4050a6e31
commit 17cc64c522
15 changed files with 565 additions and 0 deletions

View file

@ -0,0 +1 @@
from . import stock_inventory

View file

@ -0,0 +1,113 @@
# Copyright 2025 Your Name or Company
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, models, api, fields
import logging
_logger = logging.getLogger(__name__)
class StockInventory(models.Model):
_inherit = "stock.inventory"
include_exhausted_products = fields.Boolean(
string="Include Exhausted Products",
help="If enabled, products with zero stock will be included "
"in the inventory adjustment by creating zero-quantity quants.",
default=False,
)
def _create_zero_quants(self, locations, products):
"""Create zero-quantity quants for products without existing quants.
This method creates stock quants with zero quantity for storable products
that don't have existing quants in the specified locations. This allows
these products to be included in inventory adjustments even when they
have no current stock.
Args:
locations (stock.location recordset): Locations to check
products (product.product recordset): Products to process
"""
Quant = self.env["stock.quant"]
# Get existing quants to avoid duplicates
existing_quants = Quant.search(
[
("product_id", "in", products.ids),
("location_id", "in", locations.ids),
]
)
existing_combinations = {
(q.product_id.id, q.location_id.id) for q in existing_quants
}
quants_to_create = []
for location in locations:
for product in products.filtered(lambda p: p.type == "product"):
if (product.id, location.id) not in existing_combinations:
_logger.debug(
"Creating zero quant for product %s in location %s",
product.name,
location.name,
)
quants_to_create.append(
{
"product_id": product.id,
"location_id": location.id,
"quantity": 0,
"company_id": location.company_id.id or self.env.company.id,
}
)
if quants_to_create:
Quant.create(quants_to_create)
def _get_quants(self, locations):
"""Override to include zero-quantity quants when requested.
This method extends the base functionality to optionally include
products with zero stock by creating zero-quantity quants before
retrieving the final quant list.
Args:
locations (stock.location recordset): Locations for inventory
Returns:
stock.quant recordset: Quants to include in inventory
"""
quants = super()._get_quants(locations)
if self.include_exhausted_products:
# Determine products based on selection criteria
if self.product_selection == "category":
products = self.env["product.product"].search(
[("categ_id", "child_of", self.category_id.id)]
)
elif self.product_selection in ("manual", "one", "lot"):
products = self.product_ids
else: # "all"
products = self.env["product.product"].search(
[("type", "=", "product")]
)
self._create_zero_quants(locations, products)
# Re-fetch quants to include newly created ones
return super()._get_quants(locations)
return quants
class StockQuant(models.Model):
_inherit = "stock.quant"
@api.model
def _unlink_zero_quants(self):
"""Prevent automatic unlinking of zero quants.
This method overrides the default behavior to prevent
zero quants from being automatically removed.
This may need review to ensure it doesn't conflict
with standard Odoo behavior.
"""
_logger.debug("Preventing automatic unlinking of zero quants")