
001package ca.uhn.fhir.jpa.provider.r4; 002 003import ca.uhn.fhir.context.FhirContext; 004import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; 005import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; 006import ca.uhn.fhir.model.primitive.IdDt; 007import ca.uhn.fhir.rest.param.StringParam; 008import ca.uhn.fhir.rest.param.TokenOrListParam; 009import ca.uhn.fhir.util.ParametersUtil; 010import com.google.common.collect.Lists; 011import org.hl7.fhir.instance.model.api.IBaseParameters; 012import org.hl7.fhir.instance.model.api.IBaseResource; 013import org.hl7.fhir.r4.model.CodeableConcept; 014import org.hl7.fhir.r4.model.Coding; 015import org.hl7.fhir.r4.model.Coverage; 016import org.hl7.fhir.r4.model.Identifier; 017import org.hl7.fhir.r4.model.Parameters; 018import org.hl7.fhir.r4.model.Patient; 019import org.hl7.fhir.r4.model.Reference; 020import org.springframework.beans.factory.annotation.Autowired; 021 022import java.util.List; 023import java.util.Optional; 024 025import static ca.uhn.fhir.rest.api.Constants.PARAM_MEMBER_PATIENT; 026import static ca.uhn.fhir.rest.api.Constants.PARAM_NEW_COVERAGE; 027 028/* 029 * #%L 030 * HAPI FHIR JPA Server 031 * %% 032 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 033 * %% 034 * Licensed under the Apache License, Version 2.0 (the "License"); 035 * you may not use this file except in compliance with the License. 036 * You may obtain a copy of the License at 037 * 038 * http://www.apache.org/licenses/LICENSE-2.0 039 * 040 * Unless required by applicable law or agreed to in writing, software 041 * distributed under the License is distributed on an "AS IS" BASIS, 042 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 043 * See the License for the specific language governing permissions and 044 * limitations under the License. 045 * #L% 046 */ 047 048public class MemberMatcherR4Helper { 049 050 private static final String OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM = "http://terminology.hl7.org/CodeSystem/v2-0203"; 051 private static final String OUT_COVERAGE_IDENTIFIER_CODE = "UMB"; 052 private static final String OUT_COVERAGE_IDENTIFIER_TEXT = "Member Number"; 053 private static final String COVERAGE_TYPE = "Coverage"; 054 055 private final FhirContext myFhirContext; 056 057 @Autowired 058 private IFhirResourceDao<Coverage> myCoverageDao; 059 060 @Autowired 061 private IFhirResourceDao<Patient> myPatientDao; 062 063 064 public MemberMatcherR4Helper(FhirContext theContext) { 065 myFhirContext = theContext; 066 } 067 068 /** 069 * Find Coverage matching the received member (Patient) by coverage id or by coverage identifier 070 * Matching by member patient demographics is not supported. 071 */ 072 public Optional<Coverage> findMatchingCoverage(Coverage theCoverageToMatch) { 073 // search by received old coverage id 074 List<IBaseResource> foundCoverages = findCoverageByCoverageId(theCoverageToMatch); 075 if (foundCoverages.size() == 1 && isCoverage(foundCoverages.get(0))) { 076 return Optional.of( (Coverage) foundCoverages.get(0) ); 077 } 078 079 // search by received old coverage identifier 080 foundCoverages = findCoverageByCoverageIdentifier(theCoverageToMatch); 081 if (foundCoverages.size() == 1 && isCoverage(foundCoverages.get(0))) { 082 return Optional.of( (Coverage) foundCoverages.get(0) ); 083 } 084 085 return Optional.empty(); 086 } 087 088 089 private List<IBaseResource> findCoverageByCoverageIdentifier(Coverage theCoverageToMatch) { 090 TokenOrListParam identifierParam = new TokenOrListParam(); 091 for (Identifier identifier : theCoverageToMatch.getIdentifier()) { 092 identifierParam.add(identifier.getSystem(), identifier.getValue()); 093 } 094 095 SearchParameterMap paramMap = new SearchParameterMap() 096 .add("identifier", identifierParam); 097 ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap); 098 099 return retVal.getAllResources(); 100 } 101 102 103 private boolean isCoverage(IBaseResource theIBaseResource) { 104 return theIBaseResource.fhirType().equals(COVERAGE_TYPE); 105 } 106 107 108 private List<IBaseResource> findCoverageByCoverageId(Coverage theCoverageToMatch) { 109 SearchParameterMap paramMap = new SearchParameterMap() 110 .add("_id", new StringParam(theCoverageToMatch.getId())); 111 ca.uhn.fhir.rest.api.server.IBundleProvider retVal = myCoverageDao.search(paramMap); 112 113 return retVal.getAllResources(); 114 } 115 116 117 public Parameters buildSuccessReturnParameters(Patient theMemberPatient, Coverage theCoverage) { 118 IBaseParameters parameters = ParametersUtil.newInstance(myFhirContext); 119 ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_MEMBER_PATIENT, theMemberPatient); 120 ParametersUtil.addParameterToParameters(myFhirContext, parameters, PARAM_NEW_COVERAGE, theCoverage); 121 return (Parameters) parameters; 122 } 123 124 125 public void addMemberIdentifierToMemberPatient(Patient theMemberPatient, Identifier theNewIdentifier) { 126 Coding coding = new Coding() 127 .setSystem(OUT_COVERAGE_IDENTIFIER_CODE_SYSTEM) 128 .setCode(OUT_COVERAGE_IDENTIFIER_CODE) 129 .setDisplay(OUT_COVERAGE_IDENTIFIER_TEXT) 130 .setUserSelected(false); 131 132 CodeableConcept concept = new CodeableConcept() 133 .setCoding(Lists.newArrayList(coding)) 134 .setText(OUT_COVERAGE_IDENTIFIER_TEXT); 135 136 Identifier newIdentifier = new Identifier() 137 .setUse(Identifier.IdentifierUse.USUAL) 138 .setType(concept) 139 .setSystem(theNewIdentifier.getSystem()) 140 .setValue(theNewIdentifier.getValue()); 141 142 theMemberPatient.addIdentifier(newIdentifier); 143 } 144 145 146 public Optional<Patient> getBeneficiaryPatient(Coverage theCoverage) { 147 if (theCoverage.getBeneficiaryTarget() == null && theCoverage.getBeneficiary() == null) { 148 return Optional.empty(); 149 } 150 151 if (theCoverage.getBeneficiaryTarget() != null 152 && ! theCoverage.getBeneficiaryTarget().getIdentifier().isEmpty()) { 153 return Optional.of(theCoverage.getBeneficiaryTarget()); 154 } 155 156 Reference beneficiaryRef = theCoverage.getBeneficiary(); 157 if (beneficiaryRef == null) { 158 return Optional.empty(); 159 } 160 161 if (beneficiaryRef.getResource() != null) { 162 return Optional.of((Patient) beneficiaryRef.getResource()); 163 } 164 165 if (beneficiaryRef.getReference() == null) { 166 return Optional.empty(); 167 } 168 169 Patient beneficiary = myPatientDao.read(new IdDt(beneficiaryRef.getReference())); 170 return Optional.ofNullable(beneficiary); 171 } 172}