diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index b344763916..f5f50b14fe 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -352,14 +352,10 @@ def export_query(): ) return - columns = get_columns_dict(data.columns) - from frappe.utils.xlsxutils import make_xlsx - data["result"] = handle_duration_fieldtype_values( - data.get("result"), data.get("columns") - ) - xlsx_data, column_widths = build_xlsx_data(columns, data, visible_idx, include_indentation) + format_duration_fields(data) + xlsx_data, column_widths = build_xlsx_data(data, visible_idx, include_indentation) xlsx_file = make_xlsx(xlsx_data, "Query Report", column_widths=column_widths) frappe.response["filename"] = report_name + ".xlsx" @@ -367,39 +363,18 @@ def export_query(): frappe.response["type"] = "binary" -def handle_duration_fieldtype_values(result, columns): - for i, col in enumerate(columns): - fieldtype = None - if isinstance(col, str): - col = col.split(":") - if len(col) > 1: - if col[1]: - fieldtype = col[1] - if "/" in fieldtype: - fieldtype, options = fieldtype.split("/") - else: - fieldtype = "Data" - else: - fieldtype = col.get("fieldtype") - - if fieldtype == "Duration": - for entry in range(0, len(result)): - row = result[entry] - if isinstance(row, dict): - val_in_seconds = row[col.fieldname] - if val_in_seconds: - duration_val = format_duration(val_in_seconds) - row[col.fieldname] = duration_val - else: - val_in_seconds = row[i] - if val_in_seconds: - duration_val = format_duration(val_in_seconds) - row[i] = duration_val +def format_duration_fields(data: frappe._dict) -> None: + for i, col in enumerate(data.columns): + if col.get("fieldtype") != "Duration": + continue - return result + for row in data.result: + index = col.fieldname if isinstance(row, dict) else i + if row[index]: + row[index] = format_duration(row[index]) -def build_xlsx_data(columns, data, visible_idx, include_indentation, ignore_visible_idx=False): +def build_xlsx_data(data, visible_idx, include_indentation, ignore_visible_idx=False): result = [[]] column_widths = [] diff --git a/frappe/email/doctype/auto_email_report/auto_email_report.py b/frappe/email/doctype/auto_email_report/auto_email_report.py index 682f0df7cf..5ffde0c37b 100644 --- a/frappe/email/doctype/auto_email_report/auto_email_report.py +++ b/frappe/email/doctype/auto_email_report/auto_email_report.py @@ -104,7 +104,7 @@ class AutoEmailReport(Document): report_data['columns'] = columns report_data['result'] = data - xlsx_data, column_widths = build_xlsx_data(columns, report_data, [], 1, ignore_visible_idx=True) + xlsx_data, column_widths = build_xlsx_data(report_data, [], 1, ignore_visible_idx=True) xlsx_file = make_xlsx(xlsx_data, "Auto Email Report", column_widths=column_widths) return xlsx_file.getvalue() @@ -113,7 +113,7 @@ class AutoEmailReport(Document): report_data['columns'] = columns report_data['result'] = data - xlsx_data, column_widths = build_xlsx_data(columns, report_data, [], 1, ignore_visible_idx=True) + xlsx_data, column_widths = build_xlsx_data(report_data, [], 1, ignore_visible_idx=True) return to_csv(xlsx_data) else: diff --git a/frappe/tests/test_query_report.py b/frappe/tests/test_query_report.py index 656894fc9b..2117bc830e 100644 --- a/frappe/tests/test_query_report.py +++ b/frappe/tests/test_query_report.py @@ -12,37 +12,30 @@ class TestQueryReport(unittest.TestCase): def test_xlsx_data_with_multiple_datatypes(self): """Test exporting report using rows with multiple datatypes (list, dict)""" - # Describe the columns - columns = { - 0: {"label": "Column A", "fieldname": "column_a"}, - 1: {"label": "Column B", "fieldname": "column_b"}, - 2: {"label": "Column C", "fieldname": "column_c"} - } - # Create mock data data = frappe._dict() data.columns = [ - {"label": "Column A", "fieldname": "column_a"}, - {"label": "Column B", "fieldname": "column_b", "width": 150}, - {"label": "Column C", "fieldname": "column_c", "width": 100} + {"label": "Column A", "fieldname": "column_a", "fieldtype": "Float"}, + {"label": "Column B", "fieldname": "column_b", "width": 100, "fieldtype": "Float"}, + {"label": "Column C", "fieldname": "column_c", "width": 150, "fieldtype": "Duration"}, ] data.result = [ - [1.0, 3.0, 5.5], - {"column_a": 22.1, "column_b": 21.8, "column_c": 30.2}, - {"column_b": 5.1, "column_c": 9.5, "column_a": 11.1}, - [3.0, 1.5, 7.5], + [1.0, 3.0, 600], + {"column_a": 22.1, "column_b": 21.8, "column_c": 86412}, + {"column_b": 5.1, "column_c": 53234, "column_a": 11.1}, + [3.0, 1.5, 333], ] # Define the visible rows visible_idx = [0, 2, 3] # Build the result - xlsx_data, column_widths = build_xlsx_data(columns, data, visible_idx, include_indentation=0) + xlsx_data, column_widths = build_xlsx_data(data, visible_idx, include_indentation=0) self.assertEqual(type(xlsx_data), list) self.assertEqual(len(xlsx_data), 4) # columns + data # column widths are divided by 10 to match the scale that is supported by openpyxl - self.assertListEqual(column_widths, [0, 15, 10]) + self.assertListEqual(column_widths, [0, 10, 15]) for row in xlsx_data: self.assertEqual(type(row), list)