def json_to_eob(request): """ :param request: :param patient_id: :return: """ result = {} result['result'] = "FAIL" # if settings.DEBUG: # print("Patient_Id =", patient_id) u = User.objects.get(email=request.user.email) x_walk = Crosswalk.objects.get(user=u) guid = x_walk.guid json_stuff = x_walk.mmg_bbjson if not json_stuff: result['reason'] = "Nothing to process" messages.info(request,result['reason']) return result if not x_walk.fhir_url_id: # No fhir_url_id so we need to create a patient profile outcome = create_patient(request, bb_dict=json_stuff) x_walk = Crosswalk.objects.get(user=u) if not x_walk.fhir_url_id: # create_patient failed to create a patient profile result['reason'] = "A patient profile was not created" messages.error(request, result['reason']) return result if settings.DEBUG: print("Converted BlueButton File:\n", json_stuff, "\n===================================") # Check the Crosswalk for a FHIR Id for this user # If no Crosswalk entry let's check to see if we have a match on # name, dob and addressLine1 # Now we need to see if there is a patient record patient_count = match_patient(request, json_stuff) if settings.DEBUG: print("Patient Count: ", patient_count, "\n Request.user:"******"Unable to match a patient record. We " \ "have multiple patient records matching. " \ "We found " + str(patient_count) + " records." messages.error(request,result['reason']) return result patient_id = x_walk.get_fhir_url_id() if settings.DEBUG: print("=====================", "\nWorking with Patient Id:", patient_id, "\nGUID:", guid, "\n===========") claims = json_stuff['claims'] if settings.DEBUG: print("How many claims:", len(claims), ":", claims, "\n\n\n\nSection 0:", claims[0]) if "claimNumber" in claims[0]: for claim in claims: # Deal with the Claim Header extension = [] extension.append(extn_item("Patient", patient_id, "valueString")) extension.append(extn_item("identifier", guid, "valueString")) for key, value in claim.items(): # if settings.DEBUG: # print("Key:", key) # print("Value:", value) if key == "claimNumber": add_it = extn_item(key, value, "valueString",) claim_number = value extension.append(add_it) elif key == "claimType": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "provider": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "providerBillingAddress": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "date": period = {} if value['serviceStartDate']: period['start'] = value['serviceStartDate'] if value['serviceEndDate']: period['end'] = value['serviceEndDate'] add_it = extn_item(key, period, "valuePeriod") extension.append(add_it) # Set created to the Service End Date. # This should be easier to track duplicate # EOB entries created = value['serviceEndDate'] elif key == "diagnosisCode1": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "diagnosisCode2": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "source": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "charges": for ckey, charge in value.items(): add_it = extn_item(ckey,charge, "valueString") extension.append(add_it) elif key == "details": # Deal with the Claim Lines add_it = claim_detail(details=value) add_it = extn_item(key,add_it,"valueString") extension.append(add_it) eob_extn = [{"url" : "https://dev.bbonfhir.com/fhir/StructureDefinition/cms-eob", "extension": extension}] #if settings.DEBUG: # print("==================================", # "extension:", eob_extn, # "\n==================================") # Now we need to write an EOB Resource to the server. eob = OrderedDict() eob['resourceType'] = "ExplanationOfBenefit" id_source = {} id_list = [] id_source['system'] = "https://mymedicare.gov/claims" id_source['use'] = "official" id_source['value'] = claim_number id_list.append(unique_id(id_source)) 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)) eob['identifier'] = id_list eob['outcome'] = "complete" eob['extension'] = eob_extn #if settings.DEBUG: # print("EOB:", eob) txn = {'resourceType': "ExplanationOfBenefit", 'server': settings.FHIR_SERVER, 'locn': "/baseDstu2/ExplanationOfBenefit"} target_url = txn['server'] + txn['locn'] # Can we write the EOB now.... headers = {'Content-Type': 'application/json+fhir; charset=UTF-8', 'Accept': 'text/plain'} try: r = requests.post(target_url + "?_format=json", data=json.dumps(eob), headers=headers ) if r.status_code == 201: commit_data = r.headers['content-location'] if settings.DEBUG: print("Write returned:", r.status_code, "|", commit_data) elif r.status_code == 400: if settings.DEBUG: print(r.status_code," Problem with input") print(rec_counter,":","Mode:", claim_number,"[", r.status_code, "] NPI:", row_under['NPI'], r.__dict__) except requests.ConnectionError: messages.error(request,"Problem posting:" + claim_number) if settings.DEBUG: print("Result from post", r.status_code, "|", r.content, "|", r.text, "|", "Headers", r.headers) result['result'] = "OK" result['reason'] = "Claims extracted from BlueButton file and posted as EOBs" messages.info(request, result['reason']) return result else: result['result'] = "FAIL" result['reason'] = "No claims found in BueButton file " + str(claims[0]) messages.info(request, result['reason']) return result result['reason'] = "BlueButton file processed" messages.info(request, result['reason']) return result
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 write_eob(request, patient_id, bbj_in): """ :param request: :param patient_id: :param bbj_in: :return: """ if settings.DEBUG: print("Patient_Id =", patient_id) print("JSON File =", bbj_in) demodict = cms_file_read(settings.MEDIA_ROOT+bbj_in) json_stuff = parse_lines(demodict) if settings.DEBUG: print("Converted BlueButton File:\n", json_stuff, "\n===================================") #jfn = open(settings.MEDIA_ROOT+bbj_in, 'r') #json_stuff = json.load(jfn) # print("stuff:", json_stuff) #jfn.close() # Check the Crosswalk for a FHIR Id for this user # If no Crosswalk entry let's check to see if we have a match on # name, dob and addressLine1 # Now we need to see if there is a patient record patient_count = match_patient(request, json_stuff) if settings.DEBUG: print("Patient Count: ", patient_count, "\n Request.user:"******"Unable to match a patient record. We" "have multiple patient records matching." " We found ", patient_count, " records.") return HttpResponseRedirect(reverse("eob_upload:home")) elif patient_count == 0: # We need to create a patient resource record # If there is no fhir_url_id in the crosswalk for request.user try: x_walk = Crosswalk.objects.get(user=request.user) guid = x_walk.guid patient_id = x_walk.get_fhir_url_id() except Crosswalk.DoesNotExist: # No Crosswalk so create a patient result = create_patient(request, bb_dict=json_stuff) # create_patient should have created a crosswalk entry x_walk = Crosswalk.objects.get(user=request.user) guid = x_walk.guid patient_id = x_walk.get_fhir_url_id() else: # patient_count == 1: # x_walk = Crosswalk.objects.get(user=request.user) guid = x_walk.guid patient_id = x_walk.get_fhir_url_id() if settings.DEBUG: print("=====================", "\nWorking with Patient Id:", patient_id, "\nGUID:", guid, "\n===========") claims = json_stuff['claims'] for claim in claims: # Deal with the Claim Header extension = [] extension.append(extn_item("Patient", patient_id, "valueString")) extension.append(extn_item("identifier", guid, "valueString")) for key, value in claim.items(): # if settings.DEBUG: # print("Key:", key) # print("Value:", value) if key == "claimNumber": add_it = extn_item(key, value, "valueString",) claim_number = value extension.append(add_it) elif key == "claimType": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "provider": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "providerBillingAddress": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "date": period = {} if value['serviceStartDate']: period['start'] = value['serviceStartDate'] if value['serviceEndDate']: period['end'] = value['serviceEndDate'] add_it = extn_item(key, period, "valuePeriod") extension.append(add_it) # Set created to the Service End Date. # This should be easier to track duplicate # EOB entries created = value['serviceEndDate'] elif key == "diagnosisCode1": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "diagnosisCode2": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "source": add_it = extn_item(key, value, "valueString") extension.append(add_it) elif key == "charges": for ckey, charge in value.items(): add_it = extn_item(ckey,charge, "valueString") extension.append(add_it) elif key == "details": # Deal with the Claim Lines add_it = claim_detail(details=value) add_it = extn_item(key,add_it,"valueString") extension.append(add_it) eob_extn = [{"url" : "https://dev.bbonfhir.com/fhir/StructureDefinition/cms-eob", "extension": extension}] #if settings.DEBUG: # print("==================================", # "extension:", eob_extn, # "\n==================================") # Now we need to write an EOB Resource to the server. eob = OrderedDict() eob['resourceType'] = "ExplanationOfBenefit" id_source = {} id_list = [] id_source['system'] = "https://mymedicare.gov/claims" id_source['use'] = "official" id_source['value'] = claim_number id_list.append(unique_id(id_source)) 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)) eob['identifier'] = id_list eob['outcome'] = "complete" eob['extension'] = eob_extn #if settings.DEBUG: # print("EOB:", eob) txn = {'resourceType': "ExplanationOfBenefit", 'server': settings.FHIR_SERVER, 'locn': "/baseDstu2/ExplanationOfBenefit"} target_url = txn['server'] + txn['locn'] # Can we write the EOB now.... headers = {'Content-Type': 'application/json+fhir; charset=UTF-8', 'Accept': 'text/plain'} try: r = requests.post(target_url + "?_format=json", data=json.dumps(eob), headers=headers ) if r.status_code == 201: commit_data = r.headers['content-location'] if settings.DEBUG: print("Write returned:", r.status_code, "|", commit_data) elif r.status_code == 400: if settings.DEBUG: print(r.status_code," Problem with input") print(rec_counter,":","Mode:", claim_number,"[", r.status_code, "] NPI:", row_under['NPI'], r.__dict__) except requests.ConnectionError: messages.error(request,"Problem posting:" + claim_number) if settings.DEBUG: print("Result from post", r.status_code, "|", r.content, "|", r.text, "|", "Headers", r.headers) form = {} return render_to_response('eob_upload/eob.html', {'documents': claims, 'patient_id': patient_id, 'eob': json.dumps(eob, indent=4, ), 'form': form}, context_instance=RequestContext(request) )