# -*- 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 ReconTestCase(ModuleTestCase): 'Test cashbook reconciliation module' module = 'cashbook' @with_transaction() def test_recon_check_overlap(self): """ create, check deny of overlap date """ pool = Pool() Book = pool.get('cashbook.book') Reconciliation = pool.get('cashbook.recon') types = self.prep_type() category = self.prep_category(cattype='in') company = self.prep_company() book, = Book.create([{ 'name': 'Book 1', 'btype': types.id, 'company': company.id, 'currency': company.currency.id, }]) recon1, = Reconciliation.create([{ 'date': date(2022, 5, 1), 'date_from': date(2022, 5, 1), 'date_to': date(2022, 5, 31), 'cashbook': book.id, }]) self.assertEqual(recon1.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]') recon2, = Reconciliation.create([{ 'date': date(2022, 6, 1), 'date_from': date(2022, 6, 1), 'date_to': date(2022, 6, 30), 'cashbook': book.id, }]) self.assertEqual(recon2.rec_name, '06/01/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]') # same day for end of '0' and start of '1' Reconciliation.write(*[ [recon2], { 'date_from': date(2022, 5, 31), }, ]) self.assertEqual(recon1.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]') self.assertEqual(recon2.rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]') # 'date_from' inside of other record self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.write, *[ [recon2], { 'date_from': date(2022, 5, 30), }, ]) # 'date_from' inside of other record self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.write, *[ [recon2], { 'date_from': date(2022, 5, 2), }, ]) # 'date_from' same date_from like other record self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.write, *[ [recon2], { 'date_from': date(2022, 5, 1), }, ]) # enclose other record self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.write, *[ [recon2], { 'date_from': date(2022, 4, 30), }, ]) # within other record self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.write, *[ [recon2], { 'date_from': date(2022, 5, 2), 'date_to': date(2022, 5, 12), }, ]) # from after to self.assertRaisesRegex(UserError, 'The value for field "Start Date" in "Cashbook Reconciliation" is not valid according to its domain.', Reconciliation.write, *[ [recon2], { 'date_from': date(2022, 4, 15), 'date_to': date(2022, 4, 10), }, ]) # 'date_to' at 'date_from' of other record - allowed Reconciliation.write(*[ [recon2], { 'date_from': date(2022, 4, 15), 'date_to': date(2022, 5, 1), }]) # 'date_to' after other date_from self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.write, *[ [recon2], { 'date_to': date(2022, 5, 2), }, ]) # overlap at create self.assertRaisesRegex(UserError, 'The date range overlaps with another reconciliation.', Reconciliation.create, [{ 'date': date(2022, 5, 1), 'date_from': date(2022, 4, 1), 'date_to': date(2022, 4, 16), 'cashbook': book.id, }]) recon3, = Reconciliation.create([{ 'date': date(2022, 4, 17), 'date_from': date(2022, 4, 1), 'date_to': date(2022, 4, 15), 'cashbook': book.id, }]) self.assertEqual(recon1.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]') self.assertEqual(recon2.rec_name, '04/15/2022 - 05/01/2022 | 0.00 usd - 0.00 usd [0]') self.assertEqual(recon3.rec_name, '04/01/2022 - 04/15/2022 | 0.00 usd - 0.00 usd [0]') @with_transaction() def test_recon_create_check_line_add_to_recon(self): """ create, booklines, add reconciliation """ pool = Pool() Book = pool.get('cashbook.book') Lines = pool.get('cashbook.line') Reconciliation = pool.get('cashbook.recon') types = self.prep_type() category = self.prep_category(cattype='in') 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, 5), 'description': 'Text 2', 'category': category.id, 'bookingtype': 'in', 'amount': Decimal('1.0'), }])], 'reconciliations': [('create', [{ 'date': date(2022, 5, 28), 'date_from': date(2022, 5, 1), 'date_to': date(2022, 5, 31), }])], }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') self.assertEqual(len(book.lines), 2) self.assertEqual(book.lines[0].rec_name, '05/01/2022|1.00 usd|Text 1 [Cat1]') self.assertEqual(book.lines[1].rec_name, '05/05/2022|1.00 usd|Text 2 [Cat1]') self.assertEqual(len(book.reconciliations), 1) self.assertEqual(book.reconciliations[0].rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]') self.assertEqual(len(book.reconciliations[0].lines), 0) self.assertRaisesRegex(UserError, "For reconciliation, the line '05/01/2022|1.00 usd|Text 1 [Cat1]' must be in the status 'Check' or 'Done'.", Lines.write, *[ [book.lines[0]], { 'reconciliation': book.reconciliations[0].id, } ]) Lines.wfcheck(book.lines) Lines.write(*[ list(book.lines), { 'reconciliation': book.reconciliations[0].id, }]) self.assertEqual(len(book.reconciliations[0].lines), 2) self.assertRaisesRegex(UserError, "The status cannot be changed to 'Edit' as long as the line '05/01/2022|1.00 usd|Text 1 [Cat1]' is associated with a reconciliation.", Lines.wfedit, [book.lines[0]]) @with_transaction() def test_recon_check_deny_delete(self): """ create, booklines, reconciliation, try delete """ pool = Pool() Book = pool.get('cashbook.book') Lines = pool.get('cashbook.line') Reconciliation = pool.get('cashbook.recon') types = self.prep_type() category = self.prep_category(cattype='in') 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'), }])], 'reconciliations': [('create', [{ 'date': date(2022, 5, 28), 'date_from': date(2022, 5, 1), 'date_to': date(2022, 5, 31), }])], }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') Lines.wfcheck(list(book.lines)) Reconciliation.wfcheck(list(book.reconciliations)) self.assertEqual(len(book.reconciliations), 1) self.assertEqual(len(book.reconciliations[0].lines), 1) self.assertRaisesRegex(UserError, "The reconciliation '05/01/2022 - 05/31/2022 | 0.00 - 0.00 usd [0]' cannot be deleted, its in state 'Check'.", Reconciliation.delete, list(book.reconciliations)) Book.wfclosed([book]) self.assertRaisesRegex(UserError, "The cashbook line '05/01/2022 - 05/31/2022: 0.00 usd' cannot be deleted because the Cashbook 'Book 1 | 1.00 usd | Closed' is in state 'Closed'.", Reconciliation.delete, list(book.reconciliations)) self.assertRaisesRegex(UserError, "The cash book 'Book 1 | 1.00 usd | Closed' is 'Closed' and cannot be changed.", Reconciliation.write, *[ list(book.reconciliations), { 'date': date(2022, 5, 29), }, ]) @with_transaction() def test_recon_check_wf_edit_to_check(self): """ create, booklines, add reconciliation """ pool = Pool() Book = pool.get('cashbook.book') Lines = pool.get('cashbook.line') Reconciliation = pool.get('cashbook.recon') types = self.prep_type() category = self.prep_category(cattype='in') 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, 5), 'description': 'Text 2', 'category': category.id, 'bookingtype': 'in', 'amount': Decimal('1.0'), }])], 'reconciliations': [('create', [{ 'date': date(2022, 5, 28), 'date_from': date(2022, 5, 1), 'date_to': date(2022, 5, 31), }])], }]) self.assertEqual(book.name, 'Book 1') self.assertEqual(book.state, 'open') self.assertEqual(len(book.lines), 2) self.assertEqual(book.lines[0].rec_name, '05/01/2022|1.00 usd|Text 1 [Cat1]') self.assertEqual(book.lines[1].rec_name, '05/05/2022|1.00 usd|Text 2 [Cat1]') self.assertEqual(book.lines[0].reconciliation, None) self.assertEqual(book.lines[1].reconciliation, None) self.assertEqual(len(book.reconciliations), 1) self.assertEqual(book.reconciliations[0].rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]') self.assertEqual(len(book.reconciliations[0].lines), 0) # run wf, fail with lines not 'checked' self.assertRaisesRegex(UserError, "For the reconciliation '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]' of the cashbook 'Book 1 | 2.00 usd | Open', all lines in the date range from '05/01/2022' to '05/31/2022' must be in the 'Check' state.", Reconciliation.wfcheck, list(book.reconciliations), ) # edit --> check Lines.wfcheck(book.lines) Reconciliation.wfcheck(list(book.reconciliations)) self.assertEqual(len(book.reconciliations[0].lines), 2) self.assertEqual(book.lines[0].reconciliation.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [2]') self.assertEqual(book.lines[1].reconciliation.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [2]') # check --> edit Reconciliation.wfedit(list(book.reconciliations)) self.assertEqual(len(book.reconciliations[0].lines), 0) self.assertEqual(book.lines[0].reconciliation, None) self.assertEqual(book.lines[1].reconciliation, None) # end ReconTestCase