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. 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 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 action(self): """ send SMS to district/region | email to PNLP for each new report """ for report in MalariaReport.unvalidated\ .filter(period=self.args.period): # entity has no parent. Either Mali or error if not report.entity.parent: # should never happen but we never know # drop if entity has no parent. if not report.entity.level == 0: return # we now have a national report logger.info(u"Report %s found." % report) report._status = MalariaReport.STATUS_VALIDATED with reversion.create_revision(): report.save() reversion.set_user(get_autobot().user) #report.save() # send emails ct, oi = Access.target_data(Entity.objects.get(slug='mali')) nat_access = list(Access.objects.filter(content_type=ct, \ object_id=oi)) providers = list(Provider.active\ .select_related()\ .filter(user__email__isnull=False, \ access__in=nat_access)\ .values_list('user__email', flat=True)) rurl = full_url(path=reverse('raw_data', \ kwargs={'entity_code': report.entity.slug, \ 'period_str': report.period.middle().strftime('%m%Y')})) sent, sent_message = send_email(recipients=providers, \ context={'report': report, \ 'report_url': rurl, \ 'url': full_url()}, template='emails/mali_report_available.txt', \ title_template='emails/title.mali_report_available.txt') # the rest of the method is only for non-national return # we only send notifications for CSCom & District reports. if report.entity.type.slug not in ('cscom', 'district'): continue # we don't bug district if cscom period is over if report.entity.type.slug == 'cscom' \ and time_cscom_over(period=self.args.period): continue # we don't bug region if district period is over if report.entity.type.slug == 'district' \ and time_district_over(period=self.args.period): continue # create a dedicated alert so it can be tracked by report # then fire it. alert = IndividualMalariaReportCreated.create(report=report) if alert.can_trigger(): alert.trigger()