Merge branch 'develop' into fix-browserlite-caniuse-lite-upgrade
This commit is contained in:
commit
1cfda34d8e
12 changed files with 407 additions and 151 deletions
|
|
@ -609,7 +609,7 @@
|
|||
"link_fieldname": "reference_doctype"
|
||||
}
|
||||
],
|
||||
"modified": "2020-08-06 12:59:32.369093",
|
||||
"modified": "2020-08-06 12:59:32.369095",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "DocType",
|
||||
|
|
|
|||
|
|
@ -42,26 +42,6 @@ frappe.ui.form.on('Report', {
|
|||
}
|
||||
},
|
||||
|
||||
report_type: function(frm) {
|
||||
frm.set_intro("");
|
||||
switch(frm.doc.report_type) {
|
||||
case "Report Builder":
|
||||
frm.set_intro(__("Report Builder reports are managed directly by the report builder. Nothing to do."));
|
||||
break;
|
||||
case "Query Report":
|
||||
frm.set_intro(__("Write a SELECT query. Note result is not paged (all data is sent in one go).")
|
||||
+ __("To format columns, give column labels in the query.") + "<br>"
|
||||
+ __("[Label]:[Field Type]/[Options]:[Width]") + "<br><br>"
|
||||
+ __("Example:") + "<br>"
|
||||
+ "Employee:Link/Employee:200" + "<br>"
|
||||
+ "Rate:Currency:120" + "<br>")
|
||||
break;
|
||||
case "Script Report":
|
||||
frm.set_intro(__("Write a Python file in the same folder where this is saved and return column and result."));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
set_doctype_roles: function(frm) {
|
||||
return frm.call('set_doctype_roles').then(() => {
|
||||
frm.refresh_field('roles');
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"actions": [],
|
||||
"autoname": "field:report_name",
|
||||
"creation": "2013-03-09 15:45:57",
|
||||
"doctype": "DocType",
|
||||
|
|
@ -17,10 +18,15 @@
|
|||
"disabled",
|
||||
"disable_prepared_report",
|
||||
"prepared_report",
|
||||
"filters_section",
|
||||
"filters",
|
||||
"columns_section",
|
||||
"columns",
|
||||
"section_break_6",
|
||||
"query",
|
||||
"javascript",
|
||||
"report_script",
|
||||
"client_code_section",
|
||||
"javascript",
|
||||
"json",
|
||||
"permission_rules",
|
||||
"roles"
|
||||
|
|
@ -94,7 +100,8 @@
|
|||
},
|
||||
{
|
||||
"fieldname": "section_break_6",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Query / Script"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.report_type==\"Query Report\"",
|
||||
|
|
@ -142,15 +149,50 @@
|
|||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.report_type==\"Script Report\" && doc.is_standard===\"No\"",
|
||||
"description": "output in the form of `data = [columns, result]`",
|
||||
"depends_on": "eval:(doc.report_type===\"Script Report\" \n|| doc.report_type==\"Query Report\") \n&& doc.is_standard===\"No\"",
|
||||
"description": "Filters will be accessible via <code>filters</code>. <br><br>Send output as <code>result = [result]</code>, or for old style <code>data = [columns], [result]</code>",
|
||||
"fieldname": "report_script",
|
||||
"fieldtype": "Code",
|
||||
"label": "Script"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "filters",
|
||||
"fieldname": "filters_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Filters"
|
||||
},
|
||||
{
|
||||
"fieldname": "filters",
|
||||
"fieldtype": "Table",
|
||||
"label": "Filters",
|
||||
"options": "Report Filter"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "columns",
|
||||
"fieldname": "columns_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Columns"
|
||||
},
|
||||
{
|
||||
"fieldname": "columns",
|
||||
"fieldtype": "Table",
|
||||
"label": "Columns",
|
||||
"options": "Report Column"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "javascript",
|
||||
"fieldname": "client_code_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Client Code"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"modified": "2019-10-09 15:43:08.577610",
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-17 16:49:28.474274",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Report",
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ class Report(Document):
|
|||
def on_trash(self):
|
||||
delete_custom_role('report', self.name)
|
||||
|
||||
def get_columns(self):
|
||||
return [d.as_dict(no_default_fields = True) for d in self.columns]
|
||||
|
||||
def set_doctype_roles(self):
|
||||
if not self.get('roles') and self.is_standard == 'No':
|
||||
meta = frappe.get_meta(self.ref_doctype)
|
||||
|
|
@ -99,8 +102,8 @@ class Report(Document):
|
|||
if not self.query.lower().startswith("select"):
|
||||
frappe.throw(_("Query must be a SELECT"), title=_('Report Document Error'))
|
||||
|
||||
result = [list(t) for t in frappe.db.sql(self.query, filters)]
|
||||
columns = [cstr(c[0]) for c in frappe.db.get_description()]
|
||||
result = [list(t) for t in frappe.db.sql(self.query, filters, debug=True)]
|
||||
columns = self.get_columns() or [cstr(c[0]) for c in frappe.db.get_description()]
|
||||
|
||||
return [columns, result]
|
||||
|
||||
|
|
@ -134,135 +137,167 @@ class Report(Document):
|
|||
|
||||
def execute_script(self, filters):
|
||||
# server script
|
||||
loc = {"filters": frappe._dict(filters), 'data':[]}
|
||||
loc = {"filters": frappe._dict(filters), 'data':None, 'result':None}
|
||||
safe_exec(self.report_script, None, loc)
|
||||
return loc['data']
|
||||
if loc['data']:
|
||||
return loc['data']
|
||||
else:
|
||||
return self.get_columns(), loc['result']
|
||||
|
||||
def get_data(self, filters=None, limit=None, user=None, as_dict=False, ignore_prepared_report=False):
|
||||
columns = []
|
||||
out = []
|
||||
|
||||
if self.report_type in ('Query Report', 'Script Report', 'Custom Report'):
|
||||
# query and script reports
|
||||
data = frappe.desk.query_report.run(self.name,
|
||||
filters=filters, user=user, ignore_prepared_report=ignore_prepared_report)
|
||||
|
||||
for d in data.get('columns'):
|
||||
if isinstance(d, dict):
|
||||
col = frappe._dict(d)
|
||||
if not col.fieldname:
|
||||
col.fieldname = col.label
|
||||
columns.append(col)
|
||||
else:
|
||||
fieldtype, options = "Data", None
|
||||
parts = d.split(':')
|
||||
if len(parts) > 1:
|
||||
if parts[1]:
|
||||
fieldtype, options = parts[1], None
|
||||
if fieldtype and '/' in fieldtype:
|
||||
fieldtype, options = fieldtype.split('/')
|
||||
|
||||
columns.append(frappe._dict(label=parts[0], fieldtype=fieldtype, fieldname=parts[0], options=options))
|
||||
|
||||
out += data.get('result')
|
||||
columns, result = self.run_query_report(filters, user, ignore_prepared_report)
|
||||
else:
|
||||
# standard report
|
||||
params = json.loads(self.json)
|
||||
|
||||
if params.get('fields'):
|
||||
columns = params.get('fields')
|
||||
elif params.get('columns'):
|
||||
columns = params.get('columns')
|
||||
else:
|
||||
columns = [['name', self.ref_doctype]]
|
||||
for df in frappe.get_meta(self.ref_doctype).fields:
|
||||
if df.in_list_view:
|
||||
columns.append([df.fieldname, self.ref_doctype])
|
||||
|
||||
_filters = params.get('filters') or []
|
||||
|
||||
if filters:
|
||||
for key, value in iteritems(filters):
|
||||
condition, _value = '=', value
|
||||
if isinstance(value, (list, tuple)):
|
||||
condition, _value = value
|
||||
_filters.append([key, condition, _value])
|
||||
|
||||
def _format(parts):
|
||||
# sort by is saved as DocType.fieldname, covert it to sql
|
||||
return '`tab{0}`.`{1}`'.format(*parts)
|
||||
|
||||
if params.get('sort_by'):
|
||||
order_by = _format(params.get('sort_by').split('.')) + ' ' + params.get('sort_order')
|
||||
elif params.get('order_by'):
|
||||
order_by = params.get('order_by')
|
||||
else:
|
||||
order_by = _format([self.ref_doctype, 'modified']) + ' desc'
|
||||
|
||||
if params.get('sort_by_next'):
|
||||
order_by += ', ' + _format(params.get('sort_by_next').split('.')) + ' ' + params.get('sort_order_next')
|
||||
|
||||
group_by = None
|
||||
if params.get('group_by'):
|
||||
group_by_args = frappe._dict(params['group_by'])
|
||||
group_by = group_by_args['group_by']
|
||||
order_by = '_aggregate_column desc'
|
||||
|
||||
result = frappe.get_list(self.ref_doctype,
|
||||
fields = [
|
||||
get_group_by_field(group_by_args, c[1]) if c[0] == '_aggregate_column' and group_by_args
|
||||
else _format([c[1], c[0]])
|
||||
for c in columns
|
||||
],
|
||||
filters=_filters,
|
||||
order_by = order_by,
|
||||
as_list=True,
|
||||
limit=limit,
|
||||
group_by=group_by,
|
||||
user=user)
|
||||
|
||||
_columns = []
|
||||
|
||||
for (fieldname, doctype) in columns:
|
||||
meta = frappe.get_meta(doctype)
|
||||
|
||||
if meta.get_field(fieldname):
|
||||
field = meta.get_field(fieldname)
|
||||
else:
|
||||
if fieldname == '_aggregate_column':
|
||||
label = get_group_by_column_label(group_by_args, meta)
|
||||
else:
|
||||
label = meta.get_label(fieldname)
|
||||
|
||||
field = frappe._dict(fieldname=fieldname, label=label)
|
||||
# since name is the primary key for a document, it will always be a Link datatype
|
||||
if fieldname == "name":
|
||||
field.fieldtype = "Link"
|
||||
field.options = doctype
|
||||
|
||||
_columns.append(field)
|
||||
columns = _columns
|
||||
|
||||
out = out + [list(d) for d in result]
|
||||
|
||||
if params.get('add_totals_row'):
|
||||
out = append_totals_row(out)
|
||||
columns, result = self.run_standard_report(filters, limit, user)
|
||||
|
||||
if as_dict:
|
||||
data = []
|
||||
for row in out:
|
||||
if isinstance(row, (list, tuple)):
|
||||
_row = frappe._dict()
|
||||
for i, val in enumerate(row):
|
||||
_row[columns[i].get('fieldname')] = val
|
||||
elif isinstance(row, dict):
|
||||
# no need to convert from dict to dict
|
||||
_row = frappe._dict(row)
|
||||
data.append(_row)
|
||||
else:
|
||||
data = out
|
||||
return columns, data
|
||||
result = self.build_data_dict(result, columns)
|
||||
|
||||
return columns, result
|
||||
|
||||
def run_query_report(self, filters, user, ignore_prepared_report=False):
|
||||
columns, result = [], []
|
||||
data = frappe.desk.query_report.run(self.name,
|
||||
filters=filters, user=user, ignore_prepared_report=ignore_prepared_report)
|
||||
|
||||
for d in data.get('columns'):
|
||||
if isinstance(d, dict):
|
||||
col = frappe._dict(d)
|
||||
if not col.fieldname:
|
||||
col.fieldname = col.label
|
||||
columns.append(col)
|
||||
else:
|
||||
fieldtype, options = "Data", None
|
||||
parts = d.split(':')
|
||||
if len(parts) > 1:
|
||||
if parts[1]:
|
||||
fieldtype, options = parts[1], None
|
||||
if fieldtype and '/' in fieldtype:
|
||||
fieldtype, options = fieldtype.split('/')
|
||||
|
||||
columns.append(frappe._dict(label=parts[0], fieldtype=fieldtype, fieldname=parts[0], options=options))
|
||||
|
||||
result += data.get('result')
|
||||
|
||||
return columns, result
|
||||
|
||||
def run_standard_report(self, filters, limit, user):
|
||||
params = json.loads(self.json)
|
||||
columns = self.get_standard_report_columns(params)
|
||||
result = []
|
||||
order_by, group_by, group_by_args = self.get_standard_report_order_by(params)
|
||||
|
||||
_result = frappe.get_list(self.ref_doctype,
|
||||
fields = [
|
||||
get_group_by_field(group_by_args, c[1]) if c[0] == '_aggregate_column' and group_by_args
|
||||
else Report._format([c[1], c[0]]) for c in columns
|
||||
],
|
||||
filters = self.get_standard_report_filters(params, filters),
|
||||
order_by = order_by,
|
||||
group_by = group_by,
|
||||
as_list = True,
|
||||
limit = limit,
|
||||
user = user)
|
||||
|
||||
columns = self.build_standard_report_columns(columns, group_by_args)
|
||||
|
||||
result = result + [list(d) for d in _result]
|
||||
|
||||
if params.get('add_totals_row'):
|
||||
result = append_totals_row(result)
|
||||
|
||||
return columns, result
|
||||
|
||||
@staticmethod
|
||||
def _format(parts):
|
||||
# sort by is saved as DocType.fieldname, covert it to sql
|
||||
return '`tab{0}`.`{1}`'.format(*parts)
|
||||
|
||||
def get_standard_report_columns(self, params):
|
||||
if params.get('fields'):
|
||||
columns = params.get('fields')
|
||||
elif params.get('columns'):
|
||||
columns = params.get('columns')
|
||||
elif params.get('fields'):
|
||||
columns = params.get('fields')
|
||||
else:
|
||||
columns = [['name', self.ref_doctype]]
|
||||
for df in frappe.get_meta(self.ref_doctype).fields:
|
||||
if df.in_list_view:
|
||||
columns.append([df.fieldname, self.ref_doctype])
|
||||
|
||||
return columns
|
||||
|
||||
def get_standard_report_filters(self, params, filters):
|
||||
_filters = params.get('filters') or []
|
||||
|
||||
if filters:
|
||||
for key, value in iteritems(filters):
|
||||
condition, _value = '=', value
|
||||
if isinstance(value, (list, tuple)):
|
||||
condition, _value = value
|
||||
_filters.append([key, condition, _value])
|
||||
|
||||
return _filters
|
||||
|
||||
def get_standard_report_order_by(self, params):
|
||||
group_by_args = None
|
||||
if params.get('sort_by'):
|
||||
order_by = Report._format(params.get('sort_by').split('.')) + ' ' + params.get('sort_order')
|
||||
|
||||
elif params.get('order_by'):
|
||||
order_by = params.get('order_by')
|
||||
else:
|
||||
order_by = Report._format([self.ref_doctype, 'modified']) + ' desc'
|
||||
|
||||
if params.get('sort_by_next'):
|
||||
order_by += ', ' + Report._format(params.get('sort_by_next').split('.')) + ' ' + params.get('sort_order_next')
|
||||
|
||||
group_by = None
|
||||
if params.get('group_by'):
|
||||
group_by_args = frappe._dict(params['group_by'])
|
||||
group_by = group_by_args['group_by']
|
||||
order_by = '_aggregate_column desc'
|
||||
|
||||
return order_by, group_by, group_by_args
|
||||
|
||||
def build_standard_report_columns(self, columns, group_by_args):
|
||||
_columns = []
|
||||
|
||||
for (fieldname, doctype) in columns:
|
||||
meta = frappe.get_meta(doctype)
|
||||
|
||||
if meta.get_field(fieldname):
|
||||
field = meta.get_field(fieldname)
|
||||
else:
|
||||
if fieldname == '_aggregate_column':
|
||||
label = get_group_by_column_label(group_by_args, meta)
|
||||
else:
|
||||
label = meta.get_label(fieldname)
|
||||
|
||||
field = frappe._dict(fieldname=fieldname, label=label)
|
||||
|
||||
# since name is the primary key for a document, it will always be a Link datatype
|
||||
if fieldname == "name":
|
||||
field.fieldtype = "Link"
|
||||
field.options = doctype
|
||||
|
||||
_columns.append(field)
|
||||
return _columns
|
||||
|
||||
def build_data_dict(self, result, columns):
|
||||
data = []
|
||||
for row in result:
|
||||
if isinstance(row, (list, tuple)):
|
||||
_row = frappe._dict()
|
||||
for i, val in enumerate(row):
|
||||
_row[columns[i].get('fieldname')] = val
|
||||
elif isinstance(row, dict):
|
||||
# no need to convert from dict to dict
|
||||
_row = frappe._dict(row)
|
||||
data.append(_row)
|
||||
|
||||
return data
|
||||
|
||||
@Document.whitelist
|
||||
def toggle_disable(self, disable):
|
||||
|
|
|
|||
|
|
@ -111,3 +111,41 @@ data = [
|
|||
# check values
|
||||
self.assertTrue('System User' in [d.get('type') for d in data[1]])
|
||||
|
||||
def test_script_report_with_columns(self):
|
||||
report_name = 'Test Script Report With Columns'
|
||||
|
||||
if frappe.db.exists("Report", report_name):
|
||||
frappe.delete_doc('Report', report_name)
|
||||
|
||||
report = frappe.get_doc({
|
||||
'doctype': 'Report',
|
||||
'ref_doctype': 'User',
|
||||
'report_name': report_name,
|
||||
'report_type': 'Script Report',
|
||||
'is_standard': 'No',
|
||||
'columns': [
|
||||
dict(fieldname='type', label='Type', fieldtype='Data'),
|
||||
dict(fieldname='value', label='Value', fieldtype='Int'),
|
||||
]
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
report.report_script = '''
|
||||
totals = {}
|
||||
for user in frappe.get_all('User', fields = ['name', 'user_type', 'creation']):
|
||||
if not user.user_type in totals:
|
||||
totals[user.user_type] = 0
|
||||
totals[user.user_type] = totals[user.user_type] + 1
|
||||
|
||||
result = [
|
||||
{"type":key, "value": value} for key, value in totals.items()
|
||||
]
|
||||
'''
|
||||
|
||||
report.save()
|
||||
data = report.get_data()
|
||||
|
||||
# check columns
|
||||
self.assertEqual(data[0][0]['label'], 'Type')
|
||||
|
||||
# check values
|
||||
self.assertTrue('System User' in [d.get('type') for d in data[1]])
|
||||
|
|
|
|||
0
frappe/core/doctype/report_column/__init__.py
Normal file
0
frappe/core/doctype/report_column/__init__.py
Normal file
61
frappe/core/doctype/report_column/report_column.json
Normal file
61
frappe/core/doctype/report_column/report_column.json
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"actions": [],
|
||||
"creation": "2020-01-14 11:28:37.583656",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"fieldname",
|
||||
"label",
|
||||
"fieldtype",
|
||||
"options",
|
||||
"width"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "fieldname",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Fieldname",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "label",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Label",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "fieldtype",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Fieldtype",
|
||||
"options": "Check\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nInt\nLink\nSelect\nTime",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "options",
|
||||
"fieldtype": "Data",
|
||||
"label": "Options"
|
||||
},
|
||||
{
|
||||
"fieldname": "width",
|
||||
"fieldtype": "Int",
|
||||
"label": "Width"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-17 14:32:17.174796",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Report Column",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
10
frappe/core/doctype/report_column/report_column.py
Normal file
10
frappe/core/doctype/report_column/report_column.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ReportColumn(Document):
|
||||
pass
|
||||
0
frappe/core/doctype/report_filter/__init__.py
Normal file
0
frappe/core/doctype/report_filter/__init__.py
Normal file
71
frappe/core/doctype/report_filter/report_filter.json
Normal file
71
frappe/core/doctype/report_filter/report_filter.json
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
{
|
||||
"actions": [],
|
||||
"creation": "2020-01-14 11:38:58.016498",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"fieldname",
|
||||
"label",
|
||||
"fieldtype",
|
||||
"mandatory",
|
||||
"options",
|
||||
"wildcard_filter"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "fieldname",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Fieldname",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "label",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Label",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "fieldtype",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Fieldtype",
|
||||
"options": "Check\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nInt\nLink\nSelect\nTime",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "mandatory",
|
||||
"fieldtype": "Check",
|
||||
"in_list_view": 1,
|
||||
"label": "Mandatory"
|
||||
},
|
||||
{
|
||||
"fieldname": "options",
|
||||
"fieldtype": "Data",
|
||||
"label": "Options"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "Will add \"%\" before and after the query",
|
||||
"fieldname": "wildcard_filter",
|
||||
"fieldtype": "Check",
|
||||
"label": "Wildcard Filter"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-17 16:15:46.937267",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Report Filter",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
10
frappe/core/doctype/report_filter/report_filter.py
Normal file
10
frappe/core/doctype/report_filter/report_filter.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2020, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class ReportFilter(Document):
|
||||
pass
|
||||
|
|
@ -366,6 +366,12 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
this.report_settings.html_format = settings.html_format;
|
||||
this.report_settings.execution_time = settings.execution_time || 0;
|
||||
frappe.query_reports[this.report_name] = this.report_settings;
|
||||
|
||||
if (this.report_doc.filters && !this.report_settings.filters) {
|
||||
// add configured filters
|
||||
this.report_settings.filters = this.report_doc.filters;
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
}).catch(reject);
|
||||
|
|
@ -1109,8 +1115,11 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
.map(f => {
|
||||
var v = f.get_value();
|
||||
// hidden fields dont have $input
|
||||
if(f.df.hidden) v = f.value;
|
||||
if(v === '%') v = null;
|
||||
if (f.df.hidden) v = f.value;
|
||||
if (v === '%') v = null;
|
||||
if (f.df.wildcard_filter) {
|
||||
v = `%${v}%`;
|
||||
}
|
||||
return {
|
||||
[f.df.fieldname]: v
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue