From 473097b1f32ce25f7b4a716924143d82ac06eef8 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Sun, 10 Nov 2019 12:09:25 +0000 Subject: [PATCH] [IMP] account_bank_statement_import_paypal --- account_statement_import_paypal/README.rst | 59 +- account_statement_import_paypal/__init__.py | 2 + .../__manifest__.py | 51 +- account_statement_import_paypal/data/maps.xml | 54 ++ .../data/paypal_map_data.xml | 116 ---- .../account_bank_statement_import_paypal.pot | 381 +++++------- account_statement_import_paypal/i18n/es.po | 584 ++++++++++-------- .../migrations/12.0.2.0.0/post-migration.py | 103 +++ .../models/__init__.py | 6 +- .../models/account_bank_statement_import.py | 35 ++ ...ccount_bank_statement_import_paypal_map.py | 110 ---- ...nt_bank_statement_import_paypal_mapping.py | 130 ++++ ...unt_bank_statement_import_paypal_parser.py | 265 ++++++++ .../models/account_journal.py | 14 +- .../readme/CONFIGURE.rst | 14 +- .../readme/CONTRIBUTORS.rst | 2 + .../readme/DESCRIPTION.rst | 2 +- .../readme/HISTORY.rst | 7 + .../readme/USAGE.rst | 23 +- .../security/ir.model.access.csv | 4 +- .../static/description/index.html | 92 ++- .../static/description/paypal_backoffice.png | Bin 97703 -> 0 bytes .../tests/__init__.py | 4 +- .../tests/fixtures/activity_en.csv | 77 +++ .../tests/fixtures/empty_activity.csv | 1 + .../tests/fixtures/statement_en.csv | 20 + .../tests/paypal_en.csv | 3 - ...st_account_bank_statement_import_paypal.py | 132 ++++ .../tests/test_paypal_statement_import.py | 62 -- .../account_bank_statement_import.xml} | 11 +- ...t_bank_statement_import_paypal_mapping.xml | 78 +++ .../views/account_journal_views.xml | 16 - .../views/paypal_map_views.xml | 67 -- .../wizards/__init__.py | 5 +- .../account_bank_statement_import_paypal.py | 300 --------- ..._statement_import_paypal_mapping_wizard.py | 84 +++ ...statement_import_paypal_mapping_wizard.xml | 34 + .../wizards/create_map_lines_from_file.py | 39 -- .../create_map_lines_from_file_views.xml | 29 - 39 files changed, 1706 insertions(+), 1310 deletions(-) create mode 100644 account_statement_import_paypal/data/maps.xml delete mode 100644 account_statement_import_paypal/data/paypal_map_data.xml create mode 100644 account_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py create mode 100644 account_statement_import_paypal/models/account_bank_statement_import.py delete mode 100644 account_statement_import_paypal/models/account_bank_statement_import_paypal_map.py create mode 100644 account_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py create mode 100644 account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py create mode 100644 account_statement_import_paypal/readme/HISTORY.rst delete mode 100644 account_statement_import_paypal/static/description/paypal_backoffice.png create mode 100644 account_statement_import_paypal/tests/fixtures/activity_en.csv create mode 100644 account_statement_import_paypal/tests/fixtures/empty_activity.csv create mode 100644 account_statement_import_paypal/tests/fixtures/statement_en.csv delete mode 100644 account_statement_import_paypal/tests/paypal_en.csv create mode 100644 account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py delete mode 100644 account_statement_import_paypal/tests/test_paypal_statement_import.py rename account_statement_import_paypal/{wizards/account_bank_statement_import_view.xml => views/account_bank_statement_import.xml} (51%) create mode 100644 account_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml delete mode 100644 account_statement_import_paypal/views/account_journal_views.xml delete mode 100644 account_statement_import_paypal/views/paypal_map_views.xml delete mode 100644 account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py create mode 100644 account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py create mode 100644 account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml delete mode 100644 account_statement_import_paypal/wizards/create_map_lines_from_file.py delete mode 100644 account_statement_import_paypal/wizards/create_map_lines_from_file_views.xml diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst index f14ab9df..45816291 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -1,6 +1,6 @@ -============================= -Import Paypal Bank Statements -============================= +======================================== +PayPal CSV Format Bank Statements Import +======================================== .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! @@ -25,7 +25,7 @@ Import Paypal Bank Statements |badge1| |badge2| |badge3| |badge4| |badge5| -This module allows you to import the Paypal CSV files in Odoo as bank +This module allows you to import the PayPal CSV files in Odoo as bank statements. **Table of contents** @@ -36,30 +36,44 @@ statements. Configuration ============= -* Create or go to a bank journal where you want to import Paypal statement. -* Edit that journal and set a Paypal map in **Paypal Map** section in **Advanced - Settings** tab. +To adjust PayPal report columns mapping: -* Now you can import Paypal statements in that journal. - -Note: if existent Paypal Map does not fit to your file to import, you can -create another map in **Invoicing > Configuration > Accounting > Paypal -Mapping**. - -You can import headers from any Paypal file in **Action > Create Paypal Map -Lines** and set every line with which field of statement have to match. +#. Open *Invoicing > Configuration > Accounting > PayPal Report Mappings* +#. Modify mapping(s) according to your CSV reports format. Usage ===== -To use this module, you need to: +To import statements from PayPal via Statement report: -#. Go to Paypal and download your Bank Statement +#. Go to `PayPal `__ +#. Open *Reports > Statements* and select *Monthly* or *Custom* +#. Select date range of interest and click *Request* under *CSV* column +#. Wait for statement report to be generated +#. Download it and save to a file +#. Go to Odoo and and import saved statement file, selecting corresponding format -.. image:: https://raw.githubusercontent.com/OCA/bank-statement-import/12.0/account_bank_statement_import_paypal/account_bank_statement_import_paypal/static/description/paypal_backoffice.png - :alt: . -.. image:: https://raw.githubusercontent.com/OCA/bank-statement-import/12.0/account_bank_statement_import_paypal/static/description/paypal_backoffice.png - :alt: . +To import statements from PayPal via Activity report: + +#. Go to `PayPal `__ +#. Open *Reports > Activity download* +#. Set *Transaction type* to *Balance affecting* +#. Set *Format* to *CSV* +#. Select date range of interest and click *Create report* +#. Wait for activity report to be generated +#. Download it and save to a file +#. Go to Odoo and and import saved statement file, selecting corresponding format + +Changelog +========= + +12.0.2.0.0 +~~~~~~~~~~ + +* [BREAKING] New mapping, please review mappings after upgrade. +* [BREAKING] Different bank accounts have to be used per each currency. +* [ADD] Support for both Statement and Activity reports. +* [ADD] Separate fee and currency exchange parsing. Bug Tracker =========== @@ -78,6 +92,7 @@ Authors ~~~~~~~ * Akretion +* Brainbean Apps Contributors ~~~~~~~~~~~~ @@ -89,6 +104,8 @@ Contributors * Vicent Cubells * Victor M.M. Torres +* Alexey Pelykh + Maintainers ~~~~~~~~~~~ diff --git a/account_statement_import_paypal/__init__.py b/account_statement_import_paypal/__init__.py index aee8895e..adc6207f 100644 --- a/account_statement_import_paypal/__init__.py +++ b/account_statement_import_paypal/__init__.py @@ -1,2 +1,4 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + from . import models from . import wizards diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index 4322ee12..78e9b009 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -1,26 +1,33 @@ # Copyright 2014-2017 Akretion (http://www.akretion.com). -# @author Alexis de Lattre -# @author Sébastien BEAU -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +# Copyright 2019 Tecnativa - Vicent Cubells +# Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + { - "name": "Import Paypal Bank Statements", - 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', - "version": "12.0.1.1.0", - "category": "Accounting", - "website": "https://github.com/OCA/bank-statement-import", - "author": " Akretion, Odoo Community Association (OCA)", - "license": "AGPL-3", - "installable": True, - "depends": [ - "account_bank_statement_import", - "sale", + 'name': 'PayPal CSV Format Bank Statements Import', + 'summary': 'Import PayPal CSV files as Bank Statements in Odoo', + 'version': '12.0.2.0.0', + 'category': 'Accounting', + 'website': 'https://github.com/OCA/bank-statement-import', + 'author': + 'Akretion, ' + 'Brainbean Apps, ' + 'Odoo Community Association (OCA)', + 'license': 'AGPL-3', + 'installable': True, + 'depends': [ + 'account_bank_statement_import', + ], + 'external_dependencies': { + 'python': [ + 'csv', + ] + }, + 'data': [ + 'security/ir.model.access.csv', + 'data/maps.xml', + 'views/account_bank_statement_import_paypal_mapping.xml', + 'views/account_bank_statement_import.xml', + 'wizards/account_bank_statement_import_paypal_mapping_wizard.xml', ], - "data": [ - "security/ir.model.access.csv", - "data/paypal_map_data.xml", - "wizards/create_map_lines_from_file_views.xml", - "wizards/account_bank_statement_import_view.xml", - "views/account_journal_views.xml", - "views/paypal_map_views.xml", - ] } diff --git a/account_statement_import_paypal/data/maps.xml b/account_statement_import_paypal/data/maps.xml new file mode 100644 index 00000000..78337e43 --- /dev/null +++ b/account_statement_import_paypal/data/maps.xml @@ -0,0 +1,54 @@ + + + + + + PayPal Statement (EN) + comma + dot + %m/%d/%Y + %H:%M:%S + Date + Time + Time Zone + Name + Currency + Gross + Fee + Balance + Transaction ID + Description + From Email Address + Invoice ID + Bank Name + Bank Account + + + + PayPal Activity (EN) + comma + dot + %d/%m/%Y + %H:%M:%S + Date + Time + TimeZone + Name + Currency + Gross + Fee + Balance + Transaction ID + Type + From Email Address + To Email Address + Invoice ID + Subject + Note + + + diff --git a/account_statement_import_paypal/data/paypal_map_data.xml b/account_statement_import_paypal/data/paypal_map_data.xml deleted file mode 100644 index 0eeef9ba..00000000 --- a/account_statement_import_paypal/data/paypal_map_data.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - Paypal Monthly Statement - comma - dot - - - - Date - 0 - - date - %m/%d/%Y - - - Time - 1 - - time - - - Time Zone - 2 - - - - Description - 3 - - description - - - Currency - 4 - - currency - - - Gross - 5 - - amount - - - Fee - 6 - - commission - - - Net - 7 - - - - Balance - 8 - - balance - - - Transaction ID - 9 - - transaction_id - - - From Email Address - 10 - - email - - - Name - 11 - - partner_name - - - Bank Name - 12 - - bank_name - - - Bank Account - 13 - - bank_account - - - Shipping and Handling Amount - 14 - - - - Sales Tax - 15 - - - - Invoice ID - 16 - - invoice_number - - - Reference Txn ID - 17 - - origin_transaction_id - - - diff --git a/account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot b/account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot index b61b35a0..3eb82bdd 100644 --- a/account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot +++ b/account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot @@ -14,173 +14,216 @@ msgstr "" "Plural-Forms: \n" #. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map -msgid "Account Bank Statement Import Paypal Map" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__balance_column +msgid "\"Balance\" column" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map_line -msgid "Account Bank Statement Import Paypal Map Line" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__bank_account_column +msgid "\"Bank Account\" column" msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "All the Paypal map lines will be created automatically." +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__bank_name_column +msgid "\"Bank Name\" column" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Balance" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__currency_column +msgid "\"Currency\" column" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Bank Account" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__date_column +msgid "\"Date\" column" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Bank Name" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__description_column +msgid "\"Description\" column" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__data_file +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__fee_column +msgid "\"Fee\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__from_email_address_column +msgid "\"From Email Address\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__gross_column +msgid "\"Gross\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__invoice_id_column +msgid "\"Invoice ID\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__name_column +msgid "\"Name\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__note_column +msgid "\"Note\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__subject_column +msgid "\"Subject\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__time_column +msgid "\"Time\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__tz_column +msgid "\"Timezone\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__to_email_address_column +msgid "\"To Email Address\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__transaction_id_column +msgid "\"Transaction ID\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__type_column +msgid "\"Type\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:43 +#, python-format +msgid "%s: %s" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_mapping +msgid "Account Bank Statement Import PayPal Mapping" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_mapping_wizard +msgid "Account Bank Statement Import PayPal Mapping Wizard" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_parser +msgid "Account Bank Statement Import PayPal Parser" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__data_file msgid "Bank Statement File" msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form msgid "Cancel" msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form msgid "Choose a file to import..." msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Create Lines" +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_tree +msgid "Columns" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_create_paypal_map_lines -msgid "Create Paypal Map Lines" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__create_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__create_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__create_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__create_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__create_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__create_uid msgid "Created by" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__create_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__create_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__create_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__create_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__create_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__create_date msgid "Created on" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Currency" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Date" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__date_format +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__date_format msgid "Date Format" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:97 -#, python-format -msgid "Date format of map file and Paypal date does not match." +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__float_decimal_sep +msgid "Decimals Separator" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__float_decimal_sep -msgid "Decimals separator" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Description" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__display_name -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__display_name -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__display_name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__display_name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__display_name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__display_name msgid "Display Name" msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Download a bank statement from your bank and import it here." +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:245 +#, python-format +msgid "Fee for %s" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Fee" +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:70 +#, python-format +msgid "File structure does not look like a PayPal report, please check the file or create the mapping manually." msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__sequence -msgid "Field number" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__filename +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__filename msgid "Filename" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "From Email Address" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Gross" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__name -msgid "Header Name" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:80 -#, python-format -msgid "Headers of file to import and Paypal map lines does not match." -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__id -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__id -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__id +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__id +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__id +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__id msgid "ID" msgstr "" +#. module: account_bank_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form +msgid "Import" +msgstr "" + #. module: account_bank_statement_import_paypal #: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import msgid "Import Bank Statement" msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Import Paypal Map Lines" +#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_account_bank_statement_import_paypal_mapping_wizard +msgid "Import Mapping" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Invoice ID" +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:78 +#, python-format +msgid "Imported Mapping" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:215 +#, python-format +msgid "Invoice %s" msgstr "" #. module: account_bank_statement_import_paypal @@ -189,177 +232,89 @@ msgid "Journal" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map____last_update -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line____last_update -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create____last_update +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping____last_update +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard____last_update +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser____last_update msgid "Last Modified on" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__write_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__write_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__write_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__write_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__write_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__write_uid msgid "Last Updated by" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__write_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__write_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__write_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__write_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__write_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__write_date msgid "Last Updated on" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__map_parent_id -msgid "Map Parent" +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:26 +#, python-format +msgid "Mapping from %s" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__map_line_ids -msgid "Map lines" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form -msgid "Mapping Lines" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__name msgid "Name" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Origin Transaction ID" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:233 -#, python-format -msgid "PAYPAL-COSTS" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:198 -#, python-format -msgid "PayPal Import %s > %s" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_journal__paypal_map_id -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_tree -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.view_account_journal_form_n43 -msgid "Paypal Map" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_statement_import_paypal_mappging +#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_statement_import_paypal_report_mappings #: model:ir.ui.menu,name:account_bank_statement_import_paypal.menu_statement_import_paypal_mapping -msgid "Paypal Mapping" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:232 -#, python-format -msgid "Paypal commissions" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import__paypal_map_id -msgid "Paypal map" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_form -msgid "Paypal mapping line" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_tree -msgid "Paypal mapping lines" +msgid "PayPal Report Mappings" msgstr "" #. module: account_bank_statement_import_paypal #: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view -msgid "Paypal with Template:" +msgid "PayPal Report mapping:" msgstr "" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Select a Paypal bank statement file to create all the map lines from headers file." +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import__paypal_mapping_id +msgid "PayPal mapping" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__field_to_assign -msgid "Statement Field to Assign" +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form +msgid "Select a PayPal report file to import mapping." msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__float_thousands_sep -msgid "Thousands separator" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__float_thousands_sep +msgid "Thousands Separator" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Time" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__time_format +msgid "Time Format" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Transaction ID" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:107 +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:250 #, python-format -msgid "Value '%s' for the field '%s' on line %d, cannot be converted to float" +msgid "Transaction fee for %s" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_wizard_paypal_map_create -msgid "Wizard Paypal Map Create" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:144 -#, python-format -msgid "You must run this wizard from the journal" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 -#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_thousands_sep:0 msgid "comma (,)" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:129 -#, python-format -msgid "currency %s on line %d cannot be found in odoo" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 -#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_thousands_sep:0 msgid "dot (.)" msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,date_format:0 -msgid "i.e. 12/15/2019" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,date_format:0 -msgid "i.e. 15/12/2019" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 -#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_thousands_sep:0 msgid "none" msgstr "" diff --git a/account_statement_import_paypal/i18n/es.po b/account_statement_import_paypal/i18n/es.po index f55eceeb..878f40ad 100644 --- a/account_statement_import_paypal/i18n/es.po +++ b/account_statement_import_paypal/i18n/es.po @@ -18,181 +18,248 @@ msgstr "" "X-Generator: Weblate 3.7.1\n" #. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__balance_column #, fuzzy -#| msgid "account.bank.statement.import.paypal.map" -msgid "Account Bank Statement Import Paypal Map" -msgstr "account.bank.statement.import.paypal.map" - -#. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map_line -#, fuzzy -#| msgid "account.bank.statement.import.paypal.map.line" -msgid "Account Bank Statement Import Paypal Map Line" -msgstr "account.bank.statement.import.paypal.map.line" - -#. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "All the Paypal map lines will be created automatically." -msgstr "Todas las lineas de la plantilla se crearán automáticamente." - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Balance" +#| msgid "Balance" +msgid "\"Balance\" column" msgstr "Saldo" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Bank Account" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__bank_account_column +#, fuzzy +#| msgid "Bank Account" +msgid "\"Bank Account\" column" msgstr "Cuenta bancaria" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Bank Name" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__bank_name_column +#, fuzzy +#| msgid "Bank Name" +msgid "\"Bank Name\" column" msgstr "Nombre del banco" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__data_file +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__currency_column +#, fuzzy +#| msgid "Currency" +msgid "\"Currency\" column" +msgstr "Moneda" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__date_column +msgid "\"Date\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__description_column +#, fuzzy +#| msgid "Description" +msgid "\"Description\" column" +msgstr "Descripción" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__fee_column +msgid "\"Fee\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__from_email_address_column +#, fuzzy +#| msgid "From Email Address" +msgid "\"From Email Address\" column" +msgstr "Correo electrónico del remitente" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__gross_column +msgid "\"Gross\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__invoice_id_column +#, fuzzy +#| msgid "Invoice ID" +msgid "\"Invoice ID\" column" +msgstr "Número de factura" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__name_column +msgid "\"Name\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__note_column +msgid "\"Note\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__subject_column +msgid "\"Subject\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__time_column +msgid "\"Time\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__tz_column +msgid "\"Timezone\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__to_email_address_column +#, fuzzy +#| msgid "From Email Address" +msgid "\"To Email Address\" column" +msgstr "Correo electrónico del remitente" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__transaction_id_column +#, fuzzy +#| msgid "Transaction ID" +msgid "\"Transaction ID\" column" +msgstr "Id. de transacción" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__type_column +msgid "\"Type\" column" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:43 +#, python-format +msgid "%s: %s" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_mapping +#, fuzzy +#| msgid "account.bank.statement.import.paypal.map" +msgid "Account Bank Statement Import PayPal Mapping" +msgstr "account.bank.statement.import.paypal.map" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_mapping_wizard +#, fuzzy +#| msgid "account.bank.statement.import.paypal.map" +msgid "Account Bank Statement Import PayPal Mapping Wizard" +msgstr "account.bank.statement.import.paypal.map" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_parser +#, fuzzy +#| msgid "account.bank.statement.import.paypal.map" +msgid "Account Bank Statement Import PayPal Parser" +msgstr "account.bank.statement.import.paypal.map" + +#. module: account_bank_statement_import_paypal +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__data_file msgid "Bank Statement File" msgstr "Archivo de extracto bancario" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form msgid "Cancel" msgstr "Cancelar" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form msgid "Choose a file to import..." msgstr "Escoja un archivo a importar..." #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Create Lines" -msgstr "Crear líneas" +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_tree +msgid "Columns" +msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_create_paypal_map_lines -msgid "Create Paypal Map Lines" -msgstr "Crear las líneas de la plantilla de Paypal" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__create_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__create_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__create_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__create_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__create_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__create_uid msgid "Created by" msgstr "Creado el" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__create_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__create_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__create_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__create_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__create_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__create_date msgid "Created on" msgstr "Creado por" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Currency" -msgstr "Moneda" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Date" -msgstr "Fecha" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__date_format +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__date_format msgid "Date Format" msgstr "Formato de fecha" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:97 -#, python-format -msgid "Date format of map file and Paypal date does not match." -msgstr "" -"El format de fecha del archivo de plantilla y la fecha de Paypal no " -"coinciden." - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__float_decimal_sep -msgid "Decimals separator" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__float_decimal_sep +#, fuzzy +#| msgid "Decimals separator" +msgid "Decimals Separator" msgstr "Separador decimal" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Description" -msgstr "Descripción" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__display_name -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__display_name -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__display_name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__display_name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__display_name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__display_name msgid "Display Name" msgstr "Nombre mostrado" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Download a bank statement from your bank and import it here." -msgstr "Descargue un extracto bancario desde su banco e impórtelo aquí." +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:245 +#, python-format +msgid "Fee for %s" +msgstr "" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Fee" -msgstr "Tarifa" +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:70 +#, python-format +msgid "" +"File structure does not look like a PayPal report, please check the file or " +"create the mapping manually." +msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__sequence -msgid "Field number" -msgstr "Nº de campo" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__filename +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__filename msgid "Filename" msgstr "Nombre de archivo" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "From Email Address" -msgstr "Correo electrónico del remitente" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Gross" -msgstr "Bruto" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__name -msgid "Header Name" -msgstr "Nombre de la cabecera" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:80 -#, python-format -msgid "Headers of file to import and Paypal map lines does not match." -msgstr "" -"La cabecera del archivo a importar y las lineas de la plantilla de Paypal no " -"coinciden." - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__id -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__id -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__id +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__id +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__id +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__id msgid "ID" msgstr "ID" +#. module: account_bank_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form +msgid "Import" +msgstr "" + #. module: account_bank_statement_import_paypal #: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import msgid "Import Bank Statement" msgstr "Importar Extracto Bancario" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "Import Paypal Map Lines" +#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_account_bank_statement_import_paypal_mapping_wizard +#, fuzzy +#| msgid "Import Paypal Map Lines" +msgid "Import Mapping" msgstr "Importar las lineas de la plantilla de Paypal" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Invoice ID" +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:78 +#, fuzzy, python-format +#| msgid "Import Paypal Map Lines" +msgid "Imported Mapping" +msgstr "Importar las lineas de la plantilla de Paypal" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:215 +#, fuzzy, python-format +#| msgid "Invoice ID" +msgid "Invoice %s" msgstr "Número de factura" #. module: account_bank_statement_import_paypal @@ -201,183 +268,210 @@ msgid "Journal" msgstr "Diario" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map____last_update -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line____last_update -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create____last_update +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping____last_update +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard____last_update +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser____last_update msgid "Last Modified on" msgstr "Última modificación en" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__write_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__write_uid -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__write_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__write_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__write_uid +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__write_uid msgid "Last Updated by" msgstr "Última actualización por" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__write_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__write_date -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_wizard_paypal_map_create__write_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__write_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__write_date +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_parser__write_date msgid "Last Updated on" msgstr "Última actualización en" #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__map_parent_id -msgid "Map Parent" -msgstr "Plantilla padre" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__map_line_ids -msgid "Map lines" +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:26 +#, fuzzy, python-format +#| msgid "Mapping Lines" +msgid "Mapping from %s" msgstr "Líneas de la plantilla" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form -msgid "Mapping Lines" -msgstr "Líneas de la plantilla" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__name +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__name msgid "Name" msgstr "Nombre" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Origin Transaction ID" -msgstr "Id. de transacción" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:233 -#, python-format -msgid "PAYPAL-COSTS" -msgstr "COSTES-PAYPAL" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:198 -#, python-format -msgid "PayPal Import %s > %s" -msgstr "Importación de Paypal %s > %s" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_journal__paypal_map_id -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_tree -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.view_account_journal_form_n43 -msgid "Paypal Map" -msgstr "Plantilla de Paypal" - -#. module: account_bank_statement_import_paypal -#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_statement_import_paypal_mappging +#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_statement_import_paypal_report_mappings #: model:ir.ui.menu,name:account_bank_statement_import_paypal.menu_statement_import_paypal_mapping -msgid "Paypal Mapping" +#, fuzzy +#| msgid "Paypal Mapping" +msgid "PayPal Report Mappings" msgstr "Plantilla de Paypal" -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:232 -#, python-format -msgid "Paypal commissions" -msgstr "Tarifa de Paypal" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import__paypal_map_id -msgid "Paypal map" -msgstr "Plantilla de Paypal" - -#. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_form -msgid "Paypal mapping line" -msgstr "Línea de plantilla de Paypal" - -#. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_tree -msgid "Paypal mapping lines" -msgstr "Líneas de plantilla de Paypal" - #. module: account_bank_statement_import_paypal #: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view -msgid "Paypal with Template:" -msgstr "Paypal con la plantilla:" +#, fuzzy +#| msgid "Paypal Mapping" +msgid "PayPal Report mapping:" +msgstr "Plantilla de Paypal" #. module: account_bank_statement_import_paypal -#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view -msgid "" -"Select a Paypal bank statement file to create all the map lines from headers " -"file." +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import__paypal_mapping_id +#, fuzzy +#| msgid "Paypal Mapping" +msgid "PayPal mapping" +msgstr "Plantilla de Paypal" + +#. module: account_bank_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_paypal_mapping_wizard_form +msgid "Select a PayPal report file to import mapping." msgstr "" -"Seleccione un archivo de extracto bancario de Paypal para crear todas las " -"lineas de la plantilla a partir de la cabecera del archivo." #. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_line__field_to_assign -msgid "Statement Field to Assign" -msgstr "Campo del extracto a asignar" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map__float_thousands_sep -msgid "Thousands separator" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__float_thousands_sep +#, fuzzy +#| msgid "Thousands separator" +msgid "Thousands Separator" msgstr "Separador de miles" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Time" -msgstr "Hora" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__time_format +#, fuzzy +#| msgid "Date Format" +msgid "Time Format" +msgstr "Formato de fecha" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 -msgid "Transaction ID" +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:250 +#, fuzzy, python-format +#| msgid "Transaction ID" +msgid "Transaction fee for %s" msgstr "Id. de transacción" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:107 -#, python-format -msgid "Value '%s' for the field '%s' on line %d, cannot be converted to float" -msgstr "" -"El valor '%s' del campo '%s' en la línea %d, no se puede convertir a float" - -#. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_wizard_paypal_map_create -#, fuzzy -#| msgid "wizard.paypal.map.create" -msgid "Wizard Paypal Map Create" -msgstr "wizard.paypal.map.create" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:144 -#, python-format -msgid "You must run this wizard from the journal" -msgstr "Debe ejecutar este asistente des del diario" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 -#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_thousands_sep:0 msgid "comma (,)" msgstr "coma (,)" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:129 -#, python-format -msgid "currency %s on line %d cannot be found in odoo" -msgstr "la monea %s de la línea %d no se puede encontrar en odoo" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 -#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_thousands_sep:0 msgid "dot (.)" msgstr "punto (.)" #. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,date_format:0 -msgid "i.e. 12/15/2019" -msgstr "p.e. 12/15/2019" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map.line,date_format:0 -msgid "i.e. 15/12/2019" -msgstr "p.e. 15/12/2019" - -#. module: account_bank_statement_import_paypal -#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 -#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.mapping,float_thousands_sep:0 msgid "none" msgstr "nada" + +#, fuzzy +#~| msgid "account.bank.statement.import.paypal.map.line" +#~ msgid "Account Bank Statement Import Paypal Map Line" +#~ msgstr "account.bank.statement.import.paypal.map.line" + +#~ msgid "All the Paypal map lines will be created automatically." +#~ msgstr "Todas las lineas de la plantilla se crearán automáticamente." + +#~ msgid "Create Lines" +#~ msgstr "Crear líneas" + +#~ msgid "Create Paypal Map Lines" +#~ msgstr "Crear las líneas de la plantilla de Paypal" + +#~ msgid "Date" +#~ msgstr "Fecha" + +#~ msgid "Date format of map file and Paypal date does not match." +#~ msgstr "" +#~ "El format de fecha del archivo de plantilla y la fecha de Paypal no " +#~ "coinciden." + +#~ msgid "Download a bank statement from your bank and import it here." +#~ msgstr "Descargue un extracto bancario desde su banco e impórtelo aquí." + +#~ msgid "Fee" +#~ msgstr "Tarifa" + +#~ msgid "Field number" +#~ msgstr "Nº de campo" + +#~ msgid "Gross" +#~ msgstr "Bruto" + +#~ msgid "Header Name" +#~ msgstr "Nombre de la cabecera" + +#~ msgid "Headers of file to import and Paypal map lines does not match." +#~ msgstr "" +#~ "La cabecera del archivo a importar y las lineas de la plantilla de Paypal " +#~ "no coinciden." + +#~ msgid "Map Parent" +#~ msgstr "Plantilla padre" + +#~ msgid "Map lines" +#~ msgstr "Líneas de la plantilla" + +#~ msgid "Origin Transaction ID" +#~ msgstr "Id. de transacción" + +#~ msgid "PAYPAL-COSTS" +#~ msgstr "COSTES-PAYPAL" + +#~ msgid "PayPal Import %s > %s" +#~ msgstr "Importación de Paypal %s > %s" + +#~ msgid "Paypal Map" +#~ msgstr "Plantilla de Paypal" + +#~ msgid "Paypal commissions" +#~ msgstr "Tarifa de Paypal" + +#~ msgid "Paypal map" +#~ msgstr "Plantilla de Paypal" + +#~ msgid "Paypal mapping line" +#~ msgstr "Línea de plantilla de Paypal" + +#~ msgid "Paypal mapping lines" +#~ msgstr "Líneas de plantilla de Paypal" + +#~ msgid "Paypal with Template:" +#~ msgstr "Paypal con la plantilla:" + +#~ msgid "" +#~ "Select a Paypal bank statement file to create all the map lines from " +#~ "headers file." +#~ msgstr "" +#~ "Seleccione un archivo de extracto bancario de Paypal para crear todas las " +#~ "lineas de la plantilla a partir de la cabecera del archivo." + +#~ msgid "Statement Field to Assign" +#~ msgstr "Campo del extracto a asignar" + +#~ msgid "Time" +#~ msgstr "Hora" + +#~ msgid "" +#~ "Value '%s' for the field '%s' on line %d, cannot be converted to float" +#~ msgstr "" +#~ "El valor '%s' del campo '%s' en la línea %d, no se puede convertir a float" + +#, fuzzy +#~| msgid "wizard.paypal.map.create" +#~ msgid "Wizard Paypal Map Create" +#~ msgstr "wizard.paypal.map.create" + +#~ msgid "You must run this wizard from the journal" +#~ msgstr "Debe ejecutar este asistente des del diario" + +#~ msgid "currency %s on line %d cannot be found in odoo" +#~ msgstr "la monea %s de la línea %d no se puede encontrar en odoo" + +#~ msgid "i.e. 12/15/2019" +#~ msgstr "p.e. 12/15/2019" + +#~ msgid "i.e. 15/12/2019" +#~ msgstr "p.e. 15/12/2019" diff --git a/account_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py b/account_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py new file mode 100644 index 00000000..e2155720 --- /dev/null +++ b/account_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py @@ -0,0 +1,103 @@ +# Copyright 2020 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.logged_query( + env.cr, + """ +WITH _mappings AS ( + SELECT + m.id, + l.field_to_assign, + l.name, + l.date_format + FROM + account_bank_statement_import_paypal_map AS m + RIGHT OUTER JOIN ( + SELECT + *, + ROW_NUMBER() OVER ( + PARTITION BY map_parent_id, field_to_assign + ORDER BY id ASC + ) AS row_number + FROM account_bank_statement_import_paypal_map_line + WHERE field_to_assign IS NOT NULL + ) AS l ON m.id = l.map_parent_id AND l.row_number = 1 +) + +INSERT INTO account_bank_statement_import_paypal_mapping ( + name, + float_thousands_sep, + float_decimal_sep, + date_format, + time_format, + date_column, + time_column, + tz_column, + name_column, + currency_column, + gross_column, + fee_column, + balance_column, + transaction_id_column, + description_column, + from_email_address_column, + invoice_id_column, + bank_name_column, + bank_account_column +) +SELECT + m.name, + m.float_thousands_sep, + m.float_decimal_sep, + COALESCE(_date.date_format, '%m/%d/%Y') AS date_format, + '%H:%M:%S' AS time_format, + COALESCE(_date.name, 'Date') AS date_column, + COALESCE(_time.name, 'Time') AS time_column, + 'Time Zone' AS tz_column, + COALESCE(_name.name, 'Name') AS name_column, + COALESCE(_currency.name, 'Currency') AS currency_column, + COALESCE(_gross.name, 'Gross') AS gross_column, + COALESCE(_fee.name, 'Fee') AS fee_column, + COALESCE(_balance.name, 'Balance') AS balance_column, + COALESCE(_tid.name, 'Transaction ID') AS transaction_id_column, + COALESCE(_description.name, 'Description') AS description_column, + COALESCE(_from_email.name, 'From Email Address') + AS from_email_address_column, + COALESCE(_invoice.name, 'Invoice ID') AS invoice_id_column, + COALESCE(_bank_name.name, 'Bank Name') AS bank_name_column, + COALESCE(_bank_acc.name, 'Bank Account') AS bank_account_column +FROM + account_bank_statement_import_paypal_map AS m +LEFT JOIN _mappings AS _date + ON m.id = _date.id AND _date.field_to_assign = 'date' +LEFT JOIN _mappings AS _time + ON m.id = _time.id AND _time.field_to_assign = 'time' +LEFT JOIN _mappings AS _name + ON m.id = _name.id AND _name.field_to_assign = 'partner_name' +LEFT JOIN _mappings AS _currency + ON m.id = _currency.id AND _currency.field_to_assign = 'currency' +LEFT JOIN _mappings AS _gross + ON m.id = _gross.id AND _gross.field_to_assign = 'amount' +LEFT JOIN _mappings AS _fee + ON m.id = _fee.id AND _fee.field_to_assign = 'commission' +LEFT JOIN _mappings AS _balance + ON m.id = _balance.id AND _balance.field_to_assign = 'balance' +LEFT JOIN _mappings AS _tid + ON m.id = _tid.id AND _tid.field_to_assign = 'transaction_id' +LEFT JOIN _mappings AS _description + ON m.id = _description.id AND _description.field_to_assign = 'description' +LEFT JOIN _mappings AS _from_email + ON m.id = _from_email.id AND _from_email.field_to_assign = 'email' +LEFT JOIN _mappings AS _invoice + ON m.id = _invoice.id AND _invoice.field_to_assign = 'invoice_number' +LEFT JOIN _mappings AS _bank_name + ON m.id = _bank_name.id AND _bank_name.field_to_assign = 'bank_name' +LEFT JOIN _mappings AS _bank_acc + ON m.id = _bank_acc.id AND _bank_acc.field_to_assign = 'bank_account'; + """ + ) diff --git a/account_statement_import_paypal/models/__init__.py b/account_statement_import_paypal/models/__init__.py index 4257b3bc..42211d54 100644 --- a/account_statement_import_paypal/models/__init__.py +++ b/account_statement_import_paypal/models/__init__.py @@ -1,2 +1,6 @@ -from . import account_bank_statement_import_paypal_map +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import account_bank_statement_import_paypal_mapping +from . import account_bank_statement_import_paypal_parser +from . import account_bank_statement_import from . import account_journal diff --git a/account_statement_import_paypal/models/account_bank_statement_import.py b/account_statement_import_paypal/models/account_bank_statement_import.py new file mode 100644 index 00000000..4d3d08cf --- /dev/null +++ b/account_statement_import_paypal/models/account_bank_statement_import.py @@ -0,0 +1,35 @@ +# Copyright 2014-2017 Akretion (http://www.akretion.com). +# Copyright 2019 Tecnativa - Vicent Cubells +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + +import logging +_logger = logging.getLogger(__name__) + + +class AccountBankStatementImport(models.TransientModel): + _inherit = 'account.bank.statement.import' + + paypal_mapping_id = fields.Many2one( + string='PayPal mapping', + comodel_name='account.bank.statement.import.paypal.mapping', + ) + + @api.multi + def _parse_file(self, data_file): + self.ensure_one() + try: + Parser = self.env['account.bank.statement.import.paypal.parser'] + return Parser.parse( + self.paypal_mapping_id, + data_file, + self.filename + ) + except: + if self.env.context.get( + 'account_bank_statement_import_paypal_test'): + raise + _logger.warning('PayPal parser error', exc_info=True) + return super()._parse_file(data_file) diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal_map.py b/account_statement_import_paypal/models/account_bank_statement_import_paypal_map.py deleted file mode 100644 index 06c82ef9..00000000 --- a/account_statement_import_paypal/models/account_bank_statement_import_paypal_map.py +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright 2019 Tecnativa - Vicent Cubells -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import fields, models, api - - -class AccountBankStatementImportPaypalMap(models.Model): - _name = 'account.bank.statement.import.paypal.map' - _description = 'Account Bank Statement Import Paypal Map' - - name = fields.Char( - required=True, - ) - map_line_ids = fields.One2many( - comodel_name='account.bank.statement.import.paypal.map.line', - inverse_name='map_parent_id', - string="Map lines", - required=True, - copy=True, - ) - float_thousands_sep = fields.Selection( - [('dot', 'dot (.)'), - ('comma', 'comma (,)'), - ('none', 'none'), - ], - string='Thousands separator', - # forward compatibility: this was the value assumed - # before the field was added. - default='dot', - required=True - ) - float_decimal_sep = fields.Selection( - [('dot', 'dot (.)'), - ('comma', 'comma (,)'), - ('none', 'none'), - ], - string='Decimals separator', - # forward compatibility: this was the value assumed - # before the field was added. - default='comma', - required=True - ) - - @api.onchange('float_thousands_sep') - def onchange_thousands_separator(self): - if 'dot' == self.float_thousands_sep == self.float_decimal_sep: - self.float_decimal_sep = 'comma' - elif 'comma' == self.float_thousands_sep == self.float_decimal_sep: - self.float_decimal_sep = 'dot' - - @api.onchange('float_decimal_sep') - def onchange_decimal_separator(self): - if 'dot' == self.float_thousands_sep == self.float_decimal_sep: - self.float_thousands_sep = 'comma' - elif 'comma' == self.float_thousands_sep == self.float_decimal_sep: - self.float_thousands_sep = 'dot' - - def _get_separators(self): - separators = {'dot': '.', - 'comma': ',', - 'none': '', - } - return (separators[self.float_thousands_sep], - separators[self.float_decimal_sep]) - - -class AccountBankStatementImportPaypalMapLine(models.Model): - _name = 'account.bank.statement.import.paypal.map.line' - _description = 'Account Bank Statement Import Paypal Map Line' - _order = "sequence asc, id asc" - - sequence = fields.Integer( - string="Field number", - required=True, - ) - name = fields.Char( - string="Header Name", - required=True, - ) - map_parent_id = fields.Many2one( - comodel_name='account.bank.statement.import.paypal.map', - required=True, - ondelete='cascade', - ) - field_to_assign = fields.Selection( - selection=[ - ('date', 'Date'), - ('time', 'Time'), - ('description', 'Description'), - ('currency', 'Currency'), - ('amount', 'Gross'), - ('commission', 'Fee'), - ('balance', 'Balance'), - ('transaction_id', 'Transaction ID'), - ('email', 'From Email Address'), - ('partner_name', 'Name'), - ('bank_name', 'Bank Name'), - ('bank_account', 'Bank Account'), - ('invoice_number', 'Invoice ID'), - ('origin_transaction_id', 'Origin Transaction ID'), - ], - string="Statement Field to Assign", - ) - date_format = fields.Selection( - selection=[ - ('%d/%m/%Y', 'i.e. 15/12/2019'), - ('%m/%d/%Y', 'i.e. 12/15/2019'), - ], - string="Date Format", - ) diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py b/account_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py new file mode 100644 index 00000000..e87ddcf9 --- /dev/null +++ b/account_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py @@ -0,0 +1,130 @@ +# Copyright 2019 Tecnativa - Vicent Cubells +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class AccountBankStatementImportPayPalMapping(models.Model): + _name = 'account.bank.statement.import.paypal.mapping' + _description = 'Account Bank Statement Import PayPal Mapping' + + name = fields.Char( + required=True, + ) + float_thousands_sep = fields.Selection( + string='Thousands Separator', + selection=[ + ('dot', 'dot (.)'), + ('comma', 'comma (,)'), + ('none', 'none'), + ], + default='dot', + required=True, + ) + float_decimal_sep = fields.Selection( + string='Decimals Separator', + selection=[ + ('dot', 'dot (.)'), + ('comma', 'comma (,)'), + ('none', 'none'), + ], + default='comma', + required=True, + ) + date_format = fields.Char( + string='Date Format', + required=True, + ) + time_format = fields.Char( + string='Time Format', + required=True, + ) + date_column = fields.Char( + string='"Date" column', + required=True, + ) + time_column = fields.Char( + string='"Time" column', + required=True, + ) + tz_column = fields.Char( + string='"Timezone" column', + required=True, + ) + name_column = fields.Char( + string='"Name" column', + required=True, + ) + currency_column = fields.Char( + string='"Currency" column', + required=True, + ) + gross_column = fields.Char( + string='"Gross" column', + required=True, + ) + fee_column = fields.Char( + string='"Fee" column', + required=True, + ) + balance_column = fields.Char( + string='"Balance" column', + required=True, + ) + transaction_id_column = fields.Char( + string='"Transaction ID" column', + required=True, + ) + description_column = fields.Char( + string='"Description" column', + ) + type_column = fields.Char( + string='"Type" column', + ) + from_email_address_column = fields.Char( + string='"From Email Address" column', + ) + to_email_address_column = fields.Char( + string='"To Email Address" column', + ) + invoice_id_column = fields.Char( + string='"Invoice ID" column', + ) + subject_column = fields.Char( + string='"Subject" column', + ) + note_column = fields.Char( + string='"Note" column', + ) + bank_name_column = fields.Char( + string='"Bank Name" column', + ) + bank_account_column = fields.Char( + string='"Bank Account" column', + ) + + @api.onchange('float_thousands_sep') + def onchange_thousands_separator(self): + if 'dot' == self.float_thousands_sep == self.float_decimal_sep: + self.float_decimal_sep = 'comma' + elif 'comma' == self.float_thousands_sep == self.float_decimal_sep: + self.float_decimal_sep = 'dot' + + @api.onchange('float_decimal_sep') + def onchange_decimal_separator(self): + if 'dot' == self.float_thousands_sep == self.float_decimal_sep: + self.float_thousands_sep = 'comma' + elif 'comma' == self.float_thousands_sep == self.float_decimal_sep: + self.float_thousands_sep = 'dot' + + @api.multi + def _get_float_separators(self): + self.ensure_one() + separators = { + 'dot': '.', + 'comma': ',', + 'none': '', + } + return (separators[self.float_thousands_sep], + separators[self.float_decimal_sep]) diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py b/account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py new file mode 100644 index 00000000..cdc9bcc7 --- /dev/null +++ b/account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py @@ -0,0 +1,265 @@ +# Copyright 2019 Tecnativa - Vicent Cubells +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, models, _ + +from datetime import datetime +from decimal import Decimal +from io import StringIO +from os import path +import itertools +from pytz import timezone, utc + +import logging +_logger = logging.getLogger(__name__) + +try: + from csv import reader +except (ImportError, IOError) as err: + _logger.error(err) + + +class AccountBankStatementImportPayPalParser(models.TransientModel): + _name = 'account.bank.statement.import.paypal.parser' + _description = 'Account Bank Statement Import PayPal Parser' + + @api.model + def parse_header(self, data_file): + data = StringIO(data_file.decode('utf-8-sig')) + csv_data = reader(data) + return list(next(csv_data)) + + @api.model + def parse(self, mapping, data_file, filename): + journal = self.env['account.journal'].browse( + self.env.context.get('journal_id') + ) + currency_code = ( + journal.currency_id or journal.company_id.currency_id + ).name + account_number = journal.bank_account_id.acc_number + + name = _('%s: %s') % ( + journal.code, + path.basename(filename), + ) + lines = self._parse_lines(mapping, data_file, currency_code) + if not lines: + return currency_code, account_number, [{ + 'name': name, + 'transactions': [], + }] + + lines = list(sorted( + lines, + key=lambda line: line['timestamp'] + )) + first_line = lines[0] + balance_start = first_line['balance_amount'] + balance_start -= first_line['gross_amount'] + balance_start -= first_line['fee_amount'] + last_line = lines[-1] + balance_end = last_line['balance_amount'] + + transactions = list(itertools.chain.from_iterable(map( + lambda line: self._convert_line_to_transactions(line), + lines + ))) + + return currency_code, account_number, [{ + 'name': name, + 'date': first_line['timestamp'].date(), + 'balance_start': float(balance_start), + 'balance_end_real': float(balance_end), + 'transactions': transactions, + }] + + def _parse_lines(self, mapping, data_file, currency_code): + data = StringIO(data_file.decode('utf-8-sig')) + csv_data = reader(data) + + header = list(next(csv_data)) + date_column = header.index(mapping.date_column) + time_column = header.index(mapping.time_column) + tz_column = header.index(mapping.tz_column) + name_column = header.index(mapping.name_column) + currency_column = header.index(mapping.currency_column) + gross_column = header.index(mapping.gross_column) + fee_column = header.index(mapping.fee_column) + balance_column = header.index(mapping.balance_column) + transaction_id_column = header.index(mapping.transaction_id_column) + try: + description_column = header.index(mapping.description_column) + except ValueError: + description_column = None + try: + type_column = header.index(mapping.type_column) + except ValueError: + type_column = None + try: + from_email_address_column = header.index( + mapping.from_email_address_column + ) + except ValueError: + from_email_address_column = None + try: + to_email_address_column = header.index( + mapping.to_email_address_column + ) + except ValueError: + to_email_address_column = None + try: + invoice_id_column = header.index(mapping.invoice_id_column) + except ValueError: + invoice_id_column = None + try: + subject_column = header.index(mapping.subject_column) + except ValueError: + subject_column = None + try: + note_column = header.index(mapping.note_column) + except ValueError: + note_column = None + try: + bank_name_column = header.index(mapping.bank_name_column) + except ValueError: + bank_name_column = None + try: + bank_account_column = header.index(mapping.bank_account_column) + except ValueError: + bank_account_column = None + + lines = [] + for row in csv_data: + row = list(row) + date_value = row[date_column] + time_value = row[time_column] + tz_value = row[tz_column] + name_value = row[name_column] + currency_value = row[currency_column] + gross_value = row[gross_column] + fee_value = row[fee_column] + balance_value = row[balance_column] + transaction_id_value = row[transaction_id_column] + description_value = row[description_column] \ + if description_column is not None else None + type_value = row[type_column] \ + if type_column is not None else None + from_email_address_value = row[from_email_address_column] \ + if from_email_address_column is not None else None + to_email_address_value = row[to_email_address_column] \ + if to_email_address_column is not None else None + invoice_id_value = row[invoice_id_column] \ + if invoice_id_column is not None else None + subject_value = row[subject_column] \ + if subject_column is not None else None + note_value = row[note_column] \ + if note_column is not None else None + bank_name_value = row[bank_name_column] \ + if bank_name_column is not None else None + bank_account_value = row[bank_account_column] \ + if bank_account_column is not None else None + + if currency_value != currency_code: + continue + + date = datetime.strptime(date_value, mapping.date_format).date() + time = datetime.strptime(time_value, mapping.time_format).time() + timestamp = datetime.combine(date, time) + tz_value = self._normalize_tz(tz_value) + tz = timezone(tz_value) + timestamp = timestamp.replace(tzinfo=tz) + timestamp = timestamp.astimezone(utc).replace(tzinfo=None) + gross_amount = self._parse_decimal(gross_value, mapping) + fee_amount = self._parse_decimal(fee_value, mapping) + balance_amount = self._parse_decimal(balance_value, mapping) + bank = '%s - %s' % ( + bank_name_value, + bank_account_value, + ) if bank_name_value and bank_account_value else None + if to_email_address_column is None: + payer_email = from_email_address_value + else: + payer_email = to_email_address_value \ + if gross_amount < 0.0 else from_email_address_value + + lines.append({ + 'transaction_id': transaction_id_value, + 'invoice': invoice_id_value, + 'description': description_value or type_value, + 'details': subject_value or note_value or bank, + 'timestamp': timestamp, + 'gross_amount': gross_amount, + 'fee_amount': fee_amount, + 'balance_amount': balance_amount, + 'payer_name': name_value, + 'payer_email': payer_email, + }) + return lines + + @api.model + def _convert_line_to_transactions(self, line): + transactions = [] + + transaction_id = line['transaction_id'] + invoice = line['invoice'] + description = line['description'] + details = line['details'] + timestamp = line['timestamp'] + gross_amount = line['gross_amount'] + fee_amount = line['fee_amount'] + payer_name = line['payer_name'] + payer_email = line['payer_email'] + if invoice: + invoice = _('Invoice %s') % invoice + note = '%s %s' % ( + description, + transaction_id, + ) + if details: + note += ': %s' % details + if payer_email: + note += ' (%s)' % payer_email + + unique_import_id = '%s-%s' % ( + transaction_id, + int(timestamp.timestamp()), + ) + name = invoice or details or description or '', + transaction = { + 'name': invoice or details or description or '', + 'amount': str(gross_amount), + 'date': timestamp, + 'note': note, + 'unique_import_id': unique_import_id, + } + if payer_name: + line.update({ + 'partner_name': payer_name, + }) + transactions.append(transaction) + + if fee_amount: + transactions.append({ + 'name': _('Fee for %s') % (name or transaction_id), + 'amount': str(fee_amount), + 'date': timestamp, + 'partner_name': 'PayPal', + 'unique_import_id': '%s-FEE' % unique_import_id, + 'note': _('Transaction fee for %s') % note, + }) + return transactions + + @api.model + def _parse_decimal(self, value, mapping): + thousands, decimal = mapping._get_float_separators() + value = value.replace(thousands, '') + value = value.replace(decimal, '.') + return Decimal(value) + + @api.model + def _normalize_tz(self, value): + if value in ['PDT', 'PST']: + return 'PST8PDT' + return value diff --git a/account_statement_import_paypal/models/account_journal.py b/account_statement_import_paypal/models/account_journal.py index 0bc634e2..20fbe50a 100644 --- a/account_statement_import_paypal/models/account_journal.py +++ b/account_statement_import_paypal/models/account_journal.py @@ -1,18 +1,14 @@ # Copyright 2019 Tecnativa - Vicent Cubells -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import models class AccountJournal(models.Model): - _inherit = "account.journal" - - paypal_map_id = fields.Many2one( - comodel_name='account.bank.statement.import.paypal.map', - string='Paypal Map', - ) + _inherit = 'account.journal' def _get_bank_statements_available_import_formats(self): res = super()._get_bank_statements_available_import_formats() - res.append('Paypal') + res.append('PayPal Reports') return res diff --git a/account_statement_import_paypal/readme/CONFIGURE.rst b/account_statement_import_paypal/readme/CONFIGURE.rst index 7693cae5..f8dc1215 100644 --- a/account_statement_import_paypal/readme/CONFIGURE.rst +++ b/account_statement_import_paypal/readme/CONFIGURE.rst @@ -1,12 +1,4 @@ -* Create or go to a bank journal where you want to import Paypal statement. -* Edit that journal and set a Paypal map in **Paypal Map** section in **Advanced - Settings** tab. +To adjust PayPal report columns mapping: -* Now you can import Paypal statements in that journal. - -Note: if existent Paypal Map does not fit to your file to import, you can -create another map in **Invoicing > Configuration > Accounting > Paypal -Mapping**. - -You can import headers from any Paypal file in **Action > Create Paypal Map -Lines** and set every line with which field of statement have to match. +#. Open *Invoicing > Configuration > Accounting > PayPal Report Mappings* +#. Modify mapping(s) according to your CSV reports format. diff --git a/account_statement_import_paypal/readme/CONTRIBUTORS.rst b/account_statement_import_paypal/readme/CONTRIBUTORS.rst index 6e9a18d1..c85a59ac 100644 --- a/account_statement_import_paypal/readme/CONTRIBUTORS.rst +++ b/account_statement_import_paypal/readme/CONTRIBUTORS.rst @@ -4,3 +4,5 @@ * Vicent Cubells * Victor M.M. Torres + +* Alexey Pelykh diff --git a/account_statement_import_paypal/readme/DESCRIPTION.rst b/account_statement_import_paypal/readme/DESCRIPTION.rst index 492b95df..2c29a68f 100644 --- a/account_statement_import_paypal/readme/DESCRIPTION.rst +++ b/account_statement_import_paypal/readme/DESCRIPTION.rst @@ -1,2 +1,2 @@ -This module allows you to import the Paypal CSV files in Odoo as bank +This module allows you to import the PayPal CSV files in Odoo as bank statements. diff --git a/account_statement_import_paypal/readme/HISTORY.rst b/account_statement_import_paypal/readme/HISTORY.rst new file mode 100644 index 00000000..fe7b1add --- /dev/null +++ b/account_statement_import_paypal/readme/HISTORY.rst @@ -0,0 +1,7 @@ +12.0.2.0.0 +~~~~~~~~~~ + +* [BREAKING] New mapping, please review mappings after upgrade. +* [BREAKING] Different bank accounts have to be used per each currency. +* [ADD] Support for both Statement and Activity reports. +* [ADD] Separate fee and currency exchange parsing. diff --git a/account_statement_import_paypal/readme/USAGE.rst b/account_statement_import_paypal/readme/USAGE.rst index fdcc4da9..0e2851c2 100644 --- a/account_statement_import_paypal/readme/USAGE.rst +++ b/account_statement_import_paypal/readme/USAGE.rst @@ -1,8 +1,19 @@ -To use this module, you need to: +To import statements from PayPal via Statement report: -#. Go to Paypal and download your Bank Statement +#. Go to `PayPal `__ +#. Open *Reports > Statements* and select *Monthly* or *Custom* +#. Select date range of interest and click *Request* under *CSV* column +#. Wait for statement report to be generated +#. Download it and save to a file +#. Go to Odoo and and import saved statement file, selecting corresponding format -.. image:: account_bank_statement_import_paypal/static/description/paypal_backoffice.png - :alt: . -.. image:: static/description/paypal_backoffice.png - :alt: . +To import statements from PayPal via Activity report: + +#. Go to `PayPal `__ +#. Open *Reports > Activity download* +#. Set *Transaction type* to *Balance affecting* +#. Set *Format* to *CSV* +#. Select date range of interest and click *Create report* +#. Wait for activity report to be generated +#. Download it and save to a file +#. Go to Odoo and and import saved statement file, selecting corresponding format diff --git a/account_statement_import_paypal/security/ir.model.access.csv b/account_statement_import_paypal/security/ir.model.access.csv index db61ffb0..bd4912b5 100644 --- a/account_statement_import_paypal/security/ir.model.access.csv +++ b/account_statement_import_paypal/security/ir.model.access.csv @@ -1,3 +1,3 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" -access_account_bank_statement_import_paypal_map,Paypal map manager,model_account_bank_statement_import_paypal_map,account.group_account_manager,1,1,1,1 -access_account_bank_statement_import_paypal_map_line,Paypal map line manager,model_account_bank_statement_import_paypal_map_line,account.group_account_manager,1,1,1,1 +access_account_bank_statement_import_paypal_mapping_manager,account.bank.statement.import.paypal.mapping:account.group_account_manager,model_account_bank_statement_import_paypal_mapping,account.group_account_manager,1,1,1,1 +access_account_bank_statement_import_paypal_mapping_user,account.bank.statement.import.paypal.mapping:account.group_account_user,model_account_bank_statement_import_paypal_mapping,account.group_account_user,1,0,0,0 diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html index 402d1959..b782159f 100644 --- a/account_statement_import_paypal/static/description/index.html +++ b/account_statement_import_paypal/static/description/index.html @@ -4,7 +4,7 @@ -Import Paypal Bank Statements +PayPal CSV Format Bank Statements Import -
-

Import Paypal Bank Statements

+
+

PayPal CSV Format Bank Statements Import

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

-

This module allows you to import the Paypal CSV files in Odoo as bank +

This module allows you to import the PayPal CSV files in Odoo as bank statements.

Table of contents

-

Configuration

-
    -
  • Create or go to a bank journal where you want to import Paypal statement.
  • -
  • Edit that journal and set a Paypal map in Paypal Map section in Advanced -Settings tab.
  • -
  • Now you can import Paypal statements in that journal.
  • -
-

Note: if existent Paypal Map does not fit to your file to import, you can -create another map in Invoicing > Configuration > Accounting > Paypal -Mapping.

-

You can import headers from any Paypal file in Action > Create Paypal Map -Lines and set every line with which field of statement have to match.

+

Configuration

+

To adjust PayPal report columns mapping:

+
    +
  1. Open Invoicing > Configuration > Accounting > PayPal Report Mappings
  2. +
  3. Modify mapping(s) according to your CSV reports format.
  4. +
-

Usage

-

To use this module, you need to:

+

Usage

+

To import statements from PayPal via Statement report:

    -
  1. Go to Paypal and download your Bank Statement
  2. +
  3. Go to PayPal
  4. +
  5. Open Reports > Statements and select Monthly or Custom
  6. +
  7. Select date range of interest and click Request under CSV column
  8. +
  9. Wait for statement report to be generated
  10. +
  11. Download it and save to a file
  12. +
  13. Go to Odoo and and import saved statement file, selecting corresponding format
-. -. +

To import statements from PayPal via Activity report:

+
    +
  1. Go to PayPal
  2. +
  3. Open Reports > Activity download
  4. +
  5. Set Transaction type to Balance affecting
  6. +
  7. Set Format to CSV
  8. +
  9. Select date range of interest and click Create report
  10. +
  11. Wait for activity report to be generated
  12. +
  13. Download it and save to a file
  14. +
  15. Go to Odoo and and import saved statement file, selecting corresponding format
  16. +
+
+
+

Changelog

+
+

12.0.2.0.0

+
    +
  • [BREAKING] New mapping, please review mappings after upgrade.
  • +
  • [BREAKING] Different bank accounts have to be used per each currency.
  • +
  • [ADD] Support for both Statement and Activity reports.
  • +
  • [ADD] Separate fee and currency exchange parsing.
  • +
+
-

Bug Tracker

+

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 @@ -416,15 +440,16 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
  • +
  • Brainbean Apps
-

Contributors

+

Contributors

+
  • Alexey Pelykh <alexey.pelykh@brainbeanapps.com>
  • -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association

    OCA, or the Odoo Community Association, is a nonprofit organization whose diff --git a/account_statement_import_paypal/static/description/paypal_backoffice.png b/account_statement_import_paypal/static/description/paypal_backoffice.png deleted file mode 100644 index a902aee13bea035e22df7db0059629d3bf347eb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97703 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
    TYeiKEFlk;DkWdNtFpX#oRiKiSjqcabJ;~^ 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 + + account.bank.statement.import account.bank.statement.import -

  • Paypal with Template:
  • +
  • + PayPal Report mapping: +
  • diff --git a/account_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml b/account_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml new file mode 100644 index 00000000..05ed5fe2 --- /dev/null +++ b/account_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml @@ -0,0 +1,78 @@ + + + + + + account.bank.statement.import.paypal.mapping.form + account.bank.statement.import.paypal.mapping + + + + + + + + + account.bank.statement.import.paypal.mapping.tree + account.bank.statement.import.paypal.mapping + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    + + + + + PayPal Report Mappings + account.bank.statement.import.paypal.mapping + form + tree,form + + + + +
    diff --git a/account_statement_import_paypal/views/account_journal_views.xml b/account_statement_import_paypal/views/account_journal_views.xml deleted file mode 100644 index 3e565b7d..00000000 --- a/account_statement_import_paypal/views/account_journal_views.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - account.journal - - - - - - - - - - - diff --git a/account_statement_import_paypal/views/paypal_map_views.xml b/account_statement_import_paypal/views/paypal_map_views.xml deleted file mode 100644 index 1fee4a66..00000000 --- a/account_statement_import_paypal/views/paypal_map_views.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - account.bank.statement.import.paypal.map - - - - - - - - - account.bank.statement.import.paypal.map - -
    - - - - - - - - - -
    - - - account.bank.statement.import.paypal.map.line - - - - - - - - - - - - account.bank.statement.import.paypal.map.line - -
    - - - - - - - -
    -
    -
    - - - Paypal Mapping - account.bank.statement.import.paypal.map - form - tree,form - - - - -
    diff --git a/account_statement_import_paypal/wizards/__init__.py b/account_statement_import_paypal/wizards/__init__.py index 006d24cd..5aecceaf 100644 --- a/account_statement_import_paypal/wizards/__init__.py +++ b/account_statement_import_paypal/wizards/__init__.py @@ -1,2 +1,3 @@ -from . import create_map_lines_from_file -from . import account_bank_statement_import_paypal +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import account_bank_statement_import_paypal_mapping_wizard diff --git a/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py deleted file mode 100644 index 5eb194b1..00000000 --- a/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py +++ /dev/null @@ -1,300 +0,0 @@ -# Copyright 2014-2017 Akretion (http://www.akretion.com). -# @author Alexis de Lattre -# @author Sébastien BEAU -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import logging -from datetime import datetime -from odoo import _, api, fields, models -from odoo.exceptions import UserError -import re -from io import StringIO -_logger = logging.getLogger(__name__) - -try: - import csv -except (ImportError, IOError) as err: - _logger.debug(err) - -# Paypal header depend of the country the order are the same but the -# value are translated. You can add you header here - -HEADERS = [ - # French - '"Date","Heure","Fuseau horaire","Description","Devise","Avant commission"' - ',"Commission","Net","Solde","Numéro de transaction","Adresse email de ' - 'l\'expéditeur","Nom","Nom de la banque","Compte bancaire","Montant des ' - 'frais de livraison et de traitement","TVA","Identifiant de facture",' - '"Numéro de la transaction de référence"', - # English - '"Date","Time","Time Zone","Description","Currency","Gross ","Fee ","Net",' - '"Balance","Transaction ID","From Email Address","Name","Bank Name",' - '"Bank Account","Shipping and Handling Amount","Sales Tax","Invoice ID",' - '"Reference Txn ID"', - ] - - -class AccountBankStatementImport(models.TransientModel): - _inherit = 'account.bank.statement.import' - - paypal_map_id = fields.Many2one( - comodel_name='account.bank.statement.import.paypal.map', - string='Paypal map', - readonly=True, - ) - - @api.model - def _get_paypal_encoding(self): - return 'utf-8-sig' - - @api.model - def _get_paypal_str_data(self, data_file): - if not isinstance(data_file, str): - data_file = data_file.decode(self._get_paypal_encoding()) - return data_file.strip() - - @api.model - def _paypal_convert_amount(self, amount_str): - if self.paypal_map_id: - thousands, decimal = self.paypal_map_id._get_separators() - else: - thousands, decimal = ',', '.' - valstr = re.sub(r'[^\d%s%s.-]' % (thousands, decimal), '', amount_str) - valstrdot = valstr.replace(thousands, '') - valstrdot = valstrdot.replace(decimal, '.') - return float(valstrdot) - - @api.model - def _check_paypal(self, data_file): - if not self.paypal_map_id: - return False - try: - data_file = self._get_paypal_str_data(data_file) - except UnicodeDecodeError as e: - _logger.debug(e) - return False - headers = self.mapped('paypal_map_id.map_line_ids.name') - file_headers = data_file.split('\n', 1)[0] - if any(item not in file_headers for item in headers): - raise UserError( - _("Headers of file to import and Paypal map lines does not " - "match.")) - return True - - def _convert_paypal_line_to_dict(self, idx, line): - rline = dict() - for item in range(len(line)): - paypal_map = self.mapped('paypal_map_id.map_line_ids')[item] - value = line[item] - if not paypal_map.field_to_assign: - continue - if paypal_map.date_format: - try: - value = fields.Date.to_string( - datetime.strptime(value, paypal_map.date_format)) - except Exception: - raise UserError( - _("Date format of map file and Paypal date does " - "not match.")) - rline[paypal_map.field_to_assign] = value - - for field in ['commission', 'amount', 'balance']: - _logger.debug('Trying to convert %s to float' % rline[field]) - try: - rline[field] = self._paypal_convert_amount(rline[field]) - except Exception: - raise UserError( - _("Value '%s' for the field '%s' on line %d, " - "cannot be converted to float") - % (rline[field], field, idx)) - return rline - - def _parse_paypal_file(self, data_file): - data_file = self._get_paypal_str_data(data_file) - f = StringIO(data_file) - f.seek(0) - raw_lines = [] - reader = csv.reader(f) - next(reader) # Drop header - for idx, line in enumerate(reader): - _logger.debug("Line %d: %s" % (idx, line)) - raw_lines.append(self._convert_paypal_line_to_dict(idx, line)) - return raw_lines - - def _prepare_paypal_currency_vals(self, cline): - currencies = self.env['res.currency'].search( - [('name', '=', cline['currency'])]) - if not currencies: - raise UserError( - _('currency %s on line %d cannot be found in odoo') - % (cline['currency'], cline['idx'])) - return { - 'amount_currency': cline['amount'], - 'currency_id': currencies.id, - 'currency': cline['currency'], - 'partner_name': cline['partner_name'], - 'description': cline['description'], - 'email': cline['email'], - 'transaction_id': cline['transaction_id'], - } - - def _get_journal(self): - journal_id = self.env.context.get('journal_id') - if not journal_id: - raise UserError(_('You must run this wizard from the journal')) - return self.env['account.journal'].browse(journal_id) - - def _post_process_statement_line(self, raw_lines): - journal = self._get_journal() - currency = journal.currency_id or journal.company_id.currency_id - currency_change_lines = {} - real_transactions = [] - for line in raw_lines: - if line['currency'] != currency.name: - currency_change_lines[line['transaction_id']] = line - else: - real_transactions.append(line) - - for line in real_transactions: - # Check if the current transaction is linked with a - # transaction of currency change if yes merge the transaction - # as for odoo it's only one line - cline = currency_change_lines.get(line['origin_transaction_id']) - if cline: - # we update the current line with currency information - vals = self._prepare_paypal_currency_vals(cline) - line.update(vals) - return real_transactions - - def _prepare_paypal_statement_line(self, fline): - if fline['bank_name']: - name = '|'.join([ - fline['description'], - fline['bank_name'], - fline['bank_account'] - ]) - else: - name = '|'.join([ - fline['description'], - fline['partner_name'], - fline['email'], - fline['invoice_number'], - ]) - return { - 'date': fline['date'], - 'name': name, - 'ref': fline['transaction_id'], - 'unique_import_id': - fline['transaction_id'] + fline['date'] + fline['time'], - 'amount': fline['amount'], - 'bank_account_id': False, - 'currency_id': fline.get('currency_id'), - 'amount_currency': fline.get('amount_currency'), - } - - def _prepare_paypal_statement(self, lines): - return { - 'name': - _('PayPal Import %s > %s') - % (lines[0]['date'], lines[-1]['date']), - 'date': lines[-1]['date'], - 'balance_start': - lines[0]['balance'] - - lines[0]['amount'] - - lines[0]['commission'], - 'balance_end_real': lines[-1]['balance'], - } - - @api.model - def _parse_file(self, data_file): - """ Import a file in Paypal CSV format """ - paypal = self._check_paypal(data_file) - if not paypal: - return super(AccountBankStatementImport, self)._parse_file( - data_file) - - raw_lines = self._parse_paypal_file(data_file) - final_lines = self._post_process_statement_line(raw_lines) - - vals_bank_statement = self._prepare_paypal_statement(final_lines) - - transactions = [] - commission_total = 0 - for fline in final_lines: - commission_total += fline['commission'] - vals_line = self._prepare_paypal_statement_line(fline) - _logger.debug("vals_line = %s" % vals_line) - transactions.append(vals_line) - - if commission_total: - commission_line = { - 'date': vals_bank_statement['date'], - 'name': _('Paypal commissions'), - 'ref': _('PAYPAL-COSTS'), - 'amount': commission_total, - 'unique_import_id': False, - } - transactions.append(commission_line) - - vals_bank_statement['transactions'] = transactions - return None, None, [vals_bank_statement] - - @api.model - def _get_paypal_partner(self, description, partner_name, - partner_email, invoice_number): - if invoice_number: - # In most case e-commerce case invoice_number - # will contain the sale order number - sale = self.env['sale.order'].search([ - ('name', '=', invoice_number)]) - if sale and len(sale) == 1: - return sale.partner_id.commercial_partner_id - - invoice = self.env['account.invoice'].search([ - ('number', '=', invoice_number)]) - if invoice and len(invoice) == 1: - return invoice.partner_id.commercial_partner_id - - if partner_email: - partner = self.env['res.partner'].search([ - ('email', '=', partner_email), - ('parent_id', '=', False)]) - if partner and len(partner) == 1: - return partner.commercial_partner_id - - if partner_name: - partner = self.env['res.partner'].search([ - ('name', '=ilike', partner_name)]) - if partner and len(partner) == 1: - return partner.commercial_partner_id - return None - - @api.model - def _complete_paypal_statement_line(self, line): - _logger.debug('Process line %s', line['name']) - info = line['name'].split('|') - if len(info) == 4: - partner = self._get_paypal_partner(*info) - if partner: - return { - 'partner_id': partner.id, - } - return None - - @api.model - def _complete_stmts_vals(self, stmts_vals, journal_id, account_number): - """ Match the partner from paypal information """ - stmts_vals = super(AccountBankStatementImport, self). \ - _complete_stmts_vals(stmts_vals, journal_id, account_number) - for line in stmts_vals[0]['transactions']: - vals = self._complete_paypal_statement_line(line) - if vals: - line.update(vals) - return stmts_vals - - @api.model - def default_get(self, fields): - res = super(AccountBankStatementImport, self).default_get(fields) - journal = self._get_journal() - res['paypal_map_id'] = journal.paypal_map_id.id - return res diff --git a/account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py new file mode 100644 index 00000000..e7eb45cc --- /dev/null +++ b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py @@ -0,0 +1,84 @@ +# Copyright 2019 Tecnativa - Vicent Cubells +# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + +from base64 import b64decode +from os import path + + +class AccountBankStatementImportPayPalMappingWizard(models.TransientModel): + _name = 'account.bank.statement.import.paypal.mapping.wizard' + _description = 'Account Bank Statement Import PayPal Mapping Wizard' + + data_file = fields.Binary( + string='Bank Statement File', + required=True, + ) + filename = fields.Char() + + @api.multi + def import_mapping(self): + self.ensure_one() + mapping_values = { + 'name': _('Mapping from %s') % path.basename(self.filename), + 'float_thousands_sep': 'comma', + 'float_decimal_sep': 'dot', + 'date_format': '%d/%m/%Y', + 'time_format': '%H:%M:%S', + } + header = self.env['account.bank.statement.import.paypal.parser'] \ + .parse_header(b64decode(self.data_file)) + if len(header) == 22: + mapping_values.update({ + 'date_column': header[0], + 'time_column': header[1], + 'tz_column': header[2], + 'name_column': header[3], + 'currency_column': header[6], + 'gross_column': header[7], + 'fee_column': header[8], + 'balance_column': header[18], + 'transaction_id_column': header[12], + 'type_column': header[4], + 'from_email_address_column': header[10], + 'to_email_address_column': header[11], + 'invoice_id_column': header[16], + 'subject_column': header[20], + 'note_column': header[21], + }) + elif len(header) == 18: + mapping_values.update({ + 'date_column': header[0], + 'time_column': header[1], + 'tz_column': header[2], + 'name_column': header[11], + 'currency_column': header[4], + 'gross_column': header[5], + 'fee_column': header[6], + 'balance_column': header[8], + 'transaction_id_column': header[9], + 'description_column': header[3], + 'from_email_address_column': header[10], + 'invoice_id_column': header[16], + 'bank_name_column': header[12], + 'bank_account_column': header[13], + }) + else: + raise UserError(_( + 'File structure does not look like a PayPal report, please ' + 'check the file or create the mapping manually.' + )) + mapping = self.env['account.bank.statement.import.paypal.mapping']\ + .create(mapping_values) + return { + 'type': 'ir.actions.act_window', + 'name': _('Imported Mapping'), + 'res_model': 'account.bank.statement.import.paypal.mapping', + 'res_id': mapping.id, + 'view_mode': 'form', + 'view_id': False, + 'target': 'new', + } diff --git a/account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml new file mode 100644 index 00000000..148e5b4a --- /dev/null +++ b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml @@ -0,0 +1,34 @@ + + + + + + account.bank.statement.import.paypal.mapping.wizard.form + account.bank.statement.import.paypal.mapping.wizard + +
    +

    Select a PayPal report file to import mapping.

    + + +
    +
    + +
    +
    + + + Import Mapping + account.bank.statement.import.paypal.mapping.wizard + account.bank.statement.import.paypal.mapping + form + form + new + + +
    \ No newline at end of file diff --git a/account_statement_import_paypal/wizards/create_map_lines_from_file.py b/account_statement_import_paypal/wizards/create_map_lines_from_file.py deleted file mode 100644 index a9ca019a..00000000 --- a/account_statement_import_paypal/wizards/create_map_lines_from_file.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2019 Tecnativa - Vicent Cubells -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import csv -import base64 -from odoo import api, fields, models -from io import StringIO - - -class WizardPaypalMapCreate(models.TransientModel): - _name = 'wizard.paypal.map.create' - _description = 'Wizard Paypal Map Create' - - data_file = fields.Binary( - string='Bank Statement File', - required=True, - ) - filename = fields.Char() - - @api.multi - def create_map_lines(self): - statement_obj = self.env['account.bank.statement.import.paypal.map'] - data_file = base64.b64decode(self.data_file) - if not isinstance(data_file, str): - data_file = data_file.decode('utf-8-sig').strip() - file = StringIO(data_file) - file.seek(0) - reader = csv.reader(file) - headers = [] - for row in reader: - headers = row - break - lines = [] - for idx, title in enumerate(headers): - lines.append((0, 0, {'sequence': idx, 'name': title})) - if lines: - for statement in statement_obj.browse( - self.env.context.get('active_ids')): - statement.map_line_ids = lines diff --git a/account_statement_import_paypal/wizards/create_map_lines_from_file_views.xml b/account_statement_import_paypal/wizards/create_map_lines_from_file_views.xml deleted file mode 100644 index c61136d5..00000000 --- a/account_statement_import_paypal/wizards/create_map_lines_from_file_views.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - Create Paypal Map Lines - wizard.paypal.map.create - -
    -

    Select a Paypal bank statement file to create all the map lines from headers file.

    -

    Download a bank statement from your bank and import it here.

    -

    All the Paypal map lines will be created automatically.

    - - -
    -
    - -
    -
    - - -