def process_hei_encounter(enc, apr_id, save=False):
    entry = RegistryEntry()
    entry.site = RegistryEntry.SITE_FACES
    entry.child_id = enc.patient_id
    entry.cohort_date = enc.encounter_datetime.date()
    entry.child_initial_enc_id = enc.encounter_id

    duplicate_entries = RegistryEntry.objects.filter(site=RegistryEntry.SITE_FACES, child_id=entry.child_id)
    if duplicate_entries.count() > 0:
        entry.voided = True
        entry.voided_reason = entry.VOIDED_DUPLICATE_CHILD_ENTRY

    # TODO May need to add a check to look at the section titled:
    # FINAL HEI OUTCOMES AT EXIT
    entry.outcome = RegistryEntry.OUTCOME_LIVE
    entry.date_of_outcome = enc.patient.patient.birthdate
    entry.gender = enc.patient.patient.gender

    entry.age_first_seen = (entry.cohort_date - entry.date_of_outcome).days
    # Void entry if they were not seen in the first 3 months
    if entry.age_first_seen > 90:
        entry.voided = True
        entry.voided_reason = RegistryEntry.VOIDED_TOO_OLD_AT_PAEDS_ENC
    if save:
        entry.save(using=APR_DB)
    mom = get_mom(entry.child_id)
    if mom != None:
        entry.mother_id = mom
    else:
        entry.voided = True
        entry.voided_reason = RegistryEntry.VOIDED_MOTHER_NOT_LINKED
        if save:
            entry.save(using=APR_DB)
        return entry
    if save:
        entry.save(using=APR_DB)
    add_mother_values_except_arvs(entry)
    if save:
        entry.save(using=APR_DB)
    add_mother_arvs(entry, save=save)
    add_child_values(entry)
    # If we're not voided assign an APR ID
    if entry.voided == False:
        entry.apr_id = apr_id
    if save:
        entry.save(using=APR_DB)
    return entry
def process_nonlive_encounter(outcome_type, enc, cur_apr_id, save=False):
    """
    Encounter is the blue card from when the mother had a marked
    stillborn/miscarriage etc.
    """

    entry = RegistryEntry()
    entry.site = RegistryEntry.SITE_FACES
    entry.mother_id = enc.patient_id
    entry.cohort_date = enc.encounter_datetime.date()
    entry.outcome = outcome_type
    entry.date_of_outcome = enc.encounter_datetime.date()

    # If an entry with this mother already exists we will consider it a duplicate,
    # considering that our entire timeline is just under 2 years.
    duplicate_entries = RegistryEntry.objects.filter(site=RegistryEntry.SITE_FACES, mother_id=entry.mother_id)
    if duplicate_entries.count() > 0:
        entry.voided = True
        entry.voided_reason = entry.VOIDED_DUPLICATE_CHILD_ENTRY
        if save:
            entry.save(using=APR_DB)
        return entry

    if save:
        entry.save(using=APR_DB)
    try:
        add_mother_values_except_arvs(entry)
        add_mother_arvs(entry, save=save)
    except Patient.DoesNotExist:
        entry.voided = True
        entry.voided_reason = RegistryEntry.VOIDED_STILLBIRTH_MOTHER_MISSING
    # If we're not voided assign an APR ID
    if entry.voided == False:
        entry.apr_id = cur_apr_id
    if save:
        entry.save(using=APR_DB)
    return entry
def build_stage_1():
    """
    In stage 1 of generation we:
    1. Get the initial HEI Encounters
    2. Create a RegistryEntry for each one
    3. Calculate the age of the child at HEI presentation for each one
    4. Check if the mother is linked
    5. Add the obs for the HEI initial encounter

    Essentially, we do anything we can that's on the HEI form (except maybe
    format the actual defects in the event that there are some). Also, we see
    if we can link the mom.
    """
    # 1
    hei_enc = get_hei_encounters()
    # 2
    for enc in hei_enc:
        entry = RegistryEntry()
        entry.site = RegistryEntry.SITE_FACES
        entry.child_id = enc.patient_id
        entry.cohort_date = enc.encounter_datetime.date()
        # TODO May need to add a check to look at the section titled:
        # FINAL HEI OUTCOMES AT EXIT
        entry.outcome = RegistryEntry.OUTCOME_LIVE
        entry.date_of_outcome = enc.patient.patient.birthdate
        entry.gender = enc.patient.patient.gender
        entry.check_initial_paeds_lookup = True
        # 3
        entry.age_first_seen = (entry.cohort_date - entry.date_of_outcome).days
        # 4
        entry.save(using=APR_DB)
        mom = get_mom(entry.child_id)
        if mom != None:
            entry.mother_id = mom
            entry.check_mother_linked = True
            mom_patient = Patient.objects.using(FACES_OPENMRS_DB).get(pk=entry.mother_id)
            for mom_enc in mom_patient.encounter_set.all():
                encounter_to_encobs(entry, mom_enc, link_field='mother_entry')
            entry.check_added_moms_obs = True
        else:
            entry.voided = True
            entry.voided_reason = RegistryEntry.VOIDED_MOTHER_NOT_LINKED
        entry.save(using=APR_DB)
        set_mother_values(entry)
        # 5
        encounter_to_encobs(entry, enc)
        entry.check_added_child_obs = True
        set_child_values(entry)
        entry.save(using=APR_DB)
def set_non_livebirth_entry(outcome_type, enc):
    """
    Encounter is the blue card from when the mother had a marked
    stillborn/miscarriage etc.
    """
    entry = RegistryEntry()
    entry.site = RegistryEntry.SITE_FACES
    entry.cohort_date = enc.encounter_datetime.date()
    entry.outcome = outcome_type
    entry.date_of_outcome = enc.encounter_datetime.date()
    entry.save(using=APR_DB)
    for mom_enc in enc.patient.encounter_set.all():
        encounter_to_encobs(entry, mom_enc, link_field='mother_entry')
    entry.check_added_moms_obs = True
    try:
        set_mother_values(entry)
    except Patient.DoesNotExist:
        entry.voided = True
        entry.voided_reason = RegistryEntry.VOIDED_STILLBIRTH_MOTHER_MISSING
    entry.save(using=APR_DB)
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