def test_needs_additional_target_periods_false(self): p = RFProgramFactory() RFIndicatorFactory(program=p, target_frequency=Indicator.TRI_ANNUAL, targets=500) data = ProgramPageProgramSerializer( Program.program_page_objects.filter(pk=p.pk), many=True ).data[0] self.assertFalse(data['needs_additional_target_periods'])
def program_page(request, program): """Program Page Template view - returns the program page template with JSON populated for React logic""" # redirect to home if program isn't active or doesn't exist: try: program = Program.rf_aware_objects.only( 'reporting_period_start', 'reporting_period_end').get(pk=int(program)) except (Program.DoesNotExist, ValueError): return redirect('/') # redirect to setup page if reporting period isn't complete: if any([ program.reporting_period_start is None, program.reporting_period_end is None ]): return render(request, 'indicators/program_setup_incomplete.html', { 'program': program, 'redirect_url': request.path }) context = { 'program': ProgramPageProgramSerializer.get_for_pk(program.pk).data, 'pinned_reports': list( PinnedReport.objects.filter(program_id=program.pk, tola_user=request.user.tola_user)) + [PinnedReport.default_report(program.pk)], 'delete_pinned_report_url': reverse('delete_pinned_report'), 'indicator_on_scope_margin': Indicator.ONSCOPE_MARGIN, 'readonly': not request.has_write_access, } return render(request, 'indicators/program_page.html', context)
def test_needs_additional_target_periods_no_targets(self): p = RFProgramFactory() RFIndicatorFactory(program=p) data = ProgramPageProgramSerializer( Program.program_page_objects.filter(pk=p.pk), many=True ).data[0] self.assertFalse(data['needs_additional_target_periods'])
def test_rf_program_two_indicators_update_only(self): p = RFProgramFactory( tiers=['Tier1', 'Tier2'], levels=1, ) expected_pks = [] levels = sorted(p.levels.all(), key=operator.attrgetter('level_depth')) for level in levels: expected_pks.append(RFIndicatorFactory(program=p, level=level).pk) indicator = RFIndicatorFactory(program=p, level=levels[1], name='Test Name') expected_pks.append(indicator.pk) full_data = ProgramPageProgramSerializer.get_for_pk(p.pk).data with self.assertNumQueries(5): data = ProgramPageUpdateSerializer.update_indicator_pk(p.pk, indicator.pk).data self.assertEqual(len(data), 5) self.assertEqual(data['pk'], p.pk) self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order']) indicator_pks = data['indicator_pks_level_order'] self.assertEqual(indicator_pks, expected_pks) self.assertEqual(data['indicator']['name'], 'Test Name') for indicator_pk in full_data['indicators']: self.assertIn(indicator_pk, data['indicators']) self.assertEqual( full_data['indicators'][indicator_pk]['number'], data['indicators'][indicator_pk]['number'] )
def test_rf_program_two_indicators(self): p = RFProgramFactory( tiers=['Tier1', 'Tier2'], levels=1, reporting_period_start=datetime.date(2014, 5, 1) ) for level in p.levels.all(): RFIndicatorFactory(program=p, level=level) with self.assertNumQueries(4): data = ProgramPageProgramSerializer.get_for_pk(p.pk).data self.assertEqual(data['pk'], p.pk) self.assertEqual(data['name'], p.name) self.assertTrue(data['results_framework']) self.assertEqual(data['by_result_chain'], 'by Tier2 chain') self.assertEqual(data['reporting_period_start_iso'], '2014-05-01') self.assertEqual(data['site_count'], 0) self.assertTrue(data['has_levels']) self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order']) indicator_pks = data['indicator_pks_level_order'] self.assertEqual(len(indicator_pks), 2) indicators_data = data['indicators'] self.assertEqual(len(indicators_data), 2) goal_indicator_data = indicators_data[indicator_pks[0]] self.assertEqual(goal_indicator_data['number'], 'Tier1 a') output_indicator_data = indicators_data[indicator_pks[1]] self.assertEqual(output_indicator_data['number'], 'Tier2 1a')
def test_manual_numbering(self): p = RFProgramFactory(tiers=['Tier1', 'Tier2', 'Tier3'], levels=1, auto_number_indicators=False) levels = list( sorted( sorted( [l for l in p.levels.all()], key=lambda l: l.customsort ), key=lambda l: l.level_depth ) ) numbers = ['482', '28.C', '999'] pks = [] for level, number in zip(list(reversed(levels)), numbers): pks.append( RFIndicatorFactory( program=p, level=level, number=number ).pk ) expected_pks = list(reversed(pks)) expected_numbers = list(reversed(numbers)) with self.assertNumQueries(4): data = ProgramPageProgramSerializer.get_for_pk(p.pk).data self.assertEqual(len(data['indicators']), 3) self.assertEqual(data['indicator_pks_level_order'], expected_pks) self.assertEqual(data['indicator_pks_chain_order'], expected_pks) for pk, number in zip(expected_pks, expected_numbers): self.assertEqual(data['indicators'][pk]['number'], number)
def api_program_page(request, program): """Returns program JSON to hydrate Program Page react models""" try: data = ProgramPageProgramSerializer.get_for_pk(program).data except Program.DoesNotExist: logger.warning( 'attempt to access program page ordering for bad pk {}'.format( program)) return JsonResponse({'success': False, 'msg': 'bad Program PK'}) return JsonResponse(data)
def test_unmigrated_program(self): p = RFProgramFactory(migrated=False) pks = [] old_levels_numbers = [ ('Activity', '5'), ('Activity', '3'), ('Outcome', '3.4'), ('Outcome', '2.8'), ('Outcome', '2.2') ] for old_level, number in old_levels_numbers: pks.append( RFIndicatorFactory( program=p, old_level=old_level, number=number, target_frequency=Indicator.SEMI_ANNUAL, targets=400, results=550 ).pk ) expected_pks = list(reversed(pks)) with self.assertNumQueries(4): data = ProgramPageProgramSerializer.get_for_pk(p.pk).data self.assertFalse(data['has_levels']) self.assertEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order']) indicator_pks = data['indicator_pks_level_order'] self.assertEqual(expected_pks, indicator_pks) for (old_level, number), pk in zip(old_levels_numbers, pks): indicator_data = data['indicators'][pk] self.assertEqual(indicator_data['number'], u'{}'.format(number)) self.assertEqual(indicator_data['old_level_name'], old_level) self.assertTrue(indicator_data['is_reporting']) self.assertEqual(indicator_data['over_under'], 1) self.assertEqual(data['indicators'][pks[0]]['level_pk'], 6) self.assertEqual(data['indicators'][pks[3]]['level_pk'], 3) translation.activate('fr') with self.assertNumQueries(4): french_data = ProgramPageProgramSerializer.get_for_pk(p.pk).data translation.activate('en') self.assertEqual(french_data['indicators'][pks[0]]['old_level_name'], u'Activité') self.assertEqual(french_data['indicators'][pks[4]]['old_level_name'], u'Résultat')
def test_time_period_info_non_time_aware(self): p = RFProgramFactory() for frequency in [Indicator.LOP, Indicator.MID_END]: RFIndicatorFactory( program=p, target_frequency=frequency, targets=100 ) data = ProgramPageProgramSerializer.get_for_pk(p.pk).data tp_data = data['target_period_info'] self.assertTrue(tp_data['lop']) self.assertTrue(tp_data['midend']) self.assertFalse(tp_data['event']) self.assertFalse(tp_data['time_targets']) self.assertFalse(tp_data['annual']) self.assertFalse(tp_data['semi_annual']) self.assertFalse(tp_data['tri_annual']) self.assertFalse(tp_data['quarterly']) self.assertFalse(tp_data['monthly'])
def test_time_period_info_time_aware(self): p = RFProgramFactory( reporting_period_start=datetime.date(2016, 1, 1), reporting_period_end=datetime.date(2024, 12, 31) ) for frequency in Indicator.REGULAR_TARGET_FREQUENCIES: RFIndicatorFactory( program=p, target_frequency=frequency, targets=500, ) data = ProgramPageProgramSerializer.get_for_pk(p.pk).data today = datetime.date.today() annual = datetime.date(today.year, 1, 1)-datetime.timedelta(days=1) semi_annual = datetime.date( today.year, 7 if today.month > 6 else 1, 1 ) - datetime.timedelta(days=1) tri_annual = datetime.date( today.year, (today.month-1) // 4 * 4 + 1, 1 ) - datetime.timedelta(days=1) quarterly = datetime.date( today.year, (today.month-1) // 3 * 3 + 1, 1 ) - datetime.timedelta(days=1) monthly = datetime.date( today.year, today.month, 1 ) - datetime.timedelta(days=1) tp_data = data['target_period_info'] self.assertFalse(tp_data['lop']) self.assertFalse(tp_data['midend']) self.assertFalse(tp_data['event']) self.assertTrue(tp_data['time_targets']) self.assertEqual(tp_data['annual'], annual.isoformat()) self.assertEqual(tp_data['semi_annual'], semi_annual.isoformat()) self.assertEqual(tp_data['tri_annual'], tri_annual.isoformat()) self.assertEqual(tp_data['quarterly'], quarterly.isoformat()) self.assertEqual(tp_data['monthly'], monthly.isoformat())
def test_site_count_non_zero(self): p = RFProgramFactory() i = RFIndicatorFactory( program=p, target_frequency=Indicator.LOP, targets=1000, results=800, results__count=10 ) for result in i.result_set.all(): result.site.add( SiteProfileFactory() ) i2 = RFIndicatorFactory( program=p, target_frequency=Indicator.ANNUAL, targets=50, results=80, results__count=3 ) for result in i2.result_set.all(): result.site.add( SiteProfileFactory() ) data = ProgramPageProgramSerializer.get_for_pk(p.pk).data self.assertEqual(data['site_count'], 13)
def test_rollups(self): p = RFProgramFactory() incomplete_i = RFIndicatorFactory( program=p, target_frequency=Indicator.MONTHLY, targets=300 ) incomplete_i.periodictargets.order_by('-end_date').first().delete() targets_i = RFIndicatorFactory( program=p, target_frequency=Indicator.QUARTERLY, targets=400 ) results_i = RFIndicatorFactory( program=p, target_frequency=Indicator.SEMI_ANNUAL, targets=400, results=200, results__count=10 ) sites = itertools.cycle([SiteProfileFactory() for _ in range(8)]) for result in results_i.result_set.all(): result.site.add(next(sites)) evidence_i = RFIndicatorFactory( program=p, target_frequency=Indicator.ANNUAL, targets=40, results=100, results__count=12, results__evidence=8 ) for result in evidence_i.result_set.all(): result.site.add(next(sites)) evidence_i2 = RFIndicatorFactory( program=p, target_frequency=Indicator.ANNUAL, targets=40, results=10, results__count=4, results__evidence=4 ) with self.assertNumQueries(4): data = ProgramPageProgramSerializer.get_for_pk(p.pk).data self.assertTrue(data['needs_additional_target_periods']) self.assertEqual(data['site_count'], 8) self.assertFalse(data['indicators'][incomplete_i.pk]['has_all_targets_defined']) self.assertTrue(data['indicators'][targets_i.pk]['has_all_targets_defined']) self.assertFalse(data['indicators'][targets_i.pk]['has_results']) self.assertEqual(data['indicators'][results_i.pk]['results_count'], 10) self.assertTrue(data['indicators'][results_i.pk]['has_results']) self.assertEqual(data['indicators'][evidence_i.pk]['results_with_evidence_count'], 8) self.assertTrue(data['indicators'][evidence_i.pk]['missing_evidence']) self.assertFalse(data['indicators'][evidence_i2.pk]['missing_evidence'])
def get_program_data(self, **kwargs): return ProgramPageProgramSerializer( Program.program_page_objects.filter(pk=RFProgramFactory(**kwargs).pk), many=True ).data[0]
def test_rf_program_many_indicators(self): p = RFProgramFactory(months=20, tiers=['Goal', 'Outcome', 'Output', 'Activity'], levels=3) p.levels.filter(parent__isnull=True, customsort__gt=1).delete() goal_level = p.levels.filter(parent__isnull=True).first() goal_pk_a = RFIndicatorFactory( program=p, level=goal_level, target_frequency=Indicator.LOP, targets=300, results=310 ).pk goal_pk_b = RFIndicatorFactory( program=p, level=goal_level, target_frequency=Indicator.ANNUAL, targets=10, results=40, baseline="100", baseline_na=True ).pk pks = [] pks.append( RFIndicatorFactory( program=p, level=None, number='A1' ).pk ) pks.append( RFIndicatorFactory( program=p, level=None, old_level='Outcome', number='X21' ).pk ) pks.append( RFIndicatorFactory( program=p, level=None, old_level='Outcome', number='C14' ).pk ) pks.append( RFIndicatorFactory( program=p, level=None, old_level='Goal' ).pk ) unassigned_pks = pks[::-1] levels = list( sorted( sorted( [l for l in p.levels.filter(parent__isnull=False)], key=lambda l: l.customsort ), key=lambda l: l.level_depth ) ) for level in list(reversed(levels)): pks.append( RFIndicatorFactory( program=p, level=level, ).pk ) expected_pks = [goal_pk_a, goal_pk_b] + list(reversed(pks)) with self.assertNumQueries(4): data = ProgramPageProgramSerializer.get_for_pk(p.pk).data self.assertEqual(data['by_result_chain'], 'by Outcome chain') self.assertNotEqual(data['indicator_pks_level_order'], data['indicator_pks_chain_order']) indicator_pks = data['indicator_pks_level_order'] self.assertEqual(indicator_pks, expected_pks) chain_pks = [indicator.pk for indicator in goal_level.indicator_set.order_by('level_order')] for level in goal_level.get_children(): chain_pks += [indicator.pk for indicator in level.indicator_set.order_by('level_order')] chain_pks += unassigned_pks self.assertEqual(data['indicator_pks_chain_order'], chain_pks) self.assertTrue(data['indicators'][goal_pk_a]['is_reporting']) self.assertEqual(data['indicators'][goal_pk_a]['over_under'], 0) self.assertEqual(data['indicators'][goal_pk_a]['lop_target'], 300) self.assertEqual(data['indicators'][goal_pk_a]['level_pk'], goal_level.pk) self.assertEqual(data['indicators'][goal_pk_b]['baseline'], None) self.assertEqual(data['indicators'][goal_pk_b]['over_under'], 1) self.assertEqual(data['indicators'][unassigned_pks[0]]['number'], None) self.assertEqual(data['indicators'][unassigned_pks[1]]['old_level_name'], None) self.assertEqual(data['indicators'][unassigned_pks[2]]['level_pk'], None) translation.activate('fr') with self.assertNumQueries(4): french_data = ProgramPageProgramSerializer.get_for_pk(p.pk).data translation.activate('en') self.assertEqual(french_data['by_result_chain'], u'par chaîne Résultat') self.assertEqual(french_data['indicators'][goal_pk_b]['number'], u'Objectif b') self.assertEqual(french_data['indicators'][expected_pks[6]]['number'], u'Rendement 1.2a') self.assertEqual(french_data['indicators'][unassigned_pks[1]]['old_level_name'], None)