forked from Mapan/odoo17e
245 lines
15 KiB
Python
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',
|
|
}])
|