Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][IMP] stock_location_last_inventory_date: Make last_inventory_date storeable #2222

Open
wants to merge 1 commit into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
Loading