add worker-based precalculation of cashbook-values

This commit is contained in:
Frederik Jaeckel 2023-12-27 15:49:02 +01:00
parent 9ef465f40f
commit 5d8f924960
17 changed files with 1060 additions and 98 deletions

65
book.py
View file

@ -4,8 +4,7 @@
# full copyright notices and license terms.
from trytond.model import (
Workflow, ModelView, ModelSQL, fields, Check,
tree, Index)
Workflow, ModelView, ModelSQL, fields, Check, tree, Index)
from trytond.pyson import Eval, Or, Bool, Id, Len
from trytond.exceptions import UserError
from trytond.i18n import gettext
@ -117,6 +116,10 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
'invisible': STATES2['invisible'],
'required': ~STATES2['invisible'],
}, depends=DEPENDS2+['lines'])
value_store = fields.One2Many(
string='Values', model_name='cashbook.values', field='cashbook',
readonly=True)
balance = fields.Function(fields.Numeric(
string='Balance',
readonly=True, depends=['currency_digits'],
@ -129,7 +132,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
help='Balance of all bookings',
digits=(16, Eval('currency_digits', 2))),
'get_balance_cashbook', searcher='search_balance')
balance_ref = fields.Function(fields.Numeric(
string='Balance (Ref.)',
help='Balance in company currency',
@ -383,8 +385,54 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
getattr(tab_line, name), clause[2]))
return [('id', 'in', query)]
@classmethod
def valuestore_delete_records(cls, records):
""" delete value-records
"""
ValStore = Pool().get('cashbook.values')
if records:
ValStore.delete_values(records)
@classmethod
def valuestore_fields(cls):
""" field to update
"""
return ['balance', 'balance_all', 'balance_ref']
@classmethod
def valuestore_update_records(cls, records):
""" compute current values of records,
store to global storage
"""
ValStore = Pool().get('cashbook.values')
if records:
ValStore.update_values(
cls.get_balance_values(
records,
['balance', 'balance_all', 'balance_ref']))
@classmethod
def get_balance_cashbook(cls, cashbooks, names):
""" get balance of cashbooks
"""
context = Transaction().context
result = {x: {y.id: Decimal('0.0') for y in cashbooks} for x in names}
# return computed values if 'date' is in context
query_date = context.get('date', None)
if query_date is not None:
return cls.get_balance_values(cashbooks, names)
for cashbook in cashbooks:
for value in cashbook.value_store:
if value.field_name in names:
result[value.field_name][cashbook.id] = value.numvalue
return result
@classmethod
def get_balance_values(cls, cashbooks, names):
""" get balance of cashbook
"""
pool = Pool()
@ -498,6 +546,14 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
"""
pass
@classmethod
def create(cls, vlist):
""" update values
"""
records = super(Book, cls).create(vlist)
cls.valuestore_update_records(records)
return records
@classmethod
def write(cls, *args):
""" deny update if book is not 'open'
@ -506,7 +562,9 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
actions = iter(args)
to_write_config = []
to_update = []
for books, values in zip(actions, actions):
to_update.extend(books)
for book in books:
# deny btype-->None if lines not empty
if 'btype' in values.keys():
@ -540,6 +598,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
if len(to_write_config) > 0:
ConfigUser.write(*to_write_config)
cls.valuestore_update_records(to_update)
@classmethod
def delete(cls, books):