use of org.hl7.fhir.dstu3.model.IdType in project gpconnect-demonstrator by nhsconnect.
the class AppointmentResourceProvider method getAppointmentById.
@Read(version = true)
public Appointment getAppointmentById(@IdParam IdType appointmentId) {
Appointment appointment = null;
try {
Long id = appointmentId.getIdPartAsLong();
AppointmentDetail appointmentDetail = null;
// appointment
if (appointmentId.hasVersionIdPart()) {
try {
Long versionId = appointmentId.getVersionIdPartAsLong();
appointmentDetail = appointmentSearch.findAppointmentByIDAndLastUpdated(id, new Date(versionId));
if (appointmentDetail == null) {
// 404 version of resource not found
String msg = String.format("No appointment details found for ID: %s with versionId %s", appointmentId.getIdPart(), versionId);
throw OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException(msg), SystemCode.REFERENCE_NOT_FOUND, IssueType.NOTFOUND);
}
} catch (NumberFormatException nfe) {
// 404 resource not found - the versionId is valid according
// to FHIR
// however we have no entities matching that versionId
String msg = String.format("The version ID %s of the Appointment (ID - %s) is not valid", appointmentId.getVersionIdPart(), id);
throw OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException(msg), SystemCode.REFERENCE_NOT_FOUND, IssueType.NOTFOUND);
}
} else {
appointmentDetail = appointmentSearch.findAppointmentByID(id);
if (appointmentDetail == null) {
// 404 resource not found
String msg = String.format("No appointment details found for ID: %s", appointmentId.getIdPart());
throw OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException(msg), SystemCode.REFERENCE_NOT_FOUND, IssueType.NOTFOUND);
}
}
appointment = appointmentDetailToAppointmentResourceConverter(appointmentDetail);
} catch (NumberFormatException nfe) {
// however we have no entities matching that identifier
throw OperationOutcomeFactory.buildOperationOutcomeException(new ResourceNotFoundException("No appointment details found for ID: " + appointmentId.getIdPart()), SystemCode.REFERENCE_NOT_FOUND, IssueType.NOTFOUND);
}
return appointment;
}
use of org.hl7.fhir.dstu3.model.IdType in project gpconnect-demonstrator by nhsconnect.
the class AppointmentResourceProvider method getAppointmentsForPatientIdAndDates.
@Search
public List<Appointment> getAppointmentsForPatientIdAndDates(@RequiredParam(name = "patient") IdType patientLocalId, @Sort SortSpec sort, @Count Integer count, @RequiredParam(name = "start") DateAndListParam startDates) {
Date startLowerDate = null;
Date startUpperDate = null;
List<DateOrListParam> startDateList = startDates.getValuesAsQueryTokens();
if (startDateList.size() != 2) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Appointment search must have both 'le' and 'ge' start date parameters."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
Pattern dateOnlyPattern = Pattern.compile("[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1])))");
boolean lePrefix = false;
boolean gePrefix = false;
for (DateOrListParam filter : startDateList) {
DateParam token = filter.getValuesAsQueryTokens().get(0);
if (!dateOnlyPattern.matcher(token.getValueAsString()).matches()) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Search dates must be of the format: yyyy-MM-dd and should not include time or timezone."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
if (token.getPrefix() == ParamPrefixEnum.GREATERTHAN_OR_EQUALS) {
startLowerDate = token.getValue();
gePrefix = true;
} else if (token.getPrefix() == ParamPrefixEnum.LESSTHAN_OR_EQUALS) {
Calendar upper = Calendar.getInstance();
upper.setTime(token.getValue());
upper.add(Calendar.HOUR, 23);
upper.add(Calendar.MINUTE, 59);
upper.add(Calendar.SECOND, 59);
startUpperDate = upper.getTime();
lePrefix = true;
} else {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Unknown prefix on start date parameter: only le and ge prefixes are allowed."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
}
if (!gePrefix || !lePrefix) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Parameters must contain two start parameters, one with prefix 'ge' and one with prefix 'le'."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
} else if (startLowerDate.before(getYesterday())) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Search dates from the past: " + startLowerDate.toString() + " are not allowed in appointment search."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
} else if (startUpperDate.before(getYesterday())) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Search dates from the past: " + startUpperDate.toString() + " are not allowed in appointment search."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
} else if (startUpperDate.before(startLowerDate)) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnprocessableEntityException("Upper search date must be after the lower search date."), SystemCode.INVALID_PARAMETER, IssueType.INVALID);
}
List<Appointment> appointment = appointmentSearch.searchAppointments(patientLocalId.getIdPartAsLong(), startLowerDate, startUpperDate).stream().map(this::appointmentDetailToAppointmentResourceConverter).collect(Collectors.toList());
List<Appointment> futureAppointments = appointmentValidation.filterToReturnFutureAppointments(appointment);
if (futureAppointments.isEmpty()) {
return null;
}
// Update startIndex if we do paging
return count != null ? futureAppointments.subList(0, count) : futureAppointments;
}
use of org.hl7.fhir.dstu3.model.IdType in project gpconnect-demonstrator by nhsconnect.
the class AppointmentResourceProvider method appointmentDetailToAppointmentResourceConverter.
private Appointment appointmentDetailToAppointmentResourceConverter(AppointmentDetail appointmentDetail) {
Appointment appointment = new Appointment();
String appointmentId = String.valueOf(appointmentDetail.getId());
String versionId = String.valueOf(appointmentDetail.getLastUpdated().getTime());
String resourceType = appointment.getResourceType().toString();
IdType id = new IdType(resourceType, appointmentId, versionId);
appointment.setId(id);
appointment.getMeta().setVersionId(versionId);
appointment.getMeta().setLastUpdated(appointmentDetail.getLastUpdated());
appointment.getMeta().addProfile(SystemURL.SD_GPC_APPOINTMENT);
Extension extension = new Extension(SystemURL.SD_EXTENSION_GPC_APPOINTMENT_CANCELLATION_REASON, new IdType(appointmentDetail.getCancellationReason()));
appointment.addExtension(extension);
Identifier identifier = new Identifier();
identifier.setSystem(SystemURL.ID_GPC_APPOINTMENT_IDENTIFIER).setValue(String.valueOf(appointmentDetail.getId()));
appointment.addIdentifier(identifier);
switch(appointmentDetail.getStatus().toLowerCase(Locale.UK)) {
case "pending":
appointment.setStatus(AppointmentStatus.PENDING);
break;
case "booked":
appointment.setStatus(AppointmentStatus.BOOKED);
break;
case "arrived":
appointment.setStatus(AppointmentStatus.ARRIVED);
break;
case "fulfilled":
appointment.setStatus(AppointmentStatus.FULFILLED);
break;
case "cancelled":
appointment.setStatus(AppointmentStatus.CANCELLED);
break;
case "noshow":
appointment.setStatus(AppointmentStatus.NOSHOW);
break;
default:
appointment.setStatus(AppointmentStatus.PENDING);
break;
}
Coding coding = new Coding().setSystem(SystemURL.HL7_VS_C80_PRACTICE_CODES).setCode(String.valueOf(appointmentDetail.getTypeCode())).setDisplay(appointmentDetail.getTypeDisplay());
CodeableConcept codableConcept = new CodeableConcept().addCoding(coding);
codableConcept.setText(appointmentDetail.getTypeDisplay());
appointment.setAppointmentType(codableConcept);
// Look into this
// appointment.getType().setText(appointmentDetail.getTypeText());
String reasonCode = appointmentDetail.getReasonCode();
String reasonDisplay = appointmentDetail.getReasonDisplay();
String reasonSystem = SystemURL.DEFAULTREASONURL;
if (reasonCode != null && reasonDisplay != null && reasonSystem != null) {
Coding codingReason = new Coding().setSystem(reasonSystem).setCode(String.valueOf(reasonCode)).setDisplay(reasonDisplay);
CodeableConcept codableConceptReason = new CodeableConcept().addCoding(codingReason);
codableConceptReason.setText(reasonDisplay);
appointment.addReason(codableConceptReason);
}
appointment.setStart(appointmentDetail.getStartDateTime());
appointment.setEnd(appointmentDetail.getEndDateTime());
List<Reference> slotResources = new ArrayList<>();
for (Long slotId : appointmentDetail.getSlotIds()) {
slotResources.add(new Reference("Slot/" + slotId));
}
appointment.setSlot(slotResources);
if (appointmentDetail.getPriority() != null) {
appointment.setPriority(appointmentDetail.getPriority());
}
appointment.setComment(appointmentDetail.getComment());
appointment.setDescription(appointmentDetail.getDescription());
appointment.addParticipant().setActor(new Reference("Patient/" + appointmentDetail.getPatientId())).setStatus(ParticipationStatus.ACCEPTED);
appointment.addParticipant().setActor(new Reference("Location/" + appointmentDetail.getLocationId())).setStatus(ParticipationStatus.ACCEPTED);
if (null != appointmentDetail.getPractitionerId()) {
appointment.addParticipant().setActor(new Reference("Practitioner/" + appointmentDetail.getPractitionerId())).setStatus(ParticipationStatus.ACCEPTED);
}
if (null != appointmentDetail.getCreated()) {
// DateTimeDt created = new
// DateTimeDt(appointmentDetail.getCreated());
// Extension createdExt = new
// Extension(SystemURL.SD_CC_APPOINTMENT_CREATED, created);
appointment.setCreated(appointmentDetail.getCreated());
}
if (null != appointmentDetail.getBookingOrganization()) {
String reference = "#1";
Reference orgRef = new Reference(reference);
Extension bookingOrgExt = new Extension(SystemURL.SD_CC_APPOINTMENT_BOOKINGORG, orgRef);
appointment.addExtension(bookingOrgExt);
BookingOrgDetail bookingOrgDetail = appointmentDetail.getBookingOrganization();
Organization bookingOrg = new Organization();
bookingOrg.setId(reference);
bookingOrg.getNameElement().setValue(bookingOrgDetail.getName());
bookingOrg.getTelecomFirstRep().setValue(bookingOrgDetail.getTelephone()).setUse(ContactPointUse.TEMP).setSystem(ContactPointSystem.PHONE);
bookingOrg.getMeta().addProfile(SystemURL.SD_GPC_ORGANIZATION);
if (null != bookingOrgDetail.getOrgCode()) {
bookingOrg.getIdentifierFirstRep().setSystem(SystemURL.ID_ODS_ORGANIZATION_CODE).setValue(bookingOrgDetail.getOrgCode());
}
appointment.getContained().add(bookingOrg);
}
return appointment;
}
use of org.hl7.fhir.dstu3.model.IdType in project gpconnect-demonstrator by nhsconnect.
the class AppointmentResourceProvider method updateAppointment.
@Update
public MethodOutcome updateAppointment(@IdParam IdType appointmentId, @ResourceParam Appointment appointment) {
MethodOutcome methodOutcome = new MethodOutcome();
OperationOutcome operationalOutcome = new OperationOutcome();
AppointmentDetail appointmentDetail = appointmentResourceConverterToAppointmentDetail(appointment);
// URL ID and Resource ID must be the same
if (!Objects.equals(appointmentId.getIdPartAsLong(), appointmentDetail.getId())) {
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("Id in URL (" + appointmentId.getIdPart() + ") should match Id in Resource (" + appointmentDetail.getId() + ")");
methodOutcome.setOperationOutcome(operationalOutcome);
return methodOutcome;
}
// Make sure there is an existing appointment to be amended
AppointmentDetail oldAppointmentDetail = appointmentSearch.findAppointmentByID(appointmentId.getIdPartAsLong());
if (oldAppointmentDetail == null) {
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("No appointment details found for ID: " + appointmentId.getIdPart());
methodOutcome.setOperationOutcome(operationalOutcome);
return methodOutcome;
}
String oldAppointmentVersionId = String.valueOf(oldAppointmentDetail.getLastUpdated().getTime());
String newAppointmentVersionId = appointmentId.getVersionIdPart();
if (newAppointmentVersionId != null && !newAppointmentVersionId.equalsIgnoreCase(oldAppointmentVersionId)) {
throw new ResourceVersionConflictException("The specified version (" + newAppointmentVersionId + ") did not match the current resource version (" + oldAppointmentVersionId + ")");
}
// Determin if it is a cancel or an amend
if (appointmentDetail.getCancellationReason() != null) {
if (appointmentDetail.getCancellationReason().isEmpty()) {
operationalOutcome.addIssue().setSeverity(IssueSeverity.ERROR).setDiagnostics("The cancellation reason can not be blank");
methodOutcome.setOperationOutcome(operationalOutcome);
return methodOutcome;
}
// This is a Cancellation - so copy across fields which can be
// altered
boolean cancelComparisonResult = compareAppointmentsForInvalidPropertyCancel(oldAppointmentDetail, appointmentDetail);
if (cancelComparisonResult) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(400, "Invalid Appointment property has been amended (cancellation)"), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
}
oldAppointmentDetail.setCancellationReason(appointmentDetail.getCancellationReason());
String oldStatus = oldAppointmentDetail.getStatus();
appointmentDetail = oldAppointmentDetail;
appointmentDetail.setStatus("cancelled");
if (!"cancelled".equalsIgnoreCase(oldStatus)) {
for (Long slotId : appointmentDetail.getSlotIds()) {
SlotDetail slotDetail = slotSearch.findSlotByID(slotId);
// slotDetail.setAppointmentId(null);
slotDetail.setFreeBusyType("FREE");
slotDetail.setLastUpdated(new Date());
slotStore.saveSlot(slotDetail);
}
}
} else {
if (appointment.getStatus().equals("cancelled")) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(400, "Appointment has been cancelled and cannot be amended"), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
}
boolean amendComparisonResult = compareAppointmentsForInvalidPropertyAmend(appointmentDetail, oldAppointmentDetail);
if (amendComparisonResult) {
throw OperationOutcomeFactory.buildOperationOutcomeException(new UnclassifiedServerFailureException(403, "Invalid Appointment property has been amended"), SystemCode.BAD_REQUEST, IssueType.FORBIDDEN);
}
// This is an Amend
oldAppointmentDetail.setComment(appointmentDetail.getComment());
oldAppointmentDetail.setReasonCode(appointmentDetail.getReasonCode());
oldAppointmentDetail.setDescription(appointmentDetail.getDescription());
oldAppointmentDetail.setReasonDisplay(appointmentDetail.getReasonDisplay());
oldAppointmentDetail.setTypeCode(appointmentDetail.getTypeCode());
oldAppointmentDetail.setTypeDisplay(appointmentDetail.getTypeDisplay());
appointmentDetail = oldAppointmentDetail;
}
List<SlotDetail> slots = new ArrayList<>();
for (Long slotId : appointmentDetail.getSlotIds()) {
SlotDetail slotDetail = slotSearch.findSlotByID(slotId);
if (slotDetail == null) {
throw new UnprocessableEntityException("Slot resource reference is not a valid resource");
}
slots.add(slotDetail);
}
// Update version and
appointmentDetail.setLastUpdated(new Date());
// lastUpdated timestamp
appointmentDetail = appointmentStore.saveAppointment(appointmentDetail, slots);
methodOutcome.setId(new IdDt("Appointment", appointmentDetail.getId()));
methodOutcome.setResource(appointmentDetailToAppointmentResourceConverter(appointmentDetail));
return methodOutcome;
}
use of org.hl7.fhir.dstu3.model.IdType in project gpconnect-demonstrator by nhsconnect.
the class ScheduleResourceProvider method scheduleDetailToScheduleResourceConverter.
private Schedule scheduleDetailToScheduleResourceConverter(ScheduleDetail scheduleDetail) {
Schedule schedule = new Schedule();
String resourceId = String.valueOf(scheduleDetail.getId());
String versionId = String.valueOf(scheduleDetail.getLastUpdated().getTime());
String resourceType = schedule.getResourceType().toString();
IdType id = new IdType(resourceType, resourceId, versionId);
schedule.setId(id);
schedule.getMeta().setVersionId(versionId);
schedule.getMeta().setLastUpdated(scheduleDetail.getLastUpdated());
if (scheduleDetail.getPractitionerId() != null) {
schedule.addActor(new Reference("Practitioner/" + scheduleDetail.getPractitionerId()));
}
if (scheduleDetail.getPractitionerRoleCode() != null) {
Coding roleCoding = new Coding(SystemURL.VS_GPC_PRACTITIONER_ROLE, scheduleDetail.getPractitionerRoleCode(), scheduleDetail.getPractitionerRoleDisplay());
Extension practitionerRoleExtension = new Extension(SystemURL.SD_EXTENSION_GPC_PRACTITIONER_ROLE, new CodeableConcept().addCoding(roleCoding));
schedule.addExtension(practitionerRoleExtension);
}
if (scheduleDetail.getDeliveryChannelCode() != null) {
Coding roleCoding = new Coding(SystemURL.VS_GPC_DELIVERY_CHANNEL, scheduleDetail.getDeliveryChannelCode(), scheduleDetail.getDeliveryChannelDisplay());
Extension deliveryChannelExtension = new Extension(SystemURL.SD_EXTENSION_GPC_DELIVERY_CHANNEL, new CodeableConcept().addCoding(roleCoding));
schedule.addExtension(deliveryChannelExtension);
}
Identifier identifier = new Identifier();
identifier.setSystem(SystemURL.ID_GPC_SCHEDULE_IDENTIFIER);
identifier.setValue(scheduleDetail.getIdentifier());
schedule.addIdentifier(identifier);
Coding coding = new Coding().setSystem(SystemURL.HL7_VS_C80_PRACTICE_CODES).setCode(scheduleDetail.getTypeCode()).setDisplay(scheduleDetail.getTypeDescription());
CodeableConcept codableConcept = new CodeableConcept().addCoding(coding);
codableConcept.setText(scheduleDetail.getTypeDescription());
schedule.setServiceType(Collections.singletonList(codableConcept));
schedule.addActor(new Reference("Location/" + scheduleDetail.getLocationId()));
// schedule.setActor((List<Reference>) new Reference("Location/" + scheduleDetail.getLocationId()));
Period period = new Period();
period.setStart(scheduleDetail.getStartDateTime());
period.setEnd(scheduleDetail.getEndDateTime());
schedule.setPlanningHorizon(period);
schedule.setComment(scheduleDetail.getComment());
return schedule;
}
Aggregations