feat:Addition of custom fields in query reports
This commit is contained in:
parent
ff6cf8c3e3
commit
f4061acf90
2 changed files with 133 additions and 41 deletions
|
|
@ -17,6 +17,7 @@ from six import string_types, iteritems
|
|||
from datetime import timedelta
|
||||
from frappe.utils.file_manager import get_file
|
||||
from frappe.utils import gzip_decompress
|
||||
from frappe.model import no_value_fields
|
||||
|
||||
def get_report_doc(report_name):
|
||||
doc = frappe.get_doc("Report", report_name)
|
||||
|
|
@ -33,7 +34,7 @@ def get_report_doc(report_name):
|
|||
return doc
|
||||
|
||||
|
||||
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
|
||||
|
|
@ -83,10 +84,10 @@ def generate_report_result(report, filters=None, user=None):
|
|||
data_to_be_printed = res[4]
|
||||
|
||||
if result:
|
||||
result, columns = get_filtered_data(report.ref_doctype, columns, result, user, report.add_custom_fields_in_report)
|
||||
result, columns = get_filtered_data(report.ref_doctype, columns, result, user, custom_columns)
|
||||
|
||||
# if cint(report.add_total_row) and result:
|
||||
# result = add_total_row(result, columns)
|
||||
if cint(report.add_total_row) and result:
|
||||
result = add_total_row(result, columns)
|
||||
|
||||
return {
|
||||
"result": result,
|
||||
|
|
@ -160,7 +161,7 @@ def get_script(report_name):
|
|||
|
||||
@frappe.whitelist()
|
||||
@frappe.read_only()
|
||||
def run(report_name, filters=None, user=None):
|
||||
def run(report_name, filters=None, user=None, custom_columns=None):
|
||||
|
||||
report = get_report_doc(report_name)
|
||||
if not user:
|
||||
|
|
@ -182,7 +183,7 @@ 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
|
||||
|
||||
|
|
@ -353,8 +354,27 @@ def add_total_row(result, columns, meta = None):
|
|||
result.append(total_row)
|
||||
return result
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_custom_fields(doctypes):
|
||||
|
||||
def get_filtered_data(ref_doctype, columns, data, user, add_custom_fields):
|
||||
field_map = []
|
||||
|
||||
doclist = json.loads(doctypes)
|
||||
|
||||
for d in doclist:
|
||||
fieldlist = [f.label for f in frappe.get_meta(d).fields \
|
||||
if f.label and f.fieldname and f.fieldname not in no_value_fields
|
||||
and f.fieldname not in ["naming_series"]
|
||||
and f.fieldtype not in ["Section Break", "Column Break", "Table"]]
|
||||
|
||||
field_map.append({
|
||||
"doctype": d,
|
||||
"fields": fieldlist
|
||||
})
|
||||
|
||||
return field_map
|
||||
|
||||
def get_filtered_data(ref_doctype, columns, data, user, custom_columns):
|
||||
result = []
|
||||
linked_doctypes = get_linked_doctypes(columns, data)
|
||||
match_filters_per_doctype = get_user_match_filters(linked_doctypes, user=user)
|
||||
|
|
@ -364,45 +384,42 @@ def get_filtered_data(ref_doctype, columns, data, user, add_custom_fields):
|
|||
role_permissions = get_role_permissions(frappe.get_meta(ref_doctype), user)
|
||||
if_owner = role_permissions.get("if_owner", {}).get("report")
|
||||
|
||||
doc_fields_map = {}
|
||||
custom_field_value_map = {}
|
||||
if custom_columns:
|
||||
custom_field_value_map = {}
|
||||
fields = json.loads(custom_columns)
|
||||
custom_field_list = []
|
||||
|
||||
if add_custom_fields:
|
||||
for doctype, field_list in iteritems(fields):
|
||||
values = frappe.db.sql("select name, {fields} from `tab{doctype}` "
|
||||
.format(fields = ", ".join(field_list), doctype=doctype), as_dict=1)
|
||||
|
||||
fields = frappe.db.sql(""" select dt, fieldname, fieldtype from `tabCustom Field`
|
||||
where fieldtype not in ('Section Break', 'Column Break') and
|
||||
dt in (%s)""" % ', '.join(['%s']* len(linked_doctypes)), tuple([doctype for doctype in linked_doctypes.keys()]), as_dict=1)
|
||||
|
||||
for d in fields:
|
||||
doc_fields_map.setdefault(d.dt, [])
|
||||
doc_fields_map.get(d.dt).append(d.fieldname)
|
||||
|
||||
columns.append({
|
||||
"label": frappe.unscrub(d.fieldname),
|
||||
"fieldname": d.filedname,
|
||||
"fieldtype": d.fieldtype,
|
||||
"width": 100
|
||||
custom_field_list += field_list
|
||||
for field in field_list:
|
||||
columns.append({
|
||||
"label": frappe.unscrub(field),
|
||||
"fieldname": field,
|
||||
"fieldtype": "Data",
|
||||
"width": 100
|
||||
})
|
||||
|
||||
for doctype in linked_doctypes.keys():
|
||||
if doc_fields_map.get(doctype):
|
||||
values = frappe.db.sql("select name, {fields} from `tab{doctype}` "
|
||||
.format(fields = ", ".join(doc_fields_map.get(doctype)), doctype=doctype), as_dict=1)
|
||||
for value in values:
|
||||
custom_field_value_map.setdefault(value.name, value)
|
||||
|
||||
for value in values:
|
||||
custom_field_value_map.setdefault(value.name, value)
|
||||
columns_dict = get_columns_dict(columns)
|
||||
columns_idx_map = [columns_dict.get(i) for i in range(len(columns))]
|
||||
|
||||
for row in data:
|
||||
for index, column in enumerate(columns):
|
||||
print(index,column)
|
||||
if isinstance(row, dict) and column.get("fieldtype") == "Link":
|
||||
fieldname = column.get("fieldname")
|
||||
row.update({ "test_field": custom_field_value_map.get(row.get(fieldname),{}).get("test_field")})
|
||||
else:
|
||||
print("$$$$$$$$$$")
|
||||
custom_field_value_map.get(row[index],{})
|
||||
row.append(custom_field_value_map.get(row[index],{}).get("test_field"))
|
||||
|
||||
for index, column in enumerate(columns_idx_map):
|
||||
for d in custom_field_list:
|
||||
if column.get("fieldtype") == "Link" or column.get("fieldtype") == "Dynamic Link":
|
||||
if isinstance(row, dict):
|
||||
fieldname = column.get("fieldname")
|
||||
row.update({ fieldname: custom_field_value_map.get(row.get(fieldname),{}).get(d)})
|
||||
else:
|
||||
fieldname = column.get("fieldname")
|
||||
value = custom_field_value_map.get(row[index],{}).get(d)
|
||||
if value:
|
||||
row.append(value)
|
||||
|
||||
if match_filters_per_doctype:
|
||||
for row in data:
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
this.page.clear_fields();
|
||||
}
|
||||
|
||||
refresh() {
|
||||
refresh(values) {
|
||||
this.toggle_message(true);
|
||||
let filters = this.get_filter_values(true);
|
||||
let query = frappe.utils.get_query_string(frappe.get_route_str());
|
||||
|
|
@ -291,6 +291,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
args: {
|
||||
report_name: this.report_name,
|
||||
filters: filters,
|
||||
custom_columns: values
|
||||
},
|
||||
callback: resolve,
|
||||
always: () => this.page.btn_secondary.prop('disabled', false)
|
||||
|
|
@ -418,7 +419,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
this.raw_data = data;
|
||||
this.columns = this.prepare_columns(data.columns);
|
||||
this.data = this.prepare_data(data.result);
|
||||
|
||||
this.custom_fields = this.get_dialog_fields();
|
||||
this.tree_report = this.data.some(d => 'indent' in d);
|
||||
}
|
||||
|
||||
|
|
@ -962,6 +963,22 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
action: () => frappe.set_route('List', 'Auto Email Report', {'report' : this.report_name}),
|
||||
standard: true
|
||||
},
|
||||
{
|
||||
label: __('Add Custom Fields'),
|
||||
action: () => {
|
||||
const d = new frappe.ui.Dialog({
|
||||
title: __('Add Custom Fields'),
|
||||
fields: this.custom_fields,
|
||||
primary_action: (values) => {
|
||||
this.refresh(values);
|
||||
d.hide();
|
||||
}
|
||||
});
|
||||
|
||||
d.show();
|
||||
},
|
||||
standard: true
|
||||
},
|
||||
{
|
||||
label: __('User Permissions'),
|
||||
action: () => frappe.set_route('List', 'User Permission', {
|
||||
|
|
@ -979,6 +996,64 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
];
|
||||
}
|
||||
|
||||
get_linked_doctypes() {
|
||||
|
||||
let doctypes = [];
|
||||
let dynamic_links = [];
|
||||
let dynamic_doctypes = new Set();
|
||||
|
||||
this.columns.forEach(df => {
|
||||
if (df.fieldtype == "Link" && df.options) {
|
||||
doctypes.push(df.options);
|
||||
}
|
||||
else if (df.fieldtype == "Dynamic Link" && df.options) {
|
||||
dynamic_links.push(df.options);
|
||||
}
|
||||
});
|
||||
|
||||
this.data.forEach(row => {
|
||||
dynamic_links.forEach(field => {
|
||||
if (row[field]){
|
||||
dynamic_doctypes.add(row[field]);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
doctypes = doctypes.concat(Array.from(dynamic_doctypes));
|
||||
|
||||
return doctypes;
|
||||
}
|
||||
|
||||
get_dialog_fields() {
|
||||
var dialog_fields = [];
|
||||
const linked_doctypes = this.get_linked_doctypes();
|
||||
|
||||
frappe.call({
|
||||
method: "frappe.desk.query_report.get_custom_fields",
|
||||
args: {
|
||||
doctypes: linked_doctypes
|
||||
},
|
||||
callback: function(r) {
|
||||
r.message.forEach(df => {
|
||||
dialog_fields.push({
|
||||
label: __(df.doctype),
|
||||
fieldname: df.doctype,
|
||||
fieldtype: 'MultiCheck',
|
||||
columns: 2,
|
||||
options: df.fields
|
||||
.map(f => ({
|
||||
label: __(f),
|
||||
value: f ? frappe.scrub(f) : null,
|
||||
checked: 0
|
||||
}))
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return dialog_fields;
|
||||
}
|
||||
|
||||
setup_report_wrapper() {
|
||||
if (this.$report) return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue