use of org.hl7.fhir.dstu3.model.Bundle in project loinc2hpo by monarch-initiative.
the class FhirResourceRetriever method retrievePatientFromServer.
/**
* Retrieve a patient from the reference field of an observation
* @param subject
* @return
*/
public static Patient retrievePatientFromServer(Reference subject) throws SubjectNotFoundException, AmbiguousSubjectException {
List<Patient> patients = new ArrayList<>();
if (subject.hasReference()) {
String ref = subject.getReference();
if (!ref.startsWith(BASEURL) && ref.startsWith("Patient")) {
ref = BASEURL + "/" + ref;
}
Bundle patientBundle = client.search().byUrl(ref).returnBundle(Bundle.class).execute();
while (true) {
patientBundle.getEntry().forEach(p -> patients.add((Patient) p.getResource()));
if (patientBundle.getLink(IBaseBundle.LINK_NEXT) != null) {
patientBundle = client.loadPage().next(patientBundle).execute();
} else {
break;
}
}
} else if (subject.hasIdentifier()) {
Identifier identifier = subject.getIdentifier();
// TODO: find patient through the identifier
}
if (patients.size() == 1) {
return patients.iterator().next();
} else if (patients.isEmpty()) {
throw new SubjectNotFoundException("Expect one subject, but found none");
} else {
throw new AmbiguousSubjectException("Except one subject, but found multiple");
}
}
use of org.hl7.fhir.dstu3.model.Bundle in project loinc2hpo by monarch-initiative.
the class FhirResourceRetriever method retrieveObservationFromServer.
/**
* @TODO: implement it
* retrieve a patient's observations from FHIR server
* @param patient
* @return
*/
public static List<Observation> retrieveObservationFromServer(Patient patient) {
List<Observation> observationList = new ArrayList<>();
String id = patient.getId();
if (id != null) {
Bundle observationBundle = client.search().forResource(Observation.class).where(new ReferenceClientParam("subject").hasId(id)).prettyPrint().returnBundle(Bundle.class).execute();
while (true) {
observationBundle.getEntry().forEach(p -> observationList.add((Observation) p.getResource()));
if (observationBundle.getLink(IBaseBundle.LINK_NEXT) != null) {
observationBundle = client.loadPage().next(observationBundle).execute();
} else {
break;
}
}
}
return observationList;
}
use of org.hl7.fhir.dstu3.model.Bundle in project gpconnect-demonstrator by nhsconnect.
the class PatientResourceProvider method addWarningIssue.
/**
* see
* https://gpconnect-1-2-4.netlify.com/accessrecord_structured_development_version_compatibility.html
* add an issue to the OperationOutcome to be returned in a successful
* response bundle this is for forward compatibility as specified in 1.2.4
*
* @param param
* @param paramPart
* @param issueType
* @param details lower level details to be added to the text element
*/
private void addWarningIssue(ParametersParameterComponent param, ParametersParameterComponent paramPart, IssueType issueType, String details) {
if (operationOutcome == null) {
createOperationOutcome();
}
OperationOutcomeIssueComponent issue = new OperationOutcomeIssueComponent();
issue.setSeverity(OperationOutcome.IssueSeverity.WARNING);
CodeableConcept codeableConcept = new CodeableConcept();
Coding coding = new Coding();
coding.setSystem(VS_GPC_ERROR_WARNING_CODE);
switch(issueType) {
case NOTSUPPORTED:
issue.setCode(issueType);
coding.setCode(SystemCode.NOT_IMPLEMENTED);
coding.setDisplay("Not implemented");
break;
case REQUIRED:
issue.setCode(issueType);
coding.setCode(SystemCode.PARAMETER_NOT_FOUND);
coding.setDisplay("Parameter not found");
break;
case INVALID:
issue.setCode(issueType);
coding.setCode(SystemCode.INVALID_PARAMETER);
coding.setDisplay("Invalid Parameter");
break;
}
codeableConcept.addCoding(coding);
issue.setDetails(codeableConcept);
String locus = paramPart != null ? "." + paramPart.getName() : "";
issue.setDiagnostics(param.getName() + locus);
if (details == null) {
// mod to remove more informative text which was off spec
codeableConcept.setText(param.getName() + locus + " is an unrecognised parameter");
} else {
codeableConcept.setText(details);
}
operationOutcome.addIssue(issue);
}
use of org.hl7.fhir.dstu3.model.Bundle in project gpconnect-demonstrator by nhsconnect.
the class PopulateSlotBundle method populateBundle.
/**
* @param bundle Bundle resource to populate
* @param operationOutcome
* @param planningHorizonStart Date
* @param planningHorizonEnd Date
* @param actorPractitioner boolean
* @param actorLocation boolean
* @param managingOrganisation boolean
* @param bookingOdsCode String
* @param bookingOrgType String eg "urgent-care"
*/
public void populateBundle(Bundle bundle, OperationOutcome operationOutcome, Date planningHorizonStart, Date planningHorizonEnd, boolean actorPractitioner, boolean actorLocation, boolean managingOrganisation, String bookingOdsCode, String bookingOrgType) {
bundle.getMeta().addProfile(SystemURL.SD_GPC_SRCHSET_BUNDLE);
// TODO remove hard coding pick up from providerRouting.json ?
final String OUR_ODS_CODE = "A20047";
// find all locations for this ODS practice code and construct Resources for them
// #144 generalise to handle 1..n locations for a practice
HashMap<String, BundleEntryComponent> locationEntries = new HashMap<>();
for (LocationDetails aLocationDetail : locationSearch.findAllLocations()) {
if (aLocationDetail.getOrgOdsCode().equals(OUR_ODS_CODE)) {
Location aLocationResource = locationResourceProvider.getLocationById(new IdType(aLocationDetail.getId()));
BundleEntryComponent locationEntry = new BundleEntryComponent();
locationEntry.setResource(aLocationResource);
// #202 use full urls
// #215 full url removed completely
// locationEntry.setFullUrl(serverBaseUrl + "Location/" + aLocationResource.getIdElement().getIdPart());
locationEntries.put(aLocationResource.getIdElement().getIdPart(), locationEntry);
}
}
// find the provider organization from the ods code
List<OrganizationDetails> ourOrganizationsDetails = organizationSearch.findOrganizationDetailsByOrgODSCode(OUR_ODS_CODE);
OrganizationDetails ourOrganizationDetails = null;
if (!ourOrganizationsDetails.isEmpty()) {
// at 1.2.2 these are added regardless of the status of the relevant parameter
// Just picks the first organization. There should only be one.
ourOrganizationDetails = ourOrganizationsDetails.get(0);
} else {
// do something here .. should never happen
}
// find the bookng organization from the ods code
List<OrganizationDetails> bookingOrganizationsDetails = organizationSearch.findOrganizationDetailsByOrgODSCode(bookingOdsCode);
OrganizationDetails bookingOrganizationDetails = null;
if (!bookingOrganizationsDetails.isEmpty()) {
// at 1.2.2 these are added regardless of the status of the relevant parameter
// Just picks the first organization. There should only be one.
bookingOrganizationDetails = bookingOrganizationsDetails.get(0);
}
HashSet<BundleEntryComponent> addedSchedule = new HashSet<>();
HashSet<BundleEntryComponent> addedLocation = new HashSet<>();
HashSet<String> addedPractitioner = new HashSet<>();
HashSet<String> addedOrganization = new HashSet<>();
// issue #165 don't add duplicate slots, hashSet contains slot id as String
HashSet<String> addedSlot = new HashSet<>();
// #144 process all locations
for (String locationId : locationEntries.keySet()) {
// process the schedules
for (Schedule schedule : scheduleResourceProvider.getSchedulesForLocationId(locationId, planningHorizonStart, planningHorizonEnd)) {
boolean slotsAdded = false;
schedule.getMeta().addProfile(SystemURL.SD_GPC_SCHEDULE);
BundleEntryComponent scheduleEntry = new BundleEntryComponent();
scheduleEntry.setResource(schedule);
// #202 use full urls
// #215 full url removed completely
// scheduleEntry.setFullUrl(serverBaseUrl + "Schedule/" + schedule.getIdElement().getIdPart());
// This Set does not work as expected because Slot does not implement hashCode
// so the second set call to getSlots returns different objects with the same slot id
Set<Slot> slots = new HashSet<>();
//
if (bookingOrgType.isEmpty() && bookingOdsCode.isEmpty()) {
// OPTION 1 get slots Specfying neither org type nor org code
slots.addAll(slotResourceProvider.getSlotsForScheduleIdNoOrganizationTypeOrODS(schedule.getIdElement().getIdPart(), planningHorizonStart, planningHorizonEnd));
} else if (!bookingOrgType.isEmpty() && bookingOdsCode.isEmpty()) {
// OPTION 2 organisation type only
for (Slot slot : slotResourceProvider.getSlotsForScheduleId(schedule.getIdElement().getIdPart(), planningHorizonStart, planningHorizonEnd)) {
SlotDetail slotDetail = slotSearch.findSlotByID(Long.parseLong(slot.getId()));
if (slotDetail.getOrganizationIds().isEmpty() && (slotDetail.getOrganizationTypes().isEmpty() || slotDetail.getOrganizationTypes().contains(bookingOrgType))) {
slots.add(slot);
}
}
} else if (!bookingOdsCode.isEmpty() && bookingOrgType.isEmpty()) {
// OPTION 3 org code only
for (Slot slot : slotResourceProvider.getSlotsForScheduleId(schedule.getIdElement().getIdPart(), planningHorizonStart, planningHorizonEnd)) {
SlotDetail slotDetail = slotSearch.findSlotByID(Long.parseLong(slot.getId()));
if (slotDetail.getOrganizationTypes().isEmpty() && (slotDetail.getOrganizationIds().isEmpty() || bookingOrganizationDetails != null && slotDetail.getOrganizationIds().contains(bookingOrganizationDetails.getId()))) {
slots.add(slot);
}
}
} else if (!bookingOrgType.isEmpty() && !bookingOdsCode.isEmpty()) {
// OPTION 4 both org code and org type
for (Slot slot : slotResourceProvider.getSlotsForScheduleId(schedule.getIdElement().getIdPart(), planningHorizonStart, planningHorizonEnd)) {
SlotDetail slotDetail = slotSearch.findSlotByID(Long.parseLong(slot.getId()));
if (((slotDetail.getOrganizationTypes().isEmpty() || slotDetail.getOrganizationTypes().contains(bookingOrgType))) && (slotDetail.getOrganizationIds().isEmpty() || bookingOrganizationDetails != null && slotDetail.getOrganizationIds().contains(bookingOrganizationDetails.getId()))) {
slots.add(slot);
}
}
}
// added at 1.2.2 add the organisation but only if there are some slots available
if (slots.size() > 0 && ourOrganizationDetails != null && !addedOrganization.contains(ourOrganizationDetails.getOrgCode())) {
addOrganisation(ourOrganizationDetails, bundle);
addedOrganization.add(ourOrganizationDetails.getOrgCode());
}
String freeBusyType = "FREE";
// process all the slots to be returned
for (Slot slot : slots) {
if (freeBusyType.equalsIgnoreCase(slot.getStatus().toString())) {
String slotId = slot.getIdElement().getIdPart();
if (!addedSlot.contains(slotId)) {
BundleEntryComponent slotEntry = new BundleEntryComponent();
slotEntry.setResource(slot);
// #202 use full urls
// #215 full url removed completely
// slotEntry.setFullUrl(serverBaseUrl + "Slot/" + slotId);
bundle.addEntry(slotEntry);
addedSlot.add(slotId);
slotsAdded = true;
}
if (!addedSchedule.contains(scheduleEntry)) {
// only add a schedule if there's a reference to it and only add it once
bundle.addEntry(scheduleEntry);
addedSchedule.add(scheduleEntry);
}
if (actorLocation == true) {
// only add a unique location once
if (!addedLocation.contains(locationEntries.get(locationId))) {
bundle.addEntry(locationEntries.get(locationId));
addedLocation.add(locationEntries.get(locationId));
}
}
}
// if free/busy status matches
}
// # 193 for each schedule only add a practitioner if there have been some slots added.
if (slotsAdded) {
// practitioners for this schedule
List<Reference> practitionerActors = scheduleResourceProvider.getPractitionerReferences(schedule);
if (!practitionerActors.isEmpty()) {
for (Reference practitionerActor : practitionerActors) {
Practitioner practitioner = practitionerResourceProvider.getPractitionerById((IdType) practitionerActor.getReferenceElement());
if (practitioner == null) {
Coding errorCoding = new Coding().setSystem(SystemURL.VS_GPC_ERROR_WARNING_CODE).setCode(SystemCode.REFERENCE_NOT_FOUND);
CodeableConcept errorCodableConcept = new CodeableConcept().addCoding(errorCoding);
errorCodableConcept.setText("Invalid Reference");
operationOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setCode(IssueType.NOTFOUND).setDetails(errorCodableConcept);
throw new ResourceNotFoundException("Practitioner Reference returning null");
}
if (actorPractitioner) {
if (!addedPractitioner.contains(practitioner.getIdElement().getIdPart())) {
addPractitioner(practitioner, bundle);
addedPractitioner.add(practitioner.getIdElement().getIdPart());
}
}
}
// for practitioner
}
// if non empty practitioner list
}
// if slots added
}
// for schedules
}
// for location
}
use of org.hl7.fhir.dstu3.model.Bundle in project gpconnect-demonstrator by nhsconnect.
the class PopulateSlotBundle method addPractitioner.
// populateBundle
/**
* Add practitioner to Bundle
*
* @param practitioner
* @param bundle
*/
private void addPractitioner(Practitioner practitioner, Bundle bundle) {
BundleEntryComponent practionerEntry = new BundleEntryComponent();
practionerEntry.setResource(practitioner);
// #202 use full urls
// #215 full url removed completely
// practionerEntry.setFullUrl(serverBaseUrl + "Practitioner/" + practitioner.getIdElement().getIdPart());
bundle.addEntry(practionerEntry);
}
Aggregations