diff --git a/account_bank_statement_import_paypal/__manifest__.py b/account_bank_statement_import_paypal/__manifest__.py index 6afc103b..450f8dc8 100644 --- a/account_bank_statement_import_paypal/__manifest__.py +++ b/account_bank_statement_import_paypal/__manifest__.py @@ -4,32 +4,25 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { - 'name': 'PayPal CSV Format Bank Statements Import', - 'summary': 'Import PayPal CSV files as Bank Statements in Odoo', - 'version': '12.0.2.2.1', - 'category': 'Accounting', - 'website': 'https://github.com/OCA/bank-statement-import', - 'author': - 'Akretion, ' - 'Brainbean Apps, ' - 'Odoo Community Association (OCA)', - 'license': 'AGPL-3', - 'installable': True, - 'depends': [ - 'account_bank_statement_import', - 'multi_step_wizard', - 'web_widget_dropdown_dynamic', + "name": "PayPal CSV Format Bank Statements Import", + "summary": "Import PayPal CSV files as Bank Statements in Odoo", + "version": "12.0.2.2.1", + "category": "Accounting", + "website": "https://github.com/OCA/bank-statement-import", + "author": "Akretion, " "Brainbean Apps, " "Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "depends": [ + "account_bank_statement_import", + "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', + "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", ], } diff --git a/account_bank_statement_import_paypal/data/maps.xml b/account_bank_statement_import_paypal/data/maps.xml index d583b9ee..8aefc8d5 100644 --- a/account_bank_statement_import_paypal/data/maps.xml +++ b/account_bank_statement_import_paypal/data/maps.xml @@ -1,12 +1,14 @@ - + - - + PayPal Statement (EN) comma dot @@ -27,8 +29,10 @@ Bank Name Bank Account - - + PayPal Activity (EN) comma dot @@ -50,8 +54,10 @@ Subject Note - - + PayPal Statement (ES) dot comma @@ -72,8 +78,10 @@ Nombre del banco Cuenta bancaria - - + PayPal Activity (ES) dot comma @@ -90,13 +98,17 @@ Id. de transacción Tipo Correo electrónico del remitente - Correo electrónico del destinatario + Correo electrónico del destinatario Número de factura Asunto Nota - - + PayPal Statement (DE) dot comma @@ -117,8 +129,10 @@ Name der Bank Bankkonto - - + PayPal Activity (DE) dot comma @@ -140,5 +154,4 @@ Betreff Hinweis - diff --git a/account_bank_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py b/account_bank_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py index e2155720..06b08f5c 100644 --- a/account_bank_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py +++ b/account_bank_statement_import_paypal/migrations/12.0.2.0.0/post-migration.py @@ -99,5 +99,5 @@ LEFT JOIN _mappings AS _bank_name ON m.id = _bank_name.id AND _bank_name.field_to_assign = 'bank_name' LEFT JOIN _mappings AS _bank_acc ON m.id = _bank_acc.id AND _bank_acc.field_to_assign = 'bank_account'; - """ + """, ) diff --git a/account_bank_statement_import_paypal/models/account_bank_statement_import.py b/account_bank_statement_import_paypal/models/account_bank_statement_import.py index 4d3d08cf..d41d1da8 100644 --- a/account_bank_statement_import_paypal/models/account_bank_statement_import.py +++ b/account_bank_statement_import_paypal/models/account_bank_statement_import.py @@ -3,33 +3,29 @@ # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import logging + from odoo import api, fields, models -import logging _logger = logging.getLogger(__name__) class AccountBankStatementImport(models.TransientModel): - _inherit = 'account.bank.statement.import' + _inherit = "account.bank.statement.import" paypal_mapping_id = fields.Many2one( - string='PayPal mapping', - comodel_name='account.bank.statement.import.paypal.mapping', + string="PayPal mapping", + comodel_name="account.bank.statement.import.paypal.mapping", ) @api.multi def _parse_file(self, data_file): self.ensure_one() try: - Parser = self.env['account.bank.statement.import.paypal.parser'] - return Parser.parse( - self.paypal_mapping_id, - data_file, - self.filename - ) - except: - if self.env.context.get( - 'account_bank_statement_import_paypal_test'): + Parser = self.env["account.bank.statement.import.paypal.parser"] + return Parser.parse(self.paypal_mapping_id, data_file, self.filename) + except Exception: + if self.env.context.get("account_bank_statement_import_paypal_test"): raise - _logger.warning('PayPal parser error', exc_info=True) + _logger.warning("PayPal parser error", exc_info=True) return super()._parse_file(data_file) diff --git a/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py b/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py index e87ddcf9..431cf58f 100644 --- a/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py +++ b/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_mapping.py @@ -6,125 +6,68 @@ 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.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'), - ], - default='dot', + string="Thousands Separator", + selection=[("dot", "dot (.)"), ("comma", "comma (,)"), ("none", "none")], + default="dot", required=True, ) float_decimal_sep = fields.Selection( - string='Decimals Separator', - selection=[ - ('dot', 'dot (.)'), - ('comma', 'comma (,)'), - ('none', 'none'), - ], - default='comma', - required=True, - ) - date_format = fields.Char( - string='Date Format', - required=True, - ) - time_format = fields.Char( - string='Time Format', - required=True, - ) - date_column = fields.Char( - string='"Date" column', - required=True, - ) - time_column = fields.Char( - string='"Time" column', - required=True, - ) - tz_column = fields.Char( - string='"Timezone" column', - required=True, - ) - name_column = fields.Char( - string='"Name" column', - required=True, - ) - currency_column = fields.Char( - string='"Currency" column', - required=True, - ) - gross_column = fields.Char( - string='"Gross" column', - required=True, - ) - fee_column = fields.Char( - string='"Fee" column', - required=True, - ) - balance_column = fields.Char( - string='"Balance" column', + string="Decimals Separator", + selection=[("dot", "dot (.)"), ("comma", "comma (,)"), ("none", "none")], + default="comma", required=True, ) + date_format = fields.Char(string="Date Format", required=True,) + time_format = fields.Char(string="Time Format", required=True,) + date_column = fields.Char(string='"Date" column', required=True,) + time_column = fields.Char(string='"Time" column', required=True,) + tz_column = fields.Char(string='"Timezone" column', required=True,) + name_column = fields.Char(string='"Name" column', required=True,) + currency_column = fields.Char(string='"Currency" column', required=True,) + gross_column = fields.Char(string='"Gross" column', required=True,) + fee_column = fields.Char(string='"Fee" column', required=True,) + balance_column = fields.Char(string='"Balance" column', required=True,) transaction_id_column = fields.Char( - string='"Transaction ID" column', - required=True, - ) - description_column = fields.Char( - string='"Description" column', - ) - type_column = fields.Char( - string='"Type" column', - ) - from_email_address_column = fields.Char( - string='"From Email Address" column', - ) - to_email_address_column = fields.Char( - string='"To Email Address" column', - ) - invoice_id_column = fields.Char( - string='"Invoice ID" column', - ) - subject_column = fields.Char( - string='"Subject" column', - ) - note_column = fields.Char( - string='"Note" column', - ) - bank_name_column = fields.Char( - string='"Bank Name" column', - ) - bank_account_column = fields.Char( - string='"Bank Account" column', + string='"Transaction ID" column', required=True, ) + description_column = fields.Char(string='"Description" column',) + type_column = fields.Char(string='"Type" column',) + from_email_address_column = fields.Char(string='"From Email Address" column',) + to_email_address_column = fields.Char(string='"To Email Address" column',) + invoice_id_column = fields.Char(string='"Invoice ID" column',) + subject_column = fields.Char(string='"Subject" column',) + note_column = fields.Char(string='"Note" column',) + bank_name_column = fields.Char(string='"Bank Name" column',) + bank_account_column = fields.Char(string='"Bank Account" column',) - @api.onchange('float_thousands_sep') + @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' + 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') + @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' + if "dot" == self.float_thousands_sep == self.float_decimal_sep: + self.float_thousands_sep = "comma" + elif "comma" == self.float_thousands_sep == self.float_decimal_sep: + self.float_thousands_sep = "dot" @api.multi def _get_float_separators(self): self.ensure_one() separators = { - 'dot': '.', - 'comma': ',', - 'none': '', + "dot": ".", + "comma": ",", + "none": "", } - return (separators[self.float_thousands_sep], - separators[self.float_decimal_sep]) + return ( + separators[self.float_thousands_sep], + separators[self.float_decimal_sep], + ) diff --git a/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py b/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py index eaadfa96..8226e525 100644 --- a/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py +++ b/account_bank_statement_import_paypal/models/account_bank_statement_import_paypal_parser.py @@ -2,16 +2,17 @@ # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import api, models, _ - +import itertools +import logging from datetime import datetime from decimal import Decimal from io import StringIO from os import path -import itertools + from pytz import timezone, utc -import logging +from odoo import _, api, models + _logger = logging.getLogger(__name__) try: @@ -21,62 +22,56 @@ 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.bank.statement.import.paypal.parser" + _description = "Account Bank Statement Import PayPal Parser" @api.model def parse_header(self, data_file): - data = StringIO(data_file.decode('utf-8-sig')) + data = StringIO(data_file.decode("utf-8-sig")) csv_data = reader(data) return list(next(csv_data)) @api.model def parse(self, mapping, data_file, filename): - journal = self.env['account.journal'].browse( - self.env.context.get('journal_id') - ) - currency_code = ( - journal.currency_id or journal.company_id.currency_id - ).name + journal = self.env["account.journal"].browse(self.env.context.get("journal_id")) + currency_code = (journal.currency_id or journal.company_id.currency_id).name account_number = journal.bank_account_id.acc_number - name = _('%s: %s') % ( - journal.code, - path.basename(filename), - ) + 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': [], - }] + return currency_code, account_number, [{"name": name, "transactions": []}] - lines = list(sorted( - lines, - key=lambda line: line['timestamp'] - )) + lines = list(sorted(lines, key=lambda line: line["timestamp"])) first_line = lines[0] - balance_start = first_line['balance_amount'] - balance_start -= first_line['gross_amount'] - balance_start -= first_line['fee_amount'] + balance_start = first_line["balance_amount"] + balance_start -= first_line["gross_amount"] + balance_start -= first_line["fee_amount"] last_line = lines[-1] - balance_end = last_line['balance_amount'] + balance_end = last_line["balance_amount"] - transactions = list(itertools.chain.from_iterable(map( - lambda line: self._convert_line_to_transactions(line), - lines - ))) + transactions = list( + itertools.chain.from_iterable( + map(lambda line: self._convert_line_to_transactions(line), lines) + ) + ) - return currency_code, account_number, [{ - 'name': name, - 'date': first_line['timestamp'].date(), - 'balance_start': float(balance_start), - 'balance_end_real': float(balance_end), - 'transactions': transactions, - }] + return ( + currency_code, + account_number, + [ + { + "name": name, + "date": first_line["timestamp"].date(), + "balance_start": float(balance_start), + "balance_end_real": float(balance_end), + "transactions": transactions, + } + ], + ) def _parse_lines(self, mapping, data_file, currency_code): - data = StringIO(data_file.decode('utf-8-sig')) + data = StringIO(data_file.decode("utf-8-sig")) csv_data = reader(data) header = list(next(csv_data)) @@ -98,15 +93,11 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): except ValueError: type_column = None try: - from_email_address_column = header.index( - mapping.from_email_address_column - ) + from_email_address_column = header.index(mapping.from_email_address_column) except ValueError: from_email_address_column = None try: - to_email_address_column = header.index( - mapping.to_email_address_column - ) + to_email_address_column = header.index(mapping.to_email_address_column) except ValueError: to_email_address_column = None try: @@ -142,24 +133,31 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): fee_value = row[fee_column] balance_value = row[balance_column] transaction_id_value = row[transaction_id_column] - description_value = row[description_column] \ - if description_column is not None else None - type_value = row[type_column] \ - if type_column is not None else None - from_email_address_value = row[from_email_address_column] \ - if from_email_address_column is not None else None - to_email_address_value = row[to_email_address_column] \ - if to_email_address_column is not None else None - invoice_id_value = row[invoice_id_column] \ - if invoice_id_column is not None else None - subject_value = row[subject_column] \ - if subject_column is not None else None - note_value = row[note_column] \ - if note_column is not None else None - bank_name_value = row[bank_name_column] \ - if bank_name_column is not None else None - bank_account_value = row[bank_account_column] \ - if bank_account_column is not None else None + description_value = ( + row[description_column] if description_column is not None else None + ) + type_value = row[type_column] if type_column is not None else None + from_email_address_value = ( + row[from_email_address_column] + if from_email_address_column is not None + else None + ) + to_email_address_value = ( + row[to_email_address_column] + if to_email_address_column is not None + else None + ) + invoice_id_value = ( + row[invoice_id_column] if invoice_id_column is not None else None + ) + subject_value = row[subject_column] if subject_column is not None else None + note_value = row[note_column] if note_column is not None else None + bank_name_value = ( + row[bank_name_column] if bank_name_column is not None else None + ) + bank_account_value = ( + row[bank_account_column] if bank_account_column is not None else None + ) if currency_value != currency_code: continue @@ -174,102 +172,100 @@ class AccountBankStatementImportPayPalParser(models.TransientModel): gross_amount = self._parse_decimal(gross_value, mapping) fee_amount = self._parse_decimal(fee_value, mapping) balance_amount = self._parse_decimal(balance_value, mapping) - bank = '%s - %s' % ( - bank_name_value, - bank_account_value, - ) if bank_name_value and bank_account_value else None + bank = ( + "{} - {}".format(bank_name_value, bank_account_value) + if bank_name_value and bank_account_value + else None + ) if to_email_address_column is None: payer_email = from_email_address_value else: - payer_email = to_email_address_value \ - if gross_amount < 0.0 else from_email_address_value + payer_email = ( + to_email_address_value + if gross_amount < 0.0 + else from_email_address_value + ) - lines.append({ - 'transaction_id': transaction_id_value, - 'invoice': invoice_id_value, - 'description': description_value or type_value, - 'details': subject_value or note_value or bank, - 'timestamp': timestamp, - 'gross_amount': gross_amount, - 'fee_amount': fee_amount, - 'balance_amount': balance_amount, - 'payer_name': name_value, - 'payer_email': payer_email, - 'partner_bank_name': bank_name_value, - 'partner_bank_account': bank_account_value, - }) + lines.append( + { + "transaction_id": transaction_id_value, + "invoice": invoice_id_value, + "description": description_value or type_value, + "details": subject_value or note_value or bank, + "timestamp": timestamp, + "gross_amount": gross_amount, + "fee_amount": fee_amount, + "balance_amount": balance_amount, + "payer_name": name_value, + "payer_email": payer_email, + "partner_bank_name": bank_name_value, + "partner_bank_account": bank_account_value, + } + ) return lines @api.model def _convert_line_to_transactions(self, line): transactions = [] - transaction_id = line['transaction_id'] - invoice = line['invoice'] - description = line['description'] - details = line['details'] - timestamp = line['timestamp'] - gross_amount = line['gross_amount'] - fee_amount = line['fee_amount'] - payer_name = line['payer_name'] - payer_email = line['payer_email'] - partner_bank_account = line['partner_bank_account'] + transaction_id = line["transaction_id"] + invoice = line["invoice"] + description = line["description"] + details = line["details"] + timestamp = line["timestamp"] + gross_amount = line["gross_amount"] + fee_amount = line["fee_amount"] + payer_name = line["payer_name"] + payer_email = line["payer_email"] + partner_bank_account = line["partner_bank_account"] if invoice: - invoice = _('Invoice %s') % invoice - note = '%s %s' % ( - description, - transaction_id, - ) + invoice = _("Invoice %s") % invoice + note = "{} {}".format(description, transaction_id) if details: - note += ': %s' % details + note += ": %s" % details if payer_email: - note += ' (%s)' % payer_email + note += " (%s)" % payer_email - unique_import_id = '%s-%s' % ( - transaction_id, - int(timestamp.timestamp()), - ) - name = invoice or details or description or '', + unique_import_id = "{}-{}".format(transaction_id, int(timestamp.timestamp())) + name = (invoice or details or description or "",) transaction = { - 'name': invoice or details or description or '', - 'amount': str(gross_amount), - 'date': timestamp, - 'note': note, - 'unique_import_id': unique_import_id, + "name": invoice or details or description or "", + "amount": str(gross_amount), + "date": timestamp, + "note": note, + "unique_import_id": unique_import_id, } if payer_name: - line.update({ - 'partner_name': payer_name, - }) + line.update({"partner_name": payer_name}) if partner_bank_account: - line.update({ - 'account_number': partner_bank_account, - }) + line.update({"account_number": partner_bank_account}) transactions.append(transaction) if fee_amount: - transactions.append({ - 'name': _('Fee for %s') % (name or transaction_id), - 'amount': str(fee_amount), - 'date': timestamp, - 'partner_name': 'PayPal', - 'unique_import_id': '%s-FEE' % unique_import_id, - 'note': _('Transaction fee for %s') % note, - }) + transactions.append( + { + "name": _("Fee for %s") % (name or transaction_id), + "amount": str(fee_amount), + "date": timestamp, + "partner_name": "PayPal", + "unique_import_id": "%s-FEE" % unique_import_id, + "note": _("Transaction fee for %s") % note, + } + ) return transactions @api.model def _parse_decimal(self, value, mapping): thousands, decimal = mapping._get_float_separators() - value = value.replace(thousands, '') - value = value.replace(decimal, '.') + value = value.replace(thousands, "") + value = value.replace(decimal, ".") return Decimal(value) @api.model def _normalize_tz(self, value): - if value in ['PDT', 'PST']: - return 'America/Los_Angeles' - elif value in ['CET', 'CEST']: - return 'Europe/Paris' + if value in ["PDT", "PST"]: + return "America/Los_Angeles" + elif value in ["CET", "CEST"]: + return "Europe/Paris" return value diff --git a/account_bank_statement_import_paypal/models/account_journal.py b/account_bank_statement_import_paypal/models/account_journal.py index 20fbe50a..20756fa6 100644 --- a/account_bank_statement_import_paypal/models/account_journal.py +++ b/account_bank_statement_import_paypal/models/account_journal.py @@ -6,9 +6,9 @@ from odoo import models class AccountJournal(models.Model): - _inherit = 'account.journal' + _inherit = "account.journal" def _get_bank_statements_available_import_formats(self): res = super()._get_bank_statements_available_import_formats() - res.append('PayPal Reports') + res.append("PayPal Reports") return res 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 983396d9..5d4e4601 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 @@ -2,200 +2,210 @@ # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from base64 import b64encode +from os import path + from odoo import fields from odoo.exceptions import UserError from odoo.tests import common -from base64 import b64encode -from os import path - class TestAccountBankStatementImportPayPal(common.TransactionCase): def setUp(self): super().setUp() self.now = fields.Datetime.now() - self.currency_eur = self.env.ref('base.EUR') - self.currency_usd = self.env.ref('base.USD') + self.currency_eur = self.env.ref("base.EUR") + self.currency_usd = self.env.ref("base.USD") self.paypal_statement_map_en = self.env.ref( - 'account_bank_statement_import_paypal.paypal_statement_map_en' + "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' + "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' + "account_bank_statement_import_paypal.paypal_activity_map_en" ) - self.AccountJournal = self.env['account.journal'] - self.AccountBankStatement = self.env['account.bank.statement'] - self.AccountBankStatementImport = self.env[ - 'account.bank.statement.import' - ] + self.AccountJournal = self.env["account.journal"] + self.AccountBankStatement = self.env["account.bank.statement"] + self.AccountBankStatementImport = self.env["account.bank.statement.import"] self.AccountBankStatementImportPayPalMapping = self.env[ - 'account.bank.statement.import.paypal.mapping' + "account.bank.statement.import.paypal.mapping" ] self.AccountBankStatementImportPayPalMappingWizard = self.env[ - 'account.bank.statement.import.paypal.mapping.wizard' + "account.bank.statement.import.paypal.mapping.wizard" ] def _data_file(self, filename): with open(path.join(path.dirname(__file__), filename)) as file: - return b64encode(file.read().encode('utf-8')) + return b64encode(file.read().encode("utf-8")) def test_import_statement_en_usd(self): - journal = self.AccountJournal.create({ - 'name': 'PayPal', - 'type': 'bank', - 'code': 'PP', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/statement_en.csv', - 'data_file': self._data_file('fixtures/statement_en.csv'), - 'paypal_mapping_id': self.paypal_statement_map_en.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), - ]) + journal = self.AccountJournal.create( + { + "name": "PayPal", + "type": "bank", + "code": "PP", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id} + ).create( + { + "filename": "fixtures/statement_en.csv", + "data_file": self._data_file("fixtures/statement_en.csv"), + "paypal_mapping_id": self.paypal_statement_map_en.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), 18) def test_import_statement_en_eur(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_en.csv', - 'data_file': self._data_file('fixtures/statement_en.csv'), - 'paypal_mapping_id': self.paypal_statement_map_en.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), - ]) + 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_en.csv", + "data_file": self._data_file("fixtures/statement_en.csv"), + "paypal_mapping_id": self.paypal_statement_map_en.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_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), - ]) + 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', - 'type': 'bank', - 'code': 'PP', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/activity_en.csv', - 'data_file': self._data_file('fixtures/activity_en.csv'), - 'paypal_mapping_id': self.paypal_activity_map_en.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), - ]) + journal = self.AccountJournal.create( + { + "name": "PayPal", + "type": "bank", + "code": "PP", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id} + ).create( + { + "filename": "fixtures/activity_en.csv", + "data_file": self._data_file("fixtures/activity_en.csv"), + "paypal_mapping_id": self.paypal_activity_map_en.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), 71) def test_import_empty_activity(self): - journal = self.AccountJournal.create({ - 'name': 'PayPal', - 'type': 'bank', - 'code': 'PP', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/empty_activity.csv', - 'data_file': self._data_file('fixtures/empty_activity.csv'), - 'paypal_mapping_id': self.paypal_activity_map_en.id, - }) + journal = self.AccountJournal.create( + { + "name": "PayPal", + "type": "bank", + "code": "PP", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id} + ).create( + { + "filename": "fixtures/empty_activity.csv", + "data_file": self._data_file("fixtures/empty_activity.csv"), + "paypal_mapping_id": self.paypal_activity_map_en.id, + } + ) with self.assertRaises(UserError): - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_paypal_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.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), 0) def test_import_activity_mapping_en(self): - with common.Form( - self.AccountBankStatementImportPayPalMappingWizard) as form: - form.filename = 'fixtures/activity_en.csv' - form.data_file = self._data_file( - 'fixtures/activity_en.csv' - ) + 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() + self.AccountBankStatementImportPayPalMappingWizard.with_context( + header=form.header, + ).statement_columns() ), - 22 + 22, ) wizard = form.save() wizard.import_mapping() def test_import_statement_mapping_en(self): - with common.Form( - self.AccountBankStatementImportPayPalMappingWizard) as form: - form.filename = 'fixtures/statement_en.csv' - form.data_file = self._data_file( - 'fixtures/statement_en.csv' - ) + 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() + self.AccountBankStatementImportPayPalMappingWizard.with_context( + header=form.header, + ).statement_columns() ), - 18 + 18, ) wizard = form.save() wizard.import_mapping() diff --git a/account_bank_statement_import_paypal/views/account_bank_statement_import.xml b/account_bank_statement_import_paypal/views/account_bank_statement_import.xml index 6d5d7bf4..38e517f0 100644 --- a/account_bank_statement_import_paypal/views/account_bank_statement_import.xml +++ b/account_bank_statement_import_paypal/views/account_bank_statement_import.xml @@ -1,4 +1,4 @@ - + - account.bank.statement.import account.bank.statement.import - +
  • - PayPal Report mapping: + PayPal Report mapping:
  • -
    diff --git a/account_bank_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml b/account_bank_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml index 7d81e680..38c4f758 100644 --- a/account_bank_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml +++ b/account_bank_statement_import_paypal/views/account_bank_statement_import_paypal_mapping.xml @@ -1,21 +1,19 @@ - + - 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 @@ -23,56 +21,58 @@
    -
    - - + + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
    - - + PayPal Report Mappings account.bank.statement.import.paypal.mapping form tree,form - -
    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 bbc09a5d..6b080544 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 @@ -2,82 +2,43 @@ # 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 base64 import b64decode import json +from base64 import b64decode from os import path +from odoo import _, api, fields, models + 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'] + _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='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') + @api.onchange("data_file") def _onchange_data_file(self): - Parser = self.env['account.bank.statement.import.paypal.parser'] + Parser = self.env["account.bank.statement.import.paypal.parser"] if not self.data_file: return header = Parser.parse_header(b64decode(self.data_file)) @@ -117,7 +78,7 @@ class AccountBankStatementImportPayPalMappingWizard(models.TransientModel): @api.model def statement_columns(self): - header = self.env.context.get('header') + header = self.env.context.get("header") if not header: return [] return [(x, x) for x in json.loads(header)] @@ -127,42 +88,43 @@ class AccountBankStatementImportPayPalMappingWizard(models.TransientModel): """Hook for extension""" self.ensure_one() 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, + "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, } @api.multi def import_mapping(self): self.ensure_one() - mapping = self.env['account.bank.statement.import.paypal.mapping']\ - .create(self._get_mapping_values()) + mapping = self.env["account.bank.statement.import.paypal.mapping"].create( + self._get_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': 'current', + "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": "current", } 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 bf996279..545ffe36 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,28 +1,36 @@ - + - - - account.bank.statement.import.paypal.mapping.wizard.form + + account.bank.statement.import.paypal.mapping.wizard.form account.bank.statement.import.paypal.mapping.wizard primary - +

    Select a PayPal report file to import mapping.

    - - + + - +
    -