def single(request, chw_id): """ Single CHW """ chw = CommunityHealthWorker.get(chw_id) return render_to_response(request, "chw/single_chw.html", {"chw": chw })
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})
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 })
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
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"})
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 })
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"))
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"))
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})
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()
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])
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
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")
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})
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)
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
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 })