diff --git a/account_bank_statement_import_online_paypal/README.rst b/account_bank_statement_import_online_paypal/README.rst new file mode 100644 index 00000000..53666cd0 --- /dev/null +++ b/account_bank_statement_import_online_paypal/README.rst @@ -0,0 +1,129 @@ +================================== +Online Bank Statements: PayPal.com +================================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbank--statement--import-lightgray.png?logo=github + :target: https://github.com/OCA/bank-statement-import/tree/12.0/account_bank_statement_import_online_paypal + :alt: OCA/bank-statement-import +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/bank-statement-import-12-0/bank-statement-import-12-0-account_bank_statement_import_online_paypal + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/174/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module provides online bank statements from +`PayPal.com `_. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +To configure online bank statements provider: + +#. Go to *Invoicing > Configuration > Bank Accounts* +#. Open bank account to configure and edit it +#. Set *Bank Feeds* to *Online* +#. Select *PayPal.com* as online bank statements provider in + *Online Bank Statements (OCA)* section +#. Save the bank account +#. Click on provider and configure provider-specific settings. + +or, alternatively: + +#. Go to *Invoicing > Overview* +#. Open settings of the corresponding journal account +#. Switch to *Bank Account* tab +#. Set *Bank Feeds* to *Online* +#. Select *PayPal.com* as online bank statements provider in + *Online Bank Statements (OCA)* section +#. Save the bank account +#. Click on provider and configure provider-specific settings. + +To obtain *Client ID* and *Secret*: + +#. Open `PayPal Developer `_ +#. Go to *My Apps & Credentials* and switch to *Live* +#. Under *REST API apps*, click *Create App* to create new application (e.g. *Odoo*) +#. Copy *Client ID* and *Secret* to use during provider configuration +#. Under *Live App Settings*, uncheck all features except *Transaction Search* +#. Click Save + +Usage +===== + +To pull historical bank statements: + +#. Go to *Invoicing > Configuration > Bank Accounts* +#. Select specific bank accounts +#. Launch *Actions > Online Bank Statements Pull Wizard* +#. Configure date interval and click *Pull* + +Known issues / Roadmap +====================== + +* Only transactions for the previous three years are retrieved, historical data + can be imported manually, see ``account_bank_statement_import_paypal``. See + `PayPal Help Center article `_ + for details. +* `PayPal Transaction Info `_ + defines extra fields like ``tip_amount``, ``shipping_amount``, etc. that + could be useful to be decomposed from a single transaction. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Brainbean Apps +* Dataplug + +Contributors +~~~~~~~~~~~~ + +* Alexey Pelykh + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/bank-statement-import `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_bank_statement_import_online_paypal/__init__.py b/account_bank_statement_import_online_paypal/__init__.py new file mode 100644 index 00000000..31660d6a --- /dev/null +++ b/account_bank_statement_import_online_paypal/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import models diff --git a/account_bank_statement_import_online_paypal/__manifest__.py b/account_bank_statement_import_online_paypal/__manifest__.py new file mode 100644 index 00000000..0e9d0506 --- /dev/null +++ b/account_bank_statement_import_online_paypal/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2019 Dataplug (https://dataplug.io) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + 'name': 'Online Bank Statements: PayPal.com', + 'version': '12.0.1.0.0', + 'author': + 'Brainbean Apps, ' + 'Dataplug, ' + 'Odoo Community Association (OCA)', + 'website': 'https://github.com/OCA/bank-statement-import/', + 'license': 'AGPL-3', + 'category': 'Accounting', + 'summary': 'Online bank statements for PayPal.com', + 'depends': [ + 'account_bank_statement_import_online', + ], + 'data': [ + 'views/online_bank_statement_provider.xml', + ], + 'installable': True, +} 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 new file mode 100644 index 00000000..736ec753 --- /dev/null +++ b/account_bank_statement_import_online_paypal/i18n/account_bank_statement_import_online_paypal.pot @@ -0,0 +1,925 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_bank_statement_import_online_paypal +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:63 +#, python-format +msgid "ACH funding for funds recovery from account balance" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_online_paypal.online_bank_statement_provider_form +msgid "API base" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:52 +#, python-format +msgid "ATM withdrawal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:129 +#, python-format +msgid "Account hold for ACH deposit" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:128 +#, python-format +msgid "Account hold for open authorization" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:161 +#, python-format +msgid "Account receivable for shipping" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:53 +#, python-format +msgid "Auto-sweep from account" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:66 +#, python-format +msgid "AutoSweep" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:132 +#, python-format +msgid "BML credit, transfer from BML" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:138 +#, python-format +msgid "BML withdrawal, transfer to BML" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:79 +#, python-format +msgid "Balance manager account bonus" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:94 +#, python-format +msgid "Bill pay transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:156 +#, python-format +msgid "Blocked payments" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:85 +#, python-format +msgid "Bonus for first ACH use" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:133 +#, python-format +msgid "Buyer credit payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:134 +#, python-format +msgid "Buyer credit payment withdrawal, transfer to BML" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:106 +#, python-format +msgid "Cancellation of hold for dispute resolution" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:118 +#, python-format +msgid "Charge-off adjustment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:116 +#, python-format +msgid "Chargeback" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:122 +#, python-format +msgid "Chargeback cancellation" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:50 +#, python-format +msgid "Chargeback processing fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:121 +#, python-format +msgid "Chargeback re-presentment rejection" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:117 +#, python-format +msgid "Chargeback reversal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:49 +#, python-format +msgid "Check withdrawal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_online_paypal.online_bank_statement_provider_form +msgid "Client ID" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:91 +#, python-format +msgid "Coupon redemption" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:87 +#, python-format +msgid "Credit card cash back bonus" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:75 +#, python-format +msgid "Credit card deposit for negative PayPal account balance" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:86 +#, python-format +msgid "Credit card security charge refund" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:60 +#, python-format +msgid "Currency conversion required to cover negative balance" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:77 +#, python-format +msgid "Debit card cash back bonus" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:159 +#, python-format +msgid "Deferred disbursement, funds collected for disbursement" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:160 +#, python-format +msgid "Delayed disbursement, funds disbursed" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:29 +#, python-format +msgid "Direct payment API" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:166 +#, python-format +msgid "Display only transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:37 +#, python-format +msgid "Donation payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:64 +#, python-format +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:362 +#, 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:240 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:266 +#, 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:336 +#, python-format +msgid "Fee for %s" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:104 +#, python-format +msgid "Fee refund" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:103 +#, python-format +msgid "Fee reversal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:46 +#, python-format +msgid "Foreign bank withdrawal fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:155 +#, python-format +msgid "Funds available" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:154 +#, python-format +msgid "Funds not yet available" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:162 +#, python-format +msgid "Funds payable: PayPal-provided funds that must be paid back" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:163 +#, python-format +msgid "Funds receivable: PayPal-provided funds that are being paid back" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:67 +#, python-format +msgid "General PayPal debit card transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:24 +#, python-format +msgid "General PayPal-to-PayPal payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:115 +#, python-format +msgid "General account adjustment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:139 +#, python-format +msgid "General adjustment without business-related event" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:123 +#, python-format +msgid "General authorization" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:76 +#, python-format +msgid "General bonus" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:137 +#, python-format +msgid "General buyer credit payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:74 +#, python-format +msgid "General credit card deposit" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:73 +#, python-format +msgid "General 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:58 +#, python-format +msgid "General currency conversion" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:126 +#, python-format +msgid "General dividend" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:61 +#, python-format +msgid "General funding of PayPal account" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:144 +#, python-format +msgid "General hold" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:145 +#, python-format +msgid "General hold release" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:88 +#, python-format +msgid "General incentive or certificate redemption" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:140 +#, python-format +msgid "General intra-account transfer" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:44 +#, python-format +msgid "General non-payment fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:95 +#, python-format +msgid "General reversal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:127 +#, python-format +msgid "General temporary hold" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:65 +#, python-format +msgid "General withdrawal from PayPal account" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:135 +#, python-format +msgid "General withdrawal to non-bank institution" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:43 +#, python-format +msgid "Generic instrument-funded payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:114 +#, python-format +msgid "Generic instrument/Open Wallet reversals (buyer side)" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:113 +#, python-format +msgid "Generic instrument/Open Wallet reversals (seller side)" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:158 +#, python-format +msgid "Generic instrument/Open Wallet transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:56 +#, python-format +msgid "Gift certificate expiration fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:33 +#, python-format +msgid "Gift certificate payment, purchase of gift certificate" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:152 +#, python-format +msgid "Gift certificate purchase" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:89 +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:153 +#, python-format +msgid "Gift certificate redemption" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:70 +#, python-format +msgid "Hidden virtual PayPal debit card transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:105 +#, python-format +msgid "Hold for dispute investigation" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:119 +#, python-format +msgid "Incentive adjustment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:111 +#, python-format +msgid "Instant payment review (IPR) reversal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:54 +#, python-format +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:360 +#, 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:302 +#, python-format +msgid "Invoice %s" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:107 +#, python-format +msgid "MAM reversal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:48 +#, python-format +msgid "Mass payment batch fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:25 +#, python-format +msgid "MassPay payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:110 +#, python-format +msgid "MassPay refund transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:109 +#, python-format +msgid "MassPay reversal transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:78 +#, python-format +msgid "Merchant referral account bonus" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:35 +#, python-format +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:500 +#, python-format +msgid "No 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:108 +#, python-format +msgid "Non-reference credit payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:93 +#, python-format +msgid "Offers used as funding source" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: model:ir.model,name:account_bank_statement_import_online_paypal.model_online_bank_statement_provider +msgid "Online Bank Statement Provider" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:167 +#, python-format +msgid "Other" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:57 +#, python-format +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:356 +#, python-format +msgid "PayPal App features are configured incorrectly!" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:30 +#, python-format +msgid "PayPal Checkout APIs" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:42 +#, python-format +msgid "PayPal Here payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:199 +#, python-format +msgid "PayPal allows retrieving transactions only up to 3 years in the past. Please import older transactions manually. See https://www.paypal.com/us/smarthelp/article/why-can't-i-access-transaction-history-greater-than-3-years-ts2241" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:62 +#, python-format +msgid "PayPal balance manager funding of PayPal account" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:131 +#, python-format +msgid "PayPal buyer credit payment funding" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:80 +#, python-format +msgid "PayPal buyer warranty bonus" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:72 +#, python-format +msgid "PayPal debit authorization" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:71 +#, python-format +msgid "PayPal debit card cash advance" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:69 +#, python-format +msgid "PayPal debit card withdrawal to ATM" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:81 +#, python-format +msgid "PayPal protection bonus, payout for PayPal buyer protection, payout for full protection with PayPal buyer credit." +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:51 +#, python-format +msgid "Payment fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:150 +#, python-format +msgid "Payment hold" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:151 +#, python-format +msgid "Payment hold release" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:102 +#, python-format +msgid "Payment refund, initiated by merchant" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:101 +#, python-format +msgid "Payment reversal, initiated by PayPal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:148 +#, python-format +msgid "Payment review hold" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:149 +#, python-format +msgid "Payment review release" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:90 +#, python-format +msgid "Points incentive redemption" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:32 +#, python-format +msgid "Postage payment to carrier" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:27 +#, python-format +msgid "Pre-approved payment (BillUser API)" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:124 +#, python-format +msgid "Reauthorization" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:112 +#, python-format +msgid "Rebate or cash back reversal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:38 +#, python-format +msgid "Rebate payments" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:120 +#, python-format +msgid "Reimbursement of chargeback" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:146 +#, python-format +msgid "Reserve hold" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:147 +#, python-format +msgid "Reserve release" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:99 +#, python-format +msgid "Reversal of ACH deposit" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:96 +#, python-format +msgid "Reversal of ACH withdrawal transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:97 +#, python-format +msgid "Reversal of debit card transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:100 +#, python-format +msgid "Reversal of general account hold" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:98 +#, python-format +msgid "Reversal of points usage" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_online_paypal.online_bank_statement_provider_form +msgid "Secret" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:141 +#, python-format +msgid "Settlement consolidation" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:41 +#, python-format +msgid "Store-to-store transfers" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:26 +#, python-format +msgid "Subscription payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:130 +#, python-format +msgid "Temporary hold on available balance" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:34 +#, python-format +msgid "Third-party auction payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:39 +#, python-format +msgid "Third-party payout" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:40 +#, python-format +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:341 +#, python-format +msgid "Transaction fee for %s" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:142 +#, python-format +msgid "Transfer of funds from payable" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:157 +#, python-format +msgid "Transfer to and from a credit-card-funded restricted balance" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:143 +#, python-format +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:516 +#, 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:59 +#, python-format +msgid "User-initiated currency conversion" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:68 +#, python-format +msgid "Virtual PayPal debit card transaction" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:36 +#, python-format +msgid "Virtual terminal payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:125 +#, python-format +msgid "Void of authorization" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:55 +#, python-format +msgid "Warranty fee for warranty purchase" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:31 +#, python-format +msgid "Website payments standard payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:45 +#, python-format +msgid "Website payments. Pro account monthly fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:47 +#, python-format +msgid "WorldLink check withdrawal fee" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:136 +#, python-format +msgid "WorldLink withdrawal" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:28 +#, python-format +msgid "eBay auction payment" +msgstr "" + +#. module: account_bank_statement_import_online_paypal +#: code:addons/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py:92 +#, python-format +msgid "eBay loyalty incentive" +msgstr "" + diff --git a/account_bank_statement_import_online_paypal/models/__init__.py b/account_bank_statement_import_online_paypal/models/__init__.py new file mode 100644 index 00000000..10e8660a --- /dev/null +++ b/account_bank_statement_import_online_paypal/models/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import online_bank_statement_provider_paypal 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 new file mode 100644 index 00000000..fed83e05 --- /dev/null +++ b/account_bank_statement_import_online_paypal/models/online_bank_statement_provider_paypal.py @@ -0,0 +1,517 @@ +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2019 Dataplug (https://dataplug.io) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from base64 import b64encode +from datetime import datetime +from dateutil.relativedelta import relativedelta +import dateutil.parser +from decimal import Decimal +import itertools +import json +import pytz +from urllib.error import HTTPError +from urllib.parse import urlencode +import urllib.request + +from odoo import models, api, _ +from odoo.exceptions import UserError + + +PAYPAL_API_BASE = 'https://api.paypal.com' +TRANSACTIONS_SCOPE = 'https://uri.paypal.com/services/reporting/search/read' +EVENT_DESCRIPTIONS = { + 'T0000': _('General PayPal-to-PayPal payment'), + 'T0001': _('MassPay payment'), + 'T0002': _('Subscription payment'), + 'T0003': _('Pre-approved payment (BillUser API)'), + 'T0004': _('eBay auction payment'), + 'T0005': _('Direct payment API'), + 'T0006': _('PayPal Checkout APIs'), + 'T0007': _('Website payments standard payment'), + 'T0008': _('Postage payment to carrier'), + 'T0009': _('Gift certificate payment, purchase of gift certificate'), + 'T0010': _('Third-party auction payment'), + 'T0011': _('Mobile payment, made through a mobile phone'), + 'T0012': _('Virtual terminal payment'), + 'T0013': _('Donation payment'), + 'T0014': _('Rebate payments'), + 'T0015': _('Third-party payout'), + 'T0016': _('Third-party recoupment'), + 'T0017': _('Store-to-store transfers'), + 'T0018': _('PayPal Here payment'), + 'T0019': _('Generic instrument-funded payment'), + 'T0100': _('General non-payment fee'), + 'T0101': _('Website payments. Pro account monthly fee'), + 'T0102': _('Foreign bank withdrawal fee'), + 'T0103': _('WorldLink check withdrawal fee'), + 'T0104': _('Mass payment batch fee'), + 'T0105': _('Check withdrawal'), + 'T0106': _('Chargeback processing fee'), + 'T0107': _('Payment fee'), + 'T0108': _('ATM withdrawal'), + 'T0109': _('Auto-sweep from account'), + 'T0110': _('International credit card withdrawal'), + 'T0111': _('Warranty fee for warranty purchase'), + 'T0112': _('Gift certificate expiration fee'), + 'T0113': _('Partner fee'), + 'T0200': _('General currency conversion'), + 'T0201': _('User-initiated currency conversion'), + 'T0202': _('Currency conversion required to cover negative balance'), + 'T0300': _('General funding of PayPal account'), + 'T0301': _('PayPal balance manager funding of PayPal account'), + 'T0302': _('ACH funding for funds recovery from account balance'), + 'T0303': _('Electronic funds transfer (EFT)'), + 'T0400': _('General withdrawal from PayPal account'), + 'T0401': _('AutoSweep'), + 'T0500': _('General PayPal debit card transaction'), + 'T0501': _('Virtual PayPal debit card transaction'), + 'T0502': _('PayPal debit card withdrawal to ATM'), + 'T0503': _('Hidden virtual PayPal debit card transaction'), + 'T0504': _('PayPal debit card cash advance'), + 'T0505': _('PayPal debit authorization'), + 'T0600': _('General credit card withdrawal'), + 'T0700': _('General credit card deposit'), + 'T0701': _('Credit card deposit for negative PayPal account balance'), + 'T0800': _('General bonus'), + 'T0801': _('Debit card cash back bonus'), + 'T0802': _('Merchant referral account bonus'), + 'T0803': _('Balance manager account bonus'), + 'T0804': _('PayPal buyer warranty bonus'), + 'T0805': _( + 'PayPal protection bonus, payout for PayPal buyer protection, payout ' + 'for full protection with PayPal buyer credit.' + ), + 'T0806': _('Bonus for first ACH use'), + 'T0807': _('Credit card security charge refund'), + 'T0808': _('Credit card cash back bonus'), + 'T0900': _('General incentive or certificate redemption'), + 'T0901': _('Gift certificate redemption'), + 'T0902': _('Points incentive redemption'), + 'T0903': _('Coupon redemption'), + 'T0904': _('eBay loyalty incentive'), + 'T0905': _('Offers used as funding source'), + 'T1000': _('Bill pay transaction'), + 'T1100': _('General reversal'), + 'T1101': _('Reversal of ACH withdrawal transaction'), + 'T1102': _('Reversal of debit card transaction'), + 'T1103': _('Reversal of points usage'), + 'T1104': _('Reversal of ACH deposit'), + 'T1105': _('Reversal of general account hold'), + 'T1106': _('Payment reversal, initiated by PayPal'), + 'T1107': _('Payment refund, initiated by merchant'), + 'T1108': _('Fee reversal'), + 'T1109': _('Fee refund'), + 'T1110': _('Hold for dispute investigation'), + 'T1111': _('Cancellation of hold for dispute resolution'), + 'T1112': _('MAM reversal'), + 'T1113': _('Non-reference credit payment'), + 'T1114': _('MassPay reversal transaction'), + 'T1115': _('MassPay refund transaction'), + 'T1116': _('Instant payment review (IPR) reversal'), + 'T1117': _('Rebate or cash back reversal'), + 'T1118': _('Generic instrument/Open Wallet reversals (seller side)'), + 'T1119': _('Generic instrument/Open Wallet reversals (buyer side)'), + 'T1200': _('General account adjustment'), + 'T1201': _('Chargeback'), + 'T1202': _('Chargeback reversal'), + 'T1203': _('Charge-off adjustment'), + 'T1204': _('Incentive adjustment'), + 'T1205': _('Reimbursement of chargeback'), + 'T1207': _('Chargeback re-presentment rejection'), + 'T1208': _('Chargeback cancellation'), + 'T1300': _('General authorization'), + 'T1301': _('Reauthorization'), + 'T1302': _('Void of authorization'), + 'T1400': _('General dividend'), + 'T1500': _('General temporary hold'), + 'T1501': _('Account hold for open authorization'), + 'T1502': _('Account hold for ACH deposit'), + 'T1503': _('Temporary hold on available balance'), + 'T1600': _('PayPal buyer credit payment funding'), + 'T1601': _('BML credit, transfer from BML'), + 'T1602': _('Buyer credit payment'), + 'T1603': _('Buyer credit payment withdrawal, transfer to BML'), + 'T1700': _('General withdrawal to non-bank institution'), + 'T1701': _('WorldLink withdrawal'), + 'T1800': _('General buyer credit payment'), + 'T1801': _('BML withdrawal, transfer to BML'), + 'T1900': _('General adjustment without business-related event'), + 'T2000': _('General intra-account transfer'), + 'T2001': _('Settlement consolidation'), + 'T2002': _('Transfer of funds from payable'), + 'T2003': _('Transfer to external GL entity'), + 'T2101': _('General hold'), + 'T2102': _('General hold release'), + 'T2103': _('Reserve hold'), + 'T2104': _('Reserve release'), + 'T2105': _('Payment review hold'), + 'T2106': _('Payment review release'), + 'T2107': _('Payment hold'), + 'T2108': _('Payment hold release'), + 'T2109': _('Gift certificate purchase'), + 'T2110': _('Gift certificate redemption'), + 'T2111': _('Funds not yet available'), + 'T2112': _('Funds available'), + 'T2113': _('Blocked payments'), + 'T2201': _('Transfer to and from a credit-card-funded restricted balance'), + 'T3000': _('Generic instrument/Open Wallet transaction'), + 'T5000': _('Deferred disbursement, funds collected for disbursement'), + 'T5001': _('Delayed disbursement, funds disbursed'), + 'T9700': _('Account receivable for shipping'), + 'T9701': _('Funds payable: PayPal-provided funds that must be paid back'), + 'T9702': _( + 'Funds receivable: PayPal-provided funds that are being paid back' + ), + 'T9800': _('Display only transaction'), + 'T9900': _('Other'), +} + + +class OnlineBankStatementProviderPayPal(models.Model): + _inherit = 'online.bank.statement.provider' + + @api.model + def _get_available_services(self): + return super()._get_available_services() + [ + ('paypal', 'PayPal.com'), + ] + + @api.multi + def _obtain_statement_data(self, date_since, date_until): + self.ensure_one() + if self.service != 'paypal': + return super()._obtain_statement_data( + date_since, + date_until, + ) # pragma: no cover + + currency = ( + self.currency_id or self.company_id.currency_id + ).name + + if date_since.tzinfo: + date_since = date_since.astimezone(pytz.utc).replace(tzinfo=None) + if date_until.tzinfo: + date_until = date_until.astimezone(pytz.utc).replace(tzinfo=None) + + if date_since < datetime.utcnow() - relativedelta(years=3): + raise UserError(_( + 'PayPal allows retrieving transactions only up to 3 years in ' + 'the past. Please import older transactions manually. See ' + 'https://www.paypal.com/us/smarthelp/article/why-can\'t-i' + '-access-transaction-history-greater-than-3-years-ts2241' + )) + + token = self._paypal_get_token() + transactions = self._paypal_get_transactions( + token, + currency, + date_since, + date_until + ) + if not transactions: + return None + + # Normalize transactions, sort by date, and get lines + transactions = list(sorted( + transactions, + key=lambda transaction: self._paypal_get_transaction_date( + transaction + ) + )) + lines = list(itertools.chain.from_iterable(map( + lambda x: self._paypal_transaction_to_lines(x), + transactions + ))) + + first_transaction = transactions[0] + first_transaction_id = \ + first_transaction['transaction_info']['transaction_id'] + first_transaction_date = self._paypal_get_transaction_date( + first_transaction + ) + first_transaction = self._paypal_get_transaction( + token, + first_transaction_id, + first_transaction_date + ) + if not first_transaction: + raise UserError(_('Failed to resolve transaction %s (%s)') % ( + first_transaction_id, + first_transaction_date + )) + balance_start = self._paypal_get_transaction_ending_balance( + first_transaction + ) + balance_start -= self._paypal_get_transaction_total_amount( + first_transaction + ) + balance_start -= self._paypal_get_transaction_fee_amount( + first_transaction + ) + + last_transaction = transactions[-1] + last_transaction_id = \ + last_transaction['transaction_info']['transaction_id'] + last_transaction_date = self._paypal_get_transaction_date( + last_transaction + ) + last_transaction = self._paypal_get_transaction( + token, + last_transaction_id, + last_transaction_date + ) + if not last_transaction: + raise UserError(_('Failed to resolve transaction %s (%s)') % ( + last_transaction_id, + last_transaction_date + )) + balance_end = self._paypal_get_transaction_ending_balance( + last_transaction + ) + + return lines, { + 'balance_start': balance_start, + 'balance_end_real': balance_end, + } + + @api.model + def _paypal_preparse_transaction(self, transaction): + date = dateutil.parser.parse( + self._paypal_get_transaction_date(transaction) + ).astimezone(pytz.utc).replace(tzinfo=None) + transaction['transaction_info']['transaction_updated_date'] = date + return transaction + + @api.model + def _paypal_transaction_to_lines(self, data): + transaction = data['transaction_info'] + payer = data['payer_info'] + transaction_id = transaction['transaction_id'] + event_code = transaction['transaction_event_code'] + date = self._paypal_get_transaction_date(data) + total_amount = self._paypal_get_transaction_total_amount(data) + fee_amount = self._paypal_get_transaction_fee_amount(data) + transaction_subject = transaction.get('transaction_subject') + transaction_note = transaction.get('transaction_note') + invoice = transaction.get('invoice_id') + payer_name = payer.get('payer_name', {}) + payer_email = payer_name.get('email_address') + if invoice: + invoice = _('Invoice %s') % invoice + note = transaction_id + if transaction_subject or transaction_note: + note = '%s: %s' % ( + note, + transaction_subject or transaction_note + ) + if payer_email: + note += ' (%s)' % payer_email + unique_import_id = '%s-%s' % ( + transaction_id, + int(date.timestamp()), + ) + name = invoice \ + or transaction_subject \ + or transaction_note \ + or EVENT_DESCRIPTIONS.get(event_code) \ + or '' + line = { + 'name': name, + 'amount': str(total_amount), + 'date': date, + 'note': note, + 'unique_import_id': unique_import_id, + } + payer_full_name = payer_name.get('full_name') or \ + payer_name.get('alternate_full_name') + if payer_full_name: + line.update({ + 'partner_name': payer_full_name, + }) + lines = [line] + if fee_amount: + lines += [{ + 'name': _('Fee for %s') % (name or transaction_id), + 'amount': str(fee_amount), + 'date': date, + 'partner_name': 'PayPal', + 'unique_import_id': '%s-FEE' % unique_import_id, + 'note': _('Transaction fee for %s') % note, + }] + return lines + + @api.multi + def _paypal_get_token(self): + self.ensure_one() + data = self._paypal_retrieve( + (self.api_base or PAYPAL_API_BASE) + '/v1/oauth2/token', + (self.username, self.password), + data=urlencode({ + 'grant_type': 'client_credentials', + }).encode('utf-8') + ) + if 'scope' not in data or TRANSACTIONS_SCOPE not in data['scope']: + raise UserError(_( + 'PayPal App features are configured incorrectly!' + )) + if 'token_type' not in data or data['token_type'] != 'Bearer': + raise UserError(_('Invalid token type!')) + if 'access_token' not in data: + raise UserError(_( + 'Failed to acquire token using Client ID and Secret!' + )) + return data['access_token'] + + @api.multi + def _paypal_get_transaction(self, token, transaction_id, timestamp): + self.ensure_one() + transaction_date = timestamp.isoformat() + 'Z' + url = (self.api_base or PAYPAL_API_BASE) \ + + '/v1/reporting/transactions' \ + + ( + '?start_date=%s' + '&end_date=%s' + '&fields=all' + ) % ( + transaction_date, + transaction_date, + ) + data = self._paypal_retrieve(url, token) + transactions = data['transaction_details'] + for transaction in transactions: + if transaction['transaction_info']['transaction_id'] != \ + transaction_id: + continue + return transaction + return None + + @api.multi + def _paypal_get_transactions(self, token, currency, since, until): + self.ensure_one() + # NOTE: Not more than 31 days in a row + # NOTE: start_date <= date <= end_date, thus check every transaction + interval_step = relativedelta(days=31) + interval_start = since + transactions = [] + while interval_start < until: + interval_end = min(interval_start + interval_step, until) + page = 1 + total_pages = None + while total_pages is None or page <= total_pages: + url = (self.api_base or PAYPAL_API_BASE) \ + + '/v1/reporting/transactions' \ + + ( + '?transaction_currency=%s' + '&start_date=%s' + '&end_date=%s' + '&fields=all' + '&balance_affecting_records_only=Y' + '&page_size=500' + '&page=%d' + % ( + currency, + interval_start.isoformat() + 'Z', + interval_end.isoformat() + 'Z', + page, + )) + data = self._paypal_retrieve(url, token) + interval_transactions = map( + lambda transaction: self._paypal_preparse_transaction( + transaction + ), + data['transaction_details'] + ) + transactions += list(filter( + lambda transaction: + interval_start <= self._paypal_get_transaction_date( + transaction + ) < interval_end, + interval_transactions + )) + total_pages = data['total_pages'] + page += 1 + interval_start += interval_step + return transactions + + @api.model + def _paypal_get_transaction_date(self, transaction): + # NOTE: CSV reports from PayPal use this date, search as well + return transaction['transaction_info']['transaction_updated_date'] + + @api.model + def _paypal_get_transaction_total_amount(self, transaction): + transaction_amount = \ + transaction['transaction_info'].get('transaction_amount') + if not transaction_amount: + return Decimal() + return Decimal(transaction_amount['value']) + + @api.model + def _paypal_get_transaction_fee_amount(self, transaction): + fee_amount = transaction['transaction_info'].get('fee_amount') + if not fee_amount: + return Decimal() + return Decimal(fee_amount['value']) + + @api.model + def _paypal_get_transaction_ending_balance(self, transaction): + # NOTE: 'available_balance' instead of 'ending_balance' as per CSV file + transaction_amount = \ + transaction['transaction_info'].get('available_balance') + if not transaction_amount: + return Decimal() + return Decimal(transaction_amount['value']) + + @api.model + def _paypal_validate(self, content): + content = json.loads(content) + if 'error' in content and content['error']: + raise UserError( + content['error_description'] + if 'error_description' in content + else 'Unknown error' + ) + return content + + @api.model + def _paypal_retrieve(self, url, auth, data=None): + try: + with self._paypal_urlopen(url, auth, data) as response: + content = response.read().decode('utf-8') + except HTTPError as e: + content = self._paypal_validate( + e.read().decode('utf-8') + ) + if 'name' in content and content['name']: + raise UserError('%s: %s' % ( + content['name'], + content['error_description'] + if 'error_description' in content + else 'Unknown error', + )) + raise e + return self._paypal_validate(content) + + @api.model + def _paypal_urlopen(self, url, auth, data=None): + if not auth: + raise UserError(_('No authentication specified!')) + request = urllib.request.Request(url, data=data) + if isinstance(auth, tuple): + request.add_header( + 'Authorization', + 'Basic %s' % str( + b64encode(('%s:%s' % (auth[0], auth[1])).encode('utf-8')), + 'utf-8' + ) + ) + elif isinstance(auth, str): + request.add_header( + 'Authorization', + 'Bearer %s' % auth + ) + else: + raise UserError(_('Unknown authentication specified!')) + return urllib.request.urlopen(request) diff --git a/account_bank_statement_import_online_paypal/readme/CONFIGURE.rst b/account_bank_statement_import_online_paypal/readme/CONFIGURE.rst new file mode 100644 index 00000000..67b44183 --- /dev/null +++ b/account_bank_statement_import_online_paypal/readme/CONFIGURE.rst @@ -0,0 +1,29 @@ +To configure online bank statements provider: + +#. Go to *Invoicing > Configuration > Bank Accounts* +#. Open bank account to configure and edit it +#. Set *Bank Feeds* to *Online* +#. Select *PayPal.com* as online bank statements provider in + *Online Bank Statements (OCA)* section +#. Save the bank account +#. Click on provider and configure provider-specific settings. + +or, alternatively: + +#. Go to *Invoicing > Overview* +#. Open settings of the corresponding journal account +#. Switch to *Bank Account* tab +#. Set *Bank Feeds* to *Online* +#. Select *PayPal.com* as online bank statements provider in + *Online Bank Statements (OCA)* section +#. Save the bank account +#. Click on provider and configure provider-specific settings. + +To obtain *Client ID* and *Secret*: + +#. Open `PayPal Developer `_ +#. Go to *My Apps & Credentials* and switch to *Live* +#. Under *REST API apps*, click *Create App* to create new application (e.g. *Odoo*) +#. Copy *Client ID* and *Secret* to use during provider configuration +#. Under *Live App Settings*, uncheck all features except *Transaction Search* +#. Click Save diff --git a/account_bank_statement_import_online_paypal/readme/CONTRIBUTORS.rst b/account_bank_statement_import_online_paypal/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..1c6a35a1 --- /dev/null +++ b/account_bank_statement_import_online_paypal/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Alexey Pelykh diff --git a/account_bank_statement_import_online_paypal/readme/DESCRIPTION.rst b/account_bank_statement_import_online_paypal/readme/DESCRIPTION.rst new file mode 100644 index 00000000..a2a7a3e4 --- /dev/null +++ b/account_bank_statement_import_online_paypal/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module provides online bank statements from +`PayPal.com `_. diff --git a/account_bank_statement_import_online_paypal/readme/ROADMAP.rst b/account_bank_statement_import_online_paypal/readme/ROADMAP.rst new file mode 100644 index 00000000..d8114209 --- /dev/null +++ b/account_bank_statement_import_online_paypal/readme/ROADMAP.rst @@ -0,0 +1,7 @@ +* Only transactions for the previous three years are retrieved, historical data + can be imported manually, see ``account_bank_statement_import_paypal``. See + `PayPal Help Center article `_ + for details. +* `PayPal Transaction Info `_ + defines extra fields like ``tip_amount``, ``shipping_amount``, etc. that + could be useful to be decomposed from a single transaction. diff --git a/account_bank_statement_import_online_paypal/readme/USAGE.rst b/account_bank_statement_import_online_paypal/readme/USAGE.rst new file mode 100644 index 00000000..03845f13 --- /dev/null +++ b/account_bank_statement_import_online_paypal/readme/USAGE.rst @@ -0,0 +1,6 @@ +To pull historical bank statements: + +#. Go to *Invoicing > Configuration > Bank Accounts* +#. Select specific bank accounts +#. Launch *Actions > Online Bank Statements Pull Wizard* +#. Configure date interval and click *Pull* diff --git a/account_bank_statement_import_online_paypal/static/description/index.html b/account_bank_statement_import_online_paypal/static/description/index.html new file mode 100644 index 00000000..15eafb05 --- /dev/null +++ b/account_bank_statement_import_online_paypal/static/description/index.html @@ -0,0 +1,479 @@ + + + + + + +Online Bank Statements: PayPal.com + + + +
+

Online Bank Statements: PayPal.com

+ + +

Beta License: AGPL-3 OCA/bank-statement-import Translate me on Weblate Try me on Runbot

+

This module provides online bank statements from +PayPal.com.

+

Table of contents

+ +
+

Configuration

+

To configure online bank statements provider:

+
    +
  1. Go to Invoicing > Configuration > Bank Accounts
  2. +
  3. Open bank account to configure and edit it
  4. +
  5. Set Bank Feeds to Online
  6. +
  7. Select PayPal.com as online bank statements provider in +Online Bank Statements (OCA) section
  8. +
  9. Save the bank account
  10. +
  11. Click on provider and configure provider-specific settings.
  12. +
+

or, alternatively:

+
    +
  1. Go to Invoicing > Overview
  2. +
  3. Open settings of the corresponding journal account
  4. +
  5. Switch to Bank Account tab
  6. +
  7. Set Bank Feeds to Online
  8. +
  9. Select PayPal.com as online bank statements provider in +Online Bank Statements (OCA) section
  10. +
  11. Save the bank account
  12. +
  13. Click on provider and configure provider-specific settings.
  14. +
+

To obtain Client ID and Secret:

+
    +
  1. Open PayPal Developer
  2. +
  3. Go to My Apps & Credentials and switch to Live
  4. +
  5. Under REST API apps, click Create App to create new application (e.g. Odoo)
  6. +
  7. Copy Client ID and Secret to use during provider configuration
  8. +
  9. Under Live App Settings, uncheck all features except Transaction Search
  10. +
  11. Click Save
  12. +
+
+
+

Usage

+

To pull historical bank statements:

+
    +
  1. Go to Invoicing > Configuration > Bank Accounts
  2. +
  3. Select specific bank accounts
  4. +
  5. Launch Actions > Online Bank Statements Pull Wizard
  6. +
  7. Configure date interval and click Pull
  8. +
+
+
+

Known issues / Roadmap

+
    +
  • Only transactions for the previous three years are retrieved, historical data +can be imported manually, see account_bank_statement_import_paypal. See +PayPal Help Center article +for details.
  • +
  • PayPal Transaction Info +defines extra fields like tip_amount, shipping_amount, etc. that +could be useful to be decomposed from a single transaction.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Brainbean Apps
  • +
  • Dataplug
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/bank-statement-import project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/account_bank_statement_import_online_paypal/tests/__init__.py b/account_bank_statement_import_online_paypal/tests/__init__.py new file mode 100644 index 00000000..ca7b0d9c --- /dev/null +++ b/account_bank_statement_import_online_paypal/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_account_bank_statement_import_online_paypal 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 new file mode 100644 index 00000000..fc7e814c --- /dev/null +++ b/account_bank_statement_import_online_paypal/tests/test_account_bank_statement_import_online_paypal.py @@ -0,0 +1,576 @@ +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2019 Dataplug (https://dataplug.io) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import datetime +from dateutil.relativedelta import relativedelta +from decimal import Decimal +import json +from unittest import mock + +from odoo.tests import common +from odoo import fields + +_module_ns = 'odoo.addons.account_bank_statement_import_online_paypal' +_provider_class = ( + _module_ns + + '.models.online_bank_statement_provider_paypal' + + '.OnlineBankStatementProviderPayPal' +) + + +class TestAccountBankAccountStatementImportOnlinePayPal( + common.TransactionCase +): + + def setUp(self): + super().setUp() + + self.now = fields.Datetime.now() + self.currency_eur = self.env.ref('base.EUR') + self.currency_usd = self.env.ref('base.USD') + self.AccountJournal = self.env['account.journal'] + self.OnlineBankStatementProvider = self.env[ + 'online.bank.statement.provider' + ] + self.AccountBankStatement = self.env['account.bank.statement'] + self.AccountBankStatementLine = self.env['account.bank.statement.line'] + + Provider = self.OnlineBankStatementProvider + self.paypal_parse_transaction = lambda payload: ( + Provider._paypal_transaction_to_lines( + Provider._paypal_preparse_transaction( + json.loads( + payload, + parse_float=Decimal, + ) + ) + ) + ) + self.mock_token = lambda: mock.patch( + _provider_class + '._paypal_get_token', + return_value='--TOKEN--', + ) + + def test_good_token(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "scope": "https://uri.paypal.com/services/reporting/search/read", + "access_token": "---TOKEN---", + "token_type": "Bearer", + "app_id": "APP-1234567890", + "expires_in": 32400, + "nonce": "---NONCE---" +}""", parse_float=Decimal) + token = None + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ): + token = provider._paypal_get_token() + self.assertEqual(token, '---TOKEN---') + + def test_bad_token_scope(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "scope": "openid https://uri.paypal.com/services/applications/webhooks", + "access_token": "---TOKEN---", + "token_type": "Bearer", + "app_id": "APP-1234567890", + "expires_in": 32400, + "nonce": "---NONCE---" +}""", parse_float=Decimal) + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ): + with self.assertRaises(Exception): + provider._paypal_get_token() + + def test_bad_token_type(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "scope": "https://uri.paypal.com/services/reporting/search/read", + "access_token": "---TOKEN---", + "token_type": "NotBearer", + "app_id": "APP-1234567890", + "expires_in": 32400, + "nonce": "---NONCE---" +}""", parse_float=Decimal) + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ): + with self.assertRaises(Exception): + provider._paypal_get_token() + + def test_no_token(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "scope": "https://uri.paypal.com/services/reporting/search/read", + "token_type": "Bearer", + "app_id": "APP-1234567890", + "expires_in": 32400, + "nonce": "---NONCE---" + }""", parse_float=Decimal) + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ): + with self.assertRaises(Exception): + provider._paypal_get_token() + + def test_empty_pull(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "transaction_details": [], + "account_number": "1234567890", + "start_date": "2019-08-01T00:00:00+0000", + "end_date": "2019-08-01T00:00:00+0000", + "last_refreshed_datetime": "2019-09-01T00:00:00+0000", + "page": 1, + "total_items": 0, + "total_pages": 0 +}""", parse_float=Decimal) + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ), self.mock_token(): + data = provider._obtain_statement_data( + self.now - relativedelta(hours=1), + self.now, + ) + + self.assertIsNone(data) + + def test_ancient_pull(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "transaction_details": [], + "account_number": "1234567890", + "start_date": "2019-08-01T00:00:00+0000", + "end_date": "2019-08-01T00:00:00+0000", + "last_refreshed_datetime": "2019-09-01T00:00:00+0000", + "page": 1, + "total_items": 0, + "total_pages": 0 +}""", parse_float=Decimal) + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ), self.mock_token(): + with self.assertRaises(Exception): + provider._obtain_statement_data( + self.now - relativedelta(years=5), + self.now, + ) + + def test_pull(self): + journal = self.AccountJournal.create({ + 'name': 'Bank', + 'type': 'bank', + 'code': 'BANK', + 'currency_id': self.currency_eur.id, + 'bank_statements_source': 'online', + 'online_bank_statement_provider': 'paypal', + }) + + provider = journal.online_bank_statement_provider_id + mocked_response = json.loads("""{ + "transaction_details": [{ + "transaction_info": { + "paypal_account_id": "1234567890", + "transaction_id": "1234567890", + "transaction_event_code": "T1234", + "transaction_initiation_date": "2019-08-01T00:00:00+0000", + "transaction_updated_date": "2019-08-01T00:00:00+0000", + "transaction_amount": { + "currency_code": "USD", + "value": "1000.00" + }, + "fee_amount": { + "currency_code": "USD", + "value": "-100.00" + }, + "transaction_status": "S", + "transaction_subject": "Payment for Invoice(s) 1", + "ending_balance": { + "currency_code": "USD", + "value": "900.00" + }, + "available_balance": { + "currency_code": "USD", + "value": "900.00" + }, + "invoice_id": "1" + }, + "payer_info": { + "account_id": "1234567890", + "email_address": "partner@example.com", + "address_status": "Y", + "payer_status": "N", + "payer_name": { + "alternate_full_name": "Acme, Inc." + }, + "country_code": "US" + }, + "shipping_info": {}, + "cart_info": {}, + "store_info": {}, + "auction_info": {}, + "incentive_info": {} + }, { + "transaction_info": { + "paypal_account_id": "1234567890", + "transaction_id": "1234567891", + "transaction_event_code": "T1234", + "transaction_initiation_date": "2019-08-02T00:00:00+0000", + "transaction_updated_date": "2019-08-02T00:00:00+0000", + "transaction_amount": { + "currency_code": "USD", + "value": "1000.00" + }, + "fee_amount": { + "currency_code": "USD", + "value": "-100.00" + }, + "transaction_status": "S", + "transaction_subject": "Payment for Invoice(s) 1", + "ending_balance": { + "currency_code": "USD", + "value": "900.00" + }, + "available_balance": { + "currency_code": "USD", + "value": "900.00" + }, + "invoice_id": "1" + }, + "payer_info": { + "account_id": "1234567890", + "email_address": "partner@example.com", + "address_status": "Y", + "payer_status": "N", + "payer_name": { + "alternate_full_name": "Acme, Inc." + }, + "country_code": "US" + }, + "shipping_info": {}, + "cart_info": {}, + "store_info": {}, + "auction_info": {}, + "incentive_info": {} + }], + "account_number": "1234567890", + "start_date": "2019-08-01T00:00:00+0000", + "end_date": "2019-08-02T00:00:00+0000", + "last_refreshed_datetime": "2019-09-01T00:00:00+0000", + "page": 1, + "total_items": 1, + "total_pages": 1 +}""", parse_float=Decimal) + with mock.patch( + _provider_class + '._paypal_retrieve', + return_value=mocked_response, + ), self.mock_token(): + data = provider._obtain_statement_data( + datetime(2019, 8, 1), + datetime(2019, 8, 2), + ) + + self.assertEqual(len(data[0]), 2) + self.assertEqual(data[0][0], { + 'date': datetime(2019, 8, 1), + 'amount': '1000.00', + 'name': 'Invoice 1', + 'note': '1234567890: Payment for Invoice(s) 1', + 'partner_name': 'Acme, Inc.', + 'unique_import_id': '1234567890-1564617600', + }) + self.assertEqual(data[0][1], { + 'date': datetime(2019, 8, 1), + 'amount': '-100.00', + 'name': 'Fee for Invoice 1', + 'note': 'Transaction fee for 1234567890: Payment for Invoice(s) 1', + 'partner_name': 'PayPal', + 'unique_import_id': '1234567890-1564617600-FEE', + }) + self.assertEqual(data[1], { + 'balance_start': 0.0, + 'balance_end_real': 900.0, + }) + + def test_transaction_parse_1(self): + lines = self.paypal_parse_transaction("""{ + "transaction_info": { + "paypal_account_id": "1234567890", + "transaction_id": "1234567890", + "transaction_event_code": "T1234", + "transaction_initiation_date": "2019-08-01T00:00:00+0000", + "transaction_updated_date": "2019-08-01T00:00:00+0000", + "transaction_amount": { + "currency_code": "USD", + "value": "1000.00" + }, + "fee_amount": { + "currency_code": "USD", + "value": "0.00" + }, + "transaction_status": "S", + "transaction_subject": "Payment for Invoice(s) 1", + "ending_balance": { + "currency_code": "USD", + "value": "1000.00" + }, + "available_balance": { + "currency_code": "USD", + "value": "1000.00" + }, + "invoice_id": "1" + }, + "payer_info": { + "account_id": "1234567890", + "email_address": "partner@example.com", + "address_status": "Y", + "payer_status": "N", + "payer_name": { + "alternate_full_name": "Acme, Inc." + }, + "country_code": "US" + }, + "shipping_info": {}, + "cart_info": {}, + "store_info": {}, + "auction_info": {}, + "incentive_info": {} +}""") + self.assertEqual(len(lines), 1) + self.assertEqual(lines[0], { + 'date': datetime(2019, 8, 1), + 'amount': '1000.00', + 'name': 'Invoice 1', + 'note': '1234567890: Payment for Invoice(s) 1', + 'partner_name': 'Acme, Inc.', + 'unique_import_id': '1234567890-1564617600', + }) + + def test_transaction_parse_2(self): + lines = self.paypal_parse_transaction("""{ + "transaction_info": { + "paypal_account_id": "1234567890", + "transaction_id": "1234567890", + "transaction_event_code": "T1234", + "transaction_initiation_date": "2019-08-01T00:00:00+0000", + "transaction_updated_date": "2019-08-01T00:00:00+0000", + "transaction_amount": { + "currency_code": "USD", + "value": "1000.00" + }, + "fee_amount": { + "currency_code": "USD", + "value": "0.00" + }, + "transaction_status": "S", + "transaction_subject": "Payment for Invoice(s) 1", + "ending_balance": { + "currency_code": "USD", + "value": "1000.00" + }, + "available_balance": { + "currency_code": "USD", + "value": "1000.00" + }, + "invoice_id": "1" + }, + "payer_info": { + "account_id": "1234567890", + "email_address": "partner@example.com", + "address_status": "Y", + "payer_status": "N", + "payer_name": { + "alternate_full_name": "Acme, Inc." + }, + "country_code": "US" + }, + "shipping_info": {}, + "cart_info": {}, + "store_info": {}, + "auction_info": {}, + "incentive_info": {} +}""") + self.assertEqual(len(lines), 1) + self.assertEqual(lines[0], { + 'date': datetime(2019, 8, 1), + 'amount': '1000.00', + 'name': 'Invoice 1', + 'note': '1234567890: Payment for Invoice(s) 1', + 'partner_name': 'Acme, Inc.', + 'unique_import_id': '1234567890-1564617600', + }) + + def test_transaction_parse_3(self): + lines = self.paypal_parse_transaction("""{ + "transaction_info": { + "paypal_account_id": "1234567890", + "transaction_id": "1234567890", + "transaction_event_code": "T1234", + "transaction_initiation_date": "2019-08-01T00:00:00+0000", + "transaction_updated_date": "2019-08-01T00:00:00+0000", + "transaction_amount": { + "currency_code": "USD", + "value": "1000.00" + }, + "fee_amount": { + "currency_code": "USD", + "value": "-100.00" + }, + "transaction_status": "S", + "transaction_subject": "Payment for Invoice(s) 1", + "ending_balance": { + "currency_code": "USD", + "value": "900.00" + }, + "available_balance": { + "currency_code": "USD", + "value": "900.00" + }, + "invoice_id": "1" + }, + "payer_info": { + "account_id": "1234567890", + "email_address": "partner@example.com", + "address_status": "Y", + "payer_status": "N", + "payer_name": { + "alternate_full_name": "Acme, Inc." + }, + "country_code": "US" + }, + "shipping_info": {}, + "cart_info": {}, + "store_info": {}, + "auction_info": {}, + "incentive_info": {} +}""") + self.assertEqual(len(lines), 2) + self.assertEqual(lines[0], { + 'date': datetime(2019, 8, 1), + 'amount': '1000.00', + 'name': 'Invoice 1', + 'note': '1234567890: Payment for Invoice(s) 1', + 'partner_name': 'Acme, Inc.', + 'unique_import_id': '1234567890-1564617600', + }) + self.assertEqual(lines[1], { + 'date': datetime(2019, 8, 1), + 'amount': '-100.00', + 'name': 'Fee for Invoice 1', + 'note': 'Transaction fee for 1234567890: Payment for Invoice(s) 1', + 'partner_name': 'PayPal', + 'unique_import_id': '1234567890-1564617600-FEE', + }) + + def test_transaction_parse_4(self): + lines = self.paypal_parse_transaction("""{ + "transaction_info": { + "paypal_account_id": "1234567890", + "transaction_id": "1234567890", + "transaction_event_code": "T1234", + "transaction_initiation_date": "2019-08-01T00:00:00+0000", + "transaction_updated_date": "2019-08-01T00:00:00+0000", + "transaction_amount": { + "currency_code": "USD", + "value": "1000.00" + }, + "transaction_status": "S", + "transaction_subject": "Payment for Invoice(s) 1", + "ending_balance": { + "currency_code": "USD", + "value": "1000.00" + }, + "available_balance": { + "currency_code": "USD", + "value": "1000.00" + }, + "invoice_id": "1" + }, + "payer_info": { + "account_id": "1234567890", + "email_address": "partner@example.com", + "address_status": "Y", + "payer_status": "N", + "payer_name": { + "alternate_full_name": "Acme, Inc." + }, + "country_code": "US" + }, + "shipping_info": {}, + "cart_info": {}, + "store_info": {}, + "auction_info": {}, + "incentive_info": {} +}""") + self.assertEqual(len(lines), 1) + self.assertEqual(lines[0], { + 'date': datetime(2019, 8, 1), + 'amount': '1000.00', + 'name': 'Invoice 1', + 'note': '1234567890: Payment for Invoice(s) 1', + 'partner_name': 'Acme, Inc.', + 'unique_import_id': '1234567890-1564617600', + }) diff --git a/account_bank_statement_import_online_paypal/views/online_bank_statement_provider.xml b/account_bank_statement_import_online_paypal/views/online_bank_statement_provider.xml new file mode 100644 index 00000000..0ec34e05 --- /dev/null +++ b/account_bank_statement_import_online_paypal/views/online_bank_statement_provider.xml @@ -0,0 +1,40 @@ + + + + + + online.bank.statement.provider.form + online.bank.statement.provider + + + + + + + + + + + + + + +