neu: kategorie, config + test
This commit is contained in:
parent
b9bb433c39
commit
d6a8b254a3
28 changed files with 1255 additions and 35 deletions
|
@ -8,10 +8,15 @@ from .book import Book
|
|||
from .types import Type
|
||||
from .line import Line, LineContext
|
||||
from .wizard_openline import OpenCashBook, OpenCashBookStart
|
||||
from .configuration import Configuration, UserConfiguration
|
||||
from .category import Category
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
Configuration,
|
||||
UserConfiguration,
|
||||
Type,
|
||||
Category,
|
||||
Book,
|
||||
LineContext,
|
||||
Line,
|
||||
|
|
3
book.py
3
book.py
|
@ -42,6 +42,9 @@ class Book(Workflow, ModelSQL, ModelView):
|
|||
lines = fields.One2Many(string='Lines', field='cashbook',
|
||||
model_name='cashbook.line',
|
||||
states=STATES, depends=DEPENDS)
|
||||
account = fields.Many2One(string='Account', select=True,
|
||||
model_name='account.account', ondelete='RESTRICT',
|
||||
states=STATES, depends=DEPENDS)
|
||||
state = fields.Selection(string='State', required=True,
|
||||
readonly=True, selection=sel_state_book)
|
||||
state_string = state.translated('state')
|
||||
|
|
85
category.py
Normal file
85
category.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
# -*- 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, tree
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class Category(tree(separator='/'), ModelSQL, ModelView):
|
||||
'Category'
|
||||
__name__ = 'cashbook.category'
|
||||
|
||||
name = fields.Char(string='Name', required=True, translate=True)
|
||||
description = fields.Char(string='Description', translate=True)
|
||||
account = fields.Many2One(string='Account', select=True,
|
||||
model_name='account.account', ondelete='RESTRICT')
|
||||
account_code = fields.Function(fields.Char(string='Account', readonly=True),
|
||||
'on_change_with_account_code', searcher='search_account_code')
|
||||
|
||||
company = fields.Many2One(string='Company', model_name='company.company',
|
||||
required=True, ondelete="RESTRICT")
|
||||
parent = fields.Many2One(string="Parent",
|
||||
model_name='cashbook.category', ondelete='RESTRICT',
|
||||
left='left', right='right')
|
||||
childs = fields.One2Many(string='Children', field='parent',
|
||||
model_name='cashbook.category')
|
||||
left = fields.Integer(string='Left', required=True, select=True)
|
||||
right = fields.Integer(string='Right', required=True, select=True)
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Category, cls).__setup__()
|
||||
cls._order.insert(0, ('name', 'ASC'))
|
||||
t = cls.__table__()
|
||||
cls._sql_constraints.extend([
|
||||
('name_uniq', Unique(t, t.name, t.company, t.parent), 'cashbook.msg_category_name_unique'),
|
||||
('account_uniq', Unique(t, t.account, t.company), 'cashbook.msg_category_account_unique'),
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company') or None
|
||||
|
||||
@staticmethod
|
||||
def default_left():
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def default_right():
|
||||
return 0
|
||||
|
||||
def get_rec_name(self, name):
|
||||
""" short + name
|
||||
"""
|
||||
l1 = []
|
||||
if self.account:
|
||||
if self.account.code:
|
||||
l1.append(self.account.code)
|
||||
l1.append(super(Category, self).get_rec_name(name))
|
||||
return ' '.join(l1)
|
||||
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
""" search in account + name
|
||||
"""
|
||||
return ['OR',
|
||||
super(Category, cls).search_rec_name(name, clause),
|
||||
('account.rec_name',) + tuple(clause[1:]),
|
||||
]
|
||||
|
||||
@fields.depends('account')
|
||||
def on_change_with_account_code(self, name=None):
|
||||
""" get code of account
|
||||
"""
|
||||
if self.account:
|
||||
return self.account.code
|
||||
|
||||
@classmethod
|
||||
def search_account_code(cls, names, clause):
|
||||
""" search in code
|
||||
"""
|
||||
return [('account.code',) + tuple(clause[1:])]
|
||||
|
||||
# end Category
|
91
category.xml
Normal file
91
category.xml
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?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>
|
||||
|
||||
<!-- views -->
|
||||
<record model="ir.ui.view" id="category_view_list">
|
||||
<field name="model">cashbook.category</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">category_list</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="category_view_tree">
|
||||
<field name="model">cashbook.category</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="field_childs">childs</field>
|
||||
<field name="name">category_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="category_view_form">
|
||||
<field name="model">cashbook.category</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="name">category_form</field>
|
||||
</record>
|
||||
|
||||
<!-- action view - list -->
|
||||
<record model="ir.action.act_window" id="act_category_list">
|
||||
<field name="name">Category</field>
|
||||
<field name="res_model">cashbook.category</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_category_list-1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="category_view_list"/>
|
||||
<field name="act_window" ref="act_category_list"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_category_list-2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="category_view_form"/>
|
||||
<field name="act_window" ref="act_category_list"/>
|
||||
</record>
|
||||
|
||||
<!-- action view - tree -->
|
||||
<record model="ir.action.act_window" id="act_category_tree">
|
||||
<field name="name">Category</field>
|
||||
<field name="res_model">cashbook.category</field>
|
||||
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_category_tree-1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="category_view_tree"/>
|
||||
<field name="act_window" ref="act_category_tree"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_category_tree-2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="category_view_form"/>
|
||||
<field name="act_window" ref="act_category_tree"/>
|
||||
</record>
|
||||
|
||||
<!-- permission -->
|
||||
<!-- anon: deny all -->
|
||||
<record model="ir.model.access" id="access_category-anon">
|
||||
<field name="model" search="[('model', '=', 'cashbook.category')]"/>
|
||||
<field name="perm_read" eval="False"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_delete" eval="False"/>
|
||||
</record>
|
||||
<!-- admin: read/write -->
|
||||
<record model="ir.model.access" id="access_category-group_admin">
|
||||
<field name="model" search="[('model', '=', 'cashbook.category')]"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_delete" eval="True"/>
|
||||
</record>
|
||||
<!-- cashbook: read -->
|
||||
<record model="ir.model.access" id="access_category-group_cashbook">
|
||||
<field name="model" search="[('model', '=', 'cashbook.category')]"/>
|
||||
<field name="group" ref="group_cashbook"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_delete" eval="False"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
79
configuration.py
Normal file
79
configuration.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
# -*- 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 ModelSingleton, ModelView, ModelSQL, Workflow, fields, Check
|
||||
from .model import UserMultiValueMixin, UserValueMixin
|
||||
from trytond.pyson import Eval, If
|
||||
from trytond.pool import Pool
|
||||
|
||||
|
||||
class Configuration(ModelSingleton, ModelSQL, ModelView, UserMultiValueMixin):
|
||||
'Configuration'
|
||||
__name__ = 'cashbook.configuration'
|
||||
|
||||
date_from = fields.MultiValue(fields.Date(string='Start Date', depends=['date_to'],
|
||||
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(fields.Boolean(string='Checked'))
|
||||
done = fields.MultiValue(fields.Boolean(string='Done'))
|
||||
|
||||
@classmethod
|
||||
def multivalue_model(cls, field):
|
||||
""" get model for value
|
||||
"""
|
||||
pool = Pool()
|
||||
|
||||
if field in ['date_from', 'date_to', 'checked', 'done']:
|
||||
return pool.get('cashbook.configuration_user')
|
||||
return super(Configuration, cls).multivalue_model(field)
|
||||
|
||||
@classmethod
|
||||
def default_checked(cls, **pattern):
|
||||
return cls.multivalue_model('checked').default_checked()
|
||||
|
||||
@classmethod
|
||||
def default_done(cls, **pattern):
|
||||
return cls.multivalue_model('done').default_done()
|
||||
|
||||
# end Configuration
|
||||
|
||||
|
||||
class UserConfiguration(ModelSQL, UserValueMixin):
|
||||
'User Configuration'
|
||||
__name__ = 'cashbook.configuration_user'
|
||||
|
||||
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')
|
||||
done = fields.Boolean(string='Done')
|
||||
|
||||
@classmethod
|
||||
def default_checked(cls):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def default_done(cls):
|
||||
return False
|
||||
|
||||
# end UserConfiguration
|
24
configuration.xml
Normal file
24
configuration.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?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.ui.view" id="configuration_view_form">
|
||||
<field name="model">cashbook.configuration</field>
|
||||
<field name="type">form</field>
|
||||
<field name="name">configuration_form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_configuration_form">
|
||||
<field name="name">Configuration</field>
|
||||
<field name="res_model">cashbook.configuration</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_configuration_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="configuration_view_form"/>
|
||||
<field name="act_window" ref="act_configuration_form"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
19
line.py
19
line.py
|
@ -12,13 +12,13 @@ from trytond.exceptions import UserError
|
|||
from trytond.i18n import gettext
|
||||
from .book import sel_state_book
|
||||
|
||||
|
||||
sel_linetype = [
|
||||
('edit', 'Edit'),
|
||||
('check', 'Checked'),
|
||||
('done', 'Done'),
|
||||
]
|
||||
|
||||
|
||||
STATES = {
|
||||
'readonly': Or(
|
||||
Eval('state', '') != 'edit',
|
||||
|
@ -85,6 +85,17 @@ class LineContext(ModelView):
|
|||
context = Transaction().context
|
||||
return context.get('checked', False)
|
||||
|
||||
@classmethod
|
||||
def default_num_cashbook(cls):
|
||||
""" get default from context
|
||||
"""
|
||||
CashBook = Pool().get('cashbook.book')
|
||||
|
||||
with Transaction().set_context({
|
||||
'_check_access': True,
|
||||
}):
|
||||
return CashBook.search_count([])
|
||||
|
||||
@classmethod
|
||||
def default_done(cls):
|
||||
""" get default from context
|
||||
|
@ -96,8 +107,8 @@ class LineContext(ModelView):
|
|||
""" get number of accessible cashbooks,
|
||||
depends on user-permissions
|
||||
"""
|
||||
CashBook = Pool().get('cashbook.book')
|
||||
return CashBook.search_count([])
|
||||
LineContext = Pool().get('cashbook.line.context')
|
||||
return LineContext.default_num_cashbook()
|
||||
|
||||
# end LineContext
|
||||
|
||||
|
@ -119,6 +130,8 @@ class Line(Workflow, ModelSQL, ModelView):
|
|||
readonly=True, states={'invisible': True}, selection=sel_state_book),
|
||||
'on_change_with_state_cashbook', searcher='search_state_cashbook')
|
||||
|
||||
#image = fields.Binary...
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Line, cls).__setup__()
|
||||
|
|
133
locale/de.po
133
locale/de.po
|
@ -38,6 +38,13 @@ msgctxt "model:ir.message,text:msg_line_deny_delete2"
|
|||
msgid "The cashbook line '%(linetxt)s' cannot be deleted, its in state '%(linestate)s'."
|
||||
msgstr "Die Kassenbuchzeile '%(linetxt)s' kann nicht gelöscht werden, da sie im Status '%(linestate)s' ist."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_setting_already_exists"
|
||||
msgid "Settings for this user alredy exists."
|
||||
msgstr "Einstellungen für diesen Benutzer sind bereits vorhanden."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_category_name_unique"
|
||||
msgid "The category name already exists at this level."
|
||||
msgstr "Der Kategoriename existiert auf dieser Ebene bereits."
|
||||
|
||||
|
||||
#############
|
||||
|
@ -103,6 +110,14 @@ msgctxt "model:ir.ui.menu,name:menu_open_lines"
|
|||
msgid "Open Cashbook"
|
||||
msgstr "Kassenbuch öffnen"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_category"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_category_list"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
|
||||
#############
|
||||
# ir.action #
|
||||
|
@ -119,10 +134,14 @@ msgctxt "model:ir.action,name:act_line_view"
|
|||
msgid "Cashbook Line"
|
||||
msgstr "Kassenbuchzeile"
|
||||
|
||||
msgctxt "model:ir.action,name:act_open_chart"
|
||||
msgctxt "model:ir.action,name:act_open_lines"
|
||||
msgid "Open Cashbook"
|
||||
msgstr "Kassenbuch öffnen"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:act_category_view"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
|
||||
###################
|
||||
# ir.model.button #
|
||||
|
@ -207,6 +226,10 @@ msgctxt "help:cashbook.book,observer:"
|
|||
msgid "Group of users who have read-only access to the cashbook."
|
||||
msgstr "Gruppe von Benutzern, die nur Lesezugriff auf das Kassenbuch haben."
|
||||
|
||||
msgctxt "field:cashbook.book,account:"
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
|
||||
|
||||
#################
|
||||
# cashbook.line #
|
||||
|
@ -280,6 +303,58 @@ msgid "Fixed-term deposit"
|
|||
msgstr "Festgeld"
|
||||
|
||||
|
||||
#####################
|
||||
# cashbook.category #
|
||||
#####################
|
||||
msgctxt "model:cashbook.category,name:"
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
msgctxt "view:cashbook.category:"
|
||||
msgid "General Information"
|
||||
msgstr "Allgemeine Informationen"
|
||||
|
||||
msgctxt "view:cashbook.category:"
|
||||
msgid "Children"
|
||||
msgstr "Untergeordnet"
|
||||
|
||||
msgctxt "field:cashbook.category,name:"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
msgctxt "field:cashbook.category,description:"
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
msgctxt "field:cashbook.category,account:"
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
|
||||
msgctxt "field:cashbook.category,account_code:"
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
|
||||
msgctxt "field:cashbook.category,company:"
|
||||
msgid "Company"
|
||||
msgstr "Unternehmen"
|
||||
|
||||
msgctxt "field:cashbook.category,parent:"
|
||||
msgid "Parent"
|
||||
msgstr "Übergeordnet"
|
||||
|
||||
msgctxt "field:cashbook.category,childs:"
|
||||
msgid "Children"
|
||||
msgstr "Untergeordnet"
|
||||
|
||||
msgctxt "field:cashbook.category,left:"
|
||||
msgid "Left"
|
||||
msgstr "Links"
|
||||
|
||||
msgctxt "field:cashbook.category,right:"
|
||||
msgid "Right"
|
||||
msgstr "Rechts"
|
||||
|
||||
|
||||
#############################
|
||||
# cashbook.open_lines.start #
|
||||
#############################
|
||||
|
@ -315,6 +390,10 @@ msgctxt "field:cashbook.open_lines.start,date_to:"
|
|||
msgid "End Date"
|
||||
msgstr "Endedatum"
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,num_books:"
|
||||
msgid "Number of Cashbooks"
|
||||
msgstr "Anzahl Kassenbücher"
|
||||
|
||||
|
||||
#######################
|
||||
# cashbook.open_lines #
|
||||
|
@ -366,3 +445,55 @@ msgstr "Beginndatum"
|
|||
msgctxt "field:cashbook.line.context,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "Endedatum"
|
||||
|
||||
|
||||
##########################
|
||||
# cashbook.configuration #
|
||||
##########################
|
||||
msgctxt "model:cashbook.configuration,name:"
|
||||
msgid "Configuration"
|
||||
msgstr "Konfiguration"
|
||||
|
||||
msgctxt "view:cashbook.configuration:"
|
||||
msgid "Open Cashbook Wizard"
|
||||
msgstr "Dialog: Kassenbuch öffnen"
|
||||
|
||||
msgctxt "field:cashbook.configuration,date_from:"
|
||||
msgid "Start Date"
|
||||
msgstr "Beginndatum"
|
||||
|
||||
msgctxt "field:cashbook.configuration,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "Endedatum"
|
||||
|
||||
msgctxt "field:cashbook.configuration,checked:"
|
||||
msgid "Checked"
|
||||
msgstr "Geprüft"
|
||||
|
||||
msgctxt "field:cashbook.configuration,done:"
|
||||
msgid "Done"
|
||||
msgstr "Fertig"
|
||||
|
||||
|
||||
###############################
|
||||
# cashbook.configuration_user #
|
||||
###############################
|
||||
msgctxt "model:cashbook.configuration_user,name:"
|
||||
msgid "User Configuration"
|
||||
msgstr "Nutzer Konfiguration"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,date_from:"
|
||||
msgid "Start Date"
|
||||
msgstr "Beginndatum"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "Endedatum"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,checked:"
|
||||
msgid "Checked"
|
||||
msgstr "Geprüft"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,done:"
|
||||
msgid "Done"
|
||||
msgstr "Fertig"
|
||||
|
|
368
locale/en.po
Normal file
368
locale/en.po
Normal file
|
@ -0,0 +1,368 @@
|
|||
#
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=utf-8\n"
|
||||
|
||||
msgctxt "model:ir.message,text:msg_type_short_unique"
|
||||
msgid "The Abbreviation must be unique."
|
||||
msgstr "The Abbreviation must be unique."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_name_cashbook"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "model:ir.message,text:msg_line_wrong_state_value"
|
||||
msgid "Invalid value of the field 'Status', allowed: edit, check, done."
|
||||
msgstr "Invalid value of the field 'Status', allowed: edit, check, done."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_book_wrong_state_value"
|
||||
msgid "Invalid value of the field 'Status', allowed: open, closed, archive."
|
||||
msgstr "Invalid value of the field 'Status', allowed: open, closed, archive."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_book_deny_delete"
|
||||
msgid "The cashbook '%(bookname)s' cannot be deleted because it contains %(booklines)s lines and is not in the status 'Archive'."
|
||||
msgstr "The cashbook '%(bookname)s' cannot be deleted because it contains %(booklines)s lines and is not in the status 'Archive'."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_book_deny_write"
|
||||
msgid "The cash book '%(bookname)s' is '%(state_txt)s' and cannot be changed."
|
||||
msgstr "The cash book '%(bookname)s' is '%(state_txt)s' and cannot be changed."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_line_deny_delete1"
|
||||
msgid "The cashbook line '%(linetxt)s' cannot be deleted because the Cashbook '%(bookname)s' is in state '%(bookstate)s'."
|
||||
msgstr "The cashbook line '%(linetxt)s' cannot be deleted because the Cashbook '%(bookname)s' is in state '%(bookstate)s'."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_line_deny_delete2"
|
||||
msgid "The cashbook line '%(linetxt)s' cannot be deleted, its in state '%(linestate)s'."
|
||||
msgstr "The cashbook line '%(linetxt)s' cannot be deleted, its in state '%(linestate)s'."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_setting_already_exists"
|
||||
msgid "Settings for this user alredy exists."
|
||||
msgstr "Settings for this user alredy exists."
|
||||
|
||||
msgctxt "model:res.group,name:group_cashbook"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "model:res.group,name:group_cashbook_checkline"
|
||||
msgid "Cashbook - WF - Check"
|
||||
msgstr "Cashbook - WF - Check"
|
||||
|
||||
msgctxt "model:res.group,name:group_cashbook_doneline"
|
||||
msgid "Cashbook - WF - Done"
|
||||
msgstr "Cashbook - WF - Done"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_book_read"
|
||||
msgid "Owners, observers and reviewers: Cashbook read"
|
||||
msgstr "Owners, observers and reviewers: Cashbook read"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_book_write_adm"
|
||||
msgid "Administrators: Cashbook read/write"
|
||||
msgstr "Administrators: Cashbook read/write"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_line_write_adm"
|
||||
msgid "Administrators: Cashbook line read/write"
|
||||
msgstr "Administrators: Cashbook line read/write"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_line_write"
|
||||
msgid "Owners and reviewers: Cashbook line write"
|
||||
msgstr "Owners and reviewers: Cashbook line write"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_line_read"
|
||||
msgid "Observer: Cashbook line read"
|
||||
msgstr "Observer: Cashbook line read"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_cashbook"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_config"
|
||||
msgid "Configuration"
|
||||
msgstr "Configuration"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_typeconfig"
|
||||
msgid "Cashbook Type"
|
||||
msgstr "Cashbook Type"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_bookconfig"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "model:ir.ui.menu,name:menu_open_lines"
|
||||
msgid "Open Cashbook"
|
||||
msgstr "Open Cashbook"
|
||||
|
||||
msgctxt "model:ir.action,name:act_book_view"
|
||||
msgid "Account"
|
||||
msgstr "Account"
|
||||
|
||||
msgctxt "model:ir.action,name:act_type_view"
|
||||
msgid "Cashbook Type"
|
||||
msgstr "Cashbook Type"
|
||||
|
||||
msgctxt "model:ir.action,name:act_line_view"
|
||||
msgid "Cashbook Line"
|
||||
msgstr "Cashbook Line"
|
||||
|
||||
msgctxt "model:ir.action,name:act_open_lines"
|
||||
msgid "Open Cashbook"
|
||||
msgstr "Open Cashbook"
|
||||
|
||||
msgctxt "model:ir.model.button,string:line_wfedit_button"
|
||||
msgid "Edit"
|
||||
msgstr "Edit"
|
||||
|
||||
msgctxt "model:ir.model.button,string:line_wfcheck_button"
|
||||
msgid "Check"
|
||||
msgstr "Check"
|
||||
|
||||
msgctxt "model:ir.model.button,string:line_wfdone_button"
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
msgctxt "model:ir.model.button,string:book_wfopen_button"
|
||||
msgid "Open"
|
||||
msgstr "Open"
|
||||
|
||||
msgctxt "model:ir.model.button,string:book_wfclosed_button"
|
||||
msgid "Close"
|
||||
msgstr "Close"
|
||||
|
||||
msgctxt "model:ir.model.button,string:book_wfarchive_button"
|
||||
msgid "Archive"
|
||||
msgstr "Archive"
|
||||
|
||||
msgctxt "model:cashbook.book,name:"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "view:cashbook.book:"
|
||||
msgid "Owner & Authorizeds"
|
||||
msgstr "Owner & Authorizeds"
|
||||
|
||||
msgctxt "field:cashbook.book,name:"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
msgctxt "field:cashbook.book,btype:"
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
msgctxt "field:cashbook.book,state:"
|
||||
msgid "State"
|
||||
msgstr "State"
|
||||
|
||||
msgctxt "selection:cashbook.book,state:"
|
||||
msgid "Open"
|
||||
msgstr "Open"
|
||||
|
||||
msgctxt "selection:cashbook.book,state:"
|
||||
msgid "Closed"
|
||||
msgstr "Closed"
|
||||
|
||||
msgctxt "selection:cashbook.book,state:"
|
||||
msgid "Archive"
|
||||
msgstr "Archive"
|
||||
|
||||
msgctxt "field:cashbook.book,owner:"
|
||||
msgid "Owner"
|
||||
msgstr "Owner"
|
||||
|
||||
msgctxt "field:cashbook.book,reviewer:"
|
||||
msgid "Reviewer"
|
||||
msgstr "Reviewer"
|
||||
|
||||
msgctxt "help:cashbook.book,reviewer:"
|
||||
msgid "Group of users who have write access to the cashbook."
|
||||
msgstr "Group of users who have write access to the cashbook."
|
||||
|
||||
msgctxt "field:cashbook.book,observer:"
|
||||
msgid "Observer"
|
||||
msgstr "Observer"
|
||||
|
||||
msgctxt "help:cashbook.book,observer:"
|
||||
msgid "Group of users who have read-only access to the cashbook."
|
||||
msgstr "Group of users who have read-only access to the cashbook."
|
||||
|
||||
msgctxt "model:cashbook.line,name:"
|
||||
msgid "Cashbook Line"
|
||||
msgstr "Cashbook Line"
|
||||
|
||||
msgctxt "view:cashbook.line:"
|
||||
msgid "Cashbook Line"
|
||||
msgstr "Cashbook Line"
|
||||
|
||||
msgctxt "view:cashbook.line:"
|
||||
msgid "State"
|
||||
msgstr "State"
|
||||
|
||||
msgctxt "field:cashbook.line,cashbook:"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "field:cashbook.line,date:"
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
msgctxt "field:cashbook.line,description:"
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
||||
msgctxt "field:cashbook.line,state:"
|
||||
msgid "State"
|
||||
msgstr "State"
|
||||
|
||||
msgctxt "selection:cashbook.line,state:"
|
||||
msgid "Edit"
|
||||
msgstr "Edit"
|
||||
|
||||
msgctxt "selection:cashbook.line,state:"
|
||||
msgid "Checked"
|
||||
msgstr "Checked"
|
||||
|
||||
msgctxt "selection:cashbook.line,state:"
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
msgctxt "model:cashbook.type,name:"
|
||||
msgid "Cashbook Type"
|
||||
msgstr "Cashbook Type"
|
||||
|
||||
msgctxt "field:cashbook.type,name:"
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
msgctxt "field:cashbook.type,short:"
|
||||
msgid "Abbreviation"
|
||||
msgstr "Abbreviation"
|
||||
|
||||
msgctxt "model:cashbook.type,name:atype_cash"
|
||||
msgid "Cash"
|
||||
msgstr "Cash"
|
||||
|
||||
msgctxt "model:cashbook.type,name:atype_giro"
|
||||
msgid "Giro"
|
||||
msgstr "Giro"
|
||||
|
||||
msgctxt "model:cashbook.type,name:atype_fixtermdep"
|
||||
msgid "Fixed-term deposit"
|
||||
msgstr "Fixed-term deposit"
|
||||
|
||||
msgctxt "model:cashbook.open_lines.start,name:"
|
||||
msgid "Open Cashbook"
|
||||
msgstr "Open Cashbook"
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,cashbook:"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,checked:"
|
||||
msgid "Checked"
|
||||
msgstr "Checked"
|
||||
|
||||
msgctxt "help:cashbook.open_lines.start,checked:"
|
||||
msgid "Show cashbook lines in Checked-state."
|
||||
msgstr "Show cashbook lines in Checked-state."
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,done:"
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
msgctxt "help:cashbook.open_lines.start,done:"
|
||||
msgid "Show cashbook lines in Done-state."
|
||||
msgstr "Show cashbook lines in Done-state."
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,date_from:"
|
||||
msgid "Start Date"
|
||||
msgstr "Start Date"
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "End Date"
|
||||
|
||||
msgctxt "field:cashbook.open_lines.start,num_books:"
|
||||
msgid "Number of Cashbooks"
|
||||
msgstr "Number of Cashbooks"
|
||||
|
||||
msgctxt "model:cashbook.open_lines,name:"
|
||||
msgid "Open Cashbook"
|
||||
msgstr "Open Cashbook"
|
||||
|
||||
msgctxt "wizard_button:cashbook.open_lines,start,end:"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
msgctxt "wizard_button:cashbook.open_lines,start,open_:"
|
||||
msgid "Open"
|
||||
msgstr "Open"
|
||||
|
||||
msgctxt "model:cashbook.line.context,name:"
|
||||
msgid "Line Context"
|
||||
msgstr "Line Context"
|
||||
|
||||
msgctxt "field:cashbook.line.context,cashbook:"
|
||||
msgid "Cashbook"
|
||||
msgstr "Cashbook"
|
||||
|
||||
msgctxt "field:cashbook.line.context,checked:"
|
||||
msgid "Checked"
|
||||
msgstr "Checked"
|
||||
|
||||
msgctxt "help:cashbook.line.context,checked:"
|
||||
msgid "Show cashbook lines in Checked-state."
|
||||
msgstr "Show cashbook lines in Checked-state."
|
||||
|
||||
msgctxt "field:cashbook.line.context,done:"
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
msgctxt "help:cashbook.line.context,done:"
|
||||
msgid "Show cashbook lines in Done-state."
|
||||
msgstr "Show cashbook lines in Done-state."
|
||||
|
||||
msgctxt "field:cashbook.line.context,date_from:"
|
||||
msgid "Start Date"
|
||||
msgstr "Start Date"
|
||||
|
||||
msgctxt "field:cashbook.line.context,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "End Date"
|
||||
|
||||
msgctxt "model:cashbook.configuration,name:"
|
||||
msgid "Configuration"
|
||||
msgstr "Configuration"
|
||||
|
||||
msgctxt "view:cashbook.configuration:"
|
||||
msgid "Open Cashbook Wizard"
|
||||
msgstr "Open Cashbook Wizard"
|
||||
|
||||
msgctxt "field:cashbook.configuration,date_from:"
|
||||
msgid "Start Date"
|
||||
msgstr "Start Date"
|
||||
|
||||
msgctxt "field:cashbook.configuration,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "End Date"
|
||||
|
||||
msgctxt "field:cashbook.configuration,checked:"
|
||||
msgid "Checked"
|
||||
msgstr "Checked"
|
||||
|
||||
msgctxt "field:cashbook.configuration,done:"
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
msgctxt "model:cashbook.configuration_user,name:"
|
||||
msgid "User Configuration"
|
||||
msgstr "User Configuration"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,date_from:"
|
||||
msgid "Start Date"
|
||||
msgstr "Start Date"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,date_to:"
|
||||
msgid "End Date"
|
||||
msgstr "End Date"
|
||||
|
||||
msgctxt "field:cashbook.configuration_user,checked:"
|
||||
msgid "Checked"
|
||||
msgstr "Checked"
|
||||
|
21
menu.xml
21
menu.xml
|
@ -17,8 +17,8 @@ full copyright notices and license terms. -->
|
|||
<field name="group" ref="group_cashbook"/>
|
||||
</record>
|
||||
|
||||
<!-- menu: /Cashbook/Configuration -->
|
||||
<menuitem id="menu_config" name="Configuration"
|
||||
<!-- menu: /Cashbook/Configuration name="Configuration" -->
|
||||
<menuitem id="menu_config" action="act_configuration_form"
|
||||
icon="tryton-list"
|
||||
parent="menu_cashbook" sequence="10"/>
|
||||
<record model="ir.ui.menu-res.group" id="menu_config-group_admin">
|
||||
|
@ -44,6 +44,23 @@ full copyright notices and license terms. -->
|
|||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
|
||||
<!-- menu: /Cashbook/Configuration/Category -->
|
||||
<menuitem id="menu_category" action="act_category_tree"
|
||||
icon="tryton-tree"
|
||||
parent="menu_config" sequence="30"/>
|
||||
<record model="ir.ui.menu-res.group" id="menu_category-group_admin">
|
||||
<field name="menu" ref="menu_category"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
<!-- menu: /Cashbook/Configuration/Category/Category -->
|
||||
<menuitem id="menu_category_list" action="act_category_list"
|
||||
icon="tryton-tree"
|
||||
parent="menu_category" sequence="30"/>
|
||||
<record model="ir.ui.menu-res.group" id="menu_category_list-group_admin">
|
||||
<field name="menu" ref="menu_category_list"/>
|
||||
<field name="group" ref="res.group_admin"/>
|
||||
</record>
|
||||
|
||||
<!-- menu: /Cashbook/Open Cashbook -->
|
||||
<menuitem id="menu_open_lines" action="act_open_lines"
|
||||
icon="tryton-tree"
|
||||
|
|
|
@ -29,6 +29,12 @@ full copyright notices and license terms. -->
|
|||
<record model="ir.message" id="msg_line_deny_delete2">
|
||||
<field name="text">The cashbook line '%(linetxt)s' cannot be deleted, its in state '%(linestate)s'.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_setting_already_exists">
|
||||
<field name="text">Settings for this user alredy exists.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_category_name_unique">
|
||||
<field name="text">The category name already exists at this level.</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
|
|
47
model.py
Normal file
47
model.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
# -*- 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 MultiValueMixin, ValueMixin, fields, Unique
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class UserValueMixin(ValueMixin):
|
||||
iduser = fields.Many2One(model_name='res.user', string="User",
|
||||
select=True, ondelete='CASCADE', required=True)
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(UserValueMixin, cls).__setup__()
|
||||
tab_val = cls.__table__()
|
||||
cls._sql_constraints.extend([
|
||||
('val_uniq',
|
||||
Unique(tab_val, tab_val.iduser),
|
||||
'cashbook.msg_setting_already_exists'),
|
||||
])
|
||||
|
||||
# end UserValueMixin
|
||||
|
||||
|
||||
class UserMultiValueMixin(MultiValueMixin):
|
||||
|
||||
def updt_multivalue_pattern(self, pattern):
|
||||
""" add values to pattern
|
||||
"""
|
||||
pattern.setdefault('iduser', Transaction().user)
|
||||
return pattern
|
||||
|
||||
def get_multivalue(self, name, **pattern):
|
||||
Value = self.multivalue_model(name)
|
||||
if issubclass(Value, UserValueMixin):
|
||||
pattern = self.updt_multivalue_pattern(pattern)
|
||||
return super(UserMultiValueMixin, self).get_multivalue(name, **pattern)
|
||||
|
||||
def set_multivalue(self, name, value, **pattern):
|
||||
Value = self.multivalue_model(name)
|
||||
if issubclass(Value, UserValueMixin):
|
||||
pattern = self.updt_multivalue_pattern(pattern)
|
||||
return super(UserMultiValueMixin, self).set_multivalue(name, value, **pattern)
|
||||
|
||||
# end UserMultiValueMixin
|
|
@ -7,11 +7,15 @@ import unittest
|
|||
from trytond.modules.cashbook.tests.test_type import TypeTestCase
|
||||
from trytond.modules.cashbook.tests.test_book import BookTestCase
|
||||
from trytond.modules.cashbook.tests.test_line import LineTestCase
|
||||
from trytond.modules.cashbook.tests.test_config import ConfigTestCase
|
||||
from trytond.modules.cashbook.tests.test_category import CategoryTestCase
|
||||
|
||||
__all__ = ['suite']
|
||||
|
||||
|
||||
class CashbookTestCase(\
|
||||
CategoryTestCase,\
|
||||
ConfigTestCase,\
|
||||
LineTestCase,
|
||||
BookTestCase,
|
||||
TypeTestCase,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
# -*- 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.
|
||||
|
||||
import os, requests
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
|
@ -54,7 +55,7 @@ class BookTestCase(ModuleTestCase):
|
|||
self.assertEqual(book.state, 'open')
|
||||
|
||||
self.assertRaisesRegex(UserError,
|
||||
"The cash book 'Book 1' cannot be deleted because it contains 1 lines and is not in the status 'Archive'.",
|
||||
"The cashbook 'Book 1' cannot be deleted because it contains 1 lines and is not in the status 'Archive'.",
|
||||
Book.delete,
|
||||
[book])
|
||||
|
||||
|
@ -82,7 +83,7 @@ class BookTestCase(ModuleTestCase):
|
|||
self.assertEqual(book.state, 'closed')
|
||||
|
||||
self.assertRaisesRegex(UserError,
|
||||
"The cash book 'Book 1' cannot be deleted because it contains 1 lines and is not in the status 'Archive'.",
|
||||
"The cashbook 'Book 1' cannot be deleted because it contains 1 lines and is not in the status 'Archive'.",
|
||||
Book.delete,
|
||||
[book])
|
||||
|
||||
|
|
137
tests/test_category.py
Normal file
137
tests/test_category.py
Normal file
|
@ -0,0 +1,137 @@
|
|||
# -*- 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.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.modules.company.tests import create_company
|
||||
|
||||
|
||||
class CategoryTestCase(ModuleTestCase):
|
||||
'Test cashbook categoy module'
|
||||
module = 'cashbook'
|
||||
|
||||
@with_transaction()
|
||||
def test_category_create_nodupl_at_root(self):
|
||||
""" create category, duplicates are allowed at root-level
|
||||
"""
|
||||
pool = Pool()
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
}):
|
||||
cat1, = Category.create([{
|
||||
'name': 'Test 1',
|
||||
'description': 'Info',
|
||||
}])
|
||||
self.assertEqual(cat1.name, 'Test 1')
|
||||
self.assertEqual(cat1.rec_name, 'Test 1')
|
||||
self.assertEqual(cat1.description, 'Info')
|
||||
self.assertEqual(cat1.company.rec_name, 'm-ds')
|
||||
self.assertEqual(cat1.parent, None)
|
||||
|
||||
# duplicate, allowed
|
||||
cat2, = Category.create([{
|
||||
'name': 'Test 1',
|
||||
'description': 'Info',
|
||||
}])
|
||||
self.assertEqual(cat2.name, 'Test 1')
|
||||
self.assertEqual(cat2.rec_name, 'Test 1')
|
||||
self.assertEqual(cat2.description, 'Info')
|
||||
self.assertEqual(cat2.company.rec_name, 'm-ds')
|
||||
self.assertEqual(cat2.parent, None)
|
||||
|
||||
@with_transaction()
|
||||
def test_category_create_nodupl_diff_level(self):
|
||||
""" create category
|
||||
"""
|
||||
pool = Pool()
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
}):
|
||||
cat1, = Category.create([{
|
||||
'name': 'Test 1',
|
||||
'description': 'Info',
|
||||
'childs': [('create', [{
|
||||
'name': 'Test 1',
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(cat1.name, 'Test 1')
|
||||
self.assertEqual(cat1.rec_name, 'Test 1')
|
||||
self.assertEqual(cat1.description, 'Info')
|
||||
self.assertEqual(cat1.company.rec_name, 'm-ds')
|
||||
|
||||
self.assertEqual(len(cat1.childs), 1)
|
||||
self.assertEqual(cat1.childs[0].rec_name, 'Test 1/Test 1')
|
||||
|
||||
@with_transaction()
|
||||
def test_category_create_deny_dupl_at_sublevel(self):
|
||||
""" create category
|
||||
"""
|
||||
pool = Pool()
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
}):
|
||||
self.assertRaisesRegex(UserError,
|
||||
'The category name already exists at this level.',
|
||||
Category.create,
|
||||
[{
|
||||
'name': 'Test 1',
|
||||
'description': 'Info',
|
||||
'childs': [('create', [{
|
||||
'name': 'Test 1',
|
||||
}, {
|
||||
'name': 'Test 1',
|
||||
}])],
|
||||
}])
|
||||
|
||||
@with_transaction()
|
||||
def test_category_create_with_account(self):
|
||||
""" create category + account
|
||||
"""
|
||||
pool = Pool()
|
||||
Account = pool.get('account.account')
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
}):
|
||||
account, = Account.create([{
|
||||
'name': 'Account No 1',
|
||||
'code': '0123',
|
||||
}])
|
||||
|
||||
cat1, = Category.create([{
|
||||
'name': 'Test 1',
|
||||
'description': 'Info',
|
||||
'account': account.id,
|
||||
}])
|
||||
self.assertEqual(cat1.name, 'Test 1')
|
||||
self.assertEqual(cat1.rec_name, '0123 Test 1')
|
||||
self.assertEqual(cat1.description, 'Info')
|
||||
self.assertEqual(cat1.company.rec_name, 'm-ds')
|
||||
|
||||
self.assertEqual(Category.search_count([
|
||||
('account_code', '=', '0123'),
|
||||
]), 1)
|
||||
self.assertEqual(Category.search_count([
|
||||
('account_code', '=', '123'),
|
||||
]), 0)
|
||||
|
||||
# end CategoryTestCase
|
96
tests/test_config.py
Normal file
96
tests/test_config.py
Normal file
|
@ -0,0 +1,96 @@
|
|||
# -*- 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.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.exceptions import UserError
|
||||
from datetime import date
|
||||
|
||||
|
||||
class ConfigTestCase(ModuleTestCase):
|
||||
'Test config type module'
|
||||
module = 'cashbook'
|
||||
|
||||
@with_transaction()
|
||||
def test_config_create(self):
|
||||
""" create config
|
||||
"""
|
||||
Configuration = Pool().get('cashbook.configuration')
|
||||
|
||||
cfg1 = Configuration()
|
||||
cfg1.save()
|
||||
|
||||
cfg2 = Configuration.get_singleton()
|
||||
self.assertEqual(cfg2.date_from, None)
|
||||
self.assertEqual(cfg2.date_to, None)
|
||||
self.assertEqual(cfg2.checked, True)
|
||||
self.assertEqual(cfg2.done, False)
|
||||
|
||||
@with_transaction()
|
||||
def test_config_create_multi_user(self):
|
||||
""" create config, multi-user
|
||||
"""
|
||||
pool = Pool()
|
||||
Configuration = pool.get('cashbook.configuration')
|
||||
ResUser = pool.get('res.user')
|
||||
|
||||
usr_lst = ResUser.create([{
|
||||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
self.assertEqual(usr_lst[1].name, 'Diego')
|
||||
|
||||
with Transaction().set_context({
|
||||
'_check_access': True,
|
||||
}):
|
||||
# change to user 'frida'
|
||||
with Transaction().set_user(usr_lst[0].id):
|
||||
cfg1 = Configuration()
|
||||
cfg1.save()
|
||||
|
||||
cfg2 = Configuration.get_singleton()
|
||||
self.assertEqual(cfg2.date_from, None)
|
||||
self.assertEqual(cfg2.date_to, None)
|
||||
self.assertEqual(cfg2.checked, True)
|
||||
self.assertEqual(cfg2.done, False)
|
||||
|
||||
cfg2.date_from = date(2022, 4, 1)
|
||||
cfg2.date_to = date(2022, 5, 30)
|
||||
cfg2.checked = False
|
||||
cfg2.save()
|
||||
|
||||
# change to user 'diego'
|
||||
with Transaction().set_user(usr_lst[1].id):
|
||||
cfg1 = Configuration()
|
||||
cfg1.save()
|
||||
|
||||
cfg2 = Configuration.get_singleton()
|
||||
self.assertEqual(cfg2.date_from, None)
|
||||
self.assertEqual(cfg2.date_to, None)
|
||||
self.assertEqual(cfg2.checked, True)
|
||||
self.assertEqual(cfg2.done, False)
|
||||
|
||||
cfg2.date_from = date(2022, 4, 15)
|
||||
cfg2.date_to = date(2022, 5, 15)
|
||||
cfg2.save()
|
||||
|
||||
# change to user 'frida' - check
|
||||
with Transaction().set_user(usr_lst[0].id):
|
||||
cfg1 = Configuration()
|
||||
cfg1.save()
|
||||
|
||||
cfg2 = Configuration.get_singleton()
|
||||
self.assertEqual(cfg2.date_from, date(2022, 4, 1))
|
||||
self.assertEqual(cfg2.date_to, date(2022, 5, 30))
|
||||
self.assertEqual(cfg2.checked, False)
|
||||
self.assertEqual(cfg2.done, False)
|
||||
|
||||
# end ConfigTestCase
|
|
@ -1,7 +1,8 @@
|
|||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
# -*- 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.
|
||||
|
||||
import os, requests
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
# -*- 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.
|
||||
|
||||
import os, requests
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
from trytond.pool import Pool
|
||||
from trytond.transaction import Transaction
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
version=6.0.0
|
||||
depends:
|
||||
res
|
||||
account
|
||||
xml:
|
||||
icon.xml
|
||||
group.xml
|
||||
message.xml
|
||||
types.xml
|
||||
category.xml
|
||||
configuration.xml
|
||||
book.xml
|
||||
line.xml
|
||||
wizard_openline.xml
|
||||
|
|
6
types.py
6
types.py
|
@ -18,9 +18,9 @@ class Type(ModelSQL, ModelView):
|
|||
super(Type, cls).__setup__()
|
||||
cls._order.insert(0, ('name', 'ASC'))
|
||||
t = cls.__table__()
|
||||
cls._sql_constraints = [
|
||||
cls._sql_constraints.extend([
|
||||
('code_uniq', Unique(t, t.short), 'cashbook.msg_type_short_unique'),
|
||||
]
|
||||
])
|
||||
|
||||
def get_rec_name(self, name):
|
||||
""" short + name
|
||||
|
@ -32,7 +32,7 @@ class Type(ModelSQL, ModelView):
|
|||
|
||||
@classmethod
|
||||
def search_rec_name(cls, name, clause):
|
||||
""" search in tracker + ticket-name
|
||||
""" search in name + short
|
||||
"""
|
||||
return ['OR',
|
||||
('name',) + tuple(clause[1:]),
|
||||
|
|
|
@ -8,6 +8,10 @@ full copyright notices and license terms. -->
|
|||
<label name="btype"/>
|
||||
<field name="btype"/>
|
||||
|
||||
<label name="account"/>
|
||||
<field name="account"/>
|
||||
<newline/>
|
||||
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group id="grpstate" col="3" colspan="2">
|
||||
|
|
|
@ -5,6 +5,7 @@ full copyright notices and license terms. -->
|
|||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="btype"/>
|
||||
<field name="account"/>
|
||||
<field name="owner"/>
|
||||
<field name="reviewer"/>
|
||||
<field name="observer"/>
|
||||
|
|
|
@ -15,5 +15,7 @@ full copyright notices and license terms. -->
|
|||
<field name="checked"/>
|
||||
<label name="done"/>
|
||||
<field name="done"/>
|
||||
|
||||
<field name="num_cashbook"/>
|
||||
</form>
|
||||
|
||||
|
|
24
view/category_form.xml
Normal file
24
view/category_form.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?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. -->
|
||||
<form>
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="account"/>
|
||||
<field name="account"/>
|
||||
|
||||
<label name="description"/>
|
||||
<field name="description" colspan="3"/>
|
||||
|
||||
<notebook colspan="6">
|
||||
<page string="General Information" id="general" col="6">
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="parent"/>
|
||||
<field name="parent"/>
|
||||
<field name="childs" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
</form>
|
8
view/category_list.xml
Normal file
8
view/category_list.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?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. -->
|
||||
<tree>
|
||||
<field name="rec_name"/>
|
||||
<field name="account"/>
|
||||
</tree>
|
10
view/category_tree.xml
Normal file
10
view/category_tree.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?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. -->
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="account_code"/>
|
||||
<field name="parent" tree_invisible="1"/>
|
||||
<field name="childs" tree_invisible="1"/>
|
||||
</tree>
|
14
view/configuration_form.xml
Normal file
14
view/configuration_form.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<form>
|
||||
<separator id="sepwiz" colspan="4" string="Open Cashbook Wizard"/>
|
||||
<label name="date_from"/>
|
||||
<field name="date_from"/>
|
||||
<label name="date_to"/>
|
||||
<field name="date_to"/>
|
||||
<label name="checked"/>
|
||||
<field name="checked"/>
|
||||
<label name="done"/>
|
||||
<field name="done"/>
|
||||
</form>
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.pyson import PYSONEncoder
|
||||
from trytond.wizard import Wizard, StateView, StateAction, Button
|
||||
from trytond.wizard import Wizard, StateView, StateTransition, StateAction, Button
|
||||
from trytond.i18n import gettext
|
||||
from trytond.pool import Pool
|
||||
from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class OpenCashBookStart(ModelView):
|
||||
|
@ -36,38 +38,81 @@ class OpenCashBook(Wizard):
|
|||
'Open Cashbook'
|
||||
__name__ = 'cashbook.open_lines'
|
||||
|
||||
start = StateView('cashbook.open_lines.start',
|
||||
start_state = 'check'
|
||||
check = StateTransition()
|
||||
askuser = StateView('cashbook.open_lines.start',
|
||||
'cashbook.open_lines_view_form', [
|
||||
Button('Cancel', 'end', 'tryton-cancel'),
|
||||
Button('Open', 'open_', 'tryton-ok', default=True),
|
||||
])
|
||||
open_ = StateAction('cashbook.act_line_view')
|
||||
|
||||
def default_start(self, fields):
|
||||
""" setup form
|
||||
def transition_check(self):
|
||||
""" dont ask and open cashbook if user has 1x only
|
||||
"""
|
||||
Book = Pool().get('cashbook.book')
|
||||
|
||||
result = {}
|
||||
|
||||
with Transaction().set_context({
|
||||
'_check_access': True,
|
||||
}):
|
||||
books = Book.search([])
|
||||
print('\n## books:', books)
|
||||
if len(books) == 1:
|
||||
result['cashbook'] = books[0].id
|
||||
return 'open_'
|
||||
return 'askuser'
|
||||
|
||||
def default_askuser(self, fields):
|
||||
""" setup form
|
||||
"""
|
||||
Configuration = Pool().get('cashbook.configuration')
|
||||
|
||||
cfg1 = Configuration.get_singleton()
|
||||
result = {
|
||||
'date_from': getattr(cfg1, 'date_from', None),
|
||||
'date_to': getattr(cfg1, 'date_to', None),
|
||||
'checked': getattr(cfg1, 'checked', True),
|
||||
'done': getattr(cfg1, 'done', False),
|
||||
}
|
||||
return result
|
||||
|
||||
def do_open_(self, action):
|
||||
""" open view, use data from dialog
|
||||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Configuration = pool.get('cashbook.configuration')
|
||||
|
||||
cfg1 = Configuration.get_singleton()
|
||||
book = getattr(self.askuser, 'cashbook', None)
|
||||
if book is None:
|
||||
with Transaction().set_context({
|
||||
'_check_access': True,
|
||||
}):
|
||||
books = Book.search([])
|
||||
if len(books) > 0:
|
||||
book = books[0]
|
||||
|
||||
date_from = getattr(self.askuser, 'date_from', None)
|
||||
date_to = getattr(self.askuser, 'date_to', None)
|
||||
checked = getattr(self.askuser, 'checked', True)
|
||||
done = getattr(self.askuser, 'done', False)
|
||||
|
||||
# save settings
|
||||
cfg1.date_from = date_from
|
||||
cfg1.date_to = date_to
|
||||
cfg1.checked = checked
|
||||
cfg1.done = done
|
||||
cfg1.save()
|
||||
|
||||
action['pyson_context'] = PYSONEncoder().encode({
|
||||
'cashbook': self.start.cashbook.id,
|
||||
'date_from': self.start.date_from,
|
||||
'date_to': self.start.date_to,
|
||||
'checked': self.start.checked,
|
||||
'done': self.start.done,
|
||||
'cashbook': getattr(book, 'id', None),
|
||||
'date_from': date_from,
|
||||
'date_to': date_to,
|
||||
'checked': checked,
|
||||
'done': done,
|
||||
})
|
||||
action['name'] = '%(name)s: %(cashbook)s' % {
|
||||
'name': gettext('cashbook.msg_name_cashbook'),
|
||||
'cashbook': self.start.cashbook.rec_name,
|
||||
'cashbook': getattr(book, 'rec_name', '-/-'),
|
||||
}
|
||||
return action, {}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue