refactor(query_report): simplify excel export logicversion-14
@@ -352,14 +352,10 @@ def export_query(): | |||||
) | ) | ||||
return | return | ||||
columns = get_columns_dict(data.columns) | |||||
from frappe.utils.xlsxutils import make_xlsx | 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) | xlsx_file = make_xlsx(xlsx_data, "Query Report", column_widths=column_widths) | ||||
frappe.response["filename"] = report_name + ".xlsx" | frappe.response["filename"] = report_name + ".xlsx" | ||||
@@ -367,39 +363,18 @@ def export_query(): | |||||
frappe.response["type"] = "binary" | 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 = [[]] | result = [[]] | ||||
column_widths = [] | column_widths = [] | ||||
@@ -104,7 +104,7 @@ class AutoEmailReport(Document): | |||||
report_data['columns'] = columns | report_data['columns'] = columns | ||||
report_data['result'] = data | 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) | xlsx_file = make_xlsx(xlsx_data, "Auto Email Report", column_widths=column_widths) | ||||
return xlsx_file.getvalue() | return xlsx_file.getvalue() | ||||
@@ -113,7 +113,7 @@ class AutoEmailReport(Document): | |||||
report_data['columns'] = columns | report_data['columns'] = columns | ||||
report_data['result'] = data | 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) | return to_csv(xlsx_data) | ||||
else: | else: | ||||
@@ -12,37 +12,30 @@ class TestQueryReport(unittest.TestCase): | |||||
def test_xlsx_data_with_multiple_datatypes(self): | def test_xlsx_data_with_multiple_datatypes(self): | ||||
"""Test exporting report using rows with multiple datatypes (list, dict)""" | """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 | # Create mock data | ||||
data = frappe._dict() | data = frappe._dict() | ||||
data.columns = [ | 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 = [ | 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 | # Define the visible rows | ||||
visible_idx = [0, 2, 3] | visible_idx = [0, 2, 3] | ||||
# Build the result | # 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(type(xlsx_data), list) | ||||
self.assertEqual(len(xlsx_data), 4) # columns + data | self.assertEqual(len(xlsx_data), 4) # columns + data | ||||
# column widths are divided by 10 to match the scale that is supported by openpyxl | # 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: | for row in xlsx_data: | ||||
self.assertEqual(type(row), list) | self.assertEqual(type(row), list) |