[IMP] account_bank_statement_import_online: tz

[UPD] Update account_bank_statement_import_online.pot

account_bank_statement_import_online 12.0.1.4.0
This commit is contained in:
Alexey Pelykh
2020-04-17 08:21:44 +02:00
committed by Ronald Portier
parent f73aa32e1a
commit 16d26f04c1
6 changed files with 223 additions and 10 deletions

View File

@@ -4,7 +4,7 @@
{ {
'name': 'Online Bank Statements', 'name': 'Online Bank Statements',
'version': '12.0.1.3.1', 'version': '12.0.1.4.0',
'author': 'author':
'Brainbean Apps, ' 'Brainbean Apps, '
'Dataplug, ' 'Dataplug, '

View File

@@ -14,7 +14,7 @@ msgstr ""
"Plural-Forms: \n" "Plural-Forms: \n"
#. module: account_bank_statement_import_online #. module: account_bank_statement_import_online
#: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:141 #: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:153
#, python-format #, python-format
msgid "%(number)s %(type)s" msgid "%(number)s %(type)s"
msgstr "" msgstr ""
@@ -159,7 +159,7 @@ msgid "If checked, some messages have a delivery error."
msgstr "" msgstr ""
#. module: account_bank_statement_import_online #. module: account_bank_statement_import_online
#: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:138 #: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:150
#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_online.online_bank_statement_provider_filter #: model_terms:ir.ui.view,arch_db:account_bank_statement_import_online.online_bank_statement_provider_filter
#, python-format #, python-format
msgid "Inactive" msgid "Inactive"
@@ -235,7 +235,7 @@ msgid "Monthly statements"
msgstr "" msgstr ""
#. module: account_bank_statement_import_online #. module: account_bank_statement_import_online
#: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:191 #: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:204
#, python-format #, python-format
msgid "N/A" msgid "N/A"
msgstr "" msgstr ""
@@ -289,14 +289,14 @@ msgid "Online Bank Statement Provider"
msgstr "" msgstr ""
#. module: account_bank_statement_import_online #. module: account_bank_statement_import_online
#: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:184 #: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:197
#, python-format #, python-format
msgid "Online Bank Statement Provider \"%s\" failed to obtain statement data since %s until %s:\n" msgid "Online Bank Statement Provider \"%s\" failed to obtain statement data since %s until %s:\n"
"%s" "%s"
msgstr "" msgstr ""
#. module: account_bank_statement_import_online #. module: account_bank_statement_import_online
#: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:193 #: code:addons/account_bank_statement_import_online/models/online_bank_statement_provider.py:206
#, python-format #, python-format
msgid "Online Bank Statement Provider failure" msgid "Online Bank Statement Provider failure"
msgstr "" msgstr ""
@@ -412,6 +412,16 @@ msgstr ""
msgid "The currency used to enter statement" msgid "The currency used to enter statement"
msgstr "" msgstr ""
#. module: account_bank_statement_import_online
#: model:ir.model.fields,field_description:account_bank_statement_import_online.field_online_bank_statement_provider__tz
msgid "Timezone"
msgstr ""
#. module: account_bank_statement_import_online
#: model:ir.model.fields,help:account_bank_statement_import_online.field_online_bank_statement_provider__tz
msgid "Timezone to convert transaction timestamps to prior being saved into a statement."
msgstr ""
#. module: account_bank_statement_import_online #. module: account_bank_statement_import_online
#: model:ir.model.fields,field_description:account_bank_statement_import_online.field_online_bank_statement_provider__message_unread #: model:ir.model.fields,field_description:account_bank_statement_import_online.field_online_bank_statement_provider__message_unread
msgid "Unread Messages" msgid "Unread Messages"

View File

@@ -2,13 +2,16 @@
# Copyright 2019-2020 Dataplug (https://dataplug.io) # Copyright 2019-2020 Dataplug (https://dataplug.io)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from datetime import datetime
from dateutil.relativedelta import relativedelta, MO from dateutil.relativedelta import relativedelta, MO
from decimal import Decimal from decimal import Decimal
import logging import logging
from pytz import timezone, utc
from sys import exc_info from sys import exc_info
from odoo import models, fields, api, _ from odoo import models, fields, api, _
from odoo.addons.base.models.res_bank import sanitize_account_number 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__) _logger = logging.getLogger(__name__)
@@ -43,6 +46,15 @@ class OnlineBankStatementProvider(models.Model):
account_number = fields.Char( account_number = fields.Char(
related='journal_id.bank_account_id.sanitized_acc_number' 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( service = fields.Selection(
selection=lambda self: self._selection_service(), selection=lambda self: self._selection_service(),
required=True, required=True,
@@ -156,6 +168,7 @@ class OnlineBankStatementProvider(models.Model):
) )
AccountBankStatementLine = self.env['account.bank.statement.line'] AccountBankStatementLine = self.env['account.bank.statement.line']
for provider in self: for provider in self:
provider_tz = timezone(provider.tz) if provider.tz else utc
statement_date_since = provider._get_statement_date_since( statement_date_since = provider._get_statement_date_since(
date_since date_since
) )
@@ -225,7 +238,14 @@ class OnlineBankStatementProvider(models.Model):
) )
filtered_lines = [] filtered_lines = []
for line_values in lines_data: 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 date < statement_date_since or date < date_since:
if 'balance_start' in statement_values: if 'balance_start' in statement_values:
statement_values['balance_start'] = ( statement_values['balance_start'] = (
@@ -246,6 +266,11 @@ class OnlineBankStatementProvider(models.Model):
) )
) )
continue 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') unique_import_id = line_values.get('unique_import_id')
if unique_import_id: if unique_import_id:
unique_import_id = provider._generate_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)], [('unique_import_id', '=', unique_import_id)],
limit=1): limit=1):
continue continue
bank_account_number = line_values.get('account_number') bank_account_number = line_values.get('account_number')
if bank_account_number: if bank_account_number:
line_values.update({ line_values.update({
@@ -267,6 +293,7 @@ class OnlineBankStatementProvider(models.Model):
) )
), ),
}) })
filtered_lines.append(line_values) filtered_lines.append(line_values)
statement_values.update({ statement_values.update({
'line_ids': [[0, False, line] for line in filtered_lines], '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 # NOTE: Statement date is treated by Odoo as start of period. Details
# - addons/account/models/account_journal_dashboard.py # - addons/account/models/account_journal_dashboard.py
# - def get_line_graph_datas() # - 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() return date_since.date()
@api.multi @api.multi

View File

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

View File

@@ -2,7 +2,7 @@
# Copyright 2019-2020 Dataplug (https://dataplug.io) # Copyright 2019-2020 Dataplug (https://dataplug.io)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). # 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 dateutil.relativedelta import relativedelta
from psycopg2 import IntegrityError from psycopg2 import IntegrityError
from urllib.error import HTTPError from urllib.error import HTTPError
@@ -384,6 +384,7 @@ class TestAccountBankAccountStatementImportOnline(common.TransactionCase):
provider.with_context( provider.with_context(
step={'hours': 2}, step={'hours': 2},
balance_start=0, balance_start=0,
amount=100.0,
balance=False, balance=False,
)._pull( )._pull(
self.now - relativedelta(days=1), 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[0].balance_end_real, 31.0)
self.assertEqual(statements[1].balance_start, 31.0) self.assertEqual(statements[1].balance_start, 31.0)
self.assertEqual(statements[1].balance_end_real, 59.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))

View File

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