use of org.hl7.fhir.dstu3.model.Slot in project gpconnect-demonstrator by nhsconnect.
the class SlotResourceProvider method getSlotsForScheduleIdNoOrganizationTypeOrODS.
/**
* returns any slots not having org type or org id assigned
*
* @param scheduleId
* @param startDateTime
* @param endDateTime
* @return
*/
public List<Slot> getSlotsForScheduleIdNoOrganizationTypeOrODS(String scheduleId, Date startDateTime, Date endDateTime) {
ArrayList<Slot> slots = new ArrayList<>();
List<SlotDetail> slotDetails = slotSearch.findSlotsForScheduleIdNoOrganizationTypeOrODS(Long.valueOf(scheduleId), startDateTime, endDateTime);
if (slotDetails != null && !slotDetails.isEmpty()) {
for (SlotDetail slotDetail : slotDetails) {
slots.add(slotDetailToSlotResourceConverter(slotDetail));
}
}
return slots;
}
use of org.hl7.fhir.dstu3.model.Slot in project gpconnect-demonstrator by nhsconnect.
the class SlotResourceProvider method getSlotsForScheduleIdAndOrganizationId.
public List<Slot> getSlotsForScheduleIdAndOrganizationId(String scheduleId, Date startDateTime, Date endDateTime, Long orgId) {
ArrayList<Slot> slots = new ArrayList<>();
List<SlotDetail> slotDetails = slotSearch.findSlotsForScheduleIdAndOrganizationId(Long.valueOf(scheduleId), startDateTime, endDateTime, orgId);
if (slotDetails != null && !slotDetails.isEmpty()) {
for (SlotDetail slotDetail : slotDetails) {
slots.add(slotDetailToSlotResourceConverter(slotDetail));
}
}
return slots;
}
use of org.hl7.fhir.dstu3.model.Slot in project gpconnect-demonstrator by nhsconnect.
the class SlotResourceProvider method slotDetailToSlotResourceConverter.
private Slot slotDetailToSlotResourceConverter(SlotDetail slotDetail) {
Slot slot = new Slot();
Date lastUpdated = slotDetail.getLastUpdated() == null ? new Date() : slotDetail.getLastUpdated();
String resourceId = String.valueOf(slotDetail.getId());
String versionId = String.valueOf(lastUpdated.getTime());
IdType id = new IdType(resourceId);
slot.setId(id);
slot.getMeta().setVersionId(versionId);
slot.getMeta().addProfile(SystemURL.SD_GPC_SLOT);
slot.setSchedule(new Reference("Schedule/" + slotDetail.getScheduleReference()));
slot.setStart(slotDetail.getStartDateTime());
slot.setEnd(slotDetail.getEndDateTime());
// #218 Date time formats
slot.getStartElement().setPrecision(TemporalPrecisionEnum.SECOND);
slot.getEndElement().setPrecision(TemporalPrecisionEnum.SECOND);
switch(slotDetail.getFreeBusyType().toLowerCase(Locale.UK)) {
case "free":
slot.setStatus(SlotStatus.FREE);
break;
default:
slot.setStatus(SlotStatus.BUSY);
break;
}
String deliveryChannelCode = slotDetail.getDeliveryChannelCode();
ArrayList<Extension> al = new ArrayList<>();
if (deliveryChannelCode != null && !deliveryChannelCode.trim().isEmpty()) {
Extension deliveryChannelExtension = new Extension(SystemURL.SD_EXTENSION_GPC_DELIVERY_CHANNEL, new CodeType(deliveryChannelCode));
al.add(deliveryChannelExtension);
}
slot.setExtension(al);
// 1.2.7 add slot type description as service type
slot.addServiceType(new CodeableConcept().setText(slotDetail.getTypeDisply()));
return slot;
}
use of org.hl7.fhir.dstu3.model.Slot in project gpconnect-demonstrator by nhsconnect.
the class SlotResourceProvider method getSlotById.
@Read()
public Slot getSlotById(@IdParam IdType slotId) {
SlotDetail slotDetail = slotSearch.findSlotByID(slotId.getIdPartAsLong());
if (slotDetail == null) {
OperationOutcome operationalOutcome = new OperationOutcome();
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("No slot details found for ID: " + slotId.getIdPart());
throw new InternalErrorException("No slot details found for ID: " + slotId.getIdPart(), operationalOutcome);
}
return slotDetailToSlotResourceConverter(slotDetail);
}
use of org.hl7.fhir.dstu3.model.Slot 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
}
Aggregations