forked from OCA/sale-workflow
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sale_delivery_date: add cache to improve performance
This avoids a lot of SQL requests (several hundreds on a SO with 20-30 lines), and reduce the time needed to open orders.
- Loading branch information
Showing
6 changed files
with
136 additions
and
5 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 |
---|---|---|
|
@@ -5,3 +5,4 @@ | |
from . import stock_move | ||
from . import stock_picking | ||
from . import stock_warehouse | ||
from . import resource |
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,55 @@ | ||
# Copyright 2024 Camptocamp SA | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
|
||
from odoo import api, models | ||
|
||
|
||
class ResourceCalendar(models.Model): | ||
_inherit = "resource.calendar" | ||
|
||
def write(self, vals): | ||
res = super().write(vals) | ||
# Clear cache to ensure 'ormcache' decorated methods on 'sale.order.line' | ||
# returns the expected results if calendar is updated | ||
self.clear_caches() | ||
return res | ||
|
||
|
||
class ResourceCalendarAttendance(models.Model): | ||
_inherit = "resource.calendar.attendance" | ||
|
||
@api.model_create_multi | ||
@api.returns('self', lambda value: value.id) | ||
def create(self, vals_list): | ||
res = super().create(vals_list) | ||
# Clear cache to ensure 'ormcache' decorated methods on 'sale.order.line' | ||
# returns the expected results if attendances are created | ||
self.clear_caches() | ||
return res | ||
|
||
def write(self, vals): | ||
res = super().write(vals) | ||
# Clear cache to ensure 'ormcache' decorated methods on 'sale.order.line' | ||
# returns the expected results if attendances are updated | ||
self.clear_caches() | ||
return res | ||
|
||
|
||
class ResourceCalendarLeaves(models.Model): | ||
_inherit = "resource.calendar.leaves" | ||
|
||
@api.model_create_multi | ||
@api.returns('self', lambda value: value.id) | ||
def create(self, vals_list): | ||
res = super().create(vals_list) | ||
# Clear cache to ensure 'ormcache' decorated methods on 'sale.order.line' | ||
# returns the expected results if leaves are created | ||
self.clear_caches() | ||
return res | ||
|
||
def write(self, vals): | ||
res = super().write(vals) | ||
# Clear cache to ensure 'ormcache' decorated methods on 'sale.order.line' | ||
# returns the expected results if leaves are updated | ||
self.clear_caches() | ||
return res |
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
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,66 @@ | ||
# Copyright 2024 Camptocamp SA | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
|
||
from freezegun import freeze_time | ||
import mock | ||
|
||
from odoo import fields | ||
from odoo.tests.common import SavepointCase | ||
|
||
MONDAY = fields.Datetime.from_string("2024-03-18") | ||
TUESDAY = fields.Datetime.from_string("2024-03-19") | ||
WEDNESDAY = fields.Datetime.from_string("2024-03-20") | ||
|
||
|
||
class TestSaleOrderLineCache(SavepointCase): | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
super().setUpClass() | ||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) | ||
|
||
@freeze_time(MONDAY) | ||
def test_cache_invalidation(self): | ||
calendar = self.env.ref("resource.resource_calendar_std") | ||
sol_model = self.env["sale.order.line"] | ||
mock_args = (type(calendar), "plan_days") | ||
mock_kwargs = {"side_effect": calendar.plan_days} | ||
# First call computes the date | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
date_ = sol_model._add_delay(MONDAY, delay=1, calendar=calendar) | ||
self.assertEqual(date_.date(), TUESDAY) | ||
mocked.assert_called() | ||
# Second call get it from the cache | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
date_ = sol_model._add_delay(MONDAY, delay=1, calendar=calendar) | ||
self.assertEqual(date_.date(), TUESDAY) | ||
mocked.assert_not_called() | ||
# Update the calendar data to invalidate the cache so the date is | ||
# computed from the calendar again | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
calendar.write({}) | ||
date_ = sol_model._add_delay(MONDAY, delay=1, calendar=calendar) | ||
self.assertEqual(date_.date(), TUESDAY) | ||
mocked.assert_called() | ||
# Same by updating the attendances to invalidate the cache | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
calendar.attendance_ids.write({}) | ||
date_ = sol_model._add_delay(MONDAY, delay=1, calendar=calendar) | ||
self.assertEqual(date_.date(), TUESDAY) | ||
mocked.assert_called() | ||
# Same by updating the leaves to invalidate the cache | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
calendar.leave_ids.write({}) | ||
date_ = sol_model._add_delay(MONDAY, delay=1, calendar=calendar) | ||
self.assertEqual(date_.date(), TUESDAY) | ||
mocked.assert_called() | ||
# Using the cache again | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
date_ = sol_model._add_delay(MONDAY, delay=1, calendar=calendar) | ||
self.assertEqual(date_.date(), TUESDAY) | ||
mocked.assert_not_called() | ||
# Not using the cache with different parameters | ||
with mock.patch.object(*mock_args, **mock_kwargs) as mocked: | ||
date_ = sol_model._add_delay(MONDAY, delay=2, calendar=calendar) | ||
self.assertEqual(date_.date(), WEDNESDAY) | ||
mocked.assert_called() |