コード例 #1
0
    def save_periodic_targets(self, periodic_targets_json, indicator):
        for pt_data in periodic_targets_json:
            result_set = pt_data.pop('result_set')

            pt = PeriodicTarget(**pt_data)
            pt.indicator = indicator
            pt.save()

            self.save_results(result_set, indicator, pt)
コード例 #2
0
 def get_periods(self):
     frequency = int(self.request.get('frequency'))
     return [
         self.get_period(frequency, period_dict)
         for period_dict in PeriodicTarget.generate_for_frequency(
             int(self.request.get('frequency')))
         (self.program_data['reporting_period_start'],
          self.program_data['reporting_period_end'])
     ]
コード例 #3
0
    def make_targets(program, indicator):
        if indicator.target_frequency == Indicator.LOP:
            PeriodicTarget.objects.create(
                **{
                    'indicator': indicator,
                    'customsort': 1,
                    'edit_date': timezone.now(),
                    'period': 'LOP target',
                })
            return
        elif indicator.target_frequency == Indicator.EVENT:
            for i in range(3):
                PeriodicTarget.objects.create(
                    **{
                        'indicator': indicator,
                        'customsort': i,
                        'edit_date': timezone.now(),
                        'period': 'Event {}'.format(i + 1),
                    })
            return

        target_generator = PeriodicTarget.generate_for_frequency(
            indicator.target_frequency)
        num_periods = len([
            p for p in target_generator(program.reporting_period_start,
                                        program.reporting_period_end)
        ])

        if indicator.target_frequency == Indicator.LOP:
            print 'lop num_periods'
        targets_json = generate_periodic_targets(
            tf=indicator.target_frequency,
            start_date=program.reporting_period_start,
            numTargets=num_periods)
        for i, pt in enumerate(targets_json):
            if indicator.target_frequency in [
                    Indicator.LOP, Indicator.MID_END
            ]:
                PeriodicTarget.objects.create(
                    **{
                        'indicator': indicator,
                        'customsort': i,
                        'edit_date': timezone.now(),
                        'period': 'Period {}'.format(i + 1),
                    })
            else:
                PeriodicTarget.objects.create(
                    **{
                        'indicator': indicator,
                        'customsort': i,
                        'edit_date': timezone.now(),
                        'period': 'Period {}'.format(i + 1),
                        'start_date': pt['start_date'],
                        'end_date': pt['end_date'],
                    })
コード例 #4
0
def periodic_targets_form(request, program):
    """
    Returns a form for the periodic targets sub-section,
    used by the Indicator Form

    For historical reasons, the input is a POST of the whole indicator form sent via ajax
    from which a subset of fields are used to generate the returned template
    """
    if not request.has_write_access:
        raise PermissionDenied

    program = get_object_or_404(Program, pk=program)

    form = PTFormInputsForm(data=request.POST)

    if not form.is_valid():
        return JsonResponse(form.errors)

    event_name = ''
    start_date = ''
    target_frequency_num_periods = 1
    target_frequency_type = form.cleaned_data.get('target_frequency')

    if target_frequency_type in Indicator.REGULAR_TARGET_FREQUENCIES:
        start_date = program.reporting_period_start
        # target_frequency_num_periods = IPTT_ReportView._get_num_periods(
        #     start_date, program.reporting_period_end, target_frequency_type)
        target_frequency_num_periods = len([
            p for p in PeriodicTarget.generate_for_frequency(
                target_frequency_type)(start_date,
                                       program.reporting_period_end)
        ])

    generated_targets = generate_periodic_targets(
        target_frequency_type, start_date, target_frequency_num_periods,
        event_name)

    dummy_indicator = Indicator(
        target_frequency=target_frequency_type,
        unit_of_measure_type=form.cleaned_data.get('unit_of_measure_type'),
        is_cumulative=False,
    )

    content = render_to_string('indicators/indicatortargets.html', {
        'indicator': dummy_indicator,
        'periodic_targets': generated_targets
    })

    return JsonResponse({
        'content': content,
    })
コード例 #5
0
 def get_periods(self, frequency):
     if frequency == 1:
         return []
     periods = [
         self.get_period(frequency, period_dict)
         for period_dict in PeriodicTarget.generate_for_frequency(frequency)
         (self.program_data['reporting_period_start'],
          self.program_data['reporting_period_end'])
     ]
     start = int(self.request.get('start', 0))
     end = self.request.get('end', None)
     if end is not None:
         end = int(end) + 1
     return periods[start:end]
コード例 #6
0
 def targets(self, create, extracted, **kwargs):
     if extracted and self.target_frequency:
         period_generator = PeriodicTargetM.generate_for_frequency(
             self.target_frequency)
         if self.program:
             periods = period_generator(self.program.reporting_period_start,
                                        self.program.reporting_period_end)
         else:
             periods = period_generator(datetime.date(2016, 1, 1),
                                        datetime.date(2018, 12, 31))
         periods = list(periods)
         if extracted == "incomplete":
             if len(periods) > 1:
                 periods = periods[0:-1]
                 target_values = [self.lop_target / len(periods)
                                  ] * len(periods)
             else:
                 periods = []
                 target_values = []
         elif isinstance(extracted, (int, float)):
             target_values = [round(extracted / len(periods), 2)
                              ] * len(periods)
             if len(target_values) > 1:
                 target_values[-1] = extracted - sum(target_values[0:-1])
         elif self.lop_target:
             target_values = [round(self.lop_target / len(periods))
                              ] * len(periods)
             if len(target_values) > 1:
                 target_values[-1] = self.lop_target - sum(
                     target_values[0:-1])
         else:
             target_values = [None] * len(periods)
         for period, target_value in zip(periods, target_values):
             PeriodicTargetFactory(indicator=self,
                                   customsort=period['customsort'],
                                   target=target_value,
                                   start_date=period['start'],
                                   end_date=period['end'])
コード例 #7
0
 def generate_targets(self, indicator, skip=None):
     #pylint: disable=W0212
     target_frequency_num_periods = len([
         p for p in PeriodicTarget.generate_for_frequency(self.frequency)(
             self.program.reporting_period_start,
             self.program.reporting_period_end,
         )
     ])
     if skip is not None:
         target_frequency_num_periods -= 1
     if target_frequency_num_periods == 0:
         return []
     generatedTargets = generate_periodic_targets(
         self.frequency, self.program.reporting_period_start,
         target_frequency_num_periods, '')
     to_return_targets = []
     for target in generatedTargets:
         to_return_targets.append(
             i_factories.PeriodicTargetFactory(
                 indicator=indicator,
                 period=target['period'],
                 start_date=target['start_date'],
                 end_date=target['end_date']))
     return to_return_targets
コード例 #8
0
 def get_periods(self, frequency, start, end):
     return [{
         'start': p['start'],
         'end': p['end']
     } for p in PeriodicTarget.generate_for_frequency(frequency)(start, end)
             ]
コード例 #9
0
    def get_context_data(self, **kwargs):
        context = super(IndicatorUpdate, self).get_context_data(**kwargs)
        indicator = self.object
        program = indicator.program

        context['program'] = program

        pts = PeriodicTarget.objects.filter(indicator=indicator) \
            .annotate(num_data=Count('result')).order_by('customsort', 'create_date', 'period')

        ptargets = []
        for pt in pts:
            ptargets.append({
                'id': pt.pk,
                'num_data': pt.num_data,
                'start_date': pt.start_date,
                'end_date': pt.end_date,
                'period': pt.
                period,  # period is deprecated, this should move to .period_name
                'period_name': pt.period_name,
                'target': pt.target
            })

        # if the modal is loaded (not submitted) and the indicator frequency is a periodic
        if self.request.method == 'GET' and indicator.target_frequency in Indicator.REGULAR_TARGET_FREQUENCIES:
            latest_pt_end_date = indicator.periodictargets.aggregate(
                lastpt=Max('end_date'))['lastpt']

            if latest_pt_end_date is None or latest_pt_end_date == 'None':
                latest_pt_end_date = program.reporting_period_start
            else:
                latest_pt_end_date += timedelta(days=1)

            target_frequency_num_periods = len([
                p for p in PeriodicTarget.generate_for_frequency(
                    indicator.target_frequency)(latest_pt_end_date,
                                                program.reporting_period_end)
            ])
            # target_frequency_num_periods = IPTT_ReportView._get_num_periods(
            #     latest_pt_end_date, program.reporting_period_end, indicator.target_frequency)

            num_existing_targets = pts.count()
            event_name = ''

            generated_targets = generate_periodic_targets(
                indicator.target_frequency, latest_pt_end_date,
                target_frequency_num_periods, event_name, num_existing_targets)

            # combine the list of existing periodic_targets with the newly generated placeholder for missing targets
            ptargets += generated_targets

        context['periodic_targets'] = ptargets

        # redirect user to certain tabs of the form given GET params
        if self.request.GET.get('targetsactive') == 'true':
            context['targetsactive'] = True

        context['readonly'] = not self.request.has_write_access

        context['title_str'] = self._form_title_display_str
        context['subtitle_str'] = self._form_subtitle_display_str

        return context
コード例 #10
0
    def validate_periodic_target_json_from_client(self, normalized_pt_json,
                                                  program, target_frequency):
        """
        The client sends the full definition of all periodic targets in JSON
        In the past, the server has just accepted it as gospel
        Instead, do some basic validation to confirm what the client is telling the server is sane

        Takes the client JSON, already deserialized and having the dates and pkid normalized as input.
        """
        # Clients send nothing on LOP only
        if target_frequency == Indicator.LOP:
            return

        # Are all target values >= 0?
        for pt in normalized_pt_json:
            try:
                if Decimal(pt['target']).as_tuple()[0] == 1:
                    raise PeriodicTargetJsonValidationError(
                        'Target value must be >= 0, found %d' % pt['target'])
            except TypeError:
                pass

        # check that event names exist in the future?
        if target_frequency == Indicator.EVENT:
            return

        if target_frequency == Indicator.MID_END:
            if len(normalized_pt_json) != 2:
                raise PeriodicTargetJsonValidationError(
                    'Midline/Endline periodic target count is not 2 and is instead %d'
                    % len(normalized_pt_json))
            return

        # target_frequency_num_periods = IPTT_ReportView._get_num_periods(program.reporting_period_start,
        #                                                                 program.reporting_period_end,
        #                                                                 target_frequency)

        target_frequency_num_periods = len([
            p for p in PeriodicTarget.generate_for_frequency(target_frequency)(
                program.reporting_period_start, program.reporting_period_end)
        ])

        generated_targets = generate_periodic_targets(
            target_frequency, program.reporting_period_start,
            target_frequency_num_periods)

        if len(generated_targets) != len(normalized_pt_json):
            raise PeriodicTargetJsonValidationError((
                "Number of periodic targets sent by client "
                "does not match excepected number of targets on the server (%d vs %d)"
            ) % (len(generated_targets), len(normalized_pt_json)))

        server_period_dates = [(pt['start_date'], pt['end_date'])
                               for pt in generated_targets]
        client_period_dates = [(pt['start_date'], pt['end_date'])
                               for pt in normalized_pt_json]

        if server_period_dates != client_period_dates:
            raise PeriodicTargetJsonValidationError(
                ("Periodic Target start/end dates expected by server "
                 "do not match what was sent by the client: %s vs %s") %
                (server_period_dates, client_period_dates))
コード例 #11
0
def generate_periodic_target_single(tf,
                                    start_date,
                                    nthTargetPeriod,
                                    event_name='',
                                    num_existing_targets=0):
    i = nthTargetPeriod
    j = i + 1
    target_period = ''
    period_num = num_existing_targets
    if period_num == 0:
        period_num = j

    if tf == Indicator.LOP:
        return {
            'period': PeriodicTarget.LOP_PERIOD,
            'period_name': PeriodicTarget.generate_lop_period_name()
        }
    elif tf == Indicator.MID_END:
        return [{
            'period': PeriodicTarget.MIDLINE,
            'period_name': PeriodicTarget.generate_midline_period_name()
        }, {
            'period': PeriodicTarget.ENDLINE,
            'period_name': PeriodicTarget.generate_endline_period_name()
        }]
    elif tf == Indicator.EVENT:
        if i == 0:
            return {
                'period':
                event_name,
                'period_name':
                PeriodicTarget.generate_event_period_name(event_name)
            }
        return {'period': ''}

    if tf == Indicator.ANNUAL:
        start = ((start_date +
                  relativedelta(years=+i)).replace(day=1)).strftime('%Y-%m-%d')
        end = ((start_date + relativedelta(years=+j)) +
               relativedelta(days=-1)).strftime('%Y-%m-%d')
        period_label = '{period} {period_num}'.format(
            period=PeriodicTarget.ANNUAL_PERIOD, period_num=period_num)
        target_period = {
            'period':
            period_label,
            'start_date':
            start,
            'end_date':
            end,
            'period_name':
            PeriodicTarget.generate_annual_quarterly_period_name(
                tf, period_num)
        }

    elif tf == Indicator.SEMI_ANNUAL:
        start = ((start_date + relativedelta(months=+(i * 6))).replace(
            day=1)).strftime('%Y-%m-%d')
        end = ((start_date + relativedelta(months=+(j * 6))) +
               relativedelta(days=-1)).strftime('%Y-%m-%d')
        period_label = '{period} {period_num}'.format(
            period=PeriodicTarget.SEMI_ANNUAL_PERIOD, period_num=period_num)
        target_period = {
            'period':
            period_label,
            'start_date':
            start,
            'end_date':
            end,
            'period_name':
            PeriodicTarget.generate_annual_quarterly_period_name(
                tf, period_num)
        }

    elif tf == Indicator.TRI_ANNUAL:
        start = ((start_date + relativedelta(months=+(i * 4))).replace(
            day=1)).strftime('%Y-%m-%d')
        end = ((start_date + relativedelta(months=+(j * 4))) +
               relativedelta(days=-1)).strftime('%Y-%m-%d')
        period_label = '{period} {period_num}'.format(
            period=PeriodicTarget.TRI_ANNUAL_PERIOD, period_num=period_num)
        target_period = {
            'period':
            period_label,
            'start_date':
            start,
            'end_date':
            end,
            'period_name':
            PeriodicTarget.generate_annual_quarterly_period_name(
                tf, period_num)
        }

    elif tf == Indicator.QUARTERLY:
        start = ((start_date + relativedelta(months=+(i * 3))).replace(
            day=1)).strftime('%Y-%m-%d')
        end = ((start_date + relativedelta(months=+(j * 3))) +
               relativedelta(days=-1)).strftime('%Y-%m-%d')
        period_label = '{period} {period_num}'.format(
            period=PeriodicTarget.QUARTERLY_PERIOD, period_num=period_num)
        target_period = {
            'period':
            period_label,
            'start_date':
            start,
            'end_date':
            end,
            'period_name':
            PeriodicTarget.generate_annual_quarterly_period_name(
                tf, period_num)
        }

    elif tf == Indicator.MONTHLY:
        target_period_start_date = start_date + relativedelta(months=+i)
        name = PeriodicTarget.generate_monthly_period_name(
            target_period_start_date)

        start = ((start_date + relativedelta(months=+i)).replace(
            day=1)).strftime('%Y-%m-%d')
        end = ((start_date + relativedelta(months=+j)) +
               relativedelta(days=-1)).strftime('%Y-%m-%d')
        target_period = {
            'period': name,
            'start_date': start,
            'end_date': end,
            'period_name': name
        }

    return target_period
コード例 #12
0
def get_program_filter_data(request):
    """uses request user to populate program data for filter dropdowns in IPTT Quickstart / IPTT Reeport"""

    programs = []
    #countries = request.user.tola_user.available_countries
    programs_qs = request.user.tola_user.available_programs.filter(
        funding_status="Funded",
        reporting_period_start__isnull=False,
        reporting_period_end__isnull=False).order_by('id')
    frequencies_qs = Indicator.objects.filter(
        program__in=programs_qs, target_frequency__isnull=False).order_by(
            'program_id',
            'target_frequency').values('program_id',
                                       'target_frequency').distinct()
    for program in programs_qs:
        frequencies = [
            f['target_frequency'] for f in frequencies_qs
            if f['program_id'] == program.pk
        ]
        if frequencies:
            start_formatted = l10n_date_medium(program.reporting_period_start)
            end_formatted = l10n_date_medium(program.reporting_period_end)
            programs.append({
                'id': program.pk,
                'name': program.name,
                'old_style_levels': not program.results_framework,
                'frequencies': frequencies,
                'reporting_period_start': start_formatted,
                'reporting_period_end': end_formatted,
                'result_chain_filter_label': program.rf_chain_sort_label,
                'short_result_chain_label': program.rf_chain_group_label,
                # blanks in below strings are placeholders until this moves to associative arrays:
                'periodDateRanges': {
                    '1': [[
                        start_formatted,
                        end_formatted,
                        '',
                        '',
                        '',
                        program.reporting_period_start.isoformat(),
                        program.reporting_period_end.isoformat(),
                    ]],
                    '2': [[
                        start_formatted,
                        end_formatted,
                        ugettext('Midline'),
                        '',
                        '',
                        program.reporting_period_start.isoformat(),
                        program.reporting_period_end.isoformat(),
                    ],
                          [
                              start_formatted,
                              end_formatted,
                              ugettext('Endline'),
                              '',
                              '',
                              program.reporting_period_start.isoformat(),
                              program.reporting_period_end.isoformat(),
                          ]],
                    '3': [[
                        l10n_date_medium(period['start']),
                        l10n_date_medium(period['end']),
                        period['start'] > timezone.now().date(),
                        '',
                        '',
                        period['start'].isoformat(),
                        period['end'].isoformat(),
                    ] for period in PeriodicTarget.generate_for_frequency(3)
                          (program.reporting_period_start,
                           program.reporting_period_end)],
                    '4': [[
                        l10n_date_medium(period['start']),
                        l10n_date_medium(period['end']),
                        period['start'] > timezone.now().date(),
                        '',
                        '',
                        period['start'].isoformat(),
                        period['end'].isoformat(),
                    ] for period in PeriodicTarget.generate_for_frequency(4)
                          (program.reporting_period_start,
                           program.reporting_period_end)],
                    '5': [[
                        l10n_date_medium(period['start']),
                        l10n_date_medium(period['end']),
                        period['start'] > timezone.now().date(),
                        '',
                        '',
                        period['start'].isoformat(),
                        period['end'].isoformat(),
                    ] for period in PeriodicTarget.generate_for_frequency(5)
                          (program.reporting_period_start,
                           program.reporting_period_end)],
                    '6': [[
                        l10n_date_medium(period['start']),
                        l10n_date_medium(period['end']),
                        period['start'] > timezone.now().date(),
                        '',
                        '',
                        period['start'].isoformat(),
                        period['end'].isoformat(),
                    ] for period in PeriodicTarget.generate_for_frequency(6)
                          (program.reporting_period_start,
                           program.reporting_period_end)],
                    '7': [[
                        l10n_date_medium(period['start']),
                        l10n_date_medium(period['end']),
                        l10n_monthname(period['start']), period['start'].year,
                        period['start'] > timezone.now().date(),
                        period['start'].isoformat(), period['end'].isoformat()
                    ] for period in PeriodicTarget.generate_for_frequency(7)
                          (program.reporting_period_start,
                           program.reporting_period_end)],
                }
            })
    return programs