refactor(query_report): simplify excel export logicversion-14
@@ -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 = [] | |||
@@ -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: | |||
@@ -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) |