remove logging, add config-settings for caching, add docs
This commit is contained in:
parent
03324d5944
commit
78f160bf0b
6 changed files with 47 additions and 96 deletions
41
book.py
41
book.py
|
@ -10,15 +10,20 @@ from trytond.i18n import gettext
|
|||
from trytond.transaction import Transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.report import Report
|
||||
from trytond.config import config
|
||||
from decimal import Decimal
|
||||
from datetime import date, datetime
|
||||
from datetime import date
|
||||
from sql.aggregate import Sum
|
||||
from sql.conditionals import Case
|
||||
from .model import order_name_hierarchical, sub_ids_hierarchical, \
|
||||
AnyInArray, CACHEKEY_CURRENCY, CACHEKEY_CASHBOOK
|
||||
AnyInArray, CACHEKEY_CURRENCY
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# enable/disable caching of cachekey for 'currency.rate'
|
||||
if config.get('cashbook', 'cache_currency', default='yes').lower() in ['yes', '1', 'true']:
|
||||
ENA_CURRKEY = True
|
||||
else :
|
||||
ENA_CURRKEY = False
|
||||
|
||||
|
||||
STATES = {
|
||||
|
@ -265,16 +270,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
}
|
||||
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
|
||||
def get_balance_of_cashbook_sql(cls):
|
||||
""" sql for balance of a single cashbook
|
||||
|
@ -365,12 +360,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
cursor = Transaction().connection.cursor()
|
||||
context = Transaction().context
|
||||
|
||||
logger.warning('## get_balance_cashbook-GO %(time)s %(ids)s %(name)s' % {
|
||||
'time': datetime.now().isoformat(),
|
||||
'ids': str([x.id for x in cashbooks]),
|
||||
'name': names,
|
||||
})
|
||||
|
||||
result = {
|
||||
x:{y.id: Decimal('0.0') for y in cashbooks}
|
||||
for x in ['balance', 'balance_all', 'balance_ref']}
|
||||
|
@ -390,26 +379,19 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
query = [{
|
||||
'model': 'cashbook.line',
|
||||
'query': [('cashbook.parent', 'child_of', [x.id])],
|
||||
#'cachekey': CACHEKEY_CASHBOOK % x.id,
|
||||
}, {
|
||||
'model': 'currency.currency.rate',
|
||||
'query': [('currency.id', '=', x.currency.id)],
|
||||
'cachekey': CACHEKEY_CURRENCY % x.currency.id,
|
||||
'cachekey' if ENA_CURRKEY else 'disabled': CACHEKEY_CURRENCY % x.currency.id,
|
||||
}, ],
|
||||
addkeys = [query_date.isoformat()])
|
||||
for x in cashbooks
|
||||
}
|
||||
|
||||
# read from cache
|
||||
logger.warning('## get_balance_cashbook-KEYS %(time)s' % {
|
||||
'time': datetime.now().isoformat(),
|
||||
})
|
||||
(todo_cashbook, result) = MemCache.read_from_cache(
|
||||
cashbooks, cache_keys, names, result)
|
||||
if len(todo_cashbook) == 0:
|
||||
logger.warning('## get_balance_cashbook-HIT %(time)s' % {
|
||||
'time': datetime.now().isoformat(),
|
||||
})
|
||||
return result
|
||||
|
||||
# query balances of cashbooks and sub-cashbooks
|
||||
|
@ -446,9 +428,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
|
|||
record[2], record[5], record[3])
|
||||
|
||||
MemCache.store_result(cashbooks, cache_keys, result, todo_cashbook)
|
||||
logger.warning('## get_balance_cashbook-END %(time)s' % {
|
||||
'time': datetime.now().isoformat(),
|
||||
})
|
||||
return result
|
||||
|
||||
@fields.depends('btype')
|
||||
|
|
21
docs/settings.txt
Normal file
21
docs/settings.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
settings in tytond.conf
|
||||
|
||||
[cashbook]
|
||||
# enable caching of values, stores values between
|
||||
# browser requests, speeds up the retrieval of data.
|
||||
# default: yes
|
||||
memcache = yes
|
||||
|
||||
# Enables synchronization of the cache between multiple
|
||||
# server instances.
|
||||
# default: yes
|
||||
# Requires the setting :
|
||||
# [cache]
|
||||
# clean_timeout=0
|
||||
sync = yes
|
||||
|
||||
# Enables caching of the cache key for currency rates.
|
||||
# Reduces the time required to determine the cache
|
||||
# key for currency values.
|
||||
# default: yes
|
||||
cache_currency = yes
|
25
line.py
25
line.py
|
@ -16,7 +16,6 @@ from sql.functions import DatePart
|
|||
from sql.conditionals import Case
|
||||
from .book import sel_state_book
|
||||
from .mixin import SecondCurrencyMixin, MemCacheIndexMx
|
||||
from .model import CACHEKEY_CASHBOOK
|
||||
|
||||
|
||||
sel_payee = [
|
||||
|
@ -180,8 +179,6 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
states={'invisible': True}, model_name='res.user'),
|
||||
'on_change_with_owner_cashbook')
|
||||
|
||||
#image = fields.Binary...
|
||||
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
super(Line, cls).__register__(module_name)
|
||||
|
@ -984,8 +981,6 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
def create(cls, vlist):
|
||||
""" add debit/credit
|
||||
"""
|
||||
MemCache = Pool().get('cashbook.memcache')
|
||||
|
||||
vlist = [x.copy() for x in vlist]
|
||||
for values in vlist:
|
||||
values.update(cls.add_values_from_splitlines(values))
|
||||
|
@ -1006,20 +1001,13 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
'descr': values.get('description', '-'),
|
||||
},
|
||||
))
|
||||
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
|
||||
return super(Line, cls).create(vlist)
|
||||
|
||||
@classmethod
|
||||
def write(cls, *args):
|
||||
""" deny update if cashbook.line!='open',
|
||||
add or update debit/credit
|
||||
"""
|
||||
MemCache = Pool().get('cashbook.memcache')
|
||||
|
||||
actions = iter(args)
|
||||
to_write = []
|
||||
for lines, values in zip(actions, actions):
|
||||
|
@ -1066,22 +1054,11 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
|
|||
|
||||
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
|
||||
def delete(cls, lines):
|
||||
""" deny delete if book is not 'open' or wf is not 'edit'
|
||||
"""
|
||||
MemCache = Pool().get('cashbook.memcache')
|
||||
|
||||
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)
|
||||
|
||||
# end Line
|
||||
|
|
48
model.py
48
model.py
|
@ -7,19 +7,25 @@ from trytond.model import MultiValueMixin, ValueMixin, fields, Unique, Model
|
|||
from trytond.transaction import Transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.cache import MemoryCache
|
||||
from trytond.config import config
|
||||
from datetime import timedelta, datetime
|
||||
from decimal import Decimal
|
||||
from sql import With, Literal
|
||||
from sql.functions import Function
|
||||
from sql.conditionals import Coalesce
|
||||
import copy, logging
|
||||
import copy
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
if config.get('cashbook', 'memcache', default='yes').lower() in ['yes', '1', 'true']:
|
||||
ENABLE_CACHE = True
|
||||
else:
|
||||
ENABLE_CACHE = False
|
||||
|
||||
if config.get('cashbook', 'sync', default='yes').lower() in ['yes', '1', 'true']:
|
||||
ENABLE_CACHESYNC = True
|
||||
else:
|
||||
ENABLE_CACHESYNC = False
|
||||
|
||||
ENABLE_CACHE = True
|
||||
CACHEKEY_CURRENCY = 'currency-%s'
|
||||
CACHEKEY_CASHBOOK = 'cashbook-%s'
|
||||
|
||||
|
||||
class ArrayAgg(Function):
|
||||
|
@ -105,14 +111,8 @@ class MemCache(Model):
|
|||
for x in values.keys()
|
||||
if record.id in values[x].keys()}
|
||||
cls._cashbook_value_cache.set(cache_keys[record.id], copy.deepcopy(data))
|
||||
# ~ logger.info('memcache-VALUE-SET %(time)s key=%(key)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'key': cache_keys[record.id],
|
||||
# ~ })
|
||||
cls._cashbook_value_cache.sync(Transaction())
|
||||
# ~ logger.info('memcache-VALUE-SYNC %(time)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ })
|
||||
if ENABLE_CACHESYNC == True:
|
||||
cls._cashbook_value_cache.sync(Transaction())
|
||||
|
||||
@classmethod
|
||||
def store_value(cls, cache_key, values):
|
||||
|
@ -121,10 +121,6 @@ class MemCache(Model):
|
|||
if ENABLE_CACHE == False:
|
||||
return
|
||||
cls._cashbook_value_cache.set(cache_key, copy.deepcopy(values))
|
||||
# ~ logger.info('memcache-VALUE-SET %(time)s key=%(key)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'key': cache_key,
|
||||
# ~ })
|
||||
|
||||
@classmethod
|
||||
def read_from_cache(cls, records, cache_keys, names, result):
|
||||
|
@ -145,15 +141,7 @@ class MemCache(Model):
|
|||
if result[name][record.id] is None:
|
||||
result[name][record.id] = Decimal('0.0')
|
||||
result[name][record.id] += values[name]
|
||||
# ~ logger.info('memcache-VALUE-READ-HIT %(time)s key=%(key)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'key': cache_keys[record.id],
|
||||
# ~ })
|
||||
else :
|
||||
# ~ logger.info('memcache-VALUE-READ-FAIL %(time)s key=%(key)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'key': cache_keys[record.id],
|
||||
# ~ })
|
||||
todo_records.append(record)
|
||||
return (todo_records, result)
|
||||
|
||||
|
@ -167,11 +155,6 @@ class MemCache(Model):
|
|||
if ENABLE_CACHE == False:
|
||||
return '-'
|
||||
|
||||
# ~ logger.info('memcache-KEY %(time)s name=%(name)s record=%(record)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'name': name,
|
||||
# ~ 'record': str(record),
|
||||
# ~ })
|
||||
fname = [name, str(record.id)]
|
||||
fname.extend(addkeys)
|
||||
|
||||
|
@ -215,11 +198,6 @@ class MemCache(Model):
|
|||
|
||||
if 'cachekey' in line.keys():
|
||||
key = cls.store_value(line['cachekey'], fname[-1])
|
||||
# ~ logger.info('memcache-KEY-RESULT %(time)s name=%(name)s result=%(result)s' % {
|
||||
# ~ 'time': datetime.now().isoformat(),
|
||||
# ~ 'name': name,
|
||||
# ~ 'result': '-'.join(fname),
|
||||
# ~ })
|
||||
return '-'.join(fname)
|
||||
|
||||
@classmethod
|
||||
|
@ -238,6 +216,8 @@ class MemCache(Model):
|
|||
def record_update(cls, cache_key, record):
|
||||
""" update cache-value
|
||||
"""
|
||||
if ENABLE_CACHE == False:
|
||||
return
|
||||
cls.store_value(cache_key,
|
||||
cls.genkey(record.id, record.write_date, record.create_date)
|
||||
if record is not None else None)
|
||||
|
|
2
setup.py
2
setup.py
|
@ -99,7 +99,7 @@ setup(name='%s_%s' % (PREFIX, MODULE),
|
|||
package_data={
|
||||
'trytond.modules.%s' % MODULE: (info.get('xml', [])
|
||||
+ ['tryton.cfg', 'locale/*.po', 'tests/*.py',
|
||||
'view/*.xml', 'icon/*.svg',
|
||||
'view/*.xml', 'icon/*.svg', 'docs/*.txt',
|
||||
'report/*.fods', 'versiondep.txt', 'README.rst']),
|
||||
},
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ from trytond.transaction import Transaction
|
|||
from trytond.exceptions import UserError
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
from trytond.modules.cashbook.model import CACHEKEY_CASHBOOK
|
||||
|
||||
|
||||
class BookTestCase(ModuleTestCase):
|
||||
|
@ -190,11 +189,6 @@ class BookTestCase(ModuleTestCase):
|
|||
self.assertEqual(book.rec_name, 'Level 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.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()
|
||||
def test_book_deny_delete_open(self):
|
||||
|
|
Loading…
Reference in a new issue