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 validate(self): """ Test whether attached data matches PNLP's logic requirements """ no_more_than_text = _("%(field2)s (%(f2value)d) can't be more " "than %(field1)s (%(f1value)d)") allcats = ("u5", "o5", "pw") noo5cat = ("u5", "pw") nopwcat = ("u5", "o5") def test_value_under(fieldref, fieldtest, cats): for cat in cats: try: dic = { "field2": self.field_name("%s_%s" % (cat, fieldtest)), "f2value": self.get("%s_%s" % (cat, fieldtest)), "field1": self.field_name("%s_%s" % (cat, fieldref)), "f1value": self.get("%s_%s" % (cat, fieldref)), } if dic["f1value"] < dic["f2value"]: self.errors.add(no_more_than_text % dic, cat) except MissingData: # this missing data should have already been reported pass # total > malaria cases test_value_under("total_consultation_all_causes", "total_suspected_malaria_cases", allcats) # total > malaria simple test_value_under("total_consultation_all_causes", "total_simple_malaria_cases", nopwcat) # total > malaria severe test_value_under("total_consultation_all_causes", "total_severe_malaria_cases", allcats) # suspected > malaria simple test_value_under("total_suspected_malaria_cases", "total_simple_malaria_cases", nopwcat) # suspected > malaria severe test_value_under("total_suspected_malaria_cases", "total_severe_malaria_cases", allcats) # suspected > malaria tested test_value_under("total_suspected_malaria_cases", "total_tested_malaria_cases", allcats) # suspected > malaria confirmed test_value_under("total_suspected_malaria_cases", "total_confirmed_malaria_cases", allcats) # suspected > simple + severe for cat in nopwcat: try: dic = { "field2": _(u"%(simple)s + %(severe)s") % { "simple": self.field_name("%s_total_simple_malaria_cases" % cat), "severe": self.field_name("%s_total_severe_malaria_cases" % cat), }, "f2value": int(self.get("%s_total_simple_malaria_cases" % cat)) + int(self.get("%s_total_severe_malaria_cases" % cat)), "field1": self.field_name("%s_total_suspected_malaria_cases" % cat), "f1value": self.get("%s_total_suspected_malaria_cases" % cat), } if dic["f1value"] < dic["f2value"]: self.errors.add(no_more_than_text % dic, cat) except MissingData: pass # tested > confirmed test_value_under("total_tested_malaria_cases", "total_confirmed_malaria_cases", allcats) # tested > ACT test_value_under("total_tested_malaria_cases", "total_treated_malaria_cases", allcats) # confirmed > act test_value_under("total_confirmed_malaria_cases", "total_treated_malaria_cases", allcats) # total inpatient > malaria inpatient test_value_under("total_inpatient_all_causes", "total_malaria_inpatient", allcats) # total death > malaria death test_value_under("total_death_all_causes", "total_malaria_death", allcats) # PERIOD MONTH # range(1, 12) # already handled. # PERIOD YEAR # range(2010, 2020) # already handled # NO FUTURE if self.get("year") >= date.today().year and self.get("month") >= date.today().month: self.errors.add( _(u"The period of data (%(period)s) " "is in the future.") % {"period": u"%s %d" % (self.get("month").__str__().zfill(2), self.get("year"))}, "period", ) # DATE DAY / MONTH / YEAR try: date(self.get("fillin_year"), self.get("fillin_month"), self.get("fillin_day")) except ValueError: self.errors.add( _(u"The fillin day (%(day)s) is out of range " "for that month (%(month)s)") % { "day": self.get("fillin_day").__str__().zfill(2), "month": self.get("fillin_month").__str__().zfill(2), }, "fillin", ) # REPORTER NAME pass # ENTITY try: entity = Entity.objects.get(slug=self.get("hc"), type__slug="cscom") except Entity.DoesNotExist: entity = None self.errors.add( _(u"The entity code (%(code)s) does not " "match any HC.") % {"code": self.get("hc")}, "period" ) # NO DUPLICATE period = MonthPeriod.find_create_from(year=self.get("year"), month=self.get("month")) if entity and MalariaReport.objects.filter(entity=entity, period=period).count() > 0: self.errors.add( _(u"There is already a report for " "that HC (%(entity)s) and that " "period (%(period)s)") % {"entity": entity.display_full_name(), "period": period.name()}, "period", )
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