コード例 #1
0
ファイル: views.py プロジェクト: dimagi/bhoma
def single(request, chw_id):
    """
    Single CHW
    """
    chw = CommunityHealthWorker.get(chw_id)
    return render_to_response(request, "chw/single_chw.html", 
                              {"chw": chw }) 
コード例 #2
0
ファイル: views.py プロジェクト: dimagi/bhoma
def list_chws(request):
    """
    List chws
    """
    chws = CommunityHealthWorker.view("chw/by_clinic", include_docs=True)
    return render_to_response(request, "chw/chw_list.html",
                              {"chws": chws})
コード例 #3
0
ファイル: views.py プロジェクト: dimagi/bhoma
def single_chw_summary(request):
    """Report for a single CHW""" 
    chw_id = request.GET.get("chw", None)
    chws = CommunityHealthWorker.view("chw/by_clinic", include_docs=True)
    main_chw = CommunityHealthWorker.get(chw_id) if chw_id else None
    
    punchcard_url = ""
    if main_chw:
        punchcard_url = get_punchcard_url(get_data(main_chw.current_clinic_id, chw_id), width=910)
        # patch on extra data for display
        main_chw.last_submission = get_last_submission_date(main_chw.get_id)    
        main_chw.first_submission = get_first_submission_date(main_chw.get_id)    
        main_chw.forms_submitted = get_forms_submitted(main_chw.get_id)    
        forms_breakdown = get_submission_breakdown(main_chw.get_id)
        main_chw.hh_surveys = forms_breakdown[config.CHW_HOUSEHOLD_SURVEY_NAMESPACE]
        main_chw.fus = forms_breakdown[config.CHW_FOLLOWUP_NAMESPACE]
        main_chw.refs = forms_breakdown[config.CHW_REFERRAL_NAMESPACE]
        main_chw.monthly_surveys = forms_breakdown[config.CHW_MONTHLY_SURVEY_NAMESPACE]
        
        # recent monthly surveys
        main_chw.recent_surveys = get_recent_forms(main_chw.get_id, config.CHW_MONTHLY_SURVEY_NAMESPACE)
        
        if not request.datespan.is_valid():
            messages.error(request, request.datespan.get_validation_reason())
            messages.warning(request, "Performance Indicators are not displayed. Please fix the other errors")
            report = {"name": "Partial CHW Summary for %s" % main_chw.formatted_name}
        else:
            report = get_chw_pi_report(main_chw, request.datespan.startdate, request.datespan.enddate)
    else:        
        report = {"name": "CHW Summary"}
    fake_hh_data = []
    now = datetime.now()
    for i in range(3):
        year, month = add_months(now.year, now.month, -i)
        fake_hh_data.append(["%s %s" % (year, month), 100, 200, "25%", "13%"])
        
    return render_to_response(request, "reports/chw_summary.html", 
                              {"report": report,
                               "chw_id": chw_id,
                               "main_chw":    main_chw,
                               "chws":   chws,
                               "punchcard_url":    punchcard_url,
                               "show_dates": False,
                               "hh_data": fake_hh_data, # TODO
                               "fu_data": fake_hh_data, # TODO
                               "ref_data": fake_hh_data # TODO
                               })
コード例 #4
0
ファイル: forms.py プロジェクト: dimagi/bhoma
    def _read_only(self, field, attr):
        id = self.cleaned_data['id']
        data = self.cleaned_data[field]
        if id and data != CommunityHealthWorker.get(id)[attr]:
            raise forms.ValidationError("Sorry, you are not allowed to change the %s!" % attr)

        # Always return the cleaned data, whether you have changed it or
        return data
コード例 #5
0
ファイル: views.py プロジェクト: dimagi/bhoma
def chw_pi(request):
    """
    CHW Performance Indicator Report
    """
    # This is currently defunct and combined with the single CHW report.
    chw_id = request.GET.get("chw", None)
    chws = CommunityHealthWorker.view("chw/by_clinic", include_docs=True)
    main_chw = CommunityHealthWorker.get(chw_id) if chw_id else None
    report = { "name": "CHW PI Report" }
    if main_chw:
        if not request.datespan.is_valid():
            messages.error(request, request.datespan.get_validation_reason())
        else:
            report = get_chw_pi_report(main_chw, request.datespan.startdate, request.datespan.enddate)
    return render_to_response(request, "reports/chw_pi.html",
                              {"report": report, "chws": chws, 
                               "main_chw": main_chw,
                               "view_slug": "chw_pi"})
コード例 #6
0
ファイル: views.py プロジェクト: dimagi/bhoma
def chw_pi_details(request):
    year = int(request.GET["year"])
    month = int(request.GET["month"])
    
    chw_id = request.GET["chw"]
    col_slug = request.GET["col"]
    
    chw = CommunityHealthWorker.get(chw_id)
    report = ChwPiReportDetails(chw, year, month, col_slug)
    return render_to_response(request, "reports/chw_pi_details.html", 
                              {"report": report })
コード例 #7
0
ファイル: views.py プロジェクト: dimagi/bhoma
def _set_activation_status(request, chw_id, status):
    chw = CommunityHealthWorker.get(chw_id)
    display = "activate" if status else "deactivate"
    if chw.user == request.user:
        messages.error(request, "You can't %s the logged in user!" % display)
    elif chw.user:
        chw.user.is_active = status
        chw.user.save()
        messages.success(request, "User %s has been %sd." % (chw.formatted_name, display))
    else:
        messages.info(request, "There was no %sd account found for %s so nothing was done." % (display, chw.formatted_name))
    return HttpResponseRedirect(reverse("manage_chws"))
コード例 #8
0
ファイル: views.py プロジェクト: dimagi/bhoma
def delete(request, chw_id):
    """
    Delete a CHW
    """
    chw = CommunityHealthWorker.get(chw_id)
    name = chw.formatted_name
    if chw.user == request.user:
        messages.error(request, "You can't delete the logged in user!")
    else:
        if chw.user:
            chw.user.delete()
        chw.delete()
        messages.success(request, "User %s has been deleted." % name)
    return HttpResponseRedirect(reverse("manage_chws"))
コード例 #9
0
ファイル: views.py プロジェクト: dimagi/bhoma
def logs(request):
    # TODO: pagination, etc.
    logs = get_db().view("phone/sync_logs_by_chw", group=True, group_level=1).all()
    for log in logs:
        [chw_id] = log["key"]
        try:
            chw = CommunityHealthWorker.get(chw_id)
        except ResourceNotFound:
            chw = None
        log["chw"] = chw
        # get last sync:
        log["last_sync"] = SyncLog.last_for_chw(chw_id)
                                  
    return render_to_response(request, "phone/sync_logs.html", 
                              {"sync_data": logs})
コード例 #10
0
 def handle(self, *args, **options):
     if len(args) != 0:
         raise CommandError('Usage: manage.py add_clinic_ids_to_sync_logs')
     
     for sl in SyncLog.view("phone/sync_logs_by_chw", reduce=False, 
                             include_docs=True):
         try:
             chw = CommunityHealthWorker.get(sl.chw_id)
         except ResourceNotFound:
             chw = None
         if not chw:
             print "failed to update %s" % sl
             continue
         sl.clinic_id = chw.current_clinic_id
         sl.save()
                     
コード例 #11
0
ファイル: chw_stats.py プロジェクト: dimagi/bhoma
 def handle(self, *args, **options):
     db = Database(settings.BHOMA_NATIONAL_DATABASE)
     results = db.view("chw/by_clinic", include_docs=True).all()
     
     chws = [CommunityHealthWorker.wrap(res['doc']) for res in results]
     map = defaultdict(lambda: 0)
     
     def _fmt_date(dt):
         return "%s-%s" % (dt.year, dt.month)
     
     for chw in chws:
         print chw.username, chw.created_on
         map[_fmt_date(chw.created_on)] = map[_fmt_date(chw.created_on)] + 1
         
     for k in sorted(map.keys()):
         print "%s, %s" % (k, map[k])
コード例 #12
0
ファイル: views.py プロジェクト: dimagi/bhoma
def generate_restore_payload(user, restore_id):
    try:
        last_sync = None
        if restore_id:
            try:
                last_sync = SyncLog.get(restore_id)
            except Exception:
                logging.error("Request for bad sync log %s by %s, ignoring..." % (restore_id, user))
        
        username = user.username
        chw_id = user.get_profile().chw_id
        if not chw_id:
            raise Exception("No linked chw found for %s" % username)
        
        chw = CommunityHealthWorker.get(chw_id)
        last_seq = get_db().info()["update_seq"]
        cases_to_send = get_open_cases_to_send(chw.current_clinic_id, 
                                               chw.current_clinic_zone, 
                                               last_sync)
        case_xml_blocks = [xml.get_case_xml(case, create) for case, create in cases_to_send]
        
        # save the case blocks
        for case, _ in cases_to_send:
            case.save()
        
        saved_case_ids = [case.case_id for case, _ in cases_to_send]
        # create a sync log for this
        last_sync_id = last_sync.get_id if last_sync is not None else None
        
        # change 5/28/2011, always sync reg xml to phone
        reg_xml = xml.get_registration_xml(chw)
        synclog = SyncLog(chw_id=chw_id, last_seq=last_seq,
                          clinic_id=chw.current_clinic_id,
                          date=datetime.utcnow(), 
                          previous_log_id=last_sync_id,
                          cases=saved_case_ids)
        synclog.save()
                                             
        yield xml.RESTOREDATA_TEMPLATE % {"registration": reg_xml, 
                                          "restore_id": synclog.get_id, 
                                          "case_list": "".join(case_xml_blocks)}
    except Exception, e:
        logging.exception("problem restoring: %s" % user.username)
        raise
コード例 #13
0
ファイル: views.py プロジェクト: dimagi/bhoma
def restore_caseless(request):
    
    restore_id_from_request = lambda req: req.GET.get("since")
    restore_id = restore_id_from_request(request)
    last_sync = None
    if restore_id:
        try:
            last_sync = SyncLog.get(restore_id)
        except Exception:
            logging.error("Request for bad sync log %s by %s, ignoring..." % (restore_id, request.user))
    
    username = request.user.username
    chw_id = request.user.get_profile().chw_id
    if not chw_id:
        raise Exception("No linked chw found for %s" % username)
    chw = CommunityHealthWorker.get(chw_id)
    
    last_seq = 0 # hackity hack
    # create a sync log for this
    if last_sync == None:
        reg_xml = xml.get_registration_xml(chw)
        synclog = SyncLog(chw_id=chw_id, last_seq=last_seq,
                          clinic_id=chw.current_clinic_id,
                          date=datetime.utcnow(), previous_log_id=None,
                          cases=[])
        synclog.save()
    else:
        reg_xml = "" # don't sync registration after initial sync
        synclog = SyncLog(chw_id=chw_id, last_seq=last_seq,
                          date=datetime.utcnow(),
                          clinic_id=chw.current_clinic_id,
                          previous_log_id=last_sync.get_id,
                          cases=[])
        synclog.save()
                                         
    to_return = xml.RESTOREDATA_TEMPLATE % {"registration": reg_xml, 
                                            "restore_id": synclog.get_id, 
                                            "case_list": ""}
    return HttpResponse(to_return, mimetype="text/xml")
コード例 #14
0
ファイル: views.py プロジェクト: dimagi/bhoma
def new_or_edit(request, chw_id=None):
    """
    Create a new CHW
    """
    if request.method == "POST":
        form = CHWForm(data=request.POST)
        if form.is_valid():
            edit_mode = bool(form.cleaned_data["id"])
            if edit_mode:
                chw = CommunityHealthWorker.get(form.cleaned_data["id"])
            else:
                chw = CommunityHealthWorker()
                chw.created_on = datetime.utcnow()
            
            all_clinic_ids= [form.cleaned_data["current_clinic"].slug]
            chw.username = form.cleaned_data["username"]
            chw.password = form.cleaned_data["password"]
            chw.first_name = form.cleaned_data["first_name"]
            chw.last_name = form.cleaned_data["last_name"]
            chw.gender = form.cleaned_data["gender"]
            chw.current_clinic_id = form.cleaned_data["current_clinic"].slug
            chw.current_clinic_zone = int(form.cleaned_data["current_clinic_zone"])
            chw.clinic_ids = all_clinic_ids
            
            if not edit_mode:
                user = new_django_user_object(chw)
                
                if user.username != chw.username:
                    chw.username = user.username
            chw.save()
            if not edit_mode:
                user.save()
                user.get_profile().chw_id=chw.get_id
                # prevent them from logging in / showing up on the main screen
                user.get_profile().is_web_user=False 
                user.save()
                messages.success(request, "User %s has been created." % chw.formatted_name)
            else:
                messages.success(request, "User %s has been updated." % chw.formatted_name)
            
            return HttpResponseRedirect(reverse("manage_chws"))
            
    else:
        if chw_id:
            form = CHWForm.from_instance(CommunityHealthWorker.get(chw_id))
        else:
            form = CHWForm()

    return render_to_response(request, "chw/new_chw.html", 
                              {"form": form})
コード例 #15
0
ファイル: views.py プロジェクト: dimagi/bhoma
def export_chw_pis(request):
    report_slug = "chw_pi"
    chw_id = request.GET.get("chw", None)
    main_chw = CommunityHealthWorker.get(chw_id) 
    report = get_chw_pi_report(main_chw, request.datespan.startdate, request.datespan.enddate)
    return _export_pis(report, report_slug, non_data_cols=2)
コード例 #16
0
ファイル: views.py プロジェクト: dimagi/bhoma
def chw_dashboard_summary(clinic_dict):
    
    def _status_from_last_sync(last_sync):
        diff = datetime.utcnow() - last_sync.date if last_sync else None
        if not diff or diff > timedelta(days=5):
            return "bad"
        elif diff > timedelta(days=3):
            return "warn"
        else:
            return "good"
        
    def _fmt_hh_visits(num_visits, chw):
        ret = {}
        ret["count"] = num_visits
        
        zone = chw.get_zone()
        # > 100% of quota for the month in 30 days: green
        # 50 - 100% of quota for the month in 30 days: yellow
        # < 50% of quota for the month in 30 days: red
        # the quota is # of hh's in the zone / 3
        if zone:
            ret["households"] = zone.households
            ret["percent"] = float(100) * float(num_visits) / float(zone.households)  
            if num_visits > zone.households / 3:
                ret["status"] = "good"
            elif num_visits > zone.households / (2 * 3):
                ret["status"] = "warn"
            else: 
                ret["status"] = "bad"
        else:
            ret["percent"] = "?"
            ret["households"] = "?"
            ret["status"] = "unknown"
        return ret
    
    def _status_from_ref_visits(ref_visits):
        if ref_visits > 2:
            return "good"
        elif ref_visits > 0:
            return "warn"
        else: 
            return "bad"
        
    def _status_from_overdue_fus(fus):
        if fus > 2:
            return "bad"
        elif fus > 0:
            return "warn"
        else: 
            return "good"
        
    chws = filter(lambda chw: chw.user and chw.user.is_active,
                  CommunityHealthWorker.view("chw/by_clinic", key=clinic_dict["id"],
                                             include_docs=True).all())
    if chws:
        clinic_dict["active"] = True
        clinic_dict["chws"] = []
        for chw in chws:
            
            chw_dict = {
                "id":   chw.get_id,
                "name": chw.formatted_name,
                "zone": chw.current_clinic_zone 
            }
            # Metrics per CHW:
            # - date/time of last sync
            last_sync = SyncLog.view("phone/sync_logs_by_chw", reduce=False, 
                                     startkey=[chw.get_id, {}], endkey=[chw.get_id], 
                                     include_docs=True, limit=1, descending=True).one()
            chw_dict["last_sync"] = fmt_time(last_sync.date) if last_sync else None
            chw_dict["last_sync_status"] = _status_from_last_sync(last_sync)
            
            end = datetime.today() + timedelta(days=1)
            start = end - timedelta(days=30)
            
            # - current outstanding follow ups
            # Any follow up assigned to the CHW's clinic/zone that is past due
            # and not closed. This is different from the PI in that it won't
            # check whether or not the CHW has had that case sync down to their
            # phone or not.
            # This is much faster to calculate than anything else.
            res = get_db().view("centralreports/cases_due",
                                startkey=[chw.current_clinic_id, chw.current_clinic_zone, 0],
                                endkey=[chw.current_clinic_id, chw.current_clinic_zone, 
                                        end.year, end.month - 1, end.day],
                                reduce=True).one()
            chw_dict["overdue_fus"] = res["value"] if res else 0
            chw_dict["overdue_fus_status"] = _status_from_overdue_fus(chw_dict["overdue_fus"])
                        
            # - visits performed
            chw_dict["hh_visits"] = _fmt_hh_visits(forms_submitted\
                (chw.get_id, config.CHW_HOUSEHOLD_SURVEY_NAMESPACE,
                 start, end), chw)
            
            # - referrals made
            chw_dict["ref_visits"] = forms_submitted\
                (chw.get_id, config.CHW_REFERRAL_NAMESPACE,
                 start, end)
            chw_dict["ref_visits_status"] = _status_from_ref_visits(chw_dict["ref_visits"])
            
            clinic_dict["chws"].append(chw_dict)
        
        # sort
        clinic_dict["chws"].sort(key=lambda k: k['zone'])
            
    return clinic_dict
コード例 #17
0
ファイル: views.py プロジェクト: dimagi/bhoma
def logs_for_chw(request, chw_id):
    chw = CommunityHealthWorker.get(chw_id)
    return render_to_response(request, "phone/sync_logs_for_chw.html", 
                              {"chw": chw })