Пример #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)
Пример #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} )
Пример #3
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)
Пример #4
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