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)
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()
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)
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)
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()
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()
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()
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()
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)
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)
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()
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)
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)