Browse Source

[IMP] account_bank_statement_import_online: tz

12.0
Alexey Pelykh 5 years ago
parent
commit
dd61075792
  1. 31
      account_bank_statement_import_online/models/online_bank_statement_provider.py
  2. 17
      account_bank_statement_import_online/tests/online_bank_statement_provider_dummy.py
  3. 162
      account_bank_statement_import_online/tests/test_account_bank_statement_import_online.py
  4. 1
      account_bank_statement_import_online/views/online_bank_statement_provider.xml

31
account_bank_statement_import_online/models/online_bank_statement_provider.py

@ -2,13 +2,16 @@
# Copyright 2019-2020 Dataplug (https://dataplug.io)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from datetime import datetime
from dateutil.relativedelta import relativedelta, MO
from decimal import Decimal
import logging
from pytz import timezone, utc
from sys import exc_info
from odoo import models, fields, api, _
from odoo.addons.base.models.res_bank import sanitize_account_number
from odoo.addons.base.models.res_partner import _tz_get
_logger = logging.getLogger(__name__)
@ -43,6 +46,15 @@ class OnlineBankStatementProvider(models.Model):
account_number = fields.Char(
related='journal_id.bank_account_id.sanitized_acc_number'
)
tz = fields.Selection(
selection=_tz_get,
string='Timezone',
default=lambda self: self.env.context.get('tz'),
help=(
'Timezone to convert transaction timestamps to prior being'
' saved into a statement.'
),
)
service = fields.Selection(
selection=lambda self: self._selection_service(),
required=True,
@ -156,6 +168,7 @@ class OnlineBankStatementProvider(models.Model):
)
AccountBankStatementLine = self.env['account.bank.statement.line']
for provider in self:
provider_tz = timezone(provider.tz) if provider.tz else utc
statement_date_since = provider._get_statement_date_since(
date_since
)
@ -225,7 +238,14 @@ class OnlineBankStatementProvider(models.Model):
)
filtered_lines = []
for line_values in lines_data:
date = fields.Datetime.from_string(line_values['date'])
date = line_values['date']
if not isinstance(date, datetime):
date = fields.Datetime.from_string(date)
if date.tzinfo is None:
date = date.replace(tzinfo=utc)
date = date.astimezone(utc).replace(tzinfo=None)
if date < statement_date_since or date < date_since:
if 'balance_start' in statement_values:
statement_values['balance_start'] = (
@ -246,6 +266,11 @@ class OnlineBankStatementProvider(models.Model):
)
)
continue
date = date.replace(tzinfo=utc)
date = date.astimezone(provider_tz).replace(tzinfo=None)
line_values['date'] = date
unique_import_id = line_values.get('unique_import_id')
if unique_import_id:
unique_import_id = provider._generate_unique_import_id(
@ -258,6 +283,7 @@ class OnlineBankStatementProvider(models.Model):
[('unique_import_id', '=', unique_import_id)],
limit=1):
continue
bank_account_number = line_values.get('account_number')
if bank_account_number:
line_values.update({
@ -267,6 +293,7 @@ class OnlineBankStatementProvider(models.Model):
)
),
})
filtered_lines.append(line_values)
statement_values.update({
'line_ids': [[0, False, line] for line in filtered_lines],
@ -344,6 +371,8 @@ class OnlineBankStatementProvider(models.Model):
# NOTE: Statement date is treated by Odoo as start of period. Details
# - addons/account/models/account_journal_dashboard.py
# - def get_line_graph_datas()
tz = timezone(self.tz) if self.tz else utc
date_since = date_since.replace(tzinfo=utc).astimezone(tz)
return date_since.date()
@api.multi

17
account_bank_statement_import_online/tests/online_bank_statement_provider_dummy.py

@ -4,9 +4,10 @@
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from pytz import timezone
from random import randrange
from odoo import models, api
from odoo import api, fields, models
class OnlineBankStatementProviderDummy(models.Model):
@ -43,6 +44,13 @@ class OnlineBankStatementProviderDummy(models.Model):
randrange(-10000, 10000, 1) * 0.1
)
balance = balance_start
tz = self.env.context.get('tz')
if tz:
tz = timezone(tz)
timestamp_mode = self.env.context.get('timestamp_mode')
lines = []
date = data_since
while date < data_until:
@ -50,10 +58,15 @@ class OnlineBankStatementProviderDummy(models.Model):
'amount',
randrange(-100, 100, 1) * 0.1
)
transaction_date = date.replace(tzinfo=tz)
if timestamp_mode == 'date':
transaction_date = transaction_date.date()
elif timestamp_mode == 'str':
transaction_date = fields.Datetime.to_string(transaction_date)
lines.append({
'name': 'payment',
'amount': amount,
'date': date,
'date': transaction_date,
'unique_import_id': str(int(
(date - datetime(1970, 1, 1)) / timedelta(seconds=1)
)),

162
account_bank_statement_import_online/tests/test_account_bank_statement_import_online.py

@ -2,7 +2,7 @@
# Copyright 2019-2020 Dataplug (https://dataplug.io)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from datetime import datetime
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
from psycopg2 import IntegrityError
from urllib.error import HTTPError
@ -384,6 +384,7 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
provider.with_context(
step={'hours': 2},
balance_start=0,
amount=100.0,
balance=False,
)._pull(
self.now - relativedelta(days=1),
@ -483,3 +484,162 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
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(
step={'hours': 1},
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()
self.assertEqual(len(lines), 4)
self.assertEqual(lines[0].date, date(2020, 4, 17))
self.assertEqual(lines[1].date, date(2020, 4, 17))
self.assertEqual(lines[2].date, date(2020, 4, 18))
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',
})
provider = journal.online_bank_statement_provider_id
provider.active = True
provider.tz = 'Etc/GMT-2'
provider.with_context(
step={'hours': 1},
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()
self.assertEqual(len(lines), 4)
self.assertEqual(lines[0].date, date(2020, 4, 18))
self.assertEqual(lines[1].date, date(2020, 4, 18))
self.assertEqual(lines[2].date, date(2020, 4, 18))
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',
})
provider = journal.online_bank_statement_provider_id
provider.active = True
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),
)._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()
self.assertEqual(len(lines), 4)
self.assertEqual(lines[0].date, date(2020, 4, 17))
self.assertEqual(lines[1].date, date(2020, 4, 17))
self.assertEqual(lines[2].date, date(2020, 4, 18))
self.assertEqual(lines[3].date, date(2020, 4, 18))
def test_timestamp_date_only(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(
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
self.assertEqual(len(lines), 4)
self.assertEqual(lines[0].date, date(2020, 4, 18))
self.assertEqual(lines[1].date, date(2020, 4, 18))
self.assertEqual(lines[2].date, date(2020, 4, 18))
self.assertEqual(lines[3].date, date(2020, 4, 18))
def test_timestamp_date_only(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='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
self.assertEqual(len(lines), 4)
self.assertEqual(lines[0].date, date(2020, 4, 18))
self.assertEqual(lines[1].date, date(2020, 4, 18))
self.assertEqual(lines[2].date, date(2020, 4, 18))
self.assertEqual(lines[3].date, date(2020, 4, 18))

1
account_bank_statement_import_online/views/online_bank_statement_provider.xml

@ -80,6 +80,7 @@
<group>
<group>
<field name="statement_creation_mode"/>
<field name="tz"/>
</group>
</group>
</page>

Loading…
Cancel
Save