book, line, category, types: berechtigung für company-user + test,
book: währung neu, line: buchungstyp, betrag, credit, debit, währung, sortierung
This commit is contained in:
parent
1a85b8e80e
commit
d57d76ba3b
20 changed files with 620 additions and 115 deletions
29
book.py
29
book.py
|
@ -4,10 +4,11 @@
|
|||
# full copyright notices and license terms.
|
||||
|
||||
from trytond.model import Workflow, ModelView, ModelSQL, fields, Check
|
||||
from trytond.pyson import Eval
|
||||
from trytond.pyson import Eval, Or, Bool
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from trytond.transaction import Transaction
|
||||
from trytond.pool import Pool
|
||||
|
||||
|
||||
STATES = {
|
||||
|
@ -26,6 +27,8 @@ class Book(Workflow, ModelSQL, ModelView):
|
|||
'Cashbook'
|
||||
__name__ = 'cashbook.book'
|
||||
|
||||
company = fields.Many2One(string='Company', model_name='company.company',
|
||||
required=True, ondelete="RESTRICT")
|
||||
name = fields.Char(string='Name', required=True,
|
||||
states=STATES, depends=DEPENDS)
|
||||
btype = fields.Many2One(string='Type', required=True,
|
||||
|
@ -45,6 +48,14 @@ class Book(Workflow, ModelSQL, ModelView):
|
|||
account = fields.Many2One(string='Account', select=True,
|
||||
model_name='account.account', ondelete='RESTRICT',
|
||||
states=STATES, depends=DEPENDS)
|
||||
currency = fields.Many2One(string='Currency', required=True,
|
||||
model_name='currency.currency',
|
||||
states={
|
||||
'readonly': Or(
|
||||
STATES['readonly'],
|
||||
Bool(Eval('lines', [])),
|
||||
),
|
||||
}, depends=DEPENDS+['lines'])
|
||||
state = fields.Selection(string='State', required=True,
|
||||
readonly=True, selection=sel_state_book)
|
||||
state_string = state.translated('state')
|
||||
|
@ -79,6 +90,22 @@ class Book(Workflow, ModelSQL, ModelView):
|
|||
},
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def default_currency(cls):
|
||||
""" currency of company
|
||||
"""
|
||||
Company = Pool().get('company.company')
|
||||
|
||||
company = cls.default_company()
|
||||
if company:
|
||||
company = Company(company)
|
||||
if company.currency:
|
||||
return company.currency.id
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company') or None
|
||||
|
||||
@classmethod
|
||||
def default_state(cls):
|
||||
return 'open'
|
||||
|
|
13
book.xml
13
book.xml
|
@ -107,6 +107,19 @@ full copyright notices and license terms. -->
|
|||
<field name="group" ref="group_cashbook"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rg_book_companies">
|
||||
<field name="name">User in companies</field>
|
||||
<field name="model"
|
||||
search="[('model', '=', 'cashbook.book')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="r_book_companies">
|
||||
<field name="domain"
|
||||
eval="[('company', 'in', Eval('companies', []))]"
|
||||
pyson="1"/>
|
||||
<field name="rule_group" ref="rg_book_companies"/>
|
||||
</record>
|
||||
|
||||
<!-- button - open -->
|
||||
<record model="ir.model.button" id="book_wfopen_button">
|
||||
<field name="name">wfopen</field>
|
||||
|
|
13
category.xml
13
category.xml
|
@ -87,5 +87,18 @@ full copyright notices and license terms. -->
|
|||
<field name="perm_delete" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rg_category_companies">
|
||||
<field name="name">User in companies</field>
|
||||
<field name="model"
|
||||
search="[('model', '=', 'cashbook.category')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="r_category_companies">
|
||||
<field name="domain"
|
||||
eval="[('company', 'in', Eval('companies', []))]"
|
||||
pyson="1"/>
|
||||
<field name="rule_group" ref="rg_category_companies"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
|
|
112
line.py
112
line.py
|
@ -10,8 +10,10 @@ from trytond.transaction import Transaction
|
|||
from trytond.report import Report
|
||||
from trytond.exceptions import UserError
|
||||
from trytond.i18n import gettext
|
||||
from decimal import Decimal
|
||||
from sql import Cast, Literal
|
||||
from sql.functions import DatePart
|
||||
from sql.conditionals import Case
|
||||
from .book import sel_state_book
|
||||
|
||||
|
||||
|
@ -21,6 +23,13 @@ sel_linetype = [
|
|||
('done', 'Done'),
|
||||
]
|
||||
|
||||
sel_bookingtype = [
|
||||
('in', 'Revenue'),
|
||||
('out', 'Expense'),
|
||||
('mvin', 'Transfer from'),
|
||||
('mvout', 'Transfer to'),
|
||||
]
|
||||
|
||||
STATES = {
|
||||
'readonly': Or(
|
||||
Eval('state', '') != 'edit',
|
||||
|
@ -47,6 +56,21 @@ class Line(Workflow, ModelSQL, ModelView):
|
|||
states=STATES, depends=DEPENDS)
|
||||
category_view = fields.Function(fields.Char(string='Category', readonly=True),
|
||||
'on_change_with_category_view', searcher='search_category_view')
|
||||
|
||||
bookingtype = fields.Selection(string='Type', required=True,
|
||||
help='Type of Booking', selection=sel_bookingtype,
|
||||
states=STATES, depends=DEPENDS)
|
||||
amount = fields.Numeric(string='Amount', digits=(16, Eval('currency_digits', 2)),
|
||||
required=True, states=STATES, depends=DEPENDS+['currency_digits'])
|
||||
debit = fields.Numeric(string='Debit', digits=(16, Eval('currency_digits', 2)),
|
||||
required=True, readonly=True, depends=['currency_digits'])
|
||||
credit = fields.Numeric(string='Credit', digits=(16, Eval('currency_digits', 2)),
|
||||
required=True, readonly=True, depends=['currency_digits'])
|
||||
currency = fields.Function(fields.Many2One(model_name='currency.currency',
|
||||
string="Currency"), 'on_change_with_currency')
|
||||
currency_digits = fields.Function(fields.Integer(string='Currency Digits'),
|
||||
'on_change_with_currency_digits')
|
||||
|
||||
state = fields.Selection(string='State', required=True, readonly=True,
|
||||
select=True, selection=sel_linetype)
|
||||
state_string = state.translated('state')
|
||||
|
@ -59,6 +83,7 @@ class Line(Workflow, ModelSQL, ModelView):
|
|||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Line, cls).__setup__()
|
||||
cls._order.insert(0, ('state', 'ASC'))
|
||||
cls._order.insert(0, ('date', 'ASC'))
|
||||
t = cls.__table__()
|
||||
cls._sql_constraints.extend([
|
||||
|
@ -138,6 +163,23 @@ class Line(Workflow, ModelSQL, ModelView):
|
|||
'desc': (self.description or '-')[:40],
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def order_state(tables):
|
||||
""" edit = 0, check/done = 1
|
||||
"""
|
||||
Line = Pool().get('cashbook.line')
|
||||
tab_line = Line.__table__()
|
||||
table, _ = tables[None]
|
||||
|
||||
query = tab_line.select(
|
||||
Case(
|
||||
(tab_line.state == 'edit', 1),
|
||||
(tab_line.state.in_(['check', 'done']), 0),
|
||||
else_ = 2),
|
||||
where=tab_line.id==table.id
|
||||
)
|
||||
return [query]
|
||||
|
||||
@staticmethod
|
||||
def order_category_view(tables):
|
||||
""" order: name
|
||||
|
@ -219,11 +261,65 @@ class Line(Workflow, ModelSQL, ModelView):
|
|||
"""
|
||||
return [('cashbook.state',) + tuple(clause[1:])]
|
||||
|
||||
@fields.depends('cashbook', '_parent_cashbook.currency')
|
||||
def on_change_with_currency(self, name=None):
|
||||
""" currency of cashbook
|
||||
"""
|
||||
if self.cashbook:
|
||||
return self.cashbook.currency.id
|
||||
|
||||
@fields.depends('cashbook', '_parent_cashbook.currency')
|
||||
def on_change_with_currency_digits(self, name=None):
|
||||
""" currency of cashbook
|
||||
"""
|
||||
if self.cashbook:
|
||||
return self.cashbook.currency.digits
|
||||
else:
|
||||
return 2
|
||||
|
||||
@classmethod
|
||||
def get_debit_credit(cls, values):
|
||||
""" compute debit/credit from amount
|
||||
"""
|
||||
if isinstance(values, dict):
|
||||
type_ = values.get('bookingtype', None)
|
||||
amount = values.get('amount', None)
|
||||
else :
|
||||
type_ = getattr(values, 'bookingtype', None)
|
||||
amount = getattr(values, 'amount', None)
|
||||
|
||||
if type_:
|
||||
if amount is not None:
|
||||
if type_ in ['in', 'mvin']:
|
||||
return {
|
||||
'debit': Decimal('0.0'),
|
||||
'credit': amount,
|
||||
}
|
||||
elif type_ in ['out', 'mvout']:
|
||||
return {
|
||||
'debit': amount,
|
||||
'credit': Decimal('0.0'),
|
||||
}
|
||||
else :
|
||||
raise ValueError('invalid "bookingtype"')
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
""" add debit/credit
|
||||
"""
|
||||
vlist = [x.copy() for x in vlist]
|
||||
for vals in vlist:
|
||||
vals.update(cls.get_debit_credit(vals))
|
||||
return super(Line, cls).create(vlist)
|
||||
|
||||
@classmethod
|
||||
def write(cls, *args):
|
||||
""" deny update if cashbook.line!='open'
|
||||
""" deny update if cashbook.line!='open',
|
||||
add or update debit/credit
|
||||
"""
|
||||
actions = iter(args)
|
||||
to_write = []
|
||||
for lines, values in zip(actions, actions):
|
||||
for line in lines:
|
||||
if line.cashbook.state != 'open':
|
||||
|
@ -232,7 +328,19 @@ class Line(Workflow, ModelSQL, ModelView):
|
|||
bookname = line.cashbook.rec_name,
|
||||
state_txt = line.cashbook.state_string,
|
||||
))
|
||||
super(Line, cls).write(*args)
|
||||
|
||||
# debit / credit
|
||||
if len(set(values.keys()).intersection(set({'amount', 'bookingtype'}))) > 0:
|
||||
for line in lines:
|
||||
values2 = {}
|
||||
values2.update(values)
|
||||
values2.update(cls.get_debit_credit({
|
||||
x:values.get(x, getattr(line, x)) for x in ['amount', 'bookingtype']
|
||||
}))
|
||||
to_write.extend([lines, values2])
|
||||
else :
|
||||
to_write.extend([lines, values])
|
||||
super(Line, cls).write(*to_write)
|
||||
|
||||
@classmethod
|
||||
def delete(cls, lines):
|
||||
|
|
13
line.xml
13
line.xml
|
@ -169,6 +169,19 @@ full copyright notices and license terms. -->
|
|||
<field name="group" ref="group_cashbook"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rg_line_companies">
|
||||
<field name="name">User in companies</field>
|
||||
<field name="model"
|
||||
search="[('model', '=', 'cashbook.line')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="r_line_companies">
|
||||
<field name="domain"
|
||||
eval="[('cashbook.company', 'in', Eval('companies', []))]"
|
||||
pyson="1"/>
|
||||
<field name="rule_group" ref="rg_line_companies"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- button - edit -->
|
||||
<record model="ir.model.button" id="line_wfedit_button">
|
||||
|
|
126
locale/de.po
126
locale/de.po
|
@ -27,7 +27,7 @@ msgid "The cashbook '%(bookname)s' cannot be deleted because it contains %(bookl
|
|||
msgstr "Das Kassenbuch '%(bookname)s' kann nicht gelöscht werden, da es %(booklines)s Zeilen enthält und nicht im Status 'Archiv' ist."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_book_deny_write"
|
||||
msgid "The cash book '%(bookname)s' is '%(state_txt)s' and cannot be changed."
|
||||
msgid "The cashbook '%(bookname)s' is '%(state_txt)s' and cannot be changed."
|
||||
msgstr "Das Kassenbuch '%(bookname)s' ist '%(state_txt)s' und kann nicht geändert werden."
|
||||
|
||||
msgctxt "model:ir.message,text:msg_line_deny_delete1"
|
||||
|
@ -90,6 +90,18 @@ msgctxt "model:ir.rule.group,name:rg_line_read"
|
|||
msgid "Observer: Cashbook line read"
|
||||
msgstr "Beobachter: Kassenbuchzeile lesen"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_line_read"
|
||||
msgid "User in companies"
|
||||
msgstr "Benutzer im Unternehmen"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_type_companies"
|
||||
msgid "User in companies"
|
||||
msgstr "Benutzer im Unternehmen"
|
||||
|
||||
msgctxt "model:ir.rule.group,name:rg_book_companies"
|
||||
msgid "User in companies"
|
||||
msgstr "Benutzer im Unternehmen"
|
||||
|
||||
|
||||
##############
|
||||
# ir.ui.menu #
|
||||
|
@ -127,8 +139,8 @@ msgstr "Kategorie"
|
|||
# ir.action #
|
||||
#############
|
||||
msgctxt "model:ir.action,name:act_book_view"
|
||||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
msgid "Cashbook"
|
||||
msgstr "Kassenbuch"
|
||||
|
||||
msgctxt "model:ir.action,name:act_type_view"
|
||||
msgid "Cashbook Type"
|
||||
|
@ -147,6 +159,22 @@ msgid "Category"
|
|||
msgstr "Kategorie"
|
||||
|
||||
|
||||
###############################
|
||||
# ir.action.act_window.domain #
|
||||
###############################
|
||||
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_current"
|
||||
msgid "Current Month"
|
||||
msgstr "aktueller Monat"
|
||||
|
||||
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_last"
|
||||
msgid "Last Month"
|
||||
msgstr "letzter Monat"
|
||||
|
||||
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_all"
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
|
||||
###################
|
||||
# ir.model.button #
|
||||
###################
|
||||
|
@ -183,8 +211,8 @@ msgid "Cashbook"
|
|||
msgstr "Kassenbuch"
|
||||
|
||||
msgctxt "view:cashbook.book:"
|
||||
msgid "Owner & Authorizeds"
|
||||
msgstr "Eigentümer & Autorisierte"
|
||||
msgid "Owner and Authorizeds"
|
||||
msgstr "Eigentümer und Autorisierte"
|
||||
|
||||
msgctxt "field:cashbook.book,name:"
|
||||
msgid "Name"
|
||||
|
@ -234,6 +262,14 @@ msgctxt "field:cashbook.book,account:"
|
|||
msgid "Account"
|
||||
msgstr "Konto"
|
||||
|
||||
msgctxt "field:cashbook.book,company:"
|
||||
msgid "Company"
|
||||
msgstr "Unternehmen"
|
||||
|
||||
msgctxt "field:cashbook.book,currency:"
|
||||
msgid "Currency"
|
||||
msgstr "Währung"
|
||||
|
||||
|
||||
#################
|
||||
# cashbook.line #
|
||||
|
@ -242,6 +278,14 @@ msgctxt "model:cashbook.line,name:"
|
|||
msgid "Cashbook Line"
|
||||
msgstr "Kassenbuchzeile"
|
||||
|
||||
msgctxt "view:cashbook.line:"
|
||||
msgid "Credit"
|
||||
msgstr "Einnahme"
|
||||
|
||||
msgctxt "view:cashbook.line:"
|
||||
msgid "Debit"
|
||||
msgstr "Ausgabe"
|
||||
|
||||
msgctxt "view:cashbook.line:"
|
||||
msgid "Cashbook Line"
|
||||
msgstr "Kassenbuchzeile"
|
||||
|
@ -294,17 +338,53 @@ msgctxt "field:cashbook.line,category_view:"
|
|||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_current"
|
||||
msgid "Current Month"
|
||||
msgstr "aktueller Monat"
|
||||
msgctxt "field:cashbook.line,bookingtype:"
|
||||
msgid "Type"
|
||||
msgstr "Typ"
|
||||
|
||||
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_last"
|
||||
msgid "Last Month"
|
||||
msgstr "letzter Monat"
|
||||
msgctxt "help:cashbook.line,bookingtype:"
|
||||
msgid "Type of Booking"
|
||||
msgstr "Typ der Buchung"
|
||||
|
||||
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_all"
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
msgctxt "selection:cashbook.line,bookingtype:"
|
||||
msgid "Revenue"
|
||||
msgstr "Einnahme"
|
||||
|
||||
msgctxt "selection:cashbook.line,bookingtype:"
|
||||
msgid "Expense"
|
||||
msgstr "Ausgabe"
|
||||
|
||||
msgctxt "selection:cashbook.line,bookingtype:"
|
||||
msgid "Transfer from"
|
||||
msgstr "Umbuchung von"
|
||||
|
||||
msgctxt "selection:cashbook.line,bookingtype:"
|
||||
msgid "Transfer to"
|
||||
msgstr "Umbuchung nach"
|
||||
|
||||
msgctxt "field:cashbook.line,company:"
|
||||
msgid "Company"
|
||||
msgstr "Unternehmen"
|
||||
|
||||
msgctxt "field:cashbook.line,amount:"
|
||||
msgid "Amount"
|
||||
msgstr "Betrag"
|
||||
|
||||
msgctxt "field:cashbook.line,debit:"
|
||||
msgid "Debit"
|
||||
msgstr "Ausgabe"
|
||||
|
||||
msgctxt "field:cashbook.line,credit:"
|
||||
msgid "Credit"
|
||||
msgstr "Einnahme"
|
||||
|
||||
msgctxt "field:cashbook.line,currency:"
|
||||
msgid "Currency"
|
||||
msgstr "Währung"
|
||||
|
||||
msgctxt "field:cashbook.line,currency_digits:"
|
||||
msgid "Currency Digits"
|
||||
msgstr "Nachkommastellen Währung"
|
||||
|
||||
|
||||
#################
|
||||
|
@ -322,17 +402,9 @@ 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,name:atype_giro"
|
||||
msgid "Giro"
|
||||
msgstr "Giro"
|
||||
|
||||
msgctxt "model:cashbook.type,name:atype_fixtermdep"
|
||||
msgid "Fixed-term deposit"
|
||||
msgstr "Festgeld"
|
||||
msgctxt "field:cashbook.type,company:"
|
||||
msgid "Company"
|
||||
msgstr "Unternehmen"
|
||||
|
||||
|
||||
#####################
|
||||
|
@ -434,11 +506,11 @@ msgctxt "model:cashbook.open_lines,name:"
|
|||
msgid "Open Cashbook"
|
||||
msgstr "Kassenbuch öffnen"
|
||||
|
||||
msgctxt "wizard_button:cashbook.open_lines,start,end:"
|
||||
msgctxt "wizard_button:cashbook.open_lines,askuser,end:"
|
||||
msgid "Cancel"
|
||||
msgstr "Abbruch"
|
||||
|
||||
msgctxt "wizard_button:cashbook.open_lines,start,open_:"
|
||||
msgctxt "wizard_button:cashbook.open_lines,askuser,open_:"
|
||||
msgid "Open"
|
||||
msgstr "Öffnen"
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ full copyright notices and license terms. -->
|
|||
<field name="text">Invalid value of the field 'Status', allowed: open, closed, archive.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_book_deny_delete">
|
||||
<field name="text">The cash book '%(bookname)s' cannot be deleted because it contains %(booklines)s lines and is not in the status 'Archive'.</field>
|
||||
<field name="text">The cashbook '%(bookname)s' cannot be deleted because it contains %(booklines)s lines and is not in the status 'Archive'.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_book_deny_write">
|
||||
<field name="text">The cash book '%(bookname)s' is '%(state_txt)s' and cannot be changed.</field>
|
||||
<field name="text">The cashbook '%(bookname)s' is '%(state_txt)s' and cannot be changed.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_line_deny_delete1">
|
||||
<field name="text">The cashbook line '%(linetxt)s' cannot be deleted because the Cashbook '%(bookname)s' is in state '%(bookstate)s'.</field>
|
||||
|
|
|
@ -8,6 +8,7 @@ from trytond.pool import Pool
|
|||
from trytond.transaction import Transaction
|
||||
from trytond.exceptions import UserError
|
||||
from datetime import date
|
||||
from decimal import Decimal
|
||||
|
||||
|
||||
class BookTestCase(ModuleTestCase):
|
||||
|
@ -20,13 +21,14 @@ class BookTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
|
||||
types = self.prep_type()
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
self.assertEqual(book.btype.rec_name, 'CAS - Cash')
|
||||
|
@ -39,18 +41,21 @@ class BookTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'test 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -67,18 +72,21 @@ class BookTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'test 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -97,18 +105,21 @@ class BookTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'test 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -125,13 +136,14 @@ class BookTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
|
||||
types = self.prep_type()
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
self.assertEqual(book.state, 'open')
|
||||
|
@ -188,18 +200,22 @@ class BookTestCase(ModuleTestCase):
|
|||
ResUser = pool.get('res.user')
|
||||
ResGroup = pool.get('res.group')
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
company = self.prep_company()
|
||||
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
|
||||
usr_lst = ResUser.create([{
|
||||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
|
@ -209,6 +225,8 @@ class BookTestCase(ModuleTestCase):
|
|||
'name': 'Fridas book',
|
||||
'owner': usr_lst[0].id,
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
}])
|
||||
self.assertEqual(book.rec_name, 'Fridas book'),
|
||||
self.assertEqual(book.owner.rec_name, 'Frida'),
|
||||
|
@ -245,9 +263,9 @@ class BookTestCase(ModuleTestCase):
|
|||
ResUser = pool.get('res.user')
|
||||
ResGroup = pool.get('res.group')
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
company = self.prep_company()
|
||||
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
|
||||
grp_reviewer, = ResGroup.create([{
|
||||
'name': 'Cashbook Reviewer',
|
||||
|
@ -257,10 +275,14 @@ class BookTestCase(ModuleTestCase):
|
|||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
'groups': [('add', [grp_cashbook.id, grp_reviewer.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
|
@ -272,6 +294,8 @@ class BookTestCase(ModuleTestCase):
|
|||
'name': 'Fridas book',
|
||||
'owner': usr_lst[0].id,
|
||||
'reviewer': grp_reviewer.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'btype': types.id,
|
||||
}])
|
||||
self.assertEqual(book.rec_name, 'Fridas book'),
|
||||
|
@ -301,9 +325,9 @@ class BookTestCase(ModuleTestCase):
|
|||
ResUser = pool.get('res.user')
|
||||
ResGroup = pool.get('res.group')
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
company = self.prep_company()
|
||||
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
|
||||
grp_observer, = ResGroup.create([{
|
||||
'name': 'Cashbook Observer',
|
||||
|
@ -313,10 +337,14 @@ class BookTestCase(ModuleTestCase):
|
|||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
'groups': [('add', [grp_cashbook.id, grp_observer.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
|
@ -328,6 +356,8 @@ class BookTestCase(ModuleTestCase):
|
|||
'name': 'Fridas book',
|
||||
'owner': usr_lst[0].id,
|
||||
'observer': grp_observer.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'btype': types.id,
|
||||
}])
|
||||
self.assertEqual(book.rec_name, 'Fridas book'),
|
||||
|
|
|
@ -7,7 +7,6 @@ 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):
|
||||
|
@ -21,12 +20,7 @@ class CategoryTestCase(ModuleTestCase):
|
|||
Company = pool.get('company.company')
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = Company.search([])
|
||||
if len(company) > 0:
|
||||
company = company[0]
|
||||
else :
|
||||
company = create_company(name='m-ds')
|
||||
|
||||
company = self.prep_company()
|
||||
category, = Category.create([{
|
||||
'company': company.id,
|
||||
'name': name,
|
||||
|
@ -40,7 +34,7 @@ class CategoryTestCase(ModuleTestCase):
|
|||
pool = Pool()
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
company = self.prep_company()
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
|
@ -73,7 +67,7 @@ class CategoryTestCase(ModuleTestCase):
|
|||
pool = Pool()
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
company = self.prep_company()
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
|
@ -100,7 +94,7 @@ class CategoryTestCase(ModuleTestCase):
|
|||
pool = Pool()
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
company = self.prep_company()
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
|
@ -126,7 +120,7 @@ class CategoryTestCase(ModuleTestCase):
|
|||
Account = pool.get('account.account')
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
company = create_company(name='m-ds')
|
||||
company = self.prep_company()
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
|
|
|
@ -7,6 +7,7 @@ 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
|
||||
from datetime import date
|
||||
|
||||
|
||||
|
@ -14,6 +15,18 @@ class ConfigTestCase(ModuleTestCase):
|
|||
'Test config type module'
|
||||
module = 'cashbook'
|
||||
|
||||
def prep_company(self):
|
||||
""" get/create company
|
||||
"""
|
||||
Company = Pool().get('company.company')
|
||||
|
||||
company = Company.search([])
|
||||
if len(company) > 0:
|
||||
company = company[0]
|
||||
else :
|
||||
company = create_company(name='m-ds')
|
||||
return company
|
||||
|
||||
@with_transaction()
|
||||
def test_config_create(self):
|
||||
""" create config
|
||||
|
|
|
@ -9,6 +9,7 @@ from trytond.transaction import Transaction
|
|||
from trytond.exceptions import UserError
|
||||
from datetime import date
|
||||
from unittest.mock import MagicMock
|
||||
from decimal import Decimal
|
||||
|
||||
|
||||
class LineTestCase(ModuleTestCase):
|
||||
|
@ -21,23 +22,28 @@ class LineTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Lines = pool.get('cashbook.line')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 5, 2),
|
||||
'description': 'Text 2',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -59,29 +65,62 @@ class LineTestCase(ModuleTestCase):
|
|||
self.assertEqual(Lines.search_count([('cashbook.state', '=', 'open')]), 2)
|
||||
self.assertEqual(Lines.search_count([('cashbook.state', '=', 'closed')]), 0)
|
||||
|
||||
# sorting: date -> state -> id
|
||||
self.assertEqual(len(book.lines), 2)
|
||||
self.assertEqual(book.lines[0].rec_name, '05/01/2022 Text 1')
|
||||
self.assertEqual(book.lines[0].state, 'edit')
|
||||
self.assertEqual(book.lines[1].rec_name, '05/02/2022 Text 2')
|
||||
self.assertEqual(book.lines[1].state, 'edit')
|
||||
|
||||
# set to same date
|
||||
Lines.write(*[
|
||||
list(book.lines),
|
||||
{
|
||||
'date': date(2022, 5, 1),
|
||||
}])
|
||||
# check again
|
||||
book, = Book.search([])
|
||||
self.assertEqual(book.lines[0].rec_name, '05/01/2022 Text 1')
|
||||
self.assertEqual(book.lines[0].state, 'edit')
|
||||
self.assertEqual(book.lines[1].rec_name, '05/01/2022 Text 2')
|
||||
self.assertEqual(book.lines[1].state, 'edit')
|
||||
|
||||
# set to 'check', will sort first
|
||||
Lines.wfcheck([book.lines[1]])
|
||||
book, = Book.search([])
|
||||
self.assertEqual(book.lines[0].rec_name, '05/01/2022 Text 2')
|
||||
self.assertEqual(book.lines[0].state, 'check')
|
||||
self.assertEqual(book.lines[1].rec_name, '05/01/2022 Text 1')
|
||||
self.assertEqual(book.lines[1].state, 'edit')
|
||||
|
||||
@with_transaction()
|
||||
def test_line_create_check_deny_write(self):
|
||||
""" create cashbook + line, 'close' book, write to line
|
||||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Line = pool.get('cashbook.line')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 6, 1),
|
||||
'description': 'Text 2',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -107,26 +146,31 @@ class LineTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Line = pool.get('cashbook.line')
|
||||
IrDate = pool.get('ir.date')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
IrDate.today = MagicMock(return_value=date(2022, 6, 1))
|
||||
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 6, 1),
|
||||
'description': 'Text 2',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -159,21 +203,125 @@ class LineTestCase(ModuleTestCase):
|
|||
|
||||
IrDate.today = MagicMock(return_value=date.today())
|
||||
|
||||
@with_transaction()
|
||||
def test_line_create_check_debit_credit(self):
|
||||
""" create cashbook + line, check calculation of debit/credit
|
||||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Line = pool.get('cashbook.line')
|
||||
Configuration = pool.get('cashbook.configuration')
|
||||
Category = pool.get('cashbook.category')
|
||||
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
company = self.prep_company()
|
||||
|
||||
category2, = Category.create([{
|
||||
'company': company.id,
|
||||
'name': 'Category',
|
||||
}])
|
||||
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Revenue',
|
||||
'category': category2.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 6, 1),
|
||||
'description': 'Expense',
|
||||
'category': category2.id,
|
||||
'bookingtype': 'out',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 6, 1),
|
||||
'description': 'Transfer from',
|
||||
'category': category2.id,
|
||||
'bookingtype': 'mvin',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 6, 1),
|
||||
'description': 'Transfer to',
|
||||
'category': category2.id,
|
||||
'bookingtype': 'mvout',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
self.assertEqual(book.state, 'open')
|
||||
self.assertEqual(len(book.lines), 4)
|
||||
|
||||
self.assertEqual(book.lines[0].amount, Decimal('1.0'))
|
||||
self.assertEqual(book.lines[0].bookingtype, 'in')
|
||||
self.assertEqual(book.lines[0].credit, Decimal('1.0'))
|
||||
self.assertEqual(book.lines[0].debit, Decimal('0.0'))
|
||||
|
||||
self.assertEqual(book.lines[1].amount, Decimal('1.0'))
|
||||
self.assertEqual(book.lines[1].bookingtype, 'out')
|
||||
self.assertEqual(book.lines[1].credit, Decimal('0.0'))
|
||||
self.assertEqual(book.lines[1].debit, Decimal('1.0'))
|
||||
|
||||
self.assertEqual(book.lines[2].amount, Decimal('1.0'))
|
||||
self.assertEqual(book.lines[2].bookingtype, 'mvin')
|
||||
self.assertEqual(book.lines[2].credit, Decimal('1.0'))
|
||||
self.assertEqual(book.lines[2].debit, Decimal('0.0'))
|
||||
|
||||
self.assertEqual(book.lines[3].amount, Decimal('1.0'))
|
||||
self.assertEqual(book.lines[3].bookingtype, 'mvout')
|
||||
self.assertEqual(book.lines[3].credit, Decimal('0.0'))
|
||||
self.assertEqual(book.lines[3].debit, Decimal('1.0'))
|
||||
|
||||
Line.write(*[
|
||||
[book.lines[0]],
|
||||
{
|
||||
'amount': Decimal('2.0'),
|
||||
}])
|
||||
self.assertEqual(book.lines[0].amount, Decimal('2.0'))
|
||||
self.assertEqual(book.lines[0].bookingtype, 'in')
|
||||
self.assertEqual(book.lines[0].credit, Decimal('2.0'))
|
||||
self.assertEqual(book.lines[0].debit, Decimal('0.0'))
|
||||
|
||||
Line.write(*[
|
||||
[book.lines[0]],
|
||||
{
|
||||
'bookingtype': 'out',
|
||||
}])
|
||||
self.assertEqual(book.lines[0].amount, Decimal('2.0'))
|
||||
self.assertEqual(book.lines[0].bookingtype, 'out')
|
||||
self.assertEqual(book.lines[0].credit, Decimal('0.0'))
|
||||
self.assertEqual(book.lines[0].debit, Decimal('2.0'))
|
||||
|
||||
Line.write(*[
|
||||
[book.lines[0]],
|
||||
{
|
||||
'bookingtype': 'mvin',
|
||||
'amount': Decimal('3.0'),
|
||||
}])
|
||||
self.assertEqual(book.lines[0].amount, Decimal('3.0'))
|
||||
self.assertEqual(book.lines[0].bookingtype, 'mvin')
|
||||
self.assertEqual(book.lines[0].credit, Decimal('3.0'))
|
||||
self.assertEqual(book.lines[0].debit, Decimal('0.0'))
|
||||
|
||||
@with_transaction()
|
||||
def test_line_create_check_category_view(self):
|
||||
""" create cashbook + line, check 'category_view'
|
||||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Line = pool.get('cashbook.line')
|
||||
Configuration = pool.get('cashbook.configuration')
|
||||
Category = pool.get('cashbook.category')
|
||||
Account = pool.get('account.account')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
company = category.company
|
||||
company = self.prep_company()
|
||||
|
||||
with Transaction().set_context({
|
||||
'company': company.id,
|
||||
|
@ -208,14 +356,20 @@ class LineTestCase(ModuleTestCase):
|
|||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category2.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 6, 1),
|
||||
'description': 'Text 2',
|
||||
'category': category2.childs[0].id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -257,23 +411,28 @@ class LineTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Lines = pool.get('cashbook.line')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 5, 2),
|
||||
'description': 'Text 2',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -288,23 +447,28 @@ class LineTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Lines = pool.get('cashbook.line')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 5, 2),
|
||||
'description': 'Text 2',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -324,23 +488,28 @@ class LineTestCase(ModuleTestCase):
|
|||
"""
|
||||
pool = Pool()
|
||||
Book = pool.get('cashbook.book')
|
||||
Types = pool.get('cashbook.type')
|
||||
Lines = pool.get('cashbook.line')
|
||||
|
||||
types, = Types.search([('short', '=','CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
|
||||
company = self.prep_company()
|
||||
book, = Book.create([{
|
||||
'name': 'Book 1',
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Text 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}, {
|
||||
'date': date(2022, 5, 2),
|
||||
'description': 'Text 2',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.name, 'Book 1')
|
||||
|
@ -365,19 +534,23 @@ class LineTestCase(ModuleTestCase):
|
|||
ResGroup = pool.get('res.group')
|
||||
Book = pool.get('cashbook.book')
|
||||
Line = pool.get('cashbook.line')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
company = self.prep_company()
|
||||
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
|
||||
usr_lst = ResUser.create([{
|
||||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
|
@ -387,10 +560,14 @@ class LineTestCase(ModuleTestCase):
|
|||
'name': 'Fridas book',
|
||||
'owner': usr_lst[0].id,
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Test 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.rec_name, 'Fridas book'),
|
||||
|
@ -427,10 +604,10 @@ class LineTestCase(ModuleTestCase):
|
|||
ResGroup = pool.get('res.group')
|
||||
Book = pool.get('cashbook.book')
|
||||
Line = pool.get('cashbook.line')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
company = self.prep_company()
|
||||
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
|
||||
grp_reviewer, = ResGroup.create([{
|
||||
'name': 'Cashbook Reviewer',
|
||||
|
@ -440,10 +617,14 @@ class LineTestCase(ModuleTestCase):
|
|||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
'groups': [('add', [grp_cashbook.id, grp_reviewer.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
|
@ -456,10 +637,14 @@ class LineTestCase(ModuleTestCase):
|
|||
'owner': usr_lst[0].id,
|
||||
'reviewer': grp_reviewer.id,
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Test 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.rec_name, 'Fridas book'),
|
||||
|
@ -503,10 +688,10 @@ class LineTestCase(ModuleTestCase):
|
|||
ResGroup = pool.get('res.group')
|
||||
Book = pool.get('cashbook.book')
|
||||
Line = pool.get('cashbook.line')
|
||||
Types = pool.get('cashbook.type')
|
||||
|
||||
types, = Types.search([('short', '=', 'CAS')])
|
||||
types = self.prep_type()
|
||||
category = self.prep_category()
|
||||
company = self.prep_company()
|
||||
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
|
||||
grp_observer, = ResGroup.create([{
|
||||
'name': 'Cashbook Observer',
|
||||
|
@ -516,10 +701,14 @@ class LineTestCase(ModuleTestCase):
|
|||
'login': 'frida',
|
||||
'name': 'Frida',
|
||||
'groups': [('add', [grp_cashbook.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}, {
|
||||
'login': 'diego',
|
||||
'name': 'Diego',
|
||||
'groups': [('add', [grp_cashbook.id, grp_observer.id])],
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(len(usr_lst), 2)
|
||||
self.assertEqual(usr_lst[0].name, 'Frida')
|
||||
|
@ -532,10 +721,14 @@ class LineTestCase(ModuleTestCase):
|
|||
'owner': usr_lst[0].id,
|
||||
'observer': grp_observer.id,
|
||||
'btype': types.id,
|
||||
'company': company.id,
|
||||
'currency': company.currency.id,
|
||||
'lines': [('create', [{
|
||||
'date': date(2022, 5, 1),
|
||||
'description': 'Test 1',
|
||||
'category': category.id,
|
||||
'bookingtype': 'in',
|
||||
'amount': Decimal('1.0'),
|
||||
}])],
|
||||
}])
|
||||
self.assertEqual(book.rec_name, 'Fridas book'),
|
||||
|
|
|
@ -13,17 +13,20 @@ class TypeTestCase(ModuleTestCase):
|
|||
'Test cashbook type module'
|
||||
module = 'cashbook'
|
||||
|
||||
@with_transaction()
|
||||
def test_type_read_existing(self):
|
||||
""" read predefined types
|
||||
def prep_type(self, name='Cash', short='CAS'):
|
||||
""" create book-type
|
||||
"""
|
||||
AccType = Pool().get('cashbook.type')
|
||||
|
||||
t_lst = AccType.search([], order=[('name', 'ASC')])
|
||||
self.assertEqual(len(t_lst), 3)
|
||||
self.assertEqual(t_lst[0].rec_name, 'CAS - Cash')
|
||||
self.assertEqual(t_lst[1].rec_name, 'FTD - Fixed-term deposit')
|
||||
self.assertEqual(t_lst[2].rec_name, 'GIR - Giro')
|
||||
company = self.prep_company()
|
||||
at, = AccType.create([{
|
||||
'name': name,
|
||||
'short': short,
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(at.name, name)
|
||||
self.assertEqual(at.short, short)
|
||||
return at
|
||||
|
||||
@with_transaction()
|
||||
def test_type_create(self):
|
||||
|
@ -31,9 +34,12 @@ class TypeTestCase(ModuleTestCase):
|
|||
"""
|
||||
AccType = Pool().get('cashbook.type')
|
||||
|
||||
company = self.prep_company()
|
||||
|
||||
at, = AccType.create([{
|
||||
'name': 'Test 1',
|
||||
'short': 'T1',
|
||||
'company': company.id,
|
||||
}])
|
||||
self.assertEqual(at.name, 'Test 1')
|
||||
self.assertEqual(at.short, 'T1')
|
||||
|
@ -45,6 +51,7 @@ class TypeTestCase(ModuleTestCase):
|
|||
[{
|
||||
'name': 'Test 2',
|
||||
'short': 'T1',
|
||||
'company': company.id,
|
||||
}])
|
||||
|
||||
# end TypeTestCase
|
||||
|
|
|
@ -3,6 +3,7 @@ version=6.0.0
|
|||
depends:
|
||||
res
|
||||
account
|
||||
currency
|
||||
xml:
|
||||
icon.xml
|
||||
group.xml
|
||||
|
|
7
types.py
7
types.py
|
@ -4,6 +4,7 @@
|
|||
# full copyright notices and license terms.
|
||||
|
||||
from trytond.model import ModelView, ModelSQL, fields, Unique
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class Type(ModelSQL, ModelView):
|
||||
|
@ -12,6 +13,8 @@ class Type(ModelSQL, ModelView):
|
|||
|
||||
name = fields.Char(string='Name', required=True, translate=True)
|
||||
short = fields.Char(string='Abbreviation', required=True, size=3)
|
||||
company = fields.Many2One(string='Company', model_name='company.company',
|
||||
required=True, ondelete="RESTRICT")
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
|
@ -39,4 +42,8 @@ class Type(ModelSQL, ModelView):
|
|||
('short',) + tuple(clause[1:]),
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def default_company():
|
||||
return Transaction().context.get('company') or None
|
||||
|
||||
# end Type
|
||||
|
|
21
types.xml
21
types.xml
|
@ -63,18 +63,17 @@ full copyright notices and license terms. -->
|
|||
<field name="perm_delete" eval="False"/>
|
||||
</record>
|
||||
|
||||
<!-- defaults -->
|
||||
<record model="cashbook.type" id="atype_cash">
|
||||
<field name="short">CAS</field>
|
||||
<field name="name">Cash</field>
|
||||
<record model="ir.rule.group" id="rg_type_companies">
|
||||
<field name="name">User in companies</field>
|
||||
<field name="model"
|
||||
search="[('model', '=', 'cashbook.type')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="cashbook.type" id="atype_giro">
|
||||
<field name="short">GIR</field>
|
||||
<field name="name">Giro</field>
|
||||
</record>
|
||||
<record model="cashbook.type" id="atype_fixtermdep">
|
||||
<field name="short">FTD</field>
|
||||
<field name="name">Fixed-term deposit</field>
|
||||
<record model="ir.rule" id="r_type_companies">
|
||||
<field name="domain"
|
||||
eval="[('company', 'in', Eval('companies', []))]"
|
||||
pyson="1"/>
|
||||
<field name="rule_group" ref="rg_type_companies"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -8,9 +8,10 @@ full copyright notices and license terms. -->
|
|||
<label name="btype"/>
|
||||
<field name="btype"/>
|
||||
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<label name="account"/>
|
||||
<field name="account"/>
|
||||
<newline/>
|
||||
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
|
|
|
@ -5,6 +5,7 @@ full copyright notices and license terms. -->
|
|||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="btype"/>
|
||||
<field name="currency"/>
|
||||
<field name="account"/>
|
||||
<field name="owner"/>
|
||||
<field name="reviewer"/>
|
||||
|
|
|
@ -7,8 +7,7 @@ full copyright notices and license terms. -->
|
|||
<separator name="state" colspan="2" string="State"/>
|
||||
|
||||
<field name="cashbook" colspan="2"/>
|
||||
<label name="date"/>
|
||||
<field name="date"/>
|
||||
<label id="lab1" string=" " colspan="2"/>
|
||||
|
||||
<field name="state"/>
|
||||
<group id="grpstate" col="2">
|
||||
|
@ -16,10 +15,17 @@ full copyright notices and license terms. -->
|
|||
<button name="wfcheck"/>
|
||||
</group>
|
||||
|
||||
<label name="date"/>
|
||||
<field name="date"/>
|
||||
<label name="category"/>
|
||||
<field name="category"/>
|
||||
<newline/>
|
||||
|
||||
<label name="bookingtype"/>
|
||||
<field name="bookingtype"/>
|
||||
<label name="amount"/>
|
||||
<field name="amount" symbol="currency"/>
|
||||
|
||||
<group name="description" colspan="4" col="1" string="Description">
|
||||
<field name="description"/>
|
||||
</group>
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
The COPYRIGHT file at the top level of this repository contains the
|
||||
full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="cashbook"/>
|
||||
<field name="cashbook" tree_invisible="1"/>
|
||||
<field name="date"/>
|
||||
<field name="category_view"/>
|
||||
<field name="description"/>
|
||||
<field name="description" expand="1"/>
|
||||
<field name="credit" sum="Credit"/>
|
||||
<field name="debit" sum="Debit"/>
|
||||
<field name="currency"/>
|
||||
<field name="state"/>
|
||||
<button name="wfedit"/>
|
||||
<button name="wfcheck"/>
|
||||
|
|
|
@ -82,6 +82,10 @@ class OpenCashBook(Wizard):
|
|||
Configuration = pool.get('cashbook.configuration')
|
||||
|
||||
cfg1 = Configuration.get_singleton()
|
||||
if cfg1 is None:
|
||||
cfg1 = Configuration()
|
||||
cfg1.save()
|
||||
|
||||
book = getattr(self.askuser, 'cashbook', None)
|
||||
if book is None:
|
||||
with Transaction().set_context({
|
||||
|
|
Loading…
Reference in a new issue