From dca4e59e776e43c87da789fff3989cb8ff596be4 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 9 Jul 2013 11:55:25 +0530 Subject: [PATCH] [Report]Added permission to reports for showing data according to the user properties --- webnotes/widgets/query_report.py | 66 +++++++++++++++++++++++++++++++- webnotes/widgets/reportview.py | 34 +++++++++++----- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/webnotes/widgets/query_report.py b/webnotes/widgets/query_report.py index 4f22353e38..02e02ff4aa 100644 --- a/webnotes/widgets/query_report.py +++ b/webnotes/widgets/query_report.py @@ -24,10 +24,12 @@ from __future__ import unicode_literals import webnotes import os, json +import types from webnotes import _ from webnotes.modules import scrub, get_module_path from webnotes.utils import flt, cint +import webnotes.widgets.reportview @webnotes.whitelist() def get_script(report_name): @@ -67,6 +69,8 @@ def run(report_name, filters=None): method_name = scrub(webnotes.conn.get_value("DocType", report.ref_doctype, "module")) \ + ".report." + scrub(report.name) + "." + scrub(report.name) + ".execute" columns, result = webnotes.get_method(method_name)(filters or {}) + + result = get_filtered_data(report.ref_doctype, columns, result) if cint(report.add_total_row) and result: result = add_total_row(result, columns) @@ -88,4 +92,64 @@ def add_total_row(result, columns): total_row[0] = "Total" result.append(total_row) - return result \ No newline at end of file + return result + +def get_filtered_data(ref_doctype, columns, data): + result = [] + + linked_doctypes = get_linked_doctypes(columns) + match_filters = get_user_match_filters(linked_doctypes, ref_doctype) + + if match_filters: + matched_columns = get_matched_columns(linked_doctypes, match_filters) + for row in data: + match = True + for col, idx in matched_columns.items(): + if row[idx] not in match_filters[col]: + match = False + + if match: + result.append(row) + else: + for row in data: + result.append(row) + + return result + +def get_linked_doctypes(columns): + linked_doctypes = {} + + for idx, col in enumerate(columns): + if "Link" in col: + link_dt = col.split(":")[1].split("/")[1] + linked_doctypes[link_dt] = idx + + return linked_doctypes + +def get_user_match_filters(doctypes, ref_doctype): + match_filters = {} + doctypes_meta = {} + tables = [] + doctypes[ref_doctype] = None + + for dt in doctypes: + tables.append("`tab" + dt + "`") + doctypes_meta[dt] = webnotes.model.doctype.get(dt) + + webnotes.widgets.reportview.tables = tables + webnotes.widgets.reportview.doctypes = doctypes_meta + + for dt in doctypes: + match_filters = webnotes.widgets.reportview.build_match_conditions(dt, + None, False, match_filters) + + return match_filters + +def get_matched_columns(linked_doctypes, match_filters): + col_idx_map = {} + for dt, idx in linked_doctypes.items(): + link_field = dt.lower().replace(" ", "_") + if link_field in match_filters: + col_idx_map[link_field] = idx + + return col_idx_map \ No newline at end of file diff --git a/webnotes/widgets/reportview.py b/webnotes/widgets/reportview.py index 52aa899064..5377e0a7f7 100644 --- a/webnotes/widgets/reportview.py +++ b/webnotes/widgets/reportview.py @@ -123,7 +123,7 @@ def load_doctypes(): import webnotes.model.doctype roles = webnotes.get_roles() - + for t in tables: if t.startswith('`'): doctype = t[4:-1] @@ -190,8 +190,9 @@ def build_filter_conditions(filters, conditions): conditions.append('ifnull(' + tname + '.' + f[1] + ",0) " + f[2] \ + " " + cstr(f[3])) -def build_match_conditions(doctype, fields=None): +def build_match_conditions(doctype, fields=None, as_condition=True, match_filters={}): """add match conditions if applicable""" + global roles match_conditions = [] match = True @@ -199,7 +200,10 @@ def build_match_conditions(doctype, fields=None): global tables tables = get_tables(doctype, fields) load_doctypes() - + + if not roles: + roles = webnotes.get_roles() + for d in doctypes[doctype]: if d.doctype == 'DocPerm' and d.parent == doctype: if d.role in roles: @@ -208,20 +212,30 @@ def build_match_conditions(doctype, fields=None): document_key, default_key = d.match.split(":") else: default_key = document_key = d.match - - for v in webnotes.defaults.get_user_default_as_list(default_key) or ["** No Match **"]: - match_conditions.append('`tab%s`.%s="%s"' % (doctype, - document_key, v)) + for v in webnotes.defaults.get_user_default_as_list(default_key, \ + webnotes.session.user) or ["** No Match **"]: + if as_condition: + match_conditions.append('`tab%s`.%s="%s"' % (doctype, + document_key, v)) + else: + if v: + match_filters.setdefault(document_key, []) + if v not in match_filters[document_key]: + match_filters[document_key].append(v) elif d.read == 1 and d.permlevel == 0: # don't restrict if another read permission at level 0 # exists without a match restriction match = False - if match_conditions and match: - return '('+ ' or '.join(match_conditions) +')' + if as_condition: + if match_conditions and match: + return '('+ ' or '.join(match_conditions) +')' + else: + return "" else: - return "" + return match_filters + def get_tables(doctype, fields): """extract tables from fields"""