def create_report(self, author): """ creates and save a MalariaReport based on current data_browser No check nor validation is performed """ period = MonthPeriod.find_create_from(year=self.get('year'), \ month=self.get('month')) entity = Entity.objects.get(slug=self.get('hc'), type__slug='cscom') report = MalariaReport.start(period, entity, author, \ type=MalariaReport.TYPE_SOURCE) report.add_underfive_data(*self.data_for_cat('u5')) report.add_overfive_data(*self.data_for_cat('o5')) report.add_pregnantwomen_data(*self.data_for_cat('pw')) report.add_stockout_data(*self.data_for_cat('so')) report.save() return report
def action(self): """ Validate remaining reports and inform region """ # retrieve autobot provider if possible try: author = Provider.active.get(user__username='******') except: author = None if self.args.is_district: validate_level = 'cscom' aggregate_level = 'district' else: validate_level = 'district' aggregate_level = 'region' # validate non-validated reports for report in MalariaReport.unvalidated\ .filter(period=self.args.period, \ entity__type__slug=validate_level): report._status = MalariaReport.STATUS_VALIDATED if author: report.modified_by = author report.modified_on = datetime.now() with reversion.create_revision(): report.save() if author: reversion.set_user(author.user) else: reversion.set_user(get_autobot().user) #report.save() # create aggregated reports for entity in Entity.objects.filter(type__slug=aggregate_level): if entity.pnlp_core_malariareport_reports\ .filter(period=self.args.period).count() > 0: continue rauthor = contact_for(entity) if not author else author logger.info(u"Creating Aggregated report for %s" % entity) report = MalariaReport.create_aggregated(self.args.period, \ entity, rauthor) # region auto-validates their reports if not self.args.is_district: report._status = MalariaReport.STATUS_VALIDATED #report.save() with reversion.create_revision(): report.save() reversion.set_user(rauthor.user) # region-only section # create national report mali = Entity.objects.get(slug='mali') if not self.args.is_district \ and mali.pnlp_core_malariareport_reports\ .filter(period=self.args.period).count() == 0: rauthor = author if author else get_autobot() logger.info(u"Creating National report") report = MalariaReport.create_aggregated(self.args.period, \ mali, rauthor) # following only applies to districts (warn regions). return # district-only section # let region know there are reports to validate for region in Entity.objects.filter(type__slug='region'): contact = contact_for(region, recursive=False) # skip if not recipient if not contact or not contact.phone_number: continue nb_reports = MalariaReport.unvalidated\ .filter(period=self.args.period, \ entity__type__slug='district', \ entity__parent=region).count() message = u"[PNLP] La periode de validation CSRef est " \ u"terminee. Vous avez %(nb)d rapports de " \ u"CSRef a valider." % {'nb': nb_reports} email_title = u"[PNLP] Fin de la periode de validation CSRef" if not contact.email: continue send_email(contact.email, message=message, title=email_title)
def palu(message): # common start of error message error_start = u"Impossible d'enregistrer le rapport. " # create variables from text messages. try: args_names = ['kw1', 'username', 'password', 'month', 'year', \ 'u5_total_consultation_all_causes', \ 'u5_total_suspected_malaria_cases', \ 'u5_total_simple_malaria_cases', \ 'u5_total_severe_malaria_cases', \ 'u5_total_tested_malaria_cases', \ 'u5_total_confirmed_malaria_cases', \ 'u5_total_treated_malaria_cases', \ 'u5_total_inpatient_all_causes', \ 'u5_total_malaria_inpatient', \ 'u5_total_death_all_causes', \ 'u5_total_malaria_death', \ 'u5_total_distributed_bednets', \ 'o5_total_consultation_all_causes', \ 'o5_total_suspected_malaria_cases', \ 'o5_total_simple_malaria_cases', \ 'o5_total_severe_malaria_cases', \ 'o5_total_tested_malaria_cases', \ 'o5_total_confirmed_malaria_cases', \ 'o5_total_treated_malaria_cases', \ 'o5_total_inpatient_all_causes', \ 'o5_total_malaria_inpatient', \ 'o5_total_death_all_causes', \ 'o5_total_malaria_death', \ 'pw_total_consultation_all_causes', \ 'pw_total_suspected_malaria_cases', \ 'pw_total_severe_malaria_cases', \ 'pw_total_tested_malaria_cases', \ 'pw_total_confirmed_malaria_cases', \ 'pw_total_treated_malaria_cases', \ 'pw_total_inpatient_all_causes', \ 'pw_total_malaria_inpatient', \ 'pw_total_death_all_causes', \ 'pw_total_malaria_death', \ 'pw_total_distributed_bednets', \ 'pw_total_anc1', \ 'pw_total_sp1', \ 'pw_total_sp2', \ 'stockout_act_children', 'stockout_act_youth', 'stockout_act_adult', \ 'stockout_artemether', 'stockout_quinine', 'stockout_serum', \ 'stockout_bednet', 'stockout_rdt', 'stockout_sp'] args_values = message.content.strip().lower().split() arguments = dict(zip(args_names, args_values)) except ValueError: # failure to split means we proabably lack a data or more # we can't process it. message.respond(error_start + u" Le format du SMS est incorrect.") return True # convert form-data to int or bool respectively try: for key, value in arguments.items(): if key.split('_')[0] in ('u5', 'o5', 'pw', 'month', 'year'): arguments[key] = int(value) if key.split('_')[0] == 'stockout': arguments[key] = MalariaReport.YES if bool(int(value)) \ else MalariaReport.NO except: raise # failure to convert means non-numeric value which we can't process. message.respond(error_start + u" Les données sont malformées.") return True # check credentials try: provider = Provider.active.get(user__username=arguments['username']) except Provider.DoesNotExist: message.respond(error_start + u"Ce nom d'utilisateur " + u"(%s) n'existe pas." % \ arguments['username']) return True if not provider.check_password(arguments['password']): message.respond(error_start + u"Votre mot de passe est incorrect.") return True # now we have well formed and authenticated data. # let's check for business-logic errors. # create a data holder for validator data_browser = MalariaDataHolder() # feed data holder with sms provided data for key, value in arguments.items(): if key.split('_')[0] in ('u5', 'o5', 'pw', \ 'stockout', 'year', 'month'): data_browser.set(key, value) # feed data holder with guessable data try: hc = entity_for(provider).slug except: hc = None data_browser.set('hc', hc) today = datetime.date.today() data_browser.set('fillin_day', today.day) data_browser.set('fillin_month', today.month) data_browser.set('fillin_year', today.year) data_browser.set('author', provider.name()) # create validator and fire validator = MalariaReportValidator(data_browser) validator.errors.reset() try: validator.validate() except AttributeError as e: message.respond(error_start + e.__str__()) return True errors = validator.errors # return first error to user if errors.count() > 0: message.respond(error_start + errors.all()[0]) return True # create the report try: period = MonthPeriod.find_create_from(year=data_browser.get('year'), \ month=data_browser.get('month')) entity = Entity.objects.get(slug=data_browser.get('hc'), \ type__slug='cscom') report = MalariaReport.start(period, entity, provider, \ type=MalariaReport.TYPE_SOURCE) report.add_underfive_data(*data_browser.data_for_cat('u5')) report.add_overfive_data(*data_browser.data_for_cat('o5')) report.add_pregnantwomen_data(*data_browser.data_for_cat('pw')) report.add_stockout_data(*data_browser.data_for_cat('so')) #report.save() with reversion.create_revision(): report.save() reversion.set_user(provider.user) except Exception as e: message.respond(error_start + u"Une erreur technique s'est " \ u"produite. Reessayez plus tard et " \ u"contactez ANTIM si le probleme persiste.") logger.error(u"Unable to save report to DB. Message: %s | Exp: %r" \ % (message.content, e)) return True message.respond(u"[SUCCES] Le rapport de %(cscom)s pour %(period)s " u"a ete enregistre. " \ u"Le No de recu est #%(receipt)s." \ % {'cscom': report.entity.display_full_name(), \ 'period': report.period, \ 'receipt': report.receipt}) try: to = contact_for(report.entity.parent).phone_number except: to = None if not to: return True send_sms(to, u"[ALERTE] Le CSCom %(cscom)s vient d'envoyer le " \ u"rapport #%(receipt)s pour %(period)s." \ % {'cscom': report.entity.display_full_name(), \ 'period': report.period, \ 'receipt': report.receipt}) return True
def palu(message): # common start of error message error_start = "Impossible d'enregistrer le rapport. " # create variables from text messages. try: args_names = ['kw1', 'username', 'password', 'month', 'year', \ 'u5_total_consultation_all_causes', \ 'u5_total_suspected_malaria_cases', \ 'u5_total_simple_malaria_cases', \ 'u5_total_severe_malaria_cases', \ 'u5_total_tested_malaria_cases', \ 'u5_total_confirmed_malaria_cases', \ 'u5_total_treated_malaria_cases', \ 'u5_total_inpatient_all_causes', \ 'u5_total_malaria_inpatient', \ 'u5_total_death_all_causes', \ 'u5_total_malaria_death', \ 'u5_total_distributed_bednets', \ 'o5_total_consultation_all_causes', \ 'o5_total_suspected_malaria_cases', \ 'o5_total_simple_malaria_cases', \ 'o5_total_severe_malaria_cases', \ 'o5_total_tested_malaria_cases', \ 'o5_total_confirmed_malaria_cases', \ 'o5_total_treated_malaria_cases', \ 'o5_total_inpatient_all_causes', \ 'o5_total_malaria_inpatient', \ 'o5_total_death_all_causes', \ 'o5_total_malaria_death', \ 'pw_total_consultation_all_causes', \ 'pw_total_suspected_malaria_cases', \ 'pw_total_severe_malaria_cases', \ 'pw_total_tested_malaria_cases', \ 'pw_total_confirmed_malaria_cases', \ 'pw_total_treated_malaria_cases', \ 'pw_total_inpatient_all_causes', \ 'pw_total_malaria_inpatient', \ 'pw_total_death_all_causes', \ 'pw_total_malaria_death', \ 'pw_total_distributed_bednets', \ 'pw_total_anc1', \ 'pw_total_sp1', \ 'pw_total_sp2', \ 'stockout_act_children', 'stockout_act_youth', 'stockout_act_adult', \ 'stockout_arthemeter', 'stockout_quinine', 'stockout_serum', \ 'stockout_bednet', 'stockout_rdt', 'stockout_sp'] args_values = message.text.strip().lower().split() arguments = dict(zip(args_names, args_values)) except ValueError: # failure to split means we proabably lack a data or more # we can't process it. message.respond(error_start + " Le format du SMS est incorrect.") return True # convert form-data to int or bool respectively try: for key, value in arguments.items(): if key.split('_')[0] in ('u5', 'o5', 'pw', 'month', 'year'): arguments[key] = int(value) if key.split('_')[0] == 'stockout': arguments[key] = bool(value) except: raise # failure to convert means non-numeric value which we can't process. message.respond(error_start + " Les données sont malformées.") return True # check credentials try: provider = Provider.objects.get(user__username=arguments['username']) except Provider.DoesNotExist: message.respond(error_start + "Ce nom d'utilisateur " + "(%s) n'existe pas." % username) return True if not provider.check_password(arguments['password']): message.respond(error_start + "Votre mot de passe est incorrect.") return True # now we have well formed and authenticated data. # let's check for business-logic errors. # create a data holder for validator data_browser = MalariaDataHolder() # feed data holder with sms provided data for key, value in arguments.items(): if key.split('_')[0] in ('u5', 'o5', 'pw', \ 'stockout', 'year', 'month'): data_browser.set(key, value) # feed data holder with guessable data try: hc = entity_for(provider).slug except: hc = None data_browser.set('hc', hc) today = datetime.date.today() data_browser.set('fillin_day', today.day) data_browser.set('fillin_month', today.month) data_browser.set('fillin_year', today.year) data_browser.set('author', provider.name()) # create validator and fire validator = MalariaReportValidator(data_browser) try: validator.validate() except AttributeError as e: message.respond(error_start + e.__str__()) return True errors = validator.errors # return first error to user if errors.count() > 0: message.respond(error_start + errors.all()[0]) return True # create the report try: period = MonthPeriod.find_create_from(year=data_browser.get('year'), \ month=data_browser.get('month')) entity = Entity.objects.get(slug=data_browser.get('hc'), \ type__slug='cscom') report = MalariaReport.start(period, entity, provider, \ type=MalariaReport.TYPE_SOURCE) report.add_underfive_data(*data_browser.data_for_cat('u5')) report.add_overfive_data(*data_browser.data_for_cat('o5')) report.add_pregnantwomen_data(*data_browser.data_for_cat('pw')) report.add_stockout_data(*data_browser.data_for_cat('so')) report.save() except Exception as e: message.respond(error_start + "Une erreur technique s'est produite. " \ "Reessayez plus tard et contactez ANTIM si " \ "le probleme persiste.") # log that error raise return True message.respond("[SUCCES] Le rapport de %(cscom)s pour %(period)s " "a ete enregistre. " \ "Le No de recu est #%(receipt)s." \ % {'cscom': report.entity.display_full_name(), \ 'period': report.period, \ 'receipt': report.receipt}) return True