Skip to content

Commit f56afeb

Browse files
committed
FM2-136 : Fhir appointment resource initial implementation
1 parent 1960eeb commit f56afeb

File tree

15 files changed

+745
-0
lines changed

15 files changed

+745
-0
lines changed

fhir2-appnt-api/pom.xml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>appointments</artifactId>
7+
<groupId>org.openmrs.module</groupId>
8+
<version>1.2-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<groupId>org.openmrs.module</groupId>
13+
<artifactId>fhir2-appointment-api</artifactId>
14+
<version>${openmrsModuleFhirVersion}</version>
15+
<packaging>jar</packaging>
16+
<name>FHIR Appointment API</name>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>${project.parent.groupId}</groupId>
21+
<artifactId>${project.parent.artifactId}-api</artifactId>
22+
<version>${project.parent.version}</version>
23+
<scope>provided</scope>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.openmrs.module</groupId>
27+
<artifactId>fhir2-api</artifactId>
28+
<version>${openmrsModuleFhirVersion}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>org.openmrs.api</groupId>
32+
<artifactId>openmrs-api</artifactId>
33+
<version>${openmrs.platform.version}</version>
34+
<scope>provided</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.openmrs.api</groupId>
38+
<artifactId>openmrs-api</artifactId>
39+
<version>${openmrs.platform.version}</version>
40+
<classifier>tests</classifier>
41+
<scope>test</scope>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.projectlombok</groupId>
45+
<artifactId>lombok</artifactId>
46+
</dependency>
47+
48+
<dependency>
49+
<groupId>org.mockito</groupId>
50+
<artifactId>mockito-core</artifactId>
51+
<scope>test</scope>
52+
</dependency>
53+
<dependency>
54+
<groupId>org.hamcrest</groupId>
55+
<artifactId>hamcrest-core</artifactId>
56+
<version>${hamcrestCoreVersion}</version>
57+
<scope>test</scope>
58+
</dependency>
59+
<dependency>
60+
<groupId>org.exparity</groupId>
61+
<artifactId>hamcrest-date</artifactId>
62+
<version>${hamcrestDateVersion}</version>
63+
<scope>test</scope>
64+
</dependency>
65+
</dependencies>
66+
67+
<build>
68+
<plugins>
69+
<plugin>
70+
<groupId>com.mycila</groupId>
71+
<artifactId>license-maven-plugin</artifactId>
72+
</plugin>
73+
<plugin>
74+
<groupId>org.projectlombok</groupId>
75+
<artifactId>lombok-maven-plugin</artifactId>
76+
</plugin>
77+
<plugin>
78+
<groupId>net.revelc.code.formatter</groupId>
79+
<artifactId>formatter-maven-plugin</artifactId>
80+
</plugin>
81+
<plugin>
82+
<groupId>net.revelc.code</groupId>
83+
<artifactId>impsort-maven-plugin</artifactId>
84+
</plugin>
85+
</plugins>
86+
</build>
87+
88+
<properties>
89+
<hamcrestDateVersion>2.0.7</hamcrestDateVersion>
90+
<hamcrestCoreVersion>2.2</hamcrestCoreVersion>
91+
</properties>
92+
93+
</project>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.openmrs.module.fhirappnt.api;
2+
3+
import lombok.NoArgsConstructor;
4+
import org.openmrs.module.fhir2.FhirConstants;
5+
6+
@NoArgsConstructor
7+
public class AppointmentFhirConstants extends FhirConstants {
8+
9+
public static final String APPOINTMENT_SPECIALITY_VALUESET_URI = HL7_FHIR_VALUE_SET_PREFIX
10+
+ "/c80-practice-codes";
11+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.openmrs.module.fhirappnt.api.Impl;
2+
3+
import lombok.AccessLevel;
4+
import lombok.Setter;
5+
import org.openmrs.module.appointments.model.Appointment;
6+
import org.openmrs.module.fhir2.api.FhirAppointmentService;
7+
import org.openmrs.module.fhir2.api.dao.FhirAppointmentDao;
8+
import org.openmrs.module.fhir2.api.translators.AppointmentTranslator;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.stereotype.Component;
11+
import org.springframework.transaction.annotation.Transactional;
12+
13+
@Component
14+
@Transactional
15+
@Setter(AccessLevel.PACKAGE)
16+
public class FhirBahmniAppointmentServiceImpl implements FhirAppointmentService {
17+
18+
@Autowired
19+
private AppointmentTranslator<Appointment> appointmentTranslator;
20+
21+
@Autowired
22+
private FhirAppointmentDao<Appointment> fhirAppointmentDao;
23+
24+
public void setFhirAppointmentDao(FhirAppointmentDao<Appointment> fhirAppointmentDao) {
25+
this.fhirAppointmentDao = fhirAppointmentDao;
26+
}
27+
28+
public void setAppointmentTranslator(AppointmentTranslator<Appointment> appointmentTranslator) {
29+
this.appointmentTranslator = appointmentTranslator;
30+
}
31+
32+
@Override
33+
public org.hl7.fhir.r4.model.Appointment getAppointmentByUuid(String uuid) {
34+
return appointmentTranslator.toFhirResource(fhirAppointmentDao.getAppointmentByUuid(uuid));
35+
}
36+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.openmrs.module.fhirappnt.api.dao.impl;
2+
3+
import lombok.AccessLevel;
4+
import lombok.Setter;
5+
import org.openmrs.module.appointments.model.Appointment;
6+
import org.openmrs.module.appointments.service.AppointmentsService;
7+
import org.openmrs.module.fhir2.api.dao.FhirAppointmentDao;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.stereotype.Component;
10+
11+
@Component
12+
@Setter(AccessLevel.PACKAGE)
13+
public class FhirAppointmentDaoImpl implements FhirAppointmentDao<Appointment> {
14+
15+
@Autowired
16+
private AppointmentsService appointmentsService;
17+
18+
@Override
19+
public Appointment getAppointmentByUuid(String uuid) {
20+
return appointmentsService.getAppointmentByUuid(uuid);
21+
}
22+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.openmrs.module.fhirappnt.api.translators;
2+
3+
import org.hl7.fhir.r4.model.CodeableConcept;
4+
import org.openmrs.module.appointments.model.Speciality;
5+
import org.openmrs.module.fhir2.api.translators.OpenmrsFhirUpdatableTranslator;
6+
7+
public interface AppointmentSpecialityTranslator extends OpenmrsFhirUpdatableTranslator<Speciality, CodeableConcept>{
8+
9+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.openmrs.module.fhirappnt.api.translators.impl;
2+
3+
import org.hl7.fhir.r4.model.CodeableConcept;
4+
import org.hl7.fhir.r4.model.Coding;
5+
import org.openmrs.module.fhirappnt.api.AppointmentFhirConstants;
6+
import org.openmrs.module.fhirappnt.api.translators.AppointmentSpecialityTranslator;
7+
import org.openmrs.module.appointments.model.Speciality;
8+
import org.springframework.stereotype.Component;
9+
10+
@Component
11+
public class AppointmentSpecialityTranslatorImpl implements AppointmentSpecialityTranslator {
12+
13+
@Override
14+
public CodeableConcept toFhirResource(Speciality speciality) {
15+
if (speciality == null) {
16+
return null;
17+
}
18+
19+
CodeableConcept code = new CodeableConcept();
20+
code.addCoding(new Coding(AppointmentFhirConstants.APPOINTMENT_SPECIALITY_VALUESET_URI,speciality.getUuid(), speciality.getName()));
21+
22+
return code;
23+
}
24+
25+
@Override
26+
public Speciality toOpenmrsType(CodeableConcept codeableConcept) {
27+
return toOpenmrsType(new Speciality(), codeableConcept);
28+
}
29+
30+
@Override
31+
public Speciality toOpenmrsType(Speciality speciality, CodeableConcept codeableConcept) {
32+
if (codeableConcept == null) {
33+
return speciality;
34+
}
35+
36+
if (codeableConcept.hasCoding()) {
37+
speciality.setUuid(codeableConcept.getCoding().get(0).getCode());
38+
speciality.setName(codeableConcept.getCoding().get(0).getDisplay());
39+
}
40+
41+
return speciality;
42+
}
43+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package org.openmrs.module.fhirappnt.api.translators.impl;
2+
3+
import lombok.AccessLevel;
4+
import lombok.Setter;
5+
import org.hl7.fhir.r4.model.Appointment;
6+
import org.openmrs.module.appointments.model.AppointmentStatus;
7+
import org.openmrs.module.fhir2.api.translators.AppointmentTranslator;
8+
import org.springframework.stereotype.Component;
9+
10+
11+
@Component
12+
@Setter(AccessLevel.PACKAGE)
13+
public class AppointmentTranslatorImpl implements AppointmentTranslator<org.openmrs.module.appointments.model.Appointment> {
14+
15+
@Override
16+
public Appointment toFhirResource(org.openmrs.module.appointments.model.Appointment appointment) {
17+
Appointment fhirAppointment = new Appointment();
18+
fhirAppointment.setId(appointment.getUuid());
19+
fhirAppointment.setStart(appointment.getStartDateTime());
20+
fhirAppointment.setEnd(appointment.getEndDateTime());
21+
22+
switch (appointment.getStatus()) {
23+
case Requested :
24+
fhirAppointment.setStatus(Appointment.AppointmentStatus.PROPOSED);
25+
break;
26+
case Scheduled:
27+
fhirAppointment.setStatus(Appointment.AppointmentStatus.BOOKED);
28+
break;
29+
case CheckedIn:
30+
fhirAppointment.setStatus(Appointment.AppointmentStatus.CHECKEDIN);
31+
break;
32+
case Completed:
33+
fhirAppointment.setStatus(Appointment.AppointmentStatus.FULFILLED);
34+
break;
35+
case Missed:
36+
fhirAppointment.setStatus(Appointment.AppointmentStatus.NOSHOW);
37+
break;
38+
case Cancelled:
39+
fhirAppointment.setStatus(Appointment.AppointmentStatus.CANCELLED);
40+
break;
41+
}
42+
43+
fhirAppointment.setComment(appointment.getComments());
44+
fhirAppointment.setCreated(appointment.getDateCreated());
45+
fhirAppointment.getMeta().setLastUpdated(appointment.getDateChanged());
46+
47+
return fhirAppointment;
48+
}
49+
50+
@Override
51+
public org.openmrs.module.appointments.model.Appointment toOpenmrsType(Appointment appointment) {
52+
return toOpenmrsType(new org.openmrs.module.appointments.model.Appointment(), appointment);
53+
}
54+
55+
@Override
56+
public org.openmrs.module.appointments.model.Appointment toOpenmrsType(org.openmrs.module.appointments.model.Appointment appointment, Appointment fhirAppointment) {
57+
appointment.setUuid(fhirAppointment.getId());
58+
appointment.setStartDateTime(fhirAppointment.getStart());
59+
appointment.setEndDateTime(fhirAppointment.getEnd());
60+
61+
if (fhirAppointment.hasStatus()) {
62+
switch (fhirAppointment.getStatus()) {
63+
case PROPOSED:
64+
appointment.setStatus(AppointmentStatus.Requested);
65+
break;
66+
case BOOKED:
67+
appointment.setStatus(AppointmentStatus.Scheduled);
68+
break;
69+
case CHECKEDIN:
70+
appointment.setStatus(AppointmentStatus.CheckedIn);
71+
break;
72+
case FULFILLED:
73+
appointment.setStatus(AppointmentStatus.Completed);
74+
break;
75+
case NOSHOW:
76+
appointment.setStatus(AppointmentStatus.Missed);
77+
break;
78+
case CANCELLED:
79+
appointment.setStatus(AppointmentStatus.Cancelled);
80+
break;
81+
}
82+
}
83+
appointment.setComments(fhirAppointment.getComment());
84+
85+
return appointment;
86+
}
87+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.openmrs.module;
2+
3+
import org.springframework.context.annotation.Configuration;
4+
import org.springframework.context.annotation.ImportResource;
5+
6+
@Configuration
7+
@ImportResource({ "classpath:applicationContext-service.xml", "classpath*:moduleApplicationContext.xml" })
8+
public class TestFhirSpringConfiguration {
9+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.openmrs.module.fhirappnt.api.dao.impl;
2+
3+
import org.junit.Before;
4+
import org.junit.Test;
5+
import org.junit.runner.RunWith;
6+
import org.mockito.Mock;
7+
8+
import static org.hamcrest.CoreMatchers.nullValue;
9+
import static org.mockito.Mockito.when;
10+
11+
import org.mockito.runners.MockitoJUnitRunner;
12+
import org.openmrs.module.appointments.model.Appointment;
13+
import org.openmrs.module.appointments.service.AppointmentsService;
14+
15+
import static org.hamcrest.CoreMatchers.equalTo;
16+
import static org.hamcrest.CoreMatchers.notNullValue;
17+
import static org.hamcrest.MatcherAssert.assertThat;
18+
19+
@RunWith(MockitoJUnitRunner.class)
20+
public class FhirAppointmentDaoImplTest {
21+
22+
private static final String APPOINTMENT_UUID = "75504r42-3ca8-11e3-bf2b-0800271c1b77";
23+
24+
private static final String WRONG_APPOINTMENT_UUID = "1099AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
25+
26+
@Mock
27+
private AppointmentsService appointmentsService;
28+
29+
private FhirAppointmentDaoImpl fhirAppointmentDao;
30+
31+
private Appointment appointment;
32+
33+
@Before
34+
public void setup() {
35+
fhirAppointmentDao = new FhirAppointmentDaoImpl();
36+
fhirAppointmentDao.setAppointmentsService(appointmentsService);
37+
38+
appointment = new Appointment();
39+
}
40+
41+
@Test
42+
public void shouldGetAppointmentByUuid() {
43+
appointment.setUuid(APPOINTMENT_UUID);
44+
when(appointmentsService.getAppointmentByUuid(APPOINTMENT_UUID)).thenReturn(appointment);
45+
Appointment appointment = fhirAppointmentDao.getAppointmentByUuid(APPOINTMENT_UUID);
46+
assertThat(appointment, notNullValue());
47+
assertThat(appointment.getUuid(), notNullValue());
48+
assertThat(appointment.getUuid(), equalTo(APPOINTMENT_UUID));
49+
}
50+
51+
@Test
52+
public void shouldReturnNullWhenGetAppointmentIsCalledWithUnknownUuid() {
53+
Appointment appointment = fhirAppointmentDao.getAppointmentByUuid(WRONG_APPOINTMENT_UUID);
54+
assertThat(appointment, nullValue());
55+
}
56+
}

0 commit comments

Comments
 (0)