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
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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue