<s> from functools import partial <EOL> import copy <EOL> import datetime <EOL> import numbers <EOL> import pytz <EOL> import json <EOL> import types <EOL> from django import template <EOL> from django . core . urlresolvers import reverse <EOL> from django . template . loader import render_to_string <EOL> from django . utils . translation import ugettext as _ <EOL> from django . utils . safestring import mark_safe <EOL> from django . utils . html import escape <EOL> from casexml . apps . case . models import CommCareCase <EOL> from casexml . apps . stock . utils import get_current_ledger_transactions <EOL> from corehq . apps . products . models import SQLProduct <EOL> from couchdbkit import ResourceNotFound <EOL> register = template . Library ( ) <EOL> DYNAMIC_CASE_PROPERTIES_COLUMNS = <NUM_LIT:4> <EOL> class CaseDisplayWrapper ( object ) : <EOL> def __init__ ( self , case ) : <EOL> self . case = case <EOL> def actions ( self ) : <EOL> actions = self . case . to_json ( ) [ '<STR_LIT>' ] <EOL> return actions . reverse ( ) <EOL> def to_full_dict ( self ) : <EOL> """<STR_LIT>""" <EOL> json = self . case . to_json ( ) <EOL> json [ '<STR_LIT:status>' ] = _ ( '<STR_LIT>' ) if self . case . closed else _ ( '<STR_LIT>' ) <EOL> return json <EOL> def get_display_config ( self ) : <EOL> return [ <EOL> { <EOL> "<STR_LIT>" : [ <EOL> [ <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT:name>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT:Name>" ) , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : True , <EOL> '<STR_LIT>' : True , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : True , <EOL> "<STR_LIT>" : True , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : True , <EOL> "<STR_LIT>" : True , <EOL> } , <EOL> ] , <EOL> [ <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT:type>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> } , <EOL> ] , <EOL> ] , <EOL> } <EOL> ] <EOL> def dynamic_properties ( self ) : <EOL> dynamic_data = self . case . dynamic_case_properties ( ) <EOL> if self . case . external_id : <EOL> dynamic_data [ '<STR_LIT>' ] = self . case . external_id <EOL> return dynamic_data <EOL> @ property <EOL> def related_cases_columns ( self ) : <EOL> return [ <EOL> { <EOL> '<STR_LIT:name>' : _ ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : "<STR_LIT:status>" <EOL> } , <EOL> { <EOL> '<STR_LIT:name>' : _ ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : "<STR_LIT:type>" , <EOL> } , <EOL> { <EOL> '<STR_LIT:name>' : _ ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : True , <EOL> "<STR_LIT>" : True , <EOL> } , <EOL> { <EOL> '<STR_LIT:name>' : _ ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : "<STR_LIT>" , <EOL> '<STR_LIT>' : True , <EOL> "<STR_LIT>" : True , <EOL> } <EOL> ] <EOL> @ property <EOL> def related_type_info ( self ) : <EOL> return None <EOL> class SupplyPointDisplayWrapper ( CaseDisplayWrapper ) : <EOL> def to_full_dict ( self ) : <EOL> from corehq . apps . locations . models import SQLLocation <EOL> data = super ( SupplyPointDisplayWrapper , self ) . to_full_dict ( ) <EOL> data . update ( { <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : None , <EOL> } ) <EOL> try : <EOL> location = SQLLocation . objects . get ( location_id = self . case . location_id ) <EOL> except ( SQLLocation . DoesNotExist , AttributeError ) : <EOL> pass <EOL> else : <EOL> data [ '<STR_LIT>' ] = location . location_type_name <EOL> data [ '<STR_LIT>' ] = location . site_code <EOL> if location . parent : <EOL> data [ '<STR_LIT>' ] = location . parent . name <EOL> return data <EOL> def get_display_config ( self ) : <EOL> return [ <EOL> { <EOL> "<STR_LIT>" : [ <EOL> [ <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT:name>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT:Name>" ) , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> } , <EOL> ] , <EOL> [ <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> } , <EOL> { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT:name>" : _ ( "<STR_LIT>" ) , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> } , <EOL> ] , <EOL> ] , <EOL> } <EOL> ] <EOL> def get_wrapped_case ( case ) : <EOL> from corehq . apps . commtrack import const <EOL> wrapper_class = { <EOL> const . SUPPLY_POINT_CASE_TYPE : SupplyPointDisplayWrapper , <EOL> } . get ( case . type , CaseDisplayWrapper ) <EOL> return wrapper_class ( case ) <EOL> def normalize_date ( val ) : <EOL> if type ( val ) == datetime . date : <EOL> return datetime . datetime . combine ( val , datetime . time . min ) <EOL> return val <EOL> @ register . simple_tag <EOL> def render_case ( case , options ) : <EOL> """<STR_LIT>""" <EOL> from corehq . apps . hqwebapp . templatetags . proptable_tags import get_tables_as_rows , get_default_definition <EOL> wrapped_case = get_wrapped_case ( case ) <EOL> timezone = options . get ( '<STR_LIT>' , pytz . utc ) <EOL> timezone = timezone . localize ( datetime . datetime . utcnow ( ) ) . tzinfo <EOL> _get_tables_as_rows = partial ( get_tables_as_rows , timezone = timezone ) <EOL> display = options . get ( '<STR_LIT>' ) or wrapped_case . get_display_config ( ) <EOL> show_transaction_export = options . get ( '<STR_LIT>' ) or False <EOL> get_case_url = options [ '<STR_LIT>' ] <EOL> data = copy . deepcopy ( wrapped_case . to_full_dict ( ) ) <EOL> default_properties = _get_tables_as_rows ( data , display ) <EOL> dynamic_data = wrapped_case . dynamic_properties ( ) <EOL> for section in display : <EOL> for row in section [ '<STR_LIT>' ] : <EOL> for item in row : <EOL> dynamic_data . pop ( item . get ( "<STR_LIT>" ) , None ) <EOL> if dynamic_data : <EOL> dynamic_keys = sorted ( dynamic_data . keys ( ) ) <EOL> definition = get_default_definition ( <EOL> dynamic_keys , num_columns = DYNAMIC_CASE_PROPERTIES_COLUMNS ) <EOL> dynamic_properties = _get_tables_as_rows ( dynamic_data , definition ) <EOL> else : <EOL> dynamic_properties = None <EOL> the_time_is_now = datetime . datetime . utcnow ( ) <EOL> tz_offset_ms = int ( timezone . utcoffset ( the_time_is_now ) . total_seconds ( ) ) * <NUM_LIT:1000> <EOL> tz_abbrev = timezone . localize ( the_time_is_now ) . tzname ( ) <EOL> def _product_name ( product_id ) : <EOL> try : <EOL> return SQLProduct . objects . get ( product_id = product_id ) . name <EOL> except SQLProduct . DoesNotExist : <EOL> return ( _ ( '<STR_LIT>' ) . format ( product_id ) ) <EOL> ledgers = get_current_ledger_transactions ( case . case_id ) <EOL> for section , product_map in ledgers . items ( ) : <EOL> product_tuples = sorted ( <EOL> ( _product_name ( product_id ) , product_map [ product_id ] ) for product_id in product_map <EOL> ) <EOL> ledgers [ section ] = product_tuples <EOL> return render_to_string ( "<STR_LIT>" , { <EOL> "<STR_LIT>" : default_properties , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : "<STR_LIT>" <EOL> } , <EOL> "<STR_LIT>" : dynamic_properties , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : "<STR_LIT>" <EOL> } , <EOL> "<STR_LIT>" : wrapped_case . case , <EOL> "<STR_LIT>" : mark_safe ( json . dumps ( wrapped_case . actions ( ) ) ) , <EOL> "<STR_LIT>" : timezone , <EOL> "<STR_LIT>" : tz_abbrev , <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : True , <EOL> "<STR_LIT>" : get_case_url , <EOL> "<STR_LIT>" : timezone <EOL> } , <EOL> "<STR_LIT>" : ledgers , <EOL> "<STR_LIT>" : tz_offset_ms , <EOL> "<STR_LIT>" : show_transaction_export , <EOL> "<STR_LIT>" : reverse ( '<STR_LIT>' , args = [ case . domain , case . case_id ] ) , <EOL> } ) <EOL> def get_inverse ( val ) : <EOL> if isinstance ( val , ( datetime . datetime , datetime . date ) ) : <EOL> return datetime . datetime . max - val <EOL> elif isinstance ( val , numbers . Number ) : <EOL> return <NUM_LIT:10> ** <NUM_LIT:20> <EOL> elif isinstance ( val , ( types . NoneType , bool ) ) : <EOL> return not val <EOL> else : <EOL> raise Exception ( "<STR_LIT>" % ( val , type ( val ) ) ) <EOL> def sortkey ( child , type_info = None ) : <EOL> """<STR_LIT>""" <EOL> type_info = type_info or { } <EOL> case = child [ '<STR_LIT>' ] <EOL> if case . closed : <EOL> key = [ <NUM_LIT:1> ] <EOL> try : <EOL> for attr , direction in type_info [ case . type ] [ '<STR_LIT>' ] : <EOL> val = normalize_date ( getattr ( case , attr ) ) <EOL> if direction . lower ( ) == '<STR_LIT>' : <EOL> val = get_inverse ( val ) <EOL> key . append ( val ) <EOL> except KeyError : <EOL> key . append ( datetime . datetime . max - case . closed_on ) <EOL> else : <EOL> key = [ <NUM_LIT:0> ] <EOL> try : <EOL> for attr , direction in type_info [ case . type ] [ '<STR_LIT>' ] : <EOL> val = normalize_date ( getattr ( case , attr ) ) <EOL> if direction . lower ( ) == '<STR_LIT>' : <EOL> val = get_inverse ( val ) <EOL> key . append ( val ) <EOL> except KeyError : <EOL> key . append ( case . opened_on or datetime . datetime . min ) <EOL> return key <EOL> def get_session_data ( case , current_case , type_info ) : <EOL> if type_info and case . type in type_info : <EOL> attr = type_info [ case . type ] [ '<STR_LIT>' ] <EOL> return { <EOL> attr : case . case_id , <EOL> '<STR_LIT>' : current_case . case_id <EOL> } <EOL> else : <EOL> return { <EOL> '<STR_LIT>' : case . case_id <EOL> } <EOL> TREETABLE_INDENT_PX = <NUM_LIT> <EOL> def process_case_hierarchy ( case_output , get_case_url , type_info ) : <EOL> current_case = case_output [ '<STR_LIT>' ] <EOL> submit_url_root = reverse ( '<STR_LIT>' , args = [ current_case . domain ] ) <EOL> form_url_root = reverse ( '<STR_LIT>' , args = [ current_case . domain , '<STR_LIT>' ] ) <EOL> def process_output ( case_output , depth = <NUM_LIT:0> ) : <EOL> for c in case_output [ '<STR_LIT>' ] : <EOL> process_output ( c , depth = depth + <NUM_LIT:1> ) <EOL> case = case_output [ '<STR_LIT>' ] <EOL> common_data = { <EOL> '<STR_LIT>' : depth * TREETABLE_INDENT_PX , <EOL> '<STR_LIT>' : submit_url_root , <EOL> '<STR_LIT>' : form_url_root , <EOL> '<STR_LIT>' : get_case_url ( case . case_id ) , <EOL> '<STR_LIT>' : get_session_data ( case , current_case , type_info ) <EOL> } <EOL> data = type_info . get ( case . type , { } ) <EOL> if '<STR_LIT>' in data : <EOL> data [ '<STR_LIT:description>' ] = getattr ( <EOL> case , data [ '<STR_LIT>' ] , None ) <EOL> if '<STR_LIT>' in data : <EOL> data [ '<STR_LIT>' ] . update ( data [ '<STR_LIT>' ] ) <EOL> data . update ( common_data ) <EOL> case . edit_data = data <EOL> if '<STR_LIT>' in data and not case . closed : <EOL> child_type = data [ '<STR_LIT>' ] <EOL> child_data = type_info . get ( child_type , { } ) <EOL> child_data . update ( common_data ) <EOL> child_data . update ( { <EOL> "<STR_LIT>" : _ ( "<STR_LIT>" ) % { <EOL> '<STR_LIT>' : child_data . get ( '<STR_LIT>' , child_type ) <EOL> } , <EOL> "<STR_LIT>" : case . case_id , <EOL> } ) <EOL> if '<STR_LIT>' in child_data : <EOL> child_data [ '<STR_LIT>' ] . update ( child_data [ '<STR_LIT>' ] ) <EOL> case . add_child_data = child_data <EOL> process_output ( case_output ) <EOL> def get_case_hierarchy ( case , type_info ) : <EOL> def get_children ( case , referenced_type = None , seen = None ) : <EOL> seen = seen or set ( ) <EOL> ignore_types = type_info . get ( case . type , { } ) . get ( "<STR_LIT>" , [ ] ) <EOL> if referenced_type and referenced_type in ignore_types : <EOL> return None <EOL> seen . add ( case . case_id ) <EOL> children = [ <EOL> get_children ( i . referenced_case , i . referenced_type , seen ) for i in case . reverse_indices <EOL> if i . referenced_id not in seen <EOL> ] <EOL> children = [ c for c in children if c is not None ] <EOL> descendant_types = [ ] <EOL> for c in children : <EOL> descendant_types . extend ( c [ '<STR_LIT>' ] ) <EOL> descendant_types = list ( set ( descendant_types ) ) <EOL> children = sorted ( children , key = partial ( sortkey , type_info = type_info ) ) <EOL> for c in children : <EOL> if not hasattr ( c [ '<STR_LIT>' ] , '<STR_LIT>' ) : <EOL> c [ '<STR_LIT>' ] . treetable_parent_node_id = case . case_id <EOL> child_cases = [ ] <EOL> for c in children : <EOL> child_cases . extend ( c [ '<STR_LIT>' ] ) <EOL> return { <EOL> '<STR_LIT>' : case , <EOL> '<STR_LIT>' : children , <EOL> '<STR_LIT>' : list ( set ( descendant_types + [ c [ '<STR_LIT>' ] . type for c in children ] ) ) , <EOL> '<STR_LIT>' : [ case ] + child_cases <EOL> } <EOL> return get_children ( case ) <EOL> def get_flat_descendant_case_list ( case , get_case_url , type_info = None ) : <EOL> type_info = type_info or { } <EOL> hierarchy = get_case_hierarchy ( case , type_info ) <EOL> process_case_hierarchy ( hierarchy , get_case_url , type_info ) <EOL> return hierarchy [ '<STR_LIT>' ] <EOL> @ register . simple_tag <EOL> def render_case_hierarchy ( case , options ) : <EOL> from corehq . apps . hqwebapp . templatetags . proptable_tags import get_display_data <EOL> wrapped_case = get_wrapped_case ( case ) <EOL> get_case_url = options . get ( '<STR_LIT>' ) <EOL> timezone = options . get ( '<STR_LIT>' , pytz . utc ) <EOL> columns = options . get ( '<STR_LIT>' ) or wrapped_case . related_cases_columns <EOL> show_view_buttons = options . get ( '<STR_LIT>' , True ) <EOL> type_info = options . get ( '<STR_LIT>' , wrapped_case . related_type_info ) <EOL> descendent_case_list = get_flat_descendant_case_list ( <EOL> case , get_case_url , type_info = type_info <EOL> ) <EOL> parent_cases = [ ] <EOL> if case . indices : <EOL> for idx in case . indices : <EOL> try : <EOL> parent_cases . append ( idx . referenced_case ) <EOL> except ResourceNotFound : <EOL> parent_cases . append ( None ) <EOL> for parent_case in parent_cases : <EOL> if parent_case : <EOL> parent_case . edit_data = { <EOL> '<STR_LIT>' : get_case_url ( parent_case . case_id ) <EOL> } <EOL> last_parent_id = parent_case . case_id <EOL> else : <EOL> last_parent_id = None <EOL> for c in descendent_case_list : <EOL> if not getattr ( c , '<STR_LIT>' , None ) and last_parent_id : <EOL> c . treetable_parent_node_id = last_parent_id <EOL> case_list = parent_cases + descendent_case_list <EOL> for c in case_list : <EOL> if not c : <EOL> continue <EOL> c . columns = [ ] <EOL> case_dict = get_wrapped_case ( c ) . to_full_dict ( ) <EOL> for column in columns : <EOL> c . columns . append ( get_display_data ( <EOL> case_dict , column , timezone = timezone ) ) <EOL> return render_to_string ( "<STR_LIT>" , { <EOL> '<STR_LIT>' : case , <EOL> '<STR_LIT>' : case . domain , <EOL> '<STR_LIT>' : case_list , <EOL> '<STR_LIT>' : columns , <EOL> '<STR_LIT>' : len ( columns ) + <NUM_LIT:1> , <EOL> '<STR_LIT>' : show_view_buttons , <EOL> } ) <EOL> @ register . simple_tag <EOL> def case_inline_display ( case ) : <EOL> """<STR_LIT>""" <EOL> if case : <EOL> if case . opened_on : <EOL> ret = "<STR_LIT>" % ( case . name , _ ( "<STR_LIT>" ) , case . opened_on . date ( ) ) <EOL> else : <EOL> ret = case . name <EOL> else : <EOL> ret = _ ( "<STR_LIT>" ) <EOL> return escape ( ret ) </s>
