Пример #1
0
    def report_diarrhea(self, message, ref_id, ors, days, complications):
        case = self.find_case(ref_id)

        ors     = True if ors == "y" else False
        days    = int(days)

        observed, choices = self.get_diarrheaobservations(complications)
        self.delete_similar(case.reportdiarrhea_set)

        reporter = message.persistant_connection.reporter
        report = ReportDiarrhea(case=case, reporter=reporter, ors=ors, days=days)
        report.save()
        for obs in observed:
            report.observed.add(obs)
        report.diagnose()
        report.save()

        choice_term = dict(choices)

        info = case.get_dictionary()
        info.update(report.get_dictionary())

        msg = _("%(diagnosis_msg)s. +%(ref_id)s %(last_name)s, %(first_name_short)s, %(gender)s/%(months)s (%(guardian)s). %(days)s, %(ors)s") % info

        if observed: msg += ", " + info["observed"]

        message.respond("DIARRHEA> " + msg)
        
        """
        if report.status in (report.MODERATE_STATUS,
                           report.SEVERE_STATUS,
                           report.DANGER_STATUS):
            alert = _("@%(username)s reports %(msg)s") % {"username":provider.user.username, "msg":msg}
            recipients = [provider]
            for query in (Provider.objects.filter(alerts=True),
                          Provider.objects.filter(clinic=provider.clinic)):
                for recipient in query:
                    if recipient in recipients: continue
                    recipients.append(recipient)
                    message.forward(recipient.mobile, alert)
        """
        log(case, "diarrhea_taken")
        return True            
Пример #2
0
    def followup_diarrhea(self, message, ref_id, is_ok):
        case    = self.find_case(ref_id)
        is_ok   = True if is_ok == "y" else False

        reporter = message.persistant_connection.reporter
        report = ReportDiarrhea.objects.get(case=case)
        
        if is_ok:
            report.status   = ReportDiarrhea.HEALTHY_STATUS
            report.save()
        else:
            report.status   = ReportDiarrhea.SEVERE_STATUS
            report.save()

            info = report.case.get_dictionary()
            info.update(report.get_dictionary())
   
            msg = _("%(diagnosis_msg)s. +%(ref_id)s %(last_name)s, %(first_name_short)s, %(gender)s/%(months)s (%(guardian)s). %(days)s, %(ors)s") % info
            if report.observed.all().count() > 0: msg += ", " + info["observed"]
            
            message.respond("DIARRHEA> " + msg)
            
        
        """
        if report.status in (report.MODERATE_STATUS,
                           report.SEVERE_STATUS,
                           report.DANGER_STATUS):
            alert = _("@%(username)s reports %(msg)s") % {"username":reporter.alias, "msg":msg}
            recipients = [reporter]
            for query in (Provider.objects.filter(alerts=True),
                          Provider.objects.filter(clinic=provider.clinic)):
                for recipient in query:
                    if recipient in recipients: continue
                    recipients.append(recipient)
                    message.forward(recipient.mobile, alert)
        """      
        log(case, "diarrhea_fu_taken")
        return True
Пример #3
0
    def report_malaria(self, message, ref_id, result, bednet, observed):
        """Processes incoming mrdt reports.  Expected format is as above.  Can process inputs without spaces, but symptoms must have spaces between them.  '+' and 'y' register as positive for malaria, all other characters register as negative. 'y' registers as yes for a bednet, all other characters register as no."""

        case = self.find_case(ref_id)
        observed, choices = self.get_observations(observed)
        self.delete_similar(case.reportmalaria_set)
        reporter = message.persistant_connection.reporter

        result = result == "+" or result.lower() == "y"
        bednet = bednet.lower() == "y"

        report = ReportMalaria(case=case, reporter=reporter, result=result, bednet=bednet)
        report.save()
        for obs in observed:
            report.observed.add(obs)
        report.save()

        # build up an information dictionary
        info = case.get_dictionary()
        info.update(report.get_dictionary())
        info.update(
            {
                "reporter_name": reporter.full_name(),
                "reporter_alias": reporter.alias,
                "reporter_identity": reporter.connection().identity,
            }
        )

        # this could all really do with cleaning up
        # note that there is always an alert that goes out
        if not result:
            if observed:
                info["observed"] = ", (%s)" % info["observed"]
            msg = _(
                "MRDT> Child +%(ref_id)s, %(last_name)s, %(first_name)s, "
                "%(gender)s/%(age)s (%(guardian)s), %(location)s. RDT=%(result_text)s,"
                " Bednet=%(bednet_text)s%(observed)s. Please refer patient IMMEDIATELY "
                "for clinical evaluation" % info
            )
            # alerts to health team
            alert = _(
                "MRDT> Negative MRDT with Fever. +%(ref_id)s, %(last_name)s,"
                " %(first_name)s, %(gender)s/%(age)s %(location)s. Patient "
                "requires IMMEDIATE referral. Reported by CHW %(reporter_name)s "
                "@%(reporter_alias)s m:%(reporter_identity)s." % info
            )

        else:
            # this is all for if child has tested postive
            # and is really just abut
            years, months = case.years_months()
            tabs, yage = None, None
            # just reformatted to make it look like less ugh
            if years < 1:
                if months < 5:
                    tabs, yage = None, None
                else:
                    tabs, yage = "one quarter", "under one year (5-10kg)"
            elif years < 7:
                tabs, yage = "one half", "1-6 years (11-24kg)"
            elif years < 14:
                tabs, yage = "one ", "7-13 years (25-50kg)"
            elif years < 18:
                tabs, yage = "one and a half", "14 - 17 years (50-70kg)"
            else:
                tabs, yage = "two", "18+ years (70+ kg)"

            # messages change depending upon age and dangers
            dangers = report.observed.filter(uid__in=("vomiting", "appetite", "breathing", "confusion", "fits"))
            # no tabs means too young
            if not tabs:
                info["instructions"] = "Child is too young for treatment. Please refer IMMEDIATELY to clinic"
            else:
                # old enough to take tabs, but lets format msg
                if dangers:
                    info["danger"] = " and danger signs (" + ",".join([u.name for u in dangers]) + ")"
                    info[
                        "instructions"
                    ] = "Refer to clinic after %s " " each of Artesunate 50mg and Amodiaquine 150mg is given" % (tabs)
                else:
                    info["danger"] = ""
                    info["instructions"] = (
                        "Child is %s. %s each of Artesunate 50mg and Amodiaquine 150mg morning and evening for 3 days"
                        % (yage, tabs)
                    )

            # finally build out the messages
            msg = _(
                "Patient +%(ref_id)s, %(first_name)s %(last_name)s, %(gender)s/%(age)s (%(guardian)s). Bednet=%(bednet_text)s %(observed)s.  Patient has MALARIA%(danger)s."
                % (info)
            )

            alert = _(
                "MRDT> Child +%(ref_id)s, %(last_name)s, %(first_name)s, "
                "%(gender)s/%(months)s (%(location)s) has MALARIA%(danger)s. "
                "CHW: @%(reporter_alias)s %(reporter_identity)s" % info
            )

        message.respond(msg)
        message.respond(_(info["instructions"]))
        """ @todo: enable alerts """
        """
        recipients = report.get_alert_recipients()
        for recipient in recipients:
            message.forward(recipient.mobile, alert)
        """

        log(case, "mrdt_taken")
        return True
Пример #4
0
    def report_case (self, message, ref_id, muac,
                     weight, height, complications):
        case = self.find_case(ref_id)
        try:
            muac = float(muac)
            if muac < 30: # muac is in cm?
                muac *= 10
            muac = int(muac)
        except ValueError:
            raise HandlerFailed(
                _("Can't understand MUAC (mm): %s") % muac)

        if weight is not None:
            try:
                weight = float(weight)
                if weight > 100: # weight is in g?
                    weight /= 1000.0
            except ValueError:
                raise HandlerFailed("Can't understand weight (kg): %s" % weight)

        if height is not None:
            try:
                height = float(height)
                if height < 3: # weight height in m?
                    height *= 100
                height = int(height)
            except ValueError:
                raise HandlerFailed("Can't understand height (cm): %s" % height)

        observed, choices = self.get_observations(complications)
        self.delete_similar(case.reportmalnutrition_set)

        reporter = message.persistant_connection.reporter
        report = ReportMalnutrition(case=case, reporter=reporter, muac=muac,
                        weight=weight, height=height)
        report.save()
        for obs in observed:
            report.observed.add(obs)
        report.diagnose()
        report.save()

        #choice_term = dict(choices)

        info = case.get_dictionary()
        info.update(report.get_dictionary())

        msg = _("%(diagnosis_msg)s. +%(ref_id)s %(last_name)s, %(first_name_short)s, %(gender)s/%(months)s (%(guardian)s). MUAC %(muac)s") % info

        if weight: msg += ", %.1f kg" % weight
        if height: msg += ", %.1d cm" % height
        if observed: msg += ", " + info["observed"]

        message.respond("MUAC> " + msg)
        
        """ @todo   enable alerts      """
        """
        if report.status in (report.MODERATE_STATUS,
                           report.SEVERE_STATUS,
                           report.SEVERE_COMP_STATUS):
            alert = _("@%(username)s reports %(msg)s") % {"username":provider.user.username, "msg":msg}
            recipients = [provider]
            for query in (Provider.objects.filter(alerts=True),
                          Provider.objects.filter(clinic=provider.clinic)):
                for recipient in query:
                    if recipient in recipients: continue
                    recipients.append(recipient)
                    #message.forward(recipient.mobile, alert)
        """
        log(case, "muac_taken")
        return True
Пример #5
0
 def report_birth(self, message, last, first, gender, dob, weight,where, guardian, complications=""):
     if len(dob) != 6:
         # There have been cases where a date like 30903 have been sent and
         # when saved it gives some date that is way off
         raise HandlerFailed(_("Date must be in the format ddmmyy: %s") % dob)
     else:
         dob = re.sub(r'\D', '', dob)
         try:
             dob = time.strptime(dob, "%d%m%y")
         except ValueError:
             try:
                 dob = time.strptime(dob, "%d%m%Y")
             except ValueError:
                 raise HandlerFailed(_("Couldn't understand date: %s") % dob)
         dob = datetime.date(*dob[:3])        
     reporter = message.persistant_connection.reporter
     location = None
     if not location:
         if reporter.location:
             location = reporter.location
     
     info = {
         "first_name" : first.title(),
         "last_name"  : last.title(),
         "gender"     : gender.upper(),
         "dob"        : dob,
         "guardian"   : guardian.title(),
         "mobile"     : "",
         "reporter"   : reporter,
         "location"       : location
     }
     
     abirth = ReportBirth(where=where.upper())
     #Perform Location checks
     if abirth.get_where() is None:
         raise HandlerFailed(_("Location `%s` is not known. Please try again with a known location") % where)
     
     iscase = Case.objects.filter(first_name=info['first_name'], last_name=info['last_name'], reporter=info['reporter'], dob=info['dob'])
     if iscase:
         info["PID"] = iscase[0].ref_id
         self.info(iscase[0].id)
         self.info(info)
         #message.respond(_(
         #"%(last_name)s, %(first_name)s (+%(PID)s) has already been registered by %(provider)s.") % info)
         # TODO: log this message
         case = iscase[0]
     else:
         case = Case(**info)
         case.save()
         log(case, "patient_created")
     
     info.update({
         "id": case.ref_id,
         "last_name": last.upper(),
         "age": case.age(),
         "dob": dob.strftime("%d/%m/%y")
     })
     
     info2 = {
         "case":case,
         "weight": weight,
         "where": where,
         "reporter": reporter,
         "complications": complications
     }
     
     #check if birth has already been reported
     rbirth = ReportBirth.objects.filter(case=case)
     
     if rbirth:
         raise HandlerFailed(_(
         "The birth of %(last_name)s, %(first_name)s (+%(PID)s) has already been reported by %(reporter)s.") % info)
         
     
     abirth = ReportBirth(**info2)
     abirth.save()
     
     info.update({"where":abirth.get_where()})
     
     message.respond(_(
         "Birth +%(id)s: %(last_name)s, %(first_name)s %(gender)s/%(dob)s " +
         "(%(guardian)s) %(location)s at %(where)s") % info)
     
     
     return True
Пример #6
0
    def diagnosis(self, message, ref_id, text):
        case = self.find_case(ref_id)
        reporter = message.persistant_connection.reporter
        diags = []
        labs = []

        hits = find_diagnostic_re.findall(message.text)
        for hit in hits:
            code = hit[2:]
            try:
                diags.append(Diagnosis.objects.get(code__iexact=code))
            except Diagnosis.DoesNotExist:
                raise HandlerFailed("Unknown diagnosis code: %s" % code)

        hits = find_lab_re.findall(text)
        for hit in hits:
            code, sign, number = hit
            try:
                # the code starts with /
                labs.append([Lab.objects.get(code__iexact=code[1:]), sign, number])
            except Lab.DoesNotExist:
                raise HandlerFailed("Unknown lab code: %s" % code)

        self.delete_similar(case.reportdiagnosis_set)
        report = ReportDiagnosis(case=case, reporter=reporter, text=message.text)
        report.save()
        for diag in diags:
            report.diagnosis.add(diag)
        for lab, sign, number in labs:
            ld = LabDiagnosis()
            ld.lab = lab
            ld.result = int(sign == "+")
            if number:
                ld.amount = number
            ld.diagnosis = report
            ld.save()
        report.save()

        info = case.get_dictionary()
        info.update(report.get_dictionary())
        if info["labs_text"]:
            info["labs_text"] = "%sLabs: %s" % (info["diagnosis"] and " " or "", info["labs_text"])

        message.respond(_("D> +%(ref_id)s %(first_name_short)s.%(last_name)s %(diagnosis)s%(labs_text)s") % info)
        
        # add in the forward of instructions to the case provider
        # if that it is not the reporter of the issue        

        
        instructions = []       
        for diagnosis in report.diagnosis.all():
            if diagnosis.instructions:
                instructions.append(diagnosis.instructions)

        if instructions:
            if reporter != case.reporter:
                # there's a different provider
                info = {"ref_id":ref_id, "instructions":(", ".join(instructions))}
                message.forward(case.reporter.connection().identity, "D> +%(ref_id)s %(instructions)s" % info)
                
                
        log(case, "diagnosis_taken")        
        return True