mirror of
https://github.com/OCA/bank-statement-import.git
synced 2025-01-20 12:37:43 +02:00
[MIG] account_statement_import_online: Migration to 16.0
This commit is contained in:
committed by
Carolina Fernandez
parent
d905b32731
commit
2fc9b110bb
@@ -1,4 +1,3 @@
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import test_account_bank_statement_import_online
|
||||
from . import test_account_journal
|
||||
|
||||
@@ -29,10 +29,11 @@ class OnlineBankStatementProviderDummy(models.Model):
|
||||
line_step_options = self.env.context.get("step", {"minutes": 5})
|
||||
line_step = relativedelta(**line_step_options)
|
||||
expand_by = self.env.context.get("expand_by", 0)
|
||||
data_since = self.env.context.get("data_since", date_since)
|
||||
data_until = self.env.context.get("data_until", date_until)
|
||||
data_since -= expand_by * line_step
|
||||
data_until += expand_by * line_step
|
||||
# Override date_since and date_until from context.
|
||||
override_date_since = self.env.context.get("override_date_since", date_since)
|
||||
override_date_until = self.env.context.get("override_date_until", date_until)
|
||||
override_date_since -= expand_by * line_step
|
||||
override_date_until += expand_by * line_step
|
||||
|
||||
balance_start = self.env.context.get(
|
||||
"balance_start", randrange(-10000, 10000, 1) * 0.1
|
||||
@@ -46,8 +47,8 @@ class OnlineBankStatementProviderDummy(models.Model):
|
||||
timestamp_mode = self.env.context.get("timestamp_mode")
|
||||
|
||||
lines = []
|
||||
date = data_since
|
||||
while date < data_until:
|
||||
date = override_date_since
|
||||
while date < override_date_until:
|
||||
amount = self.env.context.get("amount", randrange(-100, 100, 1) * 0.1)
|
||||
transaction_date = date.replace(tzinfo=tz)
|
||||
if timestamp_mode == "date":
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
# Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com)
|
||||
# Copyright 2019-2020 Dataplug (https://dataplug.io)
|
||||
# Copyright 2022-2023 Therp BV (https://therp.nl)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
import logging
|
||||
from datetime import date, datetime
|
||||
from unittest import mock
|
||||
from urllib.error import HTTPError
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from odoo_test_helper import FakeModelLoader
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
from odoo import fields
|
||||
from odoo import _, fields
|
||||
from odoo.tests import common
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
mock_obtain_statement_data = (
|
||||
"odoo.addons.account_statement_import_online.tests."
|
||||
@@ -37,352 +38,131 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
cls.loader.update_registry((OnlineBankStatementProviderDummy,))
|
||||
|
||||
cls.now = fields.Datetime.now()
|
||||
cls.AccountAccount = cls.env["account.account"]
|
||||
cls.AccountJournal = cls.env["account.journal"]
|
||||
cls.OnlineBankStatementProvider = cls.env["online.bank.statement.provider"]
|
||||
cls.OnlineBankStatementPullWizard = cls.env["online.bank.statement.pull.wizard"]
|
||||
cls.AccountBankStatement = cls.env["account.bank.statement"]
|
||||
cls.AccountBankStatementLine = cls.env["account.bank.statement.line"]
|
||||
|
||||
def test_provider_unlink_restricted(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{"name": "Bank", "type": "bank", "code": "BANK"}
|
||||
cls.journal = cls.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
}
|
||||
)
|
||||
with common.Form(journal) as journal_form:
|
||||
journal_form.bank_statements_source = "online"
|
||||
journal_form.online_bank_statement_provider = "dummy"
|
||||
journal_form.save()
|
||||
|
||||
with self.assertRaises(IntegrityError), mute_logger("odoo.sql_db"):
|
||||
journal.online_bank_statement_provider_id.unlink()
|
||||
|
||||
def test_cascade_unlink(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{"name": "Bank", "type": "bank", "code": "BANK"}
|
||||
)
|
||||
with common.Form(journal) as journal_form:
|
||||
journal_form.bank_statements_source = "online"
|
||||
journal_form.online_bank_statement_provider = "dummy"
|
||||
journal_form.save()
|
||||
|
||||
self.assertTrue(journal.online_bank_statement_provider_id)
|
||||
save_provider_id = journal.online_bank_statement_provider_id.id
|
||||
journal.unlink()
|
||||
self.assertFalse(
|
||||
self.OnlineBankStatementProvider.search(
|
||||
[
|
||||
("id", "=", save_provider_id),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
def test_source_change_cleanup(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{"name": "Bank", "type": "bank", "code": "BANK"}
|
||||
)
|
||||
with common.Form(journal) as journal_form:
|
||||
journal_form.bank_statements_source = "online"
|
||||
journal_form.online_bank_statement_provider = "dummy"
|
||||
journal_form.save()
|
||||
|
||||
self.assertTrue(journal.online_bank_statement_provider_id)
|
||||
save_provider_id = journal.online_bank_statement_provider_id.id
|
||||
|
||||
# Stuff should not change when doing unrelated write.
|
||||
journal.write({"code": "BIGBANK"})
|
||||
self.assertTrue(journal.online_bank_statement_provider_id)
|
||||
self.assertEqual(journal.online_bank_statement_provider_id.id, save_provider_id)
|
||||
|
||||
with common.Form(journal) as journal_form:
|
||||
journal_form.bank_statements_source = "undefined"
|
||||
journal_form.save()
|
||||
|
||||
self.assertFalse(journal.online_bank_statement_provider_id)
|
||||
self.assertFalse(
|
||||
self.OnlineBankStatementProvider.search(
|
||||
[
|
||||
("id", "=", save_provider_id),
|
||||
]
|
||||
)
|
||||
cls.provider = cls.OnlineBankStatementProvider.create(
|
||||
{
|
||||
"name": "Dummy Provider",
|
||||
"service": "dummy",
|
||||
"journal_id": cls.journal.id,
|
||||
"statement_creation_mode": "daily",
|
||||
}
|
||||
)
|
||||
|
||||
def test_pull_mode_daily(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "daily"
|
||||
|
||||
provider.with_context(step={"hours": 2})._pull(
|
||||
self.provider.statement_creation_mode = "daily"
|
||||
self.provider.with_context(step={"hours": 2})._pull(
|
||||
self.now - relativedelta(days=1),
|
||||
self.now,
|
||||
)
|
||||
self.assertEqual(
|
||||
len(self.AccountBankStatement.search([("journal_id", "=", journal.id)])), 2
|
||||
)
|
||||
self._getExpectedStatements(2)
|
||||
|
||||
def test_pull_mode_weekly(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "weekly"
|
||||
|
||||
provider.with_context(step={"hours": 8})._pull(
|
||||
self.provider.statement_creation_mode = "weekly"
|
||||
self.provider.with_context(step={"hours": 8})._pull(
|
||||
self.now - relativedelta(weeks=1),
|
||||
self.now,
|
||||
)
|
||||
self.assertEqual(
|
||||
len(self.AccountBankStatement.search([("journal_id", "=", journal.id)])), 2
|
||||
)
|
||||
self._getExpectedStatements(2)
|
||||
|
||||
def test_pull_mode_monthly(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "monthly"
|
||||
|
||||
provider.with_context(step={"hours": 8})._pull(
|
||||
self.provider.statement_creation_mode = "monthly"
|
||||
self.provider.with_context(step={"hours": 8})._pull(
|
||||
self.now - relativedelta(months=1),
|
||||
self.now,
|
||||
)
|
||||
self.assertEqual(
|
||||
len(self.AccountBankStatement.search([("journal_id", "=", journal.id)])), 2
|
||||
)
|
||||
self._getExpectedStatements(2)
|
||||
|
||||
def test_pull_scheduled(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.next_run = self.now - relativedelta(days=15)
|
||||
|
||||
self.assertFalse(
|
||||
self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
)
|
||||
|
||||
provider.with_context(step={"hours": 8})._scheduled_pull()
|
||||
|
||||
statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statement), 1)
|
||||
self.provider.next_run = self.now - relativedelta(days=15)
|
||||
self._getExpectedStatements(0)
|
||||
self.provider.with_context(step={"hours": 8})._scheduled_pull()
|
||||
self._getExpectedStatements(1)
|
||||
|
||||
def test_pull_skip_duplicates_by_unique_import_id(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "weekly"
|
||||
|
||||
provider.with_context(
|
||||
self.provider.statement_creation_mode = "weekly"
|
||||
# Get for two weeks of data.
|
||||
self.provider.with_context(
|
||||
step={"hours": 8},
|
||||
data_since=self.now - relativedelta(weeks=2),
|
||||
data_until=self.now,
|
||||
override_date_since=self.now - relativedelta(weeks=2),
|
||||
override_date_until=self.now,
|
||||
)._pull(
|
||||
self.now - relativedelta(weeks=2),
|
||||
self.now,
|
||||
)
|
||||
self.assertEqual(
|
||||
len(
|
||||
self.AccountBankStatementLine.search([("journal_id", "=", journal.id)])
|
||||
),
|
||||
14 * (24 / 8),
|
||||
)
|
||||
|
||||
provider.with_context(
|
||||
expected_count = 14 * (24 / 8)
|
||||
self._getExpectedLines(expected_count)
|
||||
# Get two weeks, but one overlapping with previous.
|
||||
self.provider.with_context(
|
||||
step={"hours": 8},
|
||||
data_since=self.now - relativedelta(weeks=3),
|
||||
data_until=self.now - relativedelta(weeks=1),
|
||||
override_date_since=self.now - relativedelta(weeks=3),
|
||||
override_date_until=self.now - relativedelta(weeks=1),
|
||||
)._pull(
|
||||
self.now - relativedelta(weeks=3),
|
||||
self.now - relativedelta(weeks=1),
|
||||
)
|
||||
self.assertEqual(
|
||||
len(
|
||||
self.AccountBankStatementLine.search([("journal_id", "=", journal.id)])
|
||||
),
|
||||
21 * (24 / 8),
|
||||
)
|
||||
|
||||
provider.with_context(
|
||||
expected_count = 21 * (24 / 8)
|
||||
self._getExpectedLines(expected_count)
|
||||
# Get another day, but within statements already retrieved.
|
||||
self.provider.with_context(
|
||||
step={"hours": 8},
|
||||
data_since=self.now - relativedelta(weeks=1),
|
||||
data_until=self.now,
|
||||
override_date_since=self.now - relativedelta(weeks=1),
|
||||
override_date_until=self.now,
|
||||
)._pull(
|
||||
self.now - relativedelta(weeks=1),
|
||||
self.now,
|
||||
)
|
||||
self.assertEqual(
|
||||
len(
|
||||
self.AccountBankStatementLine.search([("journal_id", "=", journal.id)])
|
||||
),
|
||||
21 * (24 / 8),
|
||||
)
|
||||
self._getExpectedLines(expected_count)
|
||||
|
||||
def test_interval_type_minutes(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.interval_type = "minutes"
|
||||
provider._compute_update_schedule()
|
||||
self.provider.interval_type = "minutes"
|
||||
self.provider._compute_update_schedule()
|
||||
|
||||
def test_interval_type_hours(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.interval_type = "hours"
|
||||
provider._compute_update_schedule()
|
||||
self.provider.interval_type = "hours"
|
||||
self.provider._compute_update_schedule()
|
||||
|
||||
def test_interval_type_days(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.interval_type = "days"
|
||||
provider._compute_update_schedule()
|
||||
self.provider.interval_type = "days"
|
||||
self.provider._compute_update_schedule()
|
||||
|
||||
def test_interval_type_weeks(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.interval_type = "weeks"
|
||||
provider._compute_update_schedule()
|
||||
self.provider.interval_type = "weeks"
|
||||
self.provider._compute_update_schedule()
|
||||
|
||||
def test_pull_no_crash(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "weekly"
|
||||
|
||||
provider.with_context(crash=True, scheduled=True)._pull(
|
||||
self.provider.statement_creation_mode = "weekly"
|
||||
self.provider.with_context(crash=True, scheduled=True)._pull(
|
||||
self.now - relativedelta(hours=1),
|
||||
self.now,
|
||||
)
|
||||
self.assertFalse(
|
||||
self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
)
|
||||
self._getExpectedStatements(0)
|
||||
|
||||
def test_pull_crash(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "weekly"
|
||||
|
||||
self.provider.statement_creation_mode = "weekly"
|
||||
with self.assertRaisesRegex(Exception, "Expected"):
|
||||
provider.with_context(crash=True)._pull(
|
||||
self.provider.with_context(crash=True)._pull(
|
||||
self.now - relativedelta(hours=1),
|
||||
self.now,
|
||||
)
|
||||
|
||||
def test_pull_httperror(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "weekly"
|
||||
|
||||
self.provider.statement_creation_mode = "weekly"
|
||||
with self.assertRaises(HTTPError):
|
||||
provider.with_context(
|
||||
self.provider.with_context(
|
||||
crash=True,
|
||||
exception=HTTPError(None, 500, "Error", None, None),
|
||||
)._pull(
|
||||
@@ -391,21 +171,7 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
)
|
||||
|
||||
def test_pull_no_balance(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "daily"
|
||||
|
||||
provider.with_context(
|
||||
self.provider.with_context(
|
||||
step={"hours": 2},
|
||||
balance_start=0,
|
||||
amount=100.0,
|
||||
@@ -414,135 +180,93 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
self.now - relativedelta(days=1),
|
||||
self.now,
|
||||
)
|
||||
statements = self.AccountBankStatement.search(
|
||||
[("journal_id", "=", journal.id)],
|
||||
order="date asc",
|
||||
)
|
||||
statements = self._getExpectedStatements(2)
|
||||
self.assertFalse(statements[0].balance_start)
|
||||
self.assertTrue(statements[0].balance_end)
|
||||
self.assertTrue(statements[1].balance_start)
|
||||
|
||||
def test_wizard(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
vals = self.OnlineBankStatementPullWizard.with_context(
|
||||
active_model="account.journal", active_id=journal.id
|
||||
).default_get(fields_list=["provider_ids"])
|
||||
vals["date_since"] = self.now - relativedelta(hours=1)
|
||||
vals["date_until"] = self.now
|
||||
wizard = self.OnlineBankStatementPullWizard.create(vals)
|
||||
self.assertTrue(wizard.provider_ids)
|
||||
vals = {
|
||||
"date_since": self.now - relativedelta(hours=1),
|
||||
"date_until": self.now,
|
||||
}
|
||||
wizard = self.OnlineBankStatementPullWizard.with_context(
|
||||
active_model=self.provider._name, active_id=self.provider.id
|
||||
).create(vals)
|
||||
wizard.action_pull()
|
||||
self.assertTrue(
|
||||
self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
)
|
||||
self._getExpectedStatements(1)
|
||||
|
||||
def test_wizard_on_journal(self):
|
||||
vals = {
|
||||
"date_since": self.now - relativedelta(hours=1),
|
||||
"date_until": self.now,
|
||||
}
|
||||
wizard = self.OnlineBankStatementPullWizard.with_context(
|
||||
active_model=self.journal._name, active_id=self.journal.id
|
||||
).create(vals)
|
||||
wizard.action_pull()
|
||||
self._getExpectedStatements(1)
|
||||
|
||||
def test_pull_statement_partially(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "monthly"
|
||||
|
||||
self.provider.statement_creation_mode = "monthly"
|
||||
provider_context = {
|
||||
"step": {"hours": 24},
|
||||
"data_since": datetime(2020, 1, 1),
|
||||
"override_date_since": datetime(2020, 1, 1),
|
||||
"amount": 1.0,
|
||||
"balance_start": 0,
|
||||
}
|
||||
|
||||
provider.with_context(
|
||||
# Should create statement for first 30 days of january.
|
||||
self.provider.with_context(
|
||||
**provider_context,
|
||||
data_until=datetime(2020, 1, 31),
|
||||
override_date_until=datetime(2020, 1, 31),
|
||||
)._pull(
|
||||
datetime(2020, 1, 1),
|
||||
datetime(2020, 1, 31),
|
||||
)
|
||||
statements = self.AccountBankStatement.search(
|
||||
[("journal_id", "=", journal.id)],
|
||||
order="date asc",
|
||||
)
|
||||
self.assertEqual(len(statements), 1)
|
||||
statements = self._getExpectedStatements(1)
|
||||
self.assertEqual(statements[0].balance_start, 0.0)
|
||||
self.assertEqual(statements[0].balance_end_real, 30.0)
|
||||
|
||||
provider.with_context(
|
||||
# Should create statement for first 14 days of february,
|
||||
# and add one line to statement for january.
|
||||
self.provider.with_context(
|
||||
**provider_context,
|
||||
data_until=datetime(2020, 2, 15),
|
||||
override_date_until=datetime(2020, 2, 15),
|
||||
)._pull(
|
||||
datetime(2020, 1, 1),
|
||||
datetime(2020, 2, 29),
|
||||
)
|
||||
statements = self.AccountBankStatement.search(
|
||||
[("journal_id", "=", journal.id)],
|
||||
order="date asc",
|
||||
)
|
||||
self.assertEqual(len(statements), 2)
|
||||
statements = self._getExpectedStatements(2)
|
||||
self.assertEqual(statements[0].balance_start, 0.0)
|
||||
self.assertEqual(statements[0].balance_end_real, 31.0)
|
||||
self.assertEqual(statements[1].balance_start, 31.0)
|
||||
self.assertEqual(statements[1].balance_end_real, 45.0)
|
||||
|
||||
provider.with_context(
|
||||
# Getting data for rest of februari should not create new statement.
|
||||
self.provider.with_context(
|
||||
**provider_context,
|
||||
data_until=datetime(2020, 2, 29),
|
||||
override_date_until=datetime(2020, 2, 29),
|
||||
)._pull(
|
||||
datetime(2020, 1, 1),
|
||||
datetime(2020, 2, 29),
|
||||
)
|
||||
statements = self.AccountBankStatement.search(
|
||||
[("journal_id", "=", journal.id)],
|
||||
order="date asc",
|
||||
)
|
||||
self.assertEqual(len(statements), 2)
|
||||
statements = self._getExpectedStatements(2)
|
||||
self.assertEqual(statements[0].balance_start, 0.0)
|
||||
self.assertEqual(statements[0].balance_end_real, 31.0)
|
||||
self.assertEqual(statements[1].balance_start, 31.0)
|
||||
self.assertEqual(statements[1].balance_end_real, 59.0)
|
||||
|
||||
def test_tz_utc(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.tz = "UTC"
|
||||
provider.with_context(
|
||||
self.provider.tz = "UTC"
|
||||
self.provider.with_context(
|
||||
step={"hours": 1},
|
||||
data_since=datetime(2020, 4, 17, 22, 0),
|
||||
data_until=datetime(2020, 4, 18, 2, 0),
|
||||
override_date_since=datetime(2020, 4, 17, 22, 0),
|
||||
override_date_until=datetime(2020, 4, 18, 2, 0),
|
||||
tz="UTC",
|
||||
)._pull(
|
||||
datetime(2020, 4, 17, 22, 0),
|
||||
datetime(2020, 4, 18, 2, 0),
|
||||
)
|
||||
|
||||
statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statement), 2)
|
||||
|
||||
lines = statement.mapped("line_ids").sorted()
|
||||
statements = self._getExpectedStatements(2)
|
||||
lines = statements.mapped("line_ids").sorted(key=lambda r: r.id)
|
||||
self.assertEqual(len(lines), 4)
|
||||
self.assertEqual(lines[0].date, date(2020, 4, 17))
|
||||
self.assertEqual(lines[1].date, date(2020, 4, 17))
|
||||
@@ -550,33 +274,23 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
self.assertEqual(lines[3].date, date(2020, 4, 18))
|
||||
|
||||
def test_tz_non_utc(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
"""Test situation where the provider is west of Greenwich.
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.tz = "Etc/GMT-2"
|
||||
provider.with_context(
|
||||
In this case, when it is 22:00 according to the provider, it is
|
||||
00:00 the next day according to GMT/UTZ.
|
||||
"""
|
||||
self.provider.tz = "Etc/GMT-2"
|
||||
self.provider.with_context(
|
||||
step={"hours": 1},
|
||||
data_since=datetime(2020, 4, 17, 22, 0),
|
||||
data_until=datetime(2020, 4, 18, 2, 0),
|
||||
override_date_since=datetime(2020, 4, 17, 22, 0),
|
||||
override_date_until=datetime(2020, 4, 18, 2, 0),
|
||||
tz="UTC",
|
||||
)._pull(
|
||||
datetime(2020, 4, 17, 22, 0),
|
||||
datetime(2020, 4, 18, 2, 0),
|
||||
)
|
||||
|
||||
statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statement), 2)
|
||||
|
||||
lines = statement.mapped("line_ids").sorted()
|
||||
statements = self._getExpectedStatements(2)
|
||||
lines = statements.mapped("line_ids").sorted(key=lambda r: r.id)
|
||||
self.assertEqual(len(lines), 4)
|
||||
self.assertEqual(lines[0].date, date(2020, 4, 18))
|
||||
self.assertEqual(lines[1].date, date(2020, 4, 18))
|
||||
@@ -584,32 +298,25 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
self.assertEqual(lines[3].date, date(2020, 4, 18))
|
||||
|
||||
def test_other_tz_to_utc(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
"""Test the situation where we are tot the west of the provider.
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.with_context(
|
||||
Provider will be GMT/UTC, we will be two hours to the west.
|
||||
When we pull data from 22:00 on the 17th of april, for
|
||||
the provider this will be from 00:00 on the 18th.
|
||||
|
||||
We will translate the provider times back to our time.
|
||||
"""
|
||||
self.provider.with_context(
|
||||
step={"hours": 1},
|
||||
tz="Etc/GMT-2",
|
||||
data_since=datetime(2020, 4, 18, 0, 0),
|
||||
data_until=datetime(2020, 4, 18, 4, 0),
|
||||
override_date_since=datetime(2020, 4, 18, 0, 0),
|
||||
override_date_until=datetime(2020, 4, 18, 4, 0),
|
||||
)._pull(
|
||||
datetime(2020, 4, 17, 22, 0),
|
||||
datetime(2020, 4, 18, 2, 0),
|
||||
)
|
||||
|
||||
statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statement), 2)
|
||||
|
||||
lines = statement.mapped("line_ids").sorted()
|
||||
statements = self._getExpectedStatements(2)
|
||||
lines = statements.mapped("line_ids").sorted(key=lambda r: r.id)
|
||||
self.assertEqual(len(lines), 4)
|
||||
self.assertEqual(lines[0].date, date(2020, 4, 17))
|
||||
self.assertEqual(lines[1].date, date(2020, 4, 17))
|
||||
@@ -617,58 +324,28 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
self.assertEqual(lines[3].date, date(2020, 4, 18))
|
||||
|
||||
def test_timestamp_date_only_date(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.with_context(step={"hours": 1}, timestamp_mode="date")._pull(
|
||||
self.provider.with_context(step={"hours": 1}, timestamp_mode="date")._pull(
|
||||
datetime(2020, 4, 18, 0, 0),
|
||||
datetime(2020, 4, 18, 4, 0),
|
||||
)
|
||||
|
||||
statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statement), 1)
|
||||
|
||||
lines = statement.line_ids
|
||||
statements = self._getExpectedStatements(1)
|
||||
lines = statements.line_ids
|
||||
self.assertEqual(len(lines), 24)
|
||||
for line in lines:
|
||||
self.assertEqual(line.date, date(2020, 4, 18))
|
||||
|
||||
def test_timestamp_date_only_str(self):
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.with_context(
|
||||
self.provider.with_context(
|
||||
step={"hours": 1},
|
||||
data_since=datetime(2020, 4, 18, 0, 0),
|
||||
data_until=datetime(2020, 4, 18, 4, 0),
|
||||
override_date_since=datetime(2020, 4, 18, 0, 0),
|
||||
override_date_until=datetime(2020, 4, 18, 4, 0),
|
||||
timestamp_mode="str",
|
||||
)._pull(
|
||||
datetime(2020, 4, 18, 0, 0),
|
||||
datetime(2020, 4, 18, 4, 0),
|
||||
)
|
||||
|
||||
statement = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statement), 1)
|
||||
|
||||
lines = statement.line_ids
|
||||
statements = self._getExpectedStatements(1)
|
||||
lines = statements.line_ids
|
||||
self.assertEqual(len(lines), 4)
|
||||
self.assertEqual(lines[0].date, date(2020, 4, 18))
|
||||
self.assertEqual(lines[1].date, date(2020, 4, 18))
|
||||
@@ -692,18 +369,6 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
statements ('Allow empty statements' field is uncheck at the
|
||||
provider level.).
|
||||
"""
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.statement_creation_mode = "daily"
|
||||
with mock.patch(mock_obtain_statement_data) as mock_data:
|
||||
mock_data.side_effect = [
|
||||
self._get_statement_line_data(date(2021, 8, 10)),
|
||||
@@ -711,57 +376,53 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
|
||||
([], {}), # August 9th, doesn't have statement
|
||||
self._get_statement_line_data(date(2021, 8, 13)),
|
||||
]
|
||||
provider._pull(datetime(2021, 8, 10), datetime(2021, 8, 14))
|
||||
statements = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
self.assertEqual(len(statements), 2)
|
||||
self.assertEqual(statements[1].balance_start, 0)
|
||||
self.assertEqual(statements[1].balance_end_real, 100)
|
||||
self.assertEqual(len(statements[1].line_ids), 1)
|
||||
self.assertEqual(statements[0].balance_start, 100)
|
||||
self.assertEqual(statements[0].balance_end_real, 200)
|
||||
self.provider._pull(datetime(2021, 8, 10), datetime(2021, 8, 14))
|
||||
statements = self._getExpectedStatements(2)
|
||||
self.assertEqual(statements[0].balance_start, 0)
|
||||
self.assertEqual(statements[0].balance_end, 100)
|
||||
self.assertEqual(len(statements[0].line_ids), 1)
|
||||
|
||||
def test_create_empty_statements(self):
|
||||
"""Test creating empty bank statements
|
||||
('Allow empty statements' field is check at the provider level).
|
||||
"""
|
||||
journal = self.AccountJournal.create(
|
||||
{
|
||||
"name": "Bank",
|
||||
"type": "bank",
|
||||
"code": "BANK",
|
||||
"bank_statements_source": "online",
|
||||
"online_bank_statement_provider": "dummy",
|
||||
}
|
||||
)
|
||||
provider = journal.online_bank_statement_provider_id
|
||||
provider.active = True
|
||||
provider.allow_empty_statements = True
|
||||
provider.statement_creation_mode = "daily"
|
||||
with mock.patch(mock_obtain_statement_data) as mock_data:
|
||||
mock_data.side_effect = [
|
||||
self._get_statement_line_data(date(2021, 8, 10)),
|
||||
([], {}), # August 8th, doesn't have statement
|
||||
([], {}), # August 9th, doesn't have statement
|
||||
self._get_statement_line_data(date(2021, 8, 13)),
|
||||
]
|
||||
provider._pull(datetime(2021, 8, 10), datetime(2021, 8, 14))
|
||||
statements = self.AccountBankStatement.search([("journal_id", "=", journal.id)])
|
||||
# 4 Statements: 2 with movements and 2 empty
|
||||
self.assertEqual(len(statements), 4)
|
||||
# With movement
|
||||
self.assertEqual(statements[3].balance_start, 0)
|
||||
self.assertEqual(statements[3].balance_end_real, 100)
|
||||
self.assertEqual(len(statements[3].line_ids), 1)
|
||||
# Empty
|
||||
self.assertEqual(statements[2].balance_start, 100)
|
||||
self.assertEqual(statements[2].balance_end_real, 100)
|
||||
self.assertEqual(len(statements[2].line_ids), 0)
|
||||
# Empty
|
||||
self.assertEqual(statements[1].balance_start, 100)
|
||||
self.assertEqual(statements[1].balance_end_real, 100)
|
||||
self.assertEqual(len(statements[1].line_ids), 0)
|
||||
# With movement
|
||||
self.assertEqual(statements[0].balance_start, 100)
|
||||
self.assertEqual(statements[0].balance_end_real, 200)
|
||||
self.assertEqual(len(statements[0].line_ids), 1)
|
||||
self.assertEqual(statements[1].balance_end, 200)
|
||||
self.assertEqual(len(statements[1].line_ids), 1)
|
||||
|
||||
def test_unlink_provider(self):
|
||||
"""Unlink provider should clear fields on journal."""
|
||||
self.provider.unlink()
|
||||
self.assertEqual(self.journal.bank_statements_source, "undefined")
|
||||
self.assertEqual(self.journal.online_bank_statement_provider, False)
|
||||
self.assertEqual(self.journal.online_bank_statement_provider_id.id, False)
|
||||
|
||||
def _getExpectedStatements(self, expected_length):
|
||||
"""Check for length of statement recordset, with helpfull logging."""
|
||||
statements = self.AccountBankStatement.search(
|
||||
[("journal_id", "=", self.journal.id)], order="date asc"
|
||||
)
|
||||
actual_length = len(statements)
|
||||
# If length not expected, log information about statements.
|
||||
if actual_length != expected_length:
|
||||
if actual_length == 0:
|
||||
_logger.warning(
|
||||
_("No statements found in journal"),
|
||||
)
|
||||
else:
|
||||
_logger.warning(
|
||||
_("Names and dates for statements found: %(statements)s"),
|
||||
dict(
|
||||
statements=", ".join(
|
||||
["%s - %s" % (stmt.name, stmt.date) for stmt in statements]
|
||||
)
|
||||
),
|
||||
)
|
||||
# Now do the normal assert.
|
||||
self.assertEqual(len(statements), expected_length)
|
||||
# If we got expected number, return them.
|
||||
return statements
|
||||
|
||||
def _getExpectedLines(self, expected_length):
|
||||
"""Check number of lines created."""
|
||||
lines = self.AccountBankStatementLine.search(
|
||||
[("journal_id", "=", self.journal.id)]
|
||||
)
|
||||
self.assertEqual(len(lines), expected_length)
|
||||
# If we got expected number, return them.
|
||||
return lines
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# Copyright 2021 Therp BV (https://therp.nl).
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
class TestAccountJournal(common.TransactionCase):
|
||||
"""Test some functions adde d to account.journal model."""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.AccountJournal = self.env["account.journal"]
|
||||
|
||||
def test_values_online_bank_statement_provider(self):
|
||||
"""Check method to retrieve provider types."""
|
||||
# Make sure the users seems to have the group_no_one.
|
||||
with patch.object(
|
||||
self.AccountJournal.__class__, "user_has_groups", return_value=True
|
||||
):
|
||||
values = self.AccountJournal.values_online_bank_statement_provider()
|
||||
self.assertIn("dummy", [entry[0] for entry in values])
|
||||
Reference in New Issue
Block a user