Example #1
0
def process_dots_json(doc, dots_json):
    username = doc['form']['Meta']['username']
    user = User.objects.get(username=username)
    #kinda nasty but get the pact_id for patient lookup
    patient_doc = PactPatient.view('pactcarehq/patient_pact_ids', key=doc['form']['pact_id']).first()
    pt = Patient.objects.get(doc_id=patient_doc._id)
    return Observation.from_json(dots_json, pt, user, doc) #provider=provider_actor, patient=pt, json=dots_json)
Example #2
0
def patient_url_from_form(xforminstance):
    pt = PactPatient.view('pactcarehq/patient_pact_ids', key=xforminstance.form['pact_id'], include_docs=True).all()
    if len(pt) == 0:
        return "#"

    djpatient = Patient.objects.filter(doc_id=pt[0]._id)
    if djpatient.count() == 0:
        return "#"
    else:
        return reverse('view_patient', kwargs={'patient_id':djpatient[0].id} )
Example #3
0
def run():
    #really hacky script to address null issues in couch for patient data.  a weird issue not able to pinpoint.
    #patients = PactPatient.view('patient/all').all()
    db = PactPatient.get_db()
    rawdocs = db.view('patient/all' ).all()
    for doc in rawdocs:
        #print doc
        try:
            ptdoc = doc['value']
            phone_hash = ptdoc['phones']
            for ph in phone_hash:
                print ph
                print ph.keys()
                ph['is_default'] = False
            pt = PactPatient.wrap(ptdoc)
            for phone in pt.phones:
                #print phone.is_default
                phone.save()
            pt.save()
        except Exception, e:

            print ptdoc
            print e
            print "fail!"
Example #4
0
def run():
    """Script to flip CPatient to PactPatient (subclass of BasePatient), then switch doc_id to a new id, and assign a case_id fromt he original doc_id
    """

    #django patient -> django_uuid = new
    #cpatient-> doc_id = case_id, doc_id = new, == to djpatient.django_uuid

    #this needs to be coupled with fixing up the patient/all querying
    #patient/all needs to emit the case_id
    patients = Patient.objects.all()
    db = get_db()
    for p in patients:
        print "Flipping ID Patient ID: %s: Couchdoc: %s" % (p.id, p.doc_id)
        #so the p.couchdoc is useless here because if the model code is changed we need to do it manually.

        #establish the updated ids and get them separated out
        real_case_id = p.doc_id + "" #the doc_id had been used as the case_id which in real casexml, that's bad.
        new_doc_id = uuid.uuid1().hex #now make a new doc_id for the patient document.

        couchdoc = db.open_doc(p.doc_id)

        #flip the document ids.
        copy_doc = PactPatient.wrap(couchdoc)
        copy_doc.case_id = real_case_id
        copy_doc._id = new_doc_id
        copy_doc.doc_type = PactPatient.__name__
        copy_doc.save()
        p.doc_id = new_doc_id
        p._couchdoc = copy_doc
        p.save()
        print "\tSwapping case id %s -> %s" % (real_case_id, new_doc_id)

        #having just saved it, we need to now remove the original id
        dupe_doc = db.open_doc(real_case_id) #the old doc_id
        delresult = db.delete_doc(dupe_doc)
        print "\tDeleting doc %s" % (real_case_id)
        print "\t%s" % (delresult)

        i = 0
        while db.doc_exist(real_case_id):
            i+= 1
            print "\tTrying to freaking delete!!!"
            print "\tReally deleting doc %s" % (real_case_id)
            delresult = db.delete_doc(dupe_doc)
            print "\t%s" % (delresult)
            if i == 10:
                break
Example #5
0
def get_schedule(chw_username, override_date = None):
    #print "doing schedule lookup for %s" % (chw_username)
    #if cached_schedules.has_key(chw_username):
        #return cached_schedules[chw_username]
    if override_date == None:
        nowdate = datetime.now()
    else:
        nowdate = override_date
    db = PactPatient.get_db()
    chw_schedules = db.view('pactcarehq/chw_dot_schedule_condensed', key=chw_username).all()
    day_intervaltree = {}

    for item in chw_schedules:
        single_sched = item['value']
        day_of_week = int(single_sched['day_of_week'])
        if day_intervaltree.has_key(day_of_week):
            daytree = day_intervaltree[day_of_week]
        else:
            #if there's no day of week indication for this, then it's just a null interval node.  to ensure that it's not checked, we make it REALLY old.
            daytree = IntervalNode(get_seconds(datetime.min), get_seconds(nowdate + timedelta(days=10)))

        if single_sched['ended_date'] == None:
            enddate = nowdate+timedelta(days=9)
        else:
            enddate = datetime.strptime(single_sched['ended_date'], "%Y-%m-%dT%H:%M:%SZ")
            #enddate = single_sched['ended_date']

        startdate = datetime.strptime(single_sched['active_date'], "%Y-%m-%dT%H:%M:%SZ")
        #startdate = single_sched['active_date']
        pact_id = single_sched['pact_id']
        
        daytree.insert(get_seconds(startdate), get_seconds(enddate), other=pact_id)
        day_intervaltree[day_of_week] = daytree

    #cached_schedules[chw_username] = CHWPatientSchedule(chw_username, day_intervaltree, chw_schedules)
    #return cached_schedules[chw_username]
    return CHWPatientSchedule(chw_username, day_intervaltree, chw_schedules)
Example #6
0
def name_from_pactid(xforminstance):
    pt = PactPatient.view('pactcarehq/patient_pact_ids', key=xforminstance.form['pact_id'], include_docs=True).all()
    if len(pt) == 0:
        return "[Unknown Patient]"
    else:
        return "%s %s" % (pt[0].first_name, pt[0].last_name)
Example #7
0
 def clean_pact_id(self):
     if PactPatient.check_pact_id(self.cleaned_data['pact_id']) == False:
         raise ValidationError("Error, pact id must be unique")
     else:
         return self.cleaned_data['pact_id']
Example #8
0
def new_patient(request, template_name="patient/new_patient.html"):
    context = RequestContext(request)
    if request.method == 'POST':
        form = PactPatientForm(data=request.POST)
        #make patient
        if form.is_valid():
            newptdoc = PactPatient()
            newptdoc.pact_id = form.cleaned_data['pact_id']
            newptdoc.arm = form.cleaned_data['arm']
            newptdoc.gender = form.cleaned_data['gender']
            newptdoc.birthdate = form.cleaned_data['birthdate']
            newptdoc.art_regimen = form.cleaned_data['art_regimen']
            newptdoc.non_art_regimen = form.cleaned_data['non_art_regimen']
            newptdoc.primary_hp = form.cleaned_data['primary_hp']
            newptdoc.first_name = form.cleaned_data['first_name']
            newptdoc.last_name = form.cleaned_data['last_name']
            newptdoc.case_id = uuid.uuid1().hex
            newptdoc.save()
            messages.add_message(request, messages.SUCCESS, "Added patient " + form.cleaned_data['first_name'] + " " + form.cleaned_data['last_name'])
            return HttpResponseRedirect(reverse('pactcarehq.views.patient_view', kwargs={'patient_id':newptdoc.django_uuid}))
        else:
            messages.add_message(request, messages.ERROR, "Failed to add patient!")
            context['patient_form'] = form
    else:
        context['patient_form'] = PactPatientForm()
    return render_to_response(template_name, context_instance=context)
Example #9
0
def get_couchdata(request):
    end_date = _parse_date(request.GET.get('end', datetime.utcnow()))
    start_date = _parse_date(request.GET.get('start', end_date - timedelta(14)))
    patient_id = request.GET.get('patient', None)

    do_pdf = request.GET.get('pdf', False)

    if start_date > end_date:
        end_date = start_date
    elif end_date - start_date > timedelta(365):
        end_date = start_date + timedelta(365)

    try:
        patient = Patient.objects.get(id=patient_id)
        pact_id = patient.couchdoc.pact_id


    except:
        patient = None
        pact_id = None

    view_doc_id = request.GET.get('submit_id', None)

    if view_doc_id != None:
        #we want to see a direct single instance display. override the display times
        observations = CObservation.view('dotsview/dots_observations', key=['doc_id', view_doc_id]).all()
    else:
        startkey = [pact_id, 'anchor_date', start_date.year, start_date.month, start_date.day]
        endkey = [pact_id, 'anchor_date', end_date.year, end_date.month, end_date.day]
        observations = CObservation.view('dotsview/dots_observations', startkey=startkey, endkey=endkey).all()

    total_doses_set = set([obs.total_doses for obs in observations])
    observed_dates = list(set([s.observed_date for s in observations]))
    sorted_obs = sorted(observations, key=lambda k:k['observed_date'])

    if len(observed_dates) > 0:
        min_date = min(observed_dates)
        max_date = max(observed_dates)
    else:
        min_date = datetime.utcnow()
        max_date = datetime.utcnow()

    full_dates = []
    days_delta = (max_date - min_date).days
    full_dates = [min_date + timedelta(days=x) for x in range(0,days_delta+2)]
    #while date <= max_date:
        #full_dates.append(date)
        #date += timedelta(1)

    if view_doc_id != None:
        visits_set = set([view_doc_id])
    else:
        visits_set = set([obs.doc_id for obs in observations])


    timekeys = set()
    for d in total_doses_set:
        try:
            timekeys = set.union(timekeys, set(CObservation.get_time_labels(d)))
        except:
            pass

#        timekeys = set.union(*map(set, map(CObservation.get_time_labels, total_doses_set)))
#        timekeys = sorted(timekeys, key=TIME_LABELS.index)

    artkeys = ('ART', 'Non ART')
    def group_by_is_art_and_time(date):
        grouping = {}
        conflict_dict = {}
        day_notes = []
        conflict_check = {}
        found_reconcile = False
        for artkey in artkeys:
            by_time = {}
            for timekey in timekeys:
                by_time[timekey] = []
            grouping[artkey] = by_time

        if date:
            datekey = [pact_id, 'observe_date', date.year, date.month, date.day]
            obs = CObservation.view('dotsview/dots_observations', key=datekey).all()
            for ob in obs:
                if view_doc_id != None and ob.doc_id != view_doc_id:
                    #print "\tSkip:Is ART: %s: %d/%d %s:%s" % (ob.is_art, ob.dose_number, ob.total_doses, ob.adherence, ob.method)
                    #skip if we're only looking at one doc
                    continue
                else:
                    #show it because we're looking at all observations
                    #print "\tShow:Is ART: %s: %d/%d %s:%s" % (str(ob.is_art)[0], ob.dose_number, ob.total_doses, ob.adherence, ob.method)
                    pass

                try:
                    time_label = ob.get_time_label()
                except IndexError:
                    logging.error("Error, observation time label index not found, DOT data generation error")
                    time_label = TIME_LABELS[ob.dose_number]

                #if any observation on this date has a notes for that particular check, record it.
                if ob.day_note != None and ob.day_note != '' and day_notes.count(ob.day_note) == 0:
                    day_notes.append(ob.day_note)
                    #pre-check
                if ob.is_reconciliation == True:
                    #it's a reconciled entry.  Trump all
                    grouping['ART' if ob.is_art else 'Non ART'][time_label] = [ob]
                    found_reconcile = True
                    continue
                else:
                    #base case if it's never been seen before, add it as the key
                    if not conflict_check.has_key(ob.adinfo[0]):
                        conflict_check[ob.adinfo[0]] = ob

                    #main check.  for the given key adinfo[0], check to see if the value is identical
                    prior_ob = conflict_check[ob.adinfo[0]]
                    if prior_ob.adinfo[1] != ob.adinfo[1]:
                        #they don't match, add the current ob to the conflict dictionary
                        if not conflict_dict.has_key(ob.doc_id):
                            conflict_dict[ob.doc_id] = ob
                            #next, add the one existing in the lookup checker as well because they differed.
                        if not conflict_dict.has_key(prior_ob.doc_id):
                            conflict_dict[prior_ob.doc_id] = prior_ob
                    conflict_check[ob.adinfo[0]] = ob




                    if not found_reconcile and time_label != '':
                        if grouping['ART' if ob.is_art else 'Non ART'].has_key(time_label) == False:
                            grouping['ART' if ob.is_art else 'Non ART'][time_label] = []
                            logging.error("Error, a key not expected was found in this entry: ob doc: %s, day index: %d, art status: %s, dose: %d/%d, is reconciled: %s" % (ob.doc_id, ob.day_index, ob.is_art, ob.dose_number, ob.total_doses, ob.is_reconciliation))

                        grouping['ART' if ob.is_art else 'Non ART'][time_label].append(ob)

        #for each class of drug (art, non art) in artkeys
        #for each time in the timeslots (morning, afternoon, etc)
        #get the most recent observation for that time slot observed_date[-1:] - make it a list because we iterate through them
        if found_reconcile == False:
            #little hacky here, but if we've found reconciliation items, then we can skip showing the conflict list
            conflict_list = sorted(conflict_dict.values(), key=lambda x: x.anchor_date, reverse=True)
        else:
            conflict_list = []

        return (
        [(ak, [(tk, sorted(grouping[ak][tk], key=lambda x: x.anchor_date)[-1:]) for tk in timekeys]) for ak in artkeys],
        conflict_list, day_notes, found_reconcile)

    start_padding = full_dates[0].weekday()
    end_padding = 7 - full_dates[-1].weekday() + 1
    full_dates = [None] * start_padding + full_dates + [None] * end_padding
    #week = [[date, entry]...]
    #entry = [('non_art', [(time1: [obs1, obs2, obs3]), (time2,[obs4, obs5]), (time3,[obs7]),...]), ('art', [(time1:[obs1,obs2...]), (time2, [obs3]), ...])... '
    #time = [ 

    #observed_dates = [(date, group_by_is_art_and_time(date)) for date in observed_dates] #week = [[date, entries],...], where entry = [{art:
    #weeks = [observed_dates[7*n:7*(n+1)] for n in range(len(observed_dates)/7)]
    new_dates = []
    for date in full_dates:
        observation_tuple = group_by_is_art_and_time(date)#entries = 0, conflicts = 1, notes=2, reconcile=3
        new_dates.append((date, observation_tuple[0], observation_tuple[1], observation_tuple[2], observation_tuple[3]))
    weeks = [new_dates[7 * n:7 * (n + 1)] for n in range(len(new_dates) / 7)]

    dots_pts = PactPatient.view('pactcarehq/all_dots', include_docs=True).all()
    dots_ids = [pt._id for pt in dots_pts]
    patients = Patient.objects.filter(doc_id__in=dots_ids)

    visit_docs = [XFormInstance.view('pactcarehq/all_submits_raw', key=visit_id, include_docs=True).first() for visit_id in visits_set]
    while visit_docs.count(None) > 0:
        visit_docs.remove(None) #this is a bit hacky, some of the visit_ids are actually reconcile doc_ids, so we need to remove the ones that return None from the view

    sorted_visits = sorted(visit_docs, key=lambda d: d.received_on)

    #sanity check if we're running with old data:
    if patients.count() == 0:
        patients = Patient.objects.all()

    patients = sorted(patients, key=lambda p: p.couchdoc.last_name + p.couchdoc.first_name)
    if patient:
        art_regimen = patient.couchdoc.art_regimen
        try:
            art_num = int(ghetto_regimen_map[art_regimen.lower()])
        except:
            art_num = 0

        nonart_regimen = patient.couchdoc.non_art_regimen
        try:
            nonart_num = int(ghetto_regimen_map[nonart_regimen.lower()])
        except:
            nonart_num = 0
    else:
        art_num = 0
        nonart_num = 0

    context = RequestContext(request, locals())
    {
        'weeks': weeks,
        'patients': patients,
        'patient': patient,
        'start_date': start_date,
        'end_date': end_date,
        'min_date': min_date,
        'max_date': max_date,
        'art_num': art_num,
        'nonart_num': nonart_num,
    }

    return context