diff --git a/__init__.py b/__init__.py index 7472555..b5a9987 100644 --- a/__init__.py +++ b/__init__.py @@ -5,8 +5,18 @@ from trytond.pool import Pool from .book import Book +from .account_type import AccountType +from .line import Line, LineContext +from .wizard_openline import OpenCashBook, OpenCashBookStart def register(): Pool.register( + AccountType, Book, + LineContext, + Line, + OpenCashBookStart, module='cashbook', type_='model') + Pool.register( + OpenCashBook, + module='cashbook', type_='wizard') diff --git a/account_type.py b/account_type.py new file mode 100644 index 0000000..f223290 --- /dev/null +++ b/account_type.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +# 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. + +from trytond.model import ModelView, ModelSQL, fields, Unique + + +class AccountType(ModelSQL, ModelView): + 'Account Type' + __name__ = 'cashbook.type' + + name = fields.Char(string='Name', required=True, translate=True) + short = fields.Char(string='Abbreviation', required=True, size=3) + + @classmethod + def __setup__(cls): + super(AccountType, cls).__setup__() + cls._order.insert(0, ('name', 'ASC')) + t = cls.__table__() + cls._sql_constraints = [ + ('code_uniq', Unique(t, t.short), 'cashbook.msg_type_short_unique'), + ] + + def get_rec_name(self, name): + """ short + name + """ + return '%(short)s - %(name)s' % { + 'short': self.short or '-', + 'name': self.name or '-', + } + + @classmethod + def search_rec_name(cls, name, clause): + """ search in tracker + ticket-name + """ + return ['OR', + ('name',) + tuple(clause[1:]), + ('short',) + tuple(clause[1:]), + ] + +# end AccountType diff --git a/account_type.xml b/account_type.xml new file mode 100644 index 0000000..f4fd619 --- /dev/null +++ b/account_type.xml @@ -0,0 +1,81 @@ + + + + + + + + cashbook.type + tree + + accounttype_list + + + cashbook.type + form + + accounttype_form + + + + + Account Type + cashbook.type + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CAS + Cash + + + GIR + Giro + + + FTD + Fixed-term deposit + + + + diff --git a/book.py b/book.py index 8b16927..60a635c 100644 --- a/book.py +++ b/book.py @@ -11,6 +11,10 @@ class Book(ModelSQL, ModelView): __name__ = 'cashbook.book' name = fields.Char(string='Name', required=True) + btype = fields.Many2One(string='Account Type', required=True, + model_name='cashbook.type', ondelete='RESTRICT') + lines = fields.One2Many(string='Lines', field='account', + model_name='cashbook.line') @classmethod def __setup__(cls): diff --git a/group.xml b/group.xml index e9e1f5c..78ca2d3 100644 --- a/group.xml +++ b/group.xml @@ -8,6 +8,12 @@ full copyright notices and license terms. --> Cashbook + + Cashbook - WF - Check + + + Cashbook - WF - Done + diff --git a/line.py b/line.py new file mode 100644 index 0000000..2a26727 --- /dev/null +++ b/line.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +# 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. + +from trytond.model import ModelView, ModelSQL, Workflow, fields +from trytond.pool import Pool +from trytond.pyson import Eval, If +from trytond.transaction import Transaction + +sel_linetype = [ + ('edit', 'Edit'), + ('check', 'Checked'), + ('done', 'Done'), + ] + + +STATES = { + 'readonly': Eval('state', '') != 'edit', + } +DEPENDS=['state'] + + +class LineContext(ModelView): + 'Line Context' + __name__ = 'cashbook.line.context' + + account = fields.Many2One(string='Account', required=True, + model_name='cashbook.book', + states={ + 'readonly': Eval('num_account', 0) < 2, + }, depends=['num_account']) + date_from = fields.Date(string='Start Date', depends=['date_to'], + 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 = fields.Boolean(string='Checked', + help='Show account lines in Checked-state.') + done = fields.Boolean(string='Done', + help='Show account lines in Done-state.') + num_account = fields.Function(fields.Integer(string='Number of Accounts', + readonly=True, states={'invisible': True}), + 'on_change_with_num_account') + + @classmethod + def default_account(cls): + """ get default from context + """ + context = Transaction().context + return context.get('account', None) + + @classmethod + def default_date_from(cls): + """ get default from context + """ + context = Transaction().context + return context.get('date_from', None) + + @classmethod + def default_date_to(cls): + """ get default from context + """ + context = Transaction().context + return context.get('date_to', None) + + @classmethod + def default_checked(cls): + """ get default from context + """ + context = Transaction().context + return context.get('checked', False) + + @classmethod + def default_done(cls): + """ get default from context + """ + context = Transaction().context + return context.get('done', False) + + def on_change_with_num_account(self, name=None): + """ get number of accessible accounts, + depends on user-permissions + """ + CashBook = Pool().get('cashbook.book') + return CashBook.search_count([]) + +# end LineContext + + +class Line(Workflow, ModelSQL, ModelView): + 'Account Line' + __name__ = 'cashbook.line' + + account = fields.Many2One(string='Account', required=True, select=True, + model_name='cashbook.book', ondelete='CASCADE', readonly=True) + date = fields.Date(string='Date', required=True, select=True, + states=STATES, depends=DEPENDS) + description = fields.Char(string='Description', + states=STATES, depends=DEPENDS) + state = fields.Selection(string='State', required=True, readonly=True, + select=True, selection=sel_linetype) + + @classmethod + def __setup__(cls): + super(Line, cls).__setup__() + cls._order.insert(0, ('date', 'ASC')) + cls._transitions |= set(( + ('edit', 'check'), + ('check', 'done'), + ('check', 'edit'), + )) + cls._buttons.update({ + 'wfedit': { + 'invisible': Eval('state', '') != 'check', + 'depends': ['state'], + }, + 'wfcheck': { + 'invisible': Eval('state') != 'edit', + 'depends': ['state'], + }, + 'wfdone': { + 'invisible': Eval('state') != 'check', + 'depends': ['state'], + }, + }) + + @classmethod + @ModelView.button + @Workflow.transition('edit') + def wfedit(cls, lines): + """ edit line + """ + pass + + @classmethod + @ModelView.button + @Workflow.transition('check') + def wfcheck(cls, lines): + """ line is checked + """ + pass + + @classmethod + @ModelView.button + @Workflow.transition('done') + def wfdone(cls, lines): + """ line is done + """ + pass + + @classmethod + def default_state(cls): + """ default: edit + """ + return 'edit' + + @classmethod + def default_date(cls): + """ default: today + """ + IrDate = Pool().get('ir.date') + return IrDate.today() + + @classmethod + def default_account(cls): + """ get default from context + """ + context = Transaction().context + return context.get('account', None) + +# end Line diff --git a/line.xml b/line.xml new file mode 100644 index 0000000..123d782 --- /dev/null +++ b/line.xml @@ -0,0 +1,147 @@ + + + + + + + cashbook.line.context + form + cashbook_line_context_form + + + + + cashbook.line + tree + + line_list + + + cashbook.line + form + + line_form + + + + + Account Line + cashbook.line + cashbook.line.context + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + wfedit + Edit + + + + + + + + + + + + + + + + + + wfcheck + Check + + + + + + + + + + + + + + + + + + wfdone + Done + + + + + + + + + + + + + diff --git a/locale/de.po b/locale/de.po index 7fffda3..2bcdfb0 100644 --- a/locale/de.po +++ b/locale/de.po @@ -3,6 +3,18 @@ msgid "" msgstr "Content-Type: text/plain; charset=utf-8\n" +############## +# ir.message # +############## +msgctxt "model:ir.message,text:msg_type_short_unique" +msgid "The Abbreviation must be unique." +msgstr "Das Kürzel muß eindeutig sein." + +msgctxt "model:ir.message,text:msg_name_cashbook" +msgid "Cashbook" +msgstr "Kassenbuch" + + ############# # res.group # ############# @@ -10,6 +22,14 @@ msgctxt "model:res.group,name:group_cashbook" msgid "Cashbook" msgstr "Kassenbuch" +msgctxt "model:res.group,name:group_cashbook_checkline" +msgid "Cashbook - WF - Check" +msgstr "Kassenbuch - WF - Prüfen" + +msgctxt "model:res.group,name:group_cashbook_doneline" +msgid "Cashbook - WF - Done" +msgstr "Kassenbuch - WF - Fertig" + ############## # ir.ui.menu # @@ -18,10 +38,22 @@ msgctxt "model:ir.ui.menu,name:menu_cashbook" msgid "Cashbook" msgstr "Kassenbuch" +msgctxt "model:ir.ui.menu,name:menu_config" +msgid "Configuration" +msgstr "Konfiguration" + +msgctxt "model:ir.ui.menu,name:menu_accounttype" +msgid "Account Type" +msgstr "Kontotyp" + msgctxt "model:ir.ui.menu,name:menu_account" msgid "Account" msgstr "Konto" +msgctxt "model:ir.ui.menu,name:menu_open_accountlines" +msgid "Open Cashbook" +msgstr "Kassenbuch öffnen" + ############# # ir.action # @@ -30,6 +62,38 @@ msgctxt "model:ir.action,name:act_book_view" msgid "Account" msgstr "Konto" +msgctxt "model:ir.action,name:act_accounttype_view" +msgid "Account Type" +msgstr "Kontotyp" + +msgctxt "model:ir.action,name:act_line_view" +msgid "Account Line" +msgstr "Kontozeile" + +msgctxt "model:ir.action,name:act_line_view" +msgid "Account Line" +msgstr "Kontozeile" + +msgctxt "model:ir.action,name:act_open_chart" +msgid "Open Cashbook" +msgstr "Kassenbuch öffnen" + + +################### +# ir.model.button # +################### +msgctxt "model:ir.model.button,string:line_wfedit_button" +msgid "Edit" +msgstr "Bearbeiten" + +msgctxt "model:ir.model.button,string:line_wfcheck_button" +msgid "Check" +msgstr "Prüfen" + +msgctxt "model:ir.model.button,string:line_wfdone_button" +msgid "Done" +msgstr "Fertig" + ################# # cashbook.book # @@ -41,3 +105,172 @@ msgstr "Konto" msgctxt "field:cashbook.book,name:" msgid "Name" msgstr "Name" + +msgctxt "field:cashbook.book,btype:" +msgid "Account Type" +msgstr "Kontotyp" + + +################# +# cashbook.line # +################# +msgctxt "model:cashbook.line,name:" +msgid "Account Line" +msgstr "Kontozeile" + +msgctxt "field:cashbook.line,account:" +msgid "Account" +msgstr "Konto" + +msgctxt "field:cashbook.line,date:" +msgid "Date" +msgstr "Datum" + +msgctxt "field:cashbook.line,description:" +msgid "Description" +msgstr "Beschreibung" + +msgctxt "field:cashbook.line,state:" +msgid "State" +msgstr "Status" + +msgctxt "selection:cashbook.line,state:" +msgid "Edit" +msgstr "Bearbeiten" + +msgctxt "selection:cashbook.line,state:" +msgid "Checked" +msgstr "Geprüft" + +msgctxt "selection:cashbook.line,state:" +msgid "Done" +msgstr "Fertig" + + +################# +# cashbook.type # +################# +msgctxt "model:cashbook.type,name:" +msgid "Account Type" +msgstr "Kontotyp" + +msgctxt "field:cashbook.type,name:" +msgid "Name" +msgstr "Name" + +msgctxt "field:cashbook.type,short:" +msgid "Abbreviation" +msgstr "Kürzel" + +msgctxt "model:cashbook.type,name:atype_cash" +msgid "Cash" +msgstr "Bar" + +msgctxt "model:cashbook.type,short:atype_cash" +msgid "CAS" +msgstr "CAS" + +msgctxt "model:cashbook.type,name:atype_giro" +msgid "Giro" +msgstr "Giro" + +msgctxt "model:cashbook.type,short:atype_giro" +msgid "GIR" +msgstr "GIR" + +msgctxt "model:cashbook.type,name:atype_fixtermdep" +msgid "Fixed-term deposit" +msgstr "Festgeld" + +msgctxt "model:cashbook.type,short:atype_fixtermdep" +msgid "FIX" +msgstr "FIX" + + + +#################################### +# cashbook.open_accountlines.start # +#################################### +msgctxt "model:cashbook.open_accountlines.start,name:" +msgid "Open Cashbook" +msgstr "Kassenbuch öffnen" + +msgctxt "field:cashbook.open_accountlines.start,account:" +msgid "Account" +msgstr "Konto" + +msgctxt "field:cashbook.open_accountlines.start,checked:" +msgid "Checked" +msgstr "Geprüft" + +msgctxt "help:cashbook.open_accountlines.start,checked:" +msgid "Show account lines in Checked-state." +msgstr "Zeigt Kontozeilen im 'Geprüft'-Status" + +msgctxt "field:cashbook.open_accountlines.start,done:" +msgid "Done" +msgstr "Fertig" + +msgctxt "help:cashbook.open_accountlines.start,done:" +msgid "Show account lines in Done-state." +msgstr "Zeigt Kontozeilen im 'Fertig'-Status" + +msgctxt "field:cashbook.open_accountlines.start,date_from:" +msgid "Start Date" +msgstr "Beginndatum" + +msgctxt "field:cashbook.open_accountlines.start,date_to:" +msgid "End Date" +msgstr "Endedatum" + + +############################## +# cashbook.open_accountlines # +############################## +msgctxt "model:cashbook.open_accountlines,name:" +msgid "Open Cashbook" +msgstr "Kassenbuch öffnen" + +msgctxt "wizard_button:cashbook.open_accountlines,start,end:" +msgid "Cancel" +msgstr "Abbruch" + +msgctxt "wizard_button:cashbook.open_accountlines,start,open_:" +msgid "Open" +msgstr "Öffnen" + + +######################### +# cashbook.line.context # +######################### +msgctxt "model:cashbook.line.context,name:" +msgid "Line Context" +msgstr "Zeilenkontext" + +msgctxt "field:cashbook.line.context,account:" +msgid "Account" +msgstr "Konto" + +msgctxt "field:cashbook.line.context,checked:" +msgid "Checked" +msgstr "Geprüft" + +msgctxt "help:cashbook.line.context,checked:" +msgid "Show account lines in Checked-state." +msgstr "Zeigt Kontozeilen im 'Geprüft'-Status" + +msgctxt "field:cashbook.line.context,done:" +msgid "Done" +msgstr "Fertig" + +msgctxt "help:cashbook.line.context,done:" +msgid "Show account lines in Done-state." +msgstr "Zeigt Kontozeilen im 'Fertig'-Status" + +msgctxt "field:cashbook.line.context,date_from:" +msgid "Start Date" +msgstr "Beginndatum" + +msgctxt "field:cashbook.line.context,date_to:" +msgid "End Date" +msgstr "Endedatum" diff --git a/menu.xml b/menu.xml index 9a7ae3e..035b51f 100644 --- a/menu.xml +++ b/menu.xml @@ -6,8 +6,8 @@ full copyright notices and license terms. --> - - + @@ -17,18 +17,37 @@ full copyright notices and license terms. --> - - + + + + + + + + - - - + + + + + + + + + diff --git a/message.xml b/message.xml index 25498c4..869f933 100644 --- a/message.xml +++ b/message.xml @@ -5,6 +5,12 @@ full copyright notices and license terms. --> + + The Abbreviation must be unique. + + + Cashbook + diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..bc6f09c --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,24 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + +import trytond.tests.test_tryton +import unittest + +from trytond.modules.cashbook.tests.test_accounttype import AccounttypeTestCase + + +__all__ = ['suite'] + + +class CashbookTestCase(\ + AccounttypeTestCase, + ): + 'Test cashbook module' + module = 'cashbook' + +# end CashbookTestCase + +def suite(): + suite = trytond.tests.test_tryton.suite() + suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CashbookTestCase)) + return suite diff --git a/tests/test_accounttype.py b/tests/test_accounttype.py new file mode 100644 index 0000000..97afc93 --- /dev/null +++ b/tests/test_accounttype.py @@ -0,0 +1,37 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + +import os, requests +from trytond.tests.test_tryton import ModuleTestCase, with_transaction +from trytond.pool import Pool +from trytond.transaction import Transaction +from trytond.exceptions import UserError + + +class AccounttypeTestCase(ModuleTestCase): + 'Test account type module' + module = 'cashbook' + + @with_transaction() + def test_accounttype_create(self): + """ create account type + """ + AccType = Pool().get('cashbook.type') + + at, = AccType.create([{ + 'name': 'Test 1', + 'short': 'T1', + }]) + self.assertEqual(at.name, 'Test 1') + self.assertEqual(at.short, 'T1') + + # check unique of short + self.assertRaisesRegex(UserError, + 'The Abbreviation must be unique.', + AccType.create, + [{ + 'name': 'Test 2', + 'short': 'T1', + }]) + +# end AccounttypeTestCase diff --git a/tryton.cfg b/tryton.cfg index 8714c4a..12740e0 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -5,5 +5,9 @@ depends: xml: icon.xml group.xml + message.xml + account_type.xml book.xml + line.xml + wizard_openline.xml menu.xml diff --git a/view/accounttype_form.xml b/view/accounttype_form.xml new file mode 100644 index 0000000..bc002d7 --- /dev/null +++ b/view/accounttype_form.xml @@ -0,0 +1,10 @@ + + +
+