use of org.hl7.fhir.r4.model.Property 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.r4.model.Property in project gpconnect-demonstrator by nhsconnect.
the class AppointmentResourceProvider method updateAppointment.
/**
* amend or cancel an existing appointment
*
* @param appointmentId
* @param appointment Resource
* @param theRequest required to access the interaction id
* @return MethodOutcome
*/
@Update
public MethodOutcome updateAppointment(@IdParam IdType appointmentId, @ResourceParam Appointment appointment, HttpServletRequest theRequest) {
MethodOutcome methodOutcome = new MethodOutcome();
OperationOutcome operationalOutcome = new OperationOutcome();
AppointmentDetail appointmentDetail = appointmentResourceConverterToAppointmentDetail(appointment);
Meta meta = appointment.getMeta();
final List<UriType> profiles = meta.getProfile();
// #203 validations
VC.execute(new VC[] { new VC(() -> profiles.isEmpty(), () -> "Meta element must be present in Appointment"), new VC(() -> !profiles.get(0).getValue().equalsIgnoreCase(SD_GPC_APPOINTMENT), // what to do if > 1 meta profile element?
() -> "Meta.profile " + profiles.get(0).getValue() + " is not equal to " + SD_GPC_APPOINTMENT), // #203
new VC(() -> !appointment.getReason().isEmpty(), () -> "Appointment reason shouldn't be provided!"), new VC(() -> !appointment.getSpecialty().isEmpty(), () -> "Appointment speciality shouldn't be provided!"), // new VC(() -> !appointment.getServiceType().isEmpty(), () -> "Appointment service type shouldn't be provided!"),
new VC(() -> !appointment.getAppointmentType().isEmpty(), () -> "Appointment type shouldn't be provided!"), new VC(() -> !appointment.getIndication().isEmpty(), () -> "Appointment indication shouldn't be provided!"), new VC(() -> !appointment.getSupportingInformation().isEmpty(), () -> "Appointment supporting information shouldn't be provided!"), new VC(() -> !appointment.getIncomingReferral().isEmpty(), () -> "Appointment incoming referral shouldn't be provided!") });
// 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;
}
// 1.2.7 set the old service type and service category for comparison with incoming update/cancel content values
SlotDetail slotDetail1 = slotSearch.findSlotByID(oldAppointmentDetail.getSlotIds().get(0));
oldAppointmentDetail.setServiceType(slotDetail1.getTypeDisply());
ScheduleDetail scheduleDetail = scheduleSearch.findScheduleByID(slotDetail1.getScheduleReference());
oldAppointmentDetail.setServiceCategory(scheduleDetail.getTypeDescription());
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 + ")");
}
// check for absolute reference #200
Iterator<AppointmentParticipantComponent> iter = appointment.getParticipant().iterator();
while (iter.hasNext()) {
AppointmentParticipantComponent participant = iter.next();
if (participant.getActor() != null) {
checkReferenceIsRelative(participant.getActor().getReference());
}
}
String interactionId = theRequest.getHeader(SSP_INTERACTIONID);
// Determine if it is a cancel or an amend. This was previously a check for the presence of a cancellation reason
// but that is not sufficient. We can sefely assume that the interaction id is populated at this point.
AppointmentOperation appointmentOperation = null;
final AppointmentDetail fAppointmentDetail = appointmentDetail;
switch(interactionId) {
case REST_CANCEL_APPOINTMENT:
appointmentOperation = AppointmentOperation.CANCEL;
// added at 1.2.2
VC.execute(new VC[] { new VC(() -> appointment.getStatus() != AppointmentStatus.CANCELLED, () -> "Status must be \"cancelled\""), // #203
new VC(() -> isInThePast(fAppointmentDetail.getStartDateTime()), () -> "The cancellation start date cannot be in the past"), new VC(() -> fAppointmentDetail.getCancellationReason() == null, () -> "The cancellation reason must be provided"), // no point in this since fhir forbids empty elements
new VC(() -> fAppointmentDetail.getCancellationReason().isEmpty(), () -> "The cancellation reason can not be blank") });
validateAppointmentExtensions(appointment, profiles, appointmentOperation);
// #172
String appointmentType = appointment.getAppointmentType().getText();
if (appointmentType != null) {
throwUnprocessableEntity422_InvalidResourceException("The appointment type cannot be updated on a cancellation");
}
// This is a Cancellation - so copy across fields which can be
// altered
List cancelComparisonResult = compareAppointmentsForInvalidProperty(AppointmentOperation.CANCEL, oldAppointmentDetail, appointmentDetail);
if (cancelComparisonResult.size() > 0) {
throwUnprocessableEntity422_InvalidResourceException("Invalid Appointment property has been amended (cancellation) " + cancelComparisonResult);
}
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);
}
}
break;
case REST_UPDATE_APPOINTMENT:
appointmentOperation = AppointmentOperation.AMEND;
VC.execute(new VC[] { new VC(() -> appointment.getStatus() != AppointmentStatus.BOOKED, () -> "Status must be \"booked\""), // this subsumes #161 which only inhibited amendment of the cancellation reason in an amend
new VC(() -> fAppointmentDetail.getCancellationReason() != null, () -> "Cannot amend cancellation reason in appointment amend"), // added at 1.2.2
new VC(() -> isInThePast(fAppointmentDetail.getStartDateTime()), () -> "The appointment amend start date cannot be in the past") });
List amendComparisonResult = compareAppointmentsForInvalidProperty(AppointmentOperation.AMEND, oldAppointmentDetail, appointmentDetail);
if (amendComparisonResult.size() > 0) {
throwUnprocessableEntity422_InvalidResourceException("Invalid Appointment property has been amended " + amendComparisonResult);
}
validateAppointmentExtensions(appointment, profiles, appointmentOperation);
// This is an Amend
oldAppointmentDetail.setComment(appointmentDetail.getComment());
oldAppointmentDetail.setDescription(appointmentDetail.getDescription());
appointmentDetail = oldAppointmentDetail;
break;
default:
System.err.println("AppointmentResourceProvider.updateAppointment Unhandled interaction id " + interactionId);
}
// we'll get the delivery channel from the slot
String deliveryChannel = null;
String practitionerRoleCode = null;
String practitionerRoleDisplay = null;
ScheduleDetail schedule = null;
// Common to both Update and cancel
// slots valid?
List<SlotDetail> slots = new ArrayList<>();
for (Long slotId : appointmentDetail.getSlotIds()) {
SlotDetail slotDetail = slotSearch.findSlotByID(slotId);
if (slotDetail == null) {
throwUnprocessableEntity422_InvalidResourceException("Slot resource reference is not a valid resource");
}
if (deliveryChannel == null) {
deliveryChannel = slotDetail.getDeliveryChannelCode();
}
if (schedule == null) {
// load the schedule so we can get the Practitioner ID
schedule = scheduleSearch.findScheduleByID(slotDetail.getScheduleReference());
}
if (practitionerRoleDisplay == null) {
practitionerRoleDisplay = schedule.getPractitionerRoleDisplay();
practitionerRoleCode = schedule.getPractitionerRoleCode();
}
slots.add(slotDetail);
}
validateUpdateExtensions(deliveryChannel, practitionerRoleDisplay, practitionerRoleCode, appointment.getExtension());
// dates valid?
// #203
Date firstSlotStart = slots.get(0).getStartDateTime();
Date lastSlotEnd = slots.get(slots.size() - 1).getEndDateTime();
// need to insert a colon in the timezone string
String firstSlotStartStr = TIMESTAMP_FORMAT.format(firstSlotStart).replaceFirst("([0-9]{2})([0-9]{2})$", "$1:$2");
String lastSlotEndStr = TIMESTAMP_FORMAT.format(lastSlotEnd).replaceFirst("([0-9]{2})([0-9]{2})$", "$1:$2");
VC.execute(new VC[] { new VC(() -> appointment.getStart().compareTo(firstSlotStart) != 0, () -> String.format("Start date '%s' must match start date of first slot '%s'", appointment.getStart(), firstSlotStart)), new VC(() -> appointment.getEnd().compareTo(lastSlotEnd) != 0, () -> String.format("End date '%s' must match end date of last slot '%s'", appointment.getEnd(), lastSlotEnd)), // #218 strings should match exactly
new VC(() -> !appointment.getStartElement().getValueAsString().equals(firstSlotStartStr), () -> String.format("Start date '%s' must lexically match start date of first slot '%s'", appointment.getStartElement().getValueAsString(), firstSlotStartStr)), new VC(() -> !appointment.getEndElement().getValueAsString().equals(lastSlotEndStr), () -> String.format("End date '%s' must lexically match end date of last slot '%s'", appointment.getEndElement().getValueAsString(), lastSlotEndStr)), new VC(() -> appointment.getSlot().size() != slots.size(), () -> String.format("Slot count mismatch %d provided appointment has %d", appointment.getSlot().size(), slots.size())) });
// check the slots match
HashSet<String> hs = new HashSet<>();
for (SlotDetail slotDetail : slots) {
hs.add("Slot/" + slotDetail.getId());
}
for (Reference reference : appointment.getSlot()) {
if (!hs.contains(reference.getReference())) {
throwUnprocessableEntity422_InvalidResourceException(String.format("Provided slot id %s does not exist in booked appointment", reference.getReference()));
}
}
// 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.r4.model.Property in project uPMT by coco35700.
the class Main method createBasicSchema.
/**
* Creates a basic scheme as a default
* should be improved if desired
*/
private void createBasicSchema() {
Type s = new Schema((_langBundle.getString("default_scheme")));
Type general = new Folder(_langBundle.getString("general"));
Type autre = new Folder(_langBundle.getString("other"));
Type visuel = new Category(_langBundle.getString("visual"));
Type image = new Property(_langBundle.getString("picture"));
Type sensoriel = new Category(_langBundle.getString("sensory"));
Type emotionnel = new Category(_langBundle.getString("emotional"));
Type sonore = new Category(_langBundle.getString("acoustic"));
visuel.addType(image);
general.addType(visuel);
general.addType(sensoriel);
general.addType(emotionnel);
general.addType(sonore);
s.addType(general);
s.addType(autre);
this.BasicSchema = (Schema) s;
}
use of org.hl7.fhir.r4.model.Property in project uPMT by coco35700.
the class Main method writeMoment.
/**
* Recursive method used to recursively transform a Moment and its sub Moments into CSV compatible DATAZ
*/
private void writeMoment(DescriptionInterview ent, MomentExperience m, PrintWriter writer, String hierarchy) {
LinkedList<String> classes = new LinkedList<String>();
for (Type t : m.getTypes()) {
for (Type prop : t.getTypes()) {
Property p = (Property) prop;
classes.add(format(t.getName()) + "," + format(p.getName()) + "," + format(p.getValue()));
}
}
if (!classes.isEmpty()) {
for (String s : classes) {
writer.println(format(ent.getName()) + ",\"" + hierarchy + "\"" + "," + format(m.getName()) + "," + format(m.getDescripteme()) + "," + format(m.getColor()) + "," + format(m.getDuration()) + "," + s);
}
} else {
writer.println(format(ent.getName()) + ",\"" + hierarchy + "\"" + "," + format(m.getName()) + "," + format(m.getDescripteme()) + "," + format(m.getColor()) + "," + format(m.getDuration()) + ",\"\",\"\",\"\"");
}
for (int i = 0; i < m.getSubMoments().size(); i++) {
MomentExperience sub = m.getSubMoments().get(i);
writeMoment(ent, sub, writer, hierarchy + "." + (i + 1));
}
}
use of org.hl7.fhir.r4.model.Property in project uPMT by coco35700.
the class TypeClassRepresentationController method updateVue.
@Override
public void updateVue(Observable obs, Object value) {
// TODO Auto-generated method stub
if (obs.getClass().equals(RenameClassSchemeController.class)) {
renameClass((String) value);
}
if (obs.getClass().equals(ChangeColorClassSchemeController.class)) {
setColor((String) value);
}
if (obs.getClass().equals(AddPropertySchemeController.class)) {
Property n = new Property(((Property) value).getName());
boolean contain = false;
for (Type t : classe.getTypes()) {
if (t.getName().equals(n.getName())) {
contain = true;
break;
}
}
if (!this.classe.getTypes().contains(n)) {
addProperty((Property) n);
} else {
// System.out.println("AH BAH VOILA !!!!!");
}
}
if (obs.getClass().equals(RemovePropertySchemeController.class)) {
Property toRemove = (Property) value;
// System.out.println("Remove dans TypeClassRpzCtrl "+toRemove.getName());
RemoveProperty(toRemove);
}
if (obs.getClass().equals(AddPropertySchemeWithValueController.class)) {
addProperty(stack.pop());
}
if (obs.getClass().equals(RemoveClassSchemeController.class)) {
// System.out.println("DELETINGCLASS");
moment.removeTypeClassRep(this);
}
if (obs.getClass().equals(AddClassSchemeController.class)) {
// System.out.println("REPUTINGCLASS");
moment.putPreviousClassRep();
}
}
Aggregations