# -*- 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 from decimal import Decimal class BookTestCase(ModuleTestCase): 'Test cashbook book module' module = 'cashbook' def prep_sequence(self, name='Book Sequ'): """ create numbering-equence """ pool = Pool() IrSequence = pool.get('ir.sequence') IrSequType = pool.get('ir.sequence.type') sequ_type, = IrSequType.search([('name', '=', 'Cashbook Line')]) sequ = IrSequence.search([('name', '=', name)]) if len(sequ) > 0: return sequ[0] sequ, = IrSequence.create([{ 'name': name, 'sequence_type': sequ_type.id, }]) return sequ @with_transaction() def test_book_create(self): """ create cashbook """ pool = Pool() Book = pool.get('cashbook.book') types = self.prep_type() company = self.prep_company() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.btype.rec_name, 'CAS - Cash') self.assertEqual(book.state, 'open') self.assertEqual(book.state_string, 'Open') @with_transaction() def test_book_deny_delete_open(self): """ create cashbook, add lines, try to delete in state 'open' """ pool = Pool() Book = pool.get('cashbook.book') types = self.prep_type() category = self.prep_category(cattype='in') company = self.prep_company() party = self.prep_party() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2022, 5, 1), 'lines': [('create', [{ 'date': date(2022, 5, 1), 'description': 'test 1', 'category': category.id, 'bookingtype': 'in', 'amount': Decimal('1.0'), 'party': party.id, }])], }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') self.assertRaisesRegex(UserError, "The cashbook 'Book 1 | 1.00 usd | Open' cannot be deleted because it contains 1 lines and is not in the status 'Archive'.", Book.delete, [book]) @with_transaction() def test_book_deny_delete_closed(self): """ create cashbook, add lines, try to delete in state 'closed' """ pool = Pool() Book = pool.get('cashbook.book') types = self.prep_type() category = self.prep_category(cattype='in') company = self.prep_company() party = self.prep_party() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2022, 5, 1), 'lines': [('create', [{ 'date': date(2022, 5, 1), 'description': 'test 1', 'category': category.id, 'bookingtype': 'in', 'amount': Decimal('1.0'), 'party': party.id, }])], }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') Book.wfclosed([book]) self.assertEqual(book.state, 'closed') self.assertRaisesRegex(UserError, "The cashbook 'Book 1 | 1.00 usd | Closed' cannot be deleted because it contains 1 lines and is not in the status 'Archive'.", Book.delete, [book]) @with_transaction() def test_book_deny_delete_archive(self): """ create cashbook, add lines, try to delete in state 'archive' """ pool = Pool() Book = pool.get('cashbook.book') types = self.prep_type() category = self.prep_category(cattype='in') company = self.prep_company() party = self.prep_party() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2022, 5, 1), 'lines': [('create', [{ 'date': date(2022, 5, 1), 'description': 'test 1', 'category': category.id, 'bookingtype': 'in', 'amount': Decimal('1.0'), 'party': party.id, }])], }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') Book.wfclosed([book]) Book.wfarchive([book]) self.assertEqual(book.state, 'archive') Book.delete([book]) @with_transaction() def test_book_deny_update_1(self): """ create cashbook, try to update in states open, closed, archive """ pool = Pool() Book = pool.get('cashbook.book') types = self.prep_type() company = self.prep_company() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') Book.write(*[ [book], { 'name': 'Book 1a', }]) self.assertEqual(book.name, 'Book 1a') # wf: open --> closed Book.wfclosed([book]) self.assertEqual(book.state, 'closed') self.assertRaisesRegex(UserError, "The cash book 'Book 1a | 1.00 usd | Closed' is 'Closed' and cannot be changed.", Book.write, *[ [book], { 'name': 'Book 1b', }, ]) Book.wfopen([book]) self.assertEqual(book.state, 'open') Book.write(*[ [book], { 'name': 'Book 1c', }]) self.assertEqual(book.name, 'Book 1c') Book.wfclosed([book]) Book.wfarchive([book]) self.assertRaisesRegex(UserError, "The cash book 'Book 1c | 0.00 usd | Archive' is 'Archive' and cannot be changed.", Book.write, *[ [book], { 'name': 'Book 1d', }, ]) @with_transaction() def test_book_deny_update_start_amount(self): """ create cashbook, add lines, update start-amount """ pool = Pool() Book = pool.get('cashbook.book') types = self.prep_type() company = self.prep_company() category = self.prep_category(cattype='in') party = self.prep_party() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.start_balance, Decimal('0.0')) self.assertEqual(book.rec_name, 'Book 1 | 0.00 usd | Open') Book.write(*[ [book], { 'start_balance': Decimal('1.0'), }]) self.assertEqual(book.start_balance, Decimal('1.0')) self.assertEqual(book.balance, Decimal('1.0')) Book.write(*[ [book], { 'lines': [('create', [{ 'amount': Decimal('2.0'), 'description': 'Test', 'category': category.id, 'bookingtype': 'in', 'party': party.id, }])], }]) self.assertEqual(book.start_balance, Decimal('1.0')) self.assertEqual(book.balance, Decimal('3.0')) self.assertEqual(len(book.lines), 1) self.assertEqual(book.lines[0].balance, Decimal('3.0')) self.assertRaisesRegex(UserError, "The initial amount of the cash book 'Fridas book | 3.00 usd | Open' cannot be changed because it already contains bookings.", Book.write, *[ [book], { 'start_balance': Decimal('1.5'), }, ]) @with_transaction() def test_book_permission_owner(self): """ create book + 2x users, add users to group, check access """ pool = Pool() ResUser = pool.get('res.user') ResGroup = pool.get('res.group') Book = pool.get('cashbook.book') 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') self.assertEqual(usr_lst[1].name, 'Diego') book, = Book.create([{ 'name': 'Fridas book', 'owner': usr_lst[0].id, 'btype': types.id, 'company': company.id, 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, }]) self.assertEqual(book.rec_name, 'Fridas book | 0.00 usd | Open'), self.assertEqual(book.owner.rec_name, 'Frida'), with Transaction().set_context({ '_check_access': True, }): # change to user 'diego' , try access with Transaction().set_user(usr_lst[1].id): books = Book.search([]) self.assertEqual(len(books), 0) # change to user 'frida' read/write book with Transaction().set_user(usr_lst[0].id): books = Book.search([]) self.assertEqual(len(books), 1) self.assertEqual(books[0].rec_name, 'Fridas book | 0.00 usd | Open') self.assertRaisesRegex(UserError, 'You are not allowed to access "Cashbook.Name".', Book.write, *[ books, { 'name': 'Book2', }, ]) @with_transaction() def test_book_permission_reviewer(self): """ create book + 2x users + 1x reviewer-group, add users to group, check access """ pool = Pool() ResUser = pool.get('res.user') ResGroup = pool.get('res.group') Book = pool.get('cashbook.book') types = self.prep_type() company = self.prep_company() grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')]) grp_reviewer, = ResGroup.create([{ 'name': 'Cashbook Reviewer', }]) 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, grp_reviewer.id])], 'companies': [('add', [company.id])], 'company': company.id, }]) self.assertEqual(len(usr_lst), 2) self.assertEqual(usr_lst[0].name, 'Frida') self.assertEqual(usr_lst[1].name, 'Diego') # create cashbook # add reviewer-group to allow read for users in group book, = Book.create([{ 'name': 'Fridas book', 'owner': usr_lst[0].id, 'reviewer': grp_reviewer.id, 'company': company.id, 'currency': company.currency.id, 'btype': types.id, 'number_sequ': self.prep_sequence().id, }]) self.assertEqual(book.rec_name, 'Fridas book | 0.00 usd | Open'), self.assertEqual(book.owner.rec_name, 'Frida'), with Transaction().set_context({ '_check_access': True, }): # change to user 'diego' , try access with Transaction().set_user(usr_lst[1].id): books = Book.search([]) self.assertEqual(len(books), 1) self.assertEqual(len(books[0].reviewer.users), 1) self.assertEqual(books[0].reviewer.users[0].rec_name, 'Diego') # change to user 'frida' read/write book with Transaction().set_user(usr_lst[0].id): books = Book.search([]) self.assertEqual(len(books), 1) self.assertEqual(books[0].rec_name, 'Fridas book | 0.00 usd | Open') @with_transaction() def test_book_permission_observer(self): """ create book + 2x users + 1x observer-group, add users to group, check access """ pool = Pool() ResUser = pool.get('res.user') ResGroup = pool.get('res.group') Book = pool.get('cashbook.book') types = self.prep_type() company = self.prep_company() grp_cashbook, = ResGroup.search([('name', '=', 'Cashbook')]) grp_observer, = ResGroup.create([{ 'name': 'Cashbook Observer', }]) 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, grp_observer.id])], 'companies': [('add', [company.id])], 'company': company.id, }]) self.assertEqual(len(usr_lst), 2) self.assertEqual(usr_lst[0].name, 'Frida') self.assertEqual(usr_lst[1].name, 'Diego') # create cashbook # add observer-group to allow read for users in group book, = Book.create([{ 'name': 'Fridas book', 'owner': usr_lst[0].id, 'observer': grp_observer.id, 'company': company.id, 'currency': company.currency.id, 'btype': types.id, 'number_sequ': self.prep_sequence().id, }]) self.assertEqual(book.rec_name, 'Fridas book | 0.00 usd | Open'), self.assertEqual(book.owner.rec_name, 'Frida'), with Transaction().set_context({ '_check_access': True, }): # change to user 'diego' , try access with Transaction().set_user(usr_lst[1].id): books = Book.search([]) self.assertEqual(len(books), 1) self.assertEqual(len(books[0].observer.users), 1) self.assertEqual(books[0].observer.users[0].rec_name, 'Diego') # change to user 'frida' read/write book with Transaction().set_user(usr_lst[0].id): books = Book.search([]) self.assertEqual(len(books), 1) self.assertEqual(books[0].rec_name, 'Fridas book | 0.00 usd | Open') # end BookTestCase