<s> import calendar <EOL> from datetime import datetime <EOL> from dateutil . relativedelta import relativedelta <EOL> from lxml import etree as ElementTree <EOL> from django . utils . translation import ugettext as _ <EOL> from corehq . apps . domain . models import Domain <EOL> from corehq . apps . commtrack . util import get_commtrack_location_id <EOL> from corehq . apps . locations . models import Location <EOL> from custom . m4change . constants import M4CHANGE_DOMAINS , NUMBER_OF_MONTHS_FOR_FIXTURES <EOL> from custom . m4change . models import FixtureReportResult <EOL> from custom . m4change . reports . reports import M4ChangeReportDataSource <EOL> from dimagi . utils . parsing import json_format_date <EOL> def get_last_n_months ( months ) : <EOL> ranges = [ ] <EOL> today = datetime . utcnow ( ) <EOL> for month in range ( months ) : <EOL> month_start = datetime ( today . year , today . month , <NUM_LIT:1> ) - relativedelta ( months = month ) <EOL> last_day_of_month = get_last_day_of_month ( month_start , today ) <EOL> month_end = datetime ( month_start . year , month_start . month , last_day_of_month ) <EOL> ranges . insert ( <NUM_LIT:0> , ( month_start , month_end ) ) <EOL> return ranges <EOL> def get_last_month ( ) : <EOL> return get_last_n_months ( <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> def get_last_day_of_month ( month_start , today ) : <EOL> return today . day if month_start . month == today . month else calendar . monthrange ( month_start . year , month_start . month ) [ <NUM_LIT:1> ] <EOL> class ReportFixtureProvider ( object ) : <EOL> id = '<STR_LIT>' <EOL> def __call__ ( self , user , version , last_sync = None , app = None ) : <EOL> if user . domain in M4CHANGE_DOMAINS : <EOL> domain = Domain . get_by_name ( user . domain ) <EOL> location_id = get_commtrack_location_id ( user , domain ) <EOL> if location_id is not None : <EOL> fixture = self . get_fixture ( user , domain , location_id ) <EOL> if fixture is None : <EOL> return [ ] <EOL> return [ fixture ] <EOL> else : <EOL> return [ ] <EOL> else : <EOL> return [ ] <EOL> def get_fixture ( self , user , domain , location_id ) : <EOL> """<STR_LIT>""" <EOL> def _reports_to_fixture ( data , facility_element ) : <EOL> for report_key in sorted ( data ) : <EOL> columns_added = False <EOL> report_data = data . get ( report_key , { } ) <EOL> report_element = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> "<STR_LIT:id>" : report_key , <EOL> "<STR_LIT:name>" : report_data . name <EOL> } ) <EOL> columns_element = ElementTree . Element ( '<STR_LIT>' ) <EOL> rows_element = ElementTree . Element ( '<STR_LIT>' ) <EOL> report_rows = sorted ( report_data . rows . items ( ) , key = lambda t : t [ <NUM_LIT:1> ] [ "<STR_LIT>" ] <EOL> if t [ <NUM_LIT:1> ] . get ( "<STR_LIT>" , None ) is not None else t [ <NUM_LIT:1> ] . get ( "<STR_LIT>" ) ) <EOL> for row in report_rows : <EOL> row_data = row [ <NUM_LIT:1> ] <EOL> if not columns_added : <EOL> for column_key in sorted ( row_data ) : <EOL> column = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> '<STR_LIT:name>' : column_key <EOL> } ) <EOL> columns_element . append ( column ) <EOL> columns_added = True <EOL> row_element = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> '<STR_LIT>' : str ( row_data . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> } ) <EOL> for field_key in sorted ( row_data ) : <EOL> field_element = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> '<STR_LIT:value>' : str ( row_data . get ( field_key , '<STR_LIT>' ) ) <EOL> } ) <EOL> row_element . append ( field_element ) <EOL> rows_element . append ( row_element ) <EOL> report_element . append ( columns_element ) <EOL> report_element . append ( rows_element ) <EOL> facility_element . append ( report_element ) <EOL> return facility_element <EOL> def _facility_to_fixture ( facility , startdate , enddate ) : <EOL> facility_id = facility . get_id <EOL> facility_element = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> '<STR_LIT:id>' : facility_id , <EOL> '<STR_LIT:name>' : _ ( facility . name ) <EOL> } ) <EOL> report_data = { } <EOL> m4change_data_source = M4ChangeReportDataSource ( ) <EOL> report_slugs = m4change_data_source . get_report_slugs ( ) <EOL> reports = dict ( ( report . slug , report ) for report in m4change_data_source . get_reports ( ) ) <EOL> for report_slug in report_slugs : <EOL> report_data [ report_slug ] = FixtureReportResult . by_composite_key ( <EOL> domain . name , facility_id , json_format_date ( startdate ) , <EOL> json_format_date ( enddate ) , report_slug ) <EOL> if report_data [ report_slug ] is None : <EOL> name = reports [ report_slug ] . name <EOL> rows = reports [ report_slug ] . get_initial_row_data ( ) <EOL> fixture_result = FixtureReportResult ( domain = domain . name , location_id = facility_id , <EOL> start_date = startdate , end_date = enddate , report_slug = report_slug , <EOL> rows = rows , name = name ) <EOL> report_data [ report_slug ] = fixture_result <EOL> facility_element = ( _reports_to_fixture ( report_data , facility_element ) ) <EOL> return facility_element <EOL> def _month_to_fixture ( date_tuple , locations ) : <EOL> monthly_report_element = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> '<STR_LIT>' : json_format_date ( date_tuple [ <NUM_LIT:0> ] ) , <EOL> '<STR_LIT>' : json_format_date ( date_tuple [ <NUM_LIT:1> ] ) , <EOL> '<STR_LIT>' : date_tuple [ <NUM_LIT:0> ] . strftime ( '<STR_LIT>' ) <EOL> } ) <EOL> for location in locations : <EOL> facility_element = _facility_to_fixture ( location , date_tuple [ <NUM_LIT:0> ] , date_tuple [ <NUM_LIT:1> ] ) <EOL> if facility_element : <EOL> monthly_report_element . append ( facility_element ) <EOL> else : <EOL> return None <EOL> return monthly_report_element <EOL> root = ElementTree . Element ( '<STR_LIT>' , attrib = { <EOL> '<STR_LIT:id>' : self . id , <EOL> '<STR_LIT>' : user . _id <EOL> } ) <EOL> months_element = ElementTree . Element ( '<STR_LIT>' ) <EOL> user_location = Location . get ( location_id ) <EOL> locations = [ user_location ] + [ descendant for descendant in user_location . descendants ] <EOL> dates = get_last_n_months ( NUMBER_OF_MONTHS_FOR_FIXTURES ) <EOL> for date_tuple in dates : <EOL> monthly_element = _month_to_fixture ( date_tuple , locations ) <EOL> if monthly_element : <EOL> months_element . append ( monthly_element ) <EOL> else : <EOL> return None <EOL> root . append ( months_element ) <EOL> return root <EOL> generator = ReportFixtureProvider ( ) </s>
