Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public List<QueueEntry> getOverlappingQueueEntries(QueueEntrySearchCriteria sear
predicates.add(cb.or(root.get("endedAt").isNull(), cb.greaterThan(root.get("endedAt"), startedAt)));
}

Date endedAt = searchCriteria.getEndedOn();
if (endedAt != null) {
// any queue entries that started before this queue entry ends
predicates.add(cb.lessThan(root.get("startedAt"), endedAt));
}

query.where(cb.and(predicates.toArray(new Predicate[0])));

return session.createQuery(query).list();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ public void validate(Object target, Errors errors) {
private boolean isDuplicate(QueueEntry queueEntry, QueueEntryService queueEntryService) {
List<QueueEntry> queueEntries = queueEntryService.getOverlappingQueueEntries(queueEntry.getPatient(),
queueEntry.getQueue(), queueEntry.getStartedAt(), queueEntry.getEndedAt());
// cascade voids (e.g. voiding a patient) may not yet be flushed to the DB when this runs,
// so voided entries can slip through the DAO-level filter — remove them here as a safety net
queueEntries.removeIf(QueueEntry::getVoided);

// if we aren't checking an existing queue entry, any overlaps are "duplicates"
if (queueEntry.getId() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,35 @@ public void shouldSearchAndCountQueueEntriesEndedOnOrAfterDate() {
assertResults(criteria, 2, 3);
}

@Test
// Dataset entries for queue=3, patient=2: only entry 4 [2022-03-02 16:40:56 → 2022-03-02 18:41:56]
public void getOverlappingQueueEntries_shouldReturnEntriesOverlappingWithGivenRange() {
Queue queue3 = services.getQueueService().getQueueById(3).orElseThrow(IllegalStateException::new);
Patient patient2 = services.getPatientService().getPatient(2);

// Open-ended new entry: endedAt=null — entry 4 overlaps (its endedAt > new startedAt)
QueueEntrySearchCriteria openCriteria = QueueEntrySearchCriteria.builder().queues(Collections.singletonList(queue3))
.patient(patient2).startedOn(date("2022-03-02 10:00:00")).build();
List<QueueEntry> openResults = dao.getOverlappingQueueEntries(openCriteria);
assertThat(openResults, hasSize(1));
assertThat(openResults.get(0).getQueueEntryId(), is(4));

// Finite new entry whose range overlaps entry 4: new [10:00 → 17:00], entry 4 starts at 16:40 < 17:00
QueueEntrySearchCriteria overlapCriteria = QueueEntrySearchCriteria.builder()
.queues(Collections.singletonList(queue3)).patient(patient2).startedOn(date("2022-03-02 10:00:00"))
.endedOn(date("2022-03-02 17:00:00")).build();
List<QueueEntry> overlapResults = dao.getOverlappingQueueEntries(overlapCriteria);
assertThat(overlapResults, hasSize(1));
assertThat(overlapResults.get(0).getQueueEntryId(), is(4));

// Finite new entry that ends BEFORE entry 4 starts: new [10:00 → 15:00], entry 4 starts at 16:40 — no overlap
QueueEntrySearchCriteria noOverlapCriteria = QueueEntrySearchCriteria.builder()
.queues(Collections.singletonList(queue3)).patient(patient2).startedOn(date("2022-03-02 10:00:00"))
.endedOn(date("2022-03-02 15:00:00")).build();
List<QueueEntry> noOverlapResults = dao.getOverlappingQueueEntries(noOverlapCriteria);
assertThat(noOverlapResults, hasSize(0));
}

/**
* Utility method that tests criteria against both DAO methods to getQueueEntries and
* getCountOfQueueEntries
Expand Down
Loading