book: add caching for line
This commit is contained in:
parent
1793d3653e
commit
d5bc62ca78
5 changed files with 51 additions and 10 deletions
13
book.py
13
book.py
|
@ -15,7 +15,7 @@ from datetime import date
|
||||||
from sql.aggregate import Sum
|
from sql.aggregate import Sum
|
||||||
from sql.conditionals import Case
|
from sql.conditionals import Case
|
||||||
from .model import order_name_hierarchical, sub_ids_hierarchical, \
|
from .model import order_name_hierarchical, sub_ids_hierarchical, \
|
||||||
AnyInArray, CACHEKEY_CURRENCY
|
AnyInArray, CACHEKEY_CURRENCY, CACHEKEY_CASHBOOK
|
||||||
|
|
||||||
|
|
||||||
STATES = {
|
STATES = {
|
||||||
|
@ -262,6 +262,16 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
||||||
}
|
}
|
||||||
return recname
|
return recname
|
||||||
|
|
||||||
|
def get_cachekeys_by_hierarchy(self):
|
||||||
|
""" generate keys for all cashbooks above us
|
||||||
|
"""
|
||||||
|
CBook = Pool().get('cashbook.book')
|
||||||
|
|
||||||
|
return [CACHEKEY_CASHBOOK % x.id
|
||||||
|
for x in CBook.search([
|
||||||
|
('parent', 'parent_of', [self.id]),
|
||||||
|
], order=[('id', 'ASC')])]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_balance_of_cashbook_sql(cls):
|
def get_balance_of_cashbook_sql(cls):
|
||||||
""" sql for balance of a single cashbook
|
""" sql for balance of a single cashbook
|
||||||
|
@ -371,6 +381,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
||||||
query = [{
|
query = [{
|
||||||
'model': 'cashbook.line',
|
'model': 'cashbook.line',
|
||||||
'query': [('cashbook.parent', 'child_of', [x.id])],
|
'query': [('cashbook.parent', 'child_of', [x.id])],
|
||||||
|
'cachekey': CACHEKEY_CASHBOOK % x.id,
|
||||||
}, {
|
}, {
|
||||||
'model': 'currency.currency.rate',
|
'model': 'currency.currency.rate',
|
||||||
'query': [('currency.id', '=', x.currency.id)],
|
'query': [('currency.id', '=', x.currency.id)],
|
||||||
|
|
23
line.py
23
line.py
|
@ -16,6 +16,7 @@ from sql.functions import DatePart
|
||||||
from sql.conditionals import Case
|
from sql.conditionals import Case
|
||||||
from .book import sel_state_book
|
from .book import sel_state_book
|
||||||
from .mixin import SecondCurrencyMixin, MemCacheIndexMx
|
from .mixin import SecondCurrencyMixin, MemCacheIndexMx
|
||||||
|
from .model import CACHEKEY_CASHBOOK
|
||||||
|
|
||||||
|
|
||||||
sel_payee = [
|
sel_payee = [
|
||||||
|
@ -983,6 +984,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
||||||
def create(cls, vlist):
|
def create(cls, vlist):
|
||||||
""" add debit/credit
|
""" add debit/credit
|
||||||
"""
|
"""
|
||||||
|
MemCache = Pool().get('cashbook.memcache')
|
||||||
|
|
||||||
vlist = [x.copy() for x in vlist]
|
vlist = [x.copy() for x in vlist]
|
||||||
for values in vlist:
|
for values in vlist:
|
||||||
values.update(cls.add_values_from_splitlines(values))
|
values.update(cls.add_values_from_splitlines(values))
|
||||||
|
@ -1003,13 +1006,20 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
||||||
'descr': values.get('description', '-'),
|
'descr': values.get('description', '-'),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
return super(Line, cls).create(vlist)
|
records = super(Line, cls).create(vlist)
|
||||||
|
|
||||||
|
for record in records:
|
||||||
|
for x in record.cashbook.get_cachekeys_by_hierarchy():
|
||||||
|
MemCache.record_update(x, record)
|
||||||
|
return records
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def write(cls, *args):
|
def write(cls, *args):
|
||||||
""" deny update if cashbook.line!='open',
|
""" deny update if cashbook.line!='open',
|
||||||
add or update debit/credit
|
add or update debit/credit
|
||||||
"""
|
"""
|
||||||
|
MemCache = Pool().get('cashbook.memcache')
|
||||||
|
|
||||||
actions = iter(args)
|
actions = iter(args)
|
||||||
to_write = []
|
to_write = []
|
||||||
for lines, values in zip(actions, actions):
|
for lines, values in zip(actions, actions):
|
||||||
|
@ -1056,11 +1066,22 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
||||||
|
|
||||||
super(Line, cls).write(*to_write)
|
super(Line, cls).write(*to_write)
|
||||||
|
|
||||||
|
actions = iter(to_write)
|
||||||
|
for records, values in zip(actions, actions):
|
||||||
|
for record in records:
|
||||||
|
for x in record.cashbook.get_cachekeys_by_hierarchy():
|
||||||
|
MemCache.record_update(x, record)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete(cls, lines):
|
def delete(cls, lines):
|
||||||
""" deny delete if book is not 'open' or wf is not 'edit'
|
""" deny delete if book is not 'open' or wf is not 'edit'
|
||||||
"""
|
"""
|
||||||
|
MemCache = Pool().get('cashbook.memcache')
|
||||||
|
|
||||||
cls.check_permission_delete(lines)
|
cls.check_permission_delete(lines)
|
||||||
|
for line in lines:
|
||||||
|
for x in line.cashbook.get_cachekeys_by_hierarchy():
|
||||||
|
MemCache.record_update(x, None)
|
||||||
super(Line, cls).delete(lines)
|
super(Line, cls).delete(lines)
|
||||||
|
|
||||||
# end Line
|
# end Line
|
||||||
|
|
7
model.py
7
model.py
|
@ -7,7 +7,7 @@ from trytond.model import MultiValueMixin, ValueMixin, fields, Unique, Model
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
from trytond.cache import MemoryCache
|
from trytond.cache import MemoryCache
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from sql import With, Literal
|
from sql import With, Literal
|
||||||
from sql.functions import Function
|
from sql.functions import Function
|
||||||
|
@ -15,6 +15,7 @@ from sql.conditionals import Coalesce
|
||||||
|
|
||||||
ENABLE_CACHE = True
|
ENABLE_CACHE = True
|
||||||
CACHEKEY_CURRENCY = 'currency-%s'
|
CACHEKEY_CURRENCY = 'currency-%s'
|
||||||
|
CACHEKEY_CASHBOOK = 'cashbook-%s'
|
||||||
|
|
||||||
|
|
||||||
class ArrayAgg(Function):
|
class ArrayAgg(Function):
|
||||||
|
@ -140,8 +141,6 @@ class MemCache(Model):
|
||||||
if ENABLE_CACHE == False:
|
if ENABLE_CACHE == False:
|
||||||
return '-'
|
return '-'
|
||||||
|
|
||||||
dt1 = datetime.now()
|
|
||||||
print('-- get_key_by_record:', name, record.id)
|
|
||||||
fname = [name, str(record.id)]
|
fname = [name, str(record.id)]
|
||||||
fname.extend(addkeys)
|
fname.extend(addkeys)
|
||||||
|
|
||||||
|
@ -185,8 +184,6 @@ class MemCache(Model):
|
||||||
|
|
||||||
if 'cachekey' in line.keys():
|
if 'cachekey' in line.keys():
|
||||||
key = cls.store_value(line['cachekey'], fname[-1])
|
key = cls.store_value(line['cachekey'], fname[-1])
|
||||||
|
|
||||||
print('-- get_key_by_record-END:', datetime.now() - dt1, '-'.join(fname))
|
|
||||||
return '-'.join(fname)
|
return '-'.join(fname)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -9,6 +9,7 @@ from trytond.transaction import Transaction
|
||||||
from trytond.exceptions import UserError
|
from trytond.exceptions import UserError
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from trytond.modules.cashbook.model import CACHEKEY_CASHBOOK
|
||||||
|
|
||||||
|
|
||||||
class BookTestCase(ModuleTestCase):
|
class BookTestCase(ModuleTestCase):
|
||||||
|
@ -189,6 +190,11 @@ class BookTestCase(ModuleTestCase):
|
||||||
self.assertEqual(book.rec_name, 'Level 1')
|
self.assertEqual(book.rec_name, 'Level 1')
|
||||||
self.assertEqual(len(book.childs), 1)
|
self.assertEqual(len(book.childs), 1)
|
||||||
self.assertEqual(book.childs[0].rec_name, 'Level 1/Level 2 | 0.00 usd | Open')
|
self.assertEqual(book.childs[0].rec_name, 'Level 1/Level 2 | 0.00 usd | Open')
|
||||||
|
self.assertEqual(book.get_cachekeys_by_hierarchy(), [CACHEKEY_CASHBOOK % book.id])
|
||||||
|
self.assertEqual(book.childs[0].get_cachekeys_by_hierarchy(), [
|
||||||
|
CACHEKEY_CASHBOOK % book.id,
|
||||||
|
CACHEKEY_CASHBOOK % book.childs[0].id
|
||||||
|
])
|
||||||
|
|
||||||
@with_transaction()
|
@with_transaction()
|
||||||
def test_book_deny_delete_open(self):
|
def test_book_deny_delete_open(self):
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.modules.cashbook.model import CACHEKEY_CURRENCY
|
from trytond.modules.cashbook.model import CACHEKEY_CURRENCY, ENABLE_CACHE
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import time
|
import time
|
||||||
|
@ -53,7 +53,10 @@ class CurrencyTestCase(ModuleTestCase):
|
||||||
value = '%d-c%s' % (
|
value = '%d-c%s' % (
|
||||||
currency.rates[0].id,
|
currency.rates[0].id,
|
||||||
str(currency.rates[0].create_date.timestamp()))
|
str(currency.rates[0].create_date.timestamp()))
|
||||||
self.assertEqual(MemCache.read_value(cache_key), value)
|
if ENABLE_CACHE == True:
|
||||||
|
self.assertEqual(MemCache.read_value(cache_key), value)
|
||||||
|
else :
|
||||||
|
self.assertEqual(MemCache.read_value(cache_key), None)
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
Currency.write(*[
|
Currency.write(*[
|
||||||
|
@ -70,7 +73,10 @@ class CurrencyTestCase(ModuleTestCase):
|
||||||
value = '%d-w%s' % (
|
value = '%d-w%s' % (
|
||||||
currency.rates[0].id,
|
currency.rates[0].id,
|
||||||
str(currency.rates[0].write_date.timestamp()))
|
str(currency.rates[0].write_date.timestamp()))
|
||||||
self.assertEqual(MemCache.read_value(cache_key), value)
|
if ENABLE_CACHE == True:
|
||||||
|
self.assertEqual(MemCache.read_value(cache_key), value)
|
||||||
|
else :
|
||||||
|
self.assertEqual(MemCache.read_value(cache_key), None)
|
||||||
|
|
||||||
Currency.write(*[
|
Currency.write(*[
|
||||||
[currency],
|
[currency],
|
||||||
|
|
Loading…
Reference in a new issue