diff --git a/fhir2-appnt-api/pom.xml b/fhir2-appnt-api/pom.xml new file mode 100644 index 000000000..dfbe80b29 --- /dev/null +++ b/fhir2-appnt-api/pom.xml @@ -0,0 +1,93 @@ + + + + appointments + org.openmrs.module + 1.2-SNAPSHOT + + 4.0.0 + + org.openmrs.module + fhir2-appointment-api + ${openmrsModuleFhirVersion} + jar + FHIR Appointment API + + + + ${project.parent.groupId} + ${project.parent.artifactId}-api + ${project.parent.version} + provided + + + org.openmrs.module + fhir2-api + ${openmrsModuleFhirVersion} + + + org.openmrs.api + openmrs-api + ${openmrs.platform.version} + provided + + + org.openmrs.api + openmrs-api + ${openmrs.platform.version} + tests + test + + + org.projectlombok + lombok + + + + org.mockito + mockito-core + test + + + org.hamcrest + hamcrest-core + ${hamcrestCoreVersion} + test + + + org.exparity + hamcrest-date + ${hamcrestDateVersion} + test + + + + + + + com.mycila + license-maven-plugin + + + org.projectlombok + lombok-maven-plugin + + + net.revelc.code.formatter + formatter-maven-plugin + + + net.revelc.code + impsort-maven-plugin + + + + + + 2.0.7 + 2.2 + + + diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/AppointmentFhirConstants.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/AppointmentFhirConstants.java new file mode 100644 index 000000000..a3960cda1 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/AppointmentFhirConstants.java @@ -0,0 +1,20 @@ +package org.openmrs.module.fhirappnt.api; + +import lombok.NoArgsConstructor; +import org.openmrs.module.fhir2.FhirConstants; + +@NoArgsConstructor +public class AppointmentFhirConstants extends FhirConstants { + + public static final String APPOINTMENT_SPECIALITY_VALUESET_URI = HL7_FHIR_VALUE_SET_PREFIX + + "/c80-practice-codes"; + + public static final String APPOINTMENT_PARTICIPANT_TYPE = HL7_FHIR_VALUE_SET_PREFIX + + "/encounter-participant-type"; + + public static final String APPOINTMENT_SERVICE_TYPE = HL7_FHIR_VALUE_SET_PREFIX + + "/service-type"; + + public static final String OPENMRS_FHIR_EXT_HEALTH_CARE_SERVICE= "https://fhir.openmrs.org/ext/health-care-service"; + +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/Impl/FhirBahmniAppointmentServiceImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/Impl/FhirBahmniAppointmentServiceImpl.java new file mode 100644 index 000000000..ed2353a97 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/Impl/FhirBahmniAppointmentServiceImpl.java @@ -0,0 +1,38 @@ +package org.openmrs.module.fhirappnt.api.Impl; + +import lombok.AccessLevel; +import lombok.Setter; +import org.openmrs.module.appointments.model.Appointment; +import org.openmrs.module.fhir2.api.FhirAppointmentService; +import org.openmrs.module.fhir2.api.dao.FhirAppointmentDao; +import org.openmrs.module.fhir2.api.translators.AppointmentTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +@Primary +@Component +@Transactional +@Setter(AccessLevel.PACKAGE) +public class FhirBahmniAppointmentServiceImpl implements FhirAppointmentService { + + @Autowired + private AppointmentTranslator appointmentTranslator; + + @Autowired + private FhirAppointmentDao fhirAppointmentDao; + + public void setFhirAppointmentDao(FhirAppointmentDao fhirAppointmentDao) { + this.fhirAppointmentDao = fhirAppointmentDao; + } + + public void setAppointmentTranslator(AppointmentTranslator appointmentTranslator) { + this.appointmentTranslator = appointmentTranslator; + } + + @Override + public org.hl7.fhir.r4.model.Appointment getAppointmentByUuid(String uuid) { + return appointmentTranslator.toFhirResource(fhirAppointmentDao.getAppointmentByUuid(uuid)); + } +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/dao/impl/FhirAppointmentDaoImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/dao/impl/FhirAppointmentDaoImpl.java new file mode 100644 index 000000000..15840eb6f --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/dao/impl/FhirAppointmentDaoImpl.java @@ -0,0 +1,22 @@ +package org.openmrs.module.fhirappnt.api.dao.impl; + +import lombok.AccessLevel; +import lombok.Setter; +import org.openmrs.module.appointments.model.Appointment; +import org.openmrs.module.appointments.service.AppointmentsService; +import org.openmrs.module.fhir2.api.dao.FhirAppointmentDao; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Setter(AccessLevel.PACKAGE) +public class FhirAppointmentDaoImpl implements FhirAppointmentDao { + + @Autowired + private AppointmentsService appointmentsService; + + @Override + public Appointment getAppointmentByUuid(String uuid) { + return appointmentsService.getAppointmentByUuid(uuid); + } +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/AppointmentParticipantTranslator.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/AppointmentParticipantTranslator.java new file mode 100644 index 000000000..c49fdd3f4 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/AppointmentParticipantTranslator.java @@ -0,0 +1,7 @@ +package org.openmrs.module.fhirappnt.api.translators; + +import org.hl7.fhir.r4.model.Appointment; +import org.openmrs.module.fhir2.api.translators.OpenmrsFhirUpdatableTranslator; + +public interface AppointmentParticipantTranslator extends OpenmrsFhirUpdatableTranslator { +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/AppointmentSpecialityTranslator.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/AppointmentSpecialityTranslator.java new file mode 100644 index 000000000..97b264db6 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/AppointmentSpecialityTranslator.java @@ -0,0 +1,9 @@ +package org.openmrs.module.fhirappnt.api.translators; + +import org.hl7.fhir.r4.model.CodeableConcept; +import org.openmrs.module.appointments.model.Speciality; +import org.openmrs.module.fhir2.api.translators.OpenmrsFhirUpdatableTranslator; + +public interface AppointmentSpecialityTranslator extends OpenmrsFhirUpdatableTranslator{ + +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/HealthCareServiceTranslator.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/HealthCareServiceTranslator.java new file mode 100644 index 000000000..cc15ae51c --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/HealthCareServiceTranslator.java @@ -0,0 +1,9 @@ +package org.openmrs.module.fhirappnt.api.translators; + +import org.hl7.fhir.r4.model.HealthcareService; +import org.openmrs.module.appointments.model.AppointmentServiceDefinition; +import org.openmrs.module.fhir2.api.translators.OpenmrsFhirUpdatableTranslator; + +public interface HealthCareServiceTranslator extends OpenmrsFhirUpdatableTranslator { + +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPatientTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPatientTranslatorImpl.java new file mode 100644 index 000000000..91e1716e9 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPatientTranslatorImpl.java @@ -0,0 +1,52 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import lombok.AccessLevel; +import lombok.Setter; +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.openmrs.Patient; +import org.openmrs.module.fhir2.api.translators.PatientReferenceTranslator; +import org.openmrs.module.fhir2.api.translators.impl.AbstractReferenceHandlingTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentParticipantTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Setter(AccessLevel.PACKAGE) +public class AppointmentPatientTranslatorImpl extends AbstractReferenceHandlingTranslator implements AppointmentParticipantTranslator { + + @Autowired + private PatientReferenceTranslator patientReferenceTranslator; + + @Override + public Appointment.AppointmentParticipantComponent toFhirResource(Patient patient) { + if (patient == null) { + return null; + } + Appointment.AppointmentParticipantComponent participant = new Appointment.AppointmentParticipantComponent(); + CodeableConcept role = new CodeableConcept(); + role.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "Patient", "Patient")); + participant.setRequired(Appointment.ParticipantRequired.REQUIRED); + participant.setActor(patientReferenceTranslator.toFhirResource(patient)); + participant.addType(role); + participant.setStatus(Appointment.ParticipationStatus.ACCEPTED); + + return participant; + } + + @Override + public Patient toOpenmrsType(Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + return toOpenmrsType(new Patient(), appointmentParticipantComponent); + } + + @Override + public Patient toOpenmrsType(Patient patient, Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + if (appointmentParticipantComponent == null) { + return patient; + } + + return patientReferenceTranslator.toOpenmrsType(appointmentParticipantComponent.getActor()); + } +} \ No newline at end of file diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPractitionerTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPractitionerTranslatorImpl.java new file mode 100644 index 000000000..3b381515c --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPractitionerTranslatorImpl.java @@ -0,0 +1,51 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import lombok.AccessLevel; +import lombok.Setter; +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.openmrs.Provider; +import org.openmrs.module.fhir2.api.dao.FhirPractitionerDao; +import org.openmrs.module.fhir2.api.translators.impl.AbstractReferenceHandlingTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentParticipantTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Setter(AccessLevel.PACKAGE) +public class AppointmentPractitionerTranslatorImpl extends AbstractReferenceHandlingTranslator implements AppointmentParticipantTranslator { + + @Autowired + private FhirPractitionerDao practitionerDao; + + @Override + public Appointment.AppointmentParticipantComponent toFhirResource(Provider provider) { + if (provider == null) { + return null; + } + Appointment.AppointmentParticipantComponent participant = new Appointment.AppointmentParticipantComponent(); + CodeableConcept role = new CodeableConcept(); + role.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "Practitioner", "Practitioner")); + participant.setRequired(Appointment.ParticipantRequired.OPTIONAL); + participant.setActor(createPractitionerReference(provider)); + participant.addType(role); + + return participant; + } + + @Override + public Provider toOpenmrsType(Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + return toOpenmrsType(new Provider(), appointmentParticipantComponent); + } + + @Override + public Provider toOpenmrsType(Provider appointmentProvider, Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + if (appointmentParticipantComponent == null) { + return appointmentProvider; + } + + return practitionerDao.getProviderByUuid(getReferenceId(appointmentParticipantComponent.getActor())); + } +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentProviderTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentProviderTranslatorImpl.java new file mode 100644 index 000000000..794da3b6c --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentProviderTranslatorImpl.java @@ -0,0 +1,77 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; +import lombok.AccessLevel; +import lombok.Setter; +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.openmrs.module.appointments.model.AppointmentProvider; +import org.openmrs.module.appointments.model.AppointmentProviderResponse; +import org.openmrs.module.fhir2.api.dao.FhirPractitionerDao; +import org.openmrs.module.fhir2.api.translators.impl.AbstractReferenceHandlingTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentParticipantTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Setter(AccessLevel.PACKAGE) +public class AppointmentProviderTranslatorImpl extends AbstractReferenceHandlingTranslator implements AppointmentParticipantTranslator { + + @Autowired + private FhirPractitionerDao practitionerDao; + + @Override + public Appointment.AppointmentParticipantComponent toFhirResource(AppointmentProvider appointmentProvider) { + if (appointmentProvider == null || appointmentProvider.getProvider() == null) { + return null; + } + Appointment.AppointmentParticipantComponent participant = new Appointment.AppointmentParticipantComponent(); + CodeableConcept role = new CodeableConcept(); + role.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "AppointmentPractitioner", "AppointmentPractitioner")); + participant.setRequired(Appointment.ParticipantRequired.OPTIONAL); + participant.setActor(createPractitionerReference(appointmentProvider.getProvider())); + participant.addType(role); + + switch (appointmentProvider.getResponse()) { + case ACCEPTED: + return participant.setStatus(Appointment.ParticipationStatus.ACCEPTED); + case TENTATIVE: + return participant.setStatus(Appointment.ParticipationStatus.TENTATIVE); + case AWAITING: + return participant.setStatus(Appointment.ParticipationStatus.NEEDSACTION); + case REJECTED: + return participant.setStatus(Appointment.ParticipationStatus.DECLINED); + case CANCELLED: + return participant.setStatus(Appointment.ParticipationStatus.NULL); + } + + return participant; + } + + @Override + public AppointmentProvider toOpenmrsType(Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + return toOpenmrsType(new AppointmentProvider(), appointmentParticipantComponent); + } + + @Override + public AppointmentProvider toOpenmrsType(AppointmentProvider appointmentProvider, Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + if (appointmentParticipantComponent == null) { + return appointmentProvider; + } + appointmentProvider.setProvider(practitionerDao.getProviderByUuid(getReferenceId(appointmentParticipantComponent.getActor()))); + switch (appointmentParticipantComponent.getStatus()) { + case ACCEPTED: + appointmentProvider.setResponse(AppointmentProviderResponse.ACCEPTED); + case TENTATIVE: + appointmentProvider.setResponse(AppointmentProviderResponse.TENTATIVE); + case NEEDSACTION: + appointmentProvider.setResponse(AppointmentProviderResponse.AWAITING); + case DECLINED: + appointmentProvider.setResponse(AppointmentProviderResponse.REJECTED); + case NULL: + appointmentProvider.setResponse(AppointmentProviderResponse.CANCELLED); + } + + return appointmentProvider; + } +} \ No newline at end of file diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentSpecialityTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentSpecialityTranslatorImpl.java new file mode 100644 index 000000000..e2b162cb8 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentSpecialityTranslatorImpl.java @@ -0,0 +1,43 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentSpecialityTranslator; +import org.openmrs.module.appointments.model.Speciality; +import org.springframework.stereotype.Component; + +@Component +public class AppointmentSpecialityTranslatorImpl implements AppointmentSpecialityTranslator { + + @Override + public CodeableConcept toFhirResource(Speciality speciality) { + if (speciality == null) { + return null; + } + + CodeableConcept code = new CodeableConcept(); + code.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_SPECIALITY_VALUESET_URI,speciality.getUuid(), speciality.getName())); + + return code; + } + + @Override + public Speciality toOpenmrsType(CodeableConcept codeableConcept) { + return toOpenmrsType(new Speciality(), codeableConcept); + } + + @Override + public Speciality toOpenmrsType(Speciality speciality, CodeableConcept codeableConcept) { + if (codeableConcept == null) { + return speciality; + } + + if (codeableConcept.hasCoding()) { + speciality.setUuid(codeableConcept.getCoding().get(0).getCode()); + speciality.setName(codeableConcept.getCoding().get(0).getDisplay()); + } + + return speciality; + } +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentTranslatorImpl.java new file mode 100644 index 000000000..6f5a94db9 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentTranslatorImpl.java @@ -0,0 +1,170 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; +import lombok.AccessLevel; +import lombok.Setter; +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.module.appointments.model.AppointmentKind; +import org.openmrs.module.appointments.model.AppointmentProvider; +import org.openmrs.module.appointments.model.AppointmentServiceDefinition; +import org.openmrs.module.appointments.model.AppointmentStatus; +import org.openmrs.module.appointments.service.AppointmentServiceDefinitionService; +import org.openmrs.module.fhir2.api.translators.AppointmentTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentParticipantTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashSet; +import java.util.Set; + +@Component +@Setter(AccessLevel.PACKAGE) +public class AppointmentTranslatorImpl implements AppointmentTranslator { + + @Autowired + private AppointmentParticipantTranslator patientTranslator; + + @Autowired + private AppointmentParticipantTranslator providerTranslator; + + @Autowired + private AppointmentParticipantTranslator appointmentParticipantTranslator; + + @Autowired + AppointmentParticipantTranslator serviceDefinitionAppointmentParticipantTranslator; + + @Autowired + private AppointmentServiceDefinitionService appointmentServiceDefinitionService; + + @Override + public Appointment toFhirResource(org.openmrs.module.appointments.model.Appointment appointment) { + Appointment fhirAppointment = new Appointment(); + fhirAppointment.setId(appointment.getUuid()); + fhirAppointment.setStart(appointment.getStartDateTime()); + fhirAppointment.setEnd(appointment.getEndDateTime()); + fhirAppointment.addParticipant(patientTranslator.toFhirResource(appointment.getPatient())); + if (appointment.getProvider() != null){ + fhirAppointment.addParticipant(providerTranslator.toFhirResource(appointment.getProvider())); + } + + if (appointment.getProviders() != null) { + for (AppointmentProvider provider : appointment.getProviders()) { + fhirAppointment.addParticipant(appointmentParticipantTranslator.toFhirResource(provider)); + } + } + if (appointment.getService() != null) { + fhirAppointment.addParticipant(serviceDefinitionAppointmentParticipantTranslator.toFhirResource(appointment.getService())); + } + if (appointment.getServiceType() != null) { + fhirAppointment.addServiceType(new CodeableConcept().addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_SERVICE_TYPE, appointment.getServiceType().getUuid(), appointment.getServiceType().getName()))); + } + if (appointment.getAppointmentKind() != null) { + switch (appointment.getAppointmentKind()) { + case Scheduled: + fhirAppointment.setAppointmentType(new CodeableConcept().addCoding(new Coding("", "ROUTINE", "Routine appointment "))); + break; + case WalkIn: + fhirAppointment.setAppointmentType(new CodeableConcept().addCoding(new Coding("", "WALKIN", "A previously unscheduled walk-in visit"))); + } + } + + switch (appointment.getStatus()) { + case Requested : + fhirAppointment.setStatus(Appointment.AppointmentStatus.PROPOSED); + break; + case Scheduled: + fhirAppointment.setStatus(Appointment.AppointmentStatus.BOOKED); + break; + case CheckedIn: + fhirAppointment.setStatus(Appointment.AppointmentStatus.CHECKEDIN); + break; + case Completed: + fhirAppointment.setStatus(Appointment.AppointmentStatus.FULFILLED); + break; + case Missed: + fhirAppointment.setStatus(Appointment.AppointmentStatus.NOSHOW); + break; + case Cancelled: + fhirAppointment.setStatus(Appointment.AppointmentStatus.CANCELLED); + break; + } + + fhirAppointment.setComment(appointment.getComments()); + fhirAppointment.setCreated(appointment.getDateCreated()); + fhirAppointment.getMeta().setLastUpdated(appointment.getDateChanged()); + + return fhirAppointment; + } + + @Override + public org.openmrs.module.appointments.model.Appointment toOpenmrsType(Appointment appointment) { + return toOpenmrsType(new org.openmrs.module.appointments.model.Appointment(), appointment); + } + + @Override + public org.openmrs.module.appointments.model.Appointment toOpenmrsType(org.openmrs.module.appointments.model.Appointment appointment, Appointment fhirAppointment) { + appointment.setUuid(fhirAppointment.getId()); + appointment.setStartDateTime(fhirAppointment.getStart()); + appointment.setEndDateTime(fhirAppointment.getEnd()); + + Set providers = new HashSet<>(); + + if (fhirAppointment.hasParticipant()) { + for (Appointment.AppointmentParticipantComponent participantComponent : fhirAppointment.getParticipant()) { + if (participantComponent.getType().get(0).getCoding().get(0).getCode() == "Patient") { + appointment.setPatient(patientTranslator.toOpenmrsType(participantComponent)); + } else if (participantComponent.getType().get(0).getCoding().get(0).getCode() == "Practitioner") { + appointment.setProvider(providerTranslator.toOpenmrsType(participantComponent)); + } else if (participantComponent.getType().get(0).getCoding().get(0).getCode() == "AppointmentPractitioner") { + AppointmentProvider provider = appointmentParticipantTranslator.toOpenmrsType(participantComponent); + provider.setAppointment(appointment); + providers.add(provider); + appointment.setProviders(providers); + } else { + appointment.setService(serviceDefinitionAppointmentParticipantTranslator.toOpenmrsType(participantComponent)); + } + } + } + + if (fhirAppointment.hasServiceType()) { + appointment.setServiceType(appointmentServiceDefinitionService.getAppointmentServiceTypeByUuid(fhirAppointment.getServiceType().get(0).getCoding().get(0).getCode())); + } + + if (fhirAppointment.hasAppointmentType()) { + if (fhirAppointment.getAppointmentType().getCoding().get(0).getCode() == "ROUTINE") { + appointment.setAppointmentKind(AppointmentKind.Scheduled); + } else if (fhirAppointment.getAppointmentType().getCoding().get(0).getCode() == "WALKIN") { + appointment.setAppointmentKind(AppointmentKind.WalkIn); + } + } + + if (fhirAppointment.hasStatus()) { + switch (fhirAppointment.getStatus()) { + case PROPOSED: + appointment.setStatus(AppointmentStatus.Requested); + break; + case BOOKED: + appointment.setStatus(AppointmentStatus.Scheduled); + break; + case CHECKEDIN: + appointment.setStatus(AppointmentStatus.CheckedIn); + break; + case FULFILLED: + appointment.setStatus(AppointmentStatus.Completed); + break; + case NOSHOW: + appointment.setStatus(AppointmentStatus.Missed); + break; + case CANCELLED: + appointment.setStatus(AppointmentStatus.Cancelled); + break; + } + } + appointment.setComments(fhirAppointment.getComment()); + + return appointment; + } +} \ No newline at end of file diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceParticipantTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceParticipantTranslatorImpl.java new file mode 100644 index 000000000..ee44a5004 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceParticipantTranslatorImpl.java @@ -0,0 +1,65 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import lombok.AccessLevel; +import lombok.Setter; +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Reference; +import org.openmrs.module.appointments.model.AppointmentServiceDefinition; +import org.openmrs.module.appointments.service.AppointmentServiceDefinitionService; +import org.openmrs.module.fhir2.api.translators.impl.AbstractReferenceHandlingTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentParticipantTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.validation.constraints.NotNull; + +@Component +@Setter(AccessLevel.PACKAGE) +public class HealthCareServiceParticipantTranslatorImpl extends AbstractReferenceHandlingTranslator implements AppointmentParticipantTranslator { + + @Autowired + AppointmentServiceDefinitionService appointmentServiceDefinitionService; + + @Override + public Appointment.AppointmentParticipantComponent toFhirResource(AppointmentServiceDefinition serviceDefinition) { + if (serviceDefinition == null) { + return null; + } + Appointment.AppointmentParticipantComponent participant = new Appointment.AppointmentParticipantComponent(); + CodeableConcept role = new CodeableConcept(); + role.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "HealthCareService", "HealthCareService")); + participant.setRequired(Appointment.ParticipantRequired.REQUIRED); + participant.setActor(createHeathCareServiceReference(serviceDefinition)); + participant.addType(role); + participant.setRequired(Appointment.ParticipantRequired.OPTIONAL); + participant.setStatus(Appointment.ParticipationStatus.ACCEPTED); + + return participant; + } + + @Override + public AppointmentServiceDefinition toOpenmrsType(Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + return toOpenmrsType(new AppointmentServiceDefinition(), appointmentParticipantComponent); + } + + @Override + public AppointmentServiceDefinition toOpenmrsType(AppointmentServiceDefinition serviceDefinition, Appointment.AppointmentParticipantComponent appointmentParticipantComponent) { + if (appointmentParticipantComponent == null) { + return null; + } + + return appointmentServiceDefinitionService.getAppointmentServiceByUuid(getReferenceId(appointmentParticipantComponent.getActor())); + } + + private Reference createHeathCareServiceReference(@NotNull AppointmentServiceDefinition serviceDefinition) { + Reference reference = (new Reference()).setReference("HealthCareService/" + serviceDefinition.getUuid()).setType("HealthCareService"); + if (serviceDefinition.getName() != null) { + reference.setDisplay(serviceDefinition.getName()); + } + + return reference; + } +} diff --git a/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceTranslatorImpl.java b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceTranslatorImpl.java new file mode 100644 index 000000000..b9831fe91 --- /dev/null +++ b/fhir2-appnt-api/src/main/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceTranslatorImpl.java @@ -0,0 +1,127 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import lombok.AccessLevel; +import lombok.Setter; +import org.hl7.fhir.r4.model.Extension; +import org.hl7.fhir.r4.model.HealthcareService; +import org.hl7.fhir.r4.model.StringType; +import org.openmrs.module.appointments.model.AppointmentServiceDefinition; +import org.openmrs.module.appointments.model.AppointmentStatus; +import org.openmrs.module.fhir2.api.dao.FhirLocationDao; +import org.openmrs.module.fhir2.api.translators.impl.AbstractReferenceHandlingTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentSpecialityTranslator; +import org.openmrs.module.fhirappnt.api.translators.HealthCareServiceTranslator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.validation.constraints.NotNull; +import java.util.Optional; + +@Component +@Setter(AccessLevel.PACKAGE) +public class HealthCareServiceTranslatorImpl extends AbstractReferenceHandlingTranslator implements HealthCareServiceTranslator { + + @Autowired + private AppointmentSpecialityTranslator specialityTranslator; + + @Autowired + private FhirLocationDao locationDao; + + @Override + public HealthcareService toFhirResource(AppointmentServiceDefinition appointmentService) { + if (appointmentService == null) { + return null; + } + HealthcareService service = new HealthcareService(); + service.setId(appointmentService.getUuid()); + service.setName(appointmentService.getName()); + service.setComment(appointmentService.getDescription()); + if (appointmentService.getSpeciality() != null) { + service.addSpecialty(specialityTranslator.toFhirResource(appointmentService.getSpeciality())); + } + if (appointmentService.getLocation() != null) { + service.addLocation(createLocationReference(appointmentService.getLocation())); + } + + HealthcareService.HealthcareServiceAvailableTimeComponent availableTimeComponent = new HealthcareService.HealthcareServiceAvailableTimeComponent(); + if (appointmentService.getStartTime() != null) { + availableTimeComponent.setAvailableStartTime(appointmentService.getStartTime().toString()); + } + if (appointmentService.getEndTime() != null) { + availableTimeComponent.setAvailableEndTime(appointmentService.getEndTime().toString()); + } + service.addAvailableTime(availableTimeComponent); + + addHealthCareServiceExtension(service, "maxAppointmentsLimit", appointmentService.getMaxAppointmentsLimit().toString()); + addHealthCareServiceExtension(service, "durationMins", appointmentService.getDurationMins().toString()); + addHealthCareServiceExtension(service, "color", appointmentService.getColor()); + addHealthCareServiceExtension(service, "initialAppointmentStatus", appointmentService.getInitialAppointmentStatus().toString()); + + return service; + } + + @Override + public AppointmentServiceDefinition toOpenmrsType(HealthcareService healthcareService) { + return toOpenmrsType(new AppointmentServiceDefinition(), healthcareService); + } + + @Override + public AppointmentServiceDefinition toOpenmrsType(AppointmentServiceDefinition appointmentServiceDefinition, HealthcareService healthcareService) { + if (healthcareService == null) { + return appointmentServiceDefinition; + } + appointmentServiceDefinition.setUuid(healthcareService.getId()); + appointmentServiceDefinition.setName(healthcareService.getName()); + appointmentServiceDefinition.setDescription(healthcareService.getComment()); + if (healthcareService.hasSpecialty()) { + appointmentServiceDefinition.setSpeciality(specialityTranslator.toOpenmrsType(healthcareService.getSpecialty().get(0))); + } + appointmentServiceDefinition.setLocation(locationDao.getLocationByUuid(getReferenceId(healthcareService.getLocation().get(0)))); + + getAppointmentServiceExtension(healthcareService).ifPresent(ext -> ext.getExtension() + .forEach(e -> addHealthCareServiceComponent(appointmentServiceDefinition, e.getUrl(), ((StringType) e.getValue()).getValue()))); + + + return appointmentServiceDefinition; + } + + + + public void addHealthCareServiceComponent(@NotNull AppointmentServiceDefinition serviceDefinition, @NotNull String url, @NotNull String value) { + if (value == null || url == null || !url.startsWith(AppointmentFhirConstants.OPENMRS_FHIR_EXT_HEALTH_CARE_SERVICE + "#")) { + return; + } + String val = url.substring(url.lastIndexOf('#') + 1); + switch (val) { + case "maxAppointmentsLimit": + serviceDefinition.setMaxAppointmentsLimit(Integer.valueOf(val)); + break; + case "durationMins": + serviceDefinition.setDurationMins(Integer.valueOf(val)); + break; + case "color": + serviceDefinition.setColor(val); + break; + case "initialAppointmentStatus": + serviceDefinition.setInitialAppointmentStatus(AppointmentStatus.valueOf(val)); + break; + } + } + + private void addHealthCareServiceExtension(@NotNull HealthcareService service, @NotNull java.lang.String extensionProperty, + @NotNull String value) { + if (value == null) { + return; + } + + getAppointmentServiceExtension(service) + .orElseGet(() -> service.addExtension().setUrl(AppointmentFhirConstants.OPENMRS_FHIR_EXT_HEALTH_CARE_SERVICE)) + .addExtension(AppointmentFhirConstants.OPENMRS_FHIR_EXT_HEALTH_CARE_SERVICE + "#" + extensionProperty, new StringType(value)); + } + + private Optional getAppointmentServiceExtension(@NotNull HealthcareService service) { + return Optional.ofNullable(service.getExtensionByUrl(AppointmentFhirConstants.OPENMRS_FHIR_EXT_HEALTH_CARE_SERVICE)); + + } +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/TestFhirSpringConfiguration.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/TestFhirSpringConfiguration.java new file mode 100644 index 000000000..da8e1c7e9 --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/TestFhirSpringConfiguration.java @@ -0,0 +1,9 @@ +package org.openmrs.module; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +@Configuration +@ImportResource({ "classpath:applicationContext-service.xml", "classpath*:moduleApplicationContext.xml" }) +public class TestFhirSpringConfiguration { +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/dao/impl/FhirAppointmentDaoImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/dao/impl/FhirAppointmentDaoImplTest.java new file mode 100644 index 000000000..e04d2d8ff --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/dao/impl/FhirAppointmentDaoImplTest.java @@ -0,0 +1,56 @@ +package org.openmrs.module.fhirappnt.api.dao.impl; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +import static org.hamcrest.CoreMatchers.nullValue; +import static org.mockito.Mockito.when; + +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.module.appointments.model.Appointment; +import org.openmrs.module.appointments.service.AppointmentsService; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(MockitoJUnitRunner.class) +public class FhirAppointmentDaoImplTest { + + private static final String APPOINTMENT_UUID = "75504r42-3ca8-11e3-bf2b-0800271c1b77"; + + private static final String WRONG_APPOINTMENT_UUID = "1099AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + private AppointmentsService appointmentsService; + + private FhirAppointmentDaoImpl fhirAppointmentDao; + + private Appointment appointment; + + @Before + public void setup() { + fhirAppointmentDao = new FhirAppointmentDaoImpl(); + fhirAppointmentDao.setAppointmentsService(appointmentsService); + + appointment = new Appointment(); + } + + @Test + public void shouldGetAppointmentByUuid() { + appointment.setUuid(APPOINTMENT_UUID); + when(appointmentsService.getAppointmentByUuid(APPOINTMENT_UUID)).thenReturn(appointment); + Appointment appointment = fhirAppointmentDao.getAppointmentByUuid(APPOINTMENT_UUID); + assertThat(appointment, notNullValue()); + assertThat(appointment.getUuid(), notNullValue()); + assertThat(appointment.getUuid(), equalTo(APPOINTMENT_UUID)); + } + + @Test + public void shouldReturnNullWhenGetAppointmentIsCalledWithUnknownUuid() { + Appointment appointment = fhirAppointmentDao.getAppointmentByUuid(WRONG_APPOINTMENT_UUID); + assertThat(appointment, nullValue()); + } +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/impl/FhirBahmniAppointmentServiceImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/impl/FhirBahmniAppointmentServiceImplTest.java new file mode 100644 index 000000000..74157d4c2 --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/impl/FhirBahmniAppointmentServiceImplTest.java @@ -0,0 +1,58 @@ +package org.openmrs.module.fhirappnt.api.impl; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.module.fhirappnt.api.Impl.FhirBahmniAppointmentServiceImpl; +import org.openmrs.module.appointments.model.Appointment; +import org.openmrs.module.fhir2.api.dao.FhirAppointmentDao; +import org.openmrs.module.fhir2.api.translators.AppointmentTranslator; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class FhirBahmniAppointmentServiceImplTest { + + private static final String APPOINTMENT_UUID = "1085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + private AppointmentTranslator appointmentTranslator; + + @Mock + private FhirAppointmentDao fhirAppointmentDao; + + private FhirBahmniAppointmentServiceImpl appointmentService; + + private Appointment appointment; + + @Before + public void setup() { + appointmentService = new FhirBahmniAppointmentServiceImpl(); + appointmentService.setAppointmentTranslator(appointmentTranslator); + appointmentService.setFhirAppointmentDao(fhirAppointmentDao); + + appointment = new Appointment(); + } + + @Test + public void getAppointmentByUuidShouldReturnMatchingAppointment() { + appointment.setUuid(APPOINTMENT_UUID); + + org.hl7.fhir.r4.model.Appointment fhirAppointment = new org.hl7.fhir.r4.model.Appointment(); + fhirAppointment.setId(APPOINTMENT_UUID); + + when(fhirAppointmentDao.getAppointmentByUuid(APPOINTMENT_UUID)).thenReturn(appointment); + when(appointmentTranslator.toFhirResource(appointment)).thenReturn(fhirAppointment); + + org.hl7.fhir.r4.model.Appointment result = appointmentService.getAppointmentByUuid(APPOINTMENT_UUID); + assertThat(result, notNullValue()); + assertThat(result.getId(), notNullValue()); + assertThat(result.getId(), equalTo(APPOINTMENT_UUID)); + } +} + diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPatientTranslatorImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPatientTranslatorImplTest.java new file mode 100644 index 000000000..249ed804c --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPatientTranslatorImplTest.java @@ -0,0 +1,106 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.Mockito.when; + +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Reference; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Patient; +import org.openmrs.module.fhir2.FhirConstants; +import org.openmrs.module.fhir2.api.translators.PatientReferenceTranslator; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; + +@RunWith(MockitoJUnitRunner.class) +public class AppointmentPatientTranslatorImplTest { + private static String PATIENT_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + private PatientReferenceTranslator patientReferenceTranslator; + + private AppointmentPatientTranslatorImpl appointmentPatientTranslator; + + @Before + public void setup() { + appointmentPatientTranslator = new AppointmentPatientTranslatorImpl(); + appointmentPatientTranslator.setPatientReferenceTranslator(patientReferenceTranslator); + } + + @Test + public void toFhirResourceShouldReturnNullIfPatientIsNull() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentPatientTranslator.toFhirResource(null); + assertThat(participantComponent, nullValue()); + } + + @Test + public void toFhirResourceShouldSetRoleToPatient() { + Patient patient = new Patient(); + Appointment.AppointmentParticipantComponent participantComponent = appointmentPatientTranslator.toFhirResource(patient); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getSystem(), equalTo(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE)); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getCode(), equalTo("Patient")); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getDisplay(), equalTo("Patient")); + } + + @Test + public void toFhirResourceShouldSetParticipantToRequired() { + Patient patient = new Patient(); + Appointment.AppointmentParticipantComponent participantComponent = appointmentPatientTranslator.toFhirResource(patient); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getRequired(), equalTo(Appointment.ParticipantRequired.REQUIRED)); + } + + @Test + public void toFhirResourceShouldSetStatusToAccepted() { + Patient patient = new Patient(); + Appointment.AppointmentParticipantComponent participantComponent = appointmentPatientTranslator.toFhirResource(patient); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getStatus(), equalTo(Appointment.ParticipationStatus.ACCEPTED)); + } + + @Test + public void toFhirResourceShouldSetActorToPatientPassed() { + Patient patient = new Patient(); + patient.setUuid(PATIENT_UUID); + + Reference patientReference = new Reference().setReference(FhirConstants.PATIENT + "/" + PATIENT_UUID) + .setType(FhirConstants.PATIENT).setIdentifier(new Identifier().setValue(PATIENT_UUID)); + + when(patientReferenceTranslator.toFhirResource(patient)).thenReturn(patientReference); + Appointment.AppointmentParticipantComponent result = appointmentPatientTranslator.toFhirResource(patient); + assertThat(result, notNullValue()); + assertThat(result.getActor().getType(), equalTo(FhirConstants.PATIENT)); + assertThat(result.getActor().getReference().contains(PATIENT_UUID), equalTo(true)); + } + + @Test + public void toOpenmrsTypeShouldReturnAnEmptyParticipantObject() { + Patient patient = appointmentPatientTranslator.toOpenmrsType(null); + assertThat(patient, notNullValue()); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantActorToPatient() { + Patient patient = new Patient(); + patient.setUuid(PATIENT_UUID); + Appointment.AppointmentParticipantComponent participantComponent = new Appointment.AppointmentParticipantComponent(); + + Reference patientReference = new Reference().setReference(FhirConstants.PATIENT + "/" + PATIENT_UUID) + .setType(FhirConstants.PATIENT).setIdentifier(new Identifier().setValue(PATIENT_UUID)); + participantComponent.setActor(patientReference); + + when(patientReferenceTranslator.toOpenmrsType(patientReference)).thenReturn(patient); + + Patient result = appointmentPatientTranslator.toOpenmrsType(patient, participantComponent); + assertThat(result, notNullValue()); + assertThat(result.getUuid(), notNullValue()); + assertThat(result.getUuid(), equalTo(PATIENT_UUID)); + } +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPractitionerTranslatorImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPractitionerTranslatorImplTest.java new file mode 100644 index 000000000..008796163 --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentPractitionerTranslatorImplTest.java @@ -0,0 +1,94 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.Mockito.when; + +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Reference; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Provider; +import org.openmrs.module.fhir2.FhirConstants; +import org.openmrs.module.fhir2.api.dao.FhirPractitionerDao; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; + +@RunWith(MockitoJUnitRunner.class) +public class AppointmentPractitionerTranslatorImplTest { + private static String PROVIDER_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + private FhirPractitionerDao practitionerDao; + + private AppointmentPractitionerTranslatorImpl appointmentPractitionerTranslator; + + @Before + public void setup() { + appointmentPractitionerTranslator = new AppointmentPractitionerTranslatorImpl(); + appointmentPractitionerTranslator.setPractitionerDao(practitionerDao); + } + + @Test + public void toFhirResourceShouldReturnNullIfPractitionerIsNull() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentPractitionerTranslator.toFhirResource(null); + assertThat(participantComponent, nullValue()); + } + + @Test + public void toFhirResourceShouldSetRoleToPractioner() { + Provider provider = new Provider(); + Appointment.AppointmentParticipantComponent participantComponent = appointmentPractitionerTranslator.toFhirResource(provider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getSystem(), equalTo(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE)); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getCode(), equalTo("Practitioner")); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getDisplay(), equalTo("Practitioner")); + } + + @Test + public void toFhirResourceShouldSetParticipantToRequired() { + Provider provider = new Provider(); + Appointment.AppointmentParticipantComponent participantComponent = appointmentPractitionerTranslator.toFhirResource(provider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getRequired(), equalTo(Appointment.ParticipantRequired.OPTIONAL)); + } + + @Test + public void toFhirResourceShouldSetActorToPractitioner() { + Provider provider = new Provider(); + provider.setUuid(PROVIDER_UUID); + Appointment.AppointmentParticipantComponent participantComponent = appointmentPractitionerTranslator.toFhirResource(provider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getActor().getType(), equalTo(FhirConstants.PRACTITIONER)); + } + + @Test + public void toOpenmrsTypeShouldReturnEmptyProviderObject() { + Provider provider = new Provider(); + Provider result = appointmentPractitionerTranslator.toOpenmrsType(provider,null); + assertThat(result, equalTo(provider)); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantActorToProvider() { + Provider provider = new Provider(); + provider.setUuid(PROVIDER_UUID); + Appointment.AppointmentParticipantComponent participantComponent = new Appointment.AppointmentParticipantComponent(); + + Reference providerReference = new Reference().setReference(FhirConstants.PRACTITIONER + "/" + PROVIDER_UUID) + .setType(FhirConstants.PRACTITIONER).setIdentifier(new Identifier().setValue(PROVIDER_UUID)); + participantComponent.setActor(providerReference); + + when(practitionerDao.getProviderByUuid(PROVIDER_UUID)).thenReturn(provider); + + Provider result = appointmentPractitionerTranslator.toOpenmrsType(provider, participantComponent); + assertThat(result, notNullValue()); + assertThat(result.getUuid(), notNullValue()); + assertThat(result.getUuid(), equalTo(PROVIDER_UUID)); + } +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentProviderTranslatorImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentProviderTranslatorImplTest.java new file mode 100644 index 000000000..7cc13a9c2 --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentProviderTranslatorImplTest.java @@ -0,0 +1,114 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.Mockito.when; + +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Reference; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Provider; +import org.openmrs.module.appointments.model.AppointmentProvider; +import org.openmrs.module.appointments.model.AppointmentProviderResponse; +import org.openmrs.module.fhir2.FhirConstants; +import org.openmrs.module.fhir2.api.dao.FhirPractitionerDao; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; + + +@RunWith(MockitoJUnitRunner.class) +public class AppointmentProviderTranslatorImplTest { + private static String PRACTIONER_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + private FhirPractitionerDao practitionerDao; + + private AppointmentProvider appointmentProvider; + + private AppointmentProviderTranslatorImpl appointmentProviderTranslator; + + @Before + public void setup() { + appointmentProviderTranslator = new AppointmentProviderTranslatorImpl(); + appointmentProviderTranslator.setPractitionerDao(practitionerDao); + initProvider(); + } + + public void initProvider() { + appointmentProvider = new AppointmentProvider(); + Provider provider = new Provider(); + provider.setUuid(PRACTIONER_UUID); + appointmentProvider.setResponse(AppointmentProviderResponse.AWAITING); + appointmentProvider.setProvider(provider); + } + + @Test + public void toFhirResourceShouldReturnNullIfPractitionerIsNull() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentProviderTranslator.toFhirResource(null); + assertThat(participantComponent, nullValue()); + } + + @Test + public void toFhirResourceShouldSetRoleToPractitioner() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentProviderTranslator.toFhirResource(appointmentProvider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getSystem(), equalTo(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE)); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getCode(), equalTo("AppointmentPractitioner")); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getDisplay(), equalTo("AppointmentPractitioner")); + } + + @Test + public void toFhirResourceShouldSetParticipantToRequired() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentProviderTranslator.toFhirResource(appointmentProvider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getRequired(), equalTo(Appointment.ParticipantRequired.OPTIONAL)); + } + + @Test + public void toFhirResourceShouldSetStatusToAccepted() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentProviderTranslator.toFhirResource(appointmentProvider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getStatus(), equalTo(Appointment.ParticipationStatus.NEEDSACTION)); + } + + @Test + public void toFhirResourceShouldSetActorToProvider() { + Appointment.AppointmentParticipantComponent participantComponent = appointmentProviderTranslator.toFhirResource(appointmentProvider); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getActor().getType(), equalTo(FhirConstants.PRACTITIONER)); + } + + @Test + public void toOpenmrsTypeShouldReturnEmptyProviderObject() { + AppointmentProvider appointmentProvider = new AppointmentProvider(); + AppointmentProvider result = appointmentProviderTranslator.toOpenmrsType(appointmentProvider, null); + assertThat(result, equalTo(appointmentProvider)); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantActorToProvider() { + AppointmentProvider appointmentProvider = new AppointmentProvider(); + Provider provider = new Provider(); + provider.setUuid(PRACTIONER_UUID); + appointmentProvider.setProvider(provider); + Appointment.AppointmentParticipantComponent participantComponent = new Appointment.AppointmentParticipantComponent(); + + Reference providerReference = new Reference().setReference(FhirConstants.PRACTITIONER + "/" + PRACTIONER_UUID) + .setType(FhirConstants.PRACTITIONER).setIdentifier(new Identifier().setValue(PRACTIONER_UUID)); + participantComponent.setActor(providerReference); + participantComponent.setStatus(Appointment.ParticipationStatus.ACCEPTED); + + when(practitionerDao.getProviderByUuid(PRACTIONER_UUID)).thenReturn(provider); + + AppointmentProvider result = appointmentProviderTranslator.toOpenmrsType(appointmentProvider, participantComponent); + assertThat(result, notNullValue()); + assertThat(result.getUuid(), notNullValue()); + assertThat(result.getProvider().getUuid(), equalTo(PRACTIONER_UUID)); + } +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentSpecialityTranslatorImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentSpecialityTranslatorImplTest.java new file mode 100644 index 000000000..03a1bb757 --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentSpecialityTranslatorImplTest.java @@ -0,0 +1,56 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; + +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.appointments.model.Speciality; + +@RunWith(MockitoJUnitRunner.class) +public class AppointmentSpecialityTranslatorImplTest { + + private static String SPECIALITY_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + private static String SPECIALITY_NAME = "Oncologist"; + + private AppointmentSpecialityTranslatorImpl appointmentSpecialityTranslator; + + private Speciality speciality; + + @Before + public void setup() { + appointmentSpecialityTranslator = new AppointmentSpecialityTranslatorImpl(); + speciality = new Speciality(); + } + + @Test + public void shouldTranslateSpecialityToCodeableConcept() { + speciality.setUuid(SPECIALITY_UUID); + speciality.setName(SPECIALITY_NAME); + + CodeableConcept code = appointmentSpecialityTranslator.toFhirResource(speciality); + assertThat(code, notNullValue()); + assertThat(code.getCoding().size(), equalTo(1)); + assertThat(code.getCoding().get(0).getSystem(), equalTo(AppointmentFhirConstants.APPOINTMENT_SPECIALITY_VALUESET_URI)); + assertThat(code.getCoding().get(0).getCode(), equalTo(SPECIALITY_UUID)); + assertThat(code.getCoding().get(0).getDisplay(), equalTo(SPECIALITY_NAME)); + } + + @Test + public void shouldTranslateSpecialityCodeableConceptToSpeciality() { + CodeableConcept code = new CodeableConcept(); + code.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_SPECIALITY_VALUESET_URI, SPECIALITY_UUID, SPECIALITY_NAME)); + + Speciality speciality = appointmentSpecialityTranslator.toOpenmrsType(new Speciality(), code); + assertThat(speciality, notNullValue()); + assertThat(speciality.getUuid(), equalTo(SPECIALITY_UUID)); + assertThat(speciality.getName(), equalTo(SPECIALITY_NAME)); + } +} diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentTranslatorImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentTranslatorImplTest.java new file mode 100644 index 000000000..abf109cde --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/AppointmentTranslatorImplTest.java @@ -0,0 +1,567 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import org.exparity.hamcrest.date.DateMatchers; + +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +import org.hl7.fhir.r4.model.CodeableConcept; +import org.hl7.fhir.r4.model.Coding; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.codesystems.ServiceType; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.Patient; +import org.openmrs.Provider; +import org.openmrs.module.appointments.model.Appointment; +import org.openmrs.module.appointments.model.AppointmentKind; +import org.openmrs.module.appointments.model.AppointmentProvider; +import org.openmrs.module.appointments.model.AppointmentServiceDefinition; +import org.openmrs.module.appointments.model.AppointmentServiceType; +import org.openmrs.module.appointments.model.AppointmentStatus; +import org.openmrs.module.appointments.service.AppointmentServiceDefinitionService; +import org.openmrs.module.fhir2.FhirConstants; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; +import org.openmrs.module.fhirappnt.api.translators.AppointmentParticipantTranslator; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +@RunWith(MockitoJUnitRunner.class) +public class AppointmentTranslatorImplTest { + + private static String APPOINTMENT_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + private static String PATIENT_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + private static String PROVIDER_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + private static String SERVICE_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + private static String SERVICE_TYPE_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + private AppointmentParticipantTranslator patientTranslator; + + @Mock + private AppointmentParticipantTranslator providerTranslator; + + @Mock + private AppointmentParticipantTranslator appointmentParticipantTranslator; + + @Mock + AppointmentParticipantTranslator serviceDefinitionAppointmentParticipantTranslator; + + @Mock + private AppointmentServiceDefinitionService appointmentServiceDefinitionService; + + private AppointmentTranslatorImpl appointmentTranslator; + + private Appointment appointment; + + @Before + public void setUp() { + appointmentTranslator = new AppointmentTranslatorImpl(); + appointmentTranslator.setPatientTranslator(patientTranslator); + appointmentTranslator.setProviderTranslator(providerTranslator); + appointmentTranslator.setAppointmentParticipantTranslator(appointmentParticipantTranslator); + appointmentTranslator.setAppointmentServiceDefinitionService(appointmentServiceDefinitionService); + appointmentTranslator.setServiceDefinitionAppointmentParticipantTranslator(serviceDefinitionAppointmentParticipantTranslator); + appointment = new Appointment(); + Patient patient = new Patient(); + patient.setUuid(PATIENT_UUID); + appointment.setPatient(patient); + } + + @Test + public void toFhirResourceShouldTranslateUuidToId() { + appointment.setUuid(APPOINTMENT_UUID); + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getId(), equalTo(APPOINTMENT_UUID)); + } + + @Test + public void toFhirTypeShouldMapStatusRequestedToProposed() { + appointment.setStatus(AppointmentStatus.Requested); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.PROPOSED)); + } + + @Test + public void toFhirTypeShouldMapStatusScheduledToBooked() { + appointment.setStatus(AppointmentStatus.Scheduled); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.BOOKED)); + } + + @Test + public void toFhirTypeShouldMapStatusCheckedInToCheckedIn() { + appointment.setStatus(AppointmentStatus.CheckedIn); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.CHECKEDIN)); + } + + @Test + public void toFhirTypeShouldMapStatusCompletedToFulfilled() { + appointment.setStatus(AppointmentStatus.Completed); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.FULFILLED)); + } + + @Test + public void toFhirTypeShouldMapStatusMissedToNoShow() { + appointment.setStatus(AppointmentStatus.Missed); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.NOSHOW)); + } + + @Test + public void toFhirTypeShouldMapStatusCancelledToCancelled() { + appointment.setStatus(AppointmentStatus.Cancelled); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.CANCELLED)); + } + + @Test + public void toFhirTypeShouldMapStartDateTimeToStart() { + appointment.setStartDateTime(new Date()); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getStart(), DateMatchers.sameDay(new Date())); + } + + @Test + public void toFhirTypeShouldMapEndDateTimeToEnd() { + appointment.setEndDateTime(new Date()); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getEnd(), DateMatchers.sameDay(new Date())); + } + + @Test + public void toFhirTypeShouldMapDateCreatedToDateCreated() { + appointment.setDateCreated(new Date()); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getCreated(), DateMatchers.sameDay(new Date())); + } + + @Test + public void toFhirTypeShouldMapDateChangedToLastDateUpdated() { + appointment.setDateChanged(new Date()); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getMeta().getLastUpdated(), DateMatchers.sameDay(new Date())); + } + + @Test + public void toFhirTypeShouldConvertCommentsToFhirAppointmentComment() { + appointment.setComments("Test Appointment"); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getComment(), equalTo("Test Appointment")); + } + + @Test + public void toFhirTypeShouldAddPatientAsParticipant() { + Patient patient = new Patient(); + patient.setUuid(PATIENT_UUID); + appointment.setPatient(patient); + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference patientReference = new Reference().setReference(FhirConstants.PATIENT + "/" + PATIENT_UUID) + .setType(FhirConstants.PATIENT).setIdentifier(new Identifier().setValue(PATIENT_UUID)); + participantComponent.setActor(patientReference); + + when(patientTranslator.toFhirResource(patient)).thenReturn(participantComponent); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getParticipant().size(), greaterThanOrEqualTo(1)); + assertThat(result.getParticipant().get(0).getActor(), equalTo(patientReference)); + } + + @Test + public void toFhirTypeShouldAddAppointmentProviderAsParticipant() { + Provider provider = new Provider(); + provider.setUuid(PROVIDER_UUID); + Set appointmentProviders = new HashSet<>(); + AppointmentProvider appointmentProvider = new AppointmentProvider(); + appointmentProvider.setProvider(provider); + appointmentProviders.add(appointmentProvider); + appointment.setProviders(appointmentProviders); + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference providerReference = new Reference().setReference(FhirConstants.PRACTITIONER + "/" + PROVIDER_UUID) + .setType(FhirConstants.PRACTITIONER).setIdentifier(new Identifier().setValue(PROVIDER_UUID)); + participantComponent.setActor(providerReference); + + when(appointmentParticipantTranslator.toFhirResource(appointmentProvider)).thenReturn(participantComponent); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getParticipant().size(), greaterThanOrEqualTo(1)); + assertThat(result.getParticipant().get(0).getActor(), equalTo(providerReference)); + } + + @Test + public void toFhirTypeShouldAddProviderAsParticipant() { + Provider provider = new Provider(); + provider.setUuid(PROVIDER_UUID); + appointment.setProvider(provider); + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference providerReference = new Reference().setReference(FhirConstants.PRACTITIONER + "/" + PROVIDER_UUID) + .setType(FhirConstants.PRACTITIONER).setIdentifier(new Identifier().setValue(PROVIDER_UUID)); + participantComponent.setActor(providerReference); + + when(providerTranslator.toFhirResource(provider)).thenReturn(participantComponent); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getParticipant().size(), greaterThanOrEqualTo(1)); + assertThat(result.getParticipant().get(0).getActor(), equalTo(providerReference)); + } + + @Test + public void toFhirTypeShouldReturnNullIfAppointmentServiceDefinitionIsNull() { + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getParticipant().isEmpty(), equalTo(true)); + } + + @Test + public void toFhirTypeShouldAddHealthCareServiceAsParticipant() { + AppointmentServiceDefinition appointmentService = new AppointmentServiceDefinition(); + appointmentService.setUuid(SERVICE_UUID); + appointmentService.setName("Outpatient"); + appointment.setService(appointmentService); + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference serviceReference = new Reference().setReference("HealthCareService" + "/" + SERVICE_UUID) + .setType("HealthCareService").setIdentifier(new Identifier().setValue(SERVICE_UUID)); + participantComponent.setActor(serviceReference); + + when(serviceDefinitionAppointmentParticipantTranslator.toFhirResource(appointmentService)).thenReturn(participantComponent); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getParticipant().size(), greaterThanOrEqualTo(1)); + assertThat(result.getParticipant().get(0).getActor(), equalTo(serviceReference)); + } + + @Test + public void toFhirTypeShouldReturnNullIfServiceTypeIsNull() { + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getServiceType().isEmpty(), equalTo(true)); + } + + @Test + public void toFhirTypeShouldTranslateServiceTypeCorrectly() { + AppointmentServiceType serviceType = new AppointmentServiceType(); + serviceType.setUuid(SERVICE_TYPE_UUID); + appointment.setServiceType(serviceType); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getServiceType().size(), greaterThanOrEqualTo(1)); + assertThat(result.getServiceType().get(0).getCoding().get(0).getCode(), equalTo(SERVICE_TYPE_UUID)); + } + + @Test + public void toFhirTypeShouldReturnNullIfAppointmentKindIsNull() { + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getAppointmentType().isEmpty(), equalTo(true)); + } + + @Test + public void toFhirTypeShouldTranslateScheduledToRoutineAppointmentTyeRoutine() { + appointment.setAppointmentKind(AppointmentKind.Scheduled); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getAppointmentType(), notNullValue()); + assertThat(result.getAppointmentType().getCoding().get(0).getCode(), equalTo("ROUTINE")); + } + + @Test + public void toFhirTypeShouldTranslateWalkInToRoutineAppointmentTyeWalkIn() { + appointment.setAppointmentKind(AppointmentKind.WalkIn); + + org.hl7.fhir.r4.model.Appointment result = appointmentTranslator.toFhirResource(appointment); + assertThat(result, notNullValue()); + assertThat(result.getAppointmentType(), notNullValue()); + assertThat(result.getAppointmentType().getCoding().get(0).getCode(), equalTo("WALKIN")); + } + + + + + + + + + + + + + @Test + public void toOpenmrsTypeShouldTranslateIdToUuid() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setId(APPOINTMENT_UUID); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getUuid(), equalTo(APPOINTMENT_UUID)); + } + + @Test + public void toOpenmrsTypeShouldMapStatusProposedToRequested() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStatus(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.PROPOSED); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(AppointmentStatus.Requested)); + } + + @Test + public void toOpenmrsTypeShouldMapStatusBookedToScheduled() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStatus(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.BOOKED); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(AppointmentStatus.Scheduled)); + } + + @Test + public void toOpenmrsTypeShouldMapStatusCheckedInToCheckedIn() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStatus(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.CHECKEDIN); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(AppointmentStatus.CheckedIn)); + } + + @Test + public void toOpenmrsTypeShouldMapStatusNoShowToMissed() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStatus(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.NOSHOW); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(AppointmentStatus.Missed)); + } + + @Test + public void toOpenmrsTypeShouldMapStatusCancelledToCancelled() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStatus(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.CANCELLED); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(AppointmentStatus.Cancelled)); + } + + @Test + public void toOpenmrsTypeShouldMapStatusFulfilledToCompleted() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStatus(org.hl7.fhir.r4.model.Appointment.AppointmentStatus.FULFILLED); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStatus(), equalTo(AppointmentStatus.Completed)); + } + + @Test + public void toOpenmrsTypeShouldMapStartToStartDateTime() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setStart(new Date()); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getStartDateTime(), DateMatchers.sameDay(new Date())); + } + + @Test + public void toOpenmrsTypeShouldMapEndToEndDateTime() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setEnd(new Date()); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getEndDateTime(), DateMatchers.sameDay(new Date())); + } + + @Test + public void toOpenmrsTypeShouldMapFhirCommentToComments() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setComment("Test Appointment"); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getComments(), equalTo("Test Appointment")); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantToPatient() { + Patient patient = new Patient(); + patient.setUuid(PATIENT_UUID); + appointment.setPatient(patient); + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference patientReference = new Reference().setReference(FhirConstants.PATIENT + "/" + PATIENT_UUID) + .setType(FhirConstants.PATIENT).setIdentifier(new Identifier().setValue(PATIENT_UUID)); + participantComponent.setActor(patientReference); + participantComponent.addType(new CodeableConcept().addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "Patient", "Patient"))); + + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.addParticipant(participantComponent); + + when(patientTranslator.toOpenmrsType(participantComponent)).thenReturn(patient); + + Appointment result = appointmentTranslator.toOpenmrsType(appointment); + assertThat(result, notNullValue()); + assertThat(result.getPatient(), notNullValue()); + assertThat(result.getPatient(), equalTo(patient)); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantToAppointmentProvider() { + Provider provider = new Provider(); + provider.setUuid(PROVIDER_UUID); + AppointmentProvider appointmentProvider = new AppointmentProvider(); + appointmentProvider.setProvider(provider); + + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference providerReference = new Reference().setReference(FhirConstants.PRACTITIONER + "/" + PROVIDER_UUID) + .setType(FhirConstants.PRACTITIONER).setIdentifier(new Identifier().setValue(PROVIDER_UUID)); + participantComponent.setActor(providerReference); + participantComponent.addType(new CodeableConcept().addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "AppointmentPractitioner", "AppointmentPractitioner"))); + + + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.addParticipant(participantComponent); + + when(appointmentParticipantTranslator.toOpenmrsType(participantComponent)).thenReturn(appointmentProvider); + + Appointment result = appointmentTranslator.toOpenmrsType(appointment); + assertThat(result, notNullValue()); + assertThat(result.getProviders().size(), greaterThanOrEqualTo(1)); + assertThat(result.getProviders().iterator().next().getProvider(), equalTo(provider)); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantToProvider() { + Provider provider = new Provider(); + provider.setUuid(PROVIDER_UUID); + + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference providerReference = new Reference().setReference(FhirConstants.PRACTITIONER + "/" + PROVIDER_UUID) + .setType(FhirConstants.PRACTITIONER).setIdentifier(new Identifier().setValue(PROVIDER_UUID)); + participantComponent.setActor(providerReference); + participantComponent.addType(new CodeableConcept().addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "Practitioner", "Practitioner"))); + + + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.addParticipant(participantComponent); + + when(providerTranslator.toOpenmrsType(participantComponent)).thenReturn(provider); + + Appointment result = appointmentTranslator.toOpenmrsType(appointment); + assertThat(result, notNullValue()); + assertThat(result.getProvider(), notNullValue()); + assertThat(result.getProvider(), equalTo(provider)); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantToAppointmentService() { + AppointmentServiceDefinition appointmentService = new AppointmentServiceDefinition(); + appointmentService.setUuid(SERVICE_UUID); + appointmentService.setName("Outpatient"); + + org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent participantComponent = new org.hl7.fhir.r4.model.Appointment.AppointmentParticipantComponent(); + Reference serviceReference = new Reference().setReference("HealthCareService" + "/" + SERVICE_UUID) + .setType("HealthCareService").setIdentifier(new Identifier().setValue(SERVICE_UUID)); + participantComponent.setActor(serviceReference); + participantComponent.addType(new CodeableConcept().addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE, "HealthCareService", "HealthCareService"))); + + + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.addParticipant(participantComponent); + + when(serviceDefinitionAppointmentParticipantTranslator.toOpenmrsType(participantComponent)).thenReturn(appointmentService); + + Appointment result = appointmentTranslator.toOpenmrsType(appointment); + assertThat(result, notNullValue()); + assertThat(result.getService(), notNullValue()); + assertThat(result.getService(), equalTo(appointmentService)); + } + + @Test + public void toOpenmrsTypeShouldTranslateServiceTypeCorrectly() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.addServiceType(new CodeableConcept().addCoding(new Coding("", SERVICE_TYPE_UUID,"OutPatient"))); + + AppointmentServiceType serviceType = new AppointmentServiceType(); + serviceType.setUuid(SERVICE_TYPE_UUID); + + when(appointmentServiceDefinitionService.getAppointmentServiceTypeByUuid(SERVICE_TYPE_UUID)).thenReturn(serviceType); + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getServiceType().getUuid(), equalTo(SERVICE_TYPE_UUID)); + } + + @Test + public void toOpenmrsTypeShouldTranslateAppointmentTypeScheduledCorrectly() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setAppointmentType(new CodeableConcept().addCoding(new Coding("", "ROUTINE",""))); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getAppointmentKind(), equalTo(AppointmentKind.Scheduled)); + } + + @Test + public void toOpenmrsTypeShouldTranslateAppointmentTypeWalkInCorrectly() { + org.hl7.fhir.r4.model.Appointment appointment = new org.hl7.fhir.r4.model.Appointment(); + appointment.setAppointmentType(new CodeableConcept().addCoding(new Coding("", "WALKIN",""))); + + Appointment result = appointmentTranslator.toOpenmrsType(new Appointment(), appointment); + assertThat(result, notNullValue()); + assertThat(result.getAppointmentKind(), equalTo(AppointmentKind.WalkIn)); + } + +} + diff --git a/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceParticipantTranslatorImplTest.java b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceParticipantTranslatorImplTest.java new file mode 100644 index 000000000..02b7f3afc --- /dev/null +++ b/fhir2-appnt-api/src/test/java/org/openmrs/module/fhirappnt/api/translators/impl/HealthCareServiceParticipantTranslatorImplTest.java @@ -0,0 +1,100 @@ +package org.openmrs.module.fhirappnt.api.translators.impl; + +import org.hl7.fhir.r4.model.Appointment; +import org.hl7.fhir.r4.model.Identifier; +import org.hl7.fhir.r4.model.Reference; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.openmrs.module.appointments.model.AppointmentServiceDefinition; +import org.openmrs.module.appointments.service.AppointmentServiceDefinitionService; +import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HealthCareServiceParticipantTranslatorImplTest { + + private static String SERVICE_UUID = "162298AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; + + @Mock + AppointmentServiceDefinitionService appointmentServiceDefinitionService; + + private HealthCareServiceParticipantTranslatorImpl healthCareServiceParticipantTranslator; + + @Before + public void setup() { + healthCareServiceParticipantTranslator = new HealthCareServiceParticipantTranslatorImpl(); + healthCareServiceParticipantTranslator.setAppointmentServiceDefinitionService(appointmentServiceDefinitionService); + } + + @Test + public void toFhirResourceShouldReturnNullIfHealthCareServiceIsNull() { + Appointment.AppointmentParticipantComponent participantComponent = healthCareServiceParticipantTranslator.toFhirResource(null); + assertThat(participantComponent, nullValue()); + } + + @Test + public void toFhirResourceShouldSetRoleToHealthCareService() { + AppointmentServiceDefinition appointmentServiceDefinition = new AppointmentServiceDefinition(); + Appointment.AppointmentParticipantComponent participantComponent = healthCareServiceParticipantTranslator.toFhirResource(appointmentServiceDefinition); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getSystem(), equalTo(AppointmentFhirConstants.APPOINTMENT_PARTICIPANT_TYPE)); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getCode(), equalTo("HealthCareService")); + assertThat(participantComponent.getType().get(0).getCoding().get(0).getDisplay(), equalTo("HealthCareService")); + } + + @Test + public void toFhirResourceShouldSetParticipantToRequired() { + AppointmentServiceDefinition appointmentServiceDefinition = new AppointmentServiceDefinition(); + Appointment.AppointmentParticipantComponent participantComponent = healthCareServiceParticipantTranslator.toFhirResource(appointmentServiceDefinition); + assertThat(participantComponent, notNullValue()); + assertThat(participantComponent.getRequired(), equalTo(Appointment.ParticipantRequired.OPTIONAL)); + } + + + @Test + public void toFhirResourceShouldSetActorToHealthCareService() { + AppointmentServiceDefinition serviceDefinition = new AppointmentServiceDefinition(); + serviceDefinition.setUuid(SERVICE_UUID); + + Reference serviceReference = new Reference().setReference("HealthCareService" + "/" + SERVICE_UUID) + .setType("HealthCareService").setIdentifier(new Identifier().setValue(SERVICE_UUID)); + + Appointment.AppointmentParticipantComponent result = healthCareServiceParticipantTranslator.toFhirResource(serviceDefinition); + assertThat(result, notNullValue()); + assertThat(result.getActor().getType(), equalTo("HealthCareService")); + assertThat(result.getActor().getReference().contains(SERVICE_UUID), equalTo(true)); + } + + @Test + public void toOpenmrsTypeShouldReturnAnEmptyParticipantObject() { + AppointmentServiceDefinition serviceDefinition = healthCareServiceParticipantTranslator.toOpenmrsType(null); + assertThat(serviceDefinition, nullValue()); + } + + @Test + public void toOpenmrsTypeShouldTranslateParticipantActorToHealthCareService() { + AppointmentServiceDefinition serviceDefinition = new AppointmentServiceDefinition(); + serviceDefinition.setUuid(SERVICE_UUID); + Appointment.AppointmentParticipantComponent participantComponent = new Appointment.AppointmentParticipantComponent(); + + Reference serviceReference = new Reference().setReference("HealthCareService" + "/" + SERVICE_UUID) + .setType("HealthCareService").setIdentifier(new Identifier().setValue(SERVICE_UUID)); + + participantComponent.setActor(serviceReference); + + when(appointmentServiceDefinitionService.getAppointmentServiceByUuid(SERVICE_UUID)).thenReturn(serviceDefinition); + + AppointmentServiceDefinition result = healthCareServiceParticipantTranslator.toOpenmrsType(new AppointmentServiceDefinition(), participantComponent); + assertThat(result, notNullValue()); + assertThat(result.getUuid(), notNullValue()); + assertThat(result.getUuid(), equalTo(SERVICE_UUID)); + } +} diff --git a/omod/pom.xml b/omod/pom.xml index bc249308e..8f5aaadb0 100644 --- a/omod/pom.xml +++ b/omod/pom.xml @@ -26,6 +26,11 @@ ${project.parent.artifactId}-api ${project.parent.version} + + ${project.parent.groupId} + fhir2-appointment-api + ${openmrsModuleFhirVersion} + org.openmrs.web openmrs-web diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 6cf728367..62da8afcf 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -16,6 +16,10 @@ org.ict4h.openmrs.openmrs-atomfeed + + org.openmrs.module.fhir2 + + Speciality.hbm.xml AppointmentServiceDefinition.hbm.xml diff --git a/pom.xml b/pom.xml index 92c4c5c22..0227ecff9 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ api omod + fhir2-appnt-api @@ -25,6 +26,8 @@ 0.7.9 2.5.6 1.9.4 + 1.18.10 + 1.0.0-SNAPSHOT @@ -165,6 +168,19 @@ test + + org.openmrs.module + fhir2-api + ${openmrsModuleFhirVersion} + provided + + + org.projectlombok + lombok + ${lombokVersion} + provided + + junit junit