1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/account_accountant/tests/test_account_auto_reconcile_wizard.py
2024-12-10 09:04:09 +07:00

245 lines
15 KiB
Python

from odoo import fields
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.exceptions import UserError
from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestAccountAutoReconcileWizard(AccountTestInvoicingCommon):
""" Tests the account automatic reconciliation and its wizard. """
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.comp_curr = cls.company_data['currency']
cls.foreign_curr = cls.currency_data['currency']
cls.misc_journal = cls.company_data['default_journal_misc']
cls.partners = cls.partner_a + cls.partner_b
cls.receivable_account = cls.company_data['default_account_receivable']
cls.payable_account = cls.company_data['default_account_payable']
cls.revenue_account = cls.company_data['default_account_revenue']
cls.test_date = fields.Date.from_string('2016-01-01')
def _create_many_lines(self):
self.line_1_group_1 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.line_2_group_1 = self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
self.line_3_group_1 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-03', partner=self.partner_a)
self.line_4_group_1 = self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-04', partner=self.partner_a)
self.line_5_group_1 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-05', partner=self.partner_a)
self.group_1 = self.line_1_group_1 + self.line_2_group_1 + self.line_3_group_1 + self.line_4_group_1 + self.line_5_group_1
self.line_1_group_2 = self.create_line_for_reconciliation(500.0, 500.0, self.comp_curr, '2016-01-01', partner=self.partner_b)
self.line_2_group_2 = self.create_line_for_reconciliation(-500.0, -500.0, self.comp_curr, '2016-01-01', partner=self.partner_b)
self.line_3_group_2 = self.create_line_for_reconciliation(500.0, 500.0, self.comp_curr, '2017-01-02', partner=self.partner_b)
self.line_4_group_2 = self.create_line_for_reconciliation(-500.0, -500.0, self.comp_curr, '2017-01-02', partner=self.partner_b)
self.group_2 = self.line_1_group_2 + self.line_2_group_2 + self.line_3_group_2 + self.line_4_group_2
self.line_1_group_3 = self.create_line_for_reconciliation(1500.0, 3000.0, self.foreign_curr, '2016-01-01', partner=self.partner_b)
self.line_2_group_3 = self.create_line_for_reconciliation(-1000.0, -3000.0, self.foreign_curr, '2017-01-01', partner=self.partner_b)
self.line_3_group_3 = self.create_line_for_reconciliation(3000.0, 3000.0, self.comp_curr, '2016-01-01', partner=self.partner_b)
self.line_4_group_3 = self.create_line_for_reconciliation(-3000.0, -3000.0, self.comp_curr, '2016-01-01', partner=self.partner_b)
self.group_3 = self.line_1_group_3 + self.line_2_group_3 + self.line_3_group_3 + self.line_4_group_3
self.line_1_group_4 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', account_1=self.payable_account, partner=self.partner_a)
self.line_2_group_4 = self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', account_1=self.payable_account, partner=self.partner_a)
self.group_4 = self.line_1_group_4 + self.line_2_group_4
def test_auto_reconcile_one_to_one(self):
self._create_many_lines()
should_be_reconciled = self.line_1_group_1 + self.line_2_group_1 + self.line_3_group_1 + self.line_4_group_1 \
+ self.line_1_group_2 + self.line_2_group_2 \
+ self.line_1_group_3 + self.line_2_group_3 + self.line_3_group_3 + self.line_4_group_3
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
'partner_ids': self.partners.ids,
'search_mode': 'one_to_one',
})
wizard.auto_reconcile()
self.assertTrue(should_be_reconciled.full_reconcile_id)
self.assertEqual(self.line_1_group_1.full_reconcile_id, self.line_2_group_1.full_reconcile_id,
"Entries should be reconciled together since they are in the same group and have closer dates.")
self.assertEqual(self.line_3_group_1.full_reconcile_id, self.line_4_group_1.full_reconcile_id,
"Entries should be reconciled together since they are in the same group and have closer dates.")
self.assertEqual(self.line_1_group_2.full_reconcile_id, self.line_1_group_2.full_reconcile_id,
"Entries should be reconciled together since they are in the same group and have closer dates.")
self.assertEqual(self.line_1_group_3.full_reconcile_id, self.line_2_group_3.full_reconcile_id,
"Entries should be reconciled together since they are in the same group and have closer dates.")
self.assertEqual(self.line_3_group_3.full_reconcile_id, self.line_4_group_3.full_reconcile_id,
"Entries should be reconciled together since they are in the same group and have closer dates.")
self.assertNotEqual(self.line_2_group_3.full_reconcile_id, self.line_3_group_3.full_reconcile_id,
"Entries should NOT be reconciled together as they are of different currencies.")
self.assertFalse(self.line_5_group_1.reconciled,
"This entry shouldn't be reconciled since group 1 has an odd number of lines, they can't all be reconciled, and it's the most recent one.")
self.assertFalse((self.line_3_group_2 + self.line_4_group_2).full_reconcile_id,
"Entries shouldn't be reconciled since it's outside of accepted date range of the wizard.")
self.assertFalse((self.line_1_group_4 + self.line_2_group_4).full_reconcile_id,
"Entries shouldn't be reconciled since their account is out of the wizard's scope.")
def test_auto_reconcile_zero_balance(self):
self._create_many_lines()
should_be_reconciled = self.line_1_group_2 + self.line_2_group_2 + self.group_3
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
'partner_ids': self.partners.ids,
'search_mode': 'zero_balance',
})
wizard.auto_reconcile()
self.assertTrue(should_be_reconciled.full_reconcile_id)
self.assertFalse(self.group_1.full_reconcile_id,
"Entries shouldn't be reconciled since their total balance is not zero.")
self.assertEqual((self.line_1_group_2 + self.line_2_group_2).mapped('matching_number'), [self.line_1_group_2.matching_number] * 2,
"Entries should be reconciled together as their total balance is zero.")
self.assertEqual((self.line_1_group_3 + self.line_2_group_3).mapped('matching_number'), [self.line_1_group_3.matching_number] * 2,
"Entries should be reconciled together as their total balance is zero with the same currency.")
self.assertEqual((self.line_3_group_3 + self.line_4_group_3).mapped('matching_number'), [self.line_3_group_3.matching_number] * 2,
"Lines 3 and 4 are reconciled but not with two first lines since their currency is different.")
self.assertFalse(self.group_4.full_reconcile_id,
"Entries shouldn't be reonciled since their account is out of the wizard's scope.")
def test_nothing_to_auto_reconcile(self):
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
'partner_ids': self.partners.ids,
'search_mode': 'zero_balance',
})
with self.assertRaises(UserError):
wizard.auto_reconcile()
def test_auto_reconcile_no_account_nor_partner_one_to_one(self):
self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
})
reconciled_amls = wizard._auto_reconcile_one_to_one()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_no_account_nor_partner_zero_balance(self):
self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
})
reconciled_amls = wizard._auto_reconcile_zero_balance()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_no_account_one_to_one(self):
self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'partner_ids': self.partners.ids,
})
reconciled_amls = wizard._auto_reconcile_one_to_one()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_no_account_zero_balance(self):
self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'partner_ids': self.partners.ids,
})
reconciled_amls = wizard._auto_reconcile_zero_balance()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_no_partner_one_to_one(self):
self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
})
reconciled_amls = wizard._auto_reconcile_one_to_one()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_no_partner_zero_balance(self):
self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
})
reconciled_amls = wizard._auto_reconcile_zero_balance()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_rounding_one_to_one(self):
""" Checks that two lines with different values, currency rounding aside, are reconciled in one-to-one mode. """
line_1 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
line_2 = self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
# Need to manually update the values to bypass ORM
self.env.cr.execute(
"""
UPDATE account_move_line SET amount_residual_currency = 1000.0000001 WHERE id = %(line_1_id)s;
UPDATE account_move_line SET amount_residual_currency = -999.999999 WHERE id = %(line_2_id)s;
""",
{'line_1_id': line_1.id, 'line_2_id': line_2.id}
)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
})
reconciled_amls = wizard._auto_reconcile_one_to_one()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_auto_reconcile_rounding_zero_balance(self):
""" Checks that two lines with different values, currency rounding aside, are reconciled in zero balance mode. """
line_1 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-01', partner=self.partner_a)
line_2 = self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-02', partner=self.partner_a)
# Need to manually update the values to bypass ORM
self.env.cr.execute(
"""
UPDATE account_move_line SET amount_residual_currency = 1000.0000001 WHERE id = %(line_1_id)s;
UPDATE account_move_line SET amount_residual_currency = -999.999999 WHERE id = %(line_2_id)s;
""",
{'line_1_id': line_1.id, 'line_2_id': line_2.id}
)
wizard = self.env['account.auto.reconcile.wizard'].new({
'from_date': '2016-01-01',
'to_date': '2017-01-01',
'account_ids': self.receivable_account.ids,
})
reconciled_amls = wizard._auto_reconcile_zero_balance()
self.assertTrue(reconciled_amls.full_reconcile_id)
def test_preset_wizard(self):
""" Tests that giving lines_ids to wizard presets correctly values. """
line_1 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-30', partner=self.partner_a)
line_2 = self.create_line_for_reconciliation(-1000.0, -1000.0, self.comp_curr, '2016-01-31', partner=self.partner_a)
wizard = self.env['account.auto.reconcile.wizard'].with_context(domain=[('id', 'in', (line_1 + line_2).ids)]).create({})
self.assertRecordValues(wizard, [{
'account_ids': self.receivable_account.ids,
'partner_ids': self.partner_a.ids,
'from_date': fields.Date.from_string('2016-01-30'),
'to_date': fields.Date.from_string('2016-01-31'),
'search_mode': 'zero_balance',
}])
line_3 = self.create_line_for_reconciliation(1000.0, 1000.0, self.comp_curr, '2016-01-31', partner=self.partner_a)
line_4 = self.create_line_for_reconciliation(-500.0, -500.0, self.comp_curr, '2016-02-28', partner=None)
wizard = self.env['account.auto.reconcile.wizard'].with_context(domain=[('id', 'in', (line_3 + line_4).ids)]).create({})
self.assertRecordValues(wizard, [{
'account_ids': self.receivable_account.ids,
'partner_ids': [],
'from_date': fields.Date.from_string('2016-01-31'),
'to_date': fields.Date.from_string('2016-02-28'),
'search_mode': 'one_to_one',
}])