121 lines
3.5 KiB
Python
121 lines
3.5 KiB
Python
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 |