add stock_inventory_product_exhausted: prevent for removing zero quantity stock quants. Add exhausted products to inventory adjustments
This commit is contained in:
parent
e4050a6e31
commit
17cc64c522
15 changed files with 565 additions and 0 deletions
133
stock_inventory_product_exhausted/README.rst
Normal file
133
stock_inventory_product_exhausted/README.rst
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
==========================================
|
||||
Stock Inventory Exhausted Products
|
||||
==========================================
|
||||
|
||||
..
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:...
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Beta
|
||||
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_inventory_product_exhausted
|
||||
:alt: OCA/stock-logistics-warehouse
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-16-0/stock-logistics-warehouse-16-0-stock_inventory_product_exhausted
|
||||
:alt: Translate me on Weblate
|
||||
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
||||
:target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=16.0
|
||||
:alt: Try me on Runboat
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
|
||||
This module extends the functionality of the `stock_inventory` module from the OCA/stock-logistics-warehouse repository to include exhausted products (with zero quantity) in inventory adjustments.
|
||||
|
||||
In recent versions of Odoo, when a product reaches zero available quantity, its `stock.quant` is automatically deleted. This module allows creating quants with zero quantity for exhausted products when creating a new inventory adjustment, facilitating the physical counting of these products.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
* **Configurable field**: Includes a boolean field `include_exhausted_products` to enable/disable the functionality
|
||||
* **Default behavior**: Maintains the original behavior of the base module when the option is disabled
|
||||
* **Support for all selection types**: Works with manual selection, by category, specific product, or all products
|
||||
* **Storable products only**: Creates quants only for products of type `product`, not for services
|
||||
* **Prevents duplicates**: Does not create duplicate quants if they already exist for the product and location
|
||||
* **User interface**: Field visible in the inventory adjustment form
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
The module requires no additional configuration. The `include_exhausted_products` field defaults to `False` to maintain compatibility with the original behavior.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To use this module:
|
||||
|
||||
#. Go to **Inventory > Operations > Inventory Adjustments**
|
||||
#. Create a new inventory adjustment
|
||||
#. Configure the desired locations and product selection
|
||||
#. **Enable** the "Include Exhausted Products" field if you want to include products without stock
|
||||
#. Click on "Start Inventory"
|
||||
|
||||
Use cases
|
||||
---------
|
||||
|
||||
**With the field enabled:**
|
||||
|
||||
* Zero quantity quants will be created for products that have no stock in the selected locations
|
||||
* Allows physically counting products that are exhausted in the system
|
||||
* Useful for complete inventories where you want to verify that there really is no stock of certain products
|
||||
|
||||
**With the field disabled:**
|
||||
|
||||
* Standard behavior of the original module
|
||||
* Only products that already have existing quants are included
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
* Review the necessity of the StockQuant class override
|
||||
* Consider performance optimizations for large product catalogs
|
||||
* Add option to filter by product categories when including exhausted products
|
||||
|
||||
Bug Tracker
|
||||
============
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us smash it by providing detailed and welcomed
|
||||
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_inventory_product_exhausted%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Do not contact contributors directly about support or help with technical issues.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
* Criptomart
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Luis Norte <luisnore@example.com>
|
||||
|
||||
Maintainers
|
||||
~~~~~~~~~~~
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
.. |maintainer-luisnore| image:: https://github.com/luisnore.png?size=40px
|
||||
:target: https://github.com/luisnore
|
||||
:alt: luisnore
|
||||
|
||||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|
||||
|
||||
|maintainer-luisnore|
|
||||
|
||||
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_inventory_product_exhausted>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
1
stock_inventory_product_exhausted/__init__.py
Normal file
1
stock_inventory_product_exhausted/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import models
|
||||
16
stock_inventory_product_exhausted/__manifest__.py
Normal file
16
stock_inventory_product_exhausted/__manifest__.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "Stock Inventory Exhausted Products",
|
||||
"version": "16.0.1.0.0",
|
||||
"development_status": "Beta",
|
||||
"depends": ["stock_inventory"],
|
||||
"author": "Criptomart, Odoo Community Association (OCA)",
|
||||
"maintainers": ["luisnore"],
|
||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||
"license": "AGPL-3",
|
||||
"category": "Warehouse",
|
||||
"summary": "Create quants for products with zero quantity in stock adjustments",
|
||||
"data": [
|
||||
"views/stock_inventory.xml",
|
||||
],
|
||||
"installable": True,
|
||||
}
|
||||
1
stock_inventory_product_exhausted/models/__init__.py
Normal file
1
stock_inventory_product_exhausted/models/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import stock_inventory
|
||||
113
stock_inventory_product_exhausted/models/stock_inventory.py
Normal file
113
stock_inventory_product_exhausted/models/stock_inventory.py
Normal 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")
|
||||
6
stock_inventory_product_exhausted/readme/BUGTRACKER.rst
Normal file
6
stock_inventory_product_exhausted/readme/BUGTRACKER.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us smash it by providing detailed and welcomed
|
||||
`feedback <https://github.com/OCA/stock-logistics-warehouse/issues/new?body=module:%20stock_inventory_product_exhausted%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Do not contact contributors directly about support or help with technical issues.
|
||||
1
stock_inventory_product_exhausted/readme/CONFIGURE.rst
Normal file
1
stock_inventory_product_exhausted/readme/CONFIGURE.rst
Normal file
|
|
@ -0,0 +1 @@
|
|||
The module requires no additional configuration. The `include_exhausted_products` field defaults to `False` to maintain compatibility with the original behavior.
|
||||
21
stock_inventory_product_exhausted/readme/CONTRIBUTORS.rst
Normal file
21
stock_inventory_product_exhausted/readme/CONTRIBUTORS.rst
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
This module is maintained by the OCA.
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
.. |maintainer-yourusername| image:: https://github.com/yourusername.png?size=40px
|
||||
:target: https://github.com/yourusername
|
||||
:alt: yourusername
|
||||
|
||||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|
||||
|
||||
|maintainer-yourusername|
|
||||
|
||||
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_inventory_product_exhausted>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
3
stock_inventory_product_exhausted/readme/DESCRIPTION.rst
Normal file
3
stock_inventory_product_exhausted/readme/DESCRIPTION.rst
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
This module extends the functionality of the `stock_inventory` module from the OCA/stock-logistics-warehouse repository to include exhausted products (with zero quantity) in inventory adjustments.
|
||||
|
||||
In recent versions of Odoo, when a product reaches zero available quantity, its `stock.quant` is automatically deleted. This module allows creating quants with zero quantity for exhausted products when creating a new inventory adjustment, facilitating the physical counting of these products.
|
||||
3
stock_inventory_product_exhausted/readme/DEVELOPMENT.rst
Normal file
3
stock_inventory_product_exhausted/readme/DEVELOPMENT.rst
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
This is a beta version, the data model and design can change at any time without warning.
|
||||
Only for development or testing purpose, do not use in production.
|
||||
`More details on development status <https://odoo-community.org/page/development-status>`_
|
||||
6
stock_inventory_product_exhausted/readme/FEATURES.rst
Normal file
6
stock_inventory_product_exhausted/readme/FEATURES.rst
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
* **Configurable field**: Includes a boolean field `include_exhausted_products` to enable/disable the functionality
|
||||
* **Default behavior**: Maintains the original behavior of the base module when the option is disabled
|
||||
* **Support for all selection types**: Works with manual selection, by category, specific product, or all products
|
||||
* **Storable products only**: Creates quants only for products of type `product`, not for services
|
||||
* **Prevents duplicates**: Does not create duplicate quants if they already exist for the product and location
|
||||
* **User interface**: Field visible in the inventory adjustment form
|
||||
21
stock_inventory_product_exhausted/readme/USAGE.rst
Normal file
21
stock_inventory_product_exhausted/readme/USAGE.rst
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
To use this module:
|
||||
|
||||
#. Go to **Inventory > Operations > Inventory Adjustments**
|
||||
#. Create a new inventory adjustment
|
||||
#. Configure the desired locations and product selection
|
||||
#. **Enable** the "Include Exhausted Products" field if you want to include products without stock
|
||||
#. Click on "Start Inventory"
|
||||
|
||||
Use cases
|
||||
---------
|
||||
|
||||
**With the field enabled:**
|
||||
|
||||
* Zero quantity quants will be created for products that have no stock in the selected locations
|
||||
* Allows physically counting products that are exhausted in the system
|
||||
* Useful for complete inventories where you want to verify that there really is no stock of certain products
|
||||
|
||||
**With the field disabled:**
|
||||
|
||||
* Standard behavior of the original module
|
||||
* Only products that already have existing quants are included
|
||||
1
stock_inventory_product_exhausted/tests/__init__.py
Normal file
1
stock_inventory_product_exhausted/tests/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import test_stock_inventory_exhausted
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestStockInventoryExhausted(TransactionCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# Create test products
|
||||
self.product_with_stock = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product With Stock",
|
||||
"type": "product",
|
||||
"categ_id": self.env.ref("product.product_category_all").id,
|
||||
}
|
||||
)
|
||||
|
||||
self.product_without_stock = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product Without Stock",
|
||||
"type": "product",
|
||||
"categ_id": self.env.ref("product.product_category_all").id,
|
||||
}
|
||||
)
|
||||
|
||||
# Create test location
|
||||
self.location = self.env["stock.location"].create(
|
||||
{
|
||||
"name": "Test Location",
|
||||
"usage": "internal",
|
||||
}
|
||||
)
|
||||
|
||||
# Create initial stock for one product
|
||||
self.env["stock.quant"].create(
|
||||
{
|
||||
"product_id": self.product_with_stock.id,
|
||||
"location_id": self.location.id,
|
||||
"quantity": 10.0,
|
||||
}
|
||||
)
|
||||
|
||||
def test_inventory_without_exhausted_products_flag(self):
|
||||
"""Test that without the flag, zero stock products are not included"""
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test Inventory without flag",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
"product_selection": "all",
|
||||
"include_exhausted_products": False,
|
||||
}
|
||||
)
|
||||
|
||||
inventory.action_start()
|
||||
|
||||
# Should only have quants for products with existing stock
|
||||
self.assertTrue(
|
||||
any(
|
||||
q.product_id == self.product_with_stock
|
||||
for q in inventory.stock_quant_ids
|
||||
)
|
||||
)
|
||||
self.assertFalse(
|
||||
any(
|
||||
q.product_id == self.product_without_stock
|
||||
for q in inventory.stock_quant_ids
|
||||
)
|
||||
)
|
||||
|
||||
def test_inventory_with_exhausted_products_flag(self):
|
||||
"""Test that with the flag, zero stock products are included"""
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test Inventory with flag",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
"product_selection": "all",
|
||||
"include_exhausted_products": True,
|
||||
}
|
||||
)
|
||||
|
||||
inventory.action_start()
|
||||
|
||||
# Should have quants for both products (including zero stock product)
|
||||
self.assertTrue(
|
||||
any(
|
||||
q.product_id == self.product_with_stock
|
||||
for q in inventory.stock_quant_ids
|
||||
)
|
||||
)
|
||||
self.assertTrue(
|
||||
any(
|
||||
q.product_id == self.product_without_stock
|
||||
for q in inventory.stock_quant_ids
|
||||
)
|
||||
)
|
||||
|
||||
# Check that zero stock product has quantity 0
|
||||
zero_quant = inventory.stock_quant_ids.filtered(
|
||||
lambda q: q.product_id == self.product_without_stock
|
||||
)
|
||||
self.assertEqual(zero_quant.quantity, 0.0)
|
||||
|
||||
def test_inventory_manual_selection_with_exhausted_flag(self):
|
||||
"""Test manual product selection with exhausted products flag"""
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test Manual Selection",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
"product_selection": "manual",
|
||||
"product_ids": [(6, 0, [self.product_without_stock.id])],
|
||||
"include_exhausted_products": True,
|
||||
}
|
||||
)
|
||||
|
||||
inventory.action_start()
|
||||
|
||||
# Should have quant for the selected product even if it has zero stock
|
||||
self.assertTrue(
|
||||
any(
|
||||
q.product_id == self.product_without_stock
|
||||
for q in inventory.stock_quant_ids
|
||||
)
|
||||
)
|
||||
zero_quant = inventory.stock_quant_ids.filtered(
|
||||
lambda q: q.product_id == self.product_without_stock
|
||||
)
|
||||
self.assertEqual(zero_quant.quantity, 0.0)
|
||||
|
||||
def test_inventory_category_selection_with_exhausted_flag(self):
|
||||
"""Test category selection with exhausted products flag"""
|
||||
# Create a specific category
|
||||
test_category = self.env["product.category"].create({"name": "Test Category"})
|
||||
|
||||
# Create product in this category
|
||||
product_in_category = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Product In Category",
|
||||
"type": "product",
|
||||
"categ_id": test_category.id,
|
||||
}
|
||||
)
|
||||
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test Category Selection",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
"product_selection": "category",
|
||||
"category_id": test_category.id,
|
||||
"include_exhausted_products": True,
|
||||
}
|
||||
)
|
||||
|
||||
inventory.action_start()
|
||||
|
||||
# Should have quant for the product in category even if it has zero stock
|
||||
self.assertTrue(
|
||||
any(q.product_id == product_in_category for q in inventory.stock_quant_ids)
|
||||
)
|
||||
|
||||
def test_create_zero_quants_only_for_product_type(self):
|
||||
"""Test that zero quants are only created for products with type 'product'"""
|
||||
# Create a service product
|
||||
service_product = self.env["product.product"].create(
|
||||
{
|
||||
"name": "Service Product",
|
||||
"type": "service",
|
||||
}
|
||||
)
|
||||
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test Service Product",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
"product_selection": "manual",
|
||||
"product_ids": [(6, 0, [service_product.id])],
|
||||
"include_exhausted_products": True,
|
||||
}
|
||||
)
|
||||
|
||||
inventory.action_start()
|
||||
|
||||
# Should not create quants for service products
|
||||
self.assertFalse(
|
||||
any(q.product_id == service_product for q in inventory.stock_quant_ids)
|
||||
)
|
||||
|
||||
def test_no_duplicate_quants_created(self):
|
||||
"""Test that no duplicate quants are created if they already exist"""
|
||||
# Create a quant with zero quantity manually
|
||||
existing_quant = self.env["stock.quant"].create(
|
||||
{
|
||||
"product_id": self.product_without_stock.id,
|
||||
"location_id": self.location.id,
|
||||
"quantity": 0.0,
|
||||
}
|
||||
)
|
||||
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test No Duplicates",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
"product_selection": "manual",
|
||||
"product_ids": [(6, 0, [self.product_without_stock.id])],
|
||||
"include_exhausted_products": True,
|
||||
}
|
||||
)
|
||||
|
||||
inventory.action_start()
|
||||
|
||||
# Should use existing quant, not create a new one
|
||||
quants_for_product = self.env["stock.quant"].search(
|
||||
[
|
||||
("product_id", "=", self.product_without_stock.id),
|
||||
("location_id", "=", self.location.id),
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(quants_for_product), 1)
|
||||
self.assertEqual(quants_for_product.id, existing_quant.id)
|
||||
|
||||
def test_field_default_value(self):
|
||||
"""Test that include_exhausted_products field defaults to False"""
|
||||
inventory = self.env["stock.inventory"].create(
|
||||
{
|
||||
"name": "Test Default Value",
|
||||
"location_ids": [(6, 0, [self.location.id])],
|
||||
}
|
||||
)
|
||||
|
||||
self.assertFalse(inventory.include_exhausted_products)
|
||||
12
stock_inventory_product_exhausted/views/stock_inventory.xml
Normal file
12
stock_inventory_product_exhausted/views/stock_inventory.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<odoo>
|
||||
<record id="view_stock_inventory_form_exhausted" model="ir.ui.view">
|
||||
<field name="name">stock.inventory.form.exhausted</field>
|
||||
<field name="model">stock.inventory</field>
|
||||
<field name="inherit_id" ref="stock_inventory.view_inventory_group_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="exclude_sublocation" position="after">
|
||||
<field name="include_exhausted_products"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue