optinmamanagementvue/kolanalystapp/reportquery.py

121 lines
3.5 KiB
Python
Raw Permalink Normal View History

2024-09-02 04:58:52 +00:00
import frappe
import json
from functools import lru_cache
from sql_metadata import Parser
import frappe
import frappe.permissions
from frappe import _
from frappe.core.doctype.access_log.access_log import make_access_log
from frappe.model import child_table_fields, default_fields, get_permitted_fields, optional_fields
from frappe.model.base_document import get_controller
from frappe.model.db_query import DatabaseQuery
from frappe.model.utils import is_virtual_doctype
from frappe.utils import add_user_info, cint, format_duration
from frappe.utils.data import sbool
@frappe.whitelist()
@frappe.read_only()
def export_query():
"""export from report builder"""
from frappe.desk.utils import get_csv_bytes, pop_csv_params, provide_binary_file
form_params = get_form_params()
form_params["limit_page_length"] = None
form_params["as_list"] = True
doctype = form_params.pop("doctype")
file_format_type = form_params.pop("file_format_type")
title = form_params.pop("title", doctype)
csv_params = pop_csv_params(form_params)
add_totals_row = 1 if form_params.pop("add_totals_row", None) == "1" else None
frappe.permissions.can_export(doctype, raise_exception=True)
if selection := form_params.pop("selected_items", None):
form_params["filters"] = {"name": ("in", json.loads(selection))}
make_access_log(
doctype=doctype,
file_type=file_format_type,
report_name=form_params.report_name,
filters=form_params.filters,
)
db_query = DatabaseQuery(doctype)
ret = frappe.get_list(doctype)
if add_totals_row:
ret = append_totals_row(ret)
# //data = [[_("Sr"), *get_labels(fields, doctype)]]
data.extend([i + 1, *list(row)] for i, row in enumerate(ret.value))
data = handle_duration_fieldtype_values(doctype, data, db_query.fields)
if file_format_type == "CSV":
from frappe.utils.xlsxutils import handle_html
file_extension = "csv"
content = get_csv_bytes(
[[handle_html(frappe.as_unicode(v)) if isinstance(v, str) else v for v in r] for r in data],
csv_params,
)
elif file_format_type == "Excel":
from frappe.utils.xlsxutils import make_xlsx
file_extension = "xlsx"
content = make_xlsx(data, doctype).getvalue()
provide_binary_file(title, file_extension, content)
def get_form_params():
"""parse GET request parameters."""
data = frappe._dict(frappe.local.form_dict)
# clean_params(data)
# validate_args(data)
return data
def get_labels(fields, doctype):
"""get column labels based on column names"""
labels = []
for key in fields:
try:
parenttype, fieldname = parse_field(key)
except ValueError:
continue
parenttype = parenttype or doctype
if parenttype == doctype and fieldname == "name":
label = _("ID", context="Label of name column in report")
else:
df = frappe.get_meta(parenttype).get_field(fieldname)
label = _(df.label if df else fieldname.title())
if parenttype != doctype:
# If the column is from a child table, append the child doctype.
# For example, "Item Code (Sales Invoice Item)".
label += f" ({ _(parenttype) })"
labels.append(label)
return labels
def handle_duration_fieldtype_values(doctype, data, fields):
for field in fields:
try:
parenttype, fieldname = parse_field(field)
except ValueError:
continue
parenttype = parenttype or doctype
df = frappe.get_meta(parenttype).get_field(fieldname)
if df and df.fieldtype == "Duration":
index = fields.index(field) + 1
for i in range(1, len(data)):
val_in_seconds = data[i][index]
if val_in_seconds:
duration_val = format_duration(val_in_seconds, df.hide_days)
data[i][index] = duration_val
return data