def write_practitioner_narrative(profile): """ Write a Practitioner Narrative section using the Practitioner Profile :param profile: :return: text string """ # Use <br/> to force line breaks. <br> will not validate successfully narrative = "" narrative = concat_string(narrative, ["Provider Information:"], delimiter=" ") narrative = concat_string(narrative, [ profile['Provider_Name_Prefix_Text'], profile['Provider_First_Name'], profile['Provider_Last_Name_Legal_Name'], profile['Provider_Name_Suffix_Text'], ".<br/>" ], delimiter=" ", last="") narrative = concat_string(narrative, [ "Tel:", profile[ 'Provider_Business_Practice_Location_Address_Telephone_Number'], "<br/>", "Practice Address:<br/>", profile['Provider_First_Line_Business_Practice_Location_Address'], "<br/>", profile['Provider_Second_Line_Business_Practice_Location_Address'], "<br/>", profile['Provider_Business_Practice_Location_Address_City_Name'], profile['Provider_Business_Practice_Location_Address_State_Name'], "<br/>", profile['Provider_Business_Practice_Location_Address_Postal_Code'], "<br/>" ], delimiter=" ", last="") # if settings.DEBUG: # print("Narrative function:", narrative) return narrative
def write_practitioner_narrative(profile): """ Write a Practitioner Narrative section using the Practitioner Profile :param profile: :return: text string """ # Use <br/> to force line breaks. <br> will not validate successfully narrative = "" narrative = concat_string(narrative, ["Provider Information:"], delimiter=" ") narrative = concat_string(narrative, [profile['Provider_Name_Prefix_Text'], profile['Provider_First_Name'], profile['Provider_Last_Name_Legal_Name'], profile['Provider_Name_Suffix_Text'], ".<br/>"], delimiter=" ", last="") narrative = concat_string(narrative, ["Tel:", profile['Provider_Business_Practice_Location_Address_Telephone_Number'], "<br/>", "Practice Address:<br/>", profile['Provider_First_Line_Business_Practice_Location_Address'], "<br/>", profile['Provider_Second_Line_Business_Practice_Location_Address'], "<br/>", profile['Provider_Business_Practice_Location_Address_City_Name'], profile['Provider_Business_Practice_Location_Address_State_Name'], "<br/>", profile['Provider_Business_Practice_Location_Address_Postal_Code'], "<br/>" ], delimiter=" ", last="" ) # if settings.DEBUG: # print("Narrative function:", narrative) return narrative
def get_eob(request, Access_Mode=None, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN" and kwargs['patient_id']!="": # Lookup using patient_id for fhir_url_id key = kwargs['patient_id'].strip() else: try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("FHIR URL ID :", key) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # http://ec2-52-4-198-86.compute-1.amazonaws.com:8081/baseDstu2/ # ExplanationOfBenefit/?patient=Patient/131052&_format=json # # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = {'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format', 'patient'] mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit" pass_to += "/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to += "?patient=" pass_to += "Patient/" pass_to += key pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = {'display': 'EOB', 'name': 'ExplanationOfBenefit', 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, } try: r = requests.get(pass_to) context = process_page(request,r,context) # Setup the page if settings.DEBUG: print("Context-result:", context['result']) # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": #return HttpResponse(context['result'], mimetype="application/json") return JsonResponse(context['import_text'], safe=False) else: if context['text'] == "No user readable content to display" or context['text']=="": result = json.loads(context['result'], object_pairs_hook=OrderedDict) print("Result::", result) context['text'] += "<br/> extracting information from returned record:<br/>" context['text'] += "<table>\n" if 'name' in result: patient_name = result['name'][0]['given'][0] patient_name += " " patient_name += result['name'][0]['family'][0] context['text'] += tr_build_item("Patient Name ", patient_name) if 'address' in result: context['text'] += tr_build_item("Patient Address", result['address'][0]['line'][0]) if 'birthDate' in result: context['text'] += tr_build_item("Birth Date", result['birthDate']) if 'identifier' in result: context['text'] += tr_build_item("Patient ID", result['identifier'][0]['value']) context['text'] += "</table>" return render_to_response('v1api/eob.html', RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def PatientExplanationOfBenefit(request, patient_id=None, *args, **kwargs): """ Function-based interface to ExplanationOfBenefit :param request: :return: """ if patient_id == None: try: xwalk = Crosswalk.objects.get(user=request.user.id) patient_id = xwalk.fhir_url_id except Crosswalk.DoesNotExist: reason = "Unable to find Patient ID for user:%s[%s]" % (request.user, request.user.id) messages.error(request, reason) return kickout_404(reason) # return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) if patient_id == "": err_msg = ['Sorry, No Patient Id provided', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("In apps.v1api.views.eob.PatientExplanationOfBenefit Function") print("request:", request.GET) process_mode = request.META['REQUEST_METHOD'] in_fmt = "json" get_fmt = get_format(request.GET) Txn = {'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Patient :", patient_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" key = patient_id patient_filter= "?patient=Patient/" + key pass_to += patient_filter skip_parm = ['_id', '_format'] pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] # Set Context context = {'display':"EOB", 'name': "ExplanationOfBenefit", 'mask': True, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, } if settings.DEBUG: print("Calling requests with pass_to:", pass_to) try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) print("XML_TEXT:", xml_text.toxml()) root = ET.fromstring(r.text) # root_out = etree_to_dict(r.text) json_string = "" # json_out = xml_str_to_json_str(r.text, json_string) if settings.DEBUG: print("Root ET XML:", root) # print("XML:", root_out) # print("JSON_OUT:", json_out,":", json_string) drill_down = ['Bundle', 'entry', 'Patient', ] level = 0 tag0 = xml_text.getElementsByTagName("text") # tag1 = tag0.getElementsByTagName("entry") print("Patient?:", tag0) print("DrillDown:", drill_down[level]) print("root find:", root.find(drill_down[level])) pretty_xml = xml_text.toprettyxml() #if settings.DEBUG: # print("TEXT:", text) # # print("Pretty XML:", pretty_xml) context['result'] = pretty_xml # convert context['text'] = pretty_xml else: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) # print("Next Level - entry:", convert['entry']) # print("\n ANOTHER Level- text:", convert['entry'][0]) content = OrderedDict(convert) text = "" if settings.DEBUG: print("Content:", content) print("resourceType:", content['resourceType']) if 'text' in content: if 'div' in content['text']: print("text:", content['text']['div']) # context['result'] = r.json() # convert import_text = json.loads(r.text, object_pairs_hook=OrderedDict) context['result'] = json.dumps(import_text, indent=4, sort_keys=False) if 'text' in content: if 'div' in content['text']: context['text'] = content['text']['div'] else: context['text'] = "" else: context['text'] = "No user readable content to display" if 'error' in content: context['error'] = context['issue'] # Setup the page if settings.DEBUG: print("Context-result:", context['result']) # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": #return HttpResponse(context['result'], mimetype="application/json") return JsonResponse(import_text, safe=False ) else: return render_to_response(Txn['template'], RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
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 get_patient(request, Access_Mode=None, *args, **kwargs): """ Display Patient Profile :param request: :param Access_Mode = [None], Open :param args: :param kwargs: :return: """ # Access_Mode = None = Do Crosswalk using Request.user # Access_Mode = OPEN = use kwargs['patient_id'] if settings.DEBUG: print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN" and kwargs['patient_id'] != "": # Lookup using patient_id for fhir_url_id key = kwargs['patient_id'].strip() else: # DONE: Setup Patient API so that ID is not required # DONE: Do CrossWalk Lookup to get Patient ID if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user) try: xwalk = Crosswalk.objects.get(user=request.user.id) except Crosswalk.DoesNotExist: reason = "Unable to find Patient ID for user:%s[%s]" % ( request.user, request.user.id) messages.error(request, reason) return kickout_404(reason) # return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) # return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", key) # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" # fhir_server_configuration = {"SERVER":"http://fhir-test.bbonfhir.com:8081", # "PATH":"", # "RELEASE":"/baseDstu2"} # FHIR_SERVER_CONF = fhir_server_configuration # FHIR_SERVER = FHIR_SERVER_CONF['SERVER'] + FHIR_SERVER_CONF['PATH'] # Since this is BlueButton and we are dealing with Patient Records # We need to limit the id search to the specific beneficiary. # A BlueButton user should not be able to request a patient profile # that is not their own. # We do this via the CrossWalk. The xwalk.fhir_url_id is the patient # id as used in the url. eg. /Patient/23/ # FHIR also allows an enquiry with ?_id=23. We need to detect that # and remove it from the parameters that are passed. # All other query parameters should be passed through to the # FHIR server. # Add URL Parameters to skip_parm to ignore or perform custom # processing with them. Use lower case values for matching. # DO NOT USE Uppercase skip_parm = ['_id', '_format'] mask = True pass_to = FhirServerUrl() pass_to += "/Patient" pass_to += "/" pass_to = pass_to + key + "/" # We need to detect if a format was requested in the URL Parameters # ie. _format=json|xml # modify get_format to default to return nothing. ie. make no change # internal data handling will be JSON # _format will drive external display # if no _format setting we will display in html (Current mode) # if valid _format string we will pass content through to display in # raw format get_fmt = get_format(request.GET) if settings.DEBUG: print("pass_to:", pass_to) pass_to = pass_to + build_params(request.GET, skip_parm) if settings.DEBUG: print("pass_to added to:", pass_to) mask_to = settings.DOMAIN # Set Context context = { 'display': "Patient", 'name': "Patient", 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, 'template': 'v1api/patient.html', } if settings.DEBUG: print("Calling Requests with:", pass_to) try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) # # Setup the page # # if settings.DEBUG: # print("Context-result:", context['result']) # # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # # print("Context:",context) # # if get_fmt == 'xml' or get_fmt == 'json': # if settings.DEBUG: # print("Mode = ", get_fmt) # print("Context['result']: ", context['result']) # if get_fmt == "xml": # return HttpResponse(context['result'], # content_type='application/' + get_fmt) # if get_fmt == "json": # #return HttpResponse(context['result'], mimetype="application/json") # return JsonResponse(context['import_text'], safe=False) # # else: # # if context['text'] == "No user readable content to display" or context['text']=="": # # result = json.loads(context['result'], object_pairs_hook=OrderedDict) # print("Result::", result) # context['text'] += "<br/> extracting information from returned record:<br/>" # context['text'] += "<table>\n" # if 'name' in result: # patient_name = result['name'][0]['given'][0] # patient_name += " " # patient_name += result['name'][0]['family'][0] # context['text'] += tr_build_item("Patient Name ", # patient_name) # if 'address' in result: # context['text'] += tr_build_item("Patient Address", # result['address'][0]['line'][0]) # if 'birthDate' in result: # context['text'] += tr_build_item("Birth Date", result['birthDate']) # # if 'identifier' in result: # context['text'] += tr_build_item("Patient ID", # result['identifier'][0]['value']) # context['text'] += "</table>" # # return render_to_response('v1api/patient.html', # RequestContext(request, # context, )) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob_view(request, eob_id, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor Single EOB") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id if eob_id: pass_to = pass_to + eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?patient=" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, 'template': 'v1api/eob.html', } try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob_view(request, eob_id, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor Single EOB") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = { 'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, # 'server': settings.FHIR_SERVER, # 'locn': "/baseDstu2/ExplanationOfBenefit/", 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = False if 'mask' in Txn: mask = Txn['mask'] pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id if eob_id: pass_to = pass_to + eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?patient=" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'display': Txn['display'], 'name': Txn['name'], 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': Txn['in_fmt'], # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, } try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) pretty_xml = xml_text.toprettyxml() context['result'] = pretty_xml # convert context['text'] = pretty_xml return HttpResponse(context['result'], content_type='application/' + get_fmt) else: # get_fmt == "json" or None: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) content = OrderedDict(convert) text = "" context['result'] = r.json() # convert if 'text' in content: context['text'] = content['text']['div'] if 'issue' in content: context['error'] = content['issue'] else: if settings.DEBUG: print("Resource:", convert['entry']) context['text'] = convert['entry'] if get_fmt == "json": return JsonResponse(context['result'], ) return render_to_response(Txn['template'], RequestContext( request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error( request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def PatientExplanationOfBenefit(request, patient_id=None, *args, **kwargs): """ Function-based interface to ExplanationOfBenefit :param request: :return: """ if patient_id == None: patient_id = lookup_xwalk(request) if patient_id == None: err_msg = [ 'Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) if patient_id == "": err_msg = [ 'Sorry, No Patient Id provided', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("In apps.v1api.views.eob.PatientExplanationOfBenefit Function") print("request:", request.GET) process_mode = request.META['REQUEST_METHOD'] in_fmt = "json" get_fmt = get_format(request.GET) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Patient :", patient_id) # We should have the patient_id from xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" key = patient_id patient_filter = "?patient=Patient/" + key pass_to += patient_filter skip_parm = ['_id', '_format'] pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] # Set Context context = { 'display': "EOB", 'name': "ExplanationOfBenefit", 'mask': True, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } if settings.DEBUG: print("Calling requests with pass_to:", pass_to) try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob(request, eob_id=None, Access_Mode=None, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN": # Lookup using eob_id without patient filter key = "" else: try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("FHIR URL ID :", key) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # http://ec2-52-4-198-86.compute-1.amazonaws.com:8081/baseDstu2/ # ExplanationOfBenefit/?patient=Patient/131052&_format=json # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) skip_parm = ['_id', '_format', 'patient'] mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit" pass_to += "/" if eob_id == None: pass else: pass_to += eob_id # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" if not key == "": pass_to += "?patient=" pass_to += "Patient/" pass_to += key pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = {'display': 'EOB', 'name': 'ExplanationOfBenefit', 'mask': mask, 'key': key, 'eob_id': eob_id, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } try: r = requests.get(pass_to) context = process_page(request,r,context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_eob_view(request, eob_id, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor Single EOB") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id if eob_id: pass_to = pass_to + eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?patient=" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = {'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, 'template': 'v1api/eob.html', } try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request,'api:v1:home')
def PatientExplanationOfBenefit(request, patient_id=None, *args, **kwargs): """ Function-based interface to ExplanationOfBenefit :param request: :return: """ if patient_id == None: patient_id = lookup_xwalk(request) if patient_id == None: err_msg = ['Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) if patient_id == "": err_msg = ['Sorry, No Patient Id provided', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("In apps.v1api.views.eob.PatientExplanationOfBenefit Function") print("request:", request.GET) process_mode = request.META['REQUEST_METHOD'] in_fmt = "json" get_fmt = get_format(request.GET) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Patient :", patient_id) # We should have the patient_id from xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" key = patient_id patient_filter= "?patient=Patient/" + key pass_to += patient_filter skip_parm = ['_id', '_format'] pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] # Set Context context = {'display':"EOB", 'name': "ExplanationOfBenefit", 'mask': True, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } if settings.DEBUG: print("Calling requests with pass_to:", pass_to) try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_patient(request, *args, **kwargs): """ Display Patient Profile :param request: :param args: :param kwargs: :return: """ # DONE: Setup Patient API so that ID is not required # DONE: Do CrossWalk Lookup to get Patient ID if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user) try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = {'name': "Patient", 'display': 'Patient', 'mask': True, 'server': settings.FHIR_SERVER, 'locn': "/baseDstu2/Patient/", 'template': 'v1api/patient.html', 'in_fmt': in_fmt, } # Since this is BlueButton and we are dealing with Patient Records # We need to limit the id search to the specific beneficiary. # A BlueButton user should not be able to request a patient profile # that is not their own. # We do this via the CrossWalk. The xwalk.fhir_url_id is the patient # id as used in the url. eg. /Patient/23/ # FHIR also allows an enquiry with ?_id=23. We need to detect that # and remove it from the parameters that are passed. # All other query parameters should be passed through to the # FHIR server. # Add URL Parameters to skip_parm to ignore or perform custom # processing with them. Use lower case values for matching. # DO NOT USE Uppercase skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = False if 'mask' in Txn: mask = Txn['mask'] pass_to = Txn['server'] + Txn['locn'] pass_to = pass_to + key + "/" # We need to detect if a format was requested in the URL Parameters # ie. _format=json|xml # modify get_format to default to return nothing. ie. make no change # internal data handling will be JSON # _format will drive external display # if no _format setting we will display in html (Current mode) # if valid _format string we will pass content through to display in # raw format get_fmt = get_format(request.GET) pass_to = pass_to + "?" + build_params(request.GET, skip_parm) mask_to = settings.DOMAIN # Set Context context = {'display': Txn['display'], 'name': Txn['name'], 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': Txn['in_fmt'], # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, } if settings.DEBUG: print("Calling Requests with:", pass_to) try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) print("XML_TEXT:", xml_text.toxml()) root = ET.fromstring(r.text) # root_out = etree_to_dict(r.text) json_string = "" # json_out = xml_str_to_json_str(r.text, json_string) if settings.DEBUG: print("Root ET XML:", root) # print("XML:", root_out) # print("JSON_OUT:", json_out,":", json_string) drill_down = ['Bundle', 'entry', 'Patient', ] level = 0 tag0 = xml_text.getElementsByTagName("text") # tag1 = tag0.getElementsByTagName("entry") print("Patient?:", tag0) print("DrillDown:", drill_down[level]) print("root find:", root.find(drill_down[level])) for element in root: print("Child Element:", element) if drill_down[level] in element: level += 1 for element2 in element: print("Element2:", element2) if drill_down[level] in element2: print("Element2.iter()", element2.iter()) text = root[4][0][0][2][1].findtext("text") pretty_xml = xml_text.toprettyxml() if settings.DEBUG: print("TEXT:", text) # print("Pretty XML:", pretty_xml) context['result'] = pretty_xml # convert context['text'] = pretty_xml else: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) # print("Next Level - entry:", convert['entry']) # print("\n ANOTHER Level- text:", convert['entry'][0]) content = OrderedDict(convert) text = "" if settings.DEBUG: print("Content:", content) print("resourceType:", content['resourceType']) print("text:", content['text']['div']) context['result'] = r.json() # convert context['text'] = content['text']['div'] if 'error' in content: context['error'] = context['issue'] # Setup the page if settings.DEBUG: print() # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": return JsonResponse(context['result'], ) else: return render_to_response(Txn['template'], RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def get_eob(request, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = {'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, 'server': settings.FHIR_SERVER, 'locn': "/baseDstu2/ExplanationOfBenefit/", 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = False if 'mask' in Txn: mask = Txn['mask'] pass_to = Txn['server'] + Txn['locn'] # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?identifier=" pass_to = pass_to + "https://mymedicare.gov/claims/beneficiary|" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = {'display': Txn['display'], 'name': Txn['name'], 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': Txn['in_fmt'], # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, } try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) pretty_xml = xml_text.toprettyxml() context['result'] = pretty_xml # convert context['text'] = pretty_xml return HttpResponse(context['result'], content_type='application/' + get_fmt) else: # get_fmt == "json" or None: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) content = OrderedDict(convert) text = "" context['result'] = r.json() # convert if 'text' in content: context['text'] = content['resource']['text']['div'] else: if settings.DEBUG: print("Resource:", convert['entry']) context['text'] = convert['entry'] if get_fmt == "json": return JsonResponse(context['result'], ) return render_to_response(Txn['template'], RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def get_eob_view(request, eob_id, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor Single EOB") try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) if settings.DEBUG: print("Request.GET :", request.GET) print("KWargs :", kwargs) print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", xwalk.fhir_url_id) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = {'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, # 'server': settings.FHIR_SERVER, # 'locn': "/baseDstu2/ExplanationOfBenefit/", 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format'] key = xwalk.fhir_url_id.strip() mask = False if 'mask' in Txn: mask = Txn['mask'] pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id if eob_id: pass_to = pass_to + eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to = pass_to + "?patient=" pass_to = pass_to + "Patient/" pass_to = pass_to + xwalk.fhir_url_id.strip() pass_to = pass_to + "&" + build_params(request.GET, skip_parm) if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = {'display': Txn['display'], 'name': Txn['name'], 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': Txn['in_fmt'], # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, } try: r = requests.get(pass_to) if get_fmt == "xml": xml_text = minidom.parseString(r.text) pretty_xml = xml_text.toprettyxml() context['result'] = pretty_xml # convert context['text'] = pretty_xml return HttpResponse(context['result'], content_type='application/' + get_fmt) else: # get_fmt == "json" or None: convert = OrderedDict(r.json()) # result = mark_safe(convert) if settings.DEBUG: print("Convert:", convert) content = OrderedDict(convert) text = "" context['result'] = r.json() # convert if 'text' in content: context['text'] = content['text']['div'] if 'issue' in content: context['error'] = content['issue'] else: if settings.DEBUG: print("Resource:", convert['entry']) context['text'] = convert['entry'] if get_fmt == "json": return JsonResponse(context['result'], ) return render_to_response(Txn['template'], RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def get_eob(request, eob_id=None, Access_Mode=None, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN": # Lookup using eob_id without patient filter key = "" else: try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("FHIR URL ID :", key) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # http://ec2-52-4-198-86.compute-1.amazonaws.com:8081/baseDstu2/ # ExplanationOfBenefit/?patient=Patient/131052&_format=json # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) skip_parm = ['_id', '_format', 'patient'] mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit" pass_to += "/" if eob_id == None: pass else: pass_to += eob_id # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" if not key == "": pass_to += "?patient=" pass_to += "Patient/" pass_to += key pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'display': 'EOB', 'name': 'ExplanationOfBenefit', 'mask': mask, 'key': key, 'eob_id': eob_id, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, 'template': 'v1api/eob.html', } try: r = requests.get(pass_to) context = process_page(request, r, context) return publish_page(request, context) except requests.ConnectionError: pass return cms_not_connected(request, 'api:v1:home')
def get_patient(request, Access_Mode=None, *args, **kwargs): """ Display Patient Profile :param request: :param Access_Mode = [None], Open :param args: :param kwargs: :return: """ # Access_Mode = None = Do Crosswalk using Request.user # Access_Mode = OPEN = use kwargs['patient_id'] if settings.DEBUG: print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN" and kwargs['patient_id']!="": # Lookup using patient_id for fhir_url_id key = kwargs['patient_id'].strip() else: # DONE: Setup Patient API so that ID is not required # DONE: Do CrossWalk Lookup to get Patient ID if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user) try: xwalk = Crosswalk.objects.get(user=request.user.id) except Crosswalk.DoesNotExist: reason = "Unable to find Patient ID for user:%s[%s]" % (request.user, request.user.id) messages.error(request, reason) return kickout_404(reason) # return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = ['Crosswalk lookup failed: Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return kickout_404(exit_message) # return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("Crosswalk :", xwalk) print("GUID :", xwalk.guid) print("FHIR :", xwalk.fhir) print("FHIR URL ID :", key) # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" # fhir_server_configuration = {"SERVER":"http://fhir-test.bbonfhir.com:8081", # "PATH":"", # "RELEASE":"/baseDstu2"} # FHIR_SERVER_CONF = fhir_server_configuration # FHIR_SERVER = FHIR_SERVER_CONF['SERVER'] + FHIR_SERVER_CONF['PATH'] # Since this is BlueButton and we are dealing with Patient Records # We need to limit the id search to the specific beneficiary. # A BlueButton user should not be able to request a patient profile # that is not their own. # We do this via the CrossWalk. The xwalk.fhir_url_id is the patient # id as used in the url. eg. /Patient/23/ # FHIR also allows an enquiry with ?_id=23. We need to detect that # and remove it from the parameters that are passed. # All other query parameters should be passed through to the # FHIR server. # Add URL Parameters to skip_parm to ignore or perform custom # processing with them. Use lower case values for matching. # DO NOT USE Uppercase skip_parm = ['_id', '_format'] mask = True pass_to = FhirServerUrl() pass_to += "/Patient" pass_to += "/" pass_to = pass_to + key + "/" # We need to detect if a format was requested in the URL Parameters # ie. _format=json|xml # modify get_format to default to return nothing. ie. make no change # internal data handling will be JSON # _format will drive external display # if no _format setting we will display in html (Current mode) # if valid _format string we will pass content through to display in # raw format get_fmt = get_format(request.GET) print("pass_to:", pass_to) pass_to = pass_to + build_params(request.GET, skip_parm) print("pass_to added to:", pass_to) mask_to = settings.DOMAIN # Set Context context = {'display':"Patient", 'name': "Patient", 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, # 'output' : "test output ", # 'args' : args, # 'kwargs' : kwargs, # 'get' : request.GET, 'pass_to': pass_to, } if settings.DEBUG: print("Calling Requests with:", pass_to) try: r = requests.get(pass_to) context = process_page(request,r,context) # Setup the page if settings.DEBUG: print("Context-result:", context['result']) # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": #return HttpResponse(context['result'], mimetype="application/json") return JsonResponse(context['import_text'], safe=False) else: if context['text'] == "No user readable content to display" or context['text']=="": result = json.loads(context['result'], object_pairs_hook=OrderedDict) print("Result::", result) context['text'] += "<br/> extracting information from returned record:<br/>" context['text'] += "<table>\n" if 'name' in result: patient_name = result['name'][0]['given'][0] patient_name += " " patient_name += result['name'][0]['family'][0] context['text'] += tr_build_item("Patient Name ", patient_name) if 'address' in result: context['text'] += tr_build_item("Patient Address", result['address'][0]['line'][0]) if 'birthDate' in result: context['text'] += tr_build_item("Birth Date", result['birthDate']) if 'identifier' in result: context['text'] += tr_build_item("Patient ID", result['identifier'][0]['value']) context['text'] += "</table>" return render_to_response('v1api/patient.html', RequestContext(request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error(request, "FHIR Server is unreachable. Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))
def get_eob(request, Access_Mode=None, *args, **kwargs): """ Display one or more EOBs but Always limit scope to Patient_Id :param request: :param eob_id: Request a specific EOB :param args: :param kwargs: :return: """ if settings.DEBUG: print("Request User Beneficiary(Patient):", request.user, "\nFor EOB Enquiry ") print("Request.GET :", request.GET) print("Access_Mode :", Access_Mode) print("KWargs :", kwargs) print("Args :", args) if Access_Mode == "OPEN" and kwargs['patient_id'] != "": # Lookup using patient_id for fhir_url_id key = kwargs['patient_id'].strip() else: try: xwalk = Crosswalk.objects.get(user=request.user) except Crosswalk.DoesNotExist: messages.error(request, "Unable to find Patient ID") return HttpResponseRedirect(reverse('api:v1:home')) if xwalk.fhir_url_id == "": err_msg = [ 'Sorry, We were unable to find', 'your record', ] exit_message = concat_string("", msg=err_msg, delimiter=" ", last=".") messages.error(request, exit_message) return HttpResponseRedirect(reverse('api:v1:home')) key = xwalk.fhir_url_id.strip() if settings.DEBUG: print("FHIR URL ID :", key) # We should have the xwalk.FHIR_url_id # So we will construct the EOB Identifier to include # This is a hack to limit EOBs returned to this user only. # id_source['system'] = "https://mymedicare.gov/claims/beneficiary" # id_source['use'] = "official" # id_source['value'] = "Patient/"+str(patient_id) # id_list.append(unique_id(id_source)) # this search works: # http://fhir.bbonfhir.com:8080/fhir-p/ # search?serverId=bbonfhir_dev # &resource=ExplanationOfBenefit # ¶m.0.0=https%3A%2F%2Fmymedicare.gov%2Fclaims%2Fbeneficiary # ¶m.0.1=Patient%2F4995401 # ¶m.0.name=identifier # ¶m.0.type=token # &sort_by= # &sort_direction= # &resource-search-limit= # http://ec2-52-4-198-86.compute-1.amazonaws.com:8081/baseDstu2/ # ExplanationOfBenefit/?patient=Patient/131052&_format=json # # We will deal internally in JSON Format if caller does not choose # a format in_fmt = "json" get_fmt = get_format(request.GET) # DONE: Define Transaction Dictionary to enable generic presentation of API Call Txn = { 'name': "ExplanationOfBenefit", 'display': 'EOB', 'mask': True, 'template': 'v1api/eob.html', 'in_fmt': in_fmt, } skip_parm = ['_id', '_format', 'patient'] mask = True pass_to = FhirServerUrl() pass_to += "/ExplanationOfBenefit" pass_to += "/" # We can allow an EOB but we MUST add a search Parameter # to limit the items found to those relevant to the Patient Id #if eob_id: # pass_to = eob_id + "/" # Now apply the search restriction to limit to patient _id #pass_to = pass_to + key + "/" pass_to += "?patient=" pass_to += "Patient/" pass_to += key pass_to = pass_to + "&" + build_params(request.GET, skip_parm)[1:] if settings.DEBUG: print("Pass_to from build_params:", pass_to) if settings.DEBUG: print("Calling requests with pass_to:", pass_to) # Set Context context = { 'display': 'EOB', 'name': 'ExplanationOfBenefit', 'mask': mask, 'key': key, 'get_fmt': get_fmt, 'in_fmt': in_fmt, 'pass_to': pass_to, } try: r = requests.get(pass_to) context = process_page(request, r, context) # Setup the page if settings.DEBUG: print("Context-result:", context['result']) # print("Context-converted:", json.dumps(context['result'], sort_keys=False)) # print("Context:",context) if get_fmt == 'xml' or get_fmt == 'json': if settings.DEBUG: print("Mode = ", get_fmt) print("Context['result']: ", context['result']) if get_fmt == "xml": return HttpResponse(context['result'], content_type='application/' + get_fmt) if get_fmt == "json": #return HttpResponse(context['result'], mimetype="application/json") return JsonResponse(context['import_text'], safe=False) else: if context[ 'text'] == "No user readable content to display" or context[ 'text'] == "": result = json.loads(context['result'], object_pairs_hook=OrderedDict) print("Result::", result) context[ 'text'] += "<br/> extracting information from returned record:<br/>" context['text'] += "<table>\n" if 'name' in result: patient_name = result['name'][0]['given'][0] patient_name += " " patient_name += result['name'][0]['family'][0] context['text'] += tr_build_item( "Patient Name ", patient_name) if 'address' in result: context['text'] += tr_build_item( "Patient Address", result['address'][0]['line'][0]) if 'birthDate' in result: context['text'] += tr_build_item("Birth Date", result['birthDate']) if 'identifier' in result: context['text'] += tr_build_item( "Patient ID", result['identifier'][0]['value']) context['text'] += "</table>" return render_to_response('v1api/eob.html', RequestContext( request, context, )) except requests.ConnectionError: print("Whoops - Problem connecting to FHIR Server") messages.error( request, "FHIR Server is unreachable. " "Are you on the CMS Network?") return HttpResponseRedirect(reverse('api:v1:home'))