Skip to content

Commit

Permalink
[IMP] stock_location_last_inventory_date: Make last_inventory_date st…
Browse files Browse the repository at this point in the history
…oreable

This allows to search this field
  • Loading branch information
mt-software-de committed Dec 18, 2024
1 parent 46c9883 commit 0e0121d
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 17 deletions.
2 changes: 2 additions & 0 deletions stock_location_last_inventory_date/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from .hooks import post_init_hook
from . import models
3 changes: 2 additions & 1 deletion stock_location_last_inventory_date/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{
"name": "Stock Location Last Inventory Date",
"summary": "Show the last inventory date for a leaf location",
"version": "14.0.1.0.0",
"version": "14.0.2.0.0",
"development_status": "Alpha",
"category": "Warehouse",
"website": "https://github.com/OCA/stock-logistics-warehouse",
Expand All @@ -13,4 +13,5 @@
"installable": True,
"depends": ["product", "stock"],
"data": ["views/stock_location_views.xml"],
"post_init_hook": "post_init_hook",
}
36 changes: 36 additions & 0 deletions stock_location_last_inventory_date/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
import logging

logger = logging.getLogger(__name__)


def set_initial_last_inventory_date(cr):
cr.execute(
"""
Update
stock_location
set
last_inventory_date = sub.date
from (
Select
line.location_id,
max(inventory.date) as date
from
stock_inventory_line as line
join
stock_inventory as inventory
on
inventory.id = line.inventory_id
group by
line.location_id
) as sub
where
stock_location.id = sub.location_id;
"""
)


def post_init_hook(cr, registry):
logger.info("Calculate last inventory date for locations")
set_initial_last_inventory_date(cr)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from odoo.addons.stock_location_last_inventory_date.hooks import (
set_initial_last_inventory_date,
)


def migrate(cr, version):
set_initial_last_inventory_date(cr)
2 changes: 2 additions & 0 deletions stock_location_last_inventory_date/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from . import stock_location
from . import stock_inventory
14 changes: 14 additions & 0 deletions stock_location_last_inventory_date/models/stock_inventory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from odoo import models


class StockInventory(models.Model):
_inherit = "stock.inventory"

def _action_done(self):
super()._action_done()
for inventory in self:
last_inventory_date = inventory.date
done_locations = inventory.line_ids.location_id
done_locations.write({"last_inventory_date": last_inventory_date})
15 changes: 1 addition & 14 deletions stock_location_last_inventory_date/models/stock_location.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from odoo import fields, models

Expand All @@ -8,20 +9,6 @@ class StockLocation(models.Model):

last_inventory_date = fields.Datetime(
"Last Inventory Date",
compute="_compute_last_inventory_date",
help="Indicates the last inventory date for the location, "
"including inventory done on parents location.",
)

def _compute_last_inventory_date(self):
for location in self:
location_ids = [
int(location_id)
for location_id in location.parent_path.rstrip("/").split("/")
]
last_inventory = self.env["stock.inventory"].search(
[("location_ids", "in", location_ids), ("state", "=", "done")],
order="date desc",
limit=1,
)
location.last_inventory_date = last_inventory.date
1 change: 1 addition & 0 deletions stock_location_last_inventory_date/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
* Carlos Serra-Toro <[email protected]>
* `Trobz <https://trobz.com>`_:
* Michael Tietz (MT Software) <[email protected]>
69 changes: 67 additions & 2 deletions stock_location_last_inventory_date/tests/test_stock_location.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Copyright 2021 Camptocamp SA
# Copyright 2024 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
from freezegun import freeze_time

from odoo import fields
from odoo.exceptions import AccessError
from odoo.tests import SavepointCase
Expand All @@ -10,8 +13,26 @@ class TestStockLocation(SavepointCase):
def setUpClass(cls):
super().setUpClass()
cls.product = cls.env.ref("product.product_product_7")
cls.leaf_location = cls.env.ref("stock.location_refrigerator_small")
cls.top_location = cls.leaf_location.location_id
cls.top_location = cls.env["stock.location"].create(
{
"name": "Top",
"location_id": cls.env.ref("stock.stock_location_locations").id,
}
)
cls.leaf_location = cls.env["stock.location"].create(
{"name": "Leaf", "location_id": cls.top_location.id}
)
cls.test_locations = cls.top_location | cls.leaf_location
cls.env["stock.quant"]._update_available_quantity(
cls.product,
cls.top_location,
10,
)
cls.env["stock.quant"]._update_available_quantity(
cls.product,
cls.leaf_location,
10,
)

def _create_user(self, name, groups):
return (
Expand Down Expand Up @@ -67,6 +88,13 @@ def test_leaf_location(self):
inventory.action_validate()
self.assertEqual(self.leaf_location.last_inventory_date, inventory.date)
self.assertFalse(self.top_location.last_inventory_date)
locations = self.env["stock.location"].search(
[
("last_inventory_date", "<=", inventory.date),
("id", "in", self.test_locations.ids),
]
)
self.assertEqual(locations, self.leaf_location)

def test_top_location(self):
inventory = self.env["stock.inventory"].create(
Expand All @@ -80,3 +108,40 @@ def test_top_location(self):
inventory.action_validate()
self.assertEqual(self.leaf_location.last_inventory_date, inventory.date)
self.assertEqual(self.top_location.last_inventory_date, inventory.date)
locations = self.env["stock.location"].search(
[
("last_inventory_date", "<=", inventory.date),
("id", "in", self.test_locations.ids),
]
)
self.assertEqual(locations, self.test_locations)

def test_top_and_leaf_location(self):
self.test_top_location()
top_inventory_date = self.top_location.last_inventory_date
with freeze_time(fields.Date.add(top_inventory_date, days=5)):
inventory = self.env["stock.inventory"].create(
{
"name": "Inventory Adjustment",
"product_ids": [(4, self.product.id)],
"location_ids": [(4, self.leaf_location.id)],
}
)
inventory.action_start()
inventory.action_validate()
leaf_inventory_date = self.leaf_location.last_inventory_date
self.assertTrue(leaf_inventory_date > top_inventory_date)
locations = self.env["stock.location"].search(
[
("last_inventory_date", "<=", leaf_inventory_date),
("id", "in", self.test_locations.ids),
]
)
self.assertEqual(locations, (self.leaf_location | self.top_location))
locations = self.env["stock.location"].search(
[
("last_inventory_date", "<=", top_inventory_date),
("id", "in", self.test_locations.ids),
]
)
self.assertEqual(locations, self.top_location)

0 comments on commit 0e0121d

Please sign in to comment.