feat: Allow user to save custom reports
This commit is contained in:
parent
80f2865885
commit
af0c373c8a
4 changed files with 174 additions and 14 deletions
|
|
@ -17,6 +17,9 @@ frappe.ui.form.on('Report', {
|
|||
case "Script Report":
|
||||
frappe.set_route("query-report", doc.name);
|
||||
break;
|
||||
case "Custom Report":
|
||||
frappe.set_route("query-report", doc.name);
|
||||
break;
|
||||
}
|
||||
}, "fa fa-table");
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,39 @@
|
|||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "reference_report",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Report",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
|
|
@ -228,7 +261,7 @@
|
|||
"label": "Report Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Report Builder\nQuery Report\nScript Report",
|
||||
"options": "Report Builder\nQuery Report\nScript Report\nCustom Report",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
|
|
@ -479,7 +512,7 @@
|
|||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.report_type==\"Report Builder\"",
|
||||
"depends_on": "eval:doc.report_type==\"Report Builder\" || \"Custom Report\"",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "json",
|
||||
"fieldtype": "Code",
|
||||
|
|
@ -642,17 +675,15 @@
|
|||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-04-07 20:32:30.943582",
|
||||
"modified": "2019-04-12 15:53:14.194591",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Report",
|
||||
|
|
@ -737,7 +768,6 @@
|
|||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,15 @@ from datetime import timedelta
|
|||
from frappe.utils import gzip_decompress
|
||||
|
||||
def get_report_doc(report_name):
|
||||
|
||||
custom_report = custom_columns = frappe.db.get_value("Report",
|
||||
{'report_name':report_name, 'is_standard': 'No', 'report_type': 'Custom Report'},
|
||||
['reference_report', 'json']
|
||||
)
|
||||
|
||||
if custom_report:
|
||||
report_name, custom_columns = custom_report[0], custom_report[1]
|
||||
|
||||
doc = frappe.get_doc("Report", report_name)
|
||||
if not doc.is_permitted():
|
||||
frappe.throw(_("You don't have access to Report: {0}").format(report_name), frappe.PermissionError)
|
||||
|
|
@ -29,10 +38,10 @@ def get_report_doc(report_name):
|
|||
if doc.disabled:
|
||||
frappe.throw(_("Report {0} is disabled").format(report_name))
|
||||
|
||||
return doc
|
||||
return doc, custom_columns
|
||||
|
||||
|
||||
def generate_report_result(report, filters=None, user=None):
|
||||
def generate_report_result(report, filters=None, user=None, custom_columns=None):
|
||||
status = None
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
|
@ -81,6 +90,11 @@ def generate_report_result(report, filters=None, user=None):
|
|||
if len(res) > 4:
|
||||
data_to_be_printed = res[4]
|
||||
|
||||
|
||||
if custom_columns:
|
||||
columns = json.loads(custom_columns)
|
||||
result = add_data_to_custom_columns(columns, result)
|
||||
|
||||
if result:
|
||||
result = get_filtered_data(report.ref_doctype, columns, result, user)
|
||||
|
||||
|
|
@ -102,7 +116,7 @@ def background_enqueue_run(report_name, filters=None, user=None):
|
|||
"""run reports in background"""
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
report = get_report_doc(report_name)
|
||||
report, _ = get_report_doc(report_name)
|
||||
track_instance = \
|
||||
frappe.get_doc({
|
||||
"doctype": "Prepared Report",
|
||||
|
|
@ -125,8 +139,7 @@ def background_enqueue_run(report_name, filters=None, user=None):
|
|||
|
||||
@frappe.whitelist()
|
||||
def get_script(report_name):
|
||||
report = get_report_doc(report_name)
|
||||
|
||||
report, _ = get_report_doc(report_name)
|
||||
module = report.module or frappe.db.get_value("DocType", report.ref_doctype, "module")
|
||||
module_path = get_module_path(module)
|
||||
report_folder = os.path.join(module_path, "report", scrub(report.name))
|
||||
|
|
@ -161,7 +174,7 @@ def get_script(report_name):
|
|||
@frappe.read_only()
|
||||
def run(report_name, filters=None, user=None):
|
||||
|
||||
report = get_report_doc(report_name)
|
||||
report, custom_columns = get_report_doc(report_name)
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
if not frappe.has_permission(report.ref_doctype, "report"):
|
||||
|
|
@ -181,12 +194,37 @@ def run(report_name, filters=None, user=None):
|
|||
dn = ""
|
||||
result = get_prepared_report_result(report, filters, dn, user)
|
||||
else:
|
||||
result = generate_report_result(report, filters, user)
|
||||
result = generate_report_result(report, filters, user, custom_columns)
|
||||
|
||||
result["add_total_row"] = report.add_total_row
|
||||
|
||||
return result
|
||||
|
||||
def add_data_to_custom_columns(columns, result):
|
||||
|
||||
custom_fields_data = get_data_for_custom_report(columns)
|
||||
|
||||
data = []
|
||||
for row in result:
|
||||
row_obj = {}
|
||||
if isinstance(row, list):
|
||||
for idx, column in enumerate(columns):
|
||||
if column.get('link_field'):
|
||||
row_obj[column['fieldname']] = None
|
||||
row.insert(idx,None)
|
||||
else:
|
||||
row_obj[column['fieldname']] = row[idx]
|
||||
data.append(row_obj)
|
||||
else:
|
||||
data.append(row)
|
||||
|
||||
for row in data:
|
||||
for column in columns:
|
||||
if column.get('link_field'):
|
||||
row[column['fieldname']] = \
|
||||
custom_fields_data.get((column['doctype'], column['fieldname']), {}).get(row[column['link_field']])
|
||||
|
||||
return data
|
||||
|
||||
def get_prepared_report_result(report, filters, dn="", user=None):
|
||||
latest_report_data = {}
|
||||
|
|
@ -362,6 +400,44 @@ def get_data_for_custom_field(doctype, field):
|
|||
|
||||
return value_map
|
||||
|
||||
def get_data_for_custom_report(columns):
|
||||
doc_field_value_map = {}
|
||||
|
||||
for column in columns:
|
||||
if column.get('link_field'):
|
||||
fieldname = column.get('fieldname')
|
||||
doctype = column.get('doctype')
|
||||
doc_field_value_map[(doctype, fieldname)] = get_data_for_custom_field(doctype, fieldname)
|
||||
|
||||
return doc_field_value_map
|
||||
|
||||
@frappe.whitelist()
|
||||
def save_report(reference_report, report_name, columns):
|
||||
|
||||
report_doc, _ = get_report_doc(reference_report)
|
||||
|
||||
docname = frappe.db.exists("Report", report_name)
|
||||
if docname:
|
||||
report = frappe.get_doc("Report", {'report_name':docname, 'is_standard': 'No', 'report_type': 'Custom Report'})
|
||||
report.update({"json": columns})
|
||||
report.save()
|
||||
frappe.msgprint("Report updated successfully")
|
||||
|
||||
return docname
|
||||
else:
|
||||
new_report = frappe.get_doc({
|
||||
'doctype': 'Report',
|
||||
'report_name': report_name,
|
||||
'json': columns,
|
||||
'ref_doctype': report_doc.ref_doctype,
|
||||
'is_standard': 'No',
|
||||
'report_type': 'Custom Report',
|
||||
'reference_report': reference_report
|
||||
}).insert(ignore_permissions = True)
|
||||
frappe.msgprint("{0} saved successfully".format(new_report.name))
|
||||
return new_report.name
|
||||
|
||||
|
||||
def get_filtered_data(ref_doctype, columns, data, user):
|
||||
result = []
|
||||
linked_doctypes = get_linked_doctypes(columns, data)
|
||||
|
|
|
|||
|
|
@ -110,9 +110,21 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
this.page_name = frappe.get_route_str();
|
||||
this.report_name = this.route[1];
|
||||
this.page_title = __(this.report_name);
|
||||
this.show_save = false;
|
||||
this.menu_items = this.get_menu_items();
|
||||
this.datatable = null;
|
||||
this.prepared_report_action = "New";
|
||||
this.custom_report = null;
|
||||
|
||||
frappe.db.get_value("Report",
|
||||
{"report_name": this.report_name},
|
||||
'reference_report', (r) => {
|
||||
if (r.reference_report){
|
||||
this.custom_report = this.report_name;
|
||||
this.report_name = r.reference_report;
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
frappe.run_serially([
|
||||
() => this.get_report_doc(),
|
||||
|
|
@ -289,7 +301,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
method: 'frappe.desk.query_report.run',
|
||||
type: 'GET',
|
||||
args: {
|
||||
report_name: this.report_name,
|
||||
report_name: this.custom_report || this.report_name,
|
||||
filters: filters,
|
||||
},
|
||||
callback: resolve,
|
||||
|
|
@ -1003,8 +1015,11 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
fieldname: df.fieldname,
|
||||
fieldtype: df.fieldtype,
|
||||
label: df.label,
|
||||
link_field: this.doctype_field_map[values.doctype],
|
||||
doctype: values.doctype,
|
||||
width: 100
|
||||
});
|
||||
|
||||
frappe.call({
|
||||
method: 'frappe.desk.query_report.get_data_for_custom_field',
|
||||
args: {
|
||||
|
|
@ -1018,6 +1033,8 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
d.hide();
|
||||
}
|
||||
});
|
||||
this.show_save = true;
|
||||
this.set_menu_items()
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -1025,6 +1042,40 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
},
|
||||
standard: true
|
||||
},
|
||||
{
|
||||
label: __('Save'),
|
||||
action: () => {
|
||||
let d = new frappe.ui.Dialog({
|
||||
title: __('Save Reports'),
|
||||
fields: [
|
||||
{
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'report_name',
|
||||
label: __("Report Name"),
|
||||
default: this.report_doc.is_standard == 'No' ? this.custom_report : "",
|
||||
}
|
||||
],
|
||||
primary_action: (values) => {
|
||||
frappe.call({
|
||||
method: "frappe.desk.query_report.save_report",
|
||||
args: {
|
||||
reference_report: this.report_name,
|
||||
report_name: values.report_name,
|
||||
columns: this.columns
|
||||
},
|
||||
callback: function(r) {
|
||||
this.show_save = false;
|
||||
d.hide();
|
||||
frappe.set_route('query-report', r.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
d.show()
|
||||
},
|
||||
condition: () => this.show_save,
|
||||
standard: true
|
||||
},
|
||||
{
|
||||
label: __('User Permissions'),
|
||||
action: () => frappe.set_route('List', 'User Permission', {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue