diff --git a/README.rst b/README.rst
index 83d5baa..668a099 100644
--- a/README.rst
+++ b/README.rst
@@ -9,7 +9,7 @@ pip install mds-cashbook
Requires
========
-- Tryton 6.0
+- Tryton 6.8
How to
======
@@ -153,6 +153,22 @@ currency are converted into the display currency of the parent cash book.
Changes
=======
-*6.0.0 - 05.08.2022*
+*6.8.32 - 06.12.2023*
+
+- columns optional
+
+*6.8.31 - 30.11.2023*
+
+- optimized ir.rule
+
+*6.8.30 - 25.07.2023*
+
+- updt: optimize code, add tests
+
+*6.8.29 - 24.07.2023*
+
+- fix: type of indexes
+
+*6.8.28 - 05.06.2023*
- init
diff --git a/book.py b/book.py
index 3e3fa0f..872f54a 100644
--- a/book.py
+++ b/book.py
@@ -74,8 +74,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
states={
'readonly': Or(
STATES['readonly'],
- Len(Eval('lines')) > 0,
- ),
+ Len(Eval('lines')) > 0),
}, depends=DEPENDS+['lines'])
feature = fields.Function(fields.Char(
string='Feature', readonly=True,
@@ -124,8 +123,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
states={
'readonly': Or(
STATES2['readonly'],
- Len(Eval('lines')) > 0,
- ),
+ Len(Eval('lines')) > 0),
'invisible': STATES2['invisible'],
'required': ~STATES2['invisible'],
}, depends=DEPENDS2+['lines'])
@@ -165,8 +163,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
states={
'readonly': Or(
STATES2['readonly'],
- Len(Eval('lines', [])) > 0,
- ),
+ Len(Eval('lines', [])) > 0),
}, depends=DEPENDS2+['lines'])
currency_digits = fields.Function(fields.Integer(
string='Currency Digits',
@@ -202,9 +199,6 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
Index(
t,
(t.btype, Index.Equality())),
- Index(
- t,
- (t.parent, Index.Equality())),
Index(
t,
(t.company, Index.Equality())),
@@ -396,8 +390,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
query = tab_line.select(
tab_line.cashbook,
where=Operator(
- getattr(tab_line, name), clause[2]),
- )
+ getattr(tab_line, name), clause[2]))
return [('id', 'in', query)]
@classmethod
@@ -574,7 +567,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView):
'defbook', 'book1', 'book2', 'book3',
'book4', 'book5']:
cfg1 = ConfigUser.search([
- ('iduser.id', '=', book.owner.id),
+ ('iduser', '=', book.owner.id),
('%s.id' % x, '=', book.id)])
if len(cfg1) > 0:
to_write_config.extend([cfg1, {x: None}])
diff --git a/book.xml b/book.xml
index 9b113ee..4520409 100644
--- a/book.xml
+++ b/book.xml
@@ -143,8 +143,8 @@ full copyright notices and license terms. -->
diff --git a/category.py b/category.py
index 888697a..a10b3d1 100644
--- a/category.py
+++ b/category.py
@@ -11,6 +11,7 @@ from trytond.exceptions import UserError
from trytond.i18n import gettext
from sql.operators import Equal
from .model import order_name_hierarchical
+from .const import DEF_NONE
sel_categorytype = [
@@ -70,7 +71,7 @@ class Category(tree(separator='/'), ModelSQL, ModelView):
t,
(t.name, Equal),
(t.cattype, Equal),
- where=(t.parent == None)),
+ where=(t.parent == DEF_NONE)),
'cashbook.msg_category_name_unique'),
])
diff --git a/configuration.py b/configuration.py
index 2da84ee..2f2f5db 100644
--- a/configuration.py
+++ b/configuration.py
@@ -17,7 +17,8 @@ field_done = fields.Boolean(
help='Show cashbook lines in Done-state.')
field_catnamelong = fields.Boolean(
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):
@@ -29,60 +30,47 @@ class Configuration(ModelSingleton, ModelSQL, ModelView, UserMultiValueMixin):
domain=[
If(Eval('date_to') & Eval('date_from'),
('date_from', '<=', Eval('date_to')),
- ()),
- ]))
+ ())]))
date_to = fields.MultiValue(fields.Date(
string='End Date', depends=['date_from'],
domain=[
If(Eval('date_to') & Eval('date_from'),
('date_from', '<=', Eval('date_to')),
- ()),
- ]))
+ ())]))
checked = fields.MultiValue(field_checked)
done = fields.MultiValue(field_done)
catnamelong = fields.MultiValue(field_catnamelong)
defbook = fields.MultiValue(fields.Many2One(
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',
- domain=[
- ('btype', '!=', None), ('state', '=', 'open'),
- ]))
+ domain=[('btype', '!=', None), ('state', '=', 'open')]))
book1 = fields.MultiValue(fields.Many2One(
string='Cashbook 1',
help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL',
- domain=[
- ('btype', '!=', None), ('state', '=', 'open'),
- ]))
+ domain=[('btype', '!=', None), ('state', '=', 'open')]))
book2 = fields.MultiValue(fields.Many2One(
string='Cashbook 2',
help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL',
- domain=[
- ('btype', '!=', None), ('state', '=', 'open'),
- ]))
+ domain=[('btype', '!=', None), ('state', '=', 'open')]))
book3 = fields.MultiValue(fields.Many2One(
string='Cashbook 3',
help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL',
- domain=[
- ('btype', '!=', None), ('state', '=', 'open'),
- ]))
+ domain=[('btype', '!=', None), ('state', '=', 'open')]))
book4 = fields.MultiValue(fields.Many2One(
string='Cashbook 4',
help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL',
- domain=[
- ('btype', '!=', None), ('state', '=', 'open'),
- ]))
+ domain=[('btype', '!=', None), ('state', '=', 'open')]))
book5 = fields.MultiValue(fields.Many2One(
string='Cashbook 5',
help='Cash book available in selection dialog.',
model_name='cashbook.book', ondelete='SET NULL',
- domain=[
- ('btype', '!=', None), ('state', '=', 'open'),
- ]))
+ domain=[('btype', '!=', None), ('state', '=', 'open')]))
@classmethod
def multivalue_model(cls, field):
@@ -121,21 +109,20 @@ class UserConfiguration(ModelSQL, UserValueMixin):
domain=[
If(Eval('date_to') & Eval('date_from'),
('date_from', '<=', Eval('date_to')),
- ()),
- ])
+ ())])
date_to = fields.Date(
string='End Date', depends=['date_from'],
domain=[
If(Eval('date_to') & Eval('date_from'),
('date_from', '<=', Eval('date_to')),
- ()),
- ])
+ ())])
checked = field_checked
done = field_done
catnamelong = field_catnamelong
defbook = fields.Many2One(
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',
domain=[
('btype', '!=', None),
diff --git a/const.py b/const.py
new file mode 100644
index 0000000..6eaa075
--- /dev/null
+++ b/const.py
@@ -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
+
diff --git a/currency.py b/currency.py
index 9d406c6..817812f 100644
--- a/currency.py
+++ b/currency.py
@@ -42,7 +42,8 @@ class CurrencyRate(metaclass=PoolMeta):
MemCache = Pool().get('cashbook.memcache')
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)
# end
diff --git a/line.py b/line.py
index 18cbb3e..45dae05 100644
--- a/line.py
+++ b/line.py
@@ -16,6 +16,7 @@ from sql.functions import DatePart
from sql.conditionals import Case
from .book import sel_state_book
from .mixin import SecondCurrencyMixin, MemCacheIndexMx
+from .const import DEF_NONE
sel_payee = [
@@ -23,7 +24,7 @@ sel_payee = [
('party.party', 'Party')
]
-sel_linetype = [
+sel_linestate = [
('edit', 'Edit'),
('check', 'Checked'),
('recon', 'Reconciled'),
@@ -48,7 +49,9 @@ STATES = {
DEPENDS = ['state', 'state_cashbook']
-class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
+class Line(
+ SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL,
+ ModelView):
'Cashbook Line'
__name__ = 'cashbook.line'
@@ -75,8 +78,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
states={
'readonly': Or(
STATES['readonly'],
- Bool(Eval('bookingtype')) == False,
- ),
+ ~Bool(Eval('bookingtype'))),
'required': Eval('bookingtype', '').in_(['in', 'out']),
'invisible': ~Eval('bookingtype', '').in_(['in', 'out']),
}, depends=DEPENDS+['bookingtype'],
@@ -161,7 +163,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
splitlines = fields.One2Many(
string='Split booking lines',
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={
'invisible': ~Eval('bookingtype' '').in_(['spin', 'spout']),
'readonly': Or(
@@ -197,7 +200,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
state = fields.Selection(
string='State', required=True, readonly=True,
- selection=sel_linetype)
+ selection=sel_linestate)
state_string = state.translated('state')
state_cashbook = fields.Function(fields.Selection(
string='State of Cashbook',
@@ -225,9 +228,6 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
t = cls.__table__()
cls._sql_indexes.update({
- Index(
- t,
- (t.cashbook, Index.Equality())),
Index(
t,
(t.date, Index.Range(order='ASC'))),
@@ -245,7 +245,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
(t.state, Index.Equality())),
Index(
t,
- (t.reference, Index.Range())),
+ (t.reference, Index.Equality())),
})
cls._sql_constraints.extend([
('state_val2',
@@ -308,7 +308,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
).select(
tab_line.id,
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)
)
lines = Line2.search([('id', 'in', query)])
@@ -344,7 +344,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
for line in lines:
if line.reference:
if Transaction().context.get(
- 'line.allow.wfedit', False) == False:
+ 'line.allow.wfedit', False) is False:
raise UserError(gettext(
'cashbook.msg_line_denywf_by_reference',
recname=line.reference.rec_name,
@@ -375,7 +375,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
# allow cashbook-line at range-limits
if Recon.search_count([
('state', 'in', ['check', 'done']),
- ('cashbook.id', '=', line.cashbook.id),
+ ('cashbook', '=', line.cashbook.id),
('date_from', '<', line.date),
('date_to', '>', line.date)]) > 0:
raise UserError(gettext(
@@ -386,7 +386,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
# reconciliations exist
if Recon.search_count([
('state', 'in', ['check', 'done']),
- ('cashbook.id', '=', line.cashbook.id),
+ ('cashbook', '=', line.cashbook.id),
['OR',
('date_from', '=', line.date),
('date_to', '=', line.date)]]) > 1:
@@ -508,19 +508,20 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
"""
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')
- return '%(date)s|%(type)s|%(amount)s %(symbol)s|%(desc)s [%(category)s]' % {
- 'date': Report.format_date(self.date),
- 'desc': (self.description or '-')[:40],
- 'amount': Report.format_number(
- credit - debit, None,
- digits=getattr(self.currency, 'digits', 2)),
- 'symbol': getattr(self.currency, 'symbol', '-'),
- 'category': self.category_view
- if self.bookingtype in ['in', 'out']
- else getattr(self.booktransf, 'rec_name', '-'),
- 'type': gettext(
- 'cashbook.msg_line_bookingtype_%s' %
- self.bookingtype)}
+ return '|'.join([
+ Report.format_date(self.date),
+ gettext('cashbook.msg_line_bookingtype_%s' % self.bookingtype),
+ '%(amount)s %(symbol)s' % {
+ 'amount': Report.format_number(
+ credit - debit, None,
+ digits=getattr(self.currency, 'digits', 2)),
+ 'symbol': getattr(self.currency, 'symbol', '-')},
+ '%(desc)s [%(category)s]' % {
+ 'desc': (self.description or '-')[:40],
+ 'category': self.category_view
+ if self.bookingtype in ['in', 'out']
+ else getattr(self.booktransf, 'rec_name', '-')},
+ ])
@staticmethod
def order_state(tables):
@@ -535,8 +536,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
(tab_line.state == 'edit', 1),
(tab_line.state.in_(['check', 'recon', 'done']), 0),
else_=2),
- where=tab_line.id == table.id
- )
+ where=tab_line.id == table.id)
return [query]
@staticmethod
@@ -626,7 +626,8 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
if self.bookingtype:
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
if self.bookingtype.startswith('sp'): # split booking
@@ -751,7 +752,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
end_value = None
recons = Reconciliation.search([
- ('cashbook.id', '=', line.cashbook.id),
+ ('cashbook', '=', line.cashbook.id),
('date_to', '<=', line2.date),
('state', '=', 'done'),
], order=[('date_from', 'DESC')], limit=1)
@@ -761,14 +762,14 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
('date', '<=', line2.date),
['OR',
('reconciliation', '=', None),
- ('reconciliation.id', '!=', recons[0])],
+ ('reconciliation', '!=', recons[0])],
])
end_value = getattr(recons[0], 'end_%s' % field_name)
return (query2, end_value)
if line.cashbook:
query = [
- ('cashbook.id', '=', line.cashbook.id),
+ ('cashbook', '=', line.cashbook.id),
]
balance = Decimal('0.0')
@@ -778,7 +779,7 @@ class Line(SecondCurrencyMixin, MemCacheIndexMx, Workflow, ModelSQL, ModelView):
if line.reconciliation:
if line.reconciliation.state == 'done':
query.append(
- ('reconciliation.id', '=', line.reconciliation.id),
+ ('reconciliation', '=', line.reconciliation.id),
)
balance = getattr(
line.reconciliation, 'start_%s' % field_name)
diff --git a/line.xml b/line.xml
index b26fb1a..e618696 100644
--- a/line.xml
+++ b/line.xml
@@ -146,7 +146,7 @@ full copyright notices and license terms. -->
@@ -168,7 +168,7 @@ full copyright notices and license terms. -->
diff --git a/mixin.py b/mixin.py
index 5b4f054..363bed5 100644
--- a/mixin.py
+++ b/mixin.py
@@ -31,20 +31,19 @@ class SecondCurrencyMixin:
states={
'readonly': Or(
STATES['readonly'],
- ~Bool(Eval('currency2nd'))
- ),
+ ~Bool(Eval('currency2nd'))),
'required': Bool(Eval('currency2nd')),
'invisible': ~Bool(Eval('currency2nd')),
}, depends=DEPENDS+['currency2nd_digits', 'currency2nd'])
rate_2nd_currency = fields.Function(fields.Numeric(
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),
states={
'readonly': Or(
STATES['readonly'],
- ~Bool(Eval('currency2nd'))
- ),
+ ~Bool(Eval('currency2nd'))),
'required': Bool(Eval('currency2nd')),
'invisible': ~Bool(Eval('currency2nd')),
}, depends=DEPENDS+['currency2nd_digits', 'currency2nd']),
@@ -124,15 +123,13 @@ class SecondCurrencyMixin:
self.amount_2nd_currency = Currency.compute(
self.currency,
self.amount,
- self.booktransf.currency
- )
+ self.booktransf.currency)
if self.amount != Decimal('0.0'):
self.rate_2nd_currency = \
self.amount_2nd_currency / self.amount
else:
self.amount_2nd_currency = self.booktransf.currency.round(
- self.amount * self.rate_2nd_currency
- )
+ self.amount * self.rate_2nd_currency)
@classmethod
def set_rate_2nd_currency(cls, lines, name, value):
diff --git a/model.py b/model.py
index 0d5598c..e7b4ebc 100644
--- a/model.py
+++ b/model.py
@@ -15,6 +15,8 @@ from sql import With
from sql.functions import Function
from sql.conditionals import Coalesce
import copy
+from .const import DEF_NONE
+
if config.get('cashbook', 'memcache', default='yes').lower() \
in ['yes', '1', 'true']:
@@ -269,7 +271,7 @@ def order_name_hierarchical(model_name, tables):
lines = With('id', 'name', 'name_path', recursive=True)
lines.query = tab_mod.select(
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,
diff --git a/reconciliation.py b/reconciliation.py
index 044f85c..d0d5196 100644
--- a/reconciliation.py
+++ b/reconciliation.py
@@ -183,7 +183,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
if Line.search_count([
('date', '>', reconciliation.date_from),
('date', '<', reconciliation.date_to),
- ('cashbook.id', '=', reconciliation.cashbook.id),
+ ('cashbook', '=', reconciliation.cashbook.id),
('state', 'not in', ['check', 'recon']),
]) > 0:
raise UserError(gettext(
@@ -204,7 +204,8 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
# unlink lines from reconciliation
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
@classmethod
@@ -224,7 +225,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
lines = Line.search([
('date', '>=', reconciliation.date_from),
('date', '<=', reconciliation.date_to),
- ('cashbook.id', '=', reconciliation.cashbook.id),
+ ('cashbook', '=', reconciliation.cashbook.id),
('reconciliation', '=', None),
('state', 'in', ['check', 'recon']),
])
@@ -315,7 +316,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
# deny if there are lines not linked to reconciliation
if Line.search_count([
- ('cashbook.id', '=', reconciliation.cashbook.id),
+ ('cashbook', '=', reconciliation.cashbook.id),
('reconciliation', '=', None),
['OR',
[ # lines inside of date-range
@@ -339,20 +340,24 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
def get_rec_name(self, name):
""" short + name
"""
- return '%(from)s - %(to)s | %(start_amount)s %(symbol)s - %(end_amount)s %(symbol)s [%(num)s]' % {
- 'from': Report.format_date(self.date_from, None)
+ return ' '.join([
+ Report.format_date(self.date_from, None)
if self.date_from is not None else '-',
- 'to': Report.format_date(self.date_to, None)
- if self.date_to is not None else '-',
- 'start_amount': Report.format_number(
+ '-',
+ Report.format_date(self.date_to, None)
+ if self.date_to is not None else '-',
+ '|',
+ Report.format_number(
self.start_amount or 0.0, None,
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,
digits=getattr(self.currency, 'digits', 2)),
- 'symbol': getattr(self.currency, 'symbol', '-'),
- 'num': len(self.lines),
- }
+ getattr(self.currency, 'symbol', '-'),
+ '[%(num)s]' % {'num': len(self.lines)},
+ ])
@classmethod
def default_date_from(cls):
@@ -405,7 +410,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
if self.cashbook:
if self.date_from is not None:
reconciliations = Recon.search([
- ('cashbook.id', '=', self.cashbook.id),
+ ('cashbook', '=', self.cashbook.id),
('date_from', '<', self.date_from),
], order=[('date_from', 'DESC')], limit=1)
if len(reconciliations) > 0:
@@ -457,7 +462,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
# set date_from to date_to of predecessor
recons = Recon.search([
- ('cashbook.id', '=', id_cashbook),
+ ('cashbook', '=', id_cashbook),
], order=[('date_to', 'DESC')], limit=1)
if len(recons) > 0:
values['date_from'] = recons[0].date_to
@@ -466,7 +471,7 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
# set date_to to day of last 'checked'-booking in selected cashbook
lines = Line.search([
- ('cashbook.id', '=', id_cashbook),
+ ('cashbook', '=', id_cashbook),
('state', '=', 'check'),
('reconciliation', '=', None),
], order=[('date', 'DESC')], limit=1)
diff --git a/reconciliation.xml b/reconciliation.xml
index 6e6576d..ca2f603 100644
--- a/reconciliation.xml
+++ b/reconciliation.xml
@@ -97,7 +97,7 @@ full copyright notices and license terms. -->
@@ -119,7 +119,7 @@ full copyright notices and license terms. -->
diff --git a/setup.py b/setup.py
index ff59617..d7a3bc9 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@
"""
# Always prefer setuptools over distutils
-from setuptools import setup, find_packages
+from setuptools import setup
# To use a consistent encoding
from codecs import open
from os import path
@@ -36,11 +36,11 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f:
l2 = i.strip().split(';')
if len(l2) < 4:
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
major_version = 6
-minor_version = 0
+minor_version = 8
requires = ['python-slugify']
for dep in info.get('depends', []):
@@ -51,19 +51,21 @@ for dep in info.get('depends', []):
prefix = modversion[dep]['prefix']
if len(modversion[dep]['max']) > 0:
- requires.append('%s_%s >= %s, <= %s' %
- (prefix, dep, modversion[dep]['min'], modversion[dep]['max']))
- else :
- requires.append('%s_%s >= %s' %
- (prefix, dep, modversion[dep]['min']))
- else :
- requires.append('%s_%s >= %s.%s, < %s.%s' %
- ('trytond', dep, major_version, minor_version,
+ requires.append('%s_%s >= %s, <= %s' % (
+ prefix, dep, modversion[dep]['min'],
+ modversion[dep]['max']))
+ else:
+ requires.append('%s_%s >= %s' % (
+ prefix, dep, modversion[dep]['min']))
+ else:
+ requires.append('%s_%s >= %s.%s, < %s.%s' % (
+ 'trytond', dep, major_version, minor_version,
major_version, minor_version + 1))
-requires.append('trytond >= %s.%s, < %s.%s' %
- (major_version, minor_version, major_version, minor_version + 1))
+requires.append('trytond >= %s.%s, < %s.%s' % (
+ 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'),
description='Tryton module to add a cashbook.',
long_description=long_description,
@@ -74,21 +76,21 @@ setup(name='%s_%s' % (PREFIX, MODULE),
author_email='service@m-ds.de',
license='GPL-3',
classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Plugins',
- 'Framework :: Tryton',
- 'Intended Audience :: Developers',
- 'Intended Audience :: Customer Service',
- 'Intended Audience :: Information Technology',
- 'Intended Audience :: Financial and Insurance Industry',
- 'Topic :: Office/Business',
- 'Topic :: Office/Business :: Financial :: Accounting',
- 'Natural Language :: German',
- 'Natural Language :: English',
- 'Operating System :: OS Independent',
- 'License :: OSI Approved :: GNU General Public License (GPL)',
- 'Programming Language :: Python :: 3.7',
- 'Programming Language :: Python :: 3.8',
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Customer Service',
+ 'Intended Audience :: Information Technology',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Topic :: Office/Business',
+ 'Topic :: Office/Business :: Financial :: Accounting',
+ 'Natural Language :: German',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'License :: OSI Approved :: GNU General Public License (GPL)',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
],
keywords='tryton cashbook',
@@ -97,10 +99,10 @@ setup(name='%s_%s' % (PREFIX, MODULE),
'trytond.modules.%s' % MODULE,
],
package_data={
- 'trytond.modules.%s' % MODULE: (info.get('xml', [])
- + ['tryton.cfg', 'locale/*.po', 'tests/*.py',
- 'view/*.xml', 'icon/*.svg', 'docs/*.txt',
- 'report/*.fods', 'versiondep.txt', 'README.rst']),
+ 'trytond.modules.%s' % MODULE: (info.get('xml', []) + [
+ 'tryton.cfg', 'locale/*.po', 'tests/*.py',
+ 'view/*.xml', 'icon/*.svg', 'docs/*.txt',
+ 'report/*.fods', 'versiondep.txt', 'README.rst']),
},
install_requires=requires,
diff --git a/splitline.py b/splitline.py
index a09bd77..79e78df 100644
--- a/splitline.py
+++ b/splitline.py
@@ -9,7 +9,7 @@ from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.report import Report
from trytond.i18n import gettext
-from .line import sel_bookingtype, STATES, DEPENDS
+from .line import sel_bookingtype, sel_linestate, STATES, DEPENDS
from .book import sel_state_book
from .mixin import SecondCurrencyMixin, MemCacheIndexMx
@@ -90,7 +90,7 @@ class SplitLine(SecondCurrencyMixin, MemCacheIndexMx, ModelSQL, ModelView):
selection=sel_bookingtype), 'on_change_with_bookingtype')
state = fields.Function(fields.Selection(
string='State', readonly=True,
- selection=sel_linetype), 'on_change_with_state')
+ selection=sel_linestate), 'on_change_with_state')
cashbook = fields.Function(fields.Many2One(
string='Cashbook',
readonly=True, states={'invisible': True}, model_name='cashbook.book'),
diff --git a/splitline.xml b/splitline.xml
index d2d3f87..4ab74c0 100644
--- a/splitline.xml
+++ b/splitline.xml
@@ -81,7 +81,7 @@ full copyright notices and license terms. -->
@@ -103,7 +103,7 @@ full copyright notices and license terms. -->
diff --git a/tests/splitline.py b/tests/splitline.py
index 629b7e9..477e23b 100644
--- a/tests/splitline.py
+++ b/tests/splitline.py
@@ -73,6 +73,26 @@ class SplitLineTestCase(object):
book.lines[0].splitlines[1].rec_name,
'Rev/Sp|6.00 usd|from cashbook [Cat1]')
+ # check function fields
+ self.assertEqual(
+ book.lines[0].splitlines[0].category_view,
+ 'Cat1')
+ self.assertEqual(book.lines[0].splitlines[0].date, date(2022, 5, 1))
+ self.assertEqual(book.lines[0].splitlines[0].target.rec_name, 'Cat1')
+ self.assertEqual(book.lines[0].splitlines[0].currency.rec_name, 'usd')
+ self.assertEqual(book.lines[0].splitlines[0].currency_digits, 2)
+ self.assertEqual(book.lines[0].splitlines[0].bookingtype, 'spin')
+ self.assertEqual(book.lines[0].splitlines[0].state, 'edit')
+ self.assertEqual(
+ book.lines[0].splitlines[0].cashbook.rec_name,
+ 'Book 1 | 11.00 usd | Open')
+ self.assertEqual(book.lines[0].splitlines[0].feature, 'gen')
+ self.assertEqual(book.lines[0].splitlines[0].booktransf_feature, None)
+ self.assertEqual(book.lines[0].splitlines[0].state_cashbook, 'open')
+ self.assertEqual(
+ book.lines[0].splitlines[0].owner_cashbook.rec_name,
+ 'Administrator')
+
@with_transaction()
def test_splitline_category_and_transfer(self):
""" add book, line, two split-lines,
diff --git a/tryton.cfg b/tryton.cfg
index ea57ba7..f40298a 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,5 +1,5 @@
[tryton]
-version=6.0.0
+version=6.8.32
depends:
res
currency
diff --git a/types.py b/types.py
index 1217adf..11bcaf5 100644
--- a/types.py
+++ b/types.py
@@ -3,7 +3,7 @@
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
-from trytond.model import ModelView, ModelSQL, fields, Unique
+from trytond.model import ModelView, ModelSQL, fields, Unique, Index
from trytond.transaction import Transaction
from trytond.i18n import gettext
@@ -28,8 +28,15 @@ class Type(ModelSQL, ModelView):
cls._order.insert(0, ('name', 'ASC'))
t = cls.__table__()
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({
+ Index(
+ t,
+ (t.feature, Index.Equality())),
+ })
@classmethod
def default_feature(cls):
@@ -48,8 +55,7 @@ class Type(ModelSQL, ModelView):
"""
return '%(short)s - %(name)s' % {
'short': self.short or '-',
- 'name': self.name or '-',
- }
+ 'name': self.name or '-'}
@classmethod
def search_rec_name(cls, name, clause):
@@ -58,8 +64,7 @@ class Type(ModelSQL, ModelView):
return [
'OR',
('name',) + tuple(clause[1:]),
- ('short',) + tuple(clause[1:]),
- ]
+ ('short',) + tuple(clause[1:])]
@staticmethod
def default_company():
diff --git a/view/book_list.xml b/view/book_list.xml
index 3ac0a86..2f14a6e 100644
--- a/view/book_list.xml
+++ b/view/book_list.xml
@@ -5,5 +5,5 @@ full copyright notices and license terms. -->
-
+
diff --git a/view/book_tree.xml b/view/book_tree.xml
index f3cfcb1..1ba5c32 100644
--- a/view/book_tree.xml
+++ b/view/book_tree.xml
@@ -5,7 +5,7 @@ full copyright notices and license terms. -->
-
+
diff --git a/view/line_list.xml b/view/line_list.xml
index fffc0ac..4ffa594 100644
--- a/view/line_list.xml
+++ b/view/line_list.xml
@@ -4,14 +4,14 @@ The COPYRIGHT file at the top level of this repository contains the
full copyright notices and license terms. -->
-
+
-
-
-
-
+
+
+
+
diff --git a/view/line_recon_list.xml b/view/line_recon_list.xml
index b3fee62..440b312 100644
--- a/view/line_recon_list.xml
+++ b/view/line_recon_list.xml
@@ -4,13 +4,13 @@ The COPYRIGHT file at the top level of this repository contains the
full copyright notices and license terms. -->
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/view/recon_list.xml b/view/recon_list.xml
index 2b1248e..c144bc3 100644
--- a/view/recon_list.xml
+++ b/view/recon_list.xml
@@ -4,11 +4,11 @@ The COPYRIGHT file at the top level of this repository contains the
full copyright notices and license terms. -->
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/view/split_list.xml b/view/split_list.xml
index e8fa10d..553f88b 100644
--- a/view/split_list.xml
+++ b/view/split_list.xml
@@ -8,7 +8,7 @@ full copyright notices and license terms. -->
-
-
-
+
+
+
diff --git a/wizard_booking.py b/wizard_booking.py
index ef27f32..9530a35 100644
--- a/wizard_booking.py
+++ b/wizard_booking.py
@@ -50,7 +50,7 @@ class EnterBookingStart(ModelView):
string='Category',
model_name='cashbook.category', depends=['bookingtype'],
states={
- 'readonly': Bool(Eval('bookingtype')) == False,
+ 'readonly': ~Bool(Eval('bookingtype')),
'required': Eval('bookingtype', '').in_(['in', 'out']),
'invisible': ~Eval('bookingtype', '').in_(['in', 'out']),
},
@@ -90,7 +90,8 @@ class EnterBookingStart(ModelView):
if self.bookingtype:
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
@fields.depends('cashbook', '_parent_cashbook.owner')
@@ -152,7 +153,7 @@ class EnterBookingWizard(Wizard):
'cashbooks': [x.id for x in Cashbook.search([
('state', '=', 'open'),
('btype', '!=', None),
- ('owner.id', '=', Transaction().user),
+ ('owner', '=', Transaction().user),
('id', 'in', book_ids),
])],
'bookingtype': getattr(self.start, 'bookingtype', 'out'),
diff --git a/wizard_runreport.py b/wizard_runreport.py
index 534f521..d2b4fc2 100644
--- a/wizard_runreport.py
+++ b/wizard_runreport.py
@@ -55,7 +55,7 @@ class RunCbReportStart(ModelView):
if self.cashbook:
recons = Recon2.search([
- ('cashbook.id', '=', self.cashbook.id),
+ ('cashbook', '=', self.cashbook.id),
], order=[('date_from', 'DESC')])
return [x.id for x in recons]
@@ -103,7 +103,7 @@ class RunCbReport(Wizard):
result['cashbook'] = result['cashbooks'][0]
recons = Recon2.search([
- ('cashbook.id', '=', result['cashbook']),
+ ('cashbook', '=', result['cashbook']),
], order=[('date_from', 'DESC')])
if len(recons) > 0:
result['reconciliations'] = [x.id for x in recons]