From 44c505889bf9f3477dd6de757ec0727bc854ce1c Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 5 Feb 2015 14:41:27 +0100 Subject: [PATCH 01/34] Add module account_bank_statement_import_paypal Fix spelling mistake Add methods to inherit for language-specific or country-specific stuff Port to new API FIX super Update travis config --- account_statement_import_paypal/README.rst | 41 ++++ account_statement_import_paypal/__init__.py | 23 ++ .../__openerp__.py | 34 +++ .../account_bank_statement_import_paypal.py | 222 ++++++++++++++++++ 4 files changed, 320 insertions(+) create mode 100644 account_statement_import_paypal/README.rst create mode 100644 account_statement_import_paypal/__init__.py create mode 100644 account_statement_import_paypal/__openerp__.py create mode 100644 account_statement_import_paypal/account_bank_statement_import_paypal.py diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst new file mode 100644 index 00000000..47095a68 --- /dev/null +++ b/account_statement_import_paypal/README.rst @@ -0,0 +1,41 @@ +Import Paypal Bank Statements +============================= + +This module allows you to import the Paypal CSV files in Odoo as bank statements. + +Installation +============ + +This module depends on the module *account_bank_statement_import* which +is available: +* for Odoo version 8: in the OCA project `bank-statement-import ` +* for Odoo master (future version 9): it is an official module. + +Configuration +============= + +In the menu Accounting > Configuration > Accounts > Setup your Bank Accounts, make sure that you have your Paypal bank account with the following parameters: +* Bank Account Type: Normal Bank Account +* Account Number: the email address associated with your Paypal account +* Account Journal: the journal associated to your Paypal account + +Credits +======= + +Contributors +------------ + +* Alexis de Lattre + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/account_statement_import_paypal/__init__.py b/account_statement_import_paypal/__init__.py new file mode 100644 index 00000000..f4992e13 --- /dev/null +++ b/account_statement_import_paypal/__init__.py @@ -0,0 +1,23 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# account_bank_statement_import_paypal module for Odoo +# Copyright (C) 2014-2015 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from . import account_bank_statement_import_paypal diff --git a/account_statement_import_paypal/__openerp__.py b/account_statement_import_paypal/__openerp__.py new file mode 100644 index 00000000..3369755a --- /dev/null +++ b/account_statement_import_paypal/__openerp__.py @@ -0,0 +1,34 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# account_bank_statement_import_paypal module for Odoo +# Copyright (C) 2014-2015 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +{ + 'name': 'Import Paypal Bank Statements', + 'version': '0.1', + 'license': 'AGPL-3', + 'author': 'Akretion', + 'website': 'http://www.akretion.com', + 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', + 'depends': ['account_bank_statement_import'], + 'external_dependencies': {'python': ['unicodecsv']}, + 'data': [], + 'installable': True, +} diff --git a/account_statement_import_paypal/account_bank_statement_import_paypal.py b/account_statement_import_paypal/account_bank_statement_import_paypal.py new file mode 100644 index 00000000..bf1a9ff8 --- /dev/null +++ b/account_statement_import_paypal/account_bank_statement_import_paypal.py @@ -0,0 +1,222 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# account_bank_statement_import_paypal module for Odoo +# Copyright (C) 2014-2015 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import logging +from datetime import datetime +from openerp import models, fields, api, _ +from openerp.exceptions import Warning +import unicodecsv +import re +from cStringIO import StringIO + +_logger = logging.getLogger(__name__) + + +class AccountBankStatementImport(models.TransientModel): + _inherit = 'account.bank.statement.import' + + @api.model + def _prepare_paypal_encoding(self): + '''This method is designed to be inherited''' + return 'latin1' + + @api.model + def _prepare_paypal_date_format(self): + '''This method is designed to be inherited''' + return '%d/%m/%Y' + + @api.model + def _valid_paypal_line(self, line): + '''This method is designed to be inherited''' + if line[5].startswith('Termin'): + return True + else: + return False + + @api.model + def _paypal_convert_amount(self, amount_str): + '''This method is designed to be inherited''' + valstr = re.sub(r'[^\d,.-]', '', amount_str) + valstrdot = valstr.replace(',', '.') + return float(valstrdot) + + @api.model + def _check_paypal(self, data_file): + '''This method is designed to be inherited''' + return data_file.strip().startswith('Date,') + + @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) + f = StringIO() + f.write(data_file) + f.seek(0) + transactions = [] + i = 0 + start_balance = end_balance = start_date_str = end_date_str = False + vals_line = False + company_currency_name = self.env.user.company_id.currency_id.name + commission_total = 0.0 + raw_lines = [] + paypal_email_account = False + # To confirm : is the encoding always latin1 ? + for line in unicodecsv.reader( + f, encoding=self._prepare_paypal_encoding()): + i += 1 + _logger.debug("Line %d: %s" % (i, line)) + if i == 1: + _logger.debug('Skip header line') + continue + if not line: + continue + if not self._valid_paypal_line(line): + _logger.info( + 'Skipping line %d because it is not in Done state' % i) + continue + date_dt = datetime.strptime( + line[0], self._prepare_paypal_date_format()) + rline = { + 'date': fields.Date.to_string(date_dt), + 'currency': line[6], + 'owner_name': line[3], + 'amount': line[7], + 'commission': line[8], + 'balance': line[34], + 'transac_ref': line[30], + 'ref': line[12], + 'line_nr': i, + } + 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: + raise Warning( + _("Value '%s' for the field '%s' on line %d, " + "cannot be converted to float") + % (rline[field], field, i)) + if rline['amount'] > 0: + rline['name'] = line[3] + ' ' + line[10] + rline['partner_email'] = line[10] + if not paypal_email_account: + paypal_email_account = line[11] + else: + rline['name'] = line[3] + ' ' + line[11] + rline['partner_email'] = line[11] + if not paypal_email_account: + paypal_email_account = line[10] + raw_lines.append(rline) + + # Second pass to sort out the lines in other currencies + final_lines = [] + other_currency_line = {} + for wline in raw_lines: + if company_currency_name != wline['currency']: + if not wline['transac_ref'] and not other_currency_line: + currencies = self.env['res.currency'].search( + [('name', '=', wline['currency'])]) + if not currencies: + raise Warning( + _('Currency %s on line %d cannot be found in Odoo') + % (wline['currency'], wline['line_nr'])) + other_currency_line = { + 'amount_currency': wline['amount'], + 'currency_id': currencies[0].id, + 'currency': wline['currency'], + 'name': wline['name'], + 'owner_name': wline['owner_name'], + } + if wline['transac_ref'] and other_currency_line: + assert ( + wline['currency'] == other_currency_line['currency']),\ + 'WRONG currency' + assert ( + wline['amount'] == + other_currency_line['amount_currency'] * -1),\ + 'WRONG amount' + other_currency_line['transac_ref'] = wline['transac_ref'] + else: + if ( + other_currency_line + and wline['transac_ref'] == + other_currency_line['transac_ref']): + wline.update(other_currency_line) + # reset other_currency_line + other_currency_line = {} + final_lines.append(wline) + + # PayPal statements start with the end ! + final_lines.reverse() + j = 0 + for fline in final_lines: + j += 1 + commission_total += fline['commission'] + + if j == 1: + start_date_str = fline['date'] + start_balance = fline['balance'] - fline['amount'] + end_date_str = fline['date'] + end_balance = fline['balance'] + partners = False + if fline['partner_email']: + partners = self.env['res.partner'].search( + [('email', '=', fline['partner_email'])]) + if partners: + partner_id = partners[0].commercial_partner_id.id + else: + partner_id = False + vals_line = { + 'date': fline['date'], + 'name': fline['name'], + 'ref': fline['ref'], + 'unique_import_id': fline['ref'], + 'amount': fline['amount'], + 'partner_id': partner_id, + 'bank_account_id': False, + 'currency_id': fline.get('currency_id'), + 'amount_currency': fline.get('amount_currency'), + } + _logger.debug("vals_line = %s" % vals_line) + transactions.append(vals_line) + + if commission_total: + commission_line = { + 'date': end_date_str, + 'name': _('Paypal commissions'), + 'ref': _('PAYPAL-COSTS'), + 'amount': commission_total, + 'unique_import_id': False, + } + transactions.append(commission_line) + + vals_bank_statement = { + 'name': _('PayPal Import %s > %s') + % (start_date_str, end_date_str), + 'balance_start': start_balance, + 'balance_end_real': end_balance, + 'transactions': transactions, + } + return None, paypal_email_account, [vals_bank_statement] From dd533762f0ed3529f8a5d20463dccdc1a90bc22f Mon Sep 17 00:00:00 2001 From: "Adrien Peiffer (ACSONE)" Date: Wed, 6 Jan 2016 15:06:28 +0100 Subject: [PATCH 02/34] Consider refund line Avoid to return paypal_email_account as a bank account Put file transaction ref in name to work with base_transaction_ref Remove thousands separator --- .../account_bank_statement_import_paypal.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/account_statement_import_paypal/account_bank_statement_import_paypal.py b/account_statement_import_paypal/account_bank_statement_import_paypal.py index bf1a9ff8..67012c96 100644 --- a/account_statement_import_paypal/account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/account_bank_statement_import_paypal.py @@ -47,7 +47,7 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _valid_paypal_line(self, line): '''This method is designed to be inherited''' - if line[5].startswith('Termin'): + if line[5].startswith('Termin') or line[5].startswith('Rembours'): return True else: return False @@ -56,7 +56,8 @@ class AccountBankStatementImport(models.TransientModel): def _paypal_convert_amount(self, amount_str): '''This method is designed to be inherited''' valstr = re.sub(r'[^\d,.-]', '', amount_str) - valstrdot = valstr.replace(',', '.') + valstrdot = valstr.replace('.', '') + valstrdot = valstrdot.replace(',', '.') return float(valstrdot) @api.model @@ -190,8 +191,8 @@ class AccountBankStatementImport(models.TransientModel): partner_id = False vals_line = { 'date': fline['date'], - 'name': fline['name'], - 'ref': fline['ref'], + 'name': fline['ref'], + 'ref': fline['name'], 'unique_import_id': fline['ref'], 'amount': fline['amount'], 'partner_id': partner_id, @@ -219,4 +220,4 @@ class AccountBankStatementImport(models.TransientModel): 'balance_end_real': end_balance, 'transactions': transactions, } - return None, paypal_email_account, [vals_bank_statement] + return None, None, [vals_bank_statement] From cbf0dc93637de2b8b24b087b93a8179c2a7faa1d Mon Sep 17 00:00:00 2001 From: Mourad Elhadj Mimoune Date: Thu, 30 Jun 2016 17:43:35 +0200 Subject: [PATCH 03/34] adapt code to the new paypal format error when several line defined in currency != company currency handel utf-8 file handel csv with quotechar " skip BOM character in utf-8 --- .../account_bank_statement_import_paypal.py | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/account_statement_import_paypal/account_bank_statement_import_paypal.py b/account_statement_import_paypal/account_bank_statement_import_paypal.py index 67012c96..2e714b84 100644 --- a/account_statement_import_paypal/account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/account_bank_statement_import_paypal.py @@ -37,7 +37,7 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _prepare_paypal_encoding(self): '''This method is designed to be inherited''' - return 'latin1' + return 'utf-8' @api.model def _prepare_paypal_date_format(self): @@ -47,7 +47,8 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _valid_paypal_line(self, line): '''This method is designed to be inherited''' - if line[5].startswith('Termin') or line[5].startswith('Rembours'): + col_name = line[5].replace('"','') + if col_name.startswith('Termin') or col_name.startswith('Rembours'): return True else: return False @@ -63,11 +64,16 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _check_paypal(self, data_file): '''This method is designed to be inherited''' - return data_file.strip().startswith('Date,') + paypal = data_file.strip().startswith('Date,') + if not paypal: + paypal = data_file.strip().startswith('"Date",') + + return paypal @api.model def _parse_file(self, data_file): """ Import a file in Paypal CSV format""" + data_file = data_file.replace("\xef\xbb\xbf", "") paypal = self._check_paypal(data_file) if not paypal: return super(AccountBankStatementImport, self)._parse_file( @@ -105,8 +111,8 @@ class AccountBankStatementImport(models.TransientModel): 'owner_name': line[3], 'amount': line[7], 'commission': line[8], - 'balance': line[34], - 'transac_ref': line[30], + 'balance': line[27], + 'transac_ref': line[23], 'ref': line[12], 'line_nr': i, } @@ -136,7 +142,7 @@ class AccountBankStatementImport(models.TransientModel): other_currency_line = {} for wline in raw_lines: if company_currency_name != wline['currency']: - if not wline['transac_ref'] and not other_currency_line: + if wline['transac_ref'] and not other_currency_line: currencies = self.env['res.currency'].search( [('name', '=', wline['currency'])]) if not currencies: @@ -149,8 +155,10 @@ class AccountBankStatementImport(models.TransientModel): 'currency': wline['currency'], 'name': wline['name'], 'owner_name': wline['owner_name'], - } - if wline['transac_ref'] and other_currency_line: + 'transac_ref': wline['transac_ref'], + } + + if other_currency_line and not wline['transac_ref']: assert ( wline['currency'] == other_currency_line['currency']),\ 'WRONG currency' @@ -158,11 +166,16 @@ class AccountBankStatementImport(models.TransientModel): wline['amount'] == other_currency_line['amount_currency'] * -1),\ 'WRONG amount' - other_currency_line['transac_ref'] = wline['transac_ref'] + if ( + other_currency_line and + wline['ref'] == + other_currency_line['transac_ref']): + # reset other_currency_line + other_currency_line = {} else: if ( - other_currency_line - and wline['transac_ref'] == + other_currency_line and + wline['transac_ref'] == other_currency_line['transac_ref']): wline.update(other_currency_line) # reset other_currency_line From e52bc0dad8c55b21f8bc35bdaacfefe576c1e232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Fri, 2 Feb 2018 15:06:43 +0100 Subject: [PATCH 04/34] refactor paypal import in order to use new bank statement from Paypal Remove deprecated information in readme solve issue on currency the main currency is not the first line (line are ordered by currency name). So we should take the journal currency or company currency to know the right currency to use. Also add full header to avoid issue if the paypal header change --- account_statement_import_paypal/README.rst | 24 +- account_statement_import_paypal/__init__.py | 24 +- .../__manifest__.py | 29 ++ .../__openerp__.py | 34 --- .../account_bank_statement_import_paypal.py | 236 --------------- .../models/__init__.py | 3 + .../account_bank_statement_import_paypal.py | 275 ++++++++++++++++++ .../static/description/icon.png | Bin 0 -> 6481 bytes .../static/description/paypal_backoffice.png | Bin 0 -> 97703 bytes 9 files changed, 325 insertions(+), 300 deletions(-) create mode 100644 account_statement_import_paypal/__manifest__.py delete mode 100644 account_statement_import_paypal/__openerp__.py delete mode 100644 account_statement_import_paypal/account_bank_statement_import_paypal.py create mode 100644 account_statement_import_paypal/models/__init__.py create mode 100644 account_statement_import_paypal/models/account_bank_statement_import_paypal.py create mode 100644 account_statement_import_paypal/static/description/icon.png create mode 100644 account_statement_import_paypal/static/description/paypal_backoffice.png diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst index 47095a68..1c803401 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -3,14 +3,6 @@ Import Paypal Bank Statements This module allows you to import the Paypal CSV files in Odoo as bank statements. -Installation -============ - -This module depends on the module *account_bank_statement_import* which -is available: -* for Odoo version 8: in the OCA project `bank-statement-import ` -* for Odoo master (future version 9): it is an official module. - Configuration ============= @@ -19,6 +11,15 @@ In the menu Accounting > Configuration > Accounts > Setup your Bank Accounts, ma * Account Number: the email address associated with your Paypal account * Account Journal: the journal associated to your Paypal account +============ + +Go to Paypal and download your Bank Statement + +.. image:: account_bank_statement_import_paypal/static/description/paypal_backoffice.png + :alt: . +.. image:: static/description/paypal_backoffice.png + :alt: . + Credits ======= @@ -26,6 +27,13 @@ Contributors ------------ * Alexis de Lattre +* Sebastien BEAU + +TIPS +-------- +For now only French and English report are supported +For adding new support you just need to add your header in model/account_bank_statement_import_paypal.py in the variables HEADERS. +Please help us and do a PR for adding new header ! Thanks Maintainer ---------- diff --git a/account_statement_import_paypal/__init__.py b/account_statement_import_paypal/__init__.py index f4992e13..cde864ba 100644 --- a/account_statement_import_paypal/__init__.py +++ b/account_statement_import_paypal/__init__.py @@ -1,23 +1,3 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# account_bank_statement_import_paypal module for Odoo -# Copyright (C) 2014-2015 Akretion (http://www.akretion.com) -# @author Alexis de Lattre -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## +# -*- coding: utf-8 -*- -from . import account_bank_statement_import_paypal +from . import models diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py new file mode 100644 index 00000000..4f20c115 --- /dev/null +++ b/account_statement_import_paypal/__manifest__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# 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). +{ + "name": "Import Paypal Bank Statements", + 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', + "version": "10.0.1.0.0", + "category": "Accounting", + "website": "https://github.com/OCA/bank-statement-import", + "author": " Akretion, Odoo Community Association (OCA)", + "license": "AGPL-3", + "application": False, + "installable": True, + "external_dependencies": { + 'python': ['unicodecsv'], + "bin": [], + }, + "depends": [ + "account_bank_statement_import", + ], + "data": [ + ], + "demo": [ + ], + "qweb": [ + ] +} diff --git a/account_statement_import_paypal/__openerp__.py b/account_statement_import_paypal/__openerp__.py deleted file mode 100644 index 3369755a..00000000 --- a/account_statement_import_paypal/__openerp__.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# account_bank_statement_import_paypal module for Odoo -# Copyright (C) 2014-2015 Akretion (http://www.akretion.com) -# @author Alexis de Lattre -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -{ - 'name': 'Import Paypal Bank Statements', - 'version': '0.1', - 'license': 'AGPL-3', - 'author': 'Akretion', - 'website': 'http://www.akretion.com', - 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', - 'depends': ['account_bank_statement_import'], - 'external_dependencies': {'python': ['unicodecsv']}, - 'data': [], - 'installable': True, -} diff --git a/account_statement_import_paypal/account_bank_statement_import_paypal.py b/account_statement_import_paypal/account_bank_statement_import_paypal.py deleted file mode 100644 index 2e714b84..00000000 --- a/account_statement_import_paypal/account_bank_statement_import_paypal.py +++ /dev/null @@ -1,236 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# account_bank_statement_import_paypal module for Odoo -# Copyright (C) 2014-2015 Akretion (http://www.akretion.com) -# @author Alexis de Lattre -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import logging -from datetime import datetime -from openerp import models, fields, api, _ -from openerp.exceptions import Warning -import unicodecsv -import re -from cStringIO import StringIO - -_logger = logging.getLogger(__name__) - - -class AccountBankStatementImport(models.TransientModel): - _inherit = 'account.bank.statement.import' - - @api.model - def _prepare_paypal_encoding(self): - '''This method is designed to be inherited''' - return 'utf-8' - - @api.model - def _prepare_paypal_date_format(self): - '''This method is designed to be inherited''' - return '%d/%m/%Y' - - @api.model - def _valid_paypal_line(self, line): - '''This method is designed to be inherited''' - col_name = line[5].replace('"','') - if col_name.startswith('Termin') or col_name.startswith('Rembours'): - return True - else: - return False - - @api.model - def _paypal_convert_amount(self, amount_str): - '''This method is designed to be inherited''' - valstr = re.sub(r'[^\d,.-]', '', amount_str) - valstrdot = valstr.replace('.', '') - valstrdot = valstrdot.replace(',', '.') - return float(valstrdot) - - @api.model - def _check_paypal(self, data_file): - '''This method is designed to be inherited''' - paypal = data_file.strip().startswith('Date,') - if not paypal: - paypal = data_file.strip().startswith('"Date",') - - return paypal - - @api.model - def _parse_file(self, data_file): - """ Import a file in Paypal CSV format""" - data_file = data_file.replace("\xef\xbb\xbf", "") - paypal = self._check_paypal(data_file) - if not paypal: - return super(AccountBankStatementImport, self)._parse_file( - data_file) - f = StringIO() - f.write(data_file) - f.seek(0) - transactions = [] - i = 0 - start_balance = end_balance = start_date_str = end_date_str = False - vals_line = False - company_currency_name = self.env.user.company_id.currency_id.name - commission_total = 0.0 - raw_lines = [] - paypal_email_account = False - # To confirm : is the encoding always latin1 ? - for line in unicodecsv.reader( - f, encoding=self._prepare_paypal_encoding()): - i += 1 - _logger.debug("Line %d: %s" % (i, line)) - if i == 1: - _logger.debug('Skip header line') - continue - if not line: - continue - if not self._valid_paypal_line(line): - _logger.info( - 'Skipping line %d because it is not in Done state' % i) - continue - date_dt = datetime.strptime( - line[0], self._prepare_paypal_date_format()) - rline = { - 'date': fields.Date.to_string(date_dt), - 'currency': line[6], - 'owner_name': line[3], - 'amount': line[7], - 'commission': line[8], - 'balance': line[27], - 'transac_ref': line[23], - 'ref': line[12], - 'line_nr': i, - } - 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: - raise Warning( - _("Value '%s' for the field '%s' on line %d, " - "cannot be converted to float") - % (rline[field], field, i)) - if rline['amount'] > 0: - rline['name'] = line[3] + ' ' + line[10] - rline['partner_email'] = line[10] - if not paypal_email_account: - paypal_email_account = line[11] - else: - rline['name'] = line[3] + ' ' + line[11] - rline['partner_email'] = line[11] - if not paypal_email_account: - paypal_email_account = line[10] - raw_lines.append(rline) - - # Second pass to sort out the lines in other currencies - final_lines = [] - other_currency_line = {} - for wline in raw_lines: - if company_currency_name != wline['currency']: - if wline['transac_ref'] and not other_currency_line: - currencies = self.env['res.currency'].search( - [('name', '=', wline['currency'])]) - if not currencies: - raise Warning( - _('Currency %s on line %d cannot be found in Odoo') - % (wline['currency'], wline['line_nr'])) - other_currency_line = { - 'amount_currency': wline['amount'], - 'currency_id': currencies[0].id, - 'currency': wline['currency'], - 'name': wline['name'], - 'owner_name': wline['owner_name'], - 'transac_ref': wline['transac_ref'], - } - - if other_currency_line and not wline['transac_ref']: - assert ( - wline['currency'] == other_currency_line['currency']),\ - 'WRONG currency' - assert ( - wline['amount'] == - other_currency_line['amount_currency'] * -1),\ - 'WRONG amount' - if ( - other_currency_line and - wline['ref'] == - other_currency_line['transac_ref']): - # reset other_currency_line - other_currency_line = {} - else: - if ( - other_currency_line and - wline['transac_ref'] == - other_currency_line['transac_ref']): - wline.update(other_currency_line) - # reset other_currency_line - other_currency_line = {} - final_lines.append(wline) - - # PayPal statements start with the end ! - final_lines.reverse() - j = 0 - for fline in final_lines: - j += 1 - commission_total += fline['commission'] - - if j == 1: - start_date_str = fline['date'] - start_balance = fline['balance'] - fline['amount'] - end_date_str = fline['date'] - end_balance = fline['balance'] - partners = False - if fline['partner_email']: - partners = self.env['res.partner'].search( - [('email', '=', fline['partner_email'])]) - if partners: - partner_id = partners[0].commercial_partner_id.id - else: - partner_id = False - vals_line = { - 'date': fline['date'], - 'name': fline['ref'], - 'ref': fline['name'], - 'unique_import_id': fline['ref'], - 'amount': fline['amount'], - 'partner_id': partner_id, - 'bank_account_id': False, - 'currency_id': fline.get('currency_id'), - 'amount_currency': fline.get('amount_currency'), - } - _logger.debug("vals_line = %s" % vals_line) - transactions.append(vals_line) - - if commission_total: - commission_line = { - 'date': end_date_str, - 'name': _('Paypal commissions'), - 'ref': _('PAYPAL-COSTS'), - 'amount': commission_total, - 'unique_import_id': False, - } - transactions.append(commission_line) - - vals_bank_statement = { - 'name': _('PayPal Import %s > %s') - % (start_date_str, end_date_str), - 'balance_start': start_balance, - 'balance_end_real': end_balance, - 'transactions': transactions, - } - return None, None, [vals_bank_statement] diff --git a/account_statement_import_paypal/models/__init__.py b/account_statement_import_paypal/models/__init__.py new file mode 100644 index 00000000..c950202d --- /dev/null +++ b/account_statement_import_paypal/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import account_bank_statement_import_paypal diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal.py b/account_statement_import_paypal/models/account_bank_statement_import_paypal.py new file mode 100644 index 00000000..0d3975be --- /dev/null +++ b/account_statement_import_paypal/models/account_bank_statement_import_paypal.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# 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 openerp import models, fields, api, _ +from openerp.exceptions import UserError +import re +from cStringIO import StringIO +_logger = logging.getLogger(__name__) + +try: + import unicodecsv +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' + + @api.model + def _get_paypal_encoding(self): + return 'utf-8' + + @api.model + def _get_paypal_date_format(self): + '''This method is designed to be inherited''' + return '%d/%m/%Y' + + @api.model + def _paypal_convert_amount(self, amount_str): + '''This method is designed to be inherited''' + valstr = re.sub(r'[^\d,.-]', '', amount_str) + valstrdot = valstr.replace('.', '') + valstrdot = valstrdot.replace(',', '.') + return float(valstrdot) + + @api.model + def _check_paypal(self, data_file): + for header in HEADERS: + if data_file.strip().startswith(header): + return True + return False + + def _convert_paypal_line_to_dict(self, idx, line): + date_dt = datetime.strptime(line[0], self._get_paypal_date_format()) + rline = { + 'date': fields.Date.to_string(date_dt), + 'time': line[1], + 'description': line[3], + 'currency': line[4], + 'amount': line[5], + 'commission': line[6], + 'balance': line[8], + 'transaction_id': line[9], + 'email': line[10], + 'partner_name': line[11], + # This two field are usefull for bank transfert + 'bank_name': line[12], + 'bank_account': line[13], + 'invoice_number': line[16], + 'origin_transaction_id': line[17], + 'idx': idx, + } + 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: + 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): + f = StringIO() + f.write(data_file) + f.seek(0) + raw_lines = [] + reader = unicodecsv.reader(f, encoding=self._get_paypal_encoding()) + reader.next() # 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 _post_process_statement_line(self, raw_lines): + journal_id = self.env.context.get('journal_id') + if not journal_id: + raise UserError(_('You must run this wizard from the journal')) + journal = self.env['account.journal'].browse(journal_id) + 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, + 'account_id': partner.property_account_receivable.id, + } + return None + + @api.model + def _complete_statement(self, stmts_vals, journal_id, account_number): + '''Match the partner from paypal information''' + stmts_vals = super(AccountBankStatementImport, self).\ + _complete_statement(stmts_vals, journal_id, account_number) + for line in stmts_vals['transactions']: + vals = self._complete_paypal_statement_line(line) + if vals: + line.update(vals) + return stmts_vals diff --git a/account_statement_import_paypal/static/description/icon.png b/account_statement_import_paypal/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5a237c234e73e3af7b60ec4bfda61639506379b9 GIT binary patch literal 6481 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 Z9&9huf?ZJO?yH1ATU}4BTIF@r{{ZB>*t-A# literal 0 HcmV?d00001 diff --git a/account_statement_import_paypal/static/description/paypal_backoffice.png b/account_statement_import_paypal/static/description/paypal_backoffice.png new file mode 100644 index 0000000000000000000000000000000000000000..a902aee13bea035e22df7db0059629d3bf347eb7 GIT binary patch literal 97703 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
TYeiKEFlk;DkWdNtFpX#oRiKiSjqcabJ;~^ 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 Date: Wed, 4 Jul 2018 11:16:17 +0200 Subject: [PATCH 05/34] [MIG]account_bank_statement_import_paypal: Migration to 11.0 --- account_statement_import_paypal/README.rst | 94 +++- account_statement_import_paypal/__init__.py | 2 - .../__manifest__.py | 13 +- .../account_bank_statement_import_paypal.pot | 56 +++ .../models/__init__.py | 2 - .../account_bank_statement_import_paypal.py | 40 +- .../readme/CONFIGURE.rst | 12 + .../readme/CONTRIBUTORS.rst | 5 + .../readme/DESCRIPTION.rst | 1 + .../readme/USAGE.rst | 8 + .../static/description/index.html | 453 ++++++++++++++++++ 11 files changed, 634 insertions(+), 52 deletions(-) create mode 100644 account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot create mode 100644 account_statement_import_paypal/readme/CONFIGURE.rst create mode 100644 account_statement_import_paypal/readme/CONTRIBUTORS.rst create mode 100644 account_statement_import_paypal/readme/DESCRIPTION.rst create mode 100644 account_statement_import_paypal/readme/USAGE.rst create mode 100644 account_statement_import_paypal/static/description/index.html diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst index 1c803401..b7558f30 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -1,49 +1,105 @@ +============================= Import Paypal Bank Statements ============================= +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbank--statement--import-lightgray.png?logo=github + :target: https://github.com/OCA/bank-statement-import/tree/11.0/account_bank_statement_import_paypal + :alt: OCA/bank-statement-import +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/bank-statement-import-11-0/bank-statement-import-11-0-account_bank_statement_import_paypal + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/174/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This module allows you to import the Paypal CSV files in Odoo as bank statements. +**Table of contents** + +.. contents:: + :local: + Configuration ============= -In the menu Accounting > Configuration > Accounts > Setup your Bank Accounts, make sure that you have your Paypal bank account with the following parameters: +In the menu Accounting > Configuration > Accounting > Bank Accounts, +make sure that you have your Paypal bank account with the following parameters: * Bank Account Type: Normal Bank Account * Account Number: the email address associated with your Paypal account * Account Journal: the journal associated to your Paypal account -============ +TIPS +~~~~ +For now only French and English report are supported. +For adding new support you just need to add your header in +model/account_bank_statement_import_paypal.py in the variables HEADERS. +Please help us and do a PR for adding new header ! Thanks -Go to Paypal and download your Bank Statement +Usage +===== -.. image:: account_bank_statement_import_paypal/static/description/paypal_backoffice.png +To use this module, you need to: + +#. Go to Paypal and download your Bank Statement + +.. image:: https://raw.githubusercontent.com/OCA/bank-statement-import/11.0/account_bank_statement_import_paypal/account_bank_statement_import_paypal/static/description/paypal_backoffice.png :alt: . -.. image:: static/description/paypal_backoffice.png +.. image:: https://raw.githubusercontent.com/OCA/bank-statement-import/11.0/account_bank_statement_import_paypal/static/description/paypal_backoffice.png :alt: . +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + Credits ======= +Authors +~~~~~~~ + +* Akretion + Contributors ------------- +~~~~~~~~~~~~ * Alexis de Lattre * Sebastien BEAU +* Tecnativa (https://www.tecnativa.com) -TIPS --------- -For now only French and English report are supported -For adding new support you just need to add your header in model/account_bank_statement_import_paypal.py in the variables HEADERS. -Please help us and do a PR for adding new header ! Thanks + * Vicent Cubells -Maintainer ----------- - -.. image:: http://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: http://odoo-community.org +Maintainers +~~~~~~~~~~~ This module is maintained by the OCA. -OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org -To contribute to this module, please visit http://odoo-community.org. +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/bank-statement-import `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_statement_import_paypal/__init__.py b/account_statement_import_paypal/__init__.py index cde864ba..0650744f 100644 --- a/account_statement_import_paypal/__init__.py +++ b/account_statement_import_paypal/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - from . import models diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index 4f20c115..ada7c9a0 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2014-2017 Akretion (http://www.akretion.com). # @author Alexis de Lattre # @author Sébastien BEAU @@ -6,24 +5,14 @@ { "name": "Import Paypal Bank Statements", 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', - "version": "10.0.1.0.0", + "version": "11.0.1.0.0", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", "author": " Akretion, Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, "installable": True, - "external_dependencies": { - 'python': ['unicodecsv'], - "bin": [], - }, "depends": [ "account_bank_statement_import", ], - "data": [ - ], - "demo": [ - ], - "qweb": [ - ] } 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 new file mode 100644 index 00000000..c5b0e90b --- /dev/null +++ b/account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot @@ -0,0 +1,56 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_bank_statement_import_paypal +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_bank_statement_import_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 +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:220 +#, python-format +msgid "PAYPAL-COSTS" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:185 +#, python-format +msgid "PayPal Import %s > %s" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:219 +#, python-format +msgid "Paypal commissions" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:97 +#, python-format +msgid "Value '%s' for the field '%s' on line %d, cannot be converted to float" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:134 +#, python-format +msgid "You must run this wizard from the journal" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:119 +#, python-format +msgid "currency %s on line %d cannot be found in odoo" +msgstr "" + diff --git a/account_statement_import_paypal/models/__init__.py b/account_statement_import_paypal/models/__init__.py index c950202d..4e11f724 100644 --- a/account_statement_import_paypal/models/__init__.py +++ b/account_statement_import_paypal/models/__init__.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - from . import account_bank_statement_import_paypal diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal.py b/account_statement_import_paypal/models/account_bank_statement_import_paypal.py index 0d3975be..e15d15fa 100644 --- a/account_statement_import_paypal/models/account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/models/account_bank_statement_import_paypal.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2014-2017 Akretion (http://www.akretion.com). # @author Alexis de Lattre # @author Sébastien BEAU @@ -6,14 +5,14 @@ import logging from datetime import datetime -from openerp import models, fields, api, _ -from openerp.exceptions import UserError +from odoo import _, api, fields, models +from odoo.exceptions import UserError import re -from cStringIO import StringIO +from io import StringIO _logger = logging.getLogger(__name__) try: - import unicodecsv + import csv except (ImportError, IOError) as err: _logger.debug(err) @@ -31,7 +30,7 @@ HEADERS = [ '"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"' + '"Reference Txn ID"', ] @@ -40,16 +39,22 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _get_paypal_encoding(self): - return 'utf-8' + 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 _get_paypal_date_format(self): - '''This method is designed to be inherited''' + """ This method is designed to be inherited """ return '%d/%m/%Y' @api.model def _paypal_convert_amount(self, amount_str): - '''This method is designed to be inherited''' + """ This method is designed to be inherited """ valstr = re.sub(r'[^\d,.-]', '', amount_str) valstrdot = valstr.replace('.', '') valstrdot = valstrdot.replace(',', '.') @@ -57,6 +62,7 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _check_paypal(self, data_file): + data_file = self._get_paypal_str_data(data_file) for header in HEADERS: if data_file.strip().startswith(header): return True @@ -75,7 +81,7 @@ class AccountBankStatementImport(models.TransientModel): 'transaction_id': line[9], 'email': line[10], 'partner_name': line[11], - # This two field are usefull for bank transfert + # This two field are useful for bank transfer 'bank_name': line[12], 'bank_account': line[13], 'invoice_number': line[16], @@ -86,7 +92,7 @@ class AccountBankStatementImport(models.TransientModel): _logger.debug('Trying to convert %s to float' % rline[field]) try: rline[field] = self._paypal_convert_amount(rline[field]) - except: + except Exception: raise UserError( _("Value '%s' for the field '%s' on line %d, " "cannot be converted to float") @@ -94,12 +100,12 @@ class AccountBankStatementImport(models.TransientModel): return rline def _parse_paypal_file(self, data_file): - f = StringIO() - f.write(data_file) + data_file = self._get_paypal_str_data(data_file) + f = StringIO(data_file) f.seek(0) raw_lines = [] - reader = unicodecsv.reader(f, encoding=self._get_paypal_encoding()) - reader.next() # Drop header + 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)) @@ -188,7 +194,7 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _parse_file(self, data_file): - """ Import a file in Paypal CSV format""" + """ Import a file in Paypal CSV format """ paypal = self._check_paypal(data_file) if not paypal: return super(AccountBankStatementImport, self)._parse_file( @@ -265,7 +271,7 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _complete_statement(self, stmts_vals, journal_id, account_number): - '''Match the partner from paypal information''' + """ Match the partner from paypal information """ stmts_vals = super(AccountBankStatementImport, self).\ _complete_statement(stmts_vals, journal_id, account_number) for line in stmts_vals['transactions']: diff --git a/account_statement_import_paypal/readme/CONFIGURE.rst b/account_statement_import_paypal/readme/CONFIGURE.rst new file mode 100644 index 00000000..0be09589 --- /dev/null +++ b/account_statement_import_paypal/readme/CONFIGURE.rst @@ -0,0 +1,12 @@ +In the menu Accounting > Configuration > Accounting > Bank Accounts, +make sure that you have your Paypal bank account with the following parameters: +* Bank Account Type: Normal Bank Account +* Account Number: the email address associated with your Paypal account +* Account Journal: the journal associated to your Paypal account + +TIPS +~~~~ +For now only French and English report are supported. +For adding new support you just need to add your header in +model/account_bank_statement_import_paypal.py in the variables HEADERS. +Please help us and do a PR for adding new header ! Thanks diff --git a/account_statement_import_paypal/readme/CONTRIBUTORS.rst b/account_statement_import_paypal/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..480d3836 --- /dev/null +++ b/account_statement_import_paypal/readme/CONTRIBUTORS.rst @@ -0,0 +1,5 @@ +* Alexis de Lattre +* Sebastien BEAU +* Tecnativa (https://www.tecnativa.com) + + * Vicent Cubells diff --git a/account_statement_import_paypal/readme/DESCRIPTION.rst b/account_statement_import_paypal/readme/DESCRIPTION.rst new file mode 100644 index 00000000..4da61e3a --- /dev/null +++ b/account_statement_import_paypal/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows you to import the Paypal CSV files in Odoo as bank statements. diff --git a/account_statement_import_paypal/readme/USAGE.rst b/account_statement_import_paypal/readme/USAGE.rst new file mode 100644 index 00000000..fdcc4da9 --- /dev/null +++ b/account_statement_import_paypal/readme/USAGE.rst @@ -0,0 +1,8 @@ +To use this module, you need to: + +#. Go to Paypal and download your Bank Statement + +.. image:: account_bank_statement_import_paypal/static/description/paypal_backoffice.png + :alt: . +.. image:: static/description/paypal_backoffice.png + :alt: . diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html new file mode 100644 index 00000000..5c4b7671 --- /dev/null +++ b/account_statement_import_paypal/static/description/index.html @@ -0,0 +1,453 @@ + + + + + + +Import Paypal Bank Statements + + + + + + From 026eb321f0b4dad16977eba2f8aac5d1d02ace38 Mon Sep 17 00:00:00 2001 From: cubells Date: Fri, 11 Jan 2019 11:48:33 +0100 Subject: [PATCH 06/34] [IMP] account_bank_statement_import_paypal: create paypal maps --- account_statement_import_paypal/README.rst | 25 +- account_statement_import_paypal/__init__.py | 1 + .../__manifest__.py | 12 +- .../data/paypal_map_data.xml | 114 ++++++ .../account_bank_statement_import_paypal.pot | 295 ++++++++++++++- account_statement_import_paypal/i18n/es.po | 348 ++++++++++++++++++ .../models/__init__.py | 3 +- ...ccount_bank_statement_import_paypal_map.py | 64 ++++ .../models/account_journal.py | 13 + .../readme/CONFIGURE.rst | 22 +- .../readme/DESCRIPTION.rst | 3 +- .../security/ir.model.access.csv | 3 + .../static/description/index.html | 55 ++- .../tests/__init__.py | 1 + .../tests/paypal_en.csv | 3 + .../tests/test_paypal_statement_import.py | 54 +++ .../views/account_journal_views.xml | 16 + .../views/paypal_map_views.xml | 65 ++++ .../wizards/__init__.py | 2 + .../account_bank_statement_import_paypal.py | 83 +++-- .../account_bank_statement_import_view.xml | 14 + .../wizards/create_map_lines_from_file.py | 38 ++ .../create_map_lines_from_file_views.xml | 29 ++ 23 files changed, 1166 insertions(+), 97 deletions(-) create mode 100644 account_statement_import_paypal/data/paypal_map_data.xml create mode 100644 account_statement_import_paypal/i18n/es.po create mode 100644 account_statement_import_paypal/models/account_bank_statement_import_paypal_map.py create mode 100644 account_statement_import_paypal/models/account_journal.py create mode 100644 account_statement_import_paypal/security/ir.model.access.csv create mode 100644 account_statement_import_paypal/tests/__init__.py create mode 100644 account_statement_import_paypal/tests/paypal_en.csv create mode 100644 account_statement_import_paypal/tests/test_paypal_statement_import.py create mode 100644 account_statement_import_paypal/views/account_journal_views.xml create mode 100644 account_statement_import_paypal/views/paypal_map_views.xml create mode 100644 account_statement_import_paypal/wizards/__init__.py rename account_statement_import_paypal/{models => wizards}/account_bank_statement_import_paypal.py (83%) create mode 100644 account_statement_import_paypal/wizards/account_bank_statement_import_view.xml create mode 100644 account_statement_import_paypal/wizards/create_map_lines_from_file.py create 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 b7558f30..0fa92e31 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -25,7 +25,8 @@ Import Paypal Bank Statements |badge1| |badge2| |badge3| |badge4| |badge5| -This module allows you to import the Paypal CSV files in Odoo as bank statements. +This module allows you to import the Paypal CSV files in Odoo as bank +statements. **Table of contents** @@ -35,18 +36,18 @@ This module allows you to import the Paypal CSV files in Odoo as bank statements Configuration ============= -In the menu Accounting > Configuration > Accounting > Bank Accounts, -make sure that you have your Paypal bank account with the following parameters: -* Bank Account Type: Normal Bank Account -* Account Number: the email address associated with your Paypal account -* Account Journal: the journal associated to your Paypal account +* 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. -TIPS -~~~~ -For now only French and English report are supported. -For adding new support you just need to add your header in -model/account_bank_statement_import_paypal.py in the variables HEADERS. -Please help us and do a PR for adding new header ! Thanks +* 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. Usage ===== diff --git a/account_statement_import_paypal/__init__.py b/account_statement_import_paypal/__init__.py index 0650744f..aee8895e 100644 --- a/account_statement_import_paypal/__init__.py +++ b/account_statement_import_paypal/__init__.py @@ -1 +1,2 @@ from . import models +from . import wizards diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index ada7c9a0..f4af6230 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -5,14 +5,22 @@ { "name": "Import Paypal Bank Statements", 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', - "version": "11.0.1.0.0", + "version": "11.0.2.0.0", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", "author": " Akretion, Odoo Community Association (OCA)", "license": "AGPL-3", - "application": False, "installable": True, "depends": [ "account_bank_statement_import", + "sale", ], + "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/paypal_map_data.xml b/account_statement_import_paypal/data/paypal_map_data.xml new file mode 100644 index 00000000..be289c7e --- /dev/null +++ b/account_statement_import_paypal/data/paypal_map_data.xml @@ -0,0 +1,114 @@ + + + + + Paypal Monthly Statement + + + + 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 c5b0e90b..3e24e191 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 @@ -6,6 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-01-11 10:43+0000\n" +"PO-Revision-Date: 2019-01-11 10:43+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -13,44 +15,325 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: account_bank_statement_import_paypal +#: model: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 "" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Balance" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Bank Account" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Bank Name" +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 +msgid "Bank Statement File" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Cancel" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Choose a file to import..." +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Create Lines" +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 +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 +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 +msgid "Date Format" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:90 +#, python-format +msgid "Date format of map file and Paypal date does not match." +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 +msgid "Display Name" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model: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 "" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Fee" +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 +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:73 +#, 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 +msgid "ID" +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 -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:220 +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Import Paypal Map Lines" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Invoice ID" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_journal +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 +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_line_write_uid +#: 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_wizard_paypal_map_create_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_line_write_date +#: 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_wizard_paypal_map_create_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" +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: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 +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:226 #, python-format msgid "PAYPAL-COSTS" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:185 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:191 #, python-format msgid "PayPal Import %s > %s" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:219 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_journal_paypal_map_id +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_tree +#: model: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.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:225 #, python-format msgid "Paypal commissions" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:97 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_map_id_4185 +msgid "Paypal map" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model: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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_tree +msgid "Paypal mapping lines" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view +msgid "Paypal with Template:" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: model: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." +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" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Time" +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:100 #, python-format msgid "Value '%s' for the field '%s' on line %d, cannot be converted to float" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:134 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:137 #, python-format msgid "You must run this wizard from the journal" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal.py:119 +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map +msgid "account.bank.statement.import.paypal.map" +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" +msgstr "" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:122 #, 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.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 +#: model:ir.model,name:account_bank_statement_import_paypal.model_wizard_paypal_map_create +msgid "wizard.paypal.map.create" +msgstr "" + diff --git a/account_statement_import_paypal/i18n/es.po b/account_statement_import_paypal/i18n/es.po new file mode 100644 index 00000000..d2c58f02 --- /dev/null +++ b/account_statement_import_paypal/i18n/es.po @@ -0,0 +1,348 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_bank_statement_import_paypal +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-01-11 10:43+0000\n" +"PO-Revision-Date: 2019-01-11 11:44+0100\n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 2.1.1\n" + +#. module: account_bank_statement_import_paypal +#: model: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" +msgstr "Saldo" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Bank Account" +msgstr "Cuenta bancaria" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Bank Name" +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 +msgid "Bank Statement File" +msgstr "Archivo de extracto bancario" + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Cancel" +msgstr "Cancelar" + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Choose a file to import..." +msgstr "Escoja un archivo a importar..." + +#. module: account_bank_statement_import_paypal +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Create Lines" +msgstr "Crear líneas" + +#. 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 +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 +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 +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:90 +#, 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 +#: 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 +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: account_bank_statement_import_paypal +#: model: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í." + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Fee" +msgstr "Tarifa" + +#. 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 +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:73 +#, 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 +msgid "ID" +msgstr "ID" + +#. 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +msgid "Import Paypal Map Lines" +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" +msgstr "Número de factura" + +#. module: account_bank_statement_import_paypal +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_journal +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 +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_line_write_uid +#: 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_wizard_paypal_map_create_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_line_write_date +#: 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_wizard_paypal_map_create_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" +msgstr "Líneas de la plantilla" + +#. module: account_bank_statement_import_paypal +#: model: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 +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:226 +#, 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:191 +#, 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form +#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_tree +#: model: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.ui.menu,name:account_bank_statement_import_paypal.menu_statement_import_paypal_mapping +msgid "Paypal Mapping" +msgstr "Plantilla de Paypal" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:225 +#, 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_4185 +msgid "Paypal map" +msgstr "Plantilla de Paypal" + +#. module: account_bank_statement_import_paypal +#: model: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: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:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view +msgid "Paypal with Template:" +msgstr "Paypal con la plantilla:" + +#. module: account_bank_statement_import_paypal +#: model: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." +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 +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "Time" +msgstr "Hora" + +#. module: account_bank_statement_import_paypal +#: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 +msgid "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:100 +#, 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 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:137 +#, 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 +#: model:ir.model,name:account_bank_statement_import_paypal.model_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 +msgid "account.bank.statement.import.paypal.map.line" +msgstr "account.bank.statement.import.paypal.map.line" + +#. module: account_bank_statement_import_paypal +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:122 +#, 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.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 +#: model:ir.model,name:account_bank_statement_import_paypal.model_wizard_paypal_map_create +msgid "wizard.paypal.map.create" +msgstr "wizard.paypal.map.create" diff --git a/account_statement_import_paypal/models/__init__.py b/account_statement_import_paypal/models/__init__.py index 4e11f724..4257b3bc 100644 --- a/account_statement_import_paypal/models/__init__.py +++ b/account_statement_import_paypal/models/__init__.py @@ -1 +1,2 @@ -from . import account_bank_statement_import_paypal +from . import account_bank_statement_import_paypal_map +from . import account_journal 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 new file mode 100644 index 00000000..159dfd49 --- /dev/null +++ b/account_statement_import_paypal/models/account_bank_statement_import_paypal_map.py @@ -0,0 +1,64 @@ +# Copyright 2019 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AccountBankStatementImportPaypalMap(models.Model): + _name = '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, + ) + + +class AccountBankStatementImportPaypalMapLIne(models.Model): + _name = '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_journal.py b/account_statement_import_paypal/models/account_journal.py new file mode 100644 index 00000000..5123a3c6 --- /dev/null +++ b/account_statement_import_paypal/models/account_journal.py @@ -0,0 +1,13 @@ +# Copyright 2019 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class AccountJournal(models.Model): + _inherit = "account.journal" + + paypal_map_id = fields.Many2one( + comodel_name='account.bank.statement.import.paypal.map', + string='Paypal Map', + ) diff --git a/account_statement_import_paypal/readme/CONFIGURE.rst b/account_statement_import_paypal/readme/CONFIGURE.rst index 0be09589..7693cae5 100644 --- a/account_statement_import_paypal/readme/CONFIGURE.rst +++ b/account_statement_import_paypal/readme/CONFIGURE.rst @@ -1,12 +1,12 @@ -In the menu Accounting > Configuration > Accounting > Bank Accounts, -make sure that you have your Paypal bank account with the following parameters: -* Bank Account Type: Normal Bank Account -* Account Number: the email address associated with your Paypal account -* Account Journal: the journal associated to your Paypal account +* 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. -TIPS -~~~~ -For now only French and English report are supported. -For adding new support you just need to add your header in -model/account_bank_statement_import_paypal.py in the variables HEADERS. -Please help us and do a PR for adding new header ! Thanks +* 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. diff --git a/account_statement_import_paypal/readme/DESCRIPTION.rst b/account_statement_import_paypal/readme/DESCRIPTION.rst index 4da61e3a..492b95df 100644 --- a/account_statement_import_paypal/readme/DESCRIPTION.rst +++ b/account_statement_import_paypal/readme/DESCRIPTION.rst @@ -1 +1,2 @@ -This module allows you to import the Paypal CSV files in Odoo as bank statements. +This module allows you to import the Paypal CSV files in Odoo as bank +statements. diff --git a/account_statement_import_paypal/security/ir.model.access.csv b/account_statement_import_paypal/security/ir.model.access.csv new file mode 100644 index 00000000..db61ffb0 --- /dev/null +++ b/account_statement_import_paypal/security/ir.model.access.csv @@ -0,0 +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 diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html index 5c4b7671..e3553e1a 100644 --- a/account_statement_import_paypal/static/description/index.html +++ b/account_statement_import_paypal/static/description/index.html @@ -368,41 +368,38 @@ ul.auto-toc { !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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 statements.

+

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

Table of contents

Configuration

-

In the menu Accounting > Configuration > Accounting > Bank Accounts, -make sure that you have your Paypal bank account with the following parameters: -* Bank Account Type: Normal Bank Account -* Account Number: the email address associated with your Paypal account -* Account Journal: the journal associated to your Paypal account

-
-

TIPS

-

For now only French and English report are supported. -For adding new support you just need to add your header in -model/account_bank_statement_import_paypal.py in the variables HEADERS. -Please help us and do a PR for adding new header ! Thanks

-
+
    +
  • 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.

-

Usage

+

Usage

To use this module, you need to:

  1. Go to Paypal and download your Bank Statement
  2. @@ -411,7 +408,7 @@ Please help us and do a PR for adding new header ! Thanks

    .
-

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 @@ -419,15 +416,15 @@ 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
-

Contributors

+

Contributors

-

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/tests/__init__.py b/account_statement_import_paypal/tests/__init__.py new file mode 100644 index 00000000..81608867 --- /dev/null +++ b/account_statement_import_paypal/tests/__init__.py @@ -0,0 +1 @@ +from . import test_paypal_statement_import diff --git a/account_statement_import_paypal/tests/paypal_en.csv b/account_statement_import_paypal/tests/paypal_en.csv new file mode 100644 index 00000000..f3ef282e --- /dev/null +++ b/account_statement_import_paypal/tests/paypal_en.csv @@ -0,0 +1,3 @@ +"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" +"12/15/2018","20:07:53","CET","Your best supplier","USD","-33,50","-2,3","-31,2","-31,2","53820712527632627","","John Doe","Bank of America","123456789","0","0","INV25","23" +"12/15/2018","22:07:53","CET","Your payment","USD","525","0","525","493,80","34731322767782103","","Agrolait","","","0","0","INV/2019/0003","24" diff --git a/account_statement_import_paypal/tests/test_paypal_statement_import.py b/account_statement_import_paypal/tests/test_paypal_statement_import.py new file mode 100644 index 00000000..7b241978 --- /dev/null +++ b/account_statement_import_paypal/tests/test_paypal_statement_import.py @@ -0,0 +1,54 @@ +# Copyright 2019 Tecnativa - Vicent Cubells +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import os +import base64 +from odoo.tests import common + + +class TestPaypalFile(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(TestPaypalFile, cls).setUpClass() + + cls.map = cls.env['account.bank.statement.import.paypal.map'].create({ + 'name': 'Paypal Map Test', + }) + cls.journal = cls.env['account.journal'].create({ + 'name': 'Paypal Bank', + 'type': 'bank', + 'code': 'PYPAL', + }) + + def _do_import(self, file_name): + file_name = os.path.join(os.path.dirname(__file__), file_name) + return open(file_name).read() + + def test_import_header(self): + file = self._do_import('paypal_en.csv') + file = base64.b64encode(file.encode("utf-8")) + wizard = self.env['wizard.paypal.map.create'].with_context({ + 'journal_id': self.journal.id, + 'active_ids': [self.map.id], + }).create({'data_file': file}) + wizard.create_map_lines() + self.assertEqual(len(self.map.map_line_ids.ids), 18) + + def test_import_paypal_file(self): + # Current statements before to run the wizard + old_statements = self.env['account.bank.statement'].search([]) + # This journal is for Paypal statements + map = self.env.ref('account_bank_statement_import_paypal.paypal_map') + self.journal.paypal_map_id = map.id + file = self._do_import('paypal_en.csv') + file = base64.b64encode(file.encode("utf-8")) + wizard = self.env['account.bank.statement.import'].with_context({ + 'journal_id': self.journal.id, + }).create({'data_file': file}) + wizard.import_file() + staments_now = self.env['account.bank.statement'].search([]) + statement = staments_now - old_statements + self.assertEqual(len(statement.line_ids), 3) + self.assertEqual(len(statement.mapped('line_ids').filtered( + lambda x: x.partner_id and x.account_id)), 1) + self.assertAlmostEqual(sum(statement.mapped('line_ids.amount')), 489.2) diff --git a/account_statement_import_paypal/views/account_journal_views.xml b/account_statement_import_paypal/views/account_journal_views.xml new file mode 100644 index 00000000..3e565b7d --- /dev/null +++ b/account_statement_import_paypal/views/account_journal_views.xml @@ -0,0 +1,16 @@ + + + + + account.journal + + + + + + + + + + + diff --git a/account_statement_import_paypal/views/paypal_map_views.xml b/account_statement_import_paypal/views/paypal_map_views.xml new file mode 100644 index 00000000..c3a40bac --- /dev/null +++ b/account_statement_import_paypal/views/paypal_map_views.xml @@ -0,0 +1,65 @@ + + + + + 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 new file mode 100644 index 00000000..006d24cd --- /dev/null +++ b/account_statement_import_paypal/wizards/__init__.py @@ -0,0 +1,2 @@ +from . import create_map_lines_from_file +from . import account_bank_statement_import_paypal diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal.py b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py similarity index 83% rename from account_statement_import_paypal/models/account_bank_statement_import_paypal.py rename to account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py index e15d15fa..be82f8c8 100644 --- a/account_statement_import_paypal/models/account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py @@ -37,6 +37,12 @@ HEADERS = [ 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' @@ -47,11 +53,6 @@ class AccountBankStatementImport(models.TransientModel): data_file = data_file.decode(self._get_paypal_encoding()) return data_file.strip() - @api.model - def _get_paypal_date_format(self): - """ This method is designed to be inherited """ - return '%d/%m/%Y' - @api.model def _paypal_convert_amount(self, amount_str): """ This method is designed to be inherited """ @@ -63,31 +64,33 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _check_paypal(self, data_file): data_file = self._get_paypal_str_data(data_file) - for header in HEADERS: - if data_file.strip().startswith(header): - return True - return False + if not self.paypal_map_id: + 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): - date_dt = datetime.strptime(line[0], self._get_paypal_date_format()) - rline = { - 'date': fields.Date.to_string(date_dt), - 'time': line[1], - 'description': line[3], - 'currency': line[4], - 'amount': line[5], - 'commission': line[6], - 'balance': line[8], - 'transaction_id': line[9], - 'email': line[10], - 'partner_name': line[11], - # This two field are useful for bank transfer - 'bank_name': line[12], - 'bank_account': line[13], - 'invoice_number': line[16], - 'origin_transaction_id': line[17], - 'idx': idx, - } + rline = dict() + for item in range(len(line)): + map = self.mapped('paypal_map_id.map_line_ids')[item] + value = line[item] + if not map.field_to_assign: + continue + if map.date_format: + try: + value = fields.Date.to_string( + datetime.strptime(value, map.date_format)) + except Exception: + raise UserError( + _("Date format of map file and Paypal date does " + "not match.")) + rline[map.field_to_assign] = value + for field in ['commission', 'amount', 'balance']: _logger.debug('Trying to convert %s to float' % rline[field]) try: @@ -128,11 +131,14 @@ class AccountBankStatementImport(models.TransientModel): 'transaction_id': cline['transaction_id'], } - def _post_process_statement_line(self, raw_lines): + 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')) - journal = self.env['account.journal'].browse(journal_id) + 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 = [] @@ -265,17 +271,24 @@ class AccountBankStatementImport(models.TransientModel): if partner: return { 'partner_id': partner.id, - 'account_id': partner.property_account_receivable.id, + 'account_id': partner.property_account_receivable_id.id, } return None @api.model - def _complete_statement(self, stmts_vals, journal_id, account_number): + def _complete_stmts_vals(self, stmts_vals, journal_id, account_number): """ Match the partner from paypal information """ - stmts_vals = super(AccountBankStatementImport, self).\ - _complete_statement(stmts_vals, journal_id, account_number) - for line in stmts_vals['transactions']: + 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_view.xml b/account_statement_import_paypal/wizards/account_bank_statement_import_view.xml new file mode 100644 index 00000000..ecb73648 --- /dev/null +++ b/account_statement_import_paypal/wizards/account_bank_statement_import_view.xml @@ -0,0 +1,14 @@ + + + + + account.bank.statement.import + + + +
  • Paypal with Template:
  • +
    +
    +
    + +
    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 new file mode 100644 index 00000000..139ae537 --- /dev/null +++ b/account_statement_import_paypal/wizards/create_map_lines_from_file.py @@ -0,0 +1,38 @@ +# 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' + + 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 new file mode 100644 index 00000000..c61136d5 --- /dev/null +++ b/account_statement_import_paypal/wizards/create_map_lines_from_file_views.xml @@ -0,0 +1,29 @@ + + + + + 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.

    + + +
    +
    + +
    +
    + + +
    From 5c6da31a12efe25ac410f449a5bbf5c869d18d0c Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Mon, 13 May 2019 15:17:38 +0200 Subject: [PATCH 07/34] [FIX] float parsing in paypal import In English version of the files, paypal uses ',' as thousands separator and '.' as decimal separator -> the previous code would populate the bank statement with wrong values without complaining. We fix this by allowing to configure the separators in the paypal map. --- .../data/paypal_map_data.xml | 4 +- ...ccount_bank_statement_import_paypal_map.py | 46 ++++++++++++++++++- .../tests/paypal_en.csv | 4 +- .../tests/test_paypal_statement_import.py | 10 ++-- .../views/paypal_map_views.xml | 2 + .../account_bank_statement_import_paypal.py | 21 +++++---- 6 files changed, 71 insertions(+), 16 deletions(-) diff --git a/account_statement_import_paypal/data/paypal_map_data.xml b/account_statement_import_paypal/data/paypal_map_data.xml index be289c7e..0eeef9ba 100644 --- a/account_statement_import_paypal/data/paypal_map_data.xml +++ b/account_statement_import_paypal/data/paypal_map_data.xml @@ -2,7 +2,9 @@ - Paypal Monthly Statement + Paypal Monthly Statement + comma + dot 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 index 159dfd49..cd848db6 100644 --- 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 @@ -1,7 +1,7 @@ # Copyright 2019 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models +from odoo import fields, models, api class AccountBankStatementImportPaypalMap(models.Model): @@ -17,6 +17,50 @@ class AccountBankStatementImportPaypalMap(models.Model): 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): diff --git a/account_statement_import_paypal/tests/paypal_en.csv b/account_statement_import_paypal/tests/paypal_en.csv index f3ef282e..1bef2f8a 100644 --- a/account_statement_import_paypal/tests/paypal_en.csv +++ b/account_statement_import_paypal/tests/paypal_en.csv @@ -1,3 +1,3 @@ "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" -"12/15/2018","20:07:53","CET","Your best supplier","USD","-33,50","-2,3","-31,2","-31,2","53820712527632627","","John Doe","Bank of America","123456789","0","0","INV25","23" -"12/15/2018","22:07:53","CET","Your payment","USD","525","0","525","493,80","34731322767782103","","Agrolait","","","0","0","INV/2019/0003","24" +"12/15/2018","20:07:53","CET","Your best supplier","USD","-33.50","-2.3","-31.2","-31.2","53820712527632627","","John Doe","Bank of America","123456789","0","0","INV25","23" +"12/15/2018","22:07:53","CET","Your payment","USD","1,525.00","0","1,525.00","1,493.80","34731322767782103","","Agrolait","","","0","0","INV/2019/0003","24" diff --git a/account_statement_import_paypal/tests/test_paypal_statement_import.py b/account_statement_import_paypal/tests/test_paypal_statement_import.py index 7b241978..8bd106fd 100644 --- a/account_statement_import_paypal/tests/test_paypal_statement_import.py +++ b/account_statement_import_paypal/tests/test_paypal_statement_import.py @@ -38,8 +38,10 @@ class TestPaypalFile(common.SavepointCase): # Current statements before to run the wizard old_statements = self.env['account.bank.statement'].search([]) # This journal is for Paypal statements - map = self.env.ref('account_bank_statement_import_paypal.paypal_map') - self.journal.paypal_map_id = map.id + paypal_map = self.env.ref( + 'account_bank_statement_import_paypal.paypal_map' + ) + self.journal.paypal_map_id = paypal_map.id file = self._do_import('paypal_en.csv') file = base64.b64encode(file.encode("utf-8")) wizard = self.env['account.bank.statement.import'].with_context({ @@ -51,4 +53,6 @@ class TestPaypalFile(common.SavepointCase): self.assertEqual(len(statement.line_ids), 3) self.assertEqual(len(statement.mapped('line_ids').filtered( lambda x: x.partner_id and x.account_id)), 1) - self.assertAlmostEqual(sum(statement.mapped('line_ids.amount')), 489.2) + self.assertAlmostEqual( + sum(statement.mapped('line_ids.amount')), 1489.2 + ) diff --git a/account_statement_import_paypal/views/paypal_map_views.xml b/account_statement_import_paypal/views/paypal_map_views.xml index c3a40bac..1fee4a66 100644 --- a/account_statement_import_paypal/views/paypal_map_views.xml +++ b/account_statement_import_paypal/views/paypal_map_views.xml @@ -16,6 +16,8 @@
    + + 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 index be82f8c8..ba79b534 100644 --- a/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py @@ -55,10 +55,13 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _paypal_convert_amount(self, amount_str): - """ This method is designed to be inherited """ - valstr = re.sub(r'[^\d,.-]', '', amount_str) - valstrdot = valstr.replace('.', '') - valstrdot = valstrdot.replace(',', '.') + 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 @@ -77,19 +80,19 @@ class AccountBankStatementImport(models.TransientModel): def _convert_paypal_line_to_dict(self, idx, line): rline = dict() for item in range(len(line)): - map = self.mapped('paypal_map_id.map_line_ids')[item] + paypal_map = self.mapped('paypal_map_id.map_line_ids')[item] value = line[item] - if not map.field_to_assign: + if not paypal_map.field_to_assign: continue - if map.date_format: + if paypal_map.date_format: try: value = fields.Date.to_string( - datetime.strptime(value, map.date_format)) + datetime.strptime(value, paypal_map.date_format)) except Exception: raise UserError( _("Date format of map file and Paypal date does " "not match.")) - rline[map.field_to_assign] = value + rline[paypal_map.field_to_assign] = value for field in ['commission', 'amount', 'balance']: _logger.debug('Trying to convert %s to float' % rline[field]) From c0c7bb4b7f209ba199f2438de3e2229015cb7161 Mon Sep 17 00:00:00 2001 From: Victor Martin Date: Mon, 20 May 2019 15:24:37 +0200 Subject: [PATCH 08/34] [MIG] account_bank_statement_import_paypal: Migration to 12.0 --- account_statement_import_paypal/README.rst | 15 +- .../__manifest__.py | 2 +- .../account_bank_statement_import_paypal.pot | 158 ++++++++++------- account_statement_import_paypal/i18n/es.po | 164 +++++++++++------- ...ccount_bank_statement_import_paypal_map.py | 4 +- .../readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 11 +- .../wizards/create_map_lines_from_file.py | 1 + 8 files changed, 211 insertions(+), 145 deletions(-) diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst index 0fa92e31..f14ab9df 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -14,13 +14,13 @@ Import Paypal Bank Statements :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbank--statement--import-lightgray.png?logo=github - :target: https://github.com/OCA/bank-statement-import/tree/11.0/account_bank_statement_import_paypal + :target: https://github.com/OCA/bank-statement-import/tree/12.0/account_bank_statement_import_paypal :alt: OCA/bank-statement-import .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/bank-statement-import-11-0/bank-statement-import-11-0-account_bank_statement_import_paypal + :target: https://translation.odoo-community.org/projects/bank-statement-import-12-0/bank-statement-import-12-0-account_bank_statement_import_paypal :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/174/11.0 + :target: https://runbot.odoo-community.org/runbot/174/12.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -56,9 +56,9 @@ To use this module, you need to: #. Go to Paypal and download your Bank Statement -.. image:: https://raw.githubusercontent.com/OCA/bank-statement-import/11.0/account_bank_statement_import_paypal/account_bank_statement_import_paypal/static/description/paypal_backoffice.png +.. 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/11.0/account_bank_statement_import_paypal/static/description/paypal_backoffice.png +.. image:: https://raw.githubusercontent.com/OCA/bank-statement-import/12.0/account_bank_statement_import_paypal/static/description/paypal_backoffice.png :alt: . Bug Tracker @@ -67,7 +67,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -87,6 +87,7 @@ Contributors * Tecnativa (https://www.tecnativa.com) * Vicent Cubells + * Victor M.M. Torres Maintainers ~~~~~~~~~~~ @@ -101,6 +102,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/bank-statement-import `_ project on GitHub. +This module is part of the `OCA/bank-statement-import `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index f4af6230..701d6bf8 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Import Paypal Bank Statements", 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', - "version": "11.0.2.0.0", + "version": "12.0.1.0.0", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", "author": " Akretion, Odoo Community Association (OCA)", 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 3e24e191..a2488da4 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 @@ -4,10 +4,8 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 11.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-11 10:43+0000\n" -"PO-Revision-Date: 2019-01-11 10:43+0000\n" "Last-Translator: <>\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -16,7 +14,17 @@ msgstr "" "Plural-Forms: \n" #. module: account_bank_statement_import_paypal -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map +msgid "Account Bank Statement Import Paypal Map" +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" +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." msgstr "" @@ -36,22 +44,22 @@ msgid "Bank Name" 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_wizard_paypal_map_create__data_file msgid "Bank Statement File" msgstr "" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Cancel" msgstr "" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Choose a file to import..." msgstr "" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Create Lines" msgstr "" @@ -61,16 +69,16 @@ 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_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 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_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 msgid "Created on" msgstr "" @@ -85,30 +93,35 @@ 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_map_line__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:90 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:93 #, python-format msgid "Date format of map file and Paypal date 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__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_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 msgid "Display Name" msgstr "" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Download a bank statement from your bank and import it here." msgstr "" @@ -118,12 +131,12 @@ msgid "Fee" 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 +#: 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_wizard_paypal_map_create__filename msgid "Filename" msgstr "" @@ -138,20 +151,20 @@ 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 +#: 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:73 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:76 #, 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_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 msgid "ID" msgstr "" @@ -161,7 +174,7 @@ msgid "Import Bank Statement" msgstr "" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Import Paypal Map Lines" msgstr "" @@ -176,44 +189,44 @@ 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_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 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_line_write_uid -#: 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_wizard_paypal_map_create_write_uid +#: 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 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_line_write_date -#: 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_wizard_paypal_map_create_write_date +#: 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 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 +#: 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 "" #. 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 +#: 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: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_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_map__name msgid "Name" msgstr "" @@ -223,22 +236,22 @@ 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:226 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:229 #, 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:191 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:194 #, 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_tree -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.view_account_journal_form_n43 +#: 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 "" @@ -249,41 +262,46 @@ msgid "Paypal Mapping" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:225 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:228 #, 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_4185 +#: 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_form +#: 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_tree +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_tree msgid "Paypal mapping lines" msgstr "" #. module: account_bank_statement_import_paypal -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view +#: model_terms:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view msgid "Paypal with Template:" msgstr "" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Select a Paypal bank statement file to create all the map lines from headers file." 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 +#: 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 "" +#. 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" +msgstr "" + #. module: account_bank_statement_import_paypal #: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 msgid "Time" @@ -295,33 +313,40 @@ msgid "Transaction ID" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:100 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:103 #, python-format msgid "Value '%s' for the field '%s' on line %d, cannot be converted to float" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:137 +#: 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:140 #, python-format msgid "You must run this wizard from the journal" msgstr "" #. 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" +#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +msgid "comma (,)" 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" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:122 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:125 #, 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 +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" @@ -333,7 +358,8 @@ msgid "i.e. 15/12/2019" 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" +#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.map,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 d2c58f02..1170eb5c 100644 --- a/account_statement_import_paypal/i18n/es.po +++ b/account_statement_import_paypal/i18n/es.po @@ -17,7 +17,21 @@ msgstr "" "X-Generator: Poedit 2.1.1\n" #. module: account_bank_statement_import_paypal -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.create_paypal_map_lines_view +#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map +#, 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." @@ -37,22 +51,22 @@ msgid "Bank Name" 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_wizard_paypal_map_create__data_file msgid "Bank Statement File" msgstr "Archivo de extracto bancario" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Cancel" msgstr "Cancelar" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Choose a file to import..." msgstr "Escoja un archivo a importar..." #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Create Lines" msgstr "Crear líneas" @@ -62,16 +76,16 @@ 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_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 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_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 msgid "Created on" msgstr "Creado por" @@ -86,32 +100,37 @@ 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_map_line__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:90 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:93 #, 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" +msgstr "" + #. 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_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 msgid "Display Name" msgstr "Nombre mostrado" #. module: account_bank_statement_import_paypal -#: model: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.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í." @@ -121,12 +140,12 @@ msgid "Fee" msgstr "Tarifa" #. 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 +#: 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_wizard_paypal_map_create__filename msgid "Filename" msgstr "Nombre de archivo" @@ -141,12 +160,12 @@ 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 +#: 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:73 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:76 #, python-format msgid "Headers of file to import and Paypal map lines does not match." msgstr "" @@ -154,9 +173,9 @@ msgstr "" "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_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 msgid "ID" msgstr "ID" @@ -166,7 +185,7 @@ msgid "Import Bank Statement" msgstr "Importar Extracto Bancario" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "Import Paypal Map Lines" msgstr "Importar las lineas de la plantilla de Paypal" @@ -181,44 +200,44 @@ 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_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 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_line_write_uid -#: 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_wizard_paypal_map_create_write_uid +#: 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 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_line_write_date -#: 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_wizard_paypal_map_create_write_date +#: 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 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 +#: 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 +#: 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 "Líneas de la plantilla" #. module: account_bank_statement_import_paypal -#: model: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_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_map__name msgid "Name" msgstr "Nombre" @@ -228,22 +247,22 @@ 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:226 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:229 #, 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:191 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:194 #, 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_form -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_tree -#: model:ir.ui.view,arch_db:account_bank_statement_import_paypal.view_account_journal_form_n43 +#: 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" @@ -254,33 +273,33 @@ msgid "Paypal Mapping" msgstr "Plantilla de Paypal" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:225 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:228 #, 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_4185 +#: 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_form +#: 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.statement_import_map_tax_line_tree +#: 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:ir.ui.view,arch_db:account_bank_statement_import_paypal.account_bank_statement_import_view +#: 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:" #. module: account_bank_statement_import_paypal -#: model: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.create_paypal_map_lines_view msgid "" "Select a Paypal bank statement file to create all the map lines from headers " "file." @@ -289,10 +308,15 @@ msgstr "" "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 +#: 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" +msgstr "" + #. module: account_bank_statement_import_paypal #: selection:account.bank.statement.import.paypal.map.line,field_to_assign:0 msgid "Time" @@ -304,34 +328,43 @@ msgid "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:100 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:103 #, 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 -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:137 +#: 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:140 #, 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 -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import_paypal_map -msgid "account.bank.statement.import.paypal.map" -msgstr "account.bank.statement.import.paypal.map" +#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +msgid "comma (,)" +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" -msgstr "account.bank.statement.import.paypal.map.line" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:122 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal.py:125 #, 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 +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" @@ -343,6 +376,7 @@ msgid "i.e. 15/12/2019" msgstr "p.e. 15/12/2019" #. 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 "wizard.paypal.map.create" +#: selection:account.bank.statement.import.paypal.map,float_decimal_sep:0 +#: selection:account.bank.statement.import.paypal.map,float_thousands_sep:0 +msgid "none" +msgstr "" 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 index cd848db6..06c82ef9 100644 --- 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 @@ -6,6 +6,7 @@ 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, @@ -63,8 +64,9 @@ class AccountBankStatementImportPaypalMap(models.Model): separators[self.float_decimal_sep]) -class AccountBankStatementImportPaypalMapLIne(models.Model): +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( diff --git a/account_statement_import_paypal/readme/CONTRIBUTORS.rst b/account_statement_import_paypal/readme/CONTRIBUTORS.rst index 480d3836..6e9a18d1 100644 --- a/account_statement_import_paypal/readme/CONTRIBUTORS.rst +++ b/account_statement_import_paypal/readme/CONTRIBUTORS.rst @@ -3,3 +3,4 @@ * Tecnativa (https://www.tecnativa.com) * Vicent Cubells + * Victor M.M. Torres diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html index e3553e1a..779071f9 100644 --- a/account_statement_import_paypal/static/description/index.html +++ b/account_statement_import_paypal/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

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

    +

    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 statements.

    Table of contents

    @@ -404,15 +404,15 @@ Lines and set every line with which field of statement have to match.
  • Go to Paypal and download your Bank Statement
  • -. -. +. +.

    Bug Tracker

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

    +feedback.

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

    @@ -430,6 +430,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
  • Sebastien BEAU <sebastien.beau@akretion.com>
  • Tecnativa (https://www.tecnativa.com)
  • @@ -441,7 +442,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

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

    -

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

    +

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

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

    diff --git a/account_statement_import_paypal/wizards/create_map_lines_from_file.py b/account_statement_import_paypal/wizards/create_map_lines_from_file.py index 139ae537..a9ca019a 100644 --- a/account_statement_import_paypal/wizards/create_map_lines_from_file.py +++ b/account_statement_import_paypal/wizards/create_map_lines_from_file.py @@ -9,6 +9,7 @@ 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', From d2e1e26009623110cd56b19e9f76a6b66329a822 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Mon, 1 Jul 2019 18:59:05 +0200 Subject: [PATCH 09/34] [FIX] account_bank_statement_import_paypal: Declare import type If not, no import option is available --- account_statement_import_paypal/models/account_journal.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/account_statement_import_paypal/models/account_journal.py b/account_statement_import_paypal/models/account_journal.py index 5123a3c6..0bc634e2 100644 --- a/account_statement_import_paypal/models/account_journal.py +++ b/account_statement_import_paypal/models/account_journal.py @@ -11,3 +11,8 @@ class AccountJournal(models.Model): comodel_name='account.bank.statement.import.paypal.map', string='Paypal Map', ) + + def _get_bank_statements_available_import_formats(self): + res = super()._get_bank_statements_available_import_formats() + res.append('Paypal') + return res From 5dde51681afe6afec36235c900bd5b1dba09e57a Mon Sep 17 00:00:00 2001 From: Vincent Barrier Date: Wed, 3 Jul 2019 20:57:01 +0200 Subject: [PATCH 10/34] [FIX] account_bank_statement_import_paypal: Filter Exception => UnicodeDecodeError + refactoring + exception using multiple files type --- .../wizards/account_bank_statement_import_paypal.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 index ba79b534..a6db902f 100644 --- a/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/wizards/account_bank_statement_import_paypal.py @@ -66,9 +66,13 @@ class AccountBankStatementImport(models.TransientModel): @api.model def _check_paypal(self, data_file): - data_file = self._get_paypal_str_data(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): From b40c6218e810428c64a12e7849c9234b38a25b6c Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 19 Jul 2019 17:11:12 +0200 Subject: [PATCH 11/34] [FIX] account_bank_statement_import_paypal: Don't populate partner account This makes the statement lines to not appear on reconciliation widget. --- account_statement_import_paypal/__manifest__.py | 2 +- account_statement_import_paypal/static/description/index.html | 2 +- .../tests/test_paypal_statement_import.py | 2 +- .../wizards/account_bank_statement_import_paypal.py | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index 701d6bf8..fcb02832 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Import Paypal Bank Statements", 'summary': 'Import Paypal CSV files as Bank Statements in Odoo', - "version": "12.0.1.0.0", + "version": "12.0.1.0.1", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", "author": " Akretion, Odoo Community Association (OCA)", diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html index 779071f9..402d1959 100644 --- a/account_statement_import_paypal/static/description/index.html +++ b/account_statement_import_paypal/static/description/index.html @@ -3,7 +3,7 @@ - + Import Paypal Bank Statements -
    -

    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.

    - - -
    -
    - -
    -
    - - -
    From fc0b6f756c8ef5dea53e055637e800982d939d2a Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Sun, 29 Mar 2020 13:36:20 +0200 Subject: [PATCH 15/34] [FIX] account_bank_statement_import_paypal: lost wizard --- .../__manifest__.py | 2 +- ...t_bank_statement_import_paypal_mapping.xml | 44 +++++++++---------- ...statement_import_paypal_mapping_wizard.xml | 19 ++++---- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index 78e9b009..4e4c1ef5 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -6,7 +6,7 @@ { 'name': 'PayPal CSV Format Bank Statements Import', 'summary': 'Import PayPal CSV files as Bank Statements in Odoo', - 'version': '12.0.2.0.0', + 'version': '12.0.2.0.1', 'category': 'Accounting', 'website': 'https://github.com/OCA/bank-statement-import', 'author': 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 index 05ed5fe2..7d81e680 100644 --- 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 @@ -30,37 +30,37 @@ + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - PayPal Report Mappings account.bank.statement.import.paypal.mapping 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 index 148e5b4a..19b8b3b5 100644 --- 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 @@ -22,13 +22,14 @@ - - Import Mapping - account.bank.statement.import.paypal.mapping.wizard - account.bank.statement.import.paypal.mapping - form - form - new - + - \ No newline at end of file + From 3b4db7df53a11e3e064f54bffb91c82b79f49a37 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Wed, 8 Apr 2020 09:00:59 +0200 Subject: [PATCH 16/34] [IMP] account_bank_statement_import_paypal: better wizard --- .../__manifest__.py | 4 +- account_statement_import_paypal/data/maps.xml | 47 ++++- .../account_bank_statement_import_paypal.pot | 46 +++-- account_statement_import_paypal/i18n/es.po | 60 ++++-- .../tests/fixtures/statement_en.csv | 10 +- .../tests/fixtures/statement_es.csv | 5 + ...st_account_bank_statement_import_paypal.py | 77 ++++++-- ..._statement_import_paypal_mapping_wizard.py | 180 +++++++++++++----- ...statement_import_paypal_mapping_wizard.xml | 149 ++++++++++++++- 9 files changed, 468 insertions(+), 110 deletions(-) create mode 100644 account_statement_import_paypal/tests/fixtures/statement_es.csv diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index 4e4c1ef5..e4e56a67 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -6,7 +6,7 @@ { 'name': 'PayPal CSV Format Bank Statements Import', 'summary': 'Import PayPal CSV files as Bank Statements in Odoo', - 'version': '12.0.2.0.1', + 'version': '12.0.2.1.0', 'category': 'Accounting', 'website': 'https://github.com/OCA/bank-statement-import', 'author': @@ -17,6 +17,8 @@ 'installable': True, 'depends': [ 'account_bank_statement_import', + 'multi_step_wizard', + 'web_widget_dropdown_dynamic', ], 'external_dependencies': { 'python': [ diff --git a/account_statement_import_paypal/data/maps.xml b/account_statement_import_paypal/data/maps.xml index 78337e43..1f727547 100644 --- a/account_statement_import_paypal/data/maps.xml +++ b/account_statement_import_paypal/data/maps.xml @@ -1,7 +1,7 @@ @@ -51,4 +51,49 @@ Note + + PayPal Statement (ES) + dot + comma + %d/%m/%Y + %H:%M:%S + Fecha + Hora + Zona horaria + Nombre + Divisa + Bruto + Comisión + Saldo + Id. de transacción + Descripción + Correo electrónico del remitente + Id. de factura + Nombre del banco + Cuenta bancaria + + + + PayPal Activity (ES) + dot + comma + %d/%m/%Y + %H:%M:%S + Fecha + Hora + Zona horaria + Nombre + Divisa + Bruto + Tarifa + Saldo + Id. de transacción + Tipo + Correo electrónico del remitente + Correo electrónico del destinatario + Número de factura + Asunto + Nota + + 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 3eb82bdd..1c5587d6 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 @@ -15,91 +15,109 @@ 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__balance_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__balance_column msgid "\"Balance\" 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__bank_account_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_account_column msgid "\"Bank Account\" 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__bank_name_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_name_column msgid "\"Bank 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__currency_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__currency_column msgid "\"Currency\" 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__date_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__description_column msgid "\"Description\" 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__fee_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__type_column msgid "\"Type\" column" msgstr "" @@ -124,11 +142,6 @@ msgstr "" 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.account_bank_statement_import_paypal_mapping_wizard_form msgid "Cancel" @@ -182,14 +195,13 @@ msgid "Fee for %s" msgstr "" #. module: account_bank_statement_import_paypal -#: 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." +#: 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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__filename -msgid "Filename" +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__header +msgid "Header" msgstr "" #. module: account_bank_statement_import_paypal @@ -215,7 +227,7 @@ msgid "Import Mapping" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:78 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:162 #, python-format msgid "Imported Mapping" msgstr "" @@ -253,7 +265,7 @@ msgid "Last Updated on" msgstr "" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:26 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:130 #, python-format msgid "Mapping from %s" msgstr "" @@ -263,6 +275,11 @@ msgstr "" msgid "Name" 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 "PayPal Report File" +msgstr "" + #. module: account_bank_statement_import_paypal #: 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 @@ -284,6 +301,11 @@ msgstr "" 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_mapping_wizard__state +msgid "State" +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__float_thousands_sep msgid "Thousands Separator" diff --git a/account_statement_import_paypal/i18n/es.po b/account_statement_import_paypal/i18n/es.po index 878f40ad..0baf4747 100644 --- a/account_statement_import_paypal/i18n/es.po +++ b/account_statement_import_paypal/i18n/es.po @@ -19,6 +19,7 @@ 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__balance_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__balance_column #, fuzzy #| msgid "Balance" msgid "\"Balance\" column" @@ -26,6 +27,7 @@ msgstr "Saldo" #. module: account_bank_statement_import_paypal #: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__bank_account_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_account_column #, fuzzy #| msgid "Bank Account" msgid "\"Bank Account\" column" @@ -33,6 +35,7 @@ msgstr "Cuenta bancaria" #. module: account_bank_statement_import_paypal #: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__bank_name_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_name_column #, fuzzy #| msgid "Bank Name" msgid "\"Bank Name\" column" @@ -40,6 +43,7 @@ msgstr "Nombre del banco" #. module: account_bank_statement_import_paypal #: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__currency_column +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__currency_column #, fuzzy #| msgid "Currency" msgid "\"Currency\" column" @@ -47,11 +51,13 @@ 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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__description_column #, fuzzy #| msgid "Description" msgid "\"Description\" column" @@ -59,11 +65,13 @@ 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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__from_email_address_column #, fuzzy #| msgid "From Email Address" msgid "\"From Email Address\" column" @@ -71,11 +79,13 @@ 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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__invoice_id_column #, fuzzy #| msgid "Invoice ID" msgid "\"Invoice ID\" column" @@ -83,31 +93,37 @@ 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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__to_email_address_column #, fuzzy #| msgid "From Email Address" msgid "\"To Email Address\" column" @@ -115,6 +131,7 @@ 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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__transaction_id_column #, fuzzy #| msgid "Transaction ID" msgid "\"Transaction ID\" column" @@ -122,6 +139,7 @@ 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 +#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__type_column msgid "\"Type\" column" msgstr "" @@ -152,11 +170,6 @@ msgstr "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.account_bank_statement_import_paypal_mapping_wizard_form msgid "Cancel" @@ -211,19 +224,18 @@ msgstr "Nombre mostrado" msgid "Fee for %s" msgstr "" -#. module: account_bank_statement_import_paypal -#: 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_mapping_wizard__filename msgid "Filename" msgstr "Nombre de archivo" +#. 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__header +#, fuzzy +#| msgid "Header Name" +msgid "Header" +msgstr "Nombre de la cabecera" + #. module: account_bank_statement_import_paypal #: 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 @@ -249,7 +261,7 @@ msgid "Import Mapping" msgstr "Importar las lineas de la plantilla de Paypal" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:78 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:162 #, fuzzy, python-format #| msgid "Import Paypal Map Lines" msgid "Imported Mapping" @@ -289,7 +301,7 @@ msgid "Last Updated on" msgstr "Última actualización en" #. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:26 +#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:130 #, fuzzy, python-format #| msgid "Mapping Lines" msgid "Mapping from %s" @@ -300,6 +312,13 @@ msgstr "Líneas de la plantilla" msgid "Name" msgstr "Nombre" +#. 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 +#, fuzzy +#| msgid "Paypal Mapping" +msgid "PayPal Report File" +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_report_mappings #: model:ir.ui.menu,name:account_bank_statement_import_paypal.menu_statement_import_paypal_mapping @@ -327,6 +346,11 @@ msgstr "Plantilla de Paypal" 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_mapping_wizard__state +msgid "State" +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__float_thousands_sep #, fuzzy @@ -366,6 +390,9 @@ msgstr "punto (.)" msgid "none" msgstr "nada" +#~ msgid "Bank Statement File" +#~ msgstr "Archivo de extracto bancario" + #, fuzzy #~| msgid "account.bank.statement.import.paypal.map.line" #~ msgid "Account Bank Statement Import Paypal Map Line" @@ -400,9 +427,6 @@ msgstr "nada" #~ 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 " diff --git a/account_statement_import_paypal/tests/fixtures/statement_en.csv b/account_statement_import_paypal/tests/fixtures/statement_en.csv index b7407dbb..11fea15f 100644 --- a/account_statement_import_paypal/tests/fixtures/statement_en.csv +++ b/account_statement_import_paypal/tests/fixtures/statement_en.csv @@ -9,12 +9,12 @@ "9/27/2018","21:33:27","America/Los_Angeles","General Currency Conversion","EUR","9,648.13","0.00","9,648.13","0.75","TID8","","","","","0.00","0.00","","TID7" "9/4/2018","20:44:10","America/Los_Angeles","Express Checkout Payment","USD","1,309.80","-48.76","1,261.04","1,261.93","TID9","paypal@partner1.com","Partner 1","","","0.00","0.00","361","" "9/4/2018","21:15:11","America/Los_Angeles","General Currency Conversion","USD","-1,261.00","0.00","-1,261.00","0.93","TID10","","","","","0.00","0.00","","TID1" -"9/10/2018","17:48:19","America/Los_Angeles","Express Checkout Payment","USD","3,840.60","-142.40","3,698.20","3,699.13","TID11","paypa@partner2.com","Partner 2","","","0.00","0.00","362","" +"9/10/2018","17:48:19","America/Los_Angeles","Express Checkout Payment","USD","3,840.60","-142.40","3,698.20","3,699.13","TID11","paypal@partner2.com","Partner 2","","","0.00","0.00","362","" "9/11/2018","00:01:50","America/Los_Angeles","General Currency Conversion","USD","-3,699.00","0.00","-3,699.00","0.13","TID12","","","","","0.00","0.00","","TID3" -"9/24/2018","16:41:01","America/Los_Angeles","Express Checkout Payment","USD","4,447.40","-164.85","4,282.55","4,282.68","TID13","paypa@partner2.com","Partner 2","","","0.00","0.00","363","" +"9/24/2018","16:41:01","America/Los_Angeles","Express Checkout Payment","USD","4,447.40","-164.85","4,282.55","4,282.68","TID13","paypal@partner2.com","Partner 2","","","0.00","0.00","363","" "9/25/2018","04:22:39","America/Los_Angeles","General Currency Conversion","USD","-4,282.00","0.00","-4,282.00","0.68","TID14","","","","","0.00","0.00","","TID5" -"9/27/2018","18:15:34","America/Los_Angeles","Express Checkout Payment","USD","5,600.00","-207.50","5,392.50","5,393.18","TID15","paypa@partner3.com","Partner 3","","","0.00","0.00","366","" -"9/27/2018","18:16:12","CET","Express Checkout Payment","USD","920.70","-34.37","886.33","6,279.51","TID16","paypa@partner3.com","Partner 3","","","0.00","0.00","367","" -"9/27/2018","18:17:59","America/Los_Angeles","Express Checkout Payment","USD","5,600.00","-207.50","5,392.50","11,672.01","TID17","paypa@partner3.com","Partner 3","","","0.00","0.00","371","" +"9/27/2018","18:15:34","America/Los_Angeles","Express Checkout Payment","USD","5,600.00","-207.50","5,392.50","5,393.18","TID15","paypal@partner3.com","Partner 3","","","0.00","0.00","366","" +"9/27/2018","18:16:12","CET","Express Checkout Payment","USD","920.70","-34.37","886.33","6,279.51","TID16","paypal@partner3.com","Partner 3","","","0.00","0.00","367","" +"9/27/2018","18:17:59","America/Los_Angeles","Express Checkout Payment","USD","5,600.00","-207.50","5,392.50","11,672.01","TID17","paypal@partner3.com","Partner 3","","","0.00","0.00","371","" "9/27/2018","21:33:27","America/Los_Angeles","General Currency Conversion","USD","-11,672.00","0.00","-11,672.00","0.01","TID18","","","","","0.00","0.00","","TID7" "9/30/2018","21:22:33","America/Los_Angeles","Express Checkout Payment","USD","292.30","-11.12","281.18","281.19","TID19","paypal@partner1.com","Partner 1","","","0.00","0.00","380","" diff --git a/account_statement_import_paypal/tests/fixtures/statement_es.csv b/account_statement_import_paypal/tests/fixtures/statement_es.csv new file mode 100644 index 00000000..5f01b116 --- /dev/null +++ b/account_statement_import_paypal/tests/fixtures/statement_es.csv @@ -0,0 +1,5 @@ +"Fecha","Hora","Zona horaria","Descripción","Divisa","Bruto","Comisión","Neto","Saldo","Id. de transacción","Correo electrónico del remitente","Nombre","Nombre del banco","Cuenta bancaria","Importe de envío y manipulación","Impuesto de ventas","Id. de factura","Id. de referencia de trans.",,,,,, +"2/1/2020","11:05:56","Europe/Berlin","Pago estándar","EUR","49,37","-1,78","47,59","4.626,81","TID1","paypal@partner1.com","Partner 1","","","0,00","0,00","","" +"2/1/2020","13:06:07","Europe/Berlin","Pago estándar","EUR","28,82","-1,19","27,63","4.654,44","TID2","paypal@partner2.com","Partner 2","","","0,00","0,00","","" +"2/1/2020","19:20:05","Europe/Berlin","Pago estándar","EUR","35,78","-1,39","34,39","4.688,83","TID3","paypal@partner3.com","Partner 3","","","0,00","0,00","","" +"3/1/2020","09:44:24","Europe/Berlin","Pago estándar","EUR","22,47","-1,00","21,47","4.710,30","TID4","paypal@partner4.com","Partner 4","","","0,00","0,00","","" diff --git a/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py b/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py index 8ad24de1..afb78b9c 100644 --- a/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py @@ -20,6 +20,9 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): self.paypal_statement_map_en = self.env.ref( 'account_bank_statement_import_paypal.paypal_statement_map_en' ) + self.paypal_statement_map_es = self.env.ref( + 'account_bank_statement_import_paypal.paypal_statement_map_es' + ) self.paypal_activity_map_en = self.env.ref( 'account_bank_statement_import_paypal.paypal_activity_map_en' ) @@ -63,6 +66,30 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 18) + def test_import_statement_es(self): + journal = self.AccountJournal.create({ + 'name': 'PayPal', + 'type': 'bank', + 'code': 'PP', + 'currency_id': self.currency_eur.id, + }) + wizard = self.AccountBankStatementImport.with_context({ + 'journal_id': journal.id, + }).create({ + 'filename': 'fixtures/statement_es.csv', + 'data_file': self._data_file('fixtures/statement_es.csv'), + 'paypal_mapping_id': self.paypal_statement_map_es.id, + }) + wizard.with_context({ + 'journal_id': journal.id, + 'account_bank_statement_import_paypal_test': True, + }).import_file() + statement = self.AccountBankStatement.search([ + ('journal_id', '=', journal.id), + ]) + self.assertEqual(len(statement), 1) + self.assertEqual(len(statement.line_ids), 8) + def test_import_activity_en(self): journal = self.AccountJournal.create({ 'name': 'PayPal', @@ -112,21 +139,39 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): self.assertEqual(len(statement), 0) def test_import_activity_mapping_en(self): - wizard = self.AccountBankStatementImportPayPalMappingWizard.create({ - 'filename': 'fixtures/activity_en.csv', - 'data_file': self._data_file('fixtures/activity_en.csv'), - }) - mapping = self.AccountBankStatementImportPayPalMapping.browse( - wizard.import_mapping()['res_id'] - ) - self.assertTrue(mapping) + with common.Form( + self.AccountBankStatementImportPayPalMappingWizard) as form: + form.filename = 'fixtures/activity_en.csv' + form.data_file = self._data_file( + 'fixtures/activity_en.csv' + ) + self.assertEqual( + len( + self.AccountBankStatementImportPayPalMappingWizard + .with_context( + header=form.header, + ).statement_columns() + ), + 22 + ) + wizard = form.save() + wizard.import_mapping() def test_import_statement_mapping_en(self): - wizard = self.AccountBankStatementImportPayPalMappingWizard.create({ - 'filename': 'fixtures/statement_en.csv', - 'data_file': self._data_file('fixtures/statement_en.csv'), - }) - mapping = self.AccountBankStatementImportPayPalMapping.browse( - wizard.import_mapping()['res_id'] - ) - self.assertTrue(mapping) + with common.Form( + self.AccountBankStatementImportPayPalMappingWizard) as form: + form.filename = 'fixtures/statement_en.csv' + form.data_file = self._data_file( + 'fixtures/statement_en.csv' + ) + self.assertEqual( + len( + self.AccountBankStatementImportPayPalMappingWizard + .with_context( + header=form.header, + ).statement_columns() + ), + 18 + ) + wizard = form.save() + wizard.import_mapping() 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 index e7eb45cc..1c731867 100644 --- 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 @@ -1,78 +1,162 @@ # Copyright 2019 Tecnativa - Vicent Cubells -# Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2019-2020 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 +import json from os import path class AccountBankStatementImportPayPalMappingWizard(models.TransientModel): _name = 'account.bank.statement.import.paypal.mapping.wizard' _description = 'Account Bank Statement Import PayPal Mapping Wizard' + _inherit = ['multi.step.wizard.mixin'] data_file = fields.Binary( - string='Bank Statement File', + string='PayPal Report File', required=True, ) filename = fields.Char() + header = fields.Char() + date_column = fields.Char( + string='"Date" column', + ) + time_column = fields.Char( + string='"Time" column', + ) + tz_column = fields.Char( + string='"Timezone" column', + ) + name_column = fields.Char( + string='"Name" column', + ) + currency_column = fields.Char( + string='"Currency" column', + ) + gross_column = fields.Char( + string='"Gross" column', + ) + fee_column = fields.Char( + string='"Fee" column', + ) + balance_column = fields.Char( + string='"Balance" column', + ) + transaction_id_column = fields.Char( + string='"Transaction ID" column', + ) + 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('data_file') + def _onchange_data_file(self): + Parser = self.env['account.bank.statement.import.paypal.parser'] + if not self.data_file: + return + header = Parser.parse_header(b64decode(self.data_file)) + header = [column for column in header if column] + self.header = json.dumps(header) + if len(header) == 22: + self.date_column = header[0] + self.time_column = header[1] + self.tz_column = header[2] + self.name_column = header[3] + self.currency_column = header[6] + self.gross_column = header[7] + self.fee_column = header[8] + self.balance_column = header[18] + self.transaction_id_column = header[12] + self.type_column = header[4] + self.from_email_address_column = header[10] + self.to_email_address_column = header[11] + self.invoice_id_column = header[16] + self.subject_column = header[20] + self.note_column = header[21] + elif len(header) == 18: + self.date_column = header[0] + self.time_column = header[1] + self.tz_column = header[2] + self.name_column = header[11] + self.currency_column = header[4] + self.gross_column = header[5] + self.fee_column = header[6] + self.balance_column = header[8] + self.transaction_id_column = header[9] + self.description_column = header[3] + self.from_email_address_column = header[10] + self.invoice_id_column = header[16] + self.bank_name_column = header[12] + self.bank_account_column = header[13] + + @api.model + def statement_columns(self): + header = self.env.context.get('header') + if not header: + return [] + return [(x, x) for x in json.loads(header)] @api.multi - def import_mapping(self): + def _get_mapping_values(self): + """Hook for extension""" self.ensure_one() - mapping_values = { + return { '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', + 'date_column': self.date_column, + 'time_column': self.time_column, + 'tz_column': self.tz_column, + 'name_column': self.name_column, + 'currency_column': self.currency_column, + 'gross_column': self.gross_column, + 'fee_column': self.fee_column, + 'balance_column': self.balance_column, + 'transaction_id_column': self.transaction_id_column, + 'description_column': self.description_column, + 'type_column': self.type_column, + 'from_email_address_column': self.from_email_address_column, + 'to_email_address_column': self.to_email_address_column, + 'invoice_id_column': self.invoice_id_column, + 'subject_column': self.subject_column, + 'note_column': self.note_column, + 'bank_name_column': self.bank_name_column, + 'bank_account_column': self.bank_account_column, } - 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.' - )) + + @api.multi + def import_mapping(self): + self.ensure_one() mapping = self.env['account.bank.statement.import.paypal.mapping']\ - .create(mapping_values) + .create(self._get_mapping_values()) return { 'type': 'ir.actions.act_window', 'name': _('Imported Mapping'), 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 index 19b8b3b5..7d98544f 100644 --- 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 @@ -1,7 +1,7 @@ @@ -9,16 +9,147 @@ account.bank.statement.import.paypal.mapping.wizard.form account.bank.statement.import.paypal.mapping.wizard + primary + -
    +

    Select a PayPal report file to import mapping.

    - - -
    -
    - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + btn-default + Cancel + + +
    @@ -456,6 +456,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
  • Tecnativa (https://www.tecnativa.com)
  • Alexey Pelykh <alexey.pelykh@brainbeanapps.com>
  • @@ -468,7 +469,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

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

    -

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

    +

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

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

    diff --git a/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py b/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py index 5d4e4601..d5da15ae 100644 --- a/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py @@ -53,8 +53,16 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): {"journal_id": journal.id} ).create( { - "filename": "fixtures/statement_en.csv", - "data_file": self._data_file("fixtures/statement_en.csv"), + "attachment_ids": [ + ( + 0, + 0, + { + "name": "fixtures/statement_en.csv", + "datas": self._data_file("fixtures/statement_en.csv"), + }, + ) + ], "paypal_mapping_id": self.paypal_statement_map_en.id, } ) @@ -81,8 +89,16 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): {"journal_id": journal.id} ).create( { - "filename": "fixtures/statement_en.csv", - "data_file": self._data_file("fixtures/statement_en.csv"), + "attachment_ids": [ + ( + 0, + 0, + { + "name": "fixtures/statement_en.csv", + "datas": self._data_file("fixtures/statement_en.csv"), + }, + ) + ], "paypal_mapping_id": self.paypal_statement_map_en.id, } ) @@ -109,8 +125,16 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): {"journal_id": journal.id} ).create( { - "filename": "fixtures/statement_es.csv", - "data_file": self._data_file("fixtures/statement_es.csv"), + "attachment_ids": [ + ( + 0, + 0, + { + "name": "fixtures/statement_es.csv", + "datas": self._data_file("fixtures/statement_es.csv"), + }, + ) + ], "paypal_mapping_id": self.paypal_statement_map_es.id, } ) @@ -137,8 +161,16 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): {"journal_id": journal.id} ).create( { - "filename": "fixtures/activity_en.csv", - "data_file": self._data_file("fixtures/activity_en.csv"), + "attachment_ids": [ + ( + 0, + 0, + { + "name": "fixtures/activity_en.csv", + "datas": self._data_file("fixtures/activity_en.csv"), + }, + ) + ], "paypal_mapping_id": self.paypal_activity_map_en.id, } ) @@ -165,8 +197,16 @@ class TestAccountBankStatementImportPayPal(common.TransactionCase): {"journal_id": journal.id} ).create( { - "filename": "fixtures/empty_activity.csv", - "data_file": self._data_file("fixtures/empty_activity.csv"), + "attachment_ids": [ + ( + 0, + 0, + { + "name": "fixtures/empty_activity.csv", + "datas": self._data_file("fixtures/empty_activity.csv"), + }, + ) + ], "paypal_mapping_id": self.paypal_activity_map_en.id, } ) 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 index 38c4f758..14ceae1f 100644 --- 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 @@ -66,7 +66,6 @@ > PayPal Report Mappings account.bank.statement.import.paypal.mapping - form tree,form From 704656719f295ec00e4931fdbe5e26534b7ec44e Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Wed, 30 Sep 2020 06:19:26 +0300 Subject: [PATCH 23/34] [REBRAND] account_bank_statement_import_paypal --- account_statement_import_paypal/README.rst | 4 ++-- account_statement_import_paypal/__manifest__.py | 3 ++- account_statement_import_paypal/data/maps.xml | 1 + .../models/account_bank_statement_import.py | 1 + .../models/account_bank_statement_import_paypal_mapping.py | 1 + .../models/account_bank_statement_import_paypal_parser.py | 1 + account_statement_import_paypal/models/account_journal.py | 1 + account_statement_import_paypal/readme/CONTRIBUTORS.rst | 2 +- account_statement_import_paypal/static/description/index.html | 4 ++-- .../tests/test_account_bank_statement_import_paypal.py | 1 + .../views/account_bank_statement_import.xml | 1 + .../views/account_bank_statement_import_paypal_mapping.xml | 1 + .../account_bank_statement_import_paypal_mapping_wizard.py | 1 + .../account_bank_statement_import_paypal_mapping_wizard.xml | 1 + 14 files changed, 17 insertions(+), 6 deletions(-) diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst index 211434b5..f296b884 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -92,7 +92,7 @@ Authors ~~~~~~~ * Akretion -* Brainbean Apps +* CorporateHub Contributors ~~~~~~~~~~~~ @@ -105,7 +105,7 @@ Contributors * Victor M.M. Torres * Carlos Roca -* Alexey Pelykh +* Alexey Pelykh (`CorporateHub `__) Maintainers ~~~~~~~~~~~ diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index e43b7352..eaaff8f7 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -1,6 +1,7 @@ # Copyright 2014-2017 Akretion (http://www.akretion.com). # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { @@ -9,7 +10,7 @@ "version": "13.0.1.0.0", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", - "author": "Akretion, " "Brainbean Apps, " "Odoo Community Association (OCA)", + "author": "Akretion, CorporateHub, Odoo Community Association (OCA)", "license": "AGPL-3", "installable": True, "depends": [ diff --git a/account_statement_import_paypal/data/maps.xml b/account_statement_import_paypal/data/maps.xml index 8aefc8d5..78016504 100644 --- a/account_statement_import_paypal/data/maps.xml +++ b/account_statement_import_paypal/data/maps.xml @@ -2,6 +2,7 @@ diff --git a/account_statement_import_paypal/models/account_bank_statement_import.py b/account_statement_import_paypal/models/account_bank_statement_import.py index 148d395e..37c74dea 100644 --- a/account_statement_import_paypal/models/account_bank_statement_import.py +++ b/account_statement_import_paypal/models/account_bank_statement_import.py @@ -1,6 +1,7 @@ # Copyright 2014-2017 Akretion (http://www.akretion.com). # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import logging 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 index 6da1bb38..97178b08 100644 --- 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 @@ -1,5 +1,6 @@ # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import api, fields, models 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 index 5731c97f..815d1d5b 100644 --- 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 @@ -1,5 +1,6 @@ # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import itertools diff --git a/account_statement_import_paypal/models/account_journal.py b/account_statement_import_paypal/models/account_journal.py index 20756fa6..14a519f2 100644 --- a/account_statement_import_paypal/models/account_journal.py +++ b/account_statement_import_paypal/models/account_journal.py @@ -1,5 +1,6 @@ # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo import models diff --git a/account_statement_import_paypal/readme/CONTRIBUTORS.rst b/account_statement_import_paypal/readme/CONTRIBUTORS.rst index 9a72e9eb..65ad3091 100644 --- a/account_statement_import_paypal/readme/CONTRIBUTORS.rst +++ b/account_statement_import_paypal/readme/CONTRIBUTORS.rst @@ -6,4 +6,4 @@ * Victor M.M. Torres * Carlos Roca -* Alexey Pelykh +* Alexey Pelykh (`CorporateHub `__) diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html index a3179d9c..30c95c25 100644 --- a/account_statement_import_paypal/static/description/index.html +++ b/account_statement_import_paypal/static/description/index.html @@ -445,7 +445,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

    Authors

    • Akretion
    • -
    • Brainbean Apps
    • +
    • CorporateHub
    @@ -459,7 +459,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
  • Carlos Roca
  • -
  • Alexey Pelykh <alexey.pelykh@brainbeanapps.com>
  • +
  • Alexey Pelykh <alexey.pelykh@corphub.eu> (CorporateHub)
  • diff --git a/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py b/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py index d5da15ae..769d5649 100644 --- a/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py +++ b/account_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py @@ -1,5 +1,6 @@ # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from base64 import b64encode diff --git a/account_statement_import_paypal/views/account_bank_statement_import.xml b/account_statement_import_paypal/views/account_bank_statement_import.xml index 38e517f0..d1841b3e 100644 --- a/account_statement_import_paypal/views/account_bank_statement_import.xml +++ b/account_statement_import_paypal/views/account_bank_statement_import.xml @@ -3,6 +3,7 @@ Copyright 2014-2017 Akretion (http://www.akretion.com). Copyright 2019 Tecnativa - Vicent Cubells Copyright 2019 Brainbean Apps (https://brainbeanapps.com) + Copyright 2020 CorporateHub (https://corporatehub.eu) License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> 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 index 14ceae1f..6d6d5c5b 100644 --- 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 @@ -2,6 +2,7 @@ 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 index 28e68209..ec39d6a6 100644 --- 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 @@ -1,5 +1,6 @@ # Copyright 2019 Tecnativa - Vicent Cubells # Copyright 2019-2020 Brainbean Apps (https://brainbeanapps.com) +# Copyright 2020 CorporateHub (https://corporatehub.eu) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import json 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 index 13a9a22d..6a49de9a 100644 --- 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 @@ -2,6 +2,7 @@ From 878e8871a15e8dcd0814678acf988117aafb6442 Mon Sep 17 00:00:00 2001 From: Carlos Roca Date: Tue, 13 Jul 2021 10:34:58 +0200 Subject: [PATCH 24/34] [IMP] account_bank_statement_import_paypal: black, isort, prettier --- ...nt_bank_statement_import_paypal_mapping.py | 95 ++++++++++++++----- ...unt_bank_statement_import_paypal_parser.py | 5 +- ..._statement_import_paypal_mapping_wizard.py | 77 +++++++++++---- 3 files changed, 135 insertions(+), 42 deletions(-) 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 index 97178b08..4065a294 100644 --- 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 @@ -10,7 +10,9 @@ class AccountBankStatementImportPayPalMapping(models.Model): _name = "account.bank.statement.import.paypal.mapping" _description = "Account Bank Statement Import PayPal Mapping" - name = fields.Char(required=True,) + name = fields.Char( + required=True, + ) float_thousands_sep = fields.Selection( string="Thousands Separator", selection=[("dot", "dot (.)"), ("comma", "comma (,)"), ("none", "none")], @@ -23,28 +25,77 @@ class AccountBankStatementImportPayPalMapping(models.Model): 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, + 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', ) - 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): 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 index 815d1d5b..76af4e31 100644 --- 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 @@ -38,7 +38,10 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): 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),) + 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": []}] 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 index ec39d6a6..0b3bf539 100644 --- 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 @@ -15,27 +15,66 @@ class AccountBankStatementImportPayPalMappingWizard(models.TransientModel): _description = "Account Bank Statement Import PayPal Mapping Wizard" _inherit = ["multi.step.wizard.mixin"] - data_file = fields.Binary(string="PayPal Report File", required=True,) + data_file = fields.Binary( + string="PayPal Report File", + required=True, + ) filename = fields.Char() header = fields.Char() - date_column = fields.Char(string='"Date" column',) - time_column = fields.Char(string='"Time" column',) - tz_column = fields.Char(string='"Timezone" column',) - name_column = fields.Char(string='"Name" column',) - currency_column = fields.Char(string='"Currency" column',) - gross_column = fields.Char(string='"Gross" column',) - fee_column = fields.Char(string='"Fee" column',) - balance_column = fields.Char(string='"Balance" column',) - transaction_id_column = fields.Char(string='"Transaction ID" column',) - 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',) + date_column = fields.Char( + string='"Date" column', + ) + time_column = fields.Char( + string='"Time" column', + ) + tz_column = fields.Char( + string='"Timezone" column', + ) + name_column = fields.Char( + string='"Name" column', + ) + currency_column = fields.Char( + string='"Currency" column', + ) + gross_column = fields.Char( + string='"Gross" column', + ) + fee_column = fields.Char( + string='"Fee" column', + ) + balance_column = fields.Char( + string='"Balance" column', + ) + transaction_id_column = fields.Char( + string='"Transaction ID" column', + ) + 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("data_file") def _onchange_data_file(self): From f5d5aa6bf2ce0284101e2b9790cebc95b183ddbd Mon Sep 17 00:00:00 2001 From: Carlos Roca Date: Tue, 13 Jul 2021 10:37:08 +0200 Subject: [PATCH 25/34] [MIG] account_bank_statement_import_paypal: Migration to v14.0 --- account_statement_import_paypal/README.rst | 14 +- .../__manifest__.py | 11 +- account_statement_import_paypal/data/maps.xml | 21 +- .../account_bank_statement_import_paypal.pot | 341 ----------------- .../i18n/account_statement_import_paypal.pot | 349 ++++++++++++++++++ account_statement_import_paypal/i18n/es.po | 324 ++++++++-------- .../migrations/14.0.1.0.0/pre-migrate.py | 40 ++ .../models/__init__.py | 6 +- ..._import.py => account_statement_import.py} | 12 +- ...ccount_statement_import_paypal_mapping.py} | 4 +- ...account_statement_import_paypal_parser.py} | 16 +- .../readme/CONTRIBUTORS.rst | 4 +- .../security/ir.model.access.csv | 6 +- .../static/description/index.html | 12 +- .../tests/__init__.py | 2 +- ...> test_account_statement_import_paypal.py} | 114 ++---- ...mport.xml => account_statement_import.xml} | 8 +- ...count_statement_import_paypal_mapping.xml} | 14 +- .../wizards/__init__.py | 2 +- ...statement_import_paypal_mapping_wizard.py} | 10 +- ...tatement_import_paypal_mapping_wizard.xml} | 34 +- 21 files changed, 678 insertions(+), 666 deletions(-) delete mode 100644 account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot create mode 100644 account_statement_import_paypal/i18n/account_statement_import_paypal.pot create mode 100644 account_statement_import_paypal/migrations/14.0.1.0.0/pre-migrate.py rename account_statement_import_paypal/models/{account_bank_statement_import.py => account_statement_import.py} (64%) rename account_statement_import_paypal/models/{account_bank_statement_import_paypal_mapping.py => account_statement_import_paypal_mapping.py} (96%) rename account_statement_import_paypal/models/{account_bank_statement_import_paypal_parser.py => account_statement_import_paypal_parser.py} (95%) rename account_statement_import_paypal/tests/{test_account_bank_statement_import_paypal.py => test_account_statement_import_paypal.py} (61%) rename account_statement_import_paypal/views/{account_bank_statement_import.xml => account_statement_import.xml} (73%) rename account_statement_import_paypal/views/{account_bank_statement_import_paypal_mapping.xml => account_statement_import_paypal_mapping.xml} (82%) rename account_statement_import_paypal/wizards/{account_bank_statement_import_paypal_mapping_wizard.py => account_statement_import_paypal_mapping_wizard.py} (93%) rename account_statement_import_paypal/wizards/{account_bank_statement_import_paypal_mapping_wizard.xml => account_statement_import_paypal_mapping_wizard.xml} (90%) diff --git a/account_statement_import_paypal/README.rst b/account_statement_import_paypal/README.rst index f296b884..4cfb163b 100644 --- a/account_statement_import_paypal/README.rst +++ b/account_statement_import_paypal/README.rst @@ -14,13 +14,13 @@ PayPal CSV Format Bank Statements Import :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fbank--statement--import-lightgray.png?logo=github - :target: https://github.com/OCA/bank-statement-import/tree/13.0/account_bank_statement_import_paypal + :target: https://github.com/OCA/bank-statement-import/tree/14.0/account_statement_import_paypal :alt: OCA/bank-statement-import .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/bank-statement-import-13-0/bank-statement-import-13-0-account_bank_statement_import_paypal + :target: https://translation.odoo-community.org/projects/bank-statement-import-14-0/bank-statement-import-14-0-account_statement_import_paypal :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/174/13.0 + :target: https://runbot.odoo-community.org/runbot/174/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -81,7 +81,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -101,8 +101,8 @@ Contributors * Sebastien BEAU * Tecnativa (https://www.tecnativa.com) - * Vicent Cubells - * Victor M.M. Torres + * Vicent Cubells + * Victor M.M. Torres * Carlos Roca * Alexey Pelykh (`CorporateHub `__) @@ -120,6 +120,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/bank-statement-import `_ project on GitHub. +This module is part of the `OCA/bank-statement-import `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_statement_import_paypal/__manifest__.py b/account_statement_import_paypal/__manifest__.py index eaaff8f7..d12010e6 100644 --- a/account_statement_import_paypal/__manifest__.py +++ b/account_statement_import_paypal/__manifest__.py @@ -7,23 +7,22 @@ { "name": "PayPal CSV Format Bank Statements Import", "summary": "Import PayPal CSV files as Bank Statements in Odoo", - "version": "13.0.1.0.0", + "version": "14.0.1.0.0", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", "author": "Akretion, CorporateHub, Odoo Community Association (OCA)", "license": "AGPL-3", "installable": True, "depends": [ - "account_bank_statement_import", + "account_statement_import", "multi_step_wizard", "web_widget_dropdown_dynamic", ], - "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", + "views/account_statement_import_paypal_mapping.xml", + "views/account_statement_import.xml", + "wizards/account_statement_import_paypal_mapping_wizard.xml", ], } diff --git a/account_statement_import_paypal/data/maps.xml b/account_statement_import_paypal/data/maps.xml index 78016504..ea53c03b 100644 --- a/account_statement_import_paypal/data/maps.xml +++ b/account_statement_import_paypal/data/maps.xml @@ -8,7 +8,7 @@ PayPal Statement (EN) comma @@ -30,10 +30,7 @@ Bank Name Bank Account - + PayPal Activity (EN) comma dot @@ -57,7 +54,7 @@ PayPal Statement (ES) dot @@ -79,10 +76,7 @@ Nombre del banco Cuenta bancaria - + PayPal Activity (ES) dot comma @@ -108,7 +102,7 @@ PayPal Statement (DE) dot @@ -130,10 +124,7 @@ Name der Bank Bankkonto - + PayPal Activity (DE) dot comma 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 deleted file mode 100644 index 38a10907..00000000 --- a/account_statement_import_paypal/i18n/account_bank_statement_import_paypal.pot +++ /dev/null @@ -1,341 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * account_bank_statement_import_paypal -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 13.0\n" -"Report-Msgid-Bugs-To: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__balance_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__balance_column -msgid "\"Balance\" 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__bank_account_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_account_column -msgid "\"Bank Account\" 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__bank_name_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_name_column -msgid "\"Bank 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__currency_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__currency_column -msgid "\"Currency\" 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__date_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__description_column -msgid "\"Description\" 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__fee_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__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:0 -#, 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__allow_back -msgid "Allow Back" -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 "Choose a file to import..." -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_tree -msgid "Columns" -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__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_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 -#: 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 -#: 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_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 -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:0 -#, python-format -msgid "Fee for %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_mapping_wizard__filename -msgid "Filename" -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__header -msgid "Header" -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__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: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 -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:0 -#, 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:0 -#, python-format -msgid "Invoice %s" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_journal -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_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_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_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 -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:0 -#, 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_mapping__name -msgid "Name" -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 "PayPal Report File" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: 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 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 Report 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_mapping_id -msgid "PayPal mapping" -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 "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_mapping_wizard__state -msgid "State" -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__float_thousands_sep -msgid "Thousands 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_mapping__time_format -msgid "Time Format" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:0 -#, python-format -msgid "Transaction fee for %s" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_decimal_sep__comma -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_thousands_sep__comma -msgid "comma (,)" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_decimal_sep__dot -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_thousands_sep__dot -msgid "dot (.)" -msgstr "" - -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_decimal_sep__none -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_thousands_sep__none -msgid "none" -msgstr "" diff --git a/account_statement_import_paypal/i18n/account_statement_import_paypal.pot b/account_statement_import_paypal/i18n/account_statement_import_paypal.pot new file mode 100644 index 00000000..be8a1e70 --- /dev/null +++ b/account_statement_import_paypal/i18n/account_statement_import_paypal.pot @@ -0,0 +1,349 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_statement_import_paypal +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-07-13 07:52+0000\n" +"PO-Revision-Date: 2021-07-13 07:52+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__balance_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__balance_column +msgid "\"Balance\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__bank_account_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__bank_account_column +msgid "\"Bank Account\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__bank_name_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__bank_name_column +msgid "\"Bank Name\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__currency_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__currency_column +msgid "\"Currency\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__date_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__date_column +msgid "\"Date\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__description_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__description_column +msgid "\"Description\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__fee_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__fee_column +msgid "\"Fee\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__from_email_address_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__from_email_address_column +msgid "\"From Email Address\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__gross_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__gross_column +msgid "\"Gross\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__invoice_id_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__invoice_id_column +msgid "\"Invoice ID\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__name_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__name_column +msgid "\"Name\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__note_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__note_column +msgid "\"Note\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__subject_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__subject_column +msgid "\"Subject\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__time_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__time_column +msgid "\"Time\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__tz_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__tz_column +msgid "\"Timezone\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__to_email_address_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__to_email_address_column +msgid "\"To Email Address\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__transaction_id_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__transaction_id_column +msgid "\"Transaction ID\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__type_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__type_column +msgid "\"Type\" column" +msgstr "" + +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 +#, python-format +msgid "%s: %s" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import_paypal_mapping +msgid "Account Statement Import PayPal Mapping" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import_paypal_mapping_wizard +msgid "Account Statement Import PayPal Mapping Wizard" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import_paypal_parser +msgid "Account Statement Import PayPal Parser" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__allow_back +msgid "Allow Back" +msgstr "" + +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_paypal_mapping_wizard_form +msgid "Choose a file to import..." +msgstr "" + +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_paypal_mapping_tree +msgid "Columns" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__create_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__create_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__create_uid +msgid "Created by" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__create_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__create_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__create_date +msgid "Created on" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__date_format +msgid "Date Format" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__float_decimal_sep +msgid "Decimals Separator" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_journal__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__display_name +msgid "Display Name" +msgstr "" + +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 +#, python-format +msgid "Fee for %s" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__filename +msgid "Filename" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__header +msgid "Header" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_journal__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__id +msgid "ID" +msgstr "" + +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_paypal_mapping_wizard_form +msgid "Import" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import +msgid "Import Bank Statement Files" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.actions.act_window,name:account_statement_import_paypal.action_account_statement_import_paypal_mapping_wizard +msgid "Import Mapping" +msgstr "" + +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/wizards/account_statement_import_paypal_mapping_wizard.py:0 +#, python-format +msgid "Imported Mapping" +msgstr "" + +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 +#, python-format +msgid "Invoice %s" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_journal +msgid "Journal" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_journal____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser____last_update +msgid "Last Modified on" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__write_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__write_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__write_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__write_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__write_date +msgid "Last Updated on" +msgstr "" + +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/wizards/account_statement_import_paypal_mapping_wizard.py:0 +#, python-format +msgid "Mapping from %s" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__name +msgid "Name" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__data_file +msgid "PayPal Report File" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.actions.act_window,name:account_statement_import_paypal.action_statement_import_paypal_report_mappings +#: model:ir.ui.menu,name:account_statement_import_paypal.menu_statement_import_paypal_mapping +msgid "PayPal Report Mappings" +msgstr "" + +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_form +msgid "PayPal Report mapping:" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import__paypal_mapping_id +msgid "PayPal mapping" +msgstr "" + +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_paypal_mapping_wizard_form +msgid "Select a PayPal report file to import mapping." +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__state +msgid "State" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__float_thousands_sep +msgid "Thousands Separator" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__time_format +msgid "Time Format" +msgstr "" + +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 +#, python-format +msgid "Transaction fee for %s" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_decimal_sep__comma +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_thousands_sep__comma +msgid "comma (,)" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_decimal_sep__dot +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_thousands_sep__dot +msgid "dot (.)" +msgstr "" + +#. module: account_statement_import_paypal +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_decimal_sep__none +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_thousands_sep__none +msgid "none" +msgstr "" diff --git a/account_statement_import_paypal/i18n/es.po b/account_statement_import_paypal/i18n/es.po index 202571ce..29d99ac4 100644 --- a/account_statement_import_paypal/i18n/es.po +++ b/account_statement_import_paypal/i18n/es.po @@ -6,341 +6,349 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 11.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-01-11 10:43+0000\n" -"PO-Revision-Date: 2020-05-07 15:19+0000\n" -"Last-Translator: oihane \n" +"POT-Creation-Date: 2021-07-13 07:52+0000\n" +"PO-Revision-Date: 2021-07-13 09:53+0200\n" +"Last-Translator: Carlos \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.10\n" +"X-Generator: Poedit 2.0.6\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__balance_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__balance_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__balance_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__balance_column msgid "\"Balance\" 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__bank_account_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_account_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__bank_account_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__bank_account_column msgid "\"Bank Account\" 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__bank_name_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__bank_name_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__bank_name_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__bank_name_column msgid "\"Bank 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__currency_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__currency_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__currency_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__currency_column msgid "\"Currency\" 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__date_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__date_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__date_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__description_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__description_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__description_column msgid "\"Description\" 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__fee_column -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__fee_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__fee_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__from_email_address_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__from_email_address_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__gross_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__gross_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__invoice_id_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__invoice_id_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__name_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__name_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__note_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__note_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__subject_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__subject_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__time_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__time_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__tz_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__tz_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__to_email_address_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__to_email_address_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__transaction_id_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__transaction_id_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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 -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping_wizard__type_column +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__type_column +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__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:0 +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 #, 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" +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import_paypal_mapping +msgid "Account 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" +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import_paypal_mapping_wizard +msgid "Account 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" +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import_paypal_parser +msgid "Account 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__allow_back +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__allow_back msgid "Allow Back" 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 +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_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.account_bank_statement_import_paypal_mapping_tree +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_paypal_mapping_tree msgid "Columns" msgstr "Columnas" -#. module: account_bank_statement_import_paypal -#: 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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__create_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__create_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_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_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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__create_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__create_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__create_date msgid "Created on" msgstr "Creado por" -#. 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_format +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__date_format msgid "Date Format" msgstr "Formato de fecha" -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields,field_description:account_bank_statement_import_paypal.field_account_bank_statement_import_paypal_mapping__float_decimal_sep +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__float_decimal_sep msgid "Decimals Separator" msgstr "Separador de decimales" -#. module: account_bank_statement_import_paypal -#: 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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_journal__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__display_name +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__display_name msgid "Display Name" msgstr "Nombre mostrado" -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:0 +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 #, python-format msgid "Fee for %s" msgstr "Tasa para %s" -#. 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__filename +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__filename msgid "Filename" msgstr "Nombre de archivo" -#. 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__header +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__header msgid "Header" msgstr "Cabecera" -#. module: account_bank_statement_import_paypal -#: 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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_journal__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__id +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_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 +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_paypal_mapping_wizard_form msgid "Import" msgstr "Importar" -#. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_bank_statement_import -msgid "Import Bank Statement" +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_statement_import +#, fuzzy +#| msgid "Import Bank Statement" +msgid "Import Bank Statement Files" msgstr "Importar Extracto Bancario" -#. module: account_bank_statement_import_paypal -#: model:ir.actions.act_window,name:account_bank_statement_import_paypal.action_account_bank_statement_import_paypal_mapping_wizard +#. module: account_statement_import_paypal +#: model:ir.actions.act_window,name:account_statement_import_paypal.action_account_statement_import_paypal_mapping_wizard msgid "Import Mapping" msgstr "" -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:0 +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/wizards/account_statement_import_paypal_mapping_wizard.py:0 #, 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:0 +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 #, python-format msgid "Invoice %s" msgstr "Factura %s" -#. module: account_bank_statement_import_paypal -#: model:ir.model,name:account_bank_statement_import_paypal.model_account_journal +#. module: account_statement_import_paypal +#: model:ir.model,name:account_statement_import_paypal.model_account_journal 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_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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_journal____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard____last_update +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_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_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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__write_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__write_uid +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_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_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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__write_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__write_date +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_parser__write_date msgid "Last Updated on" msgstr "Última actualización en" -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py:0 +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/wizards/account_statement_import_paypal_mapping_wizard.py:0 #, python-format msgid "Mapping from %s" msgstr "Mapeo para %s" -#. 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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__name msgid "Name" msgstr "Nombre" -#. 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 +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__data_file msgid "PayPal Report File" msgstr "" -#. module: account_bank_statement_import_paypal -#: 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 +#. module: account_statement_import_paypal +#: model:ir.actions.act_window,name:account_statement_import_paypal.action_statement_import_paypal_report_mappings +#: model:ir.ui.menu,name:account_statement_import_paypal.menu_statement_import_paypal_mapping 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 +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_statement_import_form msgid "PayPal Report 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_mapping_id +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import__paypal_mapping_id msgid "PayPal mapping" 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 +#. module: account_statement_import_paypal +#: model_terms:ir.ui.view,arch_db:account_statement_import_paypal.account_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_mapping_wizard__state +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping_wizard__state msgid "State" 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__float_thousands_sep +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__float_thousands_sep msgid "Thousands Separator" msgstr "Separador de millares" -#. 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_format +#. module: account_statement_import_paypal +#: model:ir.model.fields,field_description:account_statement_import_paypal.field_account_statement_import_paypal_mapping__time_format msgid "Time Format" msgstr "" -#. module: account_bank_statement_import_paypal -#: code:addons/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py:0 +#. module: account_statement_import_paypal +#: code:addons/account_statement_import_paypal/models/account_statement_import_paypal_parser.py:0 #, python-format msgid "Transaction fee for %s" msgstr "Tasa de transacción para %s" -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_decimal_sep__comma -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_thousands_sep__comma +#. module: account_statement_import_paypal +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_decimal_sep__comma +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_thousands_sep__comma msgid "comma (,)" msgstr "coma (,)" -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_decimal_sep__dot -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_thousands_sep__dot +#. module: account_statement_import_paypal +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_decimal_sep__dot +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_thousands_sep__dot msgid "dot (.)" msgstr "punto (.)" -#. module: account_bank_statement_import_paypal -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_decimal_sep__none -#: model:ir.model.fields.selection,name:account_bank_statement_import_paypal.selection__account_bank_statement_import_paypal_mapping__float_thousands_sep__none +#. module: account_statement_import_paypal +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_decimal_sep__none +#: model:ir.model.fields.selection,name:account_statement_import_paypal.selection__account_statement_import_paypal_mapping__float_thousands_sep__none msgid "none" msgstr "nada" diff --git a/account_statement_import_paypal/migrations/14.0.1.0.0/pre-migrate.py b/account_statement_import_paypal/migrations/14.0.1.0.0/pre-migrate.py new file mode 100644 index 00000000..baf76a8b --- /dev/null +++ b/account_statement_import_paypal/migrations/14.0.1.0.0/pre-migrate.py @@ -0,0 +1,40 @@ +# Copyright 2021 Tecnativa - Carlos Roca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from openupgradelib import openupgrade + +_model_renames = [ + ( + "account.bank.statement.import.paypal.mapping", + "account.statement.import.paypal.mapping", + ), + ( + "account.bank.statement.import.paypal.parser", + "account.statement.import.paypal.parser", + ), + ( + "account.bank.statement.import.paypal.mapping.wizard", + "account.statement.import.paypal.mapping.wizard", + ), +] + +_table_renames = [ + ( + "account_bank_statement_import_paypal_mapping", + "account_statement_import_paypal_mapping", + ), + ( + "account_bank_statement_import_paypal_parser", + "account_statement_import_paypal_parser", + ), + ( + "account_bank_statement_import_paypal_mapping_wizard", + "account_statement_import_paypal_mapping_wizard", + ), +] + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.rename_models(env.cr, _model_renames) + openupgrade.rename_tables(env.cr, _table_renames) diff --git a/account_statement_import_paypal/models/__init__.py b/account_statement_import_paypal/models/__init__.py index 42211d54..2243fca6 100644 --- a/account_statement_import_paypal/models/__init__.py +++ b/account_statement_import_paypal/models/__init__.py @@ -1,6 +1,6 @@ # 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_statement_import_paypal_mapping +from . import account_statement_import_paypal_parser +from . import account_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_statement_import.py similarity index 64% rename from account_statement_import_paypal/models/account_bank_statement_import.py rename to account_statement_import_paypal/models/account_statement_import.py index 37c74dea..d156bf98 100644 --- a/account_statement_import_paypal/models/account_bank_statement_import.py +++ b/account_statement_import_paypal/models/account_statement_import.py @@ -11,23 +11,23 @@ from odoo import fields, models _logger = logging.getLogger(__name__) -class AccountBankStatementImport(models.TransientModel): - _inherit = "account.bank.statement.import" +class AccountStatementImport(models.TransientModel): + _inherit = "account.statement.import" paypal_mapping_id = fields.Many2one( string="PayPal mapping", - comodel_name="account.bank.statement.import.paypal.mapping", + comodel_name="account.statement.import.paypal.mapping", ) def _parse_file(self, data_file): self.ensure_one() try: - Parser = self.env["account.bank.statement.import.paypal.parser"] + Parser = self.env["account.statement.import.paypal.parser"] return Parser.parse( - self.paypal_mapping_id, data_file, self.attachment_ids[:1].name + self.paypal_mapping_id, data_file, self.statement_filename ) except Exception: - if self.env.context.get("account_bank_statement_import_paypal_test"): + if self.env.context.get("account_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_mapping.py b/account_statement_import_paypal/models/account_statement_import_paypal_mapping.py similarity index 96% rename from account_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py rename to account_statement_import_paypal/models/account_statement_import_paypal_mapping.py index 4065a294..b6903703 100644 --- a/account_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py +++ b/account_statement_import_paypal/models/account_statement_import_paypal_mapping.py @@ -7,8 +7,8 @@ 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 = "account.statement.import.paypal.mapping" + _description = "Account Statement Import PayPal Mapping" name = fields.Char( required=True, diff --git a/account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py b/account_statement_import_paypal/models/account_statement_import_paypal_parser.py similarity index 95% rename from account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py rename to account_statement_import_paypal/models/account_statement_import_paypal_parser.py index 76af4e31..d1195aaf 100644 --- a/account_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py +++ b/account_statement_import_paypal/models/account_statement_import_paypal_parser.py @@ -23,8 +23,8 @@ except (ImportError, IOError) as err: class AccountBankStatementImportPayPalParser(models.TransientModel): - _name = "account.bank.statement.import.paypal.parser" - _description = "Account Bank Statement Import PayPal Parser" + _name = "account.statement.import.paypal.parser" + _description = "Account Statement Import PayPal Parser" @api.model def parse_header(self, data_file): @@ -75,7 +75,7 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): ) def _data_dict_constructor(self, mapping, header): - list_of_content = [ + required_list = [ "date_column", "time_column", "tz_column", @@ -85,6 +85,8 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): "fee_column", "balance_column", "transaction_id_column", + ] + optional_list = [ "description_column", "type_column", "from_email_address_column", @@ -96,7 +98,9 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): "bank_account_column", ] data_dict = {} - for key in list_of_content: + for key in required_list: + data_dict[key] = header.index(getattr(mapping, key)) + for key in optional_list: try: data_dict[key] = header.index(getattr(mapping, key)) except ValueError: @@ -208,7 +212,7 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): "name": invoice or details or description or "", "amount": str(gross_amount), "date": timestamp, - "note": note, + "payment_ref": note, "unique_import_id": unique_import_id, } if payer_name: @@ -225,7 +229,7 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): "date": timestamp, "partner_name": "PayPal", "unique_import_id": "%s-FEE" % unique_import_id, - "note": _("Transaction fee for %s") % note, + "payment_ref": _("Transaction fee for %s") % note, } ) return transactions diff --git a/account_statement_import_paypal/readme/CONTRIBUTORS.rst b/account_statement_import_paypal/readme/CONTRIBUTORS.rst index 65ad3091..f2c7927d 100644 --- a/account_statement_import_paypal/readme/CONTRIBUTORS.rst +++ b/account_statement_import_paypal/readme/CONTRIBUTORS.rst @@ -2,8 +2,8 @@ * Sebastien BEAU * Tecnativa (https://www.tecnativa.com) - * Vicent Cubells - * Victor M.M. Torres + * Vicent Cubells + * Victor M.M. Torres * Carlos Roca * Alexey Pelykh (`CorporateHub `__) diff --git a/account_statement_import_paypal/security/ir.model.access.csv b/account_statement_import_paypal/security/ir.model.access.csv index bd4912b5..c3ae9c75 100644 --- a/account_statement_import_paypal/security/ir.model.access.csv +++ b/account_statement_import_paypal/security/ir.model.access.csv @@ -1,3 +1,5 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" -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 +"access_account_statement_import_paypal_mapping_manager","account.statement.import.paypal.mapping:account.group_account_manager","model_account_statement_import_paypal_mapping","account.group_account_manager","1","1","1","1" +"access_account_statement_import_paypal_mapping_user","account.statement.import.paypal.mapping:account.group_account_user","model_account_statement_import_paypal_mapping","account.group_account_user","1","0","0","0" +"access_account_statement_import_paypal_parser","account.statement.import.paypal.parser:account.group_account_user","model_account_statement_import_paypal_parser","account.group_account_user","1","1","1","1" +"access_account_statement_import_paypal_mapping_wizard","Full access on account.statement.import.paypal.mapping.wizard","model_account_statement_import_paypal_mapping_wizard","account.group_account_user","1","1","1","1" diff --git a/account_statement_import_paypal/static/description/index.html b/account_statement_import_paypal/static/description/index.html index 30c95c25..a876ff17 100644 --- a/account_statement_import_paypal/static/description/index.html +++ b/account_statement_import_paypal/static/description/index.html @@ -3,7 +3,7 @@ - + PayPal CSV Format Bank Statements Import
    +

    Import Paypal Bank Statements

    + + +

    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 statements.

    +

    Table of contents

    + +
    +

    Configuration

    +

    In the menu Accounting > Configuration > Accounting > Bank Accounts, +make sure that you have your Paypal bank account with the following parameters: +* Bank Account Type: Normal Bank Account +* Account Number: the email address associated with your Paypal account +* Account Journal: the journal associated to your Paypal account

    +
    +

    TIPS

    +

    For now only French and English report are supported. +For adding new support you just need to add your header in +model/account_bank_statement_import_paypal.py in the variables HEADERS. +Please help us and do a PR for adding new header ! Thanks

    +
    +
    +
    +

    Usage

    +

    To use this module, you need to:

    +
      +
    1. Go to Paypal and download your Bank Statement
    2. +
    +. +. +
    +
    +

    Bug Tracker

    +

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

    +

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

    +
    +
    +

    Credits

    +
    +

    Authors

    +
      +
    • Akretion
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Maintainers

    +

    This module is maintained by the OCA.

    +Odoo Community Association +

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

    +

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

    +

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

    +
    +
    +