Example #1
0
def monitoring_transmission(request):
    """ stats of transmission """
    context = {'category': 'monitoring_transmission'}

    period = current_reporting_period()

    def entity_dict(entity):
        entity_dict = nb_reports_for(entity, period)
        entity_dict.update({'children': []})
        return entity_dict

    entities = []
    for entity in Entity.objects.filter(type__slug='district'):

        if MalariaReport.objects.filter(period=period, entity=entity).count():
            continue

        edata = entity_dict(entity)
        edata['children'] = [entity_dict(e) \
                             for e in entity.get_children() \
                             if not MalariaReport.objects \
                                    .filter(period=period, entity=e).count()]

        entities.append(edata)

    context.update({'entities': entities})

    return render(request, 'monitoring_transmission.html', context)
Example #2
0
    def handle(self, *args, **options):

        translation.activate(settings.DEFAULT_LOCALE)

        logger.info(u"Launching PNLP daily tasks script")

        logger.info(u"Remove orphan periods")
        [p.delete() for p
                    in MonthPeriod.objects.all()
                    if MalariaReport.objects.filter(period=p).count() == 0]

        period = current_reporting_period()

        # if new incoming report
        report = MalariaReportCreated.create(period=period, persit=False)
        if report.can_trigger():
            logger.info(u"Incoming reports.")
            report.trigger()

        # if end of CSCOM period
        cscom = EndOfCSComPeriod.create(period=period)
        if cscom.can_trigger():
            logger.info(u"End of CSCom reporting period.")
            cscom.trigger()

        # if end of DISTRICT period
        district = EndOfDistrictPeriod.create(period=period, is_district=True)
        if district.can_trigger():
            logger.info(u"End of District reporting period.")
            district.trigger()

        # if end of REGION period
        region = EndOfDistrictPeriod.create(period=period, is_district=False)
        if region.can_trigger():
            logger.info(u"End of Region reporting period.")
            region.trigger()

        cscom_reminder = Reminder.create(period=period, level='cscom')
        if cscom_reminder.can_trigger():
            logger.info(u"CSCom reminder.")
            cscom_reminder.trigger()

        district_reminder = Reminder.create(period=period, level='district')
        if district_reminder.can_trigger():
            logger.info(u"District reminder.")
            district_reminder.trigger()

        region_reminder = Reminder.create(period=period, level='region')
        if region_reminder.can_trigger():
            logger.info(u"Region reminder.")
            region_reminder.trigger()

        # last day of month
        #   send SMS+email to hotline so they send units to everybody
        eom = EndOfMonth.create(period=period)
        if eom.can_trigger():
            logger.info(u"End of Month.")
            eom.trigger()

        translation.deactivate()
Example #3
0
def validation_list(request):
    context = {'category': 'validation'}
    web_provider = request.user.get_profile()

    entity = provider_entity(web_provider)
    period = current_reporting_period()

    # check permission or raise 403
    # should never raise as already checked by decorator
    provider_can_or_403('can_validate_report', web_provider, entity)

    not_sent = [(ent, contact_for(ent)) \
                for ent in get_not_received_reports(entity, period)]

    context.update({'not_validated': get_reports_to_validate(entity, period),
                    'validated': get_validated_reports(entity, period),
                    'not_sent': not_sent})

    context.update({'is_complete': context['validated'].__len__() == \
                                   entity.get_children().__len__(),
                    'is_idle': context['not_validated'].__len__() == 0 \
                               and context['not_sent'].__len__() > 0})

    context.update({'time_cscom_over': time_cscom_over(), \
                    'time_district_over': time_district_over(), \
                    'time_region_over': time_region_over()})

    context.update({'validation_over': not time_can_validate(entity)})

    context.update({'current_period': current_period(), \
                    'current_reporting_period': period})

    return render(request, 'validation_list.html', context)
Example #4
0
def validation_list(request):
    context = {'category': 'validation'}
    web_provider = request.user.get_profile()

    entity = provider_entity(web_provider)
    period = current_reporting_period()

    # check permission or raise 403
    # should never raise as already checked by decorator
    provider_can_or_403('can_validate_report', web_provider, entity)

    not_sent = [(ent, contact_for(ent)) \
                for ent in get_not_received_reports(entity, period)]

    context.update({
        'not_validated': get_reports_to_validate(entity, period),
        'validated': get_validated_reports(entity, period),
        'not_sent': not_sent
    })

    context.update({'is_complete': context['validated'].__len__() == \
                                   entity.get_children().__len__(),
                    'is_idle': context['not_validated'].__len__() == 0 \
                               and context['not_sent'].__len__() > 0})

    context.update({'time_cscom_over': time_cscom_over(), \
                    'time_district_over': time_district_over(), \
                    'time_region_over': time_region_over()})

    context.update({'validation_over': not time_can_validate(entity)})

    context.update({'current_period': current_period(), \
                    'current_reporting_period': period})

    return render(request, 'validation_list.html', context)
Example #5
0
 def can_trigger(self, *args, **kwargs):
     # triggers happens if:
     # 1. Such alert has not been triggered
     # 2. We are in the next period as P (don't trigger is it's too late
     return self.not_triggered \
            and datetime.now() >= (self.args.period.end_on \
                                   - timedelta(days=1)) \
             and self.args.period == current_reporting_period()
Example #6
0
 def can_trigger(self, *args, **kwargs):
     # triggers happens if:
     # 1. CSCom period for P is over
     # 2. Such alert has not been triggered
     # 3. We are in the next period as P (don't trigger is it's too late)
     return time_cscom_over(period=self.args.period) \
            and self.not_triggered \
            and self.args.period == current_reporting_period()
Example #7
0
 def can_trigger(self, *args, **kwargs):
     # triggers happens if:
     # 1. District period for P is over
     # 2. Such alert has not been triggered
     # 3. We are in the next period as P (don't trigger is it's too late
     if self.args.is_district:
         time_is_over = time_district_over(period=self.args.period)
     else:
         time_is_over = time_region_over(period=self.args.period)
     return time_is_over \
            and self.not_triggered \
            and self.args.period == current_reporting_period()
Example #8
0
 def can_trigger(self, *args, **kwargs):
     # triggers happens if:
     # 1. Such alert has not been triggered
     # 2. Action period is not over
     # 2. We are in the next period as P
     try:
         time_is_over = eval('time_%s_over' \
                             % self.args.level)(period=self.args.period)
     except:
         return False
     now = datetime.now()
     return self.not_triggered \
            and now.day >= int(self.get_alert_id()[-8:-6]) \
            and not time_is_over \
            and self.args.period == current_reporting_period()
Example #9
0
def report_unvalidated(request):
    """ stats of validation """

    def entity_dict(entity):
        entity_dict = nb_reports_unvalidated_for(entity, period)
        entity_dict.update({'children': []})
        return entity_dict

    context = {'category': 'transmission'}
    period = current_reporting_period()

    entities = []
    for entity in Entity.objects.filter(type__slug='district'):
        edata = entity_dict(entity)
        edata['children'] = [e for e in entity.get_children() \
                               if MalariaReport.unvalidated \
                                    .filter(period=period, entity=e).count()]
        entities.append(edata)

    context.update({'entities': entities})
    return render(request, 'report_unvalidated.html', context)
Example #10
0
def dashboard(request):
    category = 'dashboard'
    context = {'category': category}

    from bolibana.models import Entity
    from pnlp_core.data import (current_period, current_stage, \
                                time_cscom_over, time_district_over, \
                                time_region_over)

    def sms_received_sent_by_period(period):
        received = Inbox.objects.filter(receivingdatetime__gte=period.start_on,
                                        receivingdatetime__lte=period.end_on) \
                                .count()
        sent = SentItems.objects.filter(sendingdatetime__gte=period.start_on,
                                        sendingdatetime__lte=period.end_on) \
                                .count()
        return (received, sent)

    def received_reports(period, type_):
        return MalariaReport.objects.filter(period=period, \
                                            entity__type__slug=type_)

    def reports_validated(period, type_):
        return MalariaReport.validated.filter(period=period, \
                                       entity__type__slug=type_)

    def reporting_rate(period, entity):
        return float(MalariaReport.validated.filter(period=period, \
                 entity__parent=entity).count()) \
        / Entity.objects.filter(parent__slug=entity.slug).count()

    current_period = current_period()
    period = current_reporting_period()

    context.update({'current_period': current_period,
                    'current_reporting_period': period,
                    'current_stage': current_stage(),
                    'current_sms': sms_received_sent_by_period(current_period),
                    'current_reporting_sms': \
                         sms_received_sent_by_period(period),
                    'total_cscom': Entity.objects\
                                         .filter(type__slug='cscom').count(),
                    'time_cscom_over': time_cscom_over(period),
                    'time_district_over': time_district_over(period),
                    'time_region_over': time_region_over(period)})

    received_cscom_reports = received_reports(period, 'cscom')
    cscom_reports_validated = reports_validated(period, 'cscom')
    district_reports_validated = reports_validated(period, 'district')
    reporting_rate = \
        float(MalariaReport.validated.filter(period=period).count()) \
        / Entity.objects.count()

    cscom_missed_report = \
        Entity.objects.filter(type__slug='cscom')\
                      .exclude(id__in=[r.entity.id \
                                       for r \
                                       in received_cscom_reports])\
                      .order_by('name')

    def entities_autoreports(level):
        districts_missed_report = {}
        auto_validated_cscom_reports = \
            MalariaReport.validated\
                         .filter(entity__type__slug=level, \
                                 modified_by__user__username='******')
        for report in auto_validated_cscom_reports:
            if not report.entity.parent.slug in districts_missed_report:
                districts_missed_report[report.entity.parent.slug] = \
                    {'entity': report.entity.parent, \
                     'nbauto': 0, \
                     'contact': contact_for(report.entity.parent, False)}
            districts_missed_report[report.entity.parent.slug]['nbauto'] += 1
        return districts_missed_report

    districts_missed_report = entities_autoreports('cscom')
    regions_missed_report = entities_autoreports('district')

    context.update({'received_cscom_reports': received_cscom_reports.count(),
                'cscom_reports_validated': cscom_reports_validated.count(),
              'district_reports_validated': district_reports_validated.count(),
                'reporting_rate': reporting_rate,
                'cscom_missed_report_count': cscom_missed_report.count(),
                'cscom_missed_report': [(e, contact_for(e, True)) \
                                        for e in cscom_missed_report[:20]],
                'districts_missed_report': districts_missed_report,
                'regions_missed_report': regions_missed_report})

    return render(request, 'dashboard.html', context)
Example #11
0
 def can_trigger(self, *args, **kwargs):
     # triggers happens if:
     # 1. Such alert has not been triggered
     # 2. We are in the next period as P (don't trigger is it's too late
     return self.not_triggered \
            and self.args.period == current_reporting_period()
Example #12
0
def dashboard(request):
    category = 'dashboard'
    context = {'category': category}

    from bolibana.models import Entity
    from pnlp_core.data import (current_period, current_stage, \
                                time_cscom_over, time_district_over, \
                                time_region_over)

    def sms_received_sent_by_period(period):
        received = Inbox.objects.filter(receivingdatetime__gte=period.start_on,
                                        receivingdatetime__lte=period.end_on) \
                                .count()
        sent = SentItems.objects.filter(sendingdatetime__gte=period.start_on,
                                        sendingdatetime__lte=period.end_on) \
                                .count()
        return (received, sent)

    def received_reports(period, type_):
        return MalariaReport.objects.filter(period=period, \
                                            entity__type__slug=type_)

    def reports_validated(period, type_):
        return MalariaReport.validated.filter(period=period, \
                                       entity__type__slug=type_)

    def reporting_rate(period, entity):
        return float(MalariaReport.validated.filter(period=period, \
                 entity__parent=entity).count()) \
        / Entity.objects.filter(parent__slug=entity.slug).count()

    current_period = current_period()
    period = current_reporting_period()

    context.update({'current_period': current_period,
                    'current_reporting_period': period,
                    'current_stage': current_stage(),
                    'current_sms': sms_received_sent_by_period(current_period),
                    'current_reporting_sms': \
                         sms_received_sent_by_period(period),
                    'total_cscom': Entity.objects\
                                         .filter(type__slug='cscom').count(),
                    'time_cscom_over': time_cscom_over(period),
                    'time_district_over': time_district_over(period),
                    'time_region_over': time_region_over(period)})

    received_cscom_reports = received_reports(period, 'cscom')
    cscom_reports_validated = reports_validated(period, 'cscom')
    district_reports_validated = reports_validated(period, 'district')
    reporting_rate = \
        float(MalariaReport.validated.filter(period=period).count()) \
        / Entity.objects.count()

    cscom_missed_report = \
        Entity.objects.filter(type__slug='cscom')\
                      .exclude(id__in=[r.entity.id \
                                       for r \
                                       in received_cscom_reports])\
                      .order_by('name')

    def entities_autoreports(level):
        districts_missed_report = {}
        auto_validated_cscom_reports = \
            MalariaReport.validated\
                         .filter(entity__type__slug=level, \
                                 modified_by__user__username='******')
        for report in auto_validated_cscom_reports:
            if not report.entity.parent.slug in districts_missed_report:
                districts_missed_report[report.entity.parent.slug] = \
                    {'entity': report.entity.parent, \
                     'nbauto': 0, \
                     'contact': contact_for(report.entity.parent, False)}
            districts_missed_report[report.entity.parent.slug]['nbauto'] += 1
        return districts_missed_report

    districts_missed_report = entities_autoreports('cscom')
    regions_missed_report = entities_autoreports('district')

    context.update({'received_cscom_reports': received_cscom_reports.count(),
                'cscom_reports_validated': cscom_reports_validated.count(),
              'district_reports_validated': district_reports_validated.count(),
                'reporting_rate': reporting_rate,
                'cscom_missed_report_count': cscom_missed_report.count(),
                'cscom_missed_report': [(e, contact_for(e, True)) \
                                        for e in cscom_missed_report[:20]],
                'districts_missed_report': districts_missed_report,
                'regions_missed_report': regions_missed_report})

    return render(request, 'dashboard.html', context)
Example #13
0
def indicator_browser(request, entity_code=None, period_str=None, \
                    section_index='1', sub_section=None):
    context = {'category': 'indicator_data'}
    web_provider = request.user.get_profile()

    root = web_provider.first_target()

    periods = []
    speriod = eperiod = None
    entity = None
    #section_index = int(section_index) - 1

    # find entity or default to provider target
    # raise 404 on wrong provided entity code
    if entity_code:
        entity = get_object_or_404(Entity, slug=entity_code)

    if not entity:
        entity = web_provider.first_target()
    context.update({'entity': entity})

    # define a list of all possible periods.
    # this is the list of all existing MonthPeriod anterior to current
    def all_anterior_periods(period):
        return MonthPeriod.objects\
                          .filter(start_on__lte=period.start_on)\
                          .order_by('start_on')

    all_periods = list(all_anterior_periods(current_reporting_period()).all())
    if not MalariaReport.validated.filter(entity=entity,
                                          period=current_reporting_period()) \
                                  .count():
        all_periods.remove(current_reporting_period())

    # retrieve Periods from string
    # if period_string include innexistant periods -> 404.
    if period_str:
        speriod_str, eperiod_str = period_str.split('-')
        try:
            speriod = MonthPeriod.find_create_from(\
                                                  year=int(speriod_str[-4:]), \
                                                  month=int(speriod_str[:2]), \
                                                  dont_create=True)
            eperiod = MonthPeriod.find_create_from(\
                                                  year=int(eperiod_str[-4:]), \
                                                  month=int(eperiod_str[:2]), \
                                                  dont_create=True)

            # loop on Period.next() from start one to end one.
            period = speriod
            while period.middle() <= eperiod.middle():
                periods.append(period)
                period = period.next()
        except:
            raise Http404(_(u"Requested period interval (%(period_str)s) " \
                            u"includes inexistant periods.") \
                          % {'period': period_str})

    # in case user did not request a specific interval
    # default to current_reporting_period
    if not speriod or not eperiod:
        speriod = eperiod = current_reporting_period()
        periods = [speriod]

    # if end period is before start period, redirect to opposite
    if eperiod.middle() < speriod.middle():
        return redirect('indicator_data', \
                        entity_code=entity.slug, \
                        period_str='%s-%s' % (eperiod.pid, speriod.pid))

    # periods variables
    context.update({'period_str': '%s-%s' % (speriod.pid, eperiod.pid), \
                    'speriod': speriod, 'eperiod': eperiod})
    context.update({'periods': [(p.pid, p.middle()) for p in periods], \
                    'all_periods': [(p.pid, p.middle()) for p in all_periods]})

    # check permissions on this entity and raise 403
    provider_can_or_403('can_view_indicator_data', web_provider, entity)

    # build entities browser
    context.update({'root': root, \
                    'paths': entities_path(root, entity)})

    from pnlp_core.indicators import INDICATOR_SECTIONS

    context.update({'sections': \
                    sorted(INDICATOR_SECTIONS.values(), \
                          cmp=lambda a, b: int(a['id'].strip('a').strip('b')) \
                                        - int(b['id'].strip('a').strip('b')))})

    try:
        section = INDICATOR_SECTIONS[section_index]
        if not sub_section:
            if len(section['sections']):
                sub_section = section['sections'].keys()[0]
        sname = 'pnlp_core.indicators.section%s' % section_index.__str__()
        if sub_section:
            sname = '%s_%s' % (sname, sub_section.__str__())
        sm = import_path(sname)
    except:
        raise
        raise Http404(_(u"This section does not exist."))

    # section 1 specifics
    if section_index == '1':
        context.update({'contact': contact_for(entity)})

    context.update({'section': section, 'sub_section': sub_section})

    context.update({'widgets': [widget(entity=entity, periods=periods) \
                                for widget in sm.WIDGETS]})

    return render(request, 'indicator_data.html', context)
Example #14
0
def data_browser(request, entity_code=None, period_str=None):
    context = {'category': 'raw_data'}
    web_provider = request.user.get_profile()

    root = web_provider.first_target()

    period = None
    entity = None

    # find period from string or default to current reporting
    if period_str:
        try:
            period = MonthPeriod.find_create_from(year=int(period_str[-4:]), \
                                                  month=int(period_str[:2]), \
                                                  dont_create=True)
        except:
            pass
    if not period:
        period = current_reporting_period()

    # find entity or default to provider target
    # raise 404 on wrong provided entity code
    if entity_code:
        entity = get_object_or_404(Entity, slug=entity_code)

    if not entity:
        entity = web_provider.first_target()
    context.update({'entity': entity})

    # check permissions on this entity and raise 403
    provider_can_or_403('can_view_raw_data', web_provider, entity)

    # build entities browser
    context.update({'root': root, \
                    'paths': entities_path(root, entity)})

    # build periods list
    all_periods = raw_data_periods_for(entity)
    if period_str and not period in all_periods:
        raise Http404(_(u"No report for that period"))

    try:
        # get validated report for that period and location
        report = MalariaReport.validated.get(entity=entity, period=period)
    except MalariaReport.DoesNotExist:
        # district users need to be able to see the generated report
        # which have been created based on their validations/data.
        # if a district is looking at its root district and report exist
        # but not validated, we show it (with period) and no valid flag
        if web_provider.first_role().slug == 'district' and root == entity:
            try:
                report = MalariaReport.unvalidated.get(entity=entity, \
                                                       period=period)
                if not period in all_periods:
                    all_periods.insert(0, period)
            except:
                report = None
        else:
            report = None

    # send period variables to template
    context.update({'periods': [(p.middle().strftime('%m%Y'), p.middle()) \
                                for p in all_periods], \
                    'period': period})

    if report:
        context.update({'report': report})
        form = MalariaReportForm(instance=report)
        context.update({'form': form})
    else:
        context.update({'no_report': True})

    return render(request, 'raw_data.html', context)