-
-
Notifications
You must be signed in to change notification settings - Fork 729
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IMP] stock_location_last_inventory_date: Make last_inventory_date st…
…oreable This allows to search this field
- Loading branch information
1 parent
46c9883
commit 0e0121d
Showing
9 changed files
with
134 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
9 changes: 9 additions & 0 deletions
9
stock_location_last_inventory_date/migrations/14.0.2.0.0/post-migration.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
14
stock_location_last_inventory_date/models/stock_inventory.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
@@ -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 ( | ||
|
@@ -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( | ||
|
@@ -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) |