Previously a task was created to prevent holes between bank statement, meaning that starting balance should always be the same as previous ending balance. The goal was that during synchronization or imports, we could add statement lines in previous statement and not have to recompute manually the full chain of starting and ending balance of next statements entries. This works fine with online synchronization as we always write after creating the statements the balance of the account on the latest statements to detect missing stmts, however if we create stmts by hand, it is possible that we have the following case: Statement on 10 January with a starting and ending balance of 100 and 200 respectively. We are missing 2 statements with a line of 50 each before that date. So we create the first missing statement at date: 8 January with a starting balance 0 and ending balance 50, this will recompute the starting and ending balance of next statement and overwrite the values to 50 and 150 (starting and ending balance respectively). At that time the system will say that everything is normal but we are still missing a stmt and we are not seeing it. The way to fix this is by not touching the ending balance of the last stmt entry during the computation, that way we can still detect that there is an error and that 50€ are still missing. closes odoo/odoo#48000 X-original-commit: b97b4f4217989e8cae5c32be0d62c11d36eaf1d7 Signed-off-by: Cedric Snauwaert (csn) <csn@openerp.com>
245 lines
12 KiB
Python
245 lines
12 KiB
Python
from odoo.addons.account.tests.common import AccountTestCommon
|
|
from odoo.tests import tagged
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestBankStatement(AccountTestCommon):
|
|
|
|
def setUp(self):
|
|
super(TestBankStatement, self).setUp()
|
|
self.bs_model = self.env['account.bank.statement']
|
|
self.bsl_model = self.env['account.bank.statement.line']
|
|
self.partner = self.env['res.partner'].create({'name': 'test'})
|
|
self.journal = self.env['account.journal'].create({
|
|
'name': 'BnkJournal',
|
|
'type': 'bank'
|
|
})
|
|
self.journal2 = self.env['account.journal'].create({
|
|
'name': 'BnkJournal2',
|
|
'type': 'bank'
|
|
})
|
|
self.cashjournal = self.env['account.journal'].create({
|
|
'name': 'CashJournal',
|
|
'type': 'cash'
|
|
})
|
|
self.number = 1
|
|
|
|
def create_bank_statement(self, date, line_amount, balance_end_real=False, journal=False):
|
|
vals = {
|
|
'name': 'BNK' + str(self.number),
|
|
'date': date,
|
|
'line_ids': [(0, 0, {
|
|
'name': '_',
|
|
'amount': line_amount,
|
|
})],
|
|
'journal_id': journal or self.journal.id
|
|
}
|
|
if balance_end_real:
|
|
vals['balance_end_real'] = balance_end_real
|
|
self.number += 1
|
|
return self.bs_model.create(vals)
|
|
|
|
def test_compute_balance_end_real_with_lines(self):
|
|
bnk1 = self.create_bank_statement('2019-01-02', 100)
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
# Balance is automatically computed when creating statement with the lines
|
|
self.assertEqual(bnk1.balance_end_real, 100)
|
|
self.assertEqual(bnk1.balance_end, 100)
|
|
|
|
def test_compute_balance_end_real_without_lines(self):
|
|
vals = {
|
|
'name': 'BNK' + str(self.number),
|
|
'date': '2019-01-01',
|
|
'journal_id': self.journal.id
|
|
}
|
|
bnk1 = self.bs_model.create(vals)
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
self.assertEqual(bnk1.balance_end_real, 0)
|
|
self.assertEqual(bnk1.balance_end, 0)
|
|
# Add a line
|
|
self.bsl_model.create({
|
|
'name': '_',
|
|
'amount': 10,
|
|
'statement_id': bnk1.id
|
|
})
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
# balance_end_real should not have changed
|
|
self.assertEqual(bnk1.balance_end_real, 0)
|
|
# Compute balance should have been computed
|
|
self.assertEqual(bnk1.balance_end, 10)
|
|
|
|
def test_create_new_statement(self):
|
|
# Create first statement on 1/1/2019
|
|
bnk1 = self.create_bank_statement('2019-01-02', 100)
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
# Balance is automatically computed when creating statement with the lines
|
|
self.assertEqual(bnk1.balance_end_real, 100)
|
|
self.assertEqual(bnk1.balance_end, 100)
|
|
self.assertEqual(bnk1.previous_statement_id.id, False)
|
|
|
|
# Create a new statement after that one
|
|
bnk2 = self.create_bank_statement('2019-01-10', 50)
|
|
self.assertEqual(bnk2.balance_start, 100)
|
|
self.assertEqual(bnk2.balance_end_real, 150)
|
|
self.assertEqual(bnk2.balance_end, 150)
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk1.id)
|
|
|
|
# Create new statement with given ending balance
|
|
bnk3 = self.create_bank_statement('2019-01-15', 25, 200)
|
|
self.assertEqual(bnk3.balance_end_real, 200)
|
|
self.assertEqual(bnk3.balance_start, 150)
|
|
self.assertEqual(bnk3.balance_end, 175)
|
|
self.assertEqual(bnk3.previous_statement_id.id, bnk2.id)
|
|
|
|
bnk4 = self.create_bank_statement('2019-01-03', 100)
|
|
self.assertEqual(bnk4.balance_start, 100)
|
|
self.assertEqual(bnk4.balance_end_real, 200)
|
|
self.assertEqual(bnk4.balance_end, 200)
|
|
self.assertEqual(bnk4.previous_statement_id.id, bnk1.id)
|
|
# Bnk2 should have changed its previous statement
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk4.id)
|
|
# The starting balance and balance_end_real should have been recomputed
|
|
self.assertEqual(bnk2.balance_start, 200)
|
|
self.assertEqual(bnk2.balance_end_real, 250)
|
|
self.assertEqual(bnk2.balance_end, 250)
|
|
# The starting balance and balance_end_real of next entries should also have been recomputed
|
|
# and since we are propagating an update, the balance_end_real should have been recomputed to
|
|
# the correct value
|
|
self.assertEqual(bnk3.balance_start, 250)
|
|
self.assertEqual(bnk3.balance_end_real, 200) # This should not have been recomputed as this is the last of the chain
|
|
self.assertEqual(bnk3.balance_end, 275)
|
|
bnk3.balance_end_real = 275 # Correct ending balance
|
|
|
|
# Change date of bank stmt4 to be the last
|
|
self.assertEqual(bnk4.balance_end_real, 200) #Check balance before moving it to the last
|
|
bnk4.date = '2019-01-20'
|
|
self.assertEqual(bnk1.previous_statement_id.id, False)
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk1.id)
|
|
self.assertEqual(bnk3.previous_statement_id.id, bnk2.id)
|
|
self.assertEqual(bnk4.previous_statement_id.id, bnk3.id)
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
self.assertEqual(bnk2.balance_start, 100)
|
|
self.assertEqual(bnk3.balance_start, 150)
|
|
self.assertEqual(bnk4.balance_start, 175)
|
|
self.assertEqual(bnk1.balance_end_real, 100)
|
|
self.assertEqual(bnk2.balance_end_real, 150)
|
|
self.assertEqual(bnk3.balance_end_real, 175)
|
|
self.assertEqual(bnk4.balance_end_real, 200) # This should not have change
|
|
bnk4.balance_end_real = 275 # Correct ending balance
|
|
|
|
# Move bnk3 to first position
|
|
bnk3.date = '2019-01-01'
|
|
self.assertEqual(bnk3.previous_statement_id.id, False)
|
|
self.assertEqual(bnk1.previous_statement_id.id, bnk3.id)
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk1.id)
|
|
self.assertEqual(bnk4.previous_statement_id.id, bnk2.id)
|
|
self.assertEqual(bnk3.balance_start, 0)
|
|
self.assertEqual(bnk1.balance_start, 25)
|
|
self.assertEqual(bnk2.balance_start, 125)
|
|
self.assertEqual(bnk4.balance_start, 175)
|
|
self.assertEqual(bnk3.balance_end_real, 25)
|
|
self.assertEqual(bnk1.balance_end_real, 125)
|
|
self.assertEqual(bnk2.balance_end_real, 175)
|
|
self.assertEqual(bnk4.balance_end_real, 275)
|
|
|
|
# Change bnk1 and bnk2
|
|
bnk1.date = '2019-01-11'
|
|
self.assertEqual(bnk3.previous_statement_id.id, False)
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk3.id)
|
|
self.assertEqual(bnk1.previous_statement_id.id, bnk2.id)
|
|
self.assertEqual(bnk4.previous_statement_id.id, bnk1.id)
|
|
self.assertEqual(bnk3.balance_start, 0)
|
|
self.assertEqual(bnk2.balance_start, 25)
|
|
self.assertEqual(bnk1.balance_start, 75)
|
|
self.assertEqual(bnk4.balance_start, 175)
|
|
self.assertEqual(bnk3.balance_end_real, 25)
|
|
self.assertEqual(bnk2.balance_end_real, 75)
|
|
self.assertEqual(bnk1.balance_end_real, 175)
|
|
self.assertEqual(bnk4.balance_end_real, 275)
|
|
|
|
def test_create_statements_in_different_journal(self):
|
|
# Bank statement create in two different journal should not link with each other
|
|
bnk1 = self.create_bank_statement('2019-01-01', 100, 100)
|
|
bnk2 = self.create_bank_statement('2019-01-10', 50)
|
|
|
|
bnk1other = self.create_bank_statement('2019-01-02', 20, 20, self.journal2.id)
|
|
bnk2other = self.create_bank_statement('2019-01-12', 10, False, self.journal2.id)
|
|
|
|
self.assertEqual(bnk1.previous_statement_id.id, False)
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk1.id)
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
self.assertEqual(bnk2.balance_start, 100)
|
|
self.assertEqual(bnk2.balance_end_real, 150)
|
|
|
|
self.assertEqual(bnk1other.previous_statement_id.id, False)
|
|
self.assertEqual(bnk2other.previous_statement_id.id, bnk1other.id)
|
|
self.assertEqual(bnk1other.balance_start, 0)
|
|
self.assertEqual(bnk2other.balance_start, 20)
|
|
self.assertEqual(bnk2other.balance_end_real, 30)
|
|
|
|
def test_statement_cash_journal(self):
|
|
# Entry in cash journal should not recompute the balance_end_real
|
|
cash1 = self.create_bank_statement('2019-01-01', 100, 100, self.cashjournal.id)
|
|
cash2 = self.create_bank_statement('2019-01-03', 100, False, self.cashjournal.id)
|
|
self.assertEqual(cash1.balance_start, 0)
|
|
self.assertEqual(cash1.balance_end_real, 100)
|
|
self.assertEqual(cash2.balance_start, 100)
|
|
self.assertEqual(cash2.balance_end_real, 0)
|
|
cash2.balance_end_real = 1000
|
|
self.assertEqual(cash2.balance_end_real, 1000)
|
|
# add cash entry in between, should recompute starting balance of cash2 entry but not ending balance
|
|
cash3 = self.create_bank_statement('2019-01-02', 100, 200, self.cashjournal.id)
|
|
self.assertEqual(cash3.balance_start, 100)
|
|
self.assertEqual(cash3.balance_end_real, 200)
|
|
self.assertEqual(cash2.balance_start, 200)
|
|
self.assertEqual(cash2.balance_end_real, 1000)
|
|
|
|
def test_is_valid_balance_start(self):
|
|
bnk1 = self.create_bank_statement('2019-01-01', 100, 100.0000001)
|
|
bnk2 = self.create_bank_statement('2019-01-10', 50)
|
|
bnk2.write({'balance_start': 100})
|
|
self.assertTrue(bnk2.is_valid_balance_start)
|
|
bnk2.write({'balance_start': 100.01})
|
|
self.assertFalse(bnk2.is_valid_balance_start)
|
|
|
|
def test_unlink_bank_statement(self):
|
|
bnk1 = self.create_bank_statement('2019-01-02', 100)
|
|
bnk2 = self.create_bank_statement('2019-01-10', 50)
|
|
bnk3 = self.create_bank_statement('2019-01-15', 25)
|
|
bnk4 = self.create_bank_statement('2019-01-21', 100)
|
|
bnk5 = self.create_bank_statement('2019-01-22', 100)
|
|
self.assertEqual(bnk1.previous_statement_id.id, False)
|
|
self.assertEqual(bnk2.previous_statement_id.id, bnk1.id)
|
|
self.assertEqual(bnk3.previous_statement_id.id, bnk2.id)
|
|
self.assertEqual(bnk4.previous_statement_id.id, bnk3.id)
|
|
self.assertEqual(bnk5.previous_statement_id.id, bnk4.id)
|
|
self.assertEqual(bnk1.balance_start, 0)
|
|
self.assertEqual(bnk1.balance_end_real, 100)
|
|
self.assertEqual(bnk2.balance_start, 100)
|
|
self.assertEqual(bnk2.balance_end_real, 150)
|
|
self.assertEqual(bnk3.balance_start, 150)
|
|
self.assertEqual(bnk3.balance_end_real, 175)
|
|
self.assertEqual(bnk4.balance_start, 175)
|
|
self.assertEqual(bnk4.balance_end_real, 275)
|
|
self.assertEqual(bnk5.balance_start, 275)
|
|
self.assertEqual(bnk5.balance_end_real, 375)
|
|
|
|
# Delete bnk2 and check that previous_statement_id and balance are correct
|
|
bnk2.unlink()
|
|
self.assertEqual(bnk1.previous_statement_id.id, False)
|
|
self.assertEqual(bnk3.previous_statement_id.id, bnk1.id)
|
|
self.assertEqual(bnk4.previous_statement_id.id, bnk3.id)
|
|
self.assertEqual(bnk5.previous_statement_id.id, bnk4.id)
|
|
self.assertEqual(bnk3.balance_start, 100)
|
|
self.assertEqual(bnk3.balance_end_real, 125)
|
|
self.assertEqual(bnk4.balance_start, 125)
|
|
self.assertEqual(bnk4.balance_end_real, 225)
|
|
self.assertEqual(bnk5.balance_start, 225)
|
|
self.assertEqual(bnk5.balance_end_real, 375) # Ending balance of last statement should not have changed
|
|
|
|
# Delete bnk1 bnk3 and bnk4 at the same time and check that balance are correct
|
|
(bnk1 + bnk3 + bnk4).unlink()
|
|
self.assertEqual(bnk5.previous_statement_id.id, False)
|
|
self.assertEqual(bnk5.balance_start, 0)
|
|
self.assertEqual(bnk5.balance_end_real, 375) # Ending balance of last statement should not have changed
|