use of org.hl7.fhir.r4.model.CodeableConcept in project gpconnect-demonstrator by nhsconnect.
the class FhirSectionBuilder method buildFhirSection.
public static SectionComponent buildFhirSection(Page page) {
Coding coding = new Coding().setSystem(SystemURL.VS_GPC_RECORD_SECTION).setCode(page.getCode()).setDisplay(page.getName());
CodeableConcept codableConcept = new CodeableConcept().addCoding(coding);
codableConcept.setText(page.getName());
Narrative narrative = new Narrative();
narrative.setStatus(NarrativeStatus.GENERATED);
narrative.setDivAsString(createHtmlContent(page));
SectionComponent sectionComponent = new SectionComponent();
sectionComponent.setCode(codableConcept);
sectionComponent.setTitle(page.getName()).setCode(codableConcept).setText(narrative);
return sectionComponent;
}
use of org.hl7.fhir.r4.model.CodeableConcept 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.r4.model.CodeableConcept in project gpconnect-demonstrator by nhsconnect.
the class StructuredAllergyIntoleranceBuilder method buildStructuredAllergyIntolerence.
public Bundle buildStructuredAllergyIntolerence(String NHS, Set<String> practitionerIds, Bundle bundle, Boolean includedResolved) {
List<StructuredAllergyIntoleranceEntity> allergyData = structuredAllergySearch.getAllergyIntollerence(NHS);
ListResource activeList = initiateListResource(NHS, ACTIVE_ALLERGIES_DISPLAY, allergyData);
ListResource resolvedList = initiateListResource(NHS, RESOLVED_ALLERGIES_DISPLAY, allergyData);
// This is patient 5 example 2 only
if (allergyData.size() == 1 && allergyData.get(0).getClinicalStatus().equals(SystemConstants.NO_KNOWN)) {
StructuredAllergyIntoleranceEntity noKnownAllergy = allergyData.get(0);
// #214 had incorrect code and value for no known allergies
CodeableConcept noKnownAllergies = createCoding(SystemURL.VS_LIST_EMPTY_REASON_CODE, NO_CONTENT_RECORDED, NO_CONTENT_RECORDED_DISPLAY);
noKnownAllergies.setText("No Known Allergies");
// activeList.setEmptyReason(noKnownAllergies);
// see spec example 2 no known allergies positively asserted
Reference patient = new Reference(SystemConstants.PATIENT_REFERENCE_URL + allergyData.get(0).getPatientRef());
String noKnownAllergyId = noKnownAllergy.getGuid();
Reference allergyIntolerance = new Reference("AllergyIntolerance/" + noKnownAllergyId);
Resource noKnownAllergyResource = createNoKnownAllergy(noKnownAllergy);
activeList.setSubject(patient);
// reference to AllergyIntolerance item
activeList.addEntry().setItem(allergyIntolerance);
activeList.setOrderedBy(createCoding(SystemURL.CS_LIST_ORDER, "event-date", "Sorted by Event Date"));
bundle.addEntry().setResource(activeList);
bundle.addEntry().setResource(noKnownAllergyResource);
if (includedResolved) {
resolvedList.setSubject(patient);
resolvedList.setEmptyReason(noKnownAllergies);
bundle.addEntry().setResource(resolvedList);
}
return bundle;
}
for (StructuredAllergyIntoleranceEntity allergyIntoleranceEntity : allergyData) {
AllergyIntolerance allergyIntolerance = new AllergyIntolerance();
allergyIntolerance.setOnset(new DateTimeType(allergyIntoleranceEntity.getOnSetDateTime()));
allergyIntolerance.setMeta(createMeta(SystemURL.SD_CC_ALLERGY_INTOLERANCE));
allergyIntolerance.setId(allergyIntoleranceEntity.getId().toString());
List<Identifier> identifiers = new ArrayList<>();
Identifier identifier1 = new Identifier().setSystem("https://fhir.nhs.uk/Id/cross-care-setting-identifier").setValue(allergyIntoleranceEntity.getGuid());
identifiers.add(identifier1);
allergyIntolerance.setIdentifier(identifiers);
if (allergyIntoleranceEntity.getClinicalStatus().equals(SystemConstants.ACTIVE)) {
allergyIntolerance.setClinicalStatus(AllergyIntoleranceClinicalStatus.ACTIVE);
} else {
allergyIntolerance.setClinicalStatus(AllergyIntoleranceClinicalStatus.RESOLVED);
}
if (allergyIntoleranceEntity.getCategory().equals(SystemConstants.MEDICATION)) {
allergyIntolerance.addCategory(AllergyIntoleranceCategory.MEDICATION);
} else {
allergyIntolerance.addCategory(AllergyIntoleranceCategory.ENVIRONMENT);
}
allergyIntolerance.setVerificationStatus(AllergyIntoleranceVerificationStatus.UNCONFIRMED);
// CODE
codeableConceptBuilder.addConceptCode(SystemConstants.SNOMED_URL, allergyIntoleranceEntity.getConceptCode(), allergyIntoleranceEntity.getConceptDisplay()).addDescription(allergyIntoleranceEntity.getDescCode(), allergyIntoleranceEntity.getDescDisplay()).addTranslation(allergyIntoleranceEntity.getCodeTranslationRef());
allergyIntolerance.setCode(codeableConceptBuilder.build());
codeableConceptBuilder.clear();
allergyIntolerance.setAssertedDate(allergyIntoleranceEntity.getAssertedDate());
Reference patient = new Reference(SystemConstants.PATIENT_REFERENCE_URL + allergyIntoleranceEntity.getPatientRef());
allergyIntolerance.setPatient(patient);
Annotation noteAnnotation = new Annotation(new StringType(allergyIntoleranceEntity.getNote()));
allergyIntolerance.setNote(Collections.singletonList(noteAnnotation));
AllergyIntoleranceReactionComponent reaction = new AllergyIntoleranceReactionComponent();
// MANIFESTATION
List<CodeableConcept> theManifestation = new ArrayList<>();
codeableConceptBuilder.addConceptCode(SystemConstants.SNOMED_URL, allergyIntoleranceEntity.getManifestationCoding(), allergyIntoleranceEntity.getManifestationDisplay()).addDescription(allergyIntoleranceEntity.getManifestationDescCoding(), allergyIntoleranceEntity.getManifestationDescDisplay()).addTranslation(allergyIntoleranceEntity.getManTranslationRef());
theManifestation.add(codeableConceptBuilder.build());
codeableConceptBuilder.clear();
reaction.setManifestation(theManifestation);
reaction.setDescription(allergyIntoleranceEntity.getNote());
// SEVERITY
try {
reaction.setSeverity(AllergyIntoleranceSeverity.fromCode(allergyIntoleranceEntity.getSeverity()));
} catch (FHIRException e) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Unknown severity: " + allergyIntoleranceEntity.getSeverity()), SystemCode.INVALID_RESOURCE, IssueType.INVALID);
}
// EXPOSURE
CodeableConcept exposureRoute = new CodeableConcept();
reaction.setExposureRoute(exposureRoute);
allergyIntolerance.addReaction(reaction);
// RECORDER
final Reference refValue = new Reference();
final Identifier identifier = new Identifier();
final String recorder = allergyIntoleranceEntity.getRecorder();
// This is just an example to demonstrate using Reference element instead of Identifier element
if (recorder.equals(patient2NhsNo.trim())) {
Reference rec = new Reference(SystemConstants.PATIENT_REFERENCE_URL + allergyIntoleranceEntity.getPatientRef());
allergyIntolerance.setRecorder(rec);
} else if (patientRepository.findByNhsNumber(recorder) != null) {
identifier.setSystem(SystemURL.ID_NHS_NUMBER);
identifier.setValue(recorder);
refValue.setIdentifier(identifier);
allergyIntolerance.setRecorder(refValue);
} else if (practitionerSearch.findPractitionerByUserId(recorder) != null) {
refValue.setReference("Practitioner/" + recorder);
allergyIntolerance.setRecorder(refValue);
practitionerIds.add(recorder);
}
// CLINICAL STATUS
List<Extension> extensions = new ArrayList<>();
if (allergyIntolerance.getClinicalStatus().getDisplay().contains("Active")) {
listResourceBuilder(activeList, allergyIntolerance, false);
bundle.addEntry().setResource(allergyIntolerance);
} else if (allergyIntolerance.getClinicalStatus().getDisplay().equals("Resolved") && includedResolved.equals(true)) {
listResourceBuilder(resolvedList, allergyIntolerance, true);
allergyIntolerance.setLastOccurrence(allergyIntoleranceEntity.getEndDate());
final Extension allergyEndExtension = createAllergyEndExtension(allergyIntoleranceEntity);
extensions.add(allergyEndExtension);
}
if (!extensions.isEmpty()) {
allergyIntolerance.setExtension(extensions);
}
// ASSERTER
Reference asserter = allergyIntolerance.getAsserter();
if (asserter != null && asserter.getReference() != null && asserter.getReference().startsWith("Practitioner")) {
String[] split = asserter.getReference().split("/");
practitionerIds.add(split[1]);
}
}
if (!activeList.hasEntry()) {
addEmptyListNote(activeList);
addEmptyReasonCode(activeList);
}
bundle.addEntry().setResource(activeList);
if (includedResolved && !resolvedList.hasEntry()) {
addEmptyListNote(resolvedList);
addEmptyReasonCode(resolvedList);
}
if (includedResolved) {
bundle.addEntry().setResource(resolvedList);
}
return bundle;
}
use of org.hl7.fhir.r4.model.CodeableConcept in project gpconnect-demonstrator by nhsconnect.
the class StructuredAllergyIntoleranceBuilder method createNoKnownAllergy.
/**
* This relates to the positively asserted this patient has no know
* allergies as opposed to the the negatively asserted no allergies recorded
* patient 5 example 2 from the spec
*
* @param allergyIntoleranceEntity object from the db
* @return the allergy intolerance resource
*/
private AllergyIntolerance createNoKnownAllergy(StructuredAllergyIntoleranceEntity allergyIntoleranceEntity) {
AllergyIntolerance allergyIntolerance = new AllergyIntolerance();
allergyIntolerance.setId(allergyIntoleranceEntity.getGuid());
allergyIntolerance.setAssertedDate(allergyIntoleranceEntity.getAssertedDate());
// db has clinical status of "no known" which is not a valid value
allergyIntolerance.setClinicalStatus(AllergyIntoleranceClinicalStatus.ACTIVE);
allergyIntolerance.setVerificationStatus(AllergyIntoleranceVerificationStatus.valueOf(allergyIntoleranceEntity.getVerificationStatus().toUpperCase()));
allergyIntolerance.setType(AllergyIntoleranceType.ALLERGY);
CodeableConcept codeableConcept = new CodeableConcept();
Coding coding = new Coding();
coding.setDisplay(allergyIntoleranceEntity.getConceptDisplay());
// That's as in db under concept code 716186003
coding.setCode(allergyIntoleranceEntity.getConceptCode());
coding.setSystem(SystemConstants.SNOMED_URL);
Extension extension = new Extension(SystemURL.SD_EXT_SCT_DESC_ID);
// 3305010017
extension.addExtension("descriptionId", new StringType(allergyIntoleranceEntity.getDescCode()));
// NKA - No known allergy
extension.addExtension("descriptionDisplay", new StringType(allergyIntoleranceEntity.getDescDisplay()));
coding.addExtension(extension);
codeableConcept.addCoding(coding);
allergyIntolerance.setCode(codeableConcept);
return allergyIntolerance;
}
use of org.hl7.fhir.r4.model.CodeableConcept in project gpconnect-demonstrator by nhsconnect.
the class PopulateMedicationBundle method createListEntry.
private ListResource createListEntry(List<MedicationStatementDetail> medicationStatements, String nhsNumber) {
ListResource medicationStatementsList = new ListResource();
// #179 dont populate List.id
// medicationStatementsList.setId(new IdType(1));
medicationStatementsList.setMeta(new Meta().addProfile(SystemURL.SD_GPC_LIST));
medicationStatementsList.setStatus(ListStatus.CURRENT);
// #179 dont populate List.id
// medicationStatementsList.setId(new IdDt(1));
medicationStatementsList.setMode(ListMode.SNAPSHOT);
medicationStatementsList.setTitle(SystemConstants.MEDICATION_LIST);
medicationStatementsList.setCode(new CodeableConcept().addCoding(new Coding(SystemURL.VS_SNOMED, "933361000000108", MEDICATION_LIST)));
medicationStatementsList.setSubject(new Reference(new IdType("Patient", 1L)).setIdentifier(new Identifier().setValue(nhsNumber).setSystem(SystemURL.ID_NHS_NUMBER)));
medicationStatementsList.setDate(new Date());
medicationStatementsList.setOrderedBy(new CodeableConcept().addCoding(new Coding(SystemURL.CS_LIST_ORDER, "event-date", "Sorted by Event Date")));
medicationStatementsList.addExtension(setClinicalSetting());
if (medicationStatements.isEmpty()) {
medicationStatementsList.setEmptyReason(new CodeableConcept().setText(SystemConstants.NO_CONTENT));
medicationStatementsList.setNote(Arrays.asList(new Annotation(new StringType(SystemConstants.INFORMATION_NOT_AVAILABLE))));
}
Set<String> warningCodes = new HashSet<>();
medicationStatements.forEach(statement -> {
Reference statementRef = new Reference(new IdType("MedicationStatement", statement.getId()));
ListEntryComponent listEntryComponent = new ListEntryComponent(statementRef);
medicationStatementsList.addEntry(listEntryComponent);
if (statement.getWarningCode() != null) {
warningCodes.add(statement.getWarningCode());
}
});
WarningCodeExtHelper.addWarningCodeExtensions(warningCodes, medicationStatementsList, patientRepository, medicationStatementRepository, structuredAllergySearch);
return medicationStatementsList;
}
Aggregations