def set_mother_arvs(entry, save_entries=False):
    """
    Look up and set ARV's for mom. Returns a list of new ARV's.
    """
    schemafile = './apr/registry-schema.json'
    with open(schemafile) as f:
        schema = json.loads(f.read())
    arvs = schema['ampath-mapping']['arvs']
    arvset = []
    begin_date = entry.date_of_outcome - datetime.timedelta(360*2)
    log_data(entry, "Beginning date for searching ARVs %s" % (begin_date,), 'arvs', 1088)
    encobs = Obs.objects.using(AMRS_DB).filter(voided=0,
        obs_datetime__gte=begin_date,
        obs_datetime__lte=entry.date_of_outcome,
        person_id=entry.mother_id).order_by('obs_datetime')
    course = 1
    cur_arv = None
    for encob in encobs:
        if encob.concept_id == 1088:
            if encob.value_coded_id != cur_arv:
                cur_arv = encob.value_coded_id
                arvt = ArvTherapy()
                arvt.registry_entry = entry
                arvt.course = course
                arvt.medcode = arvs[str(cur_arv)]['medcode']
                arvt.date_began = encob.obs_datetime.date()
                log_data(entry, "Using ARV %s %s" % (encob.concept_id, encob.obs_datetime,), 'arv', 1088)
                if save_entries:
                    arvt.save(using=APR_DB)
                arvset.append(arvt)
                course += 1
            else:
                log_data(entry, "Skipping cur ARV %s %s" % (encob.concept_id, encob.obs_datetime,), 'arv', 1088)
                pass
    # Go through and adjust the end dates as well as the ongoing flag 
    for idx, arvt in enumerate(arvset):
        if len(arvset) == 1:
            arvt.ongoing = 1
        elif idx == 0:
            arvt.ongoing = 0
            arvt.date_ended = arvset[idx+1].date_began
        elif idx == (len(arvset)-1):
            arvt.ongoing = 1
        else:
            arvt.ongoing = 0
            arvt.date_ended = arvset[idx+1].date_began
        print("Saving the updated status...")
        arvt.save(using=APR_DB)
    return arvset
def run378form(f378, cur_apr_id, save_entries=False):
    logger.info("Starting 378 encounter: %s" % (f378.encounter_id,))
    # If we've already done this specific encounter we should skip it and 
    # move on.
    entry = RegistryEntry()
    if RegistryEntry.objects.filter(child_initial_enc_id=f378.encounter_id).count() > 0:
        logger.info("This encounter id was already processed, skipping and moving on.")
        return entry
    #  1. Encounter ID
    entry.child_initial_enc_id = f378.encounter_id
    #  2. Age in days since encounter
    entry.age_first_seen = age_in_days_at_encounter(f378)
    #  3. Child Patient ID
    entry.child_id = f378.patient_id

    # Has this child been used previously, if so void the encounter.
    duplicate_entries = RegistryEntry.objects.filter(
        site=RegistryEntry.SITE_AMPATH, child_id=entry.child_id)
    if duplicate_entries.count() > 0:
        entry.voided = True
        entry.voided_reason = entry.VOIDED_DUPLICATE_CHILD_ENTRY
        entry.voided_duplicate = True

    child_patient = f378.patient
    #  4. Mom Patient ID
    entry.mother_id = get_linked_mother(f378)
    #  5. Length of Mom's ARV History
    entry.length_of_moms_arv_history = previous_encounters_in_days(
        entry.mother_id, f378.encounter_datetime.date())

    entry.site = RegistryEntry.SITE_AMPATH
    entry.cohort_date = f378.encounter_datetime.date()
    entry.outcome = entry.OUTCOME_LIVE
    entry.date_of_outcome = child_patient.patient.birthdate
    entry.age_first_seen = (entry.cohort_date - entry.date_of_outcome).days
    entry.gender = child_patient.patient.gender

    init_obs = f378.obs_set
    # Birth Defect Noted
    """
    Field: Birth Defect 
    If concept 6246 or 6245 is used, we use that checkbox value.
    If the birth defect checkbox is left blank, then we look to see if any
    of the following concepts are recorded, and if they are we record those
    birth defects:
        8320, 8321, 8322, 8323, 8324, 8325, 8326, 8327, 8328
    aprfield"""
    if init_obs.filter(concept_id=6246, value_coded=6242).count() > 0:
        entry.birth_defect = RegistryEntry.DEFECT_NO
    elif init_obs.filter(concept_id=6245, value_coded=6242).count() > 0:
        entry.birth_defect = RegistryEntry.DEFECT_YES
    else:
        congab_concepts = [8320, 8321, 8322, 8323, 8324, 8325, 8326, 8327, 8328]
        congab_obs = init_obs.filter(concept_id__in = congab_concepts, voided=0)
        if congab_obs.count() > 0:
            entry.birth_defect = RegistryEntry.DEFECT_YES
        else:
            entry.birth_defect = RegistryEntry.DEFECT_UNKNOWN
    # Birth Weight
    weight_obs = init_obs.filter(concept_id=5916)
    if weight_obs.count() > 0:
        entry.birth_weight = weight_obs[0].value_numeric * 1000

    if save_entries:
        entry.save(using=APR_DB)

    if entry.mother_id:
        entry.check_mother_linked = True
        mother = Patient.objects.using(AMRS_DB).get(
                                    patient_id=entry.mother_id)
        # Date First Seen...
        # LMP and/or EDD
        begin_date = entry.date_of_outcome - datetime.timedelta(360)
        log_data(entry, "Beginning date of LMP Search: %s" % (begin_date,), 'lmp')
        lmp_obs = Obs.objects.using(AMRS_DB).filter(
                            concept_id=1836,
                            obs_datetime__gte=begin_date,
                            obs_datetime__lte=entry.date_of_outcome,
                            person_id=entry.mother_id,
                            voided=0,
                         ).order_by('-obs_datetime')
        if lmp_obs.count() > 0:
            entry.lmp = lmp_obs[0].value_datetime
        for lmp in lmp_obs:
            log_data(entry, "Potential LMP Obs/Date: %s , %s" % (lmp.obs_id, lmp.value_datetime), 'lmp', 1836)
        # Age at Conception
        entry.age_at_conception = calculate_age(mother.patient.birthdate,
                            entry.date_of_outcome - datetime.timedelta(days=270))
        # Mother ARVS
        arvset = set_mother_arvs(entry)
        if len(arvset) == 0:
            entry.voided = True
            entry.voided_reason = entry.VOIDED_NO_ARV_HISTORY
            entry.voided_no_arv_history = True
    else:
        entry.check_mother_linked = False
        entry.voided = True
        entry.voided_reason = RegistryEntry.VOIDED_MOTHER_NOT_LINKED
        entry.voided_mother_not_linked = True

    # If we're not voided assign an APR ID
    if entry.voided == False:
        entry.apr_id = cur_apr_id

    if save_entries:
        entry.save(using=APR_DB)

    return entry