cashbooks, types, currenciews - verknüpfung+löschen+test

This commit is contained in:
Frederik Jaeckel 2022-10-29 23:05:27 +02:00
parent 085228e047
commit 01470569e7
9 changed files with 429 additions and 22 deletions

View file

@ -4,10 +4,13 @@
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.pool import Pool from trytond.pool import Pool
from .evaluation import Evaluation, EvaluationCashbookRel from .evaluation import Evaluation, EvaluationCashbookRel, \
EvaluationTypeRel, EvaluationCurrencyRel
def register(): def register():
Pool.register( Pool.register(
Evaluation, Evaluation,
EvaluationCashbookRel, EvaluationCashbookRel,
EvaluationTypeRel,
EvaluationCurrencyRel,
module='cashbook_report', type_='model') module='cashbook_report', type_='model')

View file

@ -6,13 +6,16 @@
from trytond.model import ModelView, ModelSQL, fields, Check from trytond.model import ModelView, ModelSQL, fields, Check
from trytond.pyson import Eval, Or, Bool, Id, Len from trytond.pyson import Eval, Or, Bool, Id, Len
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.i18n import gettext
from trytond.exceptions import UserError
from .colors import sel_color as sel_bgcolor from .colors import sel_color as sel_bgcolor
sel_etype = [ sel_etype = [
('book', 'Cashbooks'), ('cashbooks', 'Cashbooks'),
('type', 'Types of Cashbooks'), ('types', 'Types of Cashbooks'),
('currency', 'Currencys'), ('currencies', 'Currencys'),
#('category', 'Category'),
] ]
sel_chart = [ sel_chart = [
@ -54,9 +57,28 @@ class Evaluation(ModelSQL, ModelView):
help='Background color of the chart area.', sort=False, help='Background color of the chart area.', sort=False,
selection=sel_bgcolor) selection=sel_bgcolor)
posted = fields.Boolean(string='Posted', help='Posted amounts only.') posted = fields.Boolean(string='Posted', help='Posted amounts only.')
lines = fields.Many2Many(string='Cashbooks',
cashbooks = fields.Many2Many(string='Cashbooks',
relation_name='cashbook_report.eval_book', relation_name='cashbook_report.eval_book',
origin='evaluation', target='cashbook') origin='evaluation', target='cashbook',
states={
'invisible': Eval('dtype', '') != 'cashbooks',
}, depends=['dtype'])
types = fields.Many2Many(string='Types',
relation_name='cashbook_report.eval_type',
origin='evaluation', target='dtype',
states={
'invisible': Eval('dtype', '') != 'types',
}, depends=['dtype'])
currencies = fields.Many2Many(string='Currencies',
relation_name='cashbook_report.eval_currency',
origin='evaluation', target='currency',
states={
'invisible': Eval('dtype', '') != 'currencies',
}, depends=['dtype'])
values = fields.One2Many(string='Values', field='evaluation',
model_name='cashbook_report.eval_book', readonly=True)
@staticmethod @staticmethod
def default_company(): def default_company():
@ -90,7 +112,7 @@ class Evaluation(ModelSQL, ModelView):
def default_dtype(cls): def default_dtype(cls):
""" default 'book' """ default 'book'
""" """
return 'book' return 'cashbooks'
@classmethod @classmethod
def default_chart(cls): def default_chart(cls):
@ -98,6 +120,50 @@ class Evaluation(ModelSQL, ModelView):
""" """
return 'pie' return 'pie'
@classmethod
def write(cls, *args):
""" unlink records if dtype changes
"""
to_write = []
actions = iter(args)
for evaluations, values in zip(actions, actions):
if 'dtype' in values.keys():
for evaluation in evaluations:
if evaluation.dtype == values['dtype']:
continue
if (values['dtype'] != 'cashbooks') and \
(len(evaluation.cashbooks) > 0):
to_write.extend([
[evaluation],
{
'cashbooks': [
('remove', [x.id for x in evaluation.cashbooks])
],
}])
if (values['dtype'] != 'types') and (len(evaluation.types) > 0):
to_write.extend([
[evaluation],
{
'types': [
('remove', [x.id for x in evaluation.types])
],
}])
if (values['dtype'] != 'currencies') and (len(evaluation.currencies) > 0):
to_write.extend([
[evaluation],
{
'currencies': [
('remove', [x.id for x in evaluation.currencies])
],
}])
args = list(args)
args.extend(to_write)
super(Evaluation, cls).write(*args)
# end Evaluation # end Evaluation
@ -112,4 +178,45 @@ class EvaluationCashbookRel(ModelSQL):
select=True, ondelete='CASCADE', select=True, ondelete='CASCADE',
model_name='cashbook.book') model_name='cashbook.book')
@classmethod
def validate(cls, records):
""" check parent record
"""
super(EvaluationCashbookRel, cls).validate(records)
for record in records:
if record.evaluation.dtype != 'cashbooks':
raise UserError(gettext(
'cashbook_report.msg_invalid_dtype',
dtype = gettext('cashbook_report.msg_dtype_cashbook'),
))
# end EvaluationCashbookRel # end EvaluationCashbookRel
class EvaluationTypeRel(ModelSQL):
'Evaluation Type Relation'
__name__ = 'cashbook_report.eval_type'
evaluation = fields.Many2One(string='Evaluation', required=True,
select=True, ondelete='CASCADE',
model_name='cashbook_report.evaluation')
dtype = fields.Many2One(string='Type', required=True,
select=True, ondelete='CASCADE',
model_name='cashbook.type')
# end EvaluationTypeRel
class EvaluationCurrencyRel(ModelSQL):
'Evaluation Currency Relation'
__name__ = 'cashbook_report.eval_currency'
evaluation = fields.Many2One(string='Evaluation', required=True,
select=True, ondelete='CASCADE',
model_name='cashbook_report.evaluation')
currency = fields.Many2One(string='Currency', required=True,
select=True, ondelete='CASCADE',
model_name='currency.currency')
# end EvaluationCurrencyRel

View file

@ -3,6 +3,18 @@ msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n" msgstr "Content-Type: text/plain; charset=utf-8\n"
##############
# ir.message #
##############
msgctxt "model:ir.message,text:msg_name_cashbook"
msgid "Type of evaluation must be '%(dtype)s'."
msgstr "Typ der Auswertung mus '%(dtype)s' sein."
msgctxt "model:ir.message,text:msg_dtype_cashbook"
msgid "Cashbooks"
msgstr "Kassenbücher"
################# #################
# ir.rule.group # # ir.rule.group #
################# #################
@ -43,6 +55,38 @@ msgid "Cashbook"
msgstr "Kassenbuch" msgstr "Kassenbuch"
#############################
# cashbook_report.eval_type #
#############################
msgctxt "model:cashbook_report.eval_type,name:"
msgid "Evaluation Type Relation"
msgstr "Auswertung Typ Verknüpfung"
msgctxt "field:cashbook_report.eval_type,evaluation:"
msgid "Evaluation"
msgstr "Auswertung"
msgctxt "field:cashbook_report.eval_type,dtype:"
msgid "Type"
msgstr "Typ"
#################################
# cashbook_report.eval_currency #
#################################
msgctxt "model:cashbook_report.eval_currency,name:"
msgid "Evaluation Currency Relation"
msgstr "Auswertung Währung Verknüpfung"
msgctxt "field:cashbook_report.eval_currency,evaluation:"
msgid "Evaluation"
msgstr "Auswertung"
msgctxt "field:cashbook_report.eval_currency,currency:"
msgid "Currency"
msgstr "Währung"
############################## ##############################
# cashbook_report.evaluation # # cashbook_report.evaluation #
############################## ##############################
@ -162,6 +206,14 @@ msgctxt "help:cashbook_report.evaluation,posted:"
msgid "Posted amounts only." msgid "Posted amounts only."
msgstr "Nur festgeschriebene Beträge." msgstr "Nur festgeschriebene Beträge."
msgctxt "field:cashbook_report.evaluation,lines:" msgctxt "field:cashbook_report.evaluation,cashbooks:"
msgid "Cashbooks" msgid "Cashbooks"
msgstr "Kassenbücher" msgstr "Kassenbücher"
msgctxt "field:cashbook_report.evaluation,types:"
msgid "Types"
msgstr "Typen"
msgctxt "field:cashbook_report.evaluation,currencies:"
msgid "Currencies"
msgstr "Währungen"

View file

@ -2,6 +2,14 @@
msgid "" msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n" msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "model:ir.message,text:msg_name_cashbook"
msgid "Type of evaluation must be '%(dtype)s'."
msgstr "Type of evaluation must be '%(dtype)s'."
msgctxt "model:ir.message,text:msg_dtype_cashbook"
msgid "Cashbooks"
msgstr "Cashbooks"
msgctxt "model:ir.rule.group,name:rg_eval_write_adm" msgctxt "model:ir.rule.group,name:rg_eval_write_adm"
msgid "Administrators: Evaluation read/write" msgid "Administrators: Evaluation read/write"
msgstr "Administrators: Evaluation read/write" msgstr "Administrators: Evaluation read/write"
@ -18,10 +26,54 @@ msgctxt "model:ir.ui.menu,name:menu_evaluation"
msgid "Evaluation" msgid "Evaluation"
msgstr "Evaluation" msgstr "Evaluation"
msgctxt "model:cashbook_report.eval_book,name:"
msgid "Evaluation Cashbook Relation"
msgstr "Evaluation Cashbook Relation"
msgctxt "field:cashbook_report.eval_book,evaluation:"
msgid "Evaluation"
msgstr "Evaluation"
msgctxt "field:cashbook_report.eval_book,cashbook:"
msgid "Cashbook"
msgstr "Cashbook"
msgctxt "model:cashbook_report.eval_type,name:"
msgid "Evaluation Type Relation"
msgstr "Evaluation Type Relation"
msgctxt "field:cashbook_report.eval_type,evaluation:"
msgid "Evaluation"
msgstr "Evaluation"
msgctxt "field:cashbook_report.eval_type,dtype:"
msgid "Type"
msgstr "Type"
msgctxt "model:cashbook_report.eval_currency,name:"
msgid "Evaluation Currency Relation"
msgstr "Evaluation Currency Relation"
msgctxt "field:cashbook_report.eval_currency,evaluation:"
msgid "Evaluation"
msgstr "Evaluation"
msgctxt "field:cashbook_report.eval_currency,currency:"
msgid "Currency"
msgstr "Currency"
msgctxt "model:cashbook_report.evaluation,name:" msgctxt "model:cashbook_report.evaluation,name:"
msgid "Evaluation" msgid "Evaluation"
msgstr "Evaluation" msgstr "Evaluation"
msgctxt "view:cashbook_report.evaluation:"
msgid "Chart"
msgstr "Chart"
msgctxt "view:cashbook_report.evaluation:"
msgid "Settings"
msgstr "Settings"
msgctxt "view:cashbook_report.evaluation:" msgctxt "view:cashbook_report.evaluation:"
msgid "Representation" msgid "Representation"
msgstr "Representation" msgstr "Representation"
@ -122,3 +174,15 @@ msgctxt "field:cashbook_report.evaluation,posted:"
msgid "Posted" msgid "Posted"
msgstr "Posted" msgstr "Posted"
msgctxt "help:cashbook_report.evaluation,posted:"
msgid "Posted amounts only."
msgstr "Posted amounts only."
msgctxt "field:cashbook_report.evaluation,cashbooks:"
msgid "Cashbooks"
msgstr "Cashbooks"
msgctxt "field:cashbook_report.evaluation,types:"
msgid "Types"
msgstr "Types"

16
message.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!-- 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
full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.message" id="msg_invalid_dtype">
<field name="text">Type of evaluation must be '%(dtype)s'.</field>
</record>
<record model="ir.message" id="msg_dtype_cashbook">
<field name="text">Cashbooks</field>
</record>
</data>
</tryton>

View file

@ -22,16 +22,18 @@ class ReportTestCase(CashbookTestCase):
pool = Pool() pool = Pool()
Book = pool.get('cashbook.book') Book = pool.get('cashbook.book')
types = self.prep_type() type_cash = self.prep_type()
type_bank = self.prep_type(name='Bank', short='BK')
company = self.prep_company() company = self.prep_company()
(usd, euro) = self.prep_2nd_currency(company)
sequ_id = self.prep_sequence().id sequ_id = self.prep_sequence().id
category = self.prep_category(cattype='in') category = self.prep_category(cattype='in')
party = self.prep_party() party = self.prep_party()
books = Book.create([{ books = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
'btype': types.id, 'btype': type_cash.id,
'company': company.id, 'company': company.id,
'currency': company.currency.id, 'currency': usd.id,
'number_sequ': sequ_id, 'number_sequ': sequ_id,
'start_date': date(2022, 4, 1), 'start_date': date(2022, 4, 1),
'lines': [('create', [{ 'lines': [('create', [{
@ -51,9 +53,9 @@ class ReportTestCase(CashbookTestCase):
}])], }])],
}, { }, {
'name': 'Book 2', 'name': 'Book 2',
'btype': types.id, 'btype': type_cash.id,
'company': company.id, 'company': company.id,
'currency': company.currency.id, 'currency': usd.id,
'number_sequ': sequ_id, 'number_sequ': sequ_id,
'start_date': date(2022, 4, 1), 'start_date': date(2022, 4, 1),
'lines': [('create', [{ 'lines': [('create', [{
@ -73,9 +75,9 @@ class ReportTestCase(CashbookTestCase):
}])], }])],
}, { }, {
'name': 'Book 3', 'name': 'Book 3',
'btype': types.id, 'btype': type_bank.id,
'company': company.id, 'company': company.id,
'currency': company.currency.id, 'currency': euro.id,
'number_sequ': sequ_id, 'number_sequ': sequ_id,
'start_date': date(2022, 4, 1), 'start_date': date(2022, 4, 1),
'lines': [('create', [{ 'lines': [('create', [{
@ -96,22 +98,120 @@ class ReportTestCase(CashbookTestCase):
}]) }])
self.assertEqual(len(books), 3) self.assertEqual(len(books), 3)
self.assertEqual(books[0].name, 'Book 1') self.assertEqual(books[0].name, 'Book 1')
self.assertEqual(books[0].btype.rec_name, 'CAS - Cash')
self.assertEqual(len(books[0].lines), 2) self.assertEqual(len(books[0].lines), 2)
self.assertEqual(books[0].balance, Decimal('25.0')) self.assertEqual(books[0].balance, Decimal('25.0'))
self.assertEqual(books[1].name, 'Book 2') self.assertEqual(books[1].name, 'Book 2')
self.assertEqual(books[1].btype.rec_name, 'CAS - Cash')
self.assertEqual(len(books[1].lines), 2) self.assertEqual(len(books[1].lines), 2)
self.assertEqual(books[1].balance, Decimal('12.5')) self.assertEqual(books[1].balance, Decimal('12.5'))
self.assertEqual(books[2].name, 'Book 3') self.assertEqual(books[2].name, 'Book 3')
self.assertEqual(books[2].btype.rec_name, 'BK - Bank')
self.assertEqual(len(books[2].lines), 2) self.assertEqual(len(books[2].lines), 2)
self.assertEqual(books[2].balance, Decimal('23.0')) self.assertEqual(books[2].balance, Decimal('23.0'))
return books return books
@with_transaction()
def test_report_dtype_update(self):
""" check unlink of cashbooks/types/currenciews
"""
pool = Pool()
Evaluation = pool.get('cashbook_report.evaluation')
Types = pool.get('cashbook.type')
Currency = pool.get('currency.currency')
books = self.prep_report_3books()
company = self.prep_company()
with Transaction().set_context({
'company': company.id,
}):
# valid
evaluation, = Evaluation.create([{
'name': 'Evaluation 1',
'dtype': 'cashbooks',
'cashbooks': [('add', [x.id for x in books])],
}])
self.assertEqual(len(evaluation.cashbooks), 3)
self.assertEqual(len(evaluation.types), 0)
self.assertEqual(len(evaluation.currencies), 0)
Evaluation.write(*[
[evaluation],
{
'dtype': 'types',
'types': [('add', [x.id for x in Types.search([])])],
}])
self.assertEqual(len(evaluation.cashbooks), 0)
self.assertEqual(len(evaluation.types), 2)
self.assertEqual(len(evaluation.currencies), 0)
# write same dtype again - no change
Evaluation.write(*[
[evaluation],
{
'dtype': 'types',
}])
self.assertEqual(len(evaluation.cashbooks), 0)
self.assertEqual(len(evaluation.types), 2)
self.assertEqual(len(evaluation.currencies), 0)
Evaluation.write(*[
[evaluation],
{
'dtype': 'currencies',
'currencies': [('add', [x.id for x in Currency.search([])])],
}])
self.assertEqual(len(evaluation.cashbooks), 0)
self.assertEqual(len(evaluation.types), 0)
self.assertEqual(len(evaluation.currencies), 2)
Evaluation.write(*[
[evaluation],
{
'dtype': 'cashbooks',
}])
self.assertEqual(len(evaluation.cashbooks), 0)
self.assertEqual(len(evaluation.types), 0)
self.assertEqual(len(evaluation.currencies), 0)
@with_transaction()
def test_report_dtype_validation(self):
""" check validation of dtype
"""
pool = Pool()
Evaluation = pool.get('cashbook_report.evaluation')
Types = pool.get('cashbook.type')
books = self.prep_report_3books()
company = self.prep_company()
with Transaction().set_context({
'company': company.id,
}):
# valid
evaluation, = Evaluation.create([{
'name': 'Evaluation 1',
'dtype': 'cashbooks',
'cashbooks': [('add', [x.id for x in books])],
}])
# must fail
self.assertRaisesRegex(UserError,
"Type of evaluation must be 'Cashbooks'.",
Evaluation.create,
[{
'name': 'Evaluation 1',
'dtype': 'types', # wrong dtype
'cashbooks': [('add', [x.id for x in books])],
}])
@with_transaction() @with_transaction()
def test_report_chart_pie_book_red(self): def test_report_chart_pie_book_red(self):
""" create 3x cashbooks, add bookings, """ create 3x cashbooks, add bookings,
create report, check create report with cashbooks, check
""" """
Evaluation = Pool().get('cashbook_report.evaluation') Evaluation = Pool().get('cashbook_report.evaluation')
@ -123,14 +223,76 @@ class ReportTestCase(CashbookTestCase):
}): }):
evaluation, = Evaluation.create([{ evaluation, = Evaluation.create([{
'name': 'Evaluation 1', 'name': 'Evaluation 1',
'lines': [('add', [x.id for x in books])], 'cashbooks': [('add', [x.id for x in books])],
}]) }])
self.assertEqual(len(evaluation.lines), 3) self.assertEqual(evaluation.dtype, 'cashbooks')
self.assertEqual(evaluation.dtype, 'book')
self.assertEqual(evaluation.chart, 'pie') self.assertEqual(evaluation.chart, 'pie')
self.assertEqual(evaluation.legend, True) self.assertEqual(evaluation.legend, True)
self.assertEqual(evaluation.posted, False) self.assertEqual(evaluation.posted, False)
self.assertEqual(evaluation.maincolor, 'default') self.assertEqual(evaluation.maincolor, 'default')
self.assertEqual(evaluation.bgcolor, '#ffffc0') self.assertEqual(evaluation.bgcolor, '#ffffc0')
self.assertEqual(len(evaluation.cashbooks), 3)
self.assertEqual(evaluation.cashbooks[0].rec_name, 'Book 1 | 25.00 usd | Open')
self.assertEqual(evaluation.cashbooks[1].rec_name, 'Book 2 | 12.50 usd | Open')
self.assertEqual(evaluation.cashbooks[2].rec_name, 'Book 3 | 23.00 € | Open')
@with_transaction()
def test_report_chart_pie_type_red(self):
""" create 3x cashbooks, add bookings,
create report with types of cashbooks, check
"""
pool = Pool()
Evaluation = pool.get('cashbook_report.evaluation')
Types = pool.get('cashbook.type')
books = self.prep_report_3books()
company = self.prep_company()
with Transaction().set_context({
'company': company.id,
}):
evaluation, = Evaluation.create([{
'name': 'Evaluation 1',
'dtype': 'types',
'types': [('add', [x.id for x in Types.search([])])],
}])
self.assertEqual(evaluation.dtype, 'types')
self.assertEqual(evaluation.chart, 'pie')
self.assertEqual(evaluation.legend, True)
self.assertEqual(evaluation.posted, False)
self.assertEqual(evaluation.maincolor, 'default')
self.assertEqual(evaluation.bgcolor, '#ffffc0')
self.assertEqual(len(evaluation.types), 2)
@with_transaction()
def test_report_chart_pie_currency_red(self):
""" create 3x cashbooks, add bookings,
create report with types of cashbooks, check
"""
pool = Pool()
Evaluation = pool.get('cashbook_report.evaluation')
Currency = pool.get('currency.currency')
books = self.prep_report_3books()
company = self.prep_company()
with Transaction().set_context({
'company': company.id,
}):
evaluation, = Evaluation.create([{
'name': 'Evaluation 1',
'dtype': 'currencies',
'currencies': [('add', [x.id for x in Currency.search([])])],
}])
self.assertEqual(evaluation.dtype, 'currencies')
self.assertEqual(evaluation.chart, 'pie')
self.assertEqual(evaluation.legend, True)
self.assertEqual(evaluation.posted, False)
self.assertEqual(evaluation.maincolor, 'default')
self.assertEqual(evaluation.bgcolor, '#ffffc0')
self.assertEqual(len(evaluation.currencies), 2)
# end ReportTestCase # end ReportTestCase

View file

@ -4,6 +4,7 @@ depends:
cashbook cashbook
xml: xml:
icon.xml icon.xml
message.xml
graph.xml graph.xml
evaluation.xml evaluation.xml
menu.xml menu.xml

View file

@ -5,7 +5,8 @@ full copyright notices and license terms. -->
<form col="1"> <form col="1">
<notebook> <notebook>
<page id="chart" col="1" string="Chart"> <page id="chart" col="1" string="Chart">
<field name="lines" view_ids="cashbook_report.book_view_graph" readonly="1"/> <field name="cashbooks" view_ids="cashbook_report.book_view_graph" readonly="1"/>
<!-- <field name="types" view_ids="cashbook_report.book_view_graph" readonly="1"/> -->
</page> </page>
<page id="config" col="6" string="Settings"> <page id="config" col="6" string="Settings">
<label name="name"/> <label name="name"/>
@ -22,7 +23,9 @@ full copyright notices and license terms. -->
<label name="legend"/> <label name="legend"/>
<field name="legend"/> <field name="legend"/>
<field name="lines" colspan="6"/> <field name="cashbooks" colspan="6"/>
<field name="types" colspan="6"/>
<field name="currencies" colspan="6"/>
</page> </page>
</notebook> </notebook>
</form> </form>

View file

@ -8,5 +8,4 @@ full copyright notices and license terms. -->
<field name="chart"/> <field name="chart"/>
<field name="legend"/> <field name="legend"/>
<field name="maincolor"/> <field name="maincolor"/>
<field name="lines"/>
</tree> </tree>