From bb47930f74de1be659d5f93171dfdc4bef5f3f21 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Mon, 13 Jan 2025 09:10:32 -0500 Subject: [PATCH 1/2] [FIX] account_statement_import_sheet_file: Prevent negative index in parser header When importing an Excel file with a header and the field header_lines_skip_count is set to its default value (0), the header is retrieved using the -1 index (the last row). complementary to commit https://github.com/OCA/bank-statement-import/commit/13285abe74d326153c8d0e74c21ddbdf3cdf17a0 --- .../models/account_statement_import_sheet_parser.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py b/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py index a9be621d9..7062f6aec 100644 --- a/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py +++ b/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py @@ -179,7 +179,10 @@ def _parse_lines(self, mapping, data_file, currency_code): csv_or_xlsx = reader(StringIO(decoded_file), **csv_options) header = False if not mapping.no_header: - header_line = mapping.header_lines_skip_count - 1 + header_line = mapping.header_lines_skip_count + # prevent negative indexes + if header_line > 0: + header_line -= 1 if isinstance(csv_or_xlsx, tuple): header = [ str(value).strip() From 6deab7c481d5f363d9306ba1b5f73a2487da2126 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Mon, 13 Jan 2025 10:20:49 -0500 Subject: [PATCH 2/2] [IMP] account_statement_import_sheet_file: Use parse_header and fine-tune the UI Before this commit, the parse_header function was unused. It is now utilized to reduce redundant code and improve maintainability. Additionally, UI adjustments have been made for better usability and clarity. --- .../account_statement_import_sheet_parser.py | 49 +++++++------------ ...account_statement_import_sheet_mapping.xml | 1 + 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py b/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py index 7062f6aec..5e788ee7b 100644 --- a/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py +++ b/account_statement_import_sheet_file/models/account_statement_import_sheet_parser.py @@ -39,22 +39,22 @@ class AccountStatementImportSheetParser(models.TransientModel): _description = "Bank Statement Import Sheet Parser" @api.model - def parse_header(self, data_file, encoding, csv_options, header_lines_skip_count=0): - try: - workbook = xlrd.open_workbook( - file_contents=data_file, - encoding_override=encoding if encoding else None, - ) - sheet = workbook.sheet_by_index(0) - values = sheet.row_values(header_lines_skip_count - 1) - return [str(value) for value in values] - except xlrd.XLRDError: - _logger.error("Pass this method") - - data = StringIO(data_file.decode(encoding or "utf-8")) - csv_data = reader(data, **csv_options) - csv_data_lst = list(csv_data) - header = [value.strip() for value in csv_data_lst[header_lines_skip_count - 1]] + def parse_header(self, csv_or_xlsx, mapping): + if mapping.no_header: + return [] + header_line = mapping.header_lines_skip_count + # prevent negative indexes + if header_line > 0: + header_line -= 1 + if isinstance(csv_or_xlsx, tuple): + header = [ + str(value).strip() for value in csv_or_xlsx[1].row_values(header_line) + ] + else: + [next(csv_or_xlsx) for _i in range(header_line)] + header = [value.strip() for value in next(csv_or_xlsx)] + if mapping.offset_column: + header = header[mapping.offset_column :] return header @api.model @@ -177,22 +177,7 @@ def _parse_lines(self, mapping, data_file, currency_code): ) from None decoded_file = data_file.decode(detected_encoding) csv_or_xlsx = reader(StringIO(decoded_file), **csv_options) - header = False - if not mapping.no_header: - header_line = mapping.header_lines_skip_count - # prevent negative indexes - if header_line > 0: - header_line -= 1 - if isinstance(csv_or_xlsx, tuple): - header = [ - str(value).strip() - for value in csv_or_xlsx[1].row_values(header_line) - ] - else: - [next(csv_or_xlsx) for _i in range(header_line)] - header = [value.strip() for value in next(csv_or_xlsx)] - if mapping.offset_column: - header = header[mapping.offset_column :] + header = self.parse_header(csv_or_xlsx, mapping) # NOTE no seria necesario debit_column y credit_column ya que tenemos los # respectivos campos related diff --git a/account_statement_import_sheet_file/views/account_statement_import_sheet_mapping.xml b/account_statement_import_sheet_file/views/account_statement_import_sheet_mapping.xml index 8a9ec8d35..1483238ea 100644 --- a/account_statement_import_sheet_file/views/account_statement_import_sheet_mapping.xml +++ b/account_statement_import_sheet_file/views/account_statement_import_sheet_mapping.xml @@ -44,6 +44,7 @@