From 5ca0b49483d1e359e997fd893e0bfd8a25a4c15e Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Sat, 20 Jun 2020 14:13:04 +0200 Subject: [PATCH] [IMP] account_bank_statement_import_online_paypal: query empty statements balance --- .../__manifest__.py | 2 +- ...nt_bank_statement_import_online_paypal.pot | 24 +++---- .../online_bank_statement_provider_paypal.py | 28 +++++++- ...unt_bank_statement_import_online_paypal.py | 64 +++++++++++++++++-- 4 files changed, 96 insertions(+), 22 deletions(-) diff --git a/account_bank_statement_import_online_paypal/__manifest__.py b/account_bank_statement_import_online_paypal/__manifest__.py index 060aca0b..436a5466 100644 --- a/account_bank_statement_import_online_paypal/__manifest__.py +++ b/account_bank_statement_import_online_paypal/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Online Bank Statements: PayPal.com', - 'version': '12.0.1.0.2', + 'version': '12.0.1.1.0', 'author': 'Brainbean Apps, ' 'Dataplug, ' diff --git a/account_bank_statement_import_online_paypal/i18n/account_bank_statement_import_online_paypal.pot b/account_bank_statement_import_online_paypal/i18n/account_bank_statement_import_online_paypal.pot index d7cb41e7..6be0529d 100644 --- a/account_bank_statement_import_online_paypal/i18n/account_bank_statement_import_online_paypal.pot +++ b/account_bank_statement_import_online_paypal/i18n/account_bank_statement_import_online_paypal.pot @@ -234,20 +234,20 @@ msgid "Electronic funds transfer (EFT)" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:363 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:371 #, python-format msgid "Failed to acquire token using Client ID and Secret!" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:241 -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:267 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:249 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:275 #, python-format msgid "Failed to resolve transaction %s (%s)" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:337 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:345 #, python-format msgid "Fee for %s" msgstr "" @@ -500,13 +500,13 @@ msgid "International credit card withdrawal" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:361 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:369 #, python-format msgid "Invalid token type!" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:303 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:311 #, python-format msgid "Invoice %s" msgstr "" @@ -554,7 +554,7 @@ msgid "Mobile payment, made through a mobile phone" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:520 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:542 #, python-format msgid "No authentication specified!" msgstr "" @@ -589,7 +589,7 @@ msgid "Partner fee" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:357 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:365 #, python-format msgid "PayPal App features are configured incorrectly!" msgstr "" @@ -828,7 +828,7 @@ msgid "Third-party recoupment" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:342 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:350 #, python-format msgid "Transaction fee for %s" msgstr "" @@ -852,14 +852,14 @@ msgid "Transfer to external GL entity" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:536 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:558 #, python-format msgid "Unknown authentication specified!" msgstr "" #. module: account_bank_statement_import_online_paypal -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:484 -#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:490 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:506 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:512 #, python-format msgid "Unknown error" msgstr "" diff --git a/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py b/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py index 96bb1583..d4e10f9b 100644 --- a/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py +++ b/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py @@ -1,5 +1,5 @@ -# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) -# Copyright 2019 Dataplug (https://dataplug.io) +# Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2019-2020 Dataplug (https://dataplug.io) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from base64 import b64encode @@ -212,7 +212,15 @@ class OnlineBankStatementProviderPayPal(models.Model): date_until ) if not transactions: - return None + balance = self._paypal_get_balance( + token, + currency, + date_since + ) + return [], { + 'balance_start': balance, + 'balance_end_real': balance, + } # Normalize transactions, sort by date, and get lines transactions = list(sorted( @@ -365,6 +373,20 @@ class OnlineBankStatementProviderPayPal(models.Model): )) return data['access_token'] + @api.multi + def _paypal_get_balance(self, token, currency, as_of_timestamp): + self.ensure_one() + url = (self.api_base or PAYPAL_API_BASE) \ + + '/v1/reporting/balances?currency_code=%s&as_of_time=%s' % ( + currency, + as_of_timestamp.isoformat() + 'Z', + ) + data = self._paypal_retrieve(url, token) + available_balance = data['balances'][0].get('available_balance') + if not available_balance: + return Decimal() + return Decimal(available_balance['value']) + @api.multi def _paypal_get_transaction(self, token, transaction_id, timestamp): self.ensure_one() diff --git a/account_bank_statement_import_online_paypal/tests/test_account_bank_statement_import_online_paypal.py b/account_bank_statement_import_online_paypal/tests/test_account_bank_statement_import_online_paypal.py index 792eb25e..30f5092b 100644 --- a/account_bank_statement_import_online_paypal/tests/test_account_bank_statement_import_online_paypal.py +++ b/account_bank_statement_import_online_paypal/tests/test_account_bank_statement_import_online_paypal.py @@ -194,16 +194,39 @@ class TestAccountBankAccountStatementImportOnlinePayPal( }) provider = journal.online_bank_statement_provider_id - mocked_response = UrlopenRetValMock("""{ + mocked_response_1 = UrlopenRetValMock("""{ "debug_id": "eec890ebd5798", "details": "xxxxxx", "links": "xxxxxx", "message": "Data for the given start date is not available.", "name": "INVALID_REQUEST" }""", throw=True) + mocked_response_2 = UrlopenRetValMock("""{ + "balances": [ + { + "currency": "EUR", + "primary": true, + "total_balance": { + "currency_code": "EUR", + "value": "0.75" + }, + "available_balance": { + "currency_code": "EUR", + "value": "0.75" + }, + "withheld_balance": { + "currency_code": "EUR", + "value": "0.00" + } + } + ], + "account_id": "1234567890", + "as_of_time": "2019-08-01T00:00:00+0000", + "last_refresh_time": "2019-08-01T00:00:00+0000" +}""") with mock.patch( _provider_class + '._paypal_urlopen', - return_value=mocked_response, + side_effect=[mocked_response_1, mocked_response_2], ), self.mock_token(): data = provider.with_context( test_account_bank_statement_import_online_paypal_monday=True, @@ -212,7 +235,10 @@ class TestAccountBankAccountStatementImportOnlinePayPal( self.now, ) - self.assertIsNone(data) + self.assertEqual(data, ([], { + 'balance_start': 0.75, + 'balance_end_real': 0.75, + })) def test_error_handling_1(self): journal = self.AccountJournal.create({ @@ -269,7 +295,7 @@ class TestAccountBankAccountStatementImportOnlinePayPal( }) provider = journal.online_bank_statement_provider_id - mocked_response = json.loads("""{ + mocked_response_1 = json.loads("""{ "transaction_details": [], "account_number": "1234567890", "start_date": "2019-08-01T00:00:00+0000", @@ -278,17 +304,43 @@ class TestAccountBankAccountStatementImportOnlinePayPal( "page": 1, "total_items": 0, "total_pages": 0 +}""", parse_float=Decimal) + mocked_response_2 = json.loads("""{ + "balances": [ + { + "currency": "EUR", + "primary": true, + "total_balance": { + "currency_code": "EUR", + "value": "0.75" + }, + "available_balance": { + "currency_code": "EUR", + "value": "0.75" + }, + "withheld_balance": { + "currency_code": "EUR", + "value": "0.00" + } + } + ], + "account_id": "1234567890", + "as_of_time": "2019-08-01T00:00:00+0000", + "last_refresh_time": "2019-08-01T00:00:00+0000" }""", parse_float=Decimal) with mock.patch( _provider_class + '._paypal_retrieve', - return_value=mocked_response, + side_effect=[mocked_response_1, mocked_response_2], ), self.mock_token(): data = provider._obtain_statement_data( self.now - relativedelta(hours=1), self.now, ) - self.assertIsNone(data) + self.assertEqual(data, ([], { + 'balance_start': 0.75, + 'balance_end_real': 0.75, + })) def test_ancient_pull(self): journal = self.AccountJournal.create({