<s> from __future__ import unicode_literals <EOL> import frappe <EOL> import os , json <EOL> from frappe import _ <EOL> from frappe . modules import scrub , get_module_path <EOL> from frappe . utils import flt , cint , get_html_format , cstr <EOL> from frappe . translate import send_translations <EOL> import frappe . desk . reportview <EOL> from frappe . permissions import get_role_permissions <EOL> def get_report_doc ( report_name ) : <EOL> doc = frappe . get_doc ( "<STR_LIT>" , report_name ) <EOL> if not doc . has_permission ( "<STR_LIT>" ) : <EOL> frappe . throw ( _ ( "<STR_LIT>" ) . format ( report_name ) , frappe . PermissionError ) <EOL> if not frappe . has_permission ( doc . ref_doctype , "<STR_LIT>" ) : <EOL> frappe . throw ( _ ( "<STR_LIT>" ) . format ( doc . ref_doctype ) , <EOL> frappe . PermissionError ) <EOL> if doc . disabled : <EOL> frappe . throw ( _ ( "<STR_LIT>" ) . format ( report_name ) ) <EOL> return doc <EOL> @ frappe . whitelist ( ) <EOL> def get_script ( report_name ) : <EOL> report = get_report_doc ( report_name ) <EOL> module = report . module or frappe . db . get_value ( "<STR_LIT>" , report . ref_doctype , "<STR_LIT>" ) <EOL> module_path = get_module_path ( module ) <EOL> report_folder = os . path . join ( module_path , "<STR_LIT>" , scrub ( report . name ) ) <EOL> script_path = os . path . join ( report_folder , scrub ( report . name ) + "<STR_LIT>" ) <EOL> print_path = os . path . join ( report_folder , scrub ( report . name ) + "<STR_LIT>" ) <EOL> script = None <EOL> if os . path . exists ( script_path ) : <EOL> with open ( script_path , "<STR_LIT:r>" ) as f : <EOL> script = f . read ( ) <EOL> html_format = get_html_format ( print_path ) <EOL> if not script and report . javascript : <EOL> script = report . javascript <EOL> if not script : <EOL> script = "<STR_LIT>" % report_name <EOL> if frappe . lang != "<STR_LIT>" : <EOL> send_translations ( frappe . get_lang_dict ( "<STR_LIT>" , report_name ) ) <EOL> return { <EOL> "<STR_LIT>" : script , <EOL> "<STR_LIT>" : html_format <EOL> } <EOL> @ frappe . whitelist ( ) <EOL> def run ( report_name , filters = ( ) ) : <EOL> report = get_report_doc ( report_name ) <EOL> if filters and isinstance ( filters , basestring ) : <EOL> filters = json . loads ( filters ) <EOL> if not frappe . has_permission ( report . ref_doctype , "<STR_LIT>" ) : <EOL> frappe . msgprint ( _ ( "<STR_LIT>" ) , <EOL> raise_exception = True ) <EOL> columns , result , message = [ ] , [ ] , None <EOL> if report . report_type == "<STR_LIT>" : <EOL> if not report . query : <EOL> frappe . msgprint ( _ ( "<STR_LIT>" ) , raise_exception = True ) <EOL> if not report . query . lower ( ) . startswith ( "<STR_LIT>" ) : <EOL> frappe . msgprint ( _ ( "<STR_LIT>" ) , raise_exception = True ) <EOL> result = [ list ( t ) for t in frappe . db . sql ( report . query , filters ) ] <EOL> columns = [ cstr ( c [ <NUM_LIT:0> ] ) for c in frappe . db . get_description ( ) ] <EOL> else : <EOL> module = report . module or frappe . db . get_value ( "<STR_LIT>" , report . ref_doctype , "<STR_LIT>" ) <EOL> if report . is_standard == "<STR_LIT>" : <EOL> method_name = get_report_module_dotted_path ( module , report . name ) + "<STR_LIT>" <EOL> res = frappe . get_attr ( method_name ) ( frappe . _dict ( filters ) ) <EOL> columns , result = res [ <NUM_LIT:0> ] , res [ <NUM_LIT:1> ] <EOL> if len ( res ) > <NUM_LIT:2> : <EOL> message = res [ <NUM_LIT:2> ] <EOL> if report . apply_user_permissions and result : <EOL> result = get_filtered_data ( report . ref_doctype , columns , result ) <EOL> if cint ( report . add_total_row ) and result : <EOL> result = add_total_row ( result , columns ) <EOL> return { <EOL> "<STR_LIT:result>" : result , <EOL> "<STR_LIT>" : columns , <EOL> "<STR_LIT:message>" : message <EOL> } <EOL> def get_report_module_dotted_path ( module , report_name ) : <EOL> return frappe . local . module_app [ scrub ( module ) ] + "<STR_LIT:.>" + scrub ( module ) + "<STR_LIT>" + scrub ( report_name ) + "<STR_LIT:.>" + scrub ( report_name ) <EOL> def add_total_row ( result , columns ) : <EOL> total_row = [ "<STR_LIT>" ] * len ( columns ) <EOL> has_percent = [ ] <EOL> for row in result : <EOL> for i , col in enumerate ( columns ) : <EOL> fieldtype = None <EOL> if isinstance ( col , basestring ) : <EOL> col = col . split ( "<STR_LIT::>" ) <EOL> if len ( col ) > <NUM_LIT:1> : <EOL> fieldtype = col [ <NUM_LIT:1> ] <EOL> if "<STR_LIT:/>" in fieldtype : <EOL> fieldtype = fieldtype . split ( "<STR_LIT:/>" ) [ <NUM_LIT:0> ] <EOL> else : <EOL> fieldtype = col . get ( "<STR_LIT>" ) <EOL> if fieldtype in [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] and flt ( row [ i ] ) : <EOL> total_row [ i ] = flt ( total_row [ i ] ) + flt ( row [ i ] ) <EOL> if fieldtype == "<STR_LIT>" and i not in has_percent : <EOL> has_percent . append ( i ) <EOL> for i in has_percent : <EOL> total_row [ i ] = total_row [ i ] / len ( result ) <EOL> first_col_fieldtype = None <EOL> if isinstance ( columns [ <NUM_LIT:0> ] , basestring ) : <EOL> first_col = columns [ <NUM_LIT:0> ] . split ( "<STR_LIT::>" ) <EOL> if len ( first_col ) > <NUM_LIT:1> : <EOL> first_col_fieldtype = first_col [ <NUM_LIT:1> ] . split ( "<STR_LIT:/>" ) [ <NUM_LIT:0> ] <EOL> else : <EOL> first_col_fieldtype = columns [ <NUM_LIT:0> ] . get ( "<STR_LIT>" ) <EOL> if first_col_fieldtype not in [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] : <EOL> if first_col_fieldtype == "<STR_LIT>" : <EOL> total_row [ <NUM_LIT:0> ] = "<STR_LIT:'>" + _ ( "<STR_LIT>" ) + "<STR_LIT:'>" <EOL> else : <EOL> total_row [ <NUM_LIT:0> ] = _ ( "<STR_LIT>" ) <EOL> result . append ( total_row ) <EOL> return result <EOL> def get_filtered_data ( ref_doctype , columns , data ) : <EOL> result = [ ] <EOL> linked_doctypes = get_linked_doctypes ( columns , data ) <EOL> match_filters_per_doctype = get_user_match_filters ( linked_doctypes , ref_doctype ) <EOL> shared = frappe . share . get_shared ( ref_doctype ) <EOL> columns_dict = get_columns_dict ( columns ) <EOL> role_permissions = get_role_permissions ( frappe . get_meta ( ref_doctype ) ) <EOL> if_owner = role_permissions . get ( "<STR_LIT>" , { } ) . get ( "<STR_LIT>" ) <EOL> if match_filters_per_doctype : <EOL> for row in data : <EOL> if linked_doctypes . get ( ref_doctype ) and shared and row [ linked_doctypes [ ref_doctype ] ] in shared : <EOL> result . append ( row ) <EOL> elif has_match ( row , linked_doctypes , match_filters_per_doctype , ref_doctype , if_owner , columns_dict ) : <EOL> result . append ( row ) <EOL> else : <EOL> result = list ( data ) <EOL> return result <EOL> def has_match ( row , linked_doctypes , doctype_match_filters , ref_doctype , if_owner , columns_dict ) : <EOL> """<STR_LIT>""" <EOL> resultant_match = True <EOL> if not row : <EOL> return resultant_match <EOL> for doctype , filter_list in doctype_match_filters . items ( ) : <EOL> matched_for_doctype = False <EOL> if doctype == ref_doctype and if_owner : <EOL> idx = linked_doctypes . get ( "<STR_LIT>" ) <EOL> if ( idx is not None <EOL> and row [ idx ] == frappe . session . user <EOL> and columns_dict [ idx ] == columns_dict . get ( "<STR_LIT>" ) ) : <EOL> matched_for_doctype = True <EOL> if not matched_for_doctype : <EOL> for match_filters in filter_list : <EOL> match = True <EOL> for dt , idx in linked_doctypes . items ( ) : <EOL> if dt == "<STR_LIT>" and columns_dict [ idx ] == columns_dict . get ( "<STR_LIT>" ) : <EOL> continue <EOL> if dt in match_filters and row [ idx ] not in match_filters [ dt ] : <EOL> match = False <EOL> break <EOL> matched_for_doctype = matched_for_doctype or match <EOL> if matched_for_doctype : <EOL> break <EOL> resultant_match = resultant_match and matched_for_doctype <EOL> if not resultant_match : <EOL> break <EOL> return resultant_match <EOL> def get_linked_doctypes ( columns , data ) : <EOL> linked_doctypes = { } <EOL> columns_dict = get_columns_dict ( columns ) <EOL> for idx , col in enumerate ( columns ) : <EOL> df = columns_dict [ idx ] <EOL> if df . get ( "<STR_LIT>" ) == "<STR_LIT>" : <EOL> if isinstance ( col , basestring ) : <EOL> linked_doctypes [ df [ "<STR_LIT>" ] ] = idx <EOL> else : <EOL> linked_doctypes [ df [ "<STR_LIT>" ] ] = df [ "<STR_LIT>" ] <EOL> columns_with_value = [ ] <EOL> for row in data : <EOL> if row : <EOL> if len ( row ) != len ( columns_with_value ) : <EOL> if isinstance ( row , ( list , tuple ) ) : <EOL> row = enumerate ( row ) <EOL> elif isinstance ( row , dict ) : <EOL> row = row . items ( ) <EOL> for col , val in row : <EOL> if val and col not in columns_with_value : <EOL> columns_with_value . append ( col ) <EOL> for doctype , key in linked_doctypes . items ( ) : <EOL> if key not in columns_with_value : <EOL> del linked_doctypes [ doctype ] <EOL> return linked_doctypes <EOL> def get_columns_dict ( columns ) : <EOL> """<STR_LIT>""" <EOL> columns_dict = { } <EOL> for idx , col in enumerate ( columns ) : <EOL> col_dict = { } <EOL> if isinstance ( col , basestring ) : <EOL> col = col . split ( "<STR_LIT::>" ) <EOL> if len ( col ) > <NUM_LIT:1> : <EOL> if "<STR_LIT:/>" in col [ <NUM_LIT:1> ] : <EOL> col_dict [ "<STR_LIT>" ] , col_dict [ "<STR_LIT>" ] = col [ <NUM_LIT:1> ] . split ( "<STR_LIT:/>" ) <EOL> else : <EOL> col_dict [ "<STR_LIT>" ] = col [ <NUM_LIT:1> ] <EOL> col_dict [ "<STR_LIT>" ] = frappe . scrub ( col [ <NUM_LIT:0> ] ) <EOL> else : <EOL> col_dict . update ( col ) <EOL> if "<STR_LIT>" not in col_dict : <EOL> col_dict [ "<STR_LIT>" ] = frappe . scrub ( col_dict [ "<STR_LIT:label>" ] ) <EOL> columns_dict [ idx ] = col_dict <EOL> columns_dict [ col_dict [ "<STR_LIT>" ] ] = col_dict <EOL> return columns_dict <EOL> def get_user_match_filters ( doctypes , ref_doctype ) : <EOL> match_filters = { } <EOL> for dt in doctypes : <EOL> filter_list = frappe . desk . reportview . build_match_conditions ( dt , False ) <EOL> if filter_list : <EOL> match_filters [ dt ] = filter_list <EOL> return match_filters </s>
