Skip to content

Commit

Permalink
#10622 - All Visits of Contacts of the same Person are deleted when p…
Browse files Browse the repository at this point in the history
…ermanent deletion is triggered for one of the Contacts, if there's a distance of >30 days between their Report Dates
  • Loading branch information
sergiupacurariu committed Oct 14, 2022
1 parent 223cedf commit 45ad154
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1502,24 +1502,13 @@ public void deletePermanent(Contact contact) {
.filter(sample -> sample.getAssociatedCase() == null && sample.getAssociatedEventParticipant() == null)
.forEach(sample -> sampleService.deletePermanent(sample));

// Delete all visits that are only associated with this contact
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaDelete<Visit> cd = cb.createCriteriaDelete(Visit.class);
Root<Visit> visitRoot = cd.from(Visit.class);
Subquery<Long> visitContactSubquery = countVisitsContactSubqueryForDelete(cb, cd, visitRoot, contact);

Subquery<Visit> getVisitContactSubquery = getVisitsContactSubqueryForDelete(cb, cd, contact);

cd.where(
cb.and(
// cb.isNull(visitRoot.get(Visit.CAZE).get(Case.ID)),
// cb.lessThanOrEqualTo(visitContactSubquery, 1L),
visitRoot.in(getVisitContactSubquery)));
em.createQuery(cd).executeUpdate();

// Remove the contact that will be deleted from contact_visits
em.createNativeQuery("delete from contacts_visits cv where cv.contact_id = ?1").setParameter(1, contact.getId()).executeUpdate();

// Delete all visits that are not associated with any contact or case
em.createNativeQuery("delete from visit v where v.caze_id is null and not exists(select from contacts_visits cv where cv.visit_id = v.id)")
.executeUpdate();

// Delete documents related to this contact
documentService.getRelatedToEntity(DocumentRelatedEntityType.CONTACT, contact.getUuid()).forEach(d -> documentService.markAsDeleted(d));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,11 @@
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import javax.validation.ConstraintViolationException;

import de.symeda.sormas.api.followup.FollowUpLogic;
import de.symeda.sormas.backend.visit.Visit;
import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.internal.SessionImpl;
import org.hibernate.query.spi.NativeQueryImplementor;
import org.hibernate.query.spi.QueryImplementor;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -35,6 +31,7 @@
import de.symeda.sormas.api.event.EventInvestigationStatus;
import de.symeda.sormas.api.event.EventParticipantDto;
import de.symeda.sormas.api.event.EventStatus;
import de.symeda.sormas.api.followup.FollowUpLogic;
import de.symeda.sormas.api.immunization.ImmunizationDto;
import de.symeda.sormas.api.person.PersonDto;
import de.symeda.sormas.api.sample.SampleDto;
Expand Down Expand Up @@ -508,7 +505,11 @@ public void testAutomaticManuallyDeletedEntitiesDeletion() {
}

@Test
public void testContactPermanentDeletion() throws IOException {
public void testContactPermanentDeletion() {

// the Visit will be added only to contacts that have REPORT_DATE_TIME, LAST_CONTACT_DATE or FOLLOW_UP_UNTIL within less than ALLOWED_DATE_OFFSET days from Visit report date
// the test is checking the permanent deletion for contacts which are more than ALLOWED_DATE_OFFSET days apart from each other so there will be no shared Visit between them
// the second part tests the permanent deletion of contacts with the same person which are less than ALLOWED_DATE_OFFSET days apart
createDeletionConfigurations();
DeletionConfiguration coreEntityTypeConfig = getDeletionConfigurationService().getCoreEntityTypeConfig(CoreEntityType.CONTACT);

Expand All @@ -519,50 +520,41 @@ public void testContactPermanentDeletion() throws IOException {

ContactDto contactDto = creator.createContact(user.toReference(), person.toReference(), Disease.CORONAVIRUS);

final Date beyondRelevanceDate = DateUtils.addDays(new Date(), (-90));
final Date beyondRelevanceDate = DateUtils.addDays(new Date(), (-1) * (FollowUpLogic.ALLOWED_DATE_OFFSET + 1));
contactDto.setReportDateTime(beyondRelevanceDate);
getContactFacade().save(contactDto);

// TaskDto taskDto = creator
// .createTask(TaskContext.CONTACT, TaskType.CONTACT_FOLLOW_UP, TaskStatus.PENDING, null, contactDto.toReference(), null, new Date(), null);
TaskDto taskDto = creator
.createTask(TaskContext.CONTACT, TaskType.CONTACT_FOLLOW_UP, TaskStatus.PENDING, null, contactDto.toReference(), null, new Date(), null);

// SampleDto sample = creator.createSample(
// contactDto.toReference(),
// user.toReference(),
// rdcf.facility,
// sampleDto -> sampleDto.setAssociatedContact(contactDto.toReference()));
SampleDto sample = creator.createSample(
contactDto.toReference(),
user.toReference(),
rdcf.facility,
sampleDto -> sampleDto.setAssociatedContact(contactDto.toReference()));

VisitDto visitDto = creator.createVisit(contactDto.getDisease(), contactDto.getPerson(), contactDto.getReportDateTime());

ContactDto contactDto2 = creator.createContact(user.toReference(), person.toReference(), Disease.CORONAVIRUS);

// TaskDto taskDto2 = creator
// .createTask(TaskContext.CONTACT, TaskType.CONTACT_FOLLOW_UP, TaskStatus.PENDING, null, contactDto2.toReference(), null, new Date(), null);
//
// SampleDto sample2 = creator.createSample(
// contactDto2.toReference(),
// user.toReference(),
// rdcf.facility,
// sampleDto -> sampleDto.setAssociatedContact(contactDto2.toReference()));
TaskDto taskDto2 = creator
.createTask(TaskContext.CONTACT, TaskType.CONTACT_FOLLOW_UP, TaskStatus.PENDING, null, contactDto2.toReference(), null, new Date(), null);

SampleDto sample2 = creator.createSample(
contactDto2.toReference(),
user.toReference(),
rdcf.facility,
sampleDto -> sampleDto.setAssociatedContact(contactDto2.toReference()));

VisitDto visitDto2 = creator.createVisit(contactDto2.getDisease(), contactDto2.getPerson(), contactDto2.getReportDateTime());

assertEquals(2, getContactService().count());
// assertEquals(1, getTaskFacade().getAllByContact(contactDto.toReference()).size());
// assertEquals(1, getTaskFacade().getAllByContact(contactDto2.toReference()).size());
// assertEquals(2, getSampleService().count());
assertEquals(1, getTaskFacade().getAllByContact(contactDto.toReference()).size());
assertEquals(1, getTaskFacade().getAllByContact(contactDto2.toReference()).size());
assertEquals(2, getSampleService().count());
assertEquals(2, getVisitService().count());

SessionImpl em = (SessionImpl) getEntityManager();
NativeQueryImplementor select_from_contacts_visits = em.createNativeQuery("select from contacts_visits");
List contacVisist1 = select_from_contacts_visits.getResultList();


QueryImplementor query3 = em.createQuery("select i from contact i where i.uuid=:uuid");
query3.setParameter("uuid", contactDto2.getUuid());
Contact singleResult3 = (Contact) query3.getSingleResult();


final Date tenYearsPlusAgo = DateUtils.addDays(new Date(), (-1) * coreEntityTypeConfig.deletionPeriod - 1);
QueryImplementor query = em.createQuery("select i from contact i where i.uuid=:uuid");
query.setParameter("uuid", contactDto.getUuid());
Expand All @@ -571,29 +563,28 @@ public void testContactPermanentDeletion() throws IOException {
singleResult.setChangeDate(new Timestamp(tenYearsPlusAgo.getTime()));
em.save(singleResult);

NativeQueryImplementor selectForDelete = em.createNativeQuery("select uuid\n" +
"from Visit\n" +
"where (caze_id is null)\n" +
" and (id in (select visit1_.id\n" +
" from Visit visit1_\n" +
" inner join contacts_visits contacts2_ on visit1_.id = contacts2_.visit_id\n" +
" inner join contact contact3_ on contacts2_.contact_id = contact3_.id\n" +
" where contact3_.id=:uuid))");
selectForDelete.setParameter("uuid", singleResult.getId());
List<String> selectForDeleteResultList = selectForDelete.getResultList();

useSystemUser();
getCoreEntityDeletionService().executeAutomaticDeletion();
loginWith(user);

NativeQueryImplementor select_from_contacts_visits2 = em.createNativeQuery("select from contacts_visits");
List contacVisist2 = select_from_contacts_visits2.getResultList();

assertEquals(1, getContactService().count());
// assertEquals(1, getTaskFacade().getAllByContact(contactDto2.toReference()).size());
// assertEquals(1, getSampleService().count());
assertEquals(1, getTaskFacade().getAllByContact(contactDto2.toReference()).size());
assertEquals(1, getSampleService().count());
assertEquals(1, getVisitService().count());

ContactDto contactDto3 = creator.createContact(user.toReference(), person.toReference(), Disease.CORONAVIRUS);

TaskDto taskDto3 = creator
.createTask(TaskContext.CONTACT, TaskType.CONTACT_FOLLOW_UP, TaskStatus.PENDING, null, contactDto3.toReference(), null, new Date(), null);

SampleDto sample3 = creator.createSample(
contactDto3.toReference(),
user.toReference(),
rdcf.facility,
sampleDto -> sampleDto.setAssociatedContact(contactDto3.toReference()));

VisitDto visitDto3 = creator.createVisit(contactDto3.getDisease(), contactDto3.getPerson(), contactDto3.getReportDateTime());

final Date tenYearsPlusAgoSecondContact = DateUtils.addDays(new Date(), (-1) * coreEntityTypeConfig.deletionPeriod - 1);
SessionImpl emSecondContact = (SessionImpl) getEntityManager();
QueryImplementor query2 = emSecondContact.createQuery("select i from contact i where i.uuid=:uuid");
Expand All @@ -607,8 +598,27 @@ public void testContactPermanentDeletion() throws IOException {
getCoreEntityDeletionService().executeAutomaticDeletion();
loginWith(user);

assertEquals(0, getContactService().count());
assertEquals(1, getContactService().count());
assertEquals(0, getTaskFacade().getAllByContact(contactDto2.toReference()).size());
assertEquals(1, getTaskFacade().getAllByContact(contactDto3.toReference()).size());
assertEquals(1, getSampleService().count());
assertEquals(2, getVisitService().count());

final Date tenYearsPlusAgoThirdContact = DateUtils.addDays(new Date(), (-1) * coreEntityTypeConfig.deletionPeriod - 1);
SessionImpl emThirdContact = (SessionImpl) getEntityManager();
QueryImplementor query3 = emThirdContact.createQuery("select i from contact i where i.uuid=:uuid");
query3.setParameter("uuid", contactDto3.getUuid());
Contact singleResult3 = (Contact) query3.getSingleResult();
singleResult3.setCreationDate(new Timestamp(tenYearsPlusAgoThirdContact.getTime()));
singleResult3.setChangeDate(new Timestamp(tenYearsPlusAgoThirdContact.getTime()));
emThirdContact.save(singleResult3);

useSystemUser();
getCoreEntityDeletionService().executeAutomaticDeletion();
loginWith(user);

assertEquals(0, getContactService().count());
assertEquals(0, getTaskFacade().getAllByContact(contactDto3.toReference()).size());
assertEquals(0, getSampleService().count());
assertEquals(0, getVisitService().count());
}
Expand Down

0 comments on commit 45ad154

Please sign in to comment.