示例#1
0
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
示例#2
0
def create_patient(request, bb_dict):
    """
    Create a Patient Profile using the contents of bb_dict
    (Medicare BlueButton 2.0 Text converted to json)

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

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

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

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

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


    # Compile Profile content

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

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

    id_list.append(unique_id(id_source))

    profile['fhir_identifier'] = id_list

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

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

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

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

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

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

    tel_list.append(contact_point(telecom_source))

    profile['fhir_contact_point'] = tel_list

    addr_source = {}
    addr_list = []

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

    addr_list.append(address(addr_source))

    profile['fhir_address'] = addr_list

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

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

    profile['narrative'] = narrative

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

    # Write Profile

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

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

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

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

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

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

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

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

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

    return
示例#3
0
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)
                              )