feat: Allow users to customize their own reports

This commit is contained in:
Daizy 2022-02-07 19:35:12 +05:30 committed by Sagar Vora
parent 71ceb496d1
commit ddd45a71bc
3 changed files with 129 additions and 18 deletions

View file

@ -4,6 +4,7 @@
import frappe, json, os
import unittest
from frappe.desk.query_report import run, save_report
from frappe.desk.reportview import delete_report, save_report as save_as_report
from frappe.custom.doctype.customize_form.customize_form import reset_customization
test_records = frappe.get_test_records('Report')
@ -30,6 +31,57 @@ class TestReport(unittest.TestCase):
self.assertEqual(columns[1].get('label'), 'Module')
self.assertTrue('User' in [d.get('name') for d in data])
def test_can_save_or_delete_report(self):
'''Test case to test if if users can create, save or delete their own report of type Report Builder'''
frappe.set_user("Administrator")
report = frappe.get_doc({
'doctype': 'Report',
'ref_doctype': 'User',
'report_name': 'Test Delete Report',
'report_type': 'Report Builder',
'is_standard': 'No',
}).insert()
frappe.set_user("test@example.com")
self.assertRaisesRegex(frappe.exceptions.ValidationError, "Only Report owner or Report Manager can delete the reports", delete_report, report.name)
frappe.set_user("Administrator")
report.report_type = 'Custom Report' # change report type to validate
report.save()
self.assertRaisesRegex(frappe.exceptions.ValidationError, "Only reports of type Report Builder can be deleted", delete_report, report.name)
report.is_standard = 'Yes' # change is_standard to validate
report.save()
self.assertRaisesRegex(frappe.exceptions.ValidationError, "Standard Reports can not be deleted", delete_report, report.name)
frappe.set_user("test@example.com")
report_name = save_as_report(
'Dummy Report',
'User',
json.dumps([{
'fieldname': 'email',
'fieldtype': 'Data',
'label': 'Email',
'insert_after_index': 0,
'link_field': 'name',
'doctype': 'User',
'options': 'Email',
'width': 100,
'id':'email',
'name': 'Email'
}])
)
doc = frappe.get_doc("Report", report_name)
delete_report(doc.name)
def test_custom_report(self):
reset_customization('User')
custom_report_name = save_report(

View file

@ -262,23 +262,47 @@ def compress(data, args=None):
}
@frappe.whitelist()
def save_report():
"""save report"""
def save_report(name, doctype, report_settings):
"""save report if report type is report builder"""
data = frappe.local.form_dict
if frappe.db.exists('Report', data['name']):
d = frappe.get_doc('Report', data['name'])
if frappe.db.exists('Report', name):
d = frappe.get_doc('Report', name)
if d.is_standard == "Yes":
frappe.throw(_("Standard Reports can not be edited"))
if d.report_type != "Report Builder":
frappe.throw(_("Only reports of type Report Builder can be created"))
if d.owner != frappe.session.user:
frappe.throw(_("Only Report owner or Report Manager can save the reports"))
else:
d = frappe.new_doc('Report')
d.report_name = data['name']
d.ref_doctype = data['doctype']
d.report_name = name
d.ref_doctype = doctype
d.report_type = "Report Builder"
d.json = data['json']
frappe.get_doc(d).save()
d.json = report_settings
frappe.get_doc(d).save(ignore_permissions=True)
frappe.msgprint(_("{0} is saved").format(d.name), alert=True)
return d.name
@frappe.whitelist()
def delete_report(name):
"""delete report type of report builder if user is report owner or has role Report Manager"""
report_doc = frappe.get_doc("Report", name)
if report_doc.is_standard == "Yes":
frappe.throw(_("Standard Reports can not be deleted"))
if report_doc.report_type != "Report Builder":
frappe.throw(_("Only reports of type Report Builder can be deleted"))
if report_doc.owner != frappe.session.user:
frappe.throw(_("Only Report owner or Report Manager can delete the reports"))
report_doc.delete(ignore_permissions=True)
frappe.msgprint(_("{0} is Deleted").format(report_doc.name), alert=True)
@frappe.whitelist()
@frappe.read_only()
def export_query():

View file

@ -18,14 +18,14 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
setup_defaults() {
super.setup_defaults();
this.page_title = __('Report:') + ' ' + this.page_title;
this.menu_items = this.report_menu_items();
this.view = 'Report';
const route = frappe.get_route();
if (route.length === 4) {
this.report_name = route[3];
}
this.view = 'Report';
if (this.report_name) {
return this.get_report_doc()
.then(doc => {
@ -39,6 +39,7 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
this.page_length = this.report_doc.json.page_length || 20;
this.order_by = this.report_doc.json.order_by || 'modified desc';
this.chart_args = this.report_doc.json.chart_args;
this.menu_items = this.report_menu_items();
});
} else {
this.add_totals_row = this.view_user_settings.add_totals_row || 0;
@ -1207,7 +1208,7 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
args: {
name: name,
doctype: this.doctype,
json: JSON.stringify(report_settings)
report_settings: JSON.stringify(report_settings)
},
callback:(r) => {
if(r.exc) {
@ -1244,6 +1245,25 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
}
}
delete_report() {
const _delete_report = (name) => {
return frappe.call({
method: 'frappe.desk.reportview.delete_report',
args: { name },
callback: (r) => {
if (r.exc) {
frappe.msgprint(__("Report was not deleted (there were errors)"));
return;
}
}
});
}
if (this.report_name) {
_delete_report(this.report_name);
}
}
get_column_widths() {
if (this.datatable) {
return this.datatable
@ -1465,12 +1485,27 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
}
});
// save buttons
if(frappe.user.is_report_manager()) {
items = items.concat([
{ label: __('Save'), action: () => this.save_report('save') },
{ label: __('Save As'), action: () => this.save_report('save_as') }
]);
const can_save_or_delete = this.report_doc.owner === frappe.session.user || frappe.user.is_report_manager()
// A user with role Report Manager or Report Owner can save
if (can_save_or_delete) {
items.push({
label: __("Save"),
action: () => this.save_report('save')
});
}
// anyone can save as
items.push({
label: __('Save As'),
action: () => this.save_report('save_as')
});
// A user with role Report Manager or Report Owner can delete
if (can_save_or_delete) {
items.push({
label: __("Delete"),
action: () => this.delete_report()
});
}
// user permissions