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
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