Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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",
            )
Esempio n. 4
0
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