line: reiter für monate, kategorie + test

This commit is contained in:
Frederik Jaeckel 2022-08-09 17:37:37 +02:00
parent d6a8b254a3
commit a23407f515
9 changed files with 333 additions and 3 deletions

53
line.py
View file

@ -10,6 +10,8 @@ from trytond.transaction import Transaction
from trytond.report import Report from trytond.report import Report
from trytond.exceptions import UserError from trytond.exceptions import UserError
from trytond.i18n import gettext from trytond.i18n import gettext
from sql import Cast, Literal
from sql.functions import DatePart
from .book import sel_state_book from .book import sel_state_book
@ -121,7 +123,12 @@ class Line(Workflow, ModelSQL, ModelView):
model_name='cashbook.book', ondelete='CASCADE', readonly=True) model_name='cashbook.book', ondelete='CASCADE', readonly=True)
date = fields.Date(string='Date', required=True, select=True, date = fields.Date(string='Date', required=True, select=True,
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
description = fields.Char(string='Description', month = fields.Function(fields.Integer(string='Month', readonly=True),
'on_change_with_month', searcher='search_month')
description = fields.Text(string='Description',
states=STATES, depends=DEPENDS)
category = fields.Many2One(string='Category', required=True,
model_name='cashbook.category', ondelete='RESTRICT',
states=STATES, depends=DEPENDS) states=STATES, depends=DEPENDS)
state = fields.Selection(string='State', required=True, readonly=True, state = fields.Selection(string='State', required=True, readonly=True,
select=True, selection=sel_linetype) select=True, selection=sel_linetype)
@ -220,6 +227,35 @@ class Line(Workflow, ModelSQL, ModelView):
""" """
return [('description',) + tuple(clause[1:])] return [('description',) + tuple(clause[1:])]
@fields.depends('date')
def on_change_with_month(self, name=None):
""" get difference of month to current date
"""
IrDate = Pool().get('ir.date')
if self.date is not None:
dt1 = IrDate.today()
return (12 * dt1.year + dt1.month) - \
(12 * self.date.year + self.date.month)
@classmethod
def search_month(cls, names, clause):
""" search in month
"""
pool = Pool()
Line = pool.get('cashbook.line')
IrDate = pool.get('ir.date')
tab_line = Line.__table__()
Operator = fields.SQL_OPERATORS[clause[1]]
dt1 = IrDate.today()
query = tab_line.select(tab_line.id,
where=Operator(
Literal(12 * dt1.year + dt1.month) - \
(Literal(12) * DatePart('year', tab_line.date) + DatePart('month', tab_line.date)),
clause[2]),
)
return [('id', 'in', query)]
@fields.depends('cashbook', '_parent_cashbook.state') @fields.depends('cashbook', '_parent_cashbook.state')
def on_change_with_state_cashbook(self, name=None): def on_change_with_state_cashbook(self, name=None):
""" get state of cashbook """ get state of cashbook
@ -233,6 +269,21 @@ class Line(Workflow, ModelSQL, ModelView):
""" """
return [('cashbook.state',) + tuple(clause[1:])] return [('cashbook.state',) + tuple(clause[1:])]
@classmethod
def write(cls, *args):
""" deny update if cashbook.line!='open'
"""
actions = iter(args)
for lines, values in zip(actions, actions):
for line in lines:
if line.cashbook.state != 'open':
raise UserError(gettext(
'cashbook.msg_book_deny_write',
bookname = line.cashbook.rec_name,
state_txt = line.cashbook.state_string,
))
super(Line, cls).write(*args)
@classmethod @classmethod
def delete(cls, lines): def delete(cls, lines):
""" deny delete if book is not 'open' or wf is not 'edit' """ deny delete if book is not 'open' or wf is not 'edit'

View file

@ -54,6 +54,28 @@ full copyright notices and license terms. -->
<field name="act_window" ref="act_line_view"/> <field name="act_window" ref="act_line_view"/>
</record> </record>
<!-- domain view -->
<record model="ir.action.act_window.domain" id="act_line_domain_current">
<field name="name">Current Month</field>
<field name="sequence" eval="10"/>
<field name="domain" eval="[('month', '=', 0)]" pyson="1"/>
<field name="count" eval="True"/>
<field name="act_window" ref="act_line_view"/>
</record>
<record model="ir.action.act_window.domain" id="act_line_domain_last">
<field name="name">Last Month</field>
<field name="sequence" eval="20"/>
<field name="domain" eval="[('month', '=', 1)]" pyson="1"/>
<field name="count" eval="True"/>
<field name="act_window" ref="act_line_view"/>
</record>
<record model="ir.action.act_window.domain" id="act_line_domain_all">
<field name="name">All</field>
<field name="sequence" eval="999"/>
<field name="domain"/>
<field name="act_window" ref="act_line_view"/>
</record>
<!-- permission --> <!-- permission -->
<!-- anon: deny all --> <!-- anon: deny all -->
<record model="ir.model.access" id="access_line-anon"> <record model="ir.model.access" id="access_line-anon">

View file

@ -242,6 +242,10 @@ msgctxt "view:cashbook.line:"
msgid "Cashbook Line" msgid "Cashbook Line"
msgstr "Kassenbuchzeile" msgstr "Kassenbuchzeile"
msgctxt "view:cashbook.line:"
msgid "Description"
msgstr "Beschreibung"
msgctxt "view:cashbook.line:" msgctxt "view:cashbook.line:"
msgid "State" msgid "State"
msgstr "Status" msgstr "Status"
@ -274,6 +278,26 @@ msgctxt "selection:cashbook.line,state:"
msgid "Done" msgid "Done"
msgstr "Fertig" msgstr "Fertig"
msgctxt "field:cashbook.line,month:"
msgid "Month"
msgstr "Monat"
msgctxt "field:cashbook.line,category:"
msgid "Category"
msgstr "Kategorie"
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"
################# #################
# cashbook.type # # cashbook.type #

View file

@ -38,6 +38,10 @@ msgctxt "model:ir.message,text:msg_setting_already_exists"
msgid "Settings for this user alredy exists." msgid "Settings for this user alredy exists."
msgstr "Settings for this user alredy exists." msgstr "Settings for this user alredy exists."
msgctxt "model:ir.message,text:msg_category_name_unique"
msgid "The category name already exists at this level."
msgstr "The category name already exists at this level."
msgctxt "model:res.group,name:group_cashbook" msgctxt "model:res.group,name:group_cashbook"
msgid "Cashbook" msgid "Cashbook"
msgstr "Cashbook" msgstr "Cashbook"
@ -90,6 +94,14 @@ msgctxt "model:ir.ui.menu,name:menu_open_lines"
msgid "Open Cashbook" msgid "Open Cashbook"
msgstr "Open Cashbook" msgstr "Open Cashbook"
msgctxt "model:ir.ui.menu,name:menu_category"
msgid "Category"
msgstr "Category"
msgctxt "model:ir.ui.menu,name:menu_category_list"
msgid "Category"
msgstr "Category"
msgctxt "model:ir.action,name:act_book_view" msgctxt "model:ir.action,name:act_book_view"
msgid "Account" msgid "Account"
msgstr "Account" msgstr "Account"
@ -106,6 +118,10 @@ msgctxt "model:ir.action,name:act_open_lines"
msgid "Open Cashbook" msgid "Open Cashbook"
msgstr "Open Cashbook" msgstr "Open Cashbook"
msgctxt "model:ir.ui.menu,name:act_category_view"
msgid "Category"
msgstr "Category"
msgctxt "model:ir.model.button,string:line_wfedit_button" msgctxt "model:ir.model.button,string:line_wfedit_button"
msgid "Edit" msgid "Edit"
msgstr "Edit" msgstr "Edit"
@ -182,6 +198,10 @@ msgctxt "help:cashbook.book,observer:"
msgid "Group of users who have read-only access to the cashbook." msgid "Group of users who have read-only access to the cashbook."
msgstr "Group of users who have read-only access to the cashbook." msgstr "Group of users who have read-only access to the cashbook."
msgctxt "field:cashbook.book,account:"
msgid "Account"
msgstr "Account"
msgctxt "model:cashbook.line,name:" msgctxt "model:cashbook.line,name:"
msgid "Cashbook Line" msgid "Cashbook Line"
msgstr "Cashbook Line" msgstr "Cashbook Line"
@ -222,6 +242,22 @@ msgctxt "selection:cashbook.line,state:"
msgid "Done" msgid "Done"
msgstr "Done" msgstr "Done"
msgctxt "field:cashbook.line,month:"
msgid "Month"
msgstr "Month"
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_current"
msgid "Current Month"
msgstr "Current Month"
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_last"
msgid "Last Month"
msgstr "Last Month"
msgctxt "model:ir.action.act_window.domain,name:act_line_domain_all"
msgid "All"
msgstr "All"
msgctxt "model:cashbook.type,name:" msgctxt "model:cashbook.type,name:"
msgid "Cashbook Type" msgid "Cashbook Type"
msgstr "Cashbook Type" msgstr "Cashbook Type"
@ -246,6 +282,54 @@ msgctxt "model:cashbook.type,name:atype_fixtermdep"
msgid "Fixed-term deposit" msgid "Fixed-term deposit"
msgstr "Fixed-term deposit" msgstr "Fixed-term deposit"
msgctxt "model:cashbook.category,name:"
msgid "Category"
msgstr "Category"
msgctxt "view:cashbook.category:"
msgid "General Information"
msgstr "General Information"
msgctxt "view:cashbook.category:"
msgid "Children"
msgstr "Children"
msgctxt "field:cashbook.category,name:"
msgid "Name"
msgstr "Name"
msgctxt "field:cashbook.category,description:"
msgid "Description"
msgstr "Description"
msgctxt "field:cashbook.category,account:"
msgid "Account"
msgstr "Account"
msgctxt "field:cashbook.category,account_code:"
msgid "Account"
msgstr "Account"
msgctxt "field:cashbook.category,company:"
msgid "Company"
msgstr "Company"
msgctxt "field:cashbook.category,parent:"
msgid "Parent"
msgstr "Parent"
msgctxt "field:cashbook.category,childs:"
msgid "Children"
msgstr "Children"
msgctxt "field:cashbook.category,left:"
msgid "Left"
msgstr "Left"
msgctxt "field:cashbook.category,right:"
msgid "Right"
msgstr "Right"
msgctxt "model:cashbook.open_lines.start,name:" msgctxt "model:cashbook.open_lines.start,name:"
msgid "Open Cashbook" msgid "Open Cashbook"
msgstr "Open Cashbook" msgstr "Open Cashbook"

View file

@ -42,6 +42,7 @@ class BookTestCase(ModuleTestCase):
Types = pool.get('cashbook.type') Types = pool.get('cashbook.type')
types, = Types.search([('short', '=', 'CAS')]) types, = Types.search([('short', '=', 'CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -49,6 +50,7 @@ class BookTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'test 1', 'description': 'test 1',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')
@ -68,6 +70,7 @@ class BookTestCase(ModuleTestCase):
Types = pool.get('cashbook.type') Types = pool.get('cashbook.type')
types, = Types.search([('short', '=', 'CAS')]) types, = Types.search([('short', '=', 'CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -75,6 +78,7 @@ class BookTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'test 1', 'description': 'test 1',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')
@ -96,6 +100,7 @@ class BookTestCase(ModuleTestCase):
Types = pool.get('cashbook.type') Types = pool.get('cashbook.type')
types, = Types.search([('short', '=', 'CAS')]) types, = Types.search([('short', '=', 'CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -103,6 +108,7 @@ class BookTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'test 1', 'description': 'test 1',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')

View file

@ -14,6 +14,25 @@ class CategoryTestCase(ModuleTestCase):
'Test cashbook categoy module' 'Test cashbook categoy module'
module = 'cashbook' module = 'cashbook'
def prep_category(self, name='Cat1'):
""" create category
"""
pool = Pool()
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')
category, = Category.create([{
'company': company.id,
'name': name,
}])
return category
@with_transaction() @with_transaction()
def test_category_create_nodupl_at_root(self): def test_category_create_nodupl_at_root(self):
""" create category, duplicates are allowed at root-level """ create category, duplicates are allowed at root-level

View file

@ -8,6 +8,7 @@ from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.exceptions import UserError from trytond.exceptions import UserError
from datetime import date from datetime import date
from unittest.mock import MagicMock
class LineTestCase(ModuleTestCase): class LineTestCase(ModuleTestCase):
@ -24,6 +25,7 @@ class LineTestCase(ModuleTestCase):
Lines = pool.get('cashbook.line') Lines = pool.get('cashbook.line')
types, = Types.search([('short', '=','CAS')]) types, = Types.search([('short', '=','CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -31,9 +33,11 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Text 1', 'description': 'Text 1',
'category': category.id,
}, { }, {
'date': date(2022, 5, 2), 'date': date(2022, 5, 2),
'description': 'Text 2', 'description': 'Text 2',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')
@ -55,6 +59,106 @@ class LineTestCase(ModuleTestCase):
self.assertEqual(Lines.search_count([('cashbook.state', '=', 'open')]), 2) self.assertEqual(Lines.search_count([('cashbook.state', '=', 'open')]), 2)
self.assertEqual(Lines.search_count([('cashbook.state', '=', 'closed')]), 0) self.assertEqual(Lines.search_count([('cashbook.state', '=', 'closed')]), 0)
@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')])
category = self.prep_category()
book, = Book.create([{
'name': 'Book 1',
'btype': types.id,
'lines': [('create', [{
'date': date(2022, 5, 1),
'description': 'Text 1',
'category': category.id,
}, {
'date': date(2022, 6, 1),
'description': 'Text 2',
'category': category.id,
}])],
}])
self.assertEqual(book.name, 'Book 1')
self.assertEqual(book.state, 'open')
self.assertEqual(len(book.lines), 2)
Book.wfclosed([book])
self.assertEqual(book.state, 'closed')
self.assertRaisesRegex(UserError,
"The cash book 'Book 1' is 'Closed' and cannot be changed.",
Line.write,
*[
[book.lines[0]],
{
'description': 'should be denied',
},
])
@with_transaction()
def test_line_create_check_month(self):
""" create cashbook + line, check 'month' + search
"""
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')])
category = self.prep_category()
IrDate.today = MagicMock(return_value=date(2022, 6, 1))
book, = Book.create([{
'name': 'Book 1',
'btype': types.id,
'lines': [('create', [{
'date': date(2022, 5, 1),
'description': 'Text 1',
'category': category.id,
}, {
'date': date(2022, 6, 1),
'description': 'Text 2',
'category': category.id,
}])],
}])
self.assertEqual(book.name, 'Book 1')
self.assertEqual(book.state, 'open')
self.assertEqual(len(book.lines), 2)
self.assertEqual(book.lines[0].date, date(2022, 5, 1))
self.assertEqual(book.lines[0].month, 1)
self.assertEqual(book.lines[1].date, date(2022, 6, 1))
self.assertEqual(book.lines[1].month, 0)
l1, = Line.search([('month', '=', 0)])
self.assertEqual(l1.date, date(2022, 6, 1))
l1, = Line.search([('month', '=', 1)])
self.assertEqual(l1.date, date(2022, 5, 1))
IrDate.today = MagicMock(return_value=date(2022, 6, 30))
l1, = Line.search([('month', '=', 0)])
self.assertEqual(l1.date, date(2022, 6, 1))
l1, = Line.search([('month', '=', 1)])
self.assertEqual(l1.date, date(2022, 5, 1))
self.assertEqual(Line.search_count([('month', '=', 2)]), 0)
IrDate.today = MagicMock(return_value=date(2022, 7, 1))
self.assertEqual(Line.search_count([('month', '=', 0)]), 0)
l1, = Line.search([('month', '=', 1)])
self.assertEqual(l1.date, date(2022, 6, 1))
IrDate.today = MagicMock(return_value=date.today())
@with_transaction() @with_transaction()
def test_line_delete_with_book_in_open_state(self): def test_line_delete_with_book_in_open_state(self):
""" create cashbook + line, book in state=open, delete a line """ create cashbook + line, book in state=open, delete a line
@ -65,6 +169,7 @@ class LineTestCase(ModuleTestCase):
Lines = pool.get('cashbook.line') Lines = pool.get('cashbook.line')
types, = Types.search([('short', '=','CAS')]) types, = Types.search([('short', '=','CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -72,9 +177,11 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Text 1', 'description': 'Text 1',
'category': category.id,
}, { }, {
'date': date(2022, 5, 2), 'date': date(2022, 5, 2),
'description': 'Text 2', 'description': 'Text 2',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')
@ -93,6 +200,7 @@ class LineTestCase(ModuleTestCase):
Lines = pool.get('cashbook.line') Lines = pool.get('cashbook.line')
types, = Types.search([('short', '=','CAS')]) types, = Types.search([('short', '=','CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -100,9 +208,11 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Text 1', 'description': 'Text 1',
'category': category.id,
}, { }, {
'date': date(2022, 5, 2), 'date': date(2022, 5, 2),
'description': 'Text 2', 'description': 'Text 2',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')
@ -126,6 +236,7 @@ class LineTestCase(ModuleTestCase):
Lines = pool.get('cashbook.line') Lines = pool.get('cashbook.line')
types, = Types.search([('short', '=','CAS')]) types, = Types.search([('short', '=','CAS')])
category = self.prep_category()
book, = Book.create([{ book, = Book.create([{
'name': 'Book 1', 'name': 'Book 1',
@ -133,9 +244,11 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Text 1', 'description': 'Text 1',
'category': category.id,
}, { }, {
'date': date(2022, 5, 2), 'date': date(2022, 5, 2),
'description': 'Text 2', 'description': 'Text 2',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.name, 'Book 1') self.assertEqual(book.name, 'Book 1')
@ -163,6 +276,7 @@ class LineTestCase(ModuleTestCase):
Types = pool.get('cashbook.type') Types = pool.get('cashbook.type')
types, = Types.search([('short', '=', 'CAS')]) types, = Types.search([('short', '=', 'CAS')])
category = self.prep_category()
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')]) grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
usr_lst = ResUser.create([{ usr_lst = ResUser.create([{
'login': 'frida', 'login': 'frida',
@ -184,6 +298,7 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Test 1', 'description': 'Test 1',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.rec_name, 'Fridas book'), self.assertEqual(book.rec_name, 'Fridas book'),
@ -223,6 +338,7 @@ class LineTestCase(ModuleTestCase):
Types = pool.get('cashbook.type') Types = pool.get('cashbook.type')
types, = Types.search([('short', '=', 'CAS')]) types, = Types.search([('short', '=', 'CAS')])
category = self.prep_category()
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')]) grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
grp_reviewer, = ResGroup.create([{ grp_reviewer, = ResGroup.create([{
'name': 'Cashbook Reviewer', 'name': 'Cashbook Reviewer',
@ -251,6 +367,7 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Test 1', 'description': 'Test 1',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.rec_name, 'Fridas book'), self.assertEqual(book.rec_name, 'Fridas book'),
@ -297,6 +414,7 @@ class LineTestCase(ModuleTestCase):
Types = pool.get('cashbook.type') Types = pool.get('cashbook.type')
types, = Types.search([('short', '=', 'CAS')]) types, = Types.search([('short', '=', 'CAS')])
category = self.prep_category()
grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')]) grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')])
grp_observer, = ResGroup.create([{ grp_observer, = ResGroup.create([{
'name': 'Cashbook Observer', 'name': 'Cashbook Observer',
@ -325,6 +443,7 @@ class LineTestCase(ModuleTestCase):
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 5, 1), 'date': date(2022, 5, 1),
'description': 'Test 1', 'description': 'Test 1',
'category': category.id,
}])], }])],
}]) }])
self.assertEqual(book.rec_name, 'Fridas book'), self.assertEqual(book.rec_name, 'Fridas book'),

View file

@ -16,7 +16,11 @@ full copyright notices and license terms. -->
<button name="wfcheck"/> <button name="wfcheck"/>
</group> </group>
<label name="description"/> <label name="category"/>
<field name="description" colspan="3"/> <field name="category"/>
<newline/>
<group name="description" colspan="4" col="1" string="Description">
<field name="description"/>
</group>
</form> </form>

View file

@ -5,6 +5,7 @@ full copyright notices and license terms. -->
<tree> <tree>
<field name="cashbook"/> <field name="cashbook"/>
<field name="date"/> <field name="date"/>
<field name="category"/>
<field name="description"/> <field name="description"/>
<field name="state"/> <field name="state"/>
<button name="wfedit"/> <button name="wfedit"/>