Example #1
0
def create_patient(request, bb_dict):
    """
    Create a Patient Profile using the contents of bb_dict
    (Medicare BlueButton 2.0 Text converted to json)

    :param request:
    :param bb_dict:
    :return:
    """

    # Get a Crosswalk entry for the user and use the Guid as
    # the identifier

    try:
        x_walk = Crosswalk.objects.get(user=request.user)
    except Crosswalk.DoesNotExist:
        x_walk = Crosswalk()
        x_walk.user = request.user
        x_walk.save()

    x_walk = Crosswalk.objects.get(user=request.user)
    guid = x_walk.guid

    if settings.DEBUG:
        print("CrossWalk Match:", x_walk,
              "\nGUID:", guid,
              "\nFHIR Id:",x_walk.fhir, "|", x_walk.fhir_url_id )


    # Compile Profile content

    profile = {}
    profile['resourceType'] = "Patient"
    profile['mode'] = "create"
    profile['versionId'] = "1"
    profile['updated'] = date_to_iso(datetime.datetime.now())
    profile['active'] = "True"

    id_list = []
    id_source = {}
    id_source['system'] = "https://mymedicare.gov"
    id_source['use'] = "official"
    id_source['value'] = guid

    id_list.append(unique_id(id_source))

    profile['fhir_identifier'] = id_list

    person = bb_dict['patient']['name']

    names = person.split(" ")
    # We will take the last entry in names and assign as family name
    # We will take first entry and assign as given name

    given = ""
    family = ""
    if len(names) > 0:
        profile['given'] = [names[0]]
        profile['family'] = [names[len(names)-1]]

    # Done: Fix call to human_name - breaking out to chars
    profile['fhir_human_name'] = human_name(profile)

    telecom_source = {}
    tel_list = []
    rank = 1
    telecom_source['system'] = "phone"
    telecom_source['value']  = bb_dict['patient']['phoneNumber'][0]
    telecom_source['rank']   = str(rank)

    tel_list.append(contact_point(telecom_source))
    rank += 1
    telecom_source['system'] = "email"
    telecom_source['value']  = bb_dict['patient']['email']
    telecom_source['rank']   = str(rank)

    tel_list.append(contact_point(telecom_source))

    profile['fhir_contact_point'] = tel_list

    addr_source = {}
    addr_list = []

    addr_source['use']   = "primary"
    addr_source['type']  = "physical"
    addr_source['line']  = [bb_dict['patient']['address']['addressLine1'],
                            bb_dict['patient']['address']['addressLine2']]
    addr_source['city']  = bb_dict['patient']['address']['city']
    addr_source['state'] = bb_dict['patient']['address']['state']
    addr_source['postalCode'] = bb_dict['patient']['address']['zip']

    addr_list.append(address(addr_source))

    profile['fhir_address'] = addr_list

    narrative = concat_string("", profile['given'],
                              delimiter=" ",
                              last=" ")
    narrative = concat_string(narrative, profile['family'],
                              delimiter=" ",
                              last = " ")
    narrative = concat_string(narrative, [" (id:",
                                          guid, ")"])

    narrative = concat_string(narrative, addr_source['line'],
                              delimiter=",",
                              last=",")
    narrative = concat_string(narrative, addr_source['city'],
                              last=" ")
    narrative = concat_string(narrative, addr_source['state'],
                              last=" ")
    narrative = concat_string(narrative, addr_source['postalCode']
                              )

    profile['narrative'] = narrative

    if settings.DEBUG:
        print("Profile:", profile, "\n====================")

    # Write Profile

    txn = {'resourceType' :"Patient",
           'display' :'Patient',
           'mask'  : True,
           'server': settings.FHIR_SERVER,
           'locn'  : "/baseDstu2/Patient",
           'template' : 'v1api/fhir_profile/patient',
           'extn'  : 'json.html',}

    context = {'txn': txn,
               'profile': profile,}
    fhir_profile = build_fhir_profile(request,
                                      context,
                                      context['txn']['template'],
                                      context['txn']['extn'],
                                     )

    if settings.DEBUG:
        print("===============================",
              "FHIR Profile:\n",
              fhir_profile,
              "===============================")
    # Submit to server
    target_url = context['txn']['server'] + context['txn']['locn']
    headers = {'Content-Type': 'application/json+fhir; charset=UTF-8',
               'Accept'      : 'text/plain'}

    try:
        if profile['mode'] == 'create':
            r = requests.post(target_url + "?_format=json",
                              data=fhir_profile,
                              headers=headers )
        else:
            r = requests.put(target_url + "/" + x_walk.fhir_url_id + "?_format=json",
                             data=fhir_profile,
                             headers=headers )
        r_returned = r.text

        print("Result from post", r.status_code, "|",
              r_returned, "|",
              r.content, "|",
              r.text, "|",
              "Headers", r.headers)

        if r.status_code == 201:
            url_result = r.headers['content-location']
            if settings.DEBUG:
                print("url_content_location", url_result)
            result = get_fhir_url(url_result, "Patient")

            if settings.DEBUG:
                print("result:", result, "|", result[1], "|")

            x_walk.fhir_url_id = result[1]
            x_walk.save()
        # Get Id from successful write
        # Update Patient Crosswalk

    except requests.ConnectionError:
        messages.error(request,"Problem posting:" + guid)

    return
def generate_fhir_profile(request, resourceType, src_dict ):
    """
    Receive a dictionary and convert to a profile. This will convert from
    input dictionary specific field names to the generic profile
    We can also build in some resourceType and input file specific logic
    :param request:
    :param resourceType: (We can use this as basis to pull a resource
            mapping if we make
    :param src_dict:
    :return: profile_dict

Profile elements:
    # Map values across to new dictionary
    npi['use']        = assign_str(source, 'use', "official")
    npi['type']       = assign_str(source, 'type',)
    npi['system']     = assign_str(source, 'system', sys_uri)
    *npi['value']      = assign_str(source, 'value',)
    npi['period']     = assign_str(source, 'period',)
    npi['assigner']   = assign_str(source, 'assigner', assigner_ref)

 * = Required

    """

    resource_map = {}

    fp = {}

    # if settings.DEBUG:
    #     print("Source:", src_dict)

    # fp.update(src_dict)
    if not 'resourceType' in fp:
        if resourceType:
            fp['resourceType'] = resourceType

    if resourceType == "Practitioner":
        # Do Practitioner Specific mapping

        id_source = {}
        # Now we need to map NPI data in to the identifier segment
        id_source['value']= src_dict['NPI']
        if 'Replacement_NPI' in src_dict:
            # If a replacement NPI we need to use it
            if not src_dict['Replacement_NPI'] == "":
                id_source['value'] = src_dict['Replacement_NPI']
        #id_source['system'] = "https://nppes.cms.hhs.gov/NPPES/"
        #id_source['use'] = "official"
        #id_source['type'] = "PRN"
        #id_source['assigner'] = "CMS National Plan and Provider Enumeration System"

        # Let's set some dates:
        # Provider_Enumeration_Date = Date created. ie Period Start
        # NPI_Deactivation_Date = Period end date
        # If NPI_Reactivation_Date

        id_list = []
        id_source['period'] = {'start': date_to_iso(datetime.strptime(src_dict['Provider_Enumeration_Date'],"%m/%d/%Y"),decimals=False)}
        if 'NPI_Reactivation_Date' in src_dict:
            if 'NPI_Deactivation_Date' in src_dict:
                if not src_dict['NPI_Deactivation_Date'] =="":
                    date_start = datetime.strptime(src_dict['Provider_Enumeration_Date'],"%m/%d/%Y")
                    date_end   = datetime.strptime(src_dict['NPI_Deactivation_Date'], "%m/%d/%Y")
                    id_source['period'] = {'start' : date_to_iso(date_start),
                                        'end' : date_to_iso(date_end)}

            id_list.append(npid(id_source))
            if src_dict['NPI_Reactivation_Date'] > src_dict['NPI_Deactivation_Date']:
                date_start = datetime.strptime(src_dict['NPI_Reactivation_Date'],"%m/%d/%Y")

                id_source['period'] = {'start' : date_to_iso(date_start)}

                id_list.append(npid(id_source))

        else:
            date_start = datetime.strptime(src_dict['Provider_Enumeration_Date'],"%m/%d/%Y")
            date_end   = datetime.strptime(src_dict['NPI_Deactivation_Date'], "%m/%d/%Y")

            id_source['period']['start'] = date_to_iso(date_start)
            if 'NPI_Deactivation_Date' in src_dict:
                if not src_dict['NPI_Deactivation_Date'] =="":
                    id_source['period']['end'] = date_to_iso(date_end)
            id_list.append(npid(id_source))

        fp['fhir_identifier'] = id_list
        if settings.DEBUG:
            # print("ID_Section:", fp['fhir_identifier'][0]['type'],":",fp['fhir_identifier'][0]['value'])
            pass
        # Now we need to map the name information to name

        #
        # hn['resourceType'] = "HumanName"
        # hn['use'] = assign_str(source, 'use', "usual")
        # hn['suffix'] = assign_str(source, 'suffix',)
        # hn['prefix'] = assign_str(source, 'prefix',)
        # hn['family'] = assign_str(source, 'family')
        # hn['given']  = assign_str(source, 'given')
        # hn['period'] = assign_str(source, 'period')

        suffix = remove_empty_string([src_dict['Provider_Name_Suffix_Text'],
                                     src_dict['Provider_Credential_Text']])
        prefix = remove_empty_string([src_dict['Provider_Name_Prefix_Text']])

        given = remove_empty_string([src_dict['Provider_First_Name'],
                                    src_dict['Provider_Middle_Name']])

        name_source = {
                       'suffix' : suffix,
                       'prefix' : prefix,
                       'family' : [src_dict['Provider_Last_Name_Legal_Name']],
                       'given'  : given
                      }

        fp['fhir_human_name'] = human_name(name_source)

        # Now we need to map the contact information

        telecom_source =  {}
        tel_list = []
        # Map values across to new dictionary
        # cp['resourceType'] = "ContactPoint"
        # cp['system'] = assign_str(source, 'system', "usual")
        # cp['value']  = assign_str(source, 'value',)
        # cp['use']    = assign_str(source, 'use')
        # cp['rank']   = int(assign_str(source, 'rank'))
        # cp['period'] = assign_str(source, 'period')

        rank = 1
        if not src_dict['Provider_Business_Practice_Location_Address_Telephone_Number'] == "":
            telecom_source['system'] = "phone"
            telecom_source['value']  = src_dict['Provider_Business_Practice_Location_Address_Telephone_Number']
            telecom_source['use']    = "practice"
            telecom_source['rank']   = str(rank)

            tel_list.append(contact_point(telecom_source))
            rank += 1


        if not src_dict['Provider_Business_Practice_Location_Address_Fax_Number'] == "":
            telecom_source['system'] = "fax"
            telecom_source['value']  = src_dict['Provider_Business_Practice_Location_Address_Fax_Number']
            telecom_source['rank']   = str(rank)

            tel_list.append(contact_point(telecom_source))
            rank += 1

        if not src_dict['Provider_Business_Mailing_Address_Telephone_Number'] == "":
            telecom_source['system'] = "phone"
            telecom_source['value']  = src_dict['Provider_Business_Mailing_Address_Telephone_Number']
            telecom_source['use']    = "business"
            telecom_source['rank']   = str(rank)

            tel_list.append(contact_point(telecom_source))
            rank += 1

        if not src_dict['Provider_Business_Mailing_Address_Fax_Number'] == "":
            telecom_source['system'] = "fax"
            telecom_source['value']  = src_dict['Provider_Business_Mailing_Address_Fax_Number']
            telecom_source['rank']   = str(rank)

            tel_list.append(contact_point(telecom_source))

        fp['fhir_contact_point'] = tel_list

        # Now we need to map the address information

        addr_source = {}

        addr_list = []

        # ad['resourceType'] = "Address"
        # ad['use']        = assign_str(source, 'use',)
        # ad['type']       = assign_str(source, 'type',)
        # ad['line']       = assign_str(source, 'line',)
        # ad['city']       = assign_str(source, 'city',)
        # ad['district']   = assign_str(source, 'district',)
        # ad['state']      = assign_str(source, 'state',)
        # ad['postalCode'] = assign_str(source, 'postalCode',)
        # ad['country']    = assign_str(source, 'country',)
        # ad['period']     = assign_str(source, 'period',)

        addr_source['use']   = "practice"
        addr_source['type']  = "physical"
        addr_source['line']  = [src_dict['Provider_First_Line_Business_Practice_Location_Address'],
                                src_dict['Provider_Second_Line_Business_Practice_Location_Address']]
        addr_source['city']  = src_dict['Provider_Business_Practice_Location_Address_City_Name']
        addr_source['state'] = src_dict['Provider_Business_Practice_Location_Address_State_Name']
        addr_source['postalCode'] = src_dict['Provider_Business_Practice_Location_Address_Postal_Code']
        addr_source['country'] = src_dict['Provider_Business_Practice_Location_Address_Country_Code_If_outside_US']

        addr_list.append(address(addr_source))

        addr_source['use']   = "business"
        addr_source['type']  = "postal"
        addr_source['line']  = [src_dict['Provider_First_Line_Business_Mailing_Address'],
                                src_dict['Provider_Second_Line_Business_Mailing_Address']]
        addr_source['city']  = src_dict['Provider_Business_Mailing_Address_City_Name']
        addr_source['state'] = src_dict['Provider_Business_Mailing_Address_State_Name']
        addr_source['postalCode'] = src_dict['Provider_Business_Mailing_Address_Postal_Code']
        addr_source['country'] = src_dict['Provider_Business_Mailing_Address_Country_Code_If_outside_US']

        addr_list.append(address(addr_source))

        fp['fhir_address'] = addr_list

        # Get Gender

        fp['gender'] = src_dict['Provider_Gender_Code']

        # Get User readable text
        fp['narrative'] = write_practitioner_narrative(src_dict)

        #fp['fhir_extension'] = npi_provider_extension(src_dict)

    return fp
Example #3
0
def generate_fhir_profile(request, resourceType, src_dict):
    """
    Receive a dictionary and convert to a profile. This will convert from
    input dictionary specific field names to the generic profile
    We can also build in some resourceType and input file specific logic
    :param request:
    :param resourceType: (We can use this as basis to pull a resource
            mapping if we make
    :param src_dict:
    :return: profile_dict

Profile elements:
    # Map values across to new dictionary
    npi['use']        = assign_str(source, 'use', "official")
    npi['type']       = assign_str(source, 'type',)
    npi['system']     = assign_str(source, 'system', sys_uri)
    *npi['value']      = assign_str(source, 'value',)
    npi['period']     = assign_str(source, 'period',)
    npi['assigner']   = assign_str(source, 'assigner', assigner_ref)

 * = Required

    """

    resource_map = {}

    fp = {}

    # if settings.DEBUG:
    #     print("Source:", src_dict)

    # fp.update(src_dict)
    if not 'resourceType' in fp:
        if resourceType:
            fp['resourceType'] = resourceType

    if resourceType == "Practitioner":
        # Do Practitioner Specific mapping

        id_source = {}
        # Now we need to map NPI data in to the identifier segment
        id_source['value'] = src_dict['NPI']
        if 'Replacement_NPI' in src_dict:
            # If a replacement NPI we need to use it
            if not src_dict['Replacement_NPI'] == "":
                id_source['value'] = src_dict['Replacement_NPI']
        #id_source['system'] = "https://nppes.cms.hhs.gov/NPPES/"
        #id_source['use'] = "official"
        #id_source['type'] = "PRN"
        #id_source['assigner'] = "CMS National Plan and Provider Enumeration System"

        # Let's set some dates:
        # Provider_Enumeration_Date = Date created. ie Period Start
        # NPI_Deactivation_Date = Period end date
        # If NPI_Reactivation_Date

        id_list = []
        id_source['period'] = {
            'start':
            date_to_iso(datetime.strptime(
                src_dict['Provider_Enumeration_Date'], "%m/%d/%Y"),
                        decimals=False)
        }
        if 'NPI_Reactivation_Date' in src_dict:
            if 'NPI_Deactivation_Date' in src_dict:
                if not src_dict['NPI_Deactivation_Date'] == "":
                    date_start = datetime.strptime(
                        src_dict['Provider_Enumeration_Date'], "%m/%d/%Y")
                    date_end = datetime.strptime(
                        src_dict['NPI_Deactivation_Date'], "%m/%d/%Y")
                    id_source['period'] = {
                        'start': date_to_iso(date_start),
                        'end': date_to_iso(date_end)
                    }

            id_list.append(npid(id_source))
            if src_dict['NPI_Reactivation_Date'] > src_dict[
                    'NPI_Deactivation_Date']:
                date_start = datetime.strptime(
                    src_dict['NPI_Reactivation_Date'], "%m/%d/%Y")

                id_source['period'] = {'start': date_to_iso(date_start)}

                id_list.append(npid(id_source))

        else:
            date_start = datetime.strptime(
                src_dict['Provider_Enumeration_Date'], "%m/%d/%Y")
            date_end = datetime.strptime(src_dict['NPI_Deactivation_Date'],
                                         "%m/%d/%Y")

            id_source['period']['start'] = date_to_iso(date_start)
            if 'NPI_Deactivation_Date' in src_dict:
                if not src_dict['NPI_Deactivation_Date'] == "":
                    id_source['period']['end'] = date_to_iso(date_end)
            id_list.append(npid(id_source))

        fp['fhir_identifier'] = id_list
        if settings.DEBUG:
            # print("ID_Section:", fp['fhir_identifier'][0]['type'],":",fp['fhir_identifier'][0]['value'])
            pass
        # Now we need to map the name information to name

        #
        # hn['resourceType'] = "HumanName"
        # hn['use'] = assign_str(source, 'use', "usual")
        # hn['suffix'] = assign_str(source, 'suffix',)
        # hn['prefix'] = assign_str(source, 'prefix',)
        # hn['family'] = assign_str(source, 'family')
        # hn['given']  = assign_str(source, 'given')
        # hn['period'] = assign_str(source, 'period')

        suffix = remove_empty_string([
            src_dict['Provider_Name_Suffix_Text'],
            src_dict['Provider_Credential_Text']
        ])
        prefix = remove_empty_string([src_dict['Provider_Name_Prefix_Text']])

        given = remove_empty_string([
            src_dict['Provider_First_Name'], src_dict['Provider_Middle_Name']
        ])

        name_source = {
            'suffix': suffix,
            'prefix': prefix,
            'family': [src_dict['Provider_Last_Name_Legal_Name']],
            'given': given
        }

        fp['fhir_human_name'] = human_name(name_source)

        # Now we need to map the contact information

        telecom_source = {}
        tel_list = []
        # Map values across to new dictionary
        # cp['resourceType'] = "ContactPoint"
        # cp['system'] = assign_str(source, 'system', "usual")
        # cp['value']  = assign_str(source, 'value',)
        # cp['use']    = assign_str(source, 'use')
        # cp['rank']   = int(assign_str(source, 'rank'))
        # cp['period'] = assign_str(source, 'period')

        rank = 1
        if not src_dict[
                'Provider_Business_Practice_Location_Address_Telephone_Number'] == "":
            telecom_source['system'] = "phone"
            telecom_source['value'] = src_dict[
                'Provider_Business_Practice_Location_Address_Telephone_Number']
            telecom_source['use'] = "practice"
            telecom_source['rank'] = str(rank)

            tel_list.append(contact_point(telecom_source))
            rank += 1

        if not src_dict[
                'Provider_Business_Practice_Location_Address_Fax_Number'] == "":
            telecom_source['system'] = "fax"
            telecom_source['value'] = src_dict[
                'Provider_Business_Practice_Location_Address_Fax_Number']
            telecom_source['rank'] = str(rank)

            tel_list.append(contact_point(telecom_source))
            rank += 1

        if not src_dict[
                'Provider_Business_Mailing_Address_Telephone_Number'] == "":
            telecom_source['system'] = "phone"
            telecom_source['value'] = src_dict[
                'Provider_Business_Mailing_Address_Telephone_Number']
            telecom_source['use'] = "business"
            telecom_source['rank'] = str(rank)

            tel_list.append(contact_point(telecom_source))
            rank += 1

        if not src_dict['Provider_Business_Mailing_Address_Fax_Number'] == "":
            telecom_source['system'] = "fax"
            telecom_source['value'] = src_dict[
                'Provider_Business_Mailing_Address_Fax_Number']
            telecom_source['rank'] = str(rank)

            tel_list.append(contact_point(telecom_source))

        fp['fhir_contact_point'] = tel_list

        # Now we need to map the address information

        addr_source = {}

        addr_list = []

        # ad['resourceType'] = "Address"
        # ad['use']        = assign_str(source, 'use',)
        # ad['type']       = assign_str(source, 'type',)
        # ad['line']       = assign_str(source, 'line',)
        # ad['city']       = assign_str(source, 'city',)
        # ad['district']   = assign_str(source, 'district',)
        # ad['state']      = assign_str(source, 'state',)
        # ad['postalCode'] = assign_str(source, 'postalCode',)
        # ad['country']    = assign_str(source, 'country',)
        # ad['period']     = assign_str(source, 'period',)

        addr_source['use'] = "practice"
        addr_source['type'] = "physical"
        addr_source['line'] = [
            src_dict['Provider_First_Line_Business_Practice_Location_Address'],
            src_dict['Provider_Second_Line_Business_Practice_Location_Address']
        ]
        addr_source['city'] = src_dict[
            'Provider_Business_Practice_Location_Address_City_Name']
        addr_source['state'] = src_dict[
            'Provider_Business_Practice_Location_Address_State_Name']
        addr_source['postalCode'] = src_dict[
            'Provider_Business_Practice_Location_Address_Postal_Code']
        addr_source['country'] = src_dict[
            'Provider_Business_Practice_Location_Address_Country_Code_If_outside_US']

        addr_list.append(address(addr_source))

        addr_source['use'] = "business"
        addr_source['type'] = "postal"
        addr_source['line'] = [
            src_dict['Provider_First_Line_Business_Mailing_Address'],
            src_dict['Provider_Second_Line_Business_Mailing_Address']
        ]
        addr_source['city'] = src_dict[
            'Provider_Business_Mailing_Address_City_Name']
        addr_source['state'] = src_dict[
            'Provider_Business_Mailing_Address_State_Name']
        addr_source['postalCode'] = src_dict[
            'Provider_Business_Mailing_Address_Postal_Code']
        addr_source['country'] = src_dict[
            'Provider_Business_Mailing_Address_Country_Code_If_outside_US']

        addr_list.append(address(addr_source))

        fp['fhir_address'] = addr_list

        # Get Gender

        fp['gender'] = src_dict['Provider_Gender_Code']

        # Get User readable text
        fp['narrative'] = write_practitioner_narrative(src_dict)

        #fp['fhir_extension'] = npi_provider_extension(src_dict)

    return fp