Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 7490d63

Browse files
Merge pull request SORMAS-Foundation#2887 from hzi-braunschweig/feat-2724-task-creation
SORMAS-Foundation#2724 Add task creation on contact creation
2 parents de05d4d + 7ffeb1e commit 7490d63

6 files changed

Lines changed: 217 additions & 63 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package de.symeda.sormas.backend.common;
2+
3+
@SuppressWarnings("serial")
4+
public class TaskCreationException extends Exception {
5+
6+
public TaskCreationException(String message) {
7+
super(message);
8+
}
9+
}

sormas-backend/src/main/java/de/symeda/sormas/backend/contact/ContactFacadeEjb.java

Lines changed: 46 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package de.symeda.sormas.backend.contact;
1919

2020
import static de.symeda.sormas.backend.visit.VisitLogic.getVisitResult;
21+
import static java.time.temporal.ChronoUnit.DAYS;
2122

2223
import java.math.BigInteger;
2324
import java.sql.Timestamp;
@@ -30,7 +31,6 @@
3031
import java.util.List;
3132
import java.util.Map;
3233
import java.util.Optional;
33-
import java.util.Random;
3434
import java.util.function.Function;
3535
import java.util.stream.Collectors;
3636
import java.util.stream.Stream;
@@ -58,6 +58,7 @@
5858
import org.slf4j.Logger;
5959
import org.slf4j.LoggerFactory;
6060

61+
import de.symeda.sormas.api.CountryHelper;
6162
import de.symeda.sormas.api.Disease;
6263
import de.symeda.sormas.api.Language;
6364
import de.symeda.sormas.api.caze.CaseReferenceDto;
@@ -117,6 +118,8 @@
117118
import de.symeda.sormas.backend.clinicalcourse.ClinicalCourseFacadeEjb;
118119
import de.symeda.sormas.backend.common.AbstractAdoService;
119120
import de.symeda.sormas.backend.common.AbstractDomainObject;
121+
import de.symeda.sormas.backend.common.ConfigFacadeEjb;
122+
import de.symeda.sormas.backend.common.TaskCreationException;
120123
import de.symeda.sormas.backend.epidata.EpiData;
121124
import de.symeda.sormas.backend.epidata.EpiDataFacadeEjb;
122125
import de.symeda.sormas.backend.epidata.EpiDataFacadeEjb.EpiDataFacadeEjbLocal;
@@ -193,6 +196,8 @@ public class ContactFacadeEjb implements ContactFacade {
193196
private EpiDataFacadeEjbLocal epiDataFacade;
194197
@EJB
195198
private ClinicalCourseFacadeEjb.ClinicalCourseFacadeEjbLocal clinicalCourseFacade;
199+
@EJB
200+
private ConfigFacadeEjb.ConfigFacadeEjbLocal configFacade;
196201

197202
@Override
198203
public List<String> getAllActiveUuids() {
@@ -274,9 +279,10 @@ public ContactDto saveContact(ContactDto dto, boolean handleChanges) {
274279
// }
275280

276281
Contact entity = fromDto(dto);
277-
278282
contactService.ensurePersisted(entity);
279283

284+
createInvestigationTask(entity);
285+
280286
if (handleChanges) {
281287
updateContactVisitAssociations(existingContactDto, entity);
282288

@@ -291,6 +297,22 @@ public ContactDto saveContact(ContactDto dto, boolean handleChanges) {
291297
return toDto(entity);
292298
}
293299

300+
private void createInvestigationTask(Contact entity) {
301+
LocalDate now = LocalDate.now();
302+
LocalDate reportDate = DateHelper8.toLocalDate(entity.getReportDateTime());
303+
if (DAYS.between(reportDate, now) <= 30) {
304+
try {
305+
User assignee = taskService.getTaskAssignee(entity);
306+
LocalDateTime fromDateTime = LocalDate.now().atStartOfDay();
307+
LocalDateTime toDateTime = fromDateTime.plusDays(1);
308+
Task task = createContactTask(TaskType.CONTACT_INVESTIGATION, fromDateTime, toDateTime, entity, assignee);
309+
taskService.ensurePersisted(task);
310+
} catch (TaskCreationException e) {
311+
logger.warn(e.getMessage());
312+
}
313+
}
314+
}
315+
294316
private void updateContactVisitAssociations(ContactDto existingContact, Contact contact) {
295317

296318
if (existingContact != null
@@ -1232,47 +1254,12 @@ public void generateContactFollowUpTasks() {
12321254
continue;
12331255
}
12341256

1235-
User assignee = null;
1236-
if (contact.getContactOfficer() != null) {
1237-
// 1) The contact officer that is responsible for the contact
1238-
assignee = contact.getContactOfficer();
1239-
} else {
1240-
// 2) A random contact officer from the contact's, contact person's or contact case's district
1241-
List<User> officers = new ArrayList<>();
1242-
if (contact.getDistrict() != null) {
1243-
officers = userService.getAllByDistrict(contact.getDistrict(), false, UserRole.CONTACT_OFFICER);
1244-
}
1245-
if (officers.isEmpty() && contact.getPerson().getAddress().getDistrict() != null) {
1246-
officers = userService.getAllByDistrict(contact.getPerson().getAddress().getDistrict(), false, UserRole.CONTACT_OFFICER);
1247-
}
1248-
if (officers.isEmpty() && contact.getCaze() != null && contact.getCaze().getDistrict() != null) {
1249-
officers = userService.getAllByDistrict(contact.getCaze().getDistrict(), false, UserRole.CONTACT_OFFICER);
1250-
}
1251-
if (!officers.isEmpty()) {
1252-
Random rand = new Random();
1253-
assignee = officers.get(rand.nextInt(officers.size()));
1254-
}
1255-
}
1256-
1257-
if (assignee == null) {
1258-
// 3) Assign a random contact supervisor from the contact's, contact person's or contact case's region
1259-
List<User> supervisors = new ArrayList<>();
1260-
if (contact.getRegion() != null) {
1261-
supervisors = userService.getAllByRegionAndUserRoles(contact.getRegion(), UserRole.CONTACT_SUPERVISOR);
1262-
}
1263-
if (supervisors.isEmpty() && contact.getPerson().getAddress().getRegion() != null) {
1264-
supervisors = userService.getAllByRegionAndUserRoles(contact.getPerson().getAddress().getRegion(), UserRole.CONTACT_SUPERVISOR);
1265-
}
1266-
if (supervisors.isEmpty()) {
1267-
supervisors = userService.getAllByRegionAndUserRoles(contact.getCaze().getRegion(), UserRole.CONTACT_SUPERVISOR);
1268-
}
1269-
if (!supervisors.isEmpty()) {
1270-
Random rand = new Random();
1271-
assignee = supervisors.get(rand.nextInt(supervisors.size()));
1272-
} else {
1273-
logger.warn("Contact has not contact officer and no region - can't create follow-up task: " + contact.getUuid());
1274-
continue;
1275-
}
1257+
User assignee;
1258+
try {
1259+
assignee = taskService.getTaskAssignee(contact);
1260+
} catch (TaskCreationException e) {
1261+
logger.warn(e.getMessage());
1262+
continue;
12761263
}
12771264

12781265
// find already existing tasks
@@ -1298,22 +1285,26 @@ public void generateContactFollowUpTasks() {
12981285
}
12991286

13001287
// none found -> create the task
1301-
Task task = taskService.buildTask(null);
1302-
task.setTaskContext(TaskContext.CONTACT);
1303-
task.setContact(contact);
1304-
task.setTaskType(TaskType.CONTACT_FOLLOW_UP);
1305-
task.setSuggestedStart(DateHelper8.toDate(fromDateTime));
1306-
task.setDueDate(DateHelper8.toDate(toDateTime.minusMinutes(1)));
1307-
task.setAssigneeUser(assignee);
1308-
1309-
if (contact.isHighPriority()) {
1310-
task.setPriority(TaskPriority.HIGH);
1311-
}
1312-
1288+
Task task = createContactTask(TaskType.CONTACT_FOLLOW_UP, fromDateTime, toDateTime, contact, assignee);
13131289
taskService.ensurePersisted(task);
13141290
}
13151291
}
13161292

1293+
private Task createContactTask(TaskType taskType, LocalDateTime fromDateTime, LocalDateTime toDateTime, Contact contact, User assignee) {
1294+
Task task = taskService.buildTask(null);
1295+
task.setTaskContext(TaskContext.CONTACT);
1296+
task.setContact(contact);
1297+
task.setTaskType(taskType);
1298+
task.setSuggestedStart(DateHelper8.toDate(fromDateTime));
1299+
task.setDueDate(DateHelper8.toDate(toDateTime.minusMinutes(1)));
1300+
task.setAssigneeUser(assignee);
1301+
1302+
if (contact.isHighPriority()) {
1303+
task.setPriority(TaskPriority.HIGH);
1304+
}
1305+
return task;
1306+
}
1307+
13171308
@Override
13181309
public void validate(ContactDto contact) throws ValidationRuntimeException {
13191310

sormas-backend/src/main/java/de/symeda/sormas/backend/task/TaskService.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
*******************************************************************************/
1818
package de.symeda.sormas.backend.task;
1919

20+
import java.util.ArrayList;
2021
import java.util.Date;
2122
import java.util.List;
23+
import java.util.Random;
2224

2325
import javax.ejb.EJB;
2426
import javax.ejb.LocalBean;
@@ -41,6 +43,7 @@
4143
import de.symeda.sormas.backend.caze.Case;
4244
import de.symeda.sormas.backend.caze.CaseService;
4345
import de.symeda.sormas.backend.common.AbstractAdoService;
46+
import de.symeda.sormas.backend.common.TaskCreationException;
4447
import de.symeda.sormas.backend.contact.Contact;
4548
import de.symeda.sormas.backend.contact.ContactService;
4649
import de.symeda.sormas.backend.event.Event;
@@ -287,4 +290,51 @@ public Task buildTask(User creatorUser) {
287290
task.setTaskStatus(TaskStatus.PENDING);
288291
return task;
289292
}
293+
294+
public User getTaskAssignee(Contact contact) throws TaskCreationException {
295+
User assignee = null;
296+
297+
if (contact.getContactOfficer() != null) {
298+
// 1) The contact officer that is responsible for the contact
299+
assignee = contact.getContactOfficer();
300+
} else {
301+
// 2) A random contact officer from the contact's, contact person's or contact case's district
302+
List<User> officers = new ArrayList<>();
303+
if (contact.getDistrict() != null) {
304+
officers = userService.getAllByDistrict(contact.getDistrict(), false, UserRole.CONTACT_OFFICER);
305+
}
306+
if (officers.isEmpty() && contact.getPerson().getAddress().getDistrict() != null) {
307+
officers = userService.getAllByDistrict(contact.getPerson().getAddress().getDistrict(), false, UserRole.CONTACT_OFFICER);
308+
}
309+
if (officers.isEmpty() && contact.getCaze() != null && contact.getCaze().getDistrict() != null) {
310+
officers = userService.getAllByDistrict(contact.getCaze().getDistrict(), false, UserRole.CONTACT_OFFICER);
311+
}
312+
if (!officers.isEmpty()) {
313+
Random rand = new Random();
314+
assignee = officers.get(rand.nextInt(officers.size()));
315+
}
316+
}
317+
318+
if (assignee == null) {
319+
// 3) Assign a random contact supervisor from the contact's, contact person's or contact case's region
320+
List<User> supervisors = new ArrayList<>();
321+
if (contact.getRegion() != null) {
322+
supervisors = userService.getAllByRegionAndUserRoles(contact.getRegion(), UserRole.CONTACT_SUPERVISOR);
323+
}
324+
if (supervisors.isEmpty() && contact.getPerson().getAddress().getRegion() != null) {
325+
supervisors = userService.getAllByRegionAndUserRoles(contact.getPerson().getAddress().getRegion(), UserRole.CONTACT_SUPERVISOR);
326+
}
327+
if (supervisors.isEmpty() && contact.getCaze() != null && contact.getCaze().getDistrict() != null) {
328+
supervisors = userService.getAllByRegionAndUserRoles(contact.getCaze().getRegion(), UserRole.CONTACT_SUPERVISOR);
329+
}
330+
if (!supervisors.isEmpty()) {
331+
Random rand = new Random();
332+
assignee = supervisors.get(rand.nextInt(supervisors.size()));
333+
} else {
334+
throw new TaskCreationException("Contact has not contact officer and no region - can't create follow-up task: " + contact.getUuid());
335+
}
336+
}
337+
338+
return assignee;
339+
}
290340
}

sormas-backend/src/test/java/de/symeda/sormas/backend/contact/ContactFacadeEjbTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Collections;
3636
import java.util.Date;
3737
import java.util.List;
38+
import java.util.stream.Collectors;
3839

3940
import org.apache.commons.lang3.time.DateUtils;
4041
import org.junit.Assert;
@@ -217,7 +218,9 @@ public void testGenerateContactFollowUpTasks() {
217218
getContactFacade().generateContactFollowUpTasks();
218219

219220
// task should have been generated
220-
List<TaskDto> tasks = getTaskFacade().getAllByContact(contact.toReference());
221+
List<TaskDto> tasks = getTaskFacade().getAllByContact(contact.toReference()).stream()
222+
.filter(t -> t.getTaskType() == TaskType.CONTACT_FOLLOW_UP)
223+
.collect(Collectors.toList());
221224
assertEquals(1, tasks.size());
222225
TaskDto task = tasks.get(0);
223226
assertEquals(TaskType.CONTACT_FOLLOW_UP, task.getTaskType());
@@ -227,7 +230,9 @@ public void testGenerateContactFollowUpTasks() {
227230

228231
// task should not be generated multiple times
229232
getContactFacade().generateContactFollowUpTasks();
230-
tasks = getTaskFacade().getAllByContact(contact.toReference());
233+
tasks = getTaskFacade().getAllByContact(contact.toReference()).stream()
234+
.filter(t -> t.getTaskType() == TaskType.CONTACT_FOLLOW_UP)
235+
.collect(Collectors.toList());
231236
assertEquals(1, tasks.size());
232237
}
233238

sormas-backend/src/test/java/de/symeda/sormas/backend/task/TaskFacadeEjbTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ public void testArchivedTaskNotGettingTransfered() {
159159
event.toReference(),
160160
DateHelper.addDays(new Date(), 1),
161161
user.toReference());
162-
// getAllActiveTasks and getAllUuids should return length 4+1 (case investigation)
163-
assertEquals(5, getTaskFacade().getAllActiveTasksAfter(null).size());
164-
assertEquals(5, getTaskFacade().getAllActiveUuids().size());
162+
// getAllActiveTasks and getAllUuids should return length 4+1+1 (case investigation & contact investigation)
163+
assertEquals(6, getTaskFacade().getAllActiveTasksAfter(null).size());
164+
assertEquals(6, getTaskFacade().getAllActiveUuids().size());
165165

166166
getCaseFacade().archiveOrDearchiveCase(caze.getUuid(), true);
167167
getEventFacade().archiveOrDearchiveEvent(event.getUuid(), true);
@@ -173,9 +173,9 @@ public void testArchivedTaskNotGettingTransfered() {
173173
getCaseFacade().archiveOrDearchiveCase(caze.getUuid(), false);
174174
getEventFacade().archiveOrDearchiveEvent(event.getUuid(), false);
175175

176-
// getAllActiveTasks and getAllUuids should return length 4
177-
assertEquals(5, getTaskFacade().getAllActiveTasksAfter(null).size());
178-
assertEquals(5, getTaskFacade().getAllActiveUuids().size());
176+
// getAllActiveTasks and getAllUuids should return length 5 + 1 (contact investigation)
177+
assertEquals(6, getTaskFacade().getAllActiveTasksAfter(null).size());
178+
assertEquals(6, getTaskFacade().getAllActiveUuids().size());
179179
}
180180

181181
@Test

0 commit comments

Comments
 (0)