formatting, indexes optimized

This commit is contained in:
Frederik Jaeckel 2023-11-29 15:19:38 +01:00
parent 77ee7d15b7
commit 7220cff5ac
12 changed files with 124 additions and 126 deletions

15
book.py
View file

@ -74,8 +74,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
states={ states={
'readonly': Or( 'readonly': Or(
STATES['readonly'], STATES['readonly'],
Len(Eval('lines')) > 0, Len(Eval('lines')) > 0),
),
}, depends=DEPENDS+['lines']) }, depends=DEPENDS+['lines'])
feature = fields.Function(fields.Char( feature = fields.Function(fields.Char(
string='Feature', readonly=True, string='Feature', readonly=True,
@ -124,8 +123,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
states={ states={
'readonly': Or( 'readonly': Or(
STATES2['readonly'], STATES2['readonly'],
Len(Eval('lines')) > 0, Len(Eval('lines')) > 0),
),
'invisible': STATES2['invisible'], 'invisible': STATES2['invisible'],
'required': ~STATES2['invisible'], 'required': ~STATES2['invisible'],
}, depends=DEPENDS2+['lines']) }, depends=DEPENDS2+['lines'])
@ -165,8 +163,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
states={ states={
'readonly': Or( 'readonly': Or(
STATES2['readonly'], STATES2['readonly'],
Len(Eval('lines', [])) > 0, Len(Eval('lines', [])) > 0),
),
}, depends=DEPENDS2+['lines']) }, depends=DEPENDS2+['lines'])
currency_digits = fields.Function(fields.Integer( currency_digits = fields.Function(fields.Integer(
string='Currency Digits', string='Currency Digits',
@ -202,9 +199,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
Index( Index(
t, t,
(t.btype, Index.Equality())), (t.btype, Index.Equality())),
Index(
t,
(t.parent, Index.Equality())),
Index( Index(
t, t,
(t.company, Index.Equality())), (t.company, Index.Equality())),
@ -396,8 +390,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
query = tab_line.select( query = tab_line.select(
tab_line.cashbook, tab_line.cashbook,
where=Operator( where=Operator(
getattr(tab_line, name), clause[2]), getattr(tab_line, name), clause[2]))
)
return [('id', 'in', query)] return [('id', 'in', query)]
@classmethod @classmethod

View file

@ -11,6 +11,7 @@ from trytond.exceptions import UserError
from trytond.i18n import gettext from trytond.i18n import gettext
from sql.operators import Equal from sql.operators import Equal
from .model import order_name_hierarchical from .model import order_name_hierarchical
from .const import DEF_NONE
sel_categorytype = [ sel_categorytype = [
@ -70,7 +71,7 @@ class Category(tree(separator='/'), ModelSQL, ModelView):
t, t,
(t.name, Equal), (t.name, Equal),
(t.cattype, Equal), (t.cattype, Equal),
where=(t.parent == None)), where=(t.parent == DEF_NONE)),
'cashbook.msg_category_name_unique'), 'cashbook.msg_category_name_unique'),
]) ])

View file

@ -17,7 +17,8 @@ field_done = fields.Boolean(
help='Show cashbook lines in Done-state.') help='Show cashbook lines in Done-state.')
field_catnamelong = fields.Boolean( field_catnamelong = fields.Boolean(
string='Category: Show long name', string='Category: Show long name',
help='Shows the long name of the category in the Category field of a cash book line.') help='Shows the long name of the category in the Category ' +
'field of a cash book line.')
class Configuration(ModelSingleton, ModelSQL, ModelView, UserMultiValueMixin): class Configuration(ModelSingleton, ModelSQL, ModelView, UserMultiValueMixin):
@ -29,60 +30,47 @@ class Configuration(ModelSingleton, ModelSQL, ModelView, UserMultiValueMixin):
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')),
()), ())]))
]))
date_to = fields.MultiValue(fields.Date( date_to = fields.MultiValue(fields.Date(
string='End Date', depends=['date_from'], string='End Date', depends=['date_from'],
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')),
()), ())]))
]))
checked = fields.MultiValue(field_checked) checked = fields.MultiValue(field_checked)
done = fields.MultiValue(field_done) done = fields.MultiValue(field_done)
catnamelong = fields.MultiValue(field_catnamelong) catnamelong = fields.MultiValue(field_catnamelong)
defbook = fields.MultiValue(fields.Many2One( defbook = fields.MultiValue(fields.Many2One(
string='Default Cashbook', string='Default Cashbook',
help='The default cashbook is selected when you open the booking wizard.', help='The default cashbook is selected when you open ' +
'the booking wizard.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[('btype', '!=', None), ('state', '=', 'open')]))
('btype', '!=', None), ('state', '=', 'open'),
]))
book1 = fields.MultiValue(fields.Many2One( book1 = fields.MultiValue(fields.Many2One(
string='Cashbook 1', string='Cashbook 1',
help='Cash book available in selection dialog.', help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[('btype', '!=', None), ('state', '=', 'open')]))
('btype', '!=', None), ('state', '=', 'open'),
]))
book2 = fields.MultiValue(fields.Many2One( book2 = fields.MultiValue(fields.Many2One(
string='Cashbook 2', string='Cashbook 2',
help='Cash book available in selection dialog.', help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[('btype', '!=', None), ('state', '=', 'open')]))
('btype', '!=', None), ('state', '=', 'open'),
]))
book3 = fields.MultiValue(fields.Many2One( book3 = fields.MultiValue(fields.Many2One(
string='Cashbook 3', string='Cashbook 3',
help='Cash book available in selection dialog.', help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[('btype', '!=', None), ('state', '=', 'open')]))
('btype', '!=', None), ('state', '=', 'open'),
]))
book4 = fields.MultiValue(fields.Many2One( book4 = fields.MultiValue(fields.Many2One(
string='Cashbook 4', string='Cashbook 4',
help='Cash book available in selection dialog.', help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[('btype', '!=', None), ('state', '=', 'open')]))
('btype', '!=', None), ('state', '=', 'open'),
]))
book5 = fields.MultiValue(fields.Many2One( book5 = fields.MultiValue(fields.Many2One(
string='Cashbook 5', string='Cashbook 5',
help='Cash book available in selection dialog.', help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[('btype', '!=', None), ('state', '=', 'open')]))
('btype', '!=', None), ('state', '=', 'open'),
]))
@classmethod @classmethod
def multivalue_model(cls, field): def multivalue_model(cls, field):
@ -121,21 +109,20 @@ class UserConfiguration(ModelSQL, UserValueMixin):
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')),
()), ())])
])
date_to = fields.Date( date_to = fields.Date(
string='End Date', depends=['date_from'], string='End Date', depends=['date_from'],
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')),
()), ())])
])
checked = field_checked checked = field_checked
done = field_done done = field_done
catnamelong = field_catnamelong catnamelong = field_catnamelong
defbook = fields.Many2One( defbook = fields.Many2One(
string='Default Cashbook', string='Default Cashbook',
help='The default cashbook is selected when you open the booking wizard.', help='The default cashbook is selected when you open ' +
'the booking wizard.',
model_name='cashbook.book', ondelete='SET NULL', model_name='cashbook.book', ondelete='SET NULL',
domain=[ domain=[
('btype', '!=', None), ('btype', '!=', None),

8
const.py Normal file
View file

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
# This file is part of the cashbook-module from m-ds.de for Tryton.
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
DEF_NONE = None

View file

@ -42,7 +42,8 @@ class CurrencyRate(metaclass=PoolMeta):
MemCache = Pool().get('cashbook.memcache') MemCache = Pool().get('cashbook.memcache')
for record in records: for record in records:
MemCache.record_update(CACHEKEY_CURRENCY % record.currency.id, None) MemCache.record_update(
CACHEKEY_CURRENCY % record.currency.id, None)
super(CurrencyRate, cls).delete(records) super(CurrencyRate, cls).delete(records)
# end # end

41
line.py
View file

@ -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 .const import DEF_NONE
sel_payee = [ sel_payee = [
@ -48,7 +49,9 @@ STATES = {
DEPENDS = ['state', 'state_cashbook'] DEPENDS = ['state', 'state_cashbook']
class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView): class Line(
SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL,
ModelView):
'Cashbook Line' 'Cashbook Line'
__name__ = 'cashbook.line' __name__ = 'cashbook.line'
@ -75,8 +78,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
states={ states={
'readonly': Or( 'readonly': Or(
STATES['readonly'], STATES['readonly'],
Bool(Eval('bookingtype')) == False, ~Bool(Eval('bookingtype'))),
),
'required': Eval('bookingtype', '').in_(['in', 'out']), 'required': Eval('bookingtype', '').in_(['in', 'out']),
'invisible': ~Eval('bookingtype', '').in_(['in', 'out']), 'invisible': ~Eval('bookingtype', '').in_(['in', 'out']),
}, depends=DEPENDS+['bookingtype'], }, depends=DEPENDS+['bookingtype'],
@ -161,7 +163,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
splitlines = fields.One2Many( splitlines = fields.One2Many(
string='Split booking lines', string='Split booking lines',
model_name='cashbook.split', model_name='cashbook.split',
help='Rows with different categories form the total sum of the booking', help='Rows with different categories form the total ' +
'sum of the booking',
states={ states={
'invisible': ~Eval('bookingtype' '').in_(['spin', 'spout']), 'invisible': ~Eval('bookingtype' '').in_(['spin', 'spout']),
'readonly': Or( 'readonly': Or(
@ -225,9 +228,6 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
t = cls.__table__() t = cls.__table__()
cls._sql_indexes.update({ cls._sql_indexes.update({
Index(
t,
(t.cashbook, Index.Equality())),
Index( Index(
t, t,
(t.date, Index.Range(order='ASC'))), (t.date, Index.Range(order='ASC'))),
@ -308,7 +308,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
).select( ).select(
tab_line.id, tab_line.id,
where=tab_line.bookingtype.in_(['mvin', 'mvout']) & where=tab_line.bookingtype.in_(['mvin', 'mvout']) &
(tab_line.amount_2nd_currency == None) & (tab_line.amount_2nd_currency == DEF_NONE) &
(tab_book.currency != tab_book2.currency) (tab_book.currency != tab_book2.currency)
) )
lines = Line2.search([('id', 'in', query)]) lines = Line2.search([('id', 'in', query)])
@ -344,7 +344,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
for line in lines: for line in lines:
if line.reference: if line.reference:
if Transaction().context.get( if Transaction().context.get(
'line.allow.wfedit', False) == False: 'line.allow.wfedit', False) is False:
raise UserError(gettext( raise UserError(gettext(
'cashbook.msg_line_denywf_by_reference', 'cashbook.msg_line_denywf_by_reference',
recname=line.reference.rec_name, recname=line.reference.rec_name,
@ -508,19 +508,20 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
""" """
credit = self.credit if self.credit is not None else Decimal('0.0') credit = self.credit if self.credit is not None else Decimal('0.0')
debit = self.debit if self.debit is not None else Decimal('0.0') debit = self.debit if self.debit is not None else Decimal('0.0')
return '%(date)s|%(type)s|%(amount)s %(symbol)s|%(desc)s [%(category)s]' % { return '|'.join([
'date': Report.format_date(self.date), Report.format_date(self.date),
'desc': (self.description or '-')[:40], gettext('cashbook.msg_line_bookingtype_%s' % self.bookingtype),
'%(amount)s %(symbol)s' % {
'amount': Report.format_number( 'amount': Report.format_number(
credit - debit, None, credit - debit, None,
digits=getattr(self.currency, 'digits', 2)), digits=getattr(self.currency, 'digits', 2)),
'symbol': getattr(self.currency, 'symbol', '-'), 'symbol': getattr(self.currency, 'symbol', '-')},
'%(desc)s [%(category)s]' % {
'desc': (self.description or '-')[:40],
'category': self.category_view 'category': self.category_view
if self.bookingtype in ['in', 'out'] if self.bookingtype in ['in', 'out']
else getattr(self.booktransf, 'rec_name', '-'), else getattr(self.booktransf, 'rec_name', '-')},
'type': gettext( ])
'cashbook.msg_line_bookingtype_%s' %
self.bookingtype)}
@staticmethod @staticmethod
def order_state(tables): def order_state(tables):
@ -535,8 +536,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
(tab_line.state == 'edit', 1), (tab_line.state == 'edit', 1),
(tab_line.state.in_(['check', 'recon', 'done']), 0), (tab_line.state.in_(['check', 'recon', 'done']), 0),
else_=2), else_=2),
where=tab_line.id == table.id where=tab_line.id == table.id)
)
return [query] return [query]
@staticmethod @staticmethod
@ -626,7 +626,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
if self.bookingtype: if self.bookingtype:
if self.category: if self.category:
if self.bookingtype not in types.get(self.category.cattype, ''): if self.bookingtype not in types.get(
self.category.cattype, ''):
self.category = None self.category = None
if self.bookingtype.startswith('sp'): # split booking if self.bookingtype.startswith('sp'): # split booking

View file

@ -31,20 +31,19 @@ class SecondCurrencyMixin:
states={ states={
'readonly': Or( 'readonly': Or(
STATES['readonly'], STATES['readonly'],
~Bool(Eval('currency2nd')) ~Bool(Eval('currency2nd'))),
),
'required': Bool(Eval('currency2nd')), 'required': Bool(Eval('currency2nd')),
'invisible': ~Bool(Eval('currency2nd')), 'invisible': ~Bool(Eval('currency2nd')),
}, depends=DEPENDS+['currency2nd_digits', 'currency2nd']) }, depends=DEPENDS+['currency2nd_digits', 'currency2nd'])
rate_2nd_currency = fields.Function(fields.Numeric( rate_2nd_currency = fields.Function(fields.Numeric(
string='Rate', string='Rate',
help='Exchange rate between the currencies of the participating cashbooks.', help='Exchange rate between the currencies of the ' +
'participating cashbooks.',
digits=(rate_decimal * 2, rate_decimal), digits=(rate_decimal * 2, rate_decimal),
states={ states={
'readonly': Or( 'readonly': Or(
STATES['readonly'], STATES['readonly'],
~Bool(Eval('currency2nd')) ~Bool(Eval('currency2nd'))),
),
'required': Bool(Eval('currency2nd')), 'required': Bool(Eval('currency2nd')),
'invisible': ~Bool(Eval('currency2nd')), 'invisible': ~Bool(Eval('currency2nd')),
}, depends=DEPENDS+['currency2nd_digits', 'currency2nd']), }, depends=DEPENDS+['currency2nd_digits', 'currency2nd']),
@ -124,15 +123,13 @@ class SecondCurrencyMixin:
self.amount_2nd_currency = Currency.compute( self.amount_2nd_currency = Currency.compute(
self.currency, self.currency,
self.amount, self.amount,
self.booktransf.currency self.booktransf.currency)
)
if self.amount != Decimal('0.0'): if self.amount != Decimal('0.0'):
self.rate_2nd_currency = \ self.rate_2nd_currency = \
self.amount_2nd_currency / self.amount self.amount_2nd_currency / self.amount
else: else:
self.amount_2nd_currency = self.booktransf.currency.round( self.amount_2nd_currency = self.booktransf.currency.round(
self.amount * self.rate_2nd_currency self.amount * self.rate_2nd_currency)
)
@classmethod @classmethod
def set_rate_2nd_currency(cls, lines, name, value): def set_rate_2nd_currency(cls, lines, name, value):

View file

@ -15,6 +15,8 @@ from sql import With
from sql.functions import Function from sql.functions import Function
from sql.conditionals import Coalesce from sql.conditionals import Coalesce
import copy import copy
from .const import DEF_NONE
if config.get('cashbook', 'memcache', default='yes').lower() \ if config.get('cashbook', 'memcache', default='yes').lower() \
in ['yes', '1', 'true']: in ['yes', '1', 'true']:
@ -269,7 +271,7 @@ def order_name_hierarchical(model_name, tables):
lines = With('id', 'name', 'name_path', recursive=True) lines = With('id', 'name', 'name_path', recursive=True)
lines.query = tab_mod.select( lines.query = tab_mod.select(
tab_mod.id, tab_mod.name, Array(tab_mod.name), tab_mod.id, tab_mod.name, Array(tab_mod.name),
where=tab_mod.parent == None, where=tab_mod.parent == DEF_NONE,
) )
lines.query |= tab_mod2.join( lines.query |= tab_mod2.join(
lines, lines,

View file

@ -204,7 +204,8 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
# unlink lines from reconciliation # unlink lines from reconciliation
if len(reconciliation.lines) > 0: if len(reconciliation.lines) > 0:
values['lines'] = [('remove', [x.id for x in reconciliation.lines])] values['lines'] = [
('remove', [x.id for x in reconciliation.lines])]
return values return values
@classmethod @classmethod
@ -339,20 +340,24 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
def get_rec_name(self, name): def get_rec_name(self, name):
""" short + name """ short + name
""" """
return '%(from)s - %(to)s | %(start_amount)s %(symbol)s - %(end_amount)s %(symbol)s [%(num)s]' % { return ' '.join([
'from': Report.format_date(self.date_from, None) Report.format_date(self.date_from, None)
if self.date_from is not None else '-', if self.date_from is not None else '-',
'to': Report.format_date(self.date_to, None) '-',
Report.format_date(self.date_to, None)
if self.date_to is not None else '-', if self.date_to is not None else '-',
'start_amount': Report.format_number( '|',
Report.format_number(
self.start_amount or 0.0, None, self.start_amount or 0.0, None,
digits=getattr(self.currency, 'digits', 2)), digits=getattr(self.currency, 'digits', 2)),
'end_amount': Report.format_number( getattr(self.currency, 'symbol', '-'),
'-',
Report.format_number(
self.end_amount or 0.0, None, self.end_amount or 0.0, None,
digits=getattr(self.currency, 'digits', 2)), digits=getattr(self.currency, 'digits', 2)),
'symbol': getattr(self.currency, 'symbol', '-'), getattr(self.currency, 'symbol', '-'),
'num': len(self.lines), '[%(num)s]' % {'num': len(self.lines)},
} ])
@classmethod @classmethod
def default_date_from(cls): def default_date_from(cls):

View file

@ -2,7 +2,7 @@
""" """
# Always prefer setuptools over distutils # Always prefer setuptools over distutils
from setuptools import setup, find_packages from setuptools import setup
# To use a consistent encoding # To use a consistent encoding
from codecs import open from codecs import open
from os import path from os import path
@ -36,7 +36,7 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f:
l2 = i.strip().split(';') l2 = i.strip().split(';')
if len(l2) < 4: if len(l2) < 4:
continue continue
modversion[l2[0]] = {'min':l2[1], 'max':l2[2], 'prefix':l2[3]} modversion[l2[0]] = {'min': l2[1], 'max': l2[2], 'prefix': l2[3]}
# tryton-version # tryton-version
major_version = 6 major_version = 6
@ -51,19 +51,21 @@ for dep in info.get('depends', []):
prefix = modversion[dep]['prefix'] prefix = modversion[dep]['prefix']
if len(modversion[dep]['max']) > 0: if len(modversion[dep]['max']) > 0:
requires.append('%s_%s >= %s, <= %s' % requires.append('%s_%s >= %s, <= %s' % (
(prefix, dep, modversion[dep]['min'], modversion[dep]['max'])) prefix, dep, modversion[dep]['min'],
else : modversion[dep]['max']))
requires.append('%s_%s >= %s' % else:
(prefix, dep, modversion[dep]['min'])) requires.append('%s_%s >= %s' % (
else : prefix, dep, modversion[dep]['min']))
requires.append('%s_%s >= %s.%s, < %s.%s' % else:
('trytond', dep, major_version, minor_version, requires.append('%s_%s >= %s.%s, < %s.%s' % (
'trytond', dep, major_version, minor_version,
major_version, minor_version + 1)) major_version, minor_version + 1))
requires.append('trytond >= %s.%s, < %s.%s' % requires.append('trytond >= %s.%s, < %s.%s' % (
(major_version, minor_version, major_version, minor_version + 1)) major_version, minor_version, major_version, minor_version + 1))
setup(name='%s_%s' % (PREFIX, MODULE), setup(
name='%s_%s' % (PREFIX, MODULE),
version=info.get('version', '0.0.1'), version=info.get('version', '0.0.1'),
description='Tryton module to add a cashbook.', description='Tryton module to add a cashbook.',
long_description=long_description, long_description=long_description,
@ -97,8 +99,8 @@ setup(name='%s_%s' % (PREFIX, MODULE),
'trytond.modules.%s' % MODULE, 'trytond.modules.%s' % MODULE,
], ],
package_data={ package_data={
'trytond.modules.%s' % MODULE: (info.get('xml', []) 'trytond.modules.%s' % MODULE: (info.get('xml', []) + [
+ ['tryton.cfg', 'locale/*.po', 'tests/*.py', 'tryton.cfg', 'locale/*.po', 'tests/*.py',
'view/*.xml', 'icon/*.svg', 'docs/*.txt', 'view/*.xml', 'icon/*.svg', 'docs/*.txt',
'report/*.fods', 'versiondep.txt', 'README.rst']), 'report/*.fods', 'versiondep.txt', 'README.rst']),
}, },

View file

@ -28,7 +28,9 @@ class Type(ModelSQL, ModelView):
cls._order.insert(0, ('name', 'ASC')) cls._order.insert(0, ('name', 'ASC'))
t = cls.__table__() t = cls.__table__()
cls._sql_constraints.extend([ cls._sql_constraints.extend([
('code_uniq', Unique(t, t.short), 'cashbook.msg_type_short_unique'), ('code_uniq',
Unique(t, t.short),
'cashbook.msg_type_short_unique'),
]) ])
cls._sql_indexes.update({ cls._sql_indexes.update({
Index( Index(
@ -53,8 +55,7 @@ class Type(ModelSQL, ModelView):
""" """
return '%(short)s - %(name)s' % { return '%(short)s - %(name)s' % {
'short': self.short or '-', 'short': self.short or '-',
'name': self.name or '-', 'name': self.name or '-'}
}
@classmethod @classmethod
def search_rec_name(cls, name, clause): def search_rec_name(cls, name, clause):
@ -63,8 +64,7 @@ class Type(ModelSQL, ModelView):
return [ return [
'OR', 'OR',
('name',) + tuple(clause[1:]), ('name',) + tuple(clause[1:]),
('short',) + tuple(clause[1:]), ('short',) + tuple(clause[1:])]
]
@staticmethod @staticmethod
def default_company(): def default_company():

View file

@ -50,7 +50,7 @@ class EnterBookingStart(ModelView):
string='Category', string='Category',
model_name='cashbook.category', depends=['bookingtype'], model_name='cashbook.category', depends=['bookingtype'],
states={ states={
'readonly': Bool(Eval('bookingtype')) == False, 'readonly': ~Bool(Eval('bookingtype')),
'required': Eval('bookingtype', '').in_(['in', 'out']), 'required': Eval('bookingtype', '').in_(['in', 'out']),
'invisible': ~Eval('bookingtype', '').in_(['in', 'out']), 'invisible': ~Eval('bookingtype', '').in_(['in', 'out']),
}, },
@ -90,7 +90,8 @@ class EnterBookingStart(ModelView):
if self.bookingtype: if self.bookingtype:
if self.category: if self.category:
if self.bookingtype not in types.get(self.category.cattype, ''): if self.bookingtype not in types.get(
self.category.cattype, ''):
self.category = None self.category = None
@fields.depends('cashbook', '_parent_cashbook.owner') @fields.depends('cashbook', '_parent_cashbook.owner')