Tryton 6.8: indexe neu, tests angepaßt

This commit is contained in:
Frederik Jaeckel 2023-06-03 19:13:05 +02:00
parent 2cf42eb9f6
commit 2b6731d071
11 changed files with 143 additions and 52 deletions

View file

@ -4,3 +4,4 @@ dist/*
mds_cashbook.egg-info/* mds_cashbook.egg-info/*
locale/convert_de2en.py locale/convert_de2en.py
__pycache__/* __pycache__/*
.pytest_cache/*

42
book.py
View file

@ -3,7 +3,9 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.model import Workflow, ModelView, ModelSQL, fields, Check, tree from trytond.model import (
Workflow, ModelView, ModelSQL, fields, Check,
tree, Index)
from trytond.pyson import Eval, Or, Bool, Id, Len from trytond.pyson import Eval, Or, Bool, Id, Len
from trytond.exceptions import UserError from trytond.exceptions import UserError
from trytond.i18n import gettext from trytond.i18n import gettext
@ -59,13 +61,13 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
company = fields.Many2One( company = fields.Many2One(
string='Company', model_name='company.company', string='Company', model_name='company.company',
required=True, select=True, ondelete="RESTRICT") required=True, ondelete="RESTRICT")
name = fields.Char( name = fields.Char(
string='Name', required=True, states=STATES, depends=DEPENDS) string='Name', required=True, states=STATES, depends=DEPENDS)
description = fields.Text( description = fields.Text(
string='Description', states=STATES, depends=DEPENDS) string='Description', states=STATES, depends=DEPENDS)
btype = fields.Many2One( btype = fields.Many2One(
string='Type', select=True, string='Type',
help='A cash book with type can contain postings. ' + help='A cash book with type can contain postings. ' +
'Without type is a view.', 'Without type is a view.',
model_name='cashbook.type', ondelete='RESTRICT', model_name='cashbook.type', ondelete='RESTRICT',
@ -79,16 +81,16 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
string='Feature', readonly=True, string='Feature', readonly=True,
states={'invisible': True}), 'on_change_with_feature') states={'invisible': True}), 'on_change_with_feature')
owner = fields.Many2One( owner = fields.Many2One(
string='Owner', required=True, select=True, string='Owner', required=True,
model_name='res.user', ondelete='SET NULL', model_name='res.user', ondelete='SET NULL',
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
reviewer = fields.Many2One( reviewer = fields.Many2One(
string='Reviewer', select=True, string='Reviewer',
help='Group of users who have write access to the cashbook.', help='Group of users who have write access to the cashbook.',
model_name='res.group', ondelete='SET NULL', model_name='res.group', ondelete='SET NULL',
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
observer = fields.Many2One( observer = fields.Many2One(
string='Observer', select=True, string='Observer',
help='Group of users who have read-only access to the cashbook.', help='Group of users who have read-only access to the cashbook.',
model_name='res.group', ondelete='SET NULL', model_name='res.group', ondelete='SET NULL',
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
@ -158,7 +160,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
'on_change_with_currency_digits') 'on_change_with_currency_digits')
currency = fields.Many2One( currency = fields.Many2One(
string='Currency', select=True, string='Currency',
model_name='currency.currency', model_name='currency.currency',
states={ states={
'readonly': Or( 'readonly': Or(
@ -196,6 +198,32 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
cls._order.insert(0, ('rec_name', 'ASC')) cls._order.insert(0, ('rec_name', 'ASC'))
cls._order.insert(0, ('state', 'ASC')) cls._order.insert(0, ('state', 'ASC'))
t = cls.__table__() t = cls.__table__()
cls._sql_indexes.update({
Index(
t,
(t.btype, Index.Equality())),
Index(
t,
(t.parent, Index.Equality())),
Index(
t,
(t.company, Index.Equality())),
Index(
t,
(t.currency, Index.Equality())),
Index(
t,
(t.state, Index.Equality())),
Index(
t,
(t.owner, Index.Equality())),
Index(
t,
(t.reviewer, Index.Equality())),
Index(
t,
(t.observer, Index.Equality())),
})
cls._sql_constraints.extend([ cls._sql_constraints.extend([
('state_val', ('state_val',
Check(t, t.state.in_(['open', 'closed', 'archive'])), Check(t, t.state.in_(['open', 'closed', 'archive'])),

42
line.py
View file

@ -3,7 +3,7 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, Workflow, fields, Check from trytond.model import ModelView, ModelSQL, Workflow, fields, Check, Index
from trytond.pool import Pool from trytond.pool import Pool
from trytond.pyson import Eval, If, Or, Bool, Date from trytond.pyson import Eval, If, Or, Bool, Date
from trytond.transaction import Transaction from trytond.transaction import Transaction
@ -53,24 +53,24 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
__name__ = 'cashbook.line' __name__ = 'cashbook.line'
cashbook = fields.Many2One( cashbook = fields.Many2One(
string='Cashbook', required=True, select=True, string='Cashbook', required=True,
model_name='cashbook.book', ondelete='CASCADE', readonly=True, model_name='cashbook.book', ondelete='CASCADE', readonly=True,
domain=[('btype', '!=', None)]) domain=[('btype', '!=', None)])
date = fields.Date( date = fields.Date(
string='Date', required=True, select=True, string='Date', required=True,
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
month = fields.Function(fields.Integer( month = fields.Function(fields.Integer(
string='Month', readonly=True), string='Month', readonly=True),
'on_change_with_month', searcher='search_month') 'on_change_with_month', searcher='search_month')
number = fields.Char(string='Number', readonly=True) number = fields.Char(string='Number', readonly=True)
description = fields.Text( description = fields.Text(
string='Description', select=True, string='Description',
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
descr_short = fields.Function(fields.Char( descr_short = fields.Function(fields.Char(
string='Description', readonly=True), string='Description', readonly=True),
'on_change_with_descr_short', searcher='search_descr_short') 'on_change_with_descr_short', searcher='search_descr_short')
category = fields.Many2One( category = fields.Many2One(
string='Category', select=True, string='Category',
model_name='cashbook.category', ondelete='RESTRICT', model_name='cashbook.category', ondelete='RESTRICT',
states={ states={
'readonly': Or( 'readonly': Or(
@ -98,7 +98,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
bookingtype = fields.Selection( bookingtype = fields.Selection(
string='Type', required=True, string='Type', required=True,
help='Type of Booking', selection=sel_bookingtype, select=True, help='Type of Booking', selection=sel_bookingtype,
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
bookingtype_string = bookingtype.translated('bookingtype') bookingtype_string = bookingtype.translated('bookingtype')
amount = fields.Numeric( amount = fields.Numeric(
@ -145,7 +145,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
# link to lines created by this record # link to lines created by this record
reference = fields.Many2One( reference = fields.Many2One(
string='Reference', readonly=True, select=True, string='Reference', readonly=True,
states={ states={
'invisible': ~Bool(Eval('reference')), 'invisible': ~Bool(Eval('reference')),
}, model_name='cashbook.line', ondelete='CASCADE', }, model_name='cashbook.line', ondelete='CASCADE',
@ -197,7 +197,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
state = fields.Selection( state = fields.Selection(
string='State', required=True, readonly=True, string='State', required=True, readonly=True,
select=True, selection=sel_linetype) selection=sel_linetype)
state_string = state.translated('state') state_string = state.translated('state')
state_cashbook = fields.Function(fields.Selection( state_cashbook = fields.Function(fields.Selection(
string='State of Cashbook', string='State of Cashbook',
@ -223,6 +223,30 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
cls._order.insert(0, ('date', 'ASC')) cls._order.insert(0, ('date', 'ASC'))
cls._order.insert(0, ('state', 'ASC')) cls._order.insert(0, ('state', 'ASC'))
t = cls.__table__() t = cls.__table__()
cls._sql_indexes.update({
Index(
t,
(t.cashbook, Index.Equality())),
Index(
t,
(t.date, Index.Range(order='ASC'))),
Index(
t,
(t.description, Index.Similarity())),
Index(
t,
(t.category, Index.Equality())),
Index(
t,
(t.bookingtype, Index.Equality())),
Index(
t,
(t.state, Index.Equality())),
Index(
t,
(t.reference, Index.Range())),
})
cls._sql_constraints.extend([ cls._sql_constraints.extend([
('state_val2', ('state_val2',
Check(t, t.state.in_(['edit', 'check', 'done', 'recon'])), Check(t, t.state.in_(['edit', 'check', 'done', 'recon'])),
@ -656,7 +680,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
@fields.depends('category') @fields.depends('category')
def on_change_with_category_view(self, name=None): def on_change_with_category_view(self, name=None):
""" show optimizef form of category for list-view """ show optimized form of category for list-view
""" """
Configuration = Pool().get('cashbook.configuration') Configuration = Pool().get('cashbook.configuration')

View file

@ -3,7 +3,7 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.model import fields from trytond.model import fields, Index
from trytond.pyson import Eval, Bool, Or from trytond.pyson import Eval, Bool, Or
from trytond.pool import Pool from trytond.pool import Pool
from trytond.modules.currency.ir import rate_decimal from trytond.modules.currency.ir import rate_decimal
@ -209,8 +209,15 @@ class MemCacheIndexMx:
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(MemCacheIndexMx, cls).__setup__() super(MemCacheIndexMx, cls).__setup__()
t = cls.__table__()
# add index # add index
cls.write_date.select = True cls._sql_indexes.update({
cls.create_date.select = True Index(
t,
(t.write_date, Index.Range())),
Index(
t,
(t.create_date, Index.Range())),
})
# end MemCacheIndexMx # end MemCacheIndexMx

View file

@ -3,7 +3,8 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.model import MultiValueMixin, ValueMixin, fields, Unique, Model from trytond.model import (
MultiValueMixin, ValueMixin, fields, Unique, Model, Index)
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
@ -290,12 +291,17 @@ def order_name_hierarchical(model_name, tables):
class UserValueMixin(ValueMixin): class UserValueMixin(ValueMixin):
iduser = fields.Many2One( iduser = fields.Many2One(
model_name='res.user', string="User", model_name='res.user', string="User",
select=True, ondelete='CASCADE', required=True) ondelete='CASCADE', required=True)
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(UserValueMixin, cls).__setup__() super(UserValueMixin, cls).__setup__()
tab_val = cls.__table__() tab_val = cls.__table__()
cls._sql_indexes.update({
Index(
tab_val,
(tab_val.iduser, Index.Equality())),
})
cls._sql_constraints.extend([ cls._sql_constraints.extend([
('val_uniq', ('val_uniq',
Unique(tab_val, tab_val.iduser), Unique(tab_val, tab_val.iduser),

View file

@ -3,7 +3,7 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.model import Workflow, ModelView, ModelSQL, fields from trytond.model import Workflow, ModelView, ModelSQL, fields, Index
from trytond.pyson import Eval, If, Or from trytond.pyson import Eval, If, Or
from trytond.pool import Pool from trytond.pool import Pool
from trytond.report import Report from trytond.report import Report
@ -34,10 +34,10 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
__name__ = 'cashbook.recon' __name__ = 'cashbook.recon'
cashbook = fields.Many2One( cashbook = fields.Many2One(
string='Cashbook', required=True, select=True, string='Cashbook', required=True,
model_name='cashbook.book', ondelete='CASCADE', readonly=True) model_name='cashbook.book', ondelete='CASCADE', readonly=True)
date = fields.Date( date = fields.Date(
string='Date', required=True, select=True, string='Date', required=True,
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
feature = fields.Function(fields.Char( feature = fields.Function(fields.Char(
string='Feature', readonly=True, string='Feature', readonly=True,
@ -54,7 +54,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
states=STATES, depends=DEPENDS+['date_to']) states=STATES, depends=DEPENDS+['date_to'])
date_to = fields.Date( date_to = fields.Date(
string='End Date', string='End Date',
required=True, select=True, required=True,
domain=[ domain=[
If(Eval('date_to') & Eval('date_from'), If(Eval('date_to') & Eval('date_from'),
('date_from', '<=', Eval('date_to')), ('date_from', '<=', Eval('date_to')),
@ -98,7 +98,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
state = fields.Selection( state = fields.Selection(
string='State', required=True, readonly=True, string='State', required=True, readonly=True,
select=True, selection=sel_reconstate) selection=sel_reconstate)
state_string = state.translated('state') state_string = state.translated('state')
state_cashbook = fields.Function(fields.Selection( state_cashbook = fields.Function(fields.Selection(
string='State of Cashbook', string='State of Cashbook',
@ -109,6 +109,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
def __setup__(cls): def __setup__(cls):
super(Reconciliation, cls).__setup__() super(Reconciliation, cls).__setup__()
cls._order.insert(0, ('date_from', 'DESC')) cls._order.insert(0, ('date_from', 'DESC'))
t = cls.__table__()
cls._transitions |= set(( cls._transitions |= set((
('edit', 'check'), ('edit', 'check'),
('check', 'done'), ('check', 'done'),
@ -128,6 +129,23 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
'depends': ['state'], 'depends': ['state'],
}, },
}) })
cls._sql_indexes.update({
Index(
t,
(t.cashbook, Index.Equality())),
Index(
t,
(t.date, Index.Range())),
Index(
t,
(t.date_to, Index.Range())),
Index(
t,
(t.date_from, Index.Range(order='DESC'))),
Index(
t,
(t.state, Index.Equality())),
})
def check_overlap_dates(self): def check_overlap_dates(self):
""" deny overlap of date_from/date_to between records of same cashbook """ deny overlap of date_from/date_to between records of same cashbook

View file

@ -4,7 +4,7 @@
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields from trytond.model import ModelView, ModelSQL, fields, Index
from trytond.pool import Pool from trytond.pool import Pool
from trytond.pyson import Eval, If from trytond.pyson import Eval, If
from trytond.report import Report from trytond.report import Report
@ -31,16 +31,16 @@ class SplitLine(SecondCurrencyMixin, MemCacheIndexMx, ModelSQL, ModelView):
line = fields.Many2One( line = fields.Many2One(
string='Line', required=True, string='Line', required=True,
select=True, ondelete='CASCADE', model_name='cashbook.line', ondelete='CASCADE', model_name='cashbook.line',
readonly=True) readonly=True)
description = fields.Text( description = fields.Text(
string='Description', states=STATES, depends=DEPENDS) string='Description', states=STATES, depends=DEPENDS)
splittype = fields.Selection( splittype = fields.Selection(
string='Type', required=True, string='Type', required=True,
help='Type of split booking line', selection=sel_linetype, help='Type of split booking line', selection=sel_linetype,
states=STATES, depends=DEPENDS, select=True) states=STATES, depends=DEPENDS)
category = fields.Many2One( category = fields.Many2One(
string='Category', select=True, string='Category',
model_name='cashbook.category', ondelete='RESTRICT', model_name='cashbook.category', ondelete='RESTRICT',
states={ states={
'readonly': STATES['readonly'], 'readonly': STATES['readonly'],
@ -63,7 +63,7 @@ class SplitLine(SecondCurrencyMixin, MemCacheIndexMx, ModelSQL, ModelView):
('owner.id', '=', Eval('owner_cashbook', -1)), ('owner.id', '=', Eval('owner_cashbook', -1)),
('id', '!=', Eval('cashbook', -1)), ('id', '!=', Eval('cashbook', -1)),
('btype', '!=', None), ('btype', '!=', None),
], select=True, ],
states={ states={
'readonly': STATES['readonly'], 'readonly': STATES['readonly'],
'invisible': Eval('splittype', '') != 'tr', 'invisible': Eval('splittype', '') != 'tr',
@ -110,6 +110,25 @@ class SplitLine(SecondCurrencyMixin, MemCacheIndexMx, ModelSQL, ModelView):
states={'invisible': True}, model_name='res.user'), states={'invisible': True}, model_name='res.user'),
'on_change_with_owner_cashbook') 'on_change_with_owner_cashbook')
@classmethod
def __setup__(cls):
super(SplitLine, cls).__setup__()
t = cls.__table__()
cls._sql_indexes.update({
Index(
t,
(t.line, Index.Equality())),
Index(
t,
(t.splittype, Index.Equality())),
Index(
t,
(t.category, Index.Equality())),
Index(
t,
(t.booktransf, Index.Equality())),
})
@classmethod @classmethod
def default_splittype(cls): def default_splittype(cls):
""" default category """ default category

View file

@ -1,16 +1,4 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of # -*- coding: utf-8 -*-
# this repository contains the full copyright notices and license terms. # This file is part of the cashbook-module from m-ds for Tryton.
# The COPYRIGHT file at the top level of this repository contains the
import trytond.tests.test_tryton # full copyright notices and license terms.
import unittest
from .test_module import CashbookTestCase
__all__ = ['suite']
def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CashbookTestCase))
return suite

View file

@ -119,8 +119,8 @@ class CategoryTestCase(object):
self.assertRaisesRegex( self.assertRaisesRegex(
UserError, UserError,
'The value for field "Type" in "Category" is not valid ' + 'The value "out" for field "Type" in "Level 1/Level 2" of ' +
'according to its domain.', '"Category" is not valid according to its domain.',
Category.write, Category.write,
*[ *[
[category.childs[0]], [category.childs[0]],

View file

@ -889,8 +889,8 @@ class LineTestCase(object):
self.assertRaisesRegex( self.assertRaisesRegex(
UserError, UserError,
'The value for field "Cashbook" in "Cashbook Line" is not ' + r'The value "Book 1" for field "Cashbook" in "\d+" of ' +
'valid according to its domain.', r'"Cashbook Line" is not valid according to its domain.',
Line.create, Line.create,
[{ [{
'cashbook': book.id, 'cashbook': book.id,

View file

@ -19,7 +19,7 @@ class Type(ModelSQL, ModelView):
required=True, ondelete="RESTRICT") required=True, ondelete="RESTRICT")
feature = fields.Selection( feature = fields.Selection(
string='Feature', required=True, string='Feature', required=True,
selection='get_sel_feature', select=True, selection='get_sel_feature',
help='Select feature set of the Cashbook.') help='Select feature set of the Cashbook.')
@classmethod @classmethod