diff --git a/account_bank_statement_import_txt_xlsx/__manifest__.py b/account_bank_statement_import_txt_xlsx/__manifest__.py index d4de2e90..ccc7c5a8 100644 --- a/account_bank_statement_import_txt_xlsx/__manifest__.py +++ b/account_bank_statement_import_txt_xlsx/__manifest__.py @@ -8,10 +8,7 @@ "version": "12.0.2.0.0", "category": "Accounting", "website": "https://github.com/OCA/bank-statement-import", - "author": - "ForgeFlow, " - "Brainbean Apps, " - "Odoo Community Association (OCA)", + "author": "ForgeFlow, " "Brainbean Apps, " "Odoo Community Association (OCA)", "license": "AGPL-3", "installable": True, "depends": [ @@ -19,12 +16,7 @@ "multi_step_wizard", "web_widget_dropdown_dynamic", ], - "external_dependencies": { - "python": [ - "csv", - "xlrd", - ] - }, + "external_dependencies": {"python": ["csv", "xlrd",]}, "data": [ "security/ir.model.access.csv", "data/map_data.xml", @@ -32,5 +24,5 @@ "views/account_bank_statement_import.xml", "views/account_journal_views.xml", "wizards/account_bank_statement_import_sheet_mapping_wizard.xml", - ] + ], } diff --git a/account_bank_statement_import_txt_xlsx/data/map_data.xml b/account_bank_statement_import_txt_xlsx/data/map_data.xml index 3025d9c9..04116d0b 100644 --- a/account_bank_statement_import_txt_xlsx/data/map_data.xml +++ b/account_bank_statement_import_txt_xlsx/data/map_data.xml @@ -1,12 +1,14 @@ - + - - + Sample Statement comma dot @@ -21,5 +23,4 @@ Partner Name Bank Account - diff --git a/account_bank_statement_import_txt_xlsx/migrations/12.0.2.0.0/post-migration.py b/account_bank_statement_import_txt_xlsx/migrations/12.0.2.0.0/post-migration.py index 49e0e6a4..821a019c 100644 --- a/account_bank_statement_import_txt_xlsx/migrations/12.0.2.0.0/post-migration.py +++ b/account_bank_statement_import_txt_xlsx/migrations/12.0.2.0.0/post-migration.py @@ -94,5 +94,5 @@ LEFT JOIN _mappings AS _p_name ON m.id = _p_name.id AND _p_name.field_to_assign = 'partner_name' LEFT JOIN _mappings AS _bank_acc ON m.id = _bank_acc.id AND _bank_acc.field_to_assign = 'account_number'; - """ + """, ) diff --git a/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import.py b/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import.py index a8724182..f087a61e 100644 --- a/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import.py +++ b/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import.py @@ -1,22 +1,26 @@ # Copyright 2020 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" def _get_default_mapping_id(self): - return self.env["account.journal"].browse( - self.env.context.get('journal_id')).default_sheet_mapping_id + return ( + self.env["account.journal"] + .browse(self.env.context.get("journal_id")) + .default_sheet_mapping_id + ) sheet_mapping_id = fields.Many2one( - string='Sheet mapping', - comodel_name='account.bank.statement.import.sheet.mapping', + string="Sheet mapping", + comodel_name="account.bank.statement.import.sheet.mapping", default=_get_default_mapping_id, ) @@ -24,15 +28,10 @@ class AccountBankStatementImport(models.TransientModel): def _parse_file(self, data_file): self.ensure_one() try: - Parser = self.env['account.bank.statement.import.sheet.parser'] - return Parser.parse( - self.sheet_mapping_id, - data_file, - self.filename - ) + Parser = self.env["account.bank.statement.import.sheet.parser"] + return Parser.parse(self.sheet_mapping_id, data_file, self.filename) except: - if self.env.context.get( - 'account_bank_statement_import_txt_xlsx_test'): + if self.env.context.get("account_bank_statement_import_txt_xlsx_test"): raise - _logger.warning('Sheet parser error', exc_info=True) + _logger.warning("Sheet parser error", exc_info=True) return super()._parse_file(data_file) diff --git a/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_mapping.py b/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_mapping.py index 2e91fdae..b2b5c2bf 100644 --- a/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_mapping.py +++ b/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_mapping.py @@ -6,182 +6,145 @@ from odoo import api, fields, models class AccountBankStatementImportSheetMapping(models.Model): - _name = 'account.bank.statement.import.sheet.mapping' - _description = 'Account Bank Statement Import Sheet Mapping' + _name = "account.bank.statement.import.sheet.mapping" + _description = "Account Bank Statement Import Sheet 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", ) float_decimal_sep = fields.Selection( - string='Decimals Separator', - selection=[ - ('dot', 'dot (.)'), - ('comma', 'comma (,)'), - ('none', 'none'), - ], - default='comma', + string="Decimals Separator", + selection=[("dot", "dot (.)"), ("comma", "comma (,)"), ("none", "none"),], + default="comma", ) file_encoding = fields.Selection( - string='Encoding', + string="Encoding", selection=[ - ('utf-8', 'UTF-8'), - ('utf-8-sig', 'UTF-8 (with BOM)'), - ('utf-16', 'UTF-16'), - ('utf-16-sig', 'UTF-16 (with BOM)'), - ('windows-1252', 'Western (Windows-1252)'), - ('iso-8859-1', 'Western (Latin-1 / ISO 8859-1)'), - ('iso-8859-2', 'Central European (Latin-2 / ISO 8859-2)'), - ('iso-8859-4', 'Baltic (Latin-4 / ISO 8859-4)'), - ('big5', 'Traditional Chinese (big5)'), - ('gb18030', 'Unified Chinese (gb18030)'), - ('shift_jis', 'Japanese (Shift JIS)'), - ('windows-1251', 'Cyrillic (Windows-1251)'), - ('koi8_r', 'Cyrillic (KOI8-R)'), - ('koi8_u', 'Cyrillic (KOI8-U)'), + ("utf-8", "UTF-8"), + ("utf-8-sig", "UTF-8 (with BOM)"), + ("utf-16", "UTF-16"), + ("utf-16-sig", "UTF-16 (with BOM)"), + ("windows-1252", "Western (Windows-1252)"), + ("iso-8859-1", "Western (Latin-1 / ISO 8859-1)"), + ("iso-8859-2", "Central European (Latin-2 / ISO 8859-2)"), + ("iso-8859-4", "Baltic (Latin-4 / ISO 8859-4)"), + ("big5", "Traditional Chinese (big5)"), + ("gb18030", "Unified Chinese (gb18030)"), + ("shift_jis", "Japanese (Shift JIS)"), + ("windows-1251", "Cyrillic (Windows-1251)"), + ("koi8_r", "Cyrillic (KOI8-R)"), + ("koi8_u", "Cyrillic (KOI8-U)"), ], - default='utf-8', + default="utf-8", ) delimiter = fields.Selection( - string='Delimiter', + string="Delimiter", selection=[ - ('dot', 'dot (.)'), - ('comma', 'comma (,)'), - ('semicolon', 'semicolon (;)'), - ('tab', 'tab'), - ('space', 'space'), - ('n/a', 'N/A'), + ("dot", "dot (.)"), + ("comma", "comma (,)"), + ("semicolon", "semicolon (;)"), + ("tab", "tab"), + ("space", "space"), + ("n/a", "N/A"), ], - default='comma', - ) - quotechar = fields.Char( - string='Text qualifier', - size=1, - default='"', - ) - timestamp_format = fields.Char( - string='Timestamp Format', - required=True, - ) - timestamp_column = fields.Char( - string='Timestamp column', - required=True, + default="comma", ) + quotechar = fields.Char(string="Text qualifier", size=1, default='"',) + timestamp_format = fields.Char(string="Timestamp Format", required=True,) + timestamp_column = fields.Char(string="Timestamp column", required=True,) currency_column = fields.Char( - string='Currency column', + string="Currency column", help=( - 'In case statement is multi-currency, column to get currency of ' - 'transaction from' + "In case statement is multi-currency, column to get currency of " + "transaction from" ), ) amount_column = fields.Char( - string='Amount column', + string="Amount column", required=True, - help='Amount of transaction in journal\'s currency', + help="Amount of transaction in journal's currency", ) balance_column = fields.Char( - string='Balance column', - help='Balance after transaction in journal\'s currency', + string="Balance column", help="Balance after transaction in journal's currency", ) original_currency_column = fields.Char( - string='Original currency column', + string="Original currency column", help=( - 'In case statement provides original currency for transactions ' - 'with automatic currency conversion, column to get original ' - 'currency of transaction from' + "In case statement provides original currency for transactions " + "with automatic currency conversion, column to get original " + "currency of transaction from" ), ) original_amount_column = fields.Char( - string='Original amount column', + string="Original amount column", help=( - 'In case statement provides original currency for transactions ' - 'with automatic currency conversion, column to get original ' - 'transaction amount in original transaction currency from' + "In case statement provides original currency for transactions " + "with automatic currency conversion, column to get original " + "transaction amount in original transaction currency from" ), ) debit_credit_column = fields.Char( - string='Debit/credit column', + string="Debit/credit column", help=( - 'Some statement formats use absolute amount value and indicate sign' - 'of the transaction by specifying if it was a debit or a credit one' + "Some statement formats use absolute amount value and indicate sign" + "of the transaction by specifying if it was a debit or a credit one" ), ) debit_value = fields.Char( - string='Debit value', - help='Value of debit/credit column that indicates if it\'s a debit', - default='D', + string="Debit value", + help="Value of debit/credit column that indicates if it's a debit", + default="D", ) credit_value = fields.Char( - string='Credit value', - help='Value of debit/credit column that indicates if it\'s a credit', - default='C', - ) - transaction_id_column = fields.Char( - string='Unique transaction ID column', - ) - description_column = fields.Char( - string='Description column', - ) - notes_column = fields.Char( - string='Notes column', - ) - reference_column = fields.Char( - string='Reference column', - ) - partner_name_column = fields.Char( - string='Partner Name column', - ) - bank_name_column = fields.Char( - string='Bank Name column', - help='Partner\'s bank', + string="Credit value", + help="Value of debit/credit column that indicates if it's a credit", + default="C", ) + transaction_id_column = fields.Char(string="Unique transaction ID column",) + description_column = fields.Char(string="Description column",) + notes_column = fields.Char(string="Notes column",) + reference_column = fields.Char(string="Reference column",) + partner_name_column = fields.Char(string="Partner Name column",) + bank_name_column = fields.Char(string="Bank Name column", help="Partner's bank",) bank_account_column = fields.Char( - string='Bank Account column', - help='Partner\'s bank account', + string="Bank Account column", help="Partner's bank account", ) - @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], + ) @api.model def _decode_column_delimiter_character(self, delimiter): - return ({ - 'dot': '.', - 'comma': ',', - 'semicolon': ';', - 'tab': '\t', - 'space': ' ', - }).get(delimiter) + return ( + {"dot": ".", "comma": ",", "semicolon": ";", "tab": "\t", "space": " ",} + ).get(delimiter) @api.multi def _get_column_delimiter_character(self): diff --git a/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_parser.py b/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_parser.py index fb056010..7923efce 100644 --- a/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_parser.py +++ b/account_bank_statement_import_txt_xlsx/models/account_bank_statement_import_sheet_parser.py @@ -2,15 +2,15 @@ # Copyright 2020 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 -import logging +from odoo import _, api, models + _logger = logging.getLogger(__name__) try: @@ -22,8 +22,8 @@ except (ImportError, IOError) as err: # pragma: no cover class AccountBankStatementImportSheetParser(models.TransientModel): - _name = 'account.bank.statement.import.sheet.parser' - _description = 'Account Bank Statement Import Sheet Parser' + _name = "account.bank.statement.import.sheet.parser" + _description = "Account Bank Statement Import Sheet Parser" @api.model def parse_header(self, data_file, encoding, csv_options): @@ -38,58 +38,48 @@ class AccountBankStatementImportSheetParser(models.TransientModel): except xlrd.XLRDError: pass - data = StringIO(data_file.decode(encoding or 'utf-8')) + data = StringIO(data_file.decode(encoding or "utf-8")) csv_data = reader(data, **csv_options) 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] last_line = lines[-1] data = { - 'name': name, - 'date': first_line['timestamp'].date(), + "name": name, + "date": first_line["timestamp"].date(), } if mapping.balance_column: - balance_start = first_line['balance'] - balance_start -= first_line['amount'] - balance_end = last_line['balance'] - data.update({ - 'balance_start': float(balance_start), - 'balance_end_real': float(balance_end), - }) + balance_start = first_line["balance"] + balance_start -= first_line["amount"] + balance_end = last_line["balance"] + data.update( + { + "balance_start": float(balance_start), + "balance_end_real": float(balance_end), + } + ) - transactions = list(itertools.chain.from_iterable(map( - lambda line: self._convert_line_to_transactions(line), - lines - ))) - data.update({ - 'transactions': transactions, - }) + transactions = list( + itertools.chain.from_iterable( + map(lambda line: self._convert_line_to_transactions(line), lines) + ) + ) + data.update( + {"transactions": transactions,} + ) return currency_code, account_number, [data] @@ -101,16 +91,19 @@ class AccountBankStatementImportSheetParser(models.TransientModel): mapping.file_encoding if mapping.file_encoding else None ), ) - csv_or_xlsx = (workbook, workbook.sheet_by_index(0),) + csv_or_xlsx = ( + workbook, + workbook.sheet_by_index(0), + ) except xlrd.XLRDError: csv_options = {} csv_delimiter = mapping._get_column_delimiter_character() if csv_delimiter: - csv_options['delimiter'] = csv_delimiter + csv_options["delimiter"] = csv_delimiter if mapping.quotechar: - csv_options['quotechar'] = mapping.quotechar + csv_options["quotechar"] = mapping.quotechar csv_or_xlsx = reader( - StringIO(data_file.decode(mapping.file_encoding or 'utf-8')), + StringIO(data_file.decode(mapping.file_encoding or "utf-8")), **csv_options ) @@ -119,35 +112,57 @@ class AccountBankStatementImportSheetParser(models.TransientModel): else: header = [value.strip() for value in next(csv_or_xlsx)] timestamp_column = header.index(mapping.timestamp_column) - currency_column = header.index(mapping.currency_column) \ - if mapping.currency_column else None + currency_column = ( + header.index(mapping.currency_column) if mapping.currency_column else None + ) amount_column = header.index(mapping.amount_column) - balance_column = header.index(mapping.balance_column) \ - if mapping.balance_column else None + balance_column = ( + header.index(mapping.balance_column) if mapping.balance_column else None + ) original_currency_column = ( header.index(mapping.original_currency_column) - if mapping.original_currency_column else None + if mapping.original_currency_column + else None ) original_amount_column = ( header.index(mapping.original_amount_column) - if mapping.original_amount_column else None + if mapping.original_amount_column + else None + ) + debit_credit_column = ( + header.index(mapping.debit_credit_column) + if mapping.debit_credit_column + else None + ) + transaction_id_column = ( + header.index(mapping.transaction_id_column) + if mapping.transaction_id_column + else None + ) + description_column = ( + header.index(mapping.description_column) + if mapping.description_column + else None + ) + notes_column = ( + header.index(mapping.notes_column) if mapping.notes_column else None + ) + reference_column = ( + header.index(mapping.reference_column) if mapping.reference_column else None + ) + partner_name_column = ( + header.index(mapping.partner_name_column) + if mapping.partner_name_column + else None + ) + bank_name_column = ( + header.index(mapping.bank_name_column) if mapping.bank_name_column else None + ) + bank_account_column = ( + header.index(mapping.bank_account_column) + if mapping.bank_account_column + else None ) - debit_credit_column = header.index(mapping.debit_credit_column) \ - if mapping.debit_credit_column else None - transaction_id_column = header.index(mapping.transaction_id_column) \ - if mapping.transaction_id_column else None - description_column = header.index(mapping.description_column) \ - if mapping.description_column else None - notes_column = header.index(mapping.notes_column) \ - if mapping.notes_column else None - reference_column = header.index(mapping.reference_column) \ - if mapping.reference_column else None - partner_name_column = header.index(mapping.partner_name_column) \ - if mapping.partner_name_column else None - bank_name_column = header.index(mapping.bank_name_column) \ - if mapping.bank_name_column else None - bank_account_column = header.index(mapping.bank_account_column) \ - if mapping.bank_account_column else None if isinstance(csv_or_xlsx, tuple): rows = range(1, csv_or_xlsx[1].nrows) @@ -170,40 +185,53 @@ class AccountBankStatementImportSheetParser(models.TransientModel): values = list(row) timestamp = values[timestamp_column] - currency = values[currency_column] \ - if currency_column is not None else currency_code + currency = ( + values[currency_column] + if currency_column is not None + else currency_code + ) amount = values[amount_column] - balance = values[balance_column] \ - if balance_column is not None else None - original_currency = values[original_currency_column] \ - if original_currency_column is not None else None - original_amount = values[original_amount_column] \ - if original_amount_column is not None else None - debit_credit = values[debit_credit_column] \ - if debit_credit_column is not None else None - transaction_id = values[transaction_id_column] \ - if transaction_id_column is not None else None - description = values[description_column] \ - if description_column is not None else None - notes = values[notes_column] \ - if notes_column is not None else None - reference = values[reference_column] \ - if reference_column is not None else None - partner_name = values[partner_name_column] \ - if partner_name_column is not None else None - bank_name = values[bank_name_column] \ - if bank_name_column is not None else None - bank_account = values[bank_account_column] \ - if bank_account_column is not None else None + balance = values[balance_column] if balance_column is not None else None + original_currency = ( + values[original_currency_column] + if original_currency_column is not None + else None + ) + original_amount = ( + values[original_amount_column] + if original_amount_column is not None + else None + ) + debit_credit = ( + values[debit_credit_column] if debit_credit_column is not None else None + ) + transaction_id = ( + values[transaction_id_column] + if transaction_id_column is not None + else None + ) + description = ( + values[description_column] if description_column is not None else None + ) + notes = values[notes_column] if notes_column is not None else None + reference = ( + values[reference_column] if reference_column is not None else None + ) + partner_name = ( + values[partner_name_column] if partner_name_column is not None else None + ) + bank_name = ( + values[bank_name_column] if bank_name_column is not None else None + ) + bank_account = ( + values[bank_account_column] if bank_account_column is not None else None + ) if currency != currency_code: continue if isinstance(timestamp, str): - timestamp = datetime.strptime( - timestamp, - mapping.timestamp_format - ) + timestamp = datetime.strptime(timestamp, mapping.timestamp_format) amount = self._parse_decimal(amount, mapping) if balance is not None: @@ -223,99 +251,91 @@ class AccountBankStatementImportSheetParser(models.TransientModel): original_amount = self._parse_decimal(original_amount, mapping) line = { - 'timestamp': timestamp, - 'amount': amount, - 'currency': currency, - 'original_amount': original_amount, - 'original_currency': original_currency, + "timestamp": timestamp, + "amount": amount, + "currency": currency, + "original_amount": original_amount, + "original_currency": original_currency, } if balance is not None: - line['balance'] = balance + line["balance"] = balance if transaction_id is not None: - line['transaction_id'] = transaction_id + line["transaction_id"] = transaction_id if description is not None: - line['description'] = description + line["description"] = description if notes is not None: - line['notes'] = notes + line["notes"] = notes if reference is not None: - line['reference'] = reference + line["reference"] = reference if partner_name is not None: - line['partner_name'] = partner_name + line["partner_name"] = partner_name if bank_name is not None: - line['bank_name'] = bank_name + line["bank_name"] = bank_name if bank_account is not None: - line['bank_account'] = bank_account + line["bank_account"] = bank_account lines.append(line) return lines @api.model def _convert_line_to_transactions(self, line): """Hook for extension""" - timestamp = line['timestamp'] - amount = line['amount'] - currency = line['currency'] - original_amount = line['original_amount'] - original_currency = line['original_currency'] - transaction_id = line.get('transaction_id') - description = line.get('description') - notes = line.get('notes') - reference = line.get('reference') - partner_name = line.get('partner_name') - bank_name = line.get('bank_name') - bank_account = line.get('bank_account') + timestamp = line["timestamp"] + amount = line["amount"] + currency = line["currency"] + original_amount = line["original_amount"] + original_currency = line["original_currency"] + transaction_id = line.get("transaction_id") + description = line.get("description") + notes = line.get("notes") + reference = line.get("reference") + partner_name = line.get("partner_name") + bank_name = line.get("bank_name") + bank_account = line.get("bank_account") transaction = { - 'date': timestamp, - 'amount': str(amount), + "date": timestamp, + "amount": str(amount), } if currency != original_currency: - original_currency = self.env['res.currency'].search( - [('name', '=', original_currency)], - limit=1, + original_currency = self.env["res.currency"].search( + [("name", "=", original_currency)], limit=1, ) if original_currency: - transaction.update({ - 'amount_currency': str(original_amount), - 'currency_id': original_currency.id, - }) + transaction.update( + { + "amount_currency": str(original_amount), + "currency_id": original_currency.id, + } + ) if transaction_id: - transaction['unique_import_id'] = '%s-%s' % ( + transaction["unique_import_id"] = "{}-{}".format( transaction_id, int(timestamp.timestamp()), ) - transaction['name'] = description or _('N/A') + transaction["name"] = description or _("N/A") if reference: - transaction['ref'] = reference + transaction["ref"] = reference - note = '' + note = "" if bank_name: - note += _('Bank: %s; ') % ( - bank_name, - ) + note += _("Bank: %s; ") % (bank_name,) if bank_account: - note += _('Account: %s; ') % ( - bank_account, - ) + note += _("Account: %s; ") % (bank_account,) if transaction_id: - note += _('Transaction ID: %s; ') % ( - transaction_id, - ) + note += _("Transaction ID: %s; ") % (transaction_id,) if note and notes: - note = '%s\n%s' % ( - note, - note.strip(), - ) + note = "{}\n{}".format(note, note.strip()) elif note: note = note.strip() if note: - transaction['note'] = note + transaction["note"] = note if partner_name: - transaction['partner_name'] = partner_name + transaction["partner_name"] = partner_name if bank_account: - transaction['account_number'] = bank_account + transaction["account_number"] = bank_account return [transaction] @@ -326,6 +346,6 @@ class AccountBankStatementImportSheetParser(models.TransientModel): elif isinstance(value, float): return Decimal(value) 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) diff --git a/account_bank_statement_import_txt_xlsx/models/account_journal.py b/account_bank_statement_import_txt_xlsx/models/account_journal.py index 8d906439..5636d600 100644 --- a/account_bank_statement_import_txt_xlsx/models/account_journal.py +++ b/account_bank_statement_import_txt_xlsx/models/account_journal.py @@ -6,13 +6,13 @@ from odoo import fields, models class AccountJournal(models.Model): - _inherit = 'account.journal' + _inherit = "account.journal" default_sheet_mapping_id = fields.Many2one( - comodel_name='account.bank.statement.import.sheet.mapping', + comodel_name="account.bank.statement.import.sheet.mapping", ) def _get_bank_statements_available_import_formats(self): res = super()._get_bank_statements_available_import_formats() - res.append('TXT/CSV/XSLX') + res.append("TXT/CSV/XSLX") return res diff --git a/account_bank_statement_import_txt_xlsx/tests/test_account_bank_statement_import_txt_xlsx.py b/account_bank_statement_import_txt_xlsx/tests/test_account_bank_statement_import_txt_xlsx.py index 9f8709bb..fb7669b9 100644 --- a/account_bank_statement_import_txt_xlsx/tests/test_account_bank_statement_import_txt_xlsx.py +++ b/account_bank_statement_import_txt_xlsx/tests/test_account_bank_statement_import_txt_xlsx.py @@ -2,38 +2,36 @@ # Copyright 2020 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 TestAccountBankStatementImportTxtXlsx(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.sample_statement_map = self.env.ref( - 'account_bank_statement_import_txt_xlsx.sample_statement_map' + "account_bank_statement_import_txt_xlsx.sample_statement_map" ) - 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.AccountBankStatementImportSheetMapping = self.env[ - 'account.bank.statement.import.sheet.mapping' + "account.bank.statement.import.sheet.mapping" ] self.AccountBankStatementImportSheetMappingWizard = self.env[ - 'account.bank.statement.import.sheet.mapping.wizard' + "account.bank.statement.import.sheet.mapping.wizard" ] def _data_file(self, filename, encoding=None): - mode = 'rt' if encoding else 'rb' + mode = "rt" if encoding else "rb" with open(path.join(path.dirname(__file__), filename), mode) as file: data = file.read() if encoding: @@ -41,175 +39,182 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): return b64encode(data) def test_import_csv_file(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/sample_statement_en.csv', - 'data_file': self._data_file( - 'fixtures/sample_statement_en.csv', - 'utf-8' - ), - 'sheet_mapping_id': self.sample_statement_map.id, - }) - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/sample_statement_en.csv", + "data_file": self._data_file( + "fixtures/sample_statement_en.csv", "utf-8" + ), + "sheet_mapping_id": self.sample_statement_map.id, + } + ) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 2) def test_import_empty_csv_file(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/empty_statement_en.csv', - 'data_file': self._data_file( - 'fixtures/empty_statement_en.csv', - 'utf-8' - ), - 'sheet_mapping_id': self.sample_statement_map.id, - }) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/empty_statement_en.csv", + "data_file": self._data_file( + "fixtures/empty_statement_en.csv", "utf-8" + ), + "sheet_mapping_id": self.sample_statement_map.id, + } + ) with self.assertRaises(UserError): - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 0) def test_import_xlsx_file(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/sample_statement_en.xlsx', - 'data_file': self._data_file('fixtures/sample_statement_en.xlsx'), - 'sheet_mapping_id': self.sample_statement_map.id, - }) - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/sample_statement_en.xlsx", + "data_file": self._data_file("fixtures/sample_statement_en.xlsx"), + "sheet_mapping_id": self.sample_statement_map.id, + } + ) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 2) def test_import_empty_xlsx_file(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/empty_statement_en.xlsx', - 'data_file': self._data_file('fixtures/empty_statement_en.xlsx'), - 'sheet_mapping_id': self.sample_statement_map.id, - }) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/empty_statement_en.xlsx", + "data_file": self._data_file("fixtures/empty_statement_en.xlsx"), + "sheet_mapping_id": self.sample_statement_map.id, + } + ) with self.assertRaises(UserError): - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 0) def test_mapping_import_wizard_xlsx(self): - with common.Form( - self.AccountBankStatementImportSheetMappingWizard) as form: - form.filename = 'fixtures/empty_statement_en.xlsx' - form.data_file = self._data_file( - 'fixtures/empty_statement_en.xlsx' - ) + with common.Form(self.AccountBankStatementImportSheetMappingWizard) as form: + form.filename = "fixtures/empty_statement_en.xlsx" + form.data_file = self._data_file("fixtures/empty_statement_en.xlsx") self.assertEqual(len(form.header), 90) self.assertEqual( len( - self.AccountBankStatementImportSheetMappingWizard - .with_context( - header=form.header, - ).statement_columns() + self.AccountBankStatementImportSheetMappingWizard.with_context( + header=form.header, + ).statement_columns() ), - 7 + 7, ) - form.timestamp_column = 'Date' - form.amount_column = 'Amount' + form.timestamp_column = "Date" + form.amount_column = "Amount" wizard = form.save() wizard.import_mapping() def test_mapping_import_wizard_csv(self): - with common.Form( - self.AccountBankStatementImportSheetMappingWizard) as form: - form.filename = 'fixtures/empty_statement_en.csv' - form.data_file = self._data_file( - 'fixtures/empty_statement_en.csv' - ) + with common.Form(self.AccountBankStatementImportSheetMappingWizard) as form: + form.filename = "fixtures/empty_statement_en.csv" + form.data_file = self._data_file("fixtures/empty_statement_en.csv") self.assertEqual(len(form.header), 90) self.assertEqual( len( - self.AccountBankStatementImportSheetMappingWizard - .with_context( - header=form.header, - ).statement_columns() + self.AccountBankStatementImportSheetMappingWizard.with_context( + header=form.header, + ).statement_columns() ), - 7 + 7, ) - form.timestamp_column = 'Date' - form.amount_column = 'Amount' + form.timestamp_column = "Date" + form.amount_column = "Amount" wizard = form.save() wizard.import_mapping() def test_original_currency(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/original_currency.csv', - 'data_file': self._data_file( - 'fixtures/original_currency.csv', - 'utf-8' - ), - 'sheet_mapping_id': self.sample_statement_map.id, - }) - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/original_currency.csv", + "data_file": self._data_file("fixtures/original_currency.csv", "utf-8"), + "sheet_mapping_id": self.sample_statement_map.id, + } + ) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 1) @@ -218,34 +223,37 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): self.assertEqual(line.amount_currency, 1000.0) def test_multi_currency(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - statement_map = self.sample_statement_map.copy({ - 'currency_column': 'Currency', - 'original_currency_column': None, - 'original_amount_column': None, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/multi_currency.csv', - 'data_file': self._data_file( - 'fixtures/multi_currency.csv', - 'utf-8' - ), - 'sheet_mapping_id': statement_map.id, - }) - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + statement_map = self.sample_statement_map.copy( + { + "currency_column": "Currency", + "original_currency_column": None, + "original_amount_column": None, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/multi_currency.csv", + "data_file": self._data_file("fixtures/multi_currency.csv", "utf-8"), + "sheet_mapping_id": statement_map.id, + } + ) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 1) @@ -254,34 +262,37 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): self.assertEqual(line.amount, -33.5) def test_balance(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - statement_map = self.sample_statement_map.copy({ - 'balance_column': 'Balance', - 'original_currency_column': None, - 'original_amount_column': None, - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/balance.csv', - 'data_file': self._data_file( - 'fixtures/balance.csv', - 'utf-8' - ), - 'sheet_mapping_id': statement_map.id, - }) - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + statement_map = self.sample_statement_map.copy( + { + "balance_column": "Balance", + "original_currency_column": None, + "original_amount_column": None, + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/balance.csv", + "data_file": self._data_file("fixtures/balance.csv", "utf-8"), + "sheet_mapping_id": statement_map.id, + } + ) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 2) self.assertEqual(statement.balance_start, 10.0) @@ -289,37 +300,40 @@ class TestAccountBankStatementImportTxtXlsx(common.TransactionCase): self.assertEqual(statement.balance_end, 1510.0) def test_debit_credit(self): - journal = self.AccountJournal.create({ - 'name': 'Bank', - 'type': 'bank', - 'code': 'BANK', - 'currency_id': self.currency_usd.id, - }) - statement_map = self.sample_statement_map.copy({ - 'balance_column': 'Balance', - 'original_currency_column': None, - 'original_amount_column': None, - 'debit_credit_column': 'D/C', - 'debit_value': 'D', - 'credit_value': 'C', - }) - wizard = self.AccountBankStatementImport.with_context({ - 'journal_id': journal.id, - }).create({ - 'filename': 'fixtures/debit_credit.csv', - 'data_file': self._data_file( - 'fixtures/debit_credit.csv', - 'utf-8' - ), - 'sheet_mapping_id': statement_map.id, - }) - wizard.with_context({ - 'journal_id': journal.id, - 'account_bank_statement_import_txt_xlsx_test': True, - }).import_file() - statement = self.AccountBankStatement.search([ - ('journal_id', '=', journal.id), - ]) + journal = self.AccountJournal.create( + { + "name": "Bank", + "type": "bank", + "code": "BANK", + "currency_id": self.currency_usd.id, + } + ) + statement_map = self.sample_statement_map.copy( + { + "balance_column": "Balance", + "original_currency_column": None, + "original_amount_column": None, + "debit_credit_column": "D/C", + "debit_value": "D", + "credit_value": "C", + } + ) + wizard = self.AccountBankStatementImport.with_context( + {"journal_id": journal.id,} + ).create( + { + "filename": "fixtures/debit_credit.csv", + "data_file": self._data_file("fixtures/debit_credit.csv", "utf-8"), + "sheet_mapping_id": statement_map.id, + } + ) + wizard.with_context( + { + "journal_id": journal.id, + "account_bank_statement_import_txt_xlsx_test": True, + } + ).import_file() + statement = self.AccountBankStatement.search([("journal_id", "=", journal.id),]) self.assertEqual(len(statement), 1) self.assertEqual(len(statement.line_ids), 2) self.assertEqual(statement.balance_start, 10.0) diff --git a/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import.xml b/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import.xml index 71e0e36e..b3e6ba5f 100644 --- a/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import.xml +++ b/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import.xml @@ -1,22 +1,23 @@ - + - account.bank.statement.import account.bank.statement.import - +
  • - TXT/CSV/XLSX mapping: + TXT/CSV/XLSX mapping:
  • -
    diff --git a/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import_sheet_mapping.xml b/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import_sheet_mapping.xml index 38eaa92b..e51cc274 100644 --- a/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import_sheet_mapping.xml +++ b/account_bank_statement_import_txt_xlsx/views/account_bank_statement_import_sheet_mapping.xml @@ -1,21 +1,19 @@ - + - account.bank.statement.import.sheet.mapping.form account.bank.statement.import.sheet.mapping - + - account.bank.statement.import.sheet.mapping.tree account.bank.statement.import.sheet.mapping @@ -23,60 +21,70 @@
    -
    - - + + - - - + + + - + - - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + +
    - - + Statement Sheet Mappings account.bank.statement.import.sheet.mapping form tree,form - -
    diff --git a/account_bank_statement_import_txt_xlsx/views/account_journal_views.xml b/account_bank_statement_import_txt_xlsx/views/account_journal_views.xml index 2686519c..92b17a96 100644 --- a/account_bank_statement_import_txt_xlsx/views/account_journal_views.xml +++ b/account_bank_statement_import_txt_xlsx/views/account_journal_views.xml @@ -1,16 +1,17 @@ - + - account.journal - + - - + + - diff --git a/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.py b/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.py index 115f1b73..3cda111d 100644 --- a/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.py +++ b/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.py @@ -2,145 +2,122 @@ # Copyright 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 AccountBankStatementImportSheetMappingWizard(models.TransientModel): - _name = 'account.bank.statement.import.sheet.mapping.wizard' - _description = 'Account Bank Statement Import Sheet Mapping Wizard' - _inherit = ['multi.step.wizard.mixin'] + _name = "account.bank.statement.import.sheet.mapping.wizard" + _description = "Account Bank Statement Import Sheet Mapping Wizard" + _inherit = ["multi.step.wizard.mixin"] - data_file = fields.Binary( - string='Bank Statement File', - required=True, - ) + data_file = fields.Binary(string="Bank Statement File", required=True,) filename = fields.Char() header = fields.Char() file_encoding = fields.Selection( - string='Encoding', - selection=lambda self: self._selection_file_encoding(), + string="Encoding", selection=lambda self: self._selection_file_encoding(), ) delimiter = fields.Selection( - string='Delimiter', - selection=lambda self: self._selection_delimiter(), - ) - quotechar = fields.Char( - string='Text qualifier', - size=1, - ) - timestamp_column = fields.Char( - string='Timestamp column', + string="Delimiter", selection=lambda self: self._selection_delimiter(), ) + quotechar = fields.Char(string="Text qualifier", size=1,) + timestamp_column = fields.Char(string="Timestamp column",) currency_column = fields.Char( - string='Currency column', + string="Currency column", help=( - 'In case statement is multi-currency, column to get currency of ' - 'transaction from' + "In case statement is multi-currency, column to get currency of " + "transaction from" ), ) amount_column = fields.Char( - string='Amount column', - help='Amount of transaction in journal\'s currency', + string="Amount column", help="Amount of transaction in journal's currency", ) balance_column = fields.Char( - string='Balance column', - help='Balance after transaction in journal\'s currency', + string="Balance column", help="Balance after transaction in journal's currency", ) original_currency_column = fields.Char( - string='Original currency column', + string="Original currency column", help=( - 'In case statement provides original currency for transactions ' - 'with automatic currency conversion, column to get original ' - 'currency of transaction from' + "In case statement provides original currency for transactions " + "with automatic currency conversion, column to get original " + "currency of transaction from" ), ) original_amount_column = fields.Char( - string='Original amount column', + string="Original amount column", help=( - 'In case statement provides original currency for transactions ' - 'with automatic currency conversion, column to get original ' - 'transaction amount in original transaction currency from' + "In case statement provides original currency for transactions " + "with automatic currency conversion, column to get original " + "transaction amount in original transaction currency from" ), ) debit_credit_column = fields.Char( - string='Debit/credit column', + string="Debit/credit column", help=( - 'Some statement formats use absolute amount value and indicate sign' - 'of the transaction by specifying if it was a debit or a credit one' + "Some statement formats use absolute amount value and indicate sign" + "of the transaction by specifying if it was a debit or a credit one" ), ) debit_value = fields.Char( - string='Debit value', - help='Value of debit/credit column that indicates if it\'s a debit', - default='D', + string="Debit value", + help="Value of debit/credit column that indicates if it's a debit", + default="D", ) credit_value = fields.Char( - string='Credit value', - help='Value of debit/credit column that indicates if it\'s a credit', - default='C', - ) - transaction_id_column = fields.Char( - string='Unique transaction ID column', - ) - description_column = fields.Char( - string='Description column', - ) - notes_column = fields.Char( - string='Notes column', - ) - reference_column = fields.Char( - string='Reference column', - ) - partner_name_column = fields.Char( - string='Partner Name column', - ) - bank_name_column = fields.Char( - string='Bank Name column', - help='Partner\'s bank', + string="Credit value", + help="Value of debit/credit column that indicates if it's a credit", + default="C", ) + transaction_id_column = fields.Char(string="Unique transaction ID column",) + description_column = fields.Char(string="Description column",) + notes_column = fields.Char(string="Notes column",) + reference_column = fields.Char(string="Reference column",) + partner_name_column = fields.Char(string="Partner Name column",) + bank_name_column = fields.Char(string="Bank Name column", help="Partner's bank",) bank_account_column = fields.Char( - string='Bank Account column', - help='Partner\'s bank account', + string="Bank Account column", help="Partner's bank account", ) @api.model def _selection_file_encoding(self): - return self.env['account.bank.statement.import.sheet.mapping']._fields[ - 'file_encoding' - ].selection + return ( + self.env["account.bank.statement.import.sheet.mapping"] + ._fields["file_encoding"] + .selection + ) @api.model def _selection_delimiter(self): - return self.env['account.bank.statement.import.sheet.mapping']._fields[ - 'delimiter' - ].selection + return ( + self.env["account.bank.statement.import.sheet.mapping"] + ._fields["delimiter"] + .selection + ) - @api.onchange('data_file') + @api.onchange("data_file") def _onchange_data_file(self): - Parser = self.env['account.bank.statement.import.sheet.parser'] - Mapping = self.env['account.bank.statement.import.sheet.mapping'] + Parser = self.env["account.bank.statement.import.sheet.parser"] + Mapping = self.env["account.bank.statement.import.sheet.mapping"] if not self.data_file: return csv_options = {} if self.delimiter: - csv_options['delimiter'] = \ - Mapping._decode_column_delimiter_character(self.delimiter) + csv_options["delimiter"] = Mapping._decode_column_delimiter_character( + self.delimiter + ) if self.quotechar: - csv_options['quotechar'] = self.quotechar + csv_options["quotechar"] = self.quotechar header = Parser.parse_header( - b64decode(self.data_file), - self.file_encoding, - csv_options + b64decode(self.data_file), self.file_encoding, csv_options ) self.header = json.dumps(header) @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)] @@ -150,42 +127,43 @@ class AccountBankStatementImportSheetMappingWizard(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', - 'file_encoding': self.file_encoding, - 'delimiter': self.delimiter, - 'quotechar': self.quotechar, - 'timestamp_format': '%d/%m/%Y', - 'timestamp_column': self.timestamp_column, - 'currency_column': self.currency_column, - 'amount_column': self.amount_column, - 'balance_column': self.balance_column, - 'original_currency_column': self.original_currency_column, - 'original_amount_column': self.original_amount_column, - 'debit_credit_column': self.debit_credit_column, - 'debit_value': self.debit_value, - 'credit_value': self.credit_value, - 'transaction_id_column': self.transaction_id_column, - 'description_column': self.description_column, - 'notes_column': self.notes_column, - 'reference_column': self.reference_column, - 'partner_name_column': self.partner_name_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", + "file_encoding": self.file_encoding, + "delimiter": self.delimiter, + "quotechar": self.quotechar, + "timestamp_format": "%d/%m/%Y", + "timestamp_column": self.timestamp_column, + "currency_column": self.currency_column, + "amount_column": self.amount_column, + "balance_column": self.balance_column, + "original_currency_column": self.original_currency_column, + "original_amount_column": self.original_amount_column, + "debit_credit_column": self.debit_credit_column, + "debit_value": self.debit_value, + "credit_value": self.credit_value, + "transaction_id_column": self.transaction_id_column, + "description_column": self.description_column, + "notes_column": self.notes_column, + "reference_column": self.reference_column, + "partner_name_column": self.partner_name_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.sheet.mapping']\ - .create(self._get_mapping_values()) + mapping = self.env["account.bank.statement.import.sheet.mapping"].create( + self._get_mapping_values() + ) return { - 'type': 'ir.actions.act_window', - 'name': _('Imported Mapping'), - 'res_model': 'account.bank.statement.import.sheet.mapping', - 'res_id': mapping.id, - 'view_mode': 'form', - 'view_id': False, - 'target': 'new', + "type": "ir.actions.act_window", + "name": _("Imported Mapping"), + "res_model": "account.bank.statement.import.sheet.mapping", + "res_id": mapping.id, + "view_mode": "form", + "view_id": False, + "target": "new", } diff --git a/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.xml b/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.xml index 9a5f372b..81b2eccb 100644 --- a/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.xml +++ b/account_bank_statement_import_txt_xlsx/wizards/account_bank_statement_import_sheet_mapping_wizard.xml @@ -1,33 +1,41 @@ - + - - - account.bank.statement.import.sheet.mapping.wizard.form + + account.bank.statement.import.sheet.mapping.wizard.form account.bank.statement.import.sheet.mapping.wizard primary - +

    Select a statement file to import mapping

    - - + + - - - + + + - + - - - + + +
    @@ -126,11 +144,15 @@ Cancel -