@@ -50,13 +50,13 @@ class Report(Document): | |||||
make_boilerplate("controller.py", self, {"name": self.name}) | make_boilerplate("controller.py", self, {"name": self.name}) | ||||
make_boilerplate("controller.js", self, {"name": self.name}) | make_boilerplate("controller.js", self, {"name": self.name}) | ||||
def get_data(self, filters=None, limit=None): | |||||
def get_data(self, filters=None, limit=None, user=None): | |||||
'''Run the report''' | '''Run the report''' | ||||
out = [] | out = [] | ||||
if self.report_type in ('Query Report', 'Script Report'): | if self.report_type in ('Query Report', 'Script Report'): | ||||
# query and script reports | # query and script reports | ||||
data = frappe.desk.query_report.run(self.name, filters=filters) | |||||
data = frappe.desk.query_report.run(self.name, filters=filters, user=user) | |||||
out.append([d.split(':')[0] for d in data.get('columns')]) | out.append([d.split(':')[0] for d in data.get('columns')]) | ||||
out += data.get('result') | out += data.get('result') | ||||
else: | else: | ||||
@@ -74,7 +74,7 @@ class Report(Document): | |||||
order_by += ', ' + _format(params.get('sort_by_next').split('.')) + ' ' + params.get('sort_order_next') | order_by += ', ' + _format(params.get('sort_by_next').split('.')) + ' ' + params.get('sort_order_next') | ||||
result = frappe.get_list(self.ref_doctype, fields = [_format([c[1], c[0]]) for c in columns], | result = frappe.get_list(self.ref_doctype, fields = [_format([c[1], c[0]]) for c in columns], | ||||
filters=filters, order_by = order_by, as_list=True, limit=limit) | |||||
filters=filters, order_by = order_by, as_list=True, limit=limit, user=user) | |||||
meta = frappe.get_meta(self.ref_doctype) | meta = frappe.get_meta(self.ref_doctype) | ||||
@@ -22,7 +22,7 @@ class TestReport(unittest.TestCase): | |||||
data = report.get_data(filters={'user': 'Administrator', 'doctype': 'DocType'}) | data = report.get_data(filters={'user': 'Administrator', 'doctype': 'DocType'}) | ||||
self.assertEquals(data[0][0], 'Name') | self.assertEquals(data[0][0], 'Name') | ||||
self.assertEquals(data[0][1], 'Module') | self.assertEquals(data[0][1], 'Module') | ||||
self.assertTrue('Auto Email Report' in [d[0] for d in data]) | |||||
self.assertTrue('User' in [d[0] for d in data]) | |||||
# test standard report with child table | # test standard report with child table | ||||
user_activity_report = ''' | user_activity_report = ''' | ||||
@@ -20,7 +20,7 @@ frappe.query_reports["Permitted Documents For User"] = { | |||||
return { | return { | ||||
"query": "frappe.core.report.permitted_documents_for_user.permitted_documents_for_user.query_doctypes", | "query": "frappe.core.report.permitted_documents_for_user.permitted_documents_for_user.query_doctypes", | ||||
"filters": { | "filters": { | ||||
"user": frappe.query_report.filters_by_name.user.get_value() | |||||
"user": frappe.query_report_filters_by_name.user.get_value() | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -60,8 +60,10 @@ def get_script(report_name): | |||||
} | } | ||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def run(report_name, filters=None): | |||||
def run(report_name, filters=None, user=None): | |||||
report = get_report_doc(report_name) | report = get_report_doc(report_name) | ||||
if not user: | |||||
user = frappe.session.user | |||||
if not filters: | if not filters: | ||||
filters = [] | filters = [] | ||||
@@ -97,7 +99,7 @@ def run(report_name, filters=None): | |||||
chart = res[3] | chart = res[3] | ||||
if report.apply_user_permissions and result: | if report.apply_user_permissions and result: | ||||
result = get_filtered_data(report.ref_doctype, columns, result) | |||||
result = get_filtered_data(report.ref_doctype, columns, result, user) | |||||
if cint(report.add_total_row) and result: | if cint(report.add_total_row) and result: | ||||
result = add_total_row(result, columns) | result = add_total_row(result, columns) | ||||
@@ -158,14 +160,14 @@ def add_total_row(result, columns): | |||||
result.append(total_row) | result.append(total_row) | ||||
return result | return result | ||||
def get_filtered_data(ref_doctype, columns, data): | |||||
def get_filtered_data(ref_doctype, columns, data, user): | |||||
result = [] | result = [] | ||||
linked_doctypes = get_linked_doctypes(columns, data) | linked_doctypes = get_linked_doctypes(columns, data) | ||||
match_filters_per_doctype = get_user_match_filters(linked_doctypes, ref_doctype) | match_filters_per_doctype = get_user_match_filters(linked_doctypes, ref_doctype) | ||||
shared = frappe.share.get_shared(ref_doctype) | |||||
shared = frappe.share.get_shared(ref_doctype, user) | |||||
columns_dict = get_columns_dict(columns) | columns_dict = get_columns_dict(columns) | ||||
role_permissions = get_role_permissions(frappe.get_meta(ref_doctype)) | |||||
role_permissions = get_role_permissions(frappe.get_meta(ref_doctype), user) | |||||
if_owner = role_permissions.get("if_owner", {}).get("report") | if_owner = role_permissions.get("if_owner", {}).get("report") | ||||
if match_filters_per_doctype: | if match_filters_per_doctype: | ||||
@@ -174,14 +176,14 @@ def get_filtered_data(ref_doctype, columns, data): | |||||
if linked_doctypes.get(ref_doctype) and shared and row[linked_doctypes[ref_doctype]] in shared: | if linked_doctypes.get(ref_doctype) and shared and row[linked_doctypes[ref_doctype]] in shared: | ||||
result.append(row) | result.append(row) | ||||
elif has_match(row, linked_doctypes, match_filters_per_doctype, ref_doctype, if_owner, columns_dict): | |||||
elif has_match(row, linked_doctypes, match_filters_per_doctype, ref_doctype, if_owner, columns_dict, user): | |||||
result.append(row) | result.append(row) | ||||
else: | else: | ||||
result = list(data) | result = list(data) | ||||
return result | return result | ||||
def has_match(row, linked_doctypes, doctype_match_filters, ref_doctype, if_owner, columns_dict): | |||||
def has_match(row, linked_doctypes, doctype_match_filters, ref_doctype, if_owner, columns_dict, user): | |||||
"""Returns True if after evaluating permissions for each linked doctype | """Returns True if after evaluating permissions for each linked doctype | ||||
- There is an owner match for the ref_doctype | - There is an owner match for the ref_doctype | ||||
- `and` There is a user permission match for all linked doctypes | - `and` There is a user permission match for all linked doctypes | ||||
@@ -205,7 +207,7 @@ def has_match(row, linked_doctypes, doctype_match_filters, ref_doctype, if_owner | |||||
if doctype==ref_doctype and if_owner: | if doctype==ref_doctype and if_owner: | ||||
idx = linked_doctypes.get("User") | idx = linked_doctypes.get("User") | ||||
if (idx is not None | if (idx is not None | ||||
and row[idx]==frappe.session.user | |||||
and row[idx]==user | |||||
and columns_dict[idx]==columns_dict.get("owner")): | and columns_dict[idx]==columns_dict.get("owner")): | ||||
# owner match is true | # owner match is true | ||||
matched_for_doctype = True | matched_for_doctype = True | ||||
@@ -0,0 +1,63 @@ | |||||
// Copyright (c) 2016, Frappe Technologies and contributors | |||||
// For license information, please see license.txt | |||||
frappe.ui.form.on('Auto Email Report', { | |||||
refresh: function(frm) { | |||||
if(frm.doc.report_type !== 'Report Builder') { | |||||
if(frm.script_setup_for !== frm.doc.report) { | |||||
frappe.call({ | |||||
method:"frappe.desk.query_report.get_script", | |||||
args: { | |||||
report_name: frm.doc.report | |||||
}, | |||||
callback: function(r) { | |||||
frappe.dom.eval(r.message.script || ""); | |||||
frm.script_setup_for = frm.doc.report; | |||||
frm.trigger('show_filters'); | |||||
} | |||||
}); | |||||
} else { | |||||
frm.trigger('show_filters'); | |||||
} | |||||
} | |||||
}, | |||||
show_filters: function(frm) { | |||||
var wrapper = $(frm.get_field('filters_display').wrapper); | |||||
wrapper.empty(); | |||||
if(frm.doc.report_type !== 'Report Builder' | |||||
&& frappe.query_reports[frm.doc.report] | |||||
&& frappe.query_reports[frm.doc.report].filters) { | |||||
// make a table to show filters | |||||
var table = $('<table class="table table-bordered" style="cursor:pointer;"><thead>\ | |||||
<tr><th style="width: 50%">'+__('Filter')+'</th><th>'+__('Value')+'</th></tr>\ | |||||
</thead><tbody></tbody></table>').appendTo(wrapper); | |||||
$('<p class="text-muted small">' + __("Click table to edit") + '</p>').appendTo(wrapper); | |||||
var filters = JSON.parse(frm.doc.filters || '{}'); | |||||
var report_filters = frappe.query_reports[frm.doc.report].filters; | |||||
report_filters.forEach(function(f) { | |||||
$('<tr><td>' + f.label + '</td><td>'+ frappe.format(filters[f.fieldname], f) +'</td></tr>') | |||||
.appendTo(table.find('tbody')); | |||||
}); | |||||
table.on('click', function() { | |||||
var dialog = new frappe.ui.Dialog({ | |||||
fields: report_filters, | |||||
primary_action: function() { | |||||
var values = this.get_values(); | |||||
if(values) { | |||||
this.hide(); | |||||
frm.set_value('filters', JSON.stringify(values)); | |||||
frm.trigger('show_filters'); | |||||
frappe.query_report_filters_by_name = null; | |||||
} | |||||
} | |||||
}); | |||||
dialog.show(); | |||||
dialog.set_values(filters); | |||||
frappe.query_report_filters_by_name = dialog.fields_dict; | |||||
}) | |||||
} | |||||
} | |||||
}); |
@@ -0,0 +1,426 @@ | |||||
{ | |||||
"allow_copy": 0, | |||||
"allow_import": 0, | |||||
"allow_rename": 1, | |||||
"autoname": "field:report", | |||||
"beta": 0, | |||||
"creation": "2016-09-01 01:34:34.985457", | |||||
"custom": 0, | |||||
"docstatus": 0, | |||||
"doctype": "DocType", | |||||
"document_type": "", | |||||
"editable_grid": 1, | |||||
"fields": [ | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "report", | |||||
"fieldtype": "Link", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Report", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "Report", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 1, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "report_type", | |||||
"fieldtype": "Read Only", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Report Type", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "report.report_type", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "user", | |||||
"fieldtype": "Link", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "For User", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "User", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 1, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "enabled", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Enabled", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"depends_on": "eval:doc.report_type !== 'Report Builder'", | |||||
"fieldname": "report_filters", | |||||
"fieldtype": "Section Break", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Report Filters", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "filters_display", | |||||
"fieldtype": "HTML", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Filters Display", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "filters", | |||||
"fieldtype": "Text", | |||||
"hidden": 1, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Filters", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "email_settings", | |||||
"fieldtype": "Section Break", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Email Settings", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "frequency", | |||||
"fieldtype": "Select", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Frequency", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "Daily\nWeekly\nMonthly", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 1, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"default": "Monday", | |||||
"depends_on": "eval:doc.frequency=='Weekly'", | |||||
"fieldname": "day_of_week", | |||||
"fieldtype": "Select", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Day of Week", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "format", | |||||
"fieldtype": "Select", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Format", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "HTML\nXLS\nCSV", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 1, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "email_to", | |||||
"fieldtype": "Small Text", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Email To", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 1, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "description", | |||||
"fieldtype": "Text Editor", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Description", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
} | |||||
], | |||||
"hide_heading": 0, | |||||
"hide_toolbar": 0, | |||||
"idx": 0, | |||||
"image_view": 0, | |||||
"in_create": 0, | |||||
"in_dialog": 0, | |||||
"is_submittable": 0, | |||||
"issingle": 0, | |||||
"istable": 0, | |||||
"max_attachments": 0, | |||||
"modified": "2016-09-01 05:21:16.487736", | |||||
"modified_by": "Administrator", | |||||
"module": "Email", | |||||
"name": "Auto Email Report", | |||||
"name_case": "", | |||||
"owner": "Administrator", | |||||
"permissions": [ | |||||
{ | |||||
"amend": 0, | |||||
"apply_user_permissions": 0, | |||||
"cancel": 0, | |||||
"create": 1, | |||||
"delete": 1, | |||||
"email": 1, | |||||
"export": 1, | |||||
"if_owner": 0, | |||||
"import": 0, | |||||
"permlevel": 0, | |||||
"print": 1, | |||||
"read": 1, | |||||
"report": 1, | |||||
"role": "System Manager", | |||||
"set_user_permissions": 0, | |||||
"share": 1, | |||||
"submit": 0, | |||||
"write": 1 | |||||
}, | |||||
{ | |||||
"amend": 0, | |||||
"apply_user_permissions": 0, | |||||
"cancel": 0, | |||||
"create": 1, | |||||
"delete": 1, | |||||
"email": 1, | |||||
"export": 1, | |||||
"if_owner": 0, | |||||
"import": 0, | |||||
"permlevel": 0, | |||||
"print": 1, | |||||
"read": 1, | |||||
"report": 1, | |||||
"role": "Report Manager", | |||||
"set_user_permissions": 0, | |||||
"share": 1, | |||||
"submit": 0, | |||||
"write": 1 | |||||
} | |||||
], | |||||
"quick_entry": 0, | |||||
"read_only": 0, | |||||
"read_only_onload": 0, | |||||
"sort_field": "modified", | |||||
"sort_order": "DESC", | |||||
"track_seen": 0 | |||||
} |
@@ -0,0 +1,86 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2015, Frappe Technologies and contributors | |||||
# For license information, please see license.txt | |||||
from __future__ import unicode_literals | |||||
import frappe | |||||
from frappe import _ | |||||
from frappe.model.document import Document | |||||
import frappe.utils | |||||
max_reports_per_user = 3 | |||||
class AutoEmailReport(Document): | |||||
def autoname(self): | |||||
self.name = _(self.report) | |||||
def validate(self): | |||||
self.validate_report_count() | |||||
self.validate_emails() | |||||
def validate_emails(self): | |||||
'''Cleanup list of emails''' | |||||
if ',' in self.emails: | |||||
self.emails.replace(',', '\n') | |||||
valid = [] | |||||
for email in self.emails.split(): | |||||
if email: | |||||
frappe.utils.validate_email_add(email, True) | |||||
valid.append(email) | |||||
self.emails = '\n'.join(valid) | |||||
def validate_report_count(self): | |||||
'''check that there are only 3 enabled reports per user''' | |||||
count = frappe.db.sql('select count(*) from `tabAuto Email Report` where user=%s and enabled=1', self.user)[0][0] | |||||
if count > max_reports_per_user: | |||||
frappe.throw(_('Only {0} emailed reports are allowed per user').format(max_reports_per_user)) | |||||
def send(self): | |||||
report = frappe.get_doc('Report', self.report) | |||||
data = report.get_data(limit=500, user = self.user, filters = self.filters) | |||||
message = '<p>{0}</p>'.format(_('{0} generated on {1}').format(self.name, | |||||
frappe.utils.format_datetime(frappe.utils.now_datetime()))) | |||||
attachments = None | |||||
if self.report_format == 'HTML': | |||||
message += self.get_html_table(data) | |||||
if self.report_format == 'XLS': | |||||
attachments.append(self.get_xls()) | |||||
frappe.sendmail( | |||||
recipients = self.emails.split(), | |||||
subject = self.name, | |||||
message = message, | |||||
attachments = attachments | |||||
) | |||||
def get_html_table(self, data): | |||||
return '' | |||||
def get_csv(self, data): | |||||
return | |||||
def get_xls(self, data): | |||||
return | |||||
def send_daily(self): | |||||
'''Check reports to be sent daily''' | |||||
now = frappe.utils.now_datetime() | |||||
for report in frappe.get_all('Auto Email Report', {'enabled': 1, 'frequency': ('in', ('Daily', 'Weekly'))}): | |||||
auto_email_report = frappe.get_doc('Auto Email Report', report.name) | |||||
if auto_email_report.frequency=='Weekly': | |||||
# if not correct weekday, skip | |||||
if now.weekday()!={'Monday':0,'Tuesday':1,'Wednesday':2, | |||||
'Thursday':3,'Friday':4,'Saturday':5,'Sunday':6}[auto_email_report.weekday]: | |||||
continue | |||||
auto_email_report.send() | |||||
def send_monthly(self): | |||||
'''Check reports to be sent monthly''' | |||||
for report in frappe.get_all('Auto Email Report', {'enabled': 1, 'frequency': 'Monthly'}): | |||||
frappe.get_doc('Auto Email Report', report.name).send() |
@@ -0,0 +1,12 @@ | |||||
# -*- coding: utf-8 -*- | |||||
# Copyright (c) 2015, Frappe Technologies and Contributors | |||||
# See license.txt | |||||
from __future__ import unicode_literals | |||||
import frappe | |||||
import unittest, json | |||||
# test_records = frappe.get_test_records('Auto Email Report') | |||||
class TestAutoEmailReport(unittest.TestCase): | |||||
pass |
@@ -142,12 +142,16 @@ scheduler_events = { | |||||
"frappe.utils.scheduler.disable_scheduler_on_expiry", | "frappe.utils.scheduler.disable_scheduler_on_expiry", | ||||
"frappe.utils.scheduler.restrict_scheduler_events_if_dormant", | "frappe.utils.scheduler.restrict_scheduler_events_if_dormant", | ||||
"frappe.limits.update_space_usage", | "frappe.limits.update_space_usage", | ||||
"frappe.email.doctype.auto_email_report.auto_email_report.send_daily" | |||||
], | ], | ||||
"daily_long": [ | "daily_long": [ | ||||
"frappe.integrations.doctype.dropbox_backup.dropbox_backup.take_backups_daily" | "frappe.integrations.doctype.dropbox_backup.dropbox_backup.take_backups_daily" | ||||
], | ], | ||||
"weekly_long": [ | "weekly_long": [ | ||||
"frappe.integrations.doctype.dropbox_backup.dropbox_backup.take_backups_weekly" | "frappe.integrations.doctype.dropbox_backup.dropbox_backup.take_backups_weekly" | ||||
], | |||||
"monthly": [ | |||||
"frappe.email.doctype.auto_email_report.auto_email_report.send_monthly" | |||||
] | ] | ||||
} | } | ||||
@@ -50,7 +50,7 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ | |||||
cur_dialog = null; | cur_dialog = null; | ||||
} | } | ||||
} | } | ||||
me.onhide && me.onhide(); | |||||
me.onhide && me.onhide.apply(me); | |||||
}) | }) | ||||
.on("shown.bs.modal", function() { | .on("shown.bs.modal", function() { | ||||
// focus on first input | // focus on first input | ||||
@@ -86,7 +86,7 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ | |||||
.html(label) | .html(label) | ||||
.click(function() { | .click(function() { | ||||
me.primary_action_fulfilled = true; | me.primary_action_fulfilled = true; | ||||
click(); | |||||
click.apply(me); | |||||
}); | }); | ||||
}, | }, | ||||
make_head: function() { | make_head: function() { | ||||
@@ -12,6 +12,9 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({ | |||||
f.fieldname = f.label.replace(/ /g, "_").toLowerCase(); | f.fieldname = f.label.replace(/ /g, "_").toLowerCase(); | ||||
} | } | ||||
}) | }) | ||||
if(this.values) { | |||||
this.set_values(this.values); | |||||
} | |||||
}, | }, | ||||
make: function() { | make: function() { | ||||
var me = this; | var me = this; | ||||
@@ -32,7 +35,7 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({ | |||||
$(this.body).find('input').on('change', function() { | $(this.body).find('input').on('change', function() { | ||||
me.refresh_dependency(); | me.refresh_dependency(); | ||||
}) | }) | ||||
$(this.body).find('select').on("change", function() { | $(this.body).find('select').on("change", function() { | ||||
me.refresh_dependency(); | me.refresh_dependency(); | ||||
}) | }) | ||||
@@ -272,10 +272,10 @@ frappe.views.QueryReport = Class.extend({ | |||||
frappe.route_options = null; | frappe.route_options = null; | ||||
}, | }, | ||||
set_filters_by_name: function() { | set_filters_by_name: function() { | ||||
this.filters_by_name = {}; | |||||
frappe.query_report_filters_by_name = {}; | |||||
for(var i in this.filters) { | for(var i in this.filters) { | ||||
this.filters_by_name[this.filters[i].df.fieldname] = this.filters[i]; | |||||
frappe.query_report_filters_by_name[this.filters[i].df.fieldname] = this.filters[i]; | |||||
} | } | ||||
}, | }, | ||||
refresh: function() { | refresh: function() { | ||||