diff --git a/frappe/core/doctype/report/report.py b/frappe/core/doctype/report/report.py index 13e8b1c39e..3c229832be 100644 --- a/frappe/core/doctype/report/report.py +++ b/frappe/core/doctype/report/report.py @@ -50,13 +50,13 @@ class Report(Document): make_boilerplate("controller.py", 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''' out = [] if self.report_type in ('Query Report', 'Script Report'): # 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 += data.get('result') else: @@ -74,7 +74,7 @@ class Report(Document): 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], - 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) diff --git a/frappe/core/doctype/report/test_report.py b/frappe/core/doctype/report/test_report.py index 2875d5fd13..4223505cf6 100644 --- a/frappe/core/doctype/report/test_report.py +++ b/frappe/core/doctype/report/test_report.py @@ -22,7 +22,7 @@ class TestReport(unittest.TestCase): data = report.get_data(filters={'user': 'Administrator', 'doctype': 'DocType'}) self.assertEquals(data[0][0], 'Name') 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 user_activity_report = ''' diff --git a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js index 3cd36806fa..d54f166fd3 100644 --- a/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js +++ b/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js @@ -20,7 +20,7 @@ frappe.query_reports["Permitted Documents For User"] = { return { "query": "frappe.core.report.permitted_documents_for_user.permitted_documents_for_user.query_doctypes", "filters": { - "user": frappe.query_report.filters_by_name.user.get_value() + "user": frappe.query_report_filters_by_name.user.get_value() } } } diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index 9c55d2f8d8..c7a33d2c83 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -60,8 +60,10 @@ def get_script(report_name): } @frappe.whitelist() -def run(report_name, filters=None): +def run(report_name, filters=None, user=None): report = get_report_doc(report_name) + if not user: + user = frappe.session.user if not filters: filters = [] @@ -97,7 +99,7 @@ def run(report_name, filters=None): chart = res[3] 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: result = add_total_row(result, columns) @@ -158,14 +160,14 @@ def add_total_row(result, columns): result.append(total_row) return result -def get_filtered_data(ref_doctype, columns, data): +def get_filtered_data(ref_doctype, columns, data, user): result = [] linked_doctypes = get_linked_doctypes(columns, data) 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) - 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 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: 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) else: result = list(data) 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 - There is an owner match for the ref_doctype - `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: idx = linked_doctypes.get("User") if (idx is not None - and row[idx]==frappe.session.user + and row[idx]==user and columns_dict[idx]==columns_dict.get("owner")): # owner match is true matched_for_doctype = True diff --git a/frappe/email/doctype/auto_email_report/__init__.py b/frappe/email/doctype/auto_email_report/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/email/doctype/auto_email_report/auto_email_report.js b/frappe/email/doctype/auto_email_report/auto_email_report.js new file mode 100644 index 0000000000..96de43ffd0 --- /dev/null +++ b/frappe/email/doctype/auto_email_report/auto_email_report.js @@ -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 = $('
'+__('Filter')+' | '+__('Value')+' |
---|
' + __("Click table to edit") + '
').appendTo(wrapper); + var filters = JSON.parse(frm.doc.filters || '{}'); + var report_filters = frappe.query_reports[frm.doc.report].filters; + + report_filters.forEach(function(f) { + $('{0}
'.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() diff --git a/frappe/email/doctype/auto_email_report/test_auto_email_report.py b/frappe/email/doctype/auto_email_report/test_auto_email_report.py new file mode 100644 index 0000000000..72da43098b --- /dev/null +++ b/frappe/email/doctype/auto_email_report/test_auto_email_report.py @@ -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 \ No newline at end of file diff --git a/frappe/hooks.py b/frappe/hooks.py index 5361cea661..4b0234140a 100755 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -142,12 +142,16 @@ scheduler_events = { "frappe.utils.scheduler.disable_scheduler_on_expiry", "frappe.utils.scheduler.restrict_scheduler_events_if_dormant", "frappe.limits.update_space_usage", + "frappe.email.doctype.auto_email_report.auto_email_report.send_daily" ], "daily_long": [ "frappe.integrations.doctype.dropbox_backup.dropbox_backup.take_backups_daily" ], "weekly_long": [ "frappe.integrations.doctype.dropbox_backup.dropbox_backup.take_backups_weekly" + ], + "monthly": [ + "frappe.email.doctype.auto_email_report.auto_email_report.send_monthly" ] } diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index 8d6d894c77..b422286fbc 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -50,7 +50,7 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ cur_dialog = null; } } - me.onhide && me.onhide(); + me.onhide && me.onhide.apply(me); }) .on("shown.bs.modal", function() { // focus on first input @@ -86,7 +86,7 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ .html(label) .click(function() { me.primary_action_fulfilled = true; - click(); + click.apply(me); }); }, make_head: function() { diff --git a/frappe/public/js/frappe/ui/field_group.js b/frappe/public/js/frappe/ui/field_group.js index 935ced0e52..cabe74f85c 100644 --- a/frappe/public/js/frappe/ui/field_group.js +++ b/frappe/public/js/frappe/ui/field_group.js @@ -12,6 +12,9 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({ f.fieldname = f.label.replace(/ /g, "_").toLowerCase(); } }) + if(this.values) { + this.set_values(this.values); + } }, make: function() { var me = this; @@ -32,7 +35,7 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({ $(this.body).find('input').on('change', function() { me.refresh_dependency(); }) - + $(this.body).find('select').on("change", function() { me.refresh_dependency(); }) diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index d2791dc2b8..d76063d13d 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -272,10 +272,10 @@ frappe.views.QueryReport = Class.extend({ frappe.route_options = null; }, set_filters_by_name: function() { - this.filters_by_name = {}; + frappe.query_report_filters_by_name = {}; 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() {