From 5703ac3ef7f796bf58b5b341140f59bea9a00b84 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Wed, 8 Apr 2020 09:00:59 +0200 Subject: [PATCH] [IMP] account_bank_statement_import_paypal: better wizard --- .../__manifest__.py | 2 + .../data/maps.xml | 47 ++++- .../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 ++++++++++++++- oca_dependencies.txt | 1 + 8 files changed, 392 insertions(+), 79 deletions(-) create mode 100644 account_bank_statement_import_paypal/tests/fixtures/statement_es.csv diff --git a/account_bank_statement_import_paypal/__manifest__.py b/account_bank_statement_import_paypal/__manifest__.py index 4e4c1ef..2fa5fd6 100644 --- a/account_bank_statement_import_paypal/__manifest__.py +++ b/account_bank_statement_import_paypal/__manifest__.py @@ -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_bank_statement_import_paypal/data/maps.xml b/account_bank_statement_import_paypal/data/maps.xml index 78337e4..1f72754 100644 --- a/account_bank_statement_import_paypal/data/maps.xml +++ b/account_bank_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_bank_statement_import_paypal/tests/fixtures/statement_en.csv b/account_bank_statement_import_paypal/tests/fixtures/statement_en.csv index b7407db..11fea15 100644 --- a/account_bank_statement_import_paypal/tests/fixtures/statement_en.csv +++ b/account_bank_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_bank_statement_import_paypal/tests/fixtures/statement_es.csv b/account_bank_statement_import_paypal/tests/fixtures/statement_es.csv new file mode 100644 index 0000000..5f01b11 --- /dev/null +++ b/account_bank_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_bank_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py b/account_bank_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py index 8ad24de..afb78b9 100644 --- a/account_bank_statement_import_paypal/tests/test_account_bank_statement_import_paypal.py +++ b/account_bank_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_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py b/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py index e7eb45c..1c73186 100644 --- a/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.py +++ b/account_bank_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_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml b/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml index 19b8b3b..7d98544 100644 --- a/account_bank_statement_import_paypal/wizards/account_bank_statement_import_paypal_mapping_wizard.xml +++ b/account_bank_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 + + +