diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index 3742e3f48b..2f29e43489 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -10,7 +10,7 @@ env: # NOTE: The expression below can be extended to multi-line # using a '\' as a continuation character. # https://stackoverflow.com/questions/6268391/is-there-a-way-to-represent-a-long-string-that-doesnt-have-any-whitespace-on-mul - workflow_files_re: "^apps/(?!bfd-pipeline/bfd-pipeline-idr|utils).+$|^.github/workflows/ci-java.yml$" + workflow_files_re: "^apps/(?!bfd-pipeline/bfd-pipeline-idr|bfd-model/bfd-model-idr|utils).+$|^.github/workflows/ci-java.yml$" jobs: workflow: diff --git a/apps/bfd-model/bfd-model-idr/README.md b/apps/bfd-model/bfd-model-idr/README.md new file mode 100644 index 0000000000..401a901cc5 --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/README.md @@ -0,0 +1,38 @@ +Placeholder directories + structures for mapping between IDR and FHIR. + +To download the FHIR Validator: +https://github.com/hapifhir/org.hl7.fhir.core/releases/latest/download/validator_cli.jar + +To execute FHIR Mapping language transforms against the sample data. +To compile the StructureMap: +```sh +java -jar validator_cli.jar -ig maps/patient.map \ + -compile https://bfd.cms.gov/MappingLanguage/Resources/Patient \ + -version 4.0.1 -output StructureMaps/bfd_patient_structuremap.json +``` + +To execute: +```sh +java -jar validator_cli.jar sample-data/BeneficiarySample.json \ + -output outputs/Patient.json \ + -transform https://bfd.cms.gov/MappingLanguage/Resources/Patient \ + -version 4.0.1 \ + -ig StructureMaps/bfd_patient_structuremap.json \ + -ig StructureDefinitions/Source/Bene-MBI.json \ + -ig StructureDefinitions/Source/Bene.json \ + -ig hl7.fhir.us.carin-bb#2.0.0 \ + -ig maps/Patient-Helper.map +``` + + +Validating sample resources against self-defined StructureDefinitions: +```sh +java -jar validator_cli.jar sample-data/.json \ + -ig StructureDefinitions/Source/.json +``` + +Validate against C4BB: +```sh +java -jar validator_cli.jar outputs/.json \ + -ig hl7.fhir.us.carin-bb#2.0.0 +``` diff --git a/apps/bfd-model/bfd-model-idr/StructureDefinitions/Source/Bene-MBI.json b/apps/bfd-model/bfd-model-idr/StructureDefinitions/Source/Bene-MBI.json new file mode 100644 index 0000000000..e6435da00d --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/StructureDefinitions/Source/Bene-MBI.json @@ -0,0 +1,64 @@ +{ + "resourceType": "StructureDefinition", + "id": "BENE_MBI", + "url": "http://hl7.org/fhir/StructureDefinition/BeneficiaryMBIIdentifier", + "name": "BENE_MBI", + "status": "draft", + "fhirVersion": "4.0.1", + "kind": "logical", + "abstract": true, + "type": "BeneficiaryMBIIdentifier", + "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Base", + "derivation": "specialization", + "differential": { + "element": [ + { + "id": "BeneficiaryMBIIdentifier", + "path": "BeneficiaryMBIIdentifier", + "label": "IDR MBI Base Resource. Ignore in DD Generation", + "definition": "BeneficiaryMBIIdentifier definition", + "min": 1, + "max": "1" + }, + { + "id": "BeneficiaryMBIIdentifier.BENE_MBI_ID", + "path": "BeneficiaryMBIIdentifier.BENE_MBI_ID", + "label": "MBI ID", + "definition": "Medicare Beneficiary Identifier", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "BeneficiaryMBIIdentifier.BENE_MBI_EFCTV_DT", + "path": "BeneficiaryMBIIdentifier.BENE_MBI_EFCTV_DT", + "label": "MBI Effective Date", + "definition": "Effective date of this MBI.", + "min": 1, + "max": "1", + "type": [ + { + "code": "dateTime" + } + ] + }, + { + "id": "BeneficiaryMBIIdentifier.BENE_MBI_OBSLT_DT", + "path": "BeneficiaryMBIIdentifier.BENE_MBI_OBSLT_DT", + "label": "MBI Obsolete Date", + "definition": "Date this MBI was marked obsolete.", + "min": 0, + "max": "1", + "type": [ + { + "code": "dateTime" + } + ] + } + ] + } +} diff --git a/apps/bfd-model/bfd-model-idr/StructureDefinitions/Source/Bene.json b/apps/bfd-model/bfd-model-idr/StructureDefinitions/Source/Bene.json new file mode 100644 index 0000000000..1e9dfaaaa1 --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/StructureDefinitions/Source/Bene.json @@ -0,0 +1,338 @@ +{ + "resourceType": "StructureDefinition", + "id": "BENE", + "url": "https://bfd.cms.gov/fhir/StructureDefinition/BENE", + "name": "BENE", + "status": "draft", + "fhirVersion": "4.0.1", + "kind": "logical", + "abstract": true, + "type": "Beneficiary", + "baseDefinition": "http://hl7.org/fhir/StructureDefinition/Base", + "derivation": "specialization", + "differential": { + "element": [ + { + "id": "Beneficiary", + "path": "Beneficiary", + "label": "IDR Beneficiary Base. Ignore in DD Generation", + "definition": "Beneficiary definition", + "min": 1, + "max": "1" + }, + { + "id": "Beneficiary.BENE_1ST_NAME", + "path": "Beneficiary.BENE_1ST_NAME", + "label": "First Name", + "definition": "First name from IDR", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LAST_NAME", + "path": "Beneficiary.BENE_LAST_NAME", + "label": "Last Name", + "definition": "Last name from IDR", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_MIDL_NAME", + "path": "Beneficiary.BENE_MIDL_NAME", + "label": "Last Name", + "definition": "Last name from IDR", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_DOB", + "path": "Beneficiary.BENE_DOB", + "label": "Date of Birth", + "definition": "Date of birth for beneficiary", + "min": 1, + "max": "1", + "type": [ + { + "code": "date" + } + ] + }, + { + "id": "Beneficiary.BENE_DEATH_DT", + "path": "Beneficiary.BENE_DEATH_DT", + "label": "Date of Death", + "definition": "Date of death for beneficiary. Only populated if BENE_VRFY_DEATH_DAY_SW is true", + "min": 1, + "max": "1", + "type": [ + { + "code": "dateTime" + } + ] + }, + { + "id": "Beneficiary.BENE_VRFY_DEATH_DAY_SW", + "path": "Beneficiary.BENE_VRFY_DEATH_DAY_SW", + "label": "Date of Death Verification Switch", + "definition": "Don't trust the date of death unless this is 'true'.", + "min": 1, + "max": "1", + "type": [ + { + "code": "boolean" + } + ] + }, + { + "id": "Beneficiary.mbi", + "path": "Beneficiary.mbi", + "label": "Medicare Beneficiary Identifier (MBI)", + "definition": "Medicare Beneficiary Identifier (MBI) for beneficiary", + "min": 1, + "max": "*", + "type": [ + { + "code": "BeneficiaryMBIIdentifier", + "targetProfile" : ["https://bfd.cms.gov/fhir/StructureDefinition/BENE_MBI"] + } + ] + }, + { + "id": "Beneficiary.XREF_EFCTV_BENE_SK", + "path": "Beneficiary.XREF_EFCTV_BENE_SK", + "label": "Effective Beneficiary SK ", + "definition": "Effective BENE_SK for the individual, representing the XREF_EFCTV_SK", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_SK", + "path": "Beneficiary.BENE_SK", + "label": "Effective Beneficiary SK ", + "definition": "BENE_SK for the individual.", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.ALL_BENE_SKs", + "path": "Beneficiary.ALL_BENE_SKs", + "label": "Beneficiary SK List.", + "definition": "A list of all BENE_SKs for the beneficiary. This list is to be used when querying the claims table.", + "min": 1, + "max": "*", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.lastUpdated", + "path": "Beneficiary.lastUpdated", + "label": "Last Updated time", + "definition": "The time the data utilized from IDR was inserted/updated", + "min": 1, + "max": "1", + "type": [ + { + "code": "date" + } + ] + }, + { + "id": "Beneficiary.GEO_USPS_STATE_CD", + "path": "Beneficiary.GEO_USPS_STATE_CD", + "label": "USPS State Code", + "definition": "USPS State Code", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_ZIP_CD", + "path": "Beneficiary.BENE_ZIP_CD", + "label": "Beneficiary Zip Code", + "definition": "Beneficiary Zip Code", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LINE_1_ADR", + "path": "Beneficiary.BENE_LINE_1_ADR", + "label": "Line 1 of address", + "definition": "Line 1 of address", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LINE_2_ADR", + "path": "Beneficiary.BENE_LINE_2_ADR", + "label": "Line 2 of address", + "definition": "Line 2 of address", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LINE_3_ADR", + "path": "Beneficiary.BENE_LINE_3_ADR", + "label": "Line 3 of address", + "definition": "Line 3 of address", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LINE_4_ADR", + "path": "Beneficiary.BENE_LINE_4_ADR", + "label": "Line 4 of address", + "definition": "Line 4 of address", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LINE_5_ADR", + "path": "Beneficiary.BENE_LINE_5_ADR", + "label": "Line 5 of address", + "definition": "Line 5 of address", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_LINE_6_ADR", + "path": "Beneficiary.BENE_LINE_6_ADR", + "label": "Line 6 of Address", + "definition": "Line 6 of address", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.GEO_ZIP_PLC_NAME", + "path": "Beneficiary.GEO_ZIP_PLC_NAME", + "label": "City Name", + "definition": "City Name of Beneficiary.", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.CNTCT_LANG_CD", + "path": "Beneficiary.CNTCT_LANG_CD", + "label": "Contact Language Code", + "definition": "Contact Language Code for beneficiary. Either English or Spanish. Used for Medicare Handbook today.", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_PHNE_NUM", + "path": "Beneficiary.BENE_PHNE_NUM", + "label": "Beneficiary Phone Number", + "definition": "Beneficiary Phone Number from BENE_HISTRY.", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_SEX_CD", + "path": "Beneficiary.BENE_SEX_CD", + "label": "Beneficiary Sex Code", + "definition": "Beneficiary Sex Code, as recorded by CMS in IDR.", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + }, + { + "id": "Beneficiary.BENE_RACE_CD", + "path": "Beneficiary.BENE_RACE_CD", + "label": "Beneficiary Race Code", + "definition": "Beneficiary Race Code, as recorded by CMS in IDR.", + "min": 1, + "max": "1", + "type": [ + { + "code": "string" + } + ] + } + ] + } +} diff --git a/apps/bfd-model/bfd-model-idr/dictionary-support-yamls/patient.yaml b/apps/bfd-model/bfd-model-idr/dictionary-support-yamls/patient.yaml new file mode 100644 index 0000000000..186ef7f914 --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/dictionary-support-yamls/patient.yaml @@ -0,0 +1,135 @@ +#of note, BENE_SSN_NUM will be consumed by BFD and should be in here, but not as part of the mapping to FHIR. It should only be used for matching, eventually. +- inputPath: Beneficiary.BENE_1ST_NAME + appliesTo: + - Patient + targetElement: BFDPatient.name.given + expectedFHIRPath: Patient.name.given[0] +- inputPath: Beneficiary.BENE_LAST_NAME + appliesTo: + - Patient + targetElement: BFDPatient.name.family + expectedFHIRPath: Patient.name.family +- inputPath: Beneficiary.BENE_MIDL_NAME + appliesTo: + - Patient + targetElement: BFDPatient.name.given + expectedFHIRPath: Patient.name.given[1] +- inputPath: Beneficiary.BENE_DOB + appliesTo: + - Patient + targetElement: BFDPatient.birthDate + expectedFHIRPath: Patient.birthDate +- inputPath: Beneficiary.BENE_DEATH_DT + appliesTo: + - Patient + targetElement: BFDPatient.deceasedDateTime + expectedFHIRPath: Patient.deceasedDateTime +- inputPath: Beneficiary.BENE_VRFY_DEATH_DAY_SW + appliesTo: + - Patient +- inputPath: Beneficiary.mbi + appliesTo: + - Patient + targetElement: BFDPatient.identifier + expectedFHIRPath: Patient.identifier.where(system='http://hl7.org/fhir/sid/us-mbi') +- inputPath: Beneficiary.XREF_EFCTV_BENE_SK + appliesTo: + - Patient + targetElement: BFDPatient.id XOR BFDPatient.link.other.display + expectedFHIRPath: iif(Patient.link.where(type = 'replaced-by').other.exists(),Patient.link.where(type = 'replaced-by').other.reference.substring(8),Patient.id) +- inputPath: Beneficiary.ALL_BENE_SKs + appliesTo: + - Patient + targetElement: BFDPatient.link.other.display OR Patient.id + expectedFHIRPath: Patient.link.other.display.union(Patient.id) +- inputPath: Beneficiary.BENE_SK + appliesTo: + - Patient + targetElement: BFDPatient.id + expectedFHIRPath: Patient.id +- inputPath: Beneficiary.lastUpdated + appliesTo: + - Patient + targetElement: Patient.meta.lastUpdated + expectedFHIRPath: Patient.meta.lastUpdated +- inputPath: Beneficiary.GEO_USPS_STATE_CD + appliesTo: + - Patient + targetElement: BFDPatient. + expectedFHIRPath: Patient.address[0].state +- inputPath: Beneficiary.BENE_ZIP_CD + appliesTo: + - Patient + targetElement: BFDPatient.address.postalCode + expectedFHIRPath: Patient.address[0].postalCode +- inputPath: Beneficiary.BENE_LINE_1_ADR + appliesTo: + - Patient + targetElement: BFDPatient.address.line + expectedFHIRPath: Patient.address[0].line[0] +- inputPath: Beneficiary.BENE_LINE_2_ADR + appliesTo: + - Patient + targetElement: BFDPatient.address.line + expectedFHIRPath: Patient.address[0].line[1] +- inputPath: Beneficiary.BENE_LINE_3_ADR + appliesTo: + - Patient + targetElement: BFDPatient.address.line + expectedFHIRPath: Patient.address[0].line[2] +- inputPath: Beneficiary.BENE_LINE_4_ADR + appliesTo: + - Patient + targetElement: BFDPatient.address.line + expectedFHIRPath: Patient.address[0].line[3] +- inputPath: Beneficiary.BENE_LINE_5_ADR + appliesTo: + - Patient + targetElement: BFDPatient.address.line + expectedFHIRPath: Patient.address[0].line[4] +- inputPath: Beneficiary.BENE_LINE_6_ADR + appliesTo: + - Patient + targetElement: BFDPatient.address.line + expectedFHIRPath: Patient.address[0].line[5] +- inputPath: Beneficiary.GEO_ZIP_PLC_NAME + appliesTo: + - Patient + targetElement: BFDPatient.address.city + expectedFHIRPath: Patient.address[0].city +- inputPath: Beneficiary.CNTCT_LANG_CD + appliesTo: + - Patient + targetElement: BFDPatient.communication.language.coding.code + expectedFHIRPath: Patient.communication.language.coding.where(system='urn:ietf:bcp:47').code +- inputPath: Beneficiary.BENE_PHNE_NUM + appliesTo: + - Patient + targetElement: BFDPatient.telecom.value + expectedFHIRPath: Patient.telecom.where(system='phone').value +- inputPath: Beneficiary.BENE_SEX_CD + appliesTo: + - Patient + targetElement: BFDPatient.gender + expectedFHIRPath: Patient.gender +- inputPath: Beneficiary.BENE_RACE_CD + appliesTo: + - Patient + targetElement: BFDPatient.extension.extension.valueString + expectedFHIRPath: Patient.extension.where(url='http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity' or url='http://hl7.org/fhir/us/core/StructureDefinition/us-core-race') +- inputPath: BeneficiaryMBIIdentifier.BENE_MBI_ID + appliesTo: + - Patient + targetElement: BFDPatient.identifier.value + expectedFHIRPath: Patient.identifier.where(system='http://hl7.org/fhir/sid/us-mbi').value +- inputPath: BeneficiaryMBIIdentifier.BENE_MBI_EFCTV_DT + appliesTo: + - Patient + targetElement: BFDPatient.identifier.period.start + expectedFHIRPath: Patient.identifier.where(system='http://hl7.org/fhir/sid/us-mbi').period.start +- inputPath: BeneficiaryMBIIdentifier.BENE_MBI_OBSLT_DT + appliesTo: + - Patient + targetElement: BFDPatient.identifier.period.end + expectedFHIRPath: Patient.identifier.where(system='http://hl7.org/fhir/sid/us-mbi').period.end + diff --git a/apps/bfd-model/bfd-model-idr/idr-queries/temp-patient-queries.txt b/apps/bfd-model/bfd-model-idr/idr-queries/temp-patient-queries.txt new file mode 100644 index 0000000000..a9dd5f398e --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/idr-queries/temp-patient-queries.txt @@ -0,0 +1,51 @@ +Query 1: +Gets the current beneficiary information, along with a list of BENE_SKs that are applicable, as well as a list of all of their MBIs + +with + bene_filtered as ( + SELECT + bene.*, + bene_history.bene_vrfy_death_day_sw, + ARRAY_AGG (bene.BENE_SK) OVER () AS ALL_BENE_SKs, + ARRAY_AGG (DISTINCT bene.BENE_MBI_ID) OVER () AS ALL_BENE_MBIs, + COALESCE(bene.IDR_UPDT_TS,bene.IDR_INSRT_TS) AS lastUpdated + FROM + IDRC_PRD.CMS_VDM_VIEW_MDCR_PRD.V2_MDCR_BENE bene + JOIN IDRC_PRD.CMS_VDM_VIEW_MDCR_PRD.V2_MDCR_BENE_HSTRY AS bene_history ON bene_history.BENE_SK = bene.BENE_XREF_EFCTV_SK + WHERE + bene.BENE_XREF_EFCTV_SK IN ( + SELECT + bene.BENE_XREF_EFCTV_SK + FROM + IDRC_PRD.CMS_VDM_VIEW_MDCR_PRD.V2_MDCR_BENE bene + WHERE + bene.BENE_MBI_ID = 'mbi' + ) + and bene_history.idr_trans_obslt_ts > '9999-12-30' + ) +SELECT + * +FROM + bene_filtered +WHERE + BENE_XREF_EFCTV_SK = BENE_SK; + + + +Query 2: +Gets the effective dates of each MBI. +WITH latest_bene_mbi AS ( + SELECT + *, + ROW_NUMBER() OVER (PARTITION BY BENE_MBI_ID ORDER BY IDR_TRANS_EFCTV_TS DESC) AS rn + FROM + IDRC_PRD.CMS_VDM_VIEW_MDCR_PRD.V2_MDCR_BENE_MBI_ID + WHERE + BENE_MBI_ID IN ('mbi1', 'mbi2') --ALL_BENE_MBIs from above. +) +SELECT + * +FROM + latest_bene_mbi +WHERE + rn = 1; diff --git a/apps/bfd-model/bfd-model-idr/maps/Patient-Helper.map b/apps/bfd-model/bfd-model-idr/maps/Patient-Helper.map new file mode 100644 index 0000000000..3ec874b916 --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/maps/Patient-Helper.map @@ -0,0 +1,43 @@ +map "https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper" = "patient-support-map" + +//Eventually these should be sourced automagically from IDR on startup. But until then! + +conceptmap "AdministrativeGender" { + prefix s = "https://hl7.org/fhir/string" + prefix t = "http://hl7.org/fhir/4.0/administrative-gender" + + s:0 = t:unknown + s:1 = t:male + s:2 = t:female +} + +conceptmap "PreferredContactLanguage" { + prefix s = "https://hl7.org/fhir/string" + prefix t = "urn:ietf:bcp:47" + + s:"~" = t:unknown + s:ENG = t:en + s:SPA = t:es +} + +conceptmap "USCDIRaceCode" { + prefix s = "https://hl7.org/fhir/string" + prefix t = "https://hl7.org/fhir/string" + + s:1 = t:"2106-3" + s:2 = t:"2054-5" + s:3 = t:"2131-1" + s:4 = t:"2028-9" + s:6 = t:"1002-5" +} + +conceptmap "USCDIRaceDisplay" { + prefix s = "https://hl7.org/fhir/string" + prefix t = "https://hl7.org/fhir/string" + + s:1 = t:"White" + s:2 = t:"Black or African American" + s:3 = t:"Other Race" + s:4 = t:"Asian" + s:6 = t:"American Indian or Alaska Native" +} diff --git a/apps/bfd-model/bfd-model-idr/maps/patient.map b/apps/bfd-model/bfd-model-idr/maps/patient.map new file mode 100644 index 0000000000..cc5cb633dd --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/maps/patient.map @@ -0,0 +1,136 @@ +//See this link for lexer order -> https://github.com/hapifhir/org.hl7.fhir.core/blob/c06051838f9bcd5fc0b552df960f5bf2fcf2dbb4/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java#L757 +//Must appear in order map -> conceptmap -> uses -> imports -> groups +map "https://bfd.cms.gov/MappingLanguage/Resources/Patient" = "BFD-Patient-Map" + + +uses "https://bfd.cms.gov/fhir/StructureDefinition/BENE" alias Bene as source +uses "http://hl7.org/fhir/StructureDefinition/BeneficiaryMBIIdentifier" alias BeneMBI as source +//The first specified target is what the default output will output as the ResourceType +uses "http://hl7.org/fhir/StructureDefinition/Patient" alias BFDPatient as target + + +imports "https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper" + +//This refers to a patient where XREF_BENE_EFCTV_SK == BENE_SK. See notes for the other identity use case. + +group createPatient(source src: Bene, target patient: BFDPatient){ + + src -> patient.name = create('HumanName') as tgtName then{ + src.BENE_1ST_NAME as firstName -> tgtName.given = firstName "Populate first name"; + src.BENE_MIDL_NAME as middleName -> tgtName.given = middleName "Populate middle name"; + src.BENE_LAST_NAME as lastName -> tgtName.family = lastName "Populate last name"; + } "add name"; + src.BENE_DOB as dob -> patient.birthDate = dob "set dob"; + src.BENE_DEATH_DT as dod where (src.BENE_VRFY_DEATH_DAY_SW = "true") -> patient.deceased = dod "Set death date"; + src.BENE_SEX_CD as gender -> patient.gender = translate(gender, 'https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper#AdministrativeGender', 'code'); + + //All except Unknown, Missing, or Hispanic + src.BENE_RACE_CD as race where (race != "~" and race != "0" and race != "5") -> patient.extension = create('Extension') as raceExtension then { + src -> raceExtension.url = "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race" "Set race extension url"; + src -> raceExtension.extension = create('Extension') as raceExtensionExtended then { + src -> raceExtensionExtended.url = "ombCategory" "Set race extension url"; + src -> raceExtensionExtended.value = create('Coding') as valueCoding then{ + src -> valueCoding.system = "urn:oid:2.16.840.1.113883.6.238" "Set race system urn"; + src -> valueCoding.code = translate(race, 'https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper#USCDIRaceCode', "code") "Set code"; + src -> valueCoding.display = translate(race, 'https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper#USCDIRaceDisplay', "code") "Set display"; + } "Create Coding within sub-extension"; + } "Create sub-extension for ombCategory"; + src -> raceExtension.extension = create('Extension') as raceExtensionExtended then { + src -> raceExtensionExtended.url = "text" "Set race extension text url"; + src -> raceExtensionExtended.valueString = translate(race, 'https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper#USCDIRaceDisplay','code') "set value string"; + } "Create sub-extension for text display"; + } "Create race extension"; + + //Missing or unknown + src.BENE_RACE_CD as race where (race = "~" or race = "0") -> patient.extension = create('Extension') as raceExtension then { + src -> raceExtension.url = "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race" "Set race extension url"; + src -> raceExtension.extension = create('Extension') as raceExtensionExtended then { + src -> raceExtensionExtended.url = "ombCategory" "Set race extension url"; + src -> raceExtensionExtended.value = create('Coding') as valueCoding then{ + src -> valueCoding.system = "http://terminology.hl7.org/CodeSystem/v3-NullFlavor" "Set race system urn"; + src -> valueCoding.code = "UNK" "Set code"; + src -> valueCoding.display = "Unknown" "Set display"; + } "Create Coding within sub-extension"; + } "Create sub-extension for ombCategory"; + src -> raceExtension.extension = create('Extension') as raceExtensionExtended then { + src -> raceExtensionExtended.url = "text" "Set race extension text url"; + src -> raceExtensionExtended.valueString = "Unknown" "Set display"; + } "Create sub-extension for text display"; + } "Create race extension"; + + + src.BENE_RACE_CD as race where (race = "5") -> patient.extension = create('Extension') as ethnicityExtension then { + src -> ethnicityExtension.url="http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity" "Set ethnicity extension url"; + src -> ethnicityExtension.extension = create('Extension') as ethnicityExtensionExtended then { + src -> ethnicityExtensionExtended.url = "ombCategory" "Set ethnicity extension url"; + src -> ethnicityExtensionExtended.value = create('Coding') as valueCoding then{ + src -> valueCoding.system = "urn:oid:2.16.840.1.113883.6.238" "Set ethnicity system urn"; + src -> valueCoding.code = "2135-2" "Set code"; + src -> valueCoding.display = "Hispanic or Latino" "Set display"; + } "Create Coding within sub-extension"; + } "Create sub-extension for ombCategory"; + src -> ethnicityExtension.extension = create('Extension') as ethnicityExtensionExtended then { + src -> ethnicityExtensionExtended.url = "text" "Set ethnicity extension text url"; + src -> ethnicityExtensionExtended.valueString = "Hispanic or Latino" "Set display"; + } "Create sub-extension for text display"; + } "create ethnicity extension"; + + + src.BENE_SK as bene_sk -> patient.id = bene_sk "Assign BENE_SK as identifier."; + + src.ALL_BENE_SKs as bene_sks where (bene_sks != src.XREF_EFCTV_BENE_SK) -> patient.link = create('BackboneElement') as patientLink then{ + src -> patientLink.type = "replaces" "replaces type"; + src -> patientLink.other = create('Reference') as tgtReference, + tgtReference.reference = append("Patient/",bene_sks), + tgtReference.display = bene_sks "Set BENE_SK"; + } "Create Patient links"; + + + src.mbi as bene_mbis -> patient.identifier = create('Identifier') as ptIdentifier then SetMBI(bene_mbis,ptIdentifier) "Set Bene MBIs"; + + + src -> patient.meta = create('Meta') as tgtMeta then{ + src.lastUpdated as lastUpdated -> tgtMeta.lastUpdated = lastUpdated "Set lastUpdated"; + src -> tgtMeta.profile = "http://hl7.org/fhir/us/carin-bb/StructureDefinition/C4BB-Patient|2.0.0" "Set C4BB profile"; + src -> tgtMeta.profile = "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient|3.1.1" "Set US Core profile"; + } "add metadata"; + + src -> patient.address = create('Address') as ptAddress then { + src.GEO_USPS_STATE_CD as stateCode -> ptAddress.state = stateCode "Set state code"; + src.BENE_ZIP_CD as zipCode -> ptAddress.postalCode = zipCode "Set zip code"; + src.BENE_LINE_1_ADR as addrLine where (addrLine.length()>0) -> ptAddress.line = addrLine "Set address line 1"; + src.BENE_LINE_2_ADR as addrLine where (addrLine.length()>0) -> ptAddress.line = addrLine "Set address line 2"; + src.BENE_LINE_3_ADR as addrLine where (addrLine.length()>0) -> ptAddress.line = addrLine "Set address line 3"; + src.BENE_LINE_4_ADR as addrLine where (addrLine.length()>0) -> ptAddress.line = addrLine "Set address line 4"; + src.BENE_LINE_5_ADR as addrLine where (addrLine.length()>0) -> ptAddress.line = addrLine "Set address line 5"; + src.BENE_LINE_6_ADR as addrLine where (addrLine.length()>0) -> ptAddress.line = addrLine "Set address line 6"; + src.GEO_ZIP_PLC_NAME as cityName -> ptAddress.city = cityName "Set city name"; + } "Set patient address"; + + src -> patient.telecom = create('ContactPoint') as ptTele then{ + src.BENE_PHNE_NUM as phoneNumber -> ptTele.value = phoneNumber "Set phone number"; + src -> ptTele.use = "home" "Set phone number use"; + src -> ptTele.system = "phone" "Set phone as system"; + } "Set beneficary contact info"; + + src -> patient.communication = create('BackboneElement') as commsBackbone then{ + src -> commsBackbone.language = create('CodeableConcept') as langCC then{ + src.CNTCT_LANG_CD as langCode -> langCC.coding = translate(langCode,'https://bfd.cms.gov/MappingLanguage/Maps/Patient-Helper#PreferredContactLanguage','coding') "set coding"; + + }"Create CodeableConcept for Language."; + src -> commsBackbone.preferred=true "set preference as true"; + } "Create backbone element for communication"; +} + +group SetMBI(source src : BeneMBI, target tgt : Identifier) { + src -> tgt.type = create('CodeableConcept') as idCC, + idCC.coding = create('Coding') as tempCode, + tempCode.system = "http://terminology.hl7.org/CodeSystem/v2-0203", + tempCode.code = "MB", + tgt.system = "http://hl7.org/fhir/sid/us-mbi" "Set identifier system and value"; + src.BENE_MBI_ID as mbi -> tgt.value = mbi "Set identifier Value"; + src -> tgt.period = create('Period') as tgtPeriod then { + src.BENE_MBI_EFCTV_DT as start-> tgtPeriod.start = start "Add MBI start date"; + src.BENE_MBI_OBSLT_DT as end -> tgtPeriod.end = end "Add MBI end date."; + } "Mark start and end dates of MBI"; +} diff --git a/apps/bfd-model/bfd-model-idr/sample-data/BeneficiarySample.json b/apps/bfd-model/bfd-model-idr/sample-data/BeneficiarySample.json new file mode 100644 index 0000000000..7788575706 --- /dev/null +++ b/apps/bfd-model/bfd-model-idr/sample-data/BeneficiarySample.json @@ -0,0 +1,29 @@ +{ + "resourceType": "Beneficiary", + "BENE_1ST_NAME": "Frankie", + "BENE_LAST_NAME": "Sheep", + "BENE_MIDL_NAME": "Le Petit Prince", + "BENE_DOB": "1995-03-11", + "BENE_DEATH_DT": "2024-03-11", + "BENE_VRFY_DEATH_DAY_SW": "true", + "mbi": [ + {"BENE_MBI_ID":"AAA1AA0AA11","BENE_MBI_EFCTV_DT":"2017-05-11","BENE_MBI_OBSLT_DT":"2017-07-01"}, + {"BENE_MBI_ID":"ABB2BB0BB22","BENE_MBI_EFCTV_DT":"2017-07-02"}], + "XREF_EFCTV_BENE_SK": "123456789", + "BENE_SK": "123456789", + "ALL_BENE_SKs": ["123456789","234567891"], + "lastUpdated": "2020-01-07T03:02:28.000000Z", + "GEO_USPS_STATE_CD": "TX", + "BENE_ZIP_CD": "77843", + "BENE_LINE_1_ADR": "600 John Kimbrough Blvd", + "BENE_LINE_2_ADR": "TEST for line 2", + "BENE_LINE_3_ADR": "", + "BENE_LINE_4_ADR": "", + "BENE_LINE_5_ADR": "", + "BENE_LINE_6_ADR": "", + "GEO_ZIP_PLC_NAME": "College Station", + "CNTCT_LANG_CD": "ENG", + "BENE_PHNE_NUM": "1-800-MEDICARE", + "BENE_SEX_CD": "2", + "BENE_RACE_CD": "5" +}