Search in sources :

Example 1 with CaseDataDto

use of de.symeda.sormas.api.caze.CaseDataDto in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjb method savePersonWithoutNotifyingExternalJournal.

/**
 * Saves the received person.
 * This method always checks if the given source person data is outdated
 * The approximate age reference date is calculated and set on the person object to be saved. In case the case classification was
 * changed by saving the person,
 * If the person is enrolled in the external journal, the relevant data is validated,but the external journal is not notified. The task
 * of notifying the external journals falls to the caller of this method.
 * Also, in case the case classification was changed, the new classification will be returned.
 *
 * @param source
 *            the person dto object to be saved
 * @return a pair of objects containing:
 *         - the new case classification or null if it was not changed
 *         - the old person data from the database
 * @throws ValidationRuntimeException
 *             if the passed source person to be saved contains invalid data
 */
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Pair<CaseClassification, PersonDto> savePersonWithoutNotifyingExternalJournal(@Valid PersonDto source) throws ValidationRuntimeException {
    Person existingPerson = personService.getByUuid(source.getUuid());
    PersonDto existingPersonDto = toDto(existingPerson);
    List<CaseDataDto> personCases = caseFacade.getAllCasesOfPerson(source.getUuid());
    computeApproximateAgeReferenceDate(existingPersonDto, source);
    restorePseudonymizedDto(source, existingPerson, existingPersonDto);
    validate(source);
    if (existingPersonDto != null && existingPersonDto.isEnrolledInExternalJournal()) {
        externalJournalService.validateExternalJournalPerson(source);
    }
    existingPerson = fillOrBuildEntity(source, existingPerson, true);
    personService.ensurePersisted(existingPerson);
    onPersonChanged(existingPersonDto, existingPerson);
    CaseClassification newClassification = getNewCaseClassification(personCases);
    return Pair.createPair(newClassification, existingPersonDto);
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) CaseClassification(de.symeda.sormas.api.caze.CaseClassification) PersonDto(de.symeda.sormas.api.person.PersonDto) SimilarPersonDto(de.symeda.sormas.api.person.SimilarPersonDto) JournalPersonDto(de.symeda.sormas.api.person.JournalPersonDto) TransactionAttribute(javax.ejb.TransactionAttribute)

Example 2 with CaseDataDto

use of de.symeda.sormas.api.caze.CaseDataDto in project SORMAS-Project by hzi-braunschweig.

the class PersonFacadeEjb method onPersonChanged.

public void onPersonChanged(PersonDto existingPerson, Person newPerson, boolean syncShares) {
    List<Case> personCases = null;
    // Do not bother to update existing cases/contacts/eventparticipants on new Persons, as none should exist yet
    if (existingPerson != null) {
        personCases = caseService.findBy(new CaseCriteria().person(new PersonReferenceDto(newPerson.getUuid())), true);
        // Attention: this may lead to infinite recursion when not properly implemented
        for (Case personCase : personCases) {
            CaseDataDto existingCase = caseFacade.toDto(personCase);
            caseFacade.onCaseChanged(existingCase, personCase, syncShares);
        }
        List<Contact> personContacts = contactService.findBy(new ContactCriteria().setPerson(new PersonReferenceDto(newPerson.getUuid())), null);
        // Attention: this may lead to infinite recursion when not properly implemented
        for (Contact personContact : personContacts) {
            contactFacade.onContactChanged(contactFacade.toDto(personContact), syncShares);
        }
        List<EventParticipant> personEventParticipants = eventParticipantService.findBy(new EventParticipantCriteria().withPerson(new PersonReferenceDto(newPerson.getUuid())), null);
        // Attention: this may lead to infinite recursion when not properly implemented
        for (EventParticipant personEventParticipant : personEventParticipants) {
            eventParticipantFacade.onEventParticipantChanged(eventFacade.toDto(personEventParticipant.getEvent()), eventParticipantFacade.toDto(personEventParticipant), personEventParticipant, syncShares);
        }
        // get the updated personCases
        personCases = caseService.findBy(new CaseCriteria().person(new PersonReferenceDto(newPerson.getUuid())), true);
        // sort cases based on recency
        Collections.sort(personCases, (c1, c2) -> CaseLogic.getStartDate(c1.getSymptoms().getOnsetDate(), c1.getReportDate()).before(CaseLogic.getStartDate(c2.getSymptoms().getOnsetDate(), c2.getReportDate())) ? 1 : -1);
        if (newPerson.getPresentCondition() != null && existingPerson.getPresentCondition() != newPerson.getPresentCondition()) {
            // get the latest case with disease==causeofdeathdisease
            Case personCase = personCases.stream().filter(caze -> caze.getDisease() == newPerson.getCauseOfDeathDisease()).findFirst().orElse(null);
            if (newPerson.getPresentCondition().isDeceased() && newPerson.getDeathDate() != null && newPerson.getCauseOfDeath() == CauseOfDeath.EPIDEMIC_DISEASE && newPerson.getCauseOfDeathDisease() != null) {
                // update the latest associated case
                if (personCase != null && personCase.getOutcome() != CaseOutcome.DECEASED && (personCase.getReportDate().before(DateHelper.addDays(newPerson.getDeathDate(), 30)) && personCase.getReportDate().after(DateHelper.subtractDays(newPerson.getDeathDate(), 30)))) {
                    CaseDataDto existingCase = caseFacade.toDto(personCase);
                    personCase.setOutcome(CaseOutcome.DECEASED);
                    personCase.setOutcomeDate(newPerson.getDeathDate());
                    caseFacade.onCaseChanged(existingCase, personCase, syncShares);
                }
            } else if (!newPerson.getPresentCondition().isDeceased() && (existingPerson.getPresentCondition() == PresentCondition.DEAD || existingPerson.getPresentCondition() == PresentCondition.BURIED)) {
                // Person was put "back alive"
                // make sure other values are set to null
                newPerson.setCauseOfDeath(null);
                newPerson.setCauseOfDeathDisease(null);
                newPerson.setDeathPlaceDescription(null);
                newPerson.setDeathPlaceType(null);
                newPerson.setBurialDate(null);
                newPerson.setCauseOfDeathDisease(null);
                // update the latest associated case, if it was set to deceased && and if the case-disease was also the causeofdeath-disease
                if (personCase != null && personCase.getOutcome() == CaseOutcome.DECEASED) {
                    CaseDataDto existingCase = caseFacade.toDto(personCase);
                    personCase.setOutcome(CaseOutcome.NO_OUTCOME);
                    personCase.setOutcomeDate(null);
                    caseFacade.onCaseChanged(existingCase, personCase, syncShares);
                }
            }
        } else if (newPerson.getPresentCondition() != null && newPerson.getPresentCondition().isDeceased() && !Objects.equals(newPerson.getDeathDate(), existingPerson.getDeathDate()) && newPerson.getDeathDate() != null) {
            // only Deathdate has changed
            // update the latest associated case to the new deathdate, if causeOfDeath matches
            Case personCase = personCases.isEmpty() ? null : personCases.get(0);
            if (personCase != null && personCase.getOutcome() == CaseOutcome.DECEASED && newPerson.getCauseOfDeath() == CauseOfDeath.EPIDEMIC_DISEASE) {
                CaseDataDto existingCase = caseFacade.toDto(personCase);
                personCase.setOutcomeDate(newPerson.getDeathDate());
                caseFacade.onCaseChanged(existingCase, personCase, syncShares);
            }
        }
    }
    // Set approximate age if it hasn't been set before
    if (newPerson.getApproximateAge() == null && newPerson.getBirthdateYYYY() != null) {
        Pair<Integer, ApproximateAgeType> pair = ApproximateAgeHelper.getApproximateAge(newPerson.getBirthdateYYYY(), newPerson.getBirthdateMM(), newPerson.getBirthdateDD(), newPerson.getDeathDate());
        newPerson.setApproximateAge(pair.getElement0());
        newPerson.setApproximateAgeType(pair.getElement1());
        newPerson.setApproximateAgeReferenceDate(newPerson.getDeathDate() != null ? newPerson.getDeathDate() : new Date());
    }
    // Update caseAge of all associated cases when approximateAge has changed
    if (existingPerson != null && existingPerson.getApproximateAge() != newPerson.getApproximateAge()) {
        // Update case list after previous onCaseChanged
        personCases = caseService.findBy(new CaseCriteria().person(new PersonReferenceDto(newPerson.getUuid())), true);
        for (Case personCase : personCases) {
            CaseDataDto existingCase = caseFacade.toDto(personCase);
            if (newPerson.getApproximateAge() == null) {
                personCase.setCaseAge(null);
            } else if (newPerson.getApproximateAgeType() == ApproximateAgeType.MONTHS) {
                personCase.setCaseAge(0);
            } else {
                Date now = new Date();
                personCase.setCaseAge(newPerson.getApproximateAge() - DateHelper.getYearsBetween(personCase.getReportDate(), now));
                if (personCase.getCaseAge() < 0) {
                    personCase.setCaseAge(0);
                }
            }
            caseFacade.onCaseChanged(existingCase, personCase, syncShares);
        }
    }
    // For newly created persons, assume no registration in external journals
    if (existingPerson == null && newPerson.getSymptomJournalStatus() == null) {
        newPerson.setSymptomJournalStatus(SymptomJournalStatus.UNREGISTERED);
    }
    cleanUp(newPerson);
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) Date(java.util.Date) Case(de.symeda.sormas.backend.caze.Case) Contact(de.symeda.sormas.backend.contact.Contact) ApproximateAgeType(de.symeda.sormas.api.person.ApproximateAgeType) CaseCriteria(de.symeda.sormas.api.caze.CaseCriteria) ContactCriteria(de.symeda.sormas.api.contact.ContactCriteria) EventParticipantCriteria(de.symeda.sormas.api.event.EventParticipantCriteria) EventParticipant(de.symeda.sormas.backend.event.EventParticipant)

Example 3 with CaseDataDto

use of de.symeda.sormas.api.caze.CaseDataDto in project SORMAS-Project by hzi-braunschweig.

the class VisitFacadeEjbTest method testGetAllActiveUuids.

@Test
public void testGetAllActiveUuids() throws ExternalSurveillanceToolException {
    TestDataCreator.RDCF rdcf = creator.createRDCF();
    UserDto user = creator.createUser(rdcf, "Surv", "Sup", UserRole.SURVEILLANCE_SUPERVISOR);
    PersonDto person = creator.createPerson();
    PersonDto person2 = creator.createPerson();
    PersonDto person3 = creator.createPerson();
    PersonDto person4 = creator.createPerson();
    PersonDto person5 = creator.createPerson();
    // contacts
    creator.createContact(user.toReference(), person.toReference());
    creator.createContact(user.toReference(), person5.toReference());
    ContactDto deletedContact = creator.createContact(user.toReference(), person2.toReference());
    getContactFacade().deleteContact(deletedContact.getUuid());
    // cases
    creator.createCase(user.toReference(), person.toReference(), rdcf);
    creator.createCase(user.toReference(), person3.toReference(), rdcf);
    CaseDataDto deletedCase = creator.createCase(user.toReference(), person4.toReference(), rdcf);
    getCaseFacade().deleteCase(deletedCase.getUuid());
    // Attached to case and contact
    creator.createVisit(person.toReference());
    // Attached to contact only
    creator.createVisit(person5.toReference());
    // Attached to case only
    creator.createVisit(person3.toReference());
    VisitDto visitOfDeletedContact = creator.createVisit(person2.toReference());
    VisitDto visitOfDeletedCase = creator.createVisit(person4.toReference());
    List<String> visitUuids = getVisitFacade().getAllActiveUuids();
    assertThat(visitUuids, hasSize(3));
    assertThat(visitUuids, not(contains(visitOfDeletedContact.getUuid())));
    assertThat(visitUuids, not(contains(visitOfDeletedCase.getUuid())));
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonDto(de.symeda.sormas.api.person.PersonDto) UserDto(de.symeda.sormas.api.user.UserDto) ContactDto(de.symeda.sormas.api.contact.ContactDto) TestDataCreator(de.symeda.sormas.backend.TestDataCreator) ExternalVisitDto(de.symeda.sormas.api.visit.ExternalVisitDto) VisitDto(de.symeda.sormas.api.visit.VisitDto) AbstractBeanTest(de.symeda.sormas.backend.AbstractBeanTest) Test(org.junit.Test)

Example 4 with CaseDataDto

use of de.symeda.sormas.api.caze.CaseDataDto in project SORMAS-Project by hzi-braunschweig.

the class VisitFacadeEjbTest method testGetLastVisitByCase.

@Test
public void testGetLastVisitByCase() {
    UserDto user = creator.createUser(creator.createRDCF(), "Surv", "Sup", UserRole.SURVEILLANCE_SUPERVISOR);
    PersonDto person = creator.createPerson();
    CaseDataDto caze = creator.createCase(user.toReference(), person.toReference(), creator.createRDCF());
    VisitDto visit = creator.createVisit(Disease.EVD, person.toReference(), new Date());
    creator.createVisit(Disease.EVD, person.toReference(), DateHelper.subtractDays(new Date(), 1));
    assertThat(getVisitFacade().getLastVisitByCase(caze.toReference()), is(visit));
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonDto(de.symeda.sormas.api.person.PersonDto) UserDto(de.symeda.sormas.api.user.UserDto) ExternalVisitDto(de.symeda.sormas.api.visit.ExternalVisitDto) VisitDto(de.symeda.sormas.api.visit.VisitDto) Date(java.util.Date) AbstractBeanTest(de.symeda.sormas.backend.AbstractBeanTest) Test(org.junit.Test)

Example 5 with CaseDataDto

use of de.symeda.sormas.api.caze.CaseDataDto in project SORMAS-Project by hzi-braunschweig.

the class VisitFacadeEjbTest method testGetAllActiveVisitsAfter.

@Test
public void testGetAllActiveVisitsAfter() throws InterruptedException, ExternalSurveillanceToolException {
    TestDataCreator.RDCF rdcf = creator.createRDCF();
    UserDto user = creator.createUser(rdcf, "Surv", "Sup", UserRole.SURVEILLANCE_SUPERVISOR);
    Date date = new Date();
    PersonDto person = creator.createPerson();
    PersonDto person2 = creator.createPerson();
    PersonDto person3 = creator.createPerson();
    PersonDto person4 = creator.createPerson();
    PersonDto person5 = creator.createPerson();
    creator.createContact(user.toReference(), person.toReference());
    creator.createContact(user.toReference(), person3.toReference());
    ContactDto deletedContact = creator.createContact(user.toReference(), person2.toReference());
    getContactFacade().deleteContact(deletedContact.getUuid());
    creator.createCase(user.toReference(), person3.toReference(), rdcf);
    creator.createCase(user.toReference(), person4.toReference(), rdcf);
    CaseDataDto deletedCaseDto = creator.createCase(user.toReference(), person5.toReference(), rdcf);
    getCaseFacade().deleteCase(deletedCaseDto.getUuid());
    creator.createVisit(person.toReference());
    creator.createVisit(person3.toReference());
    VisitDto visitOfPureCase = creator.createVisit(person4.toReference());
    VisitDto visitWithChanges = creator.createVisit(person.toReference());
    VisitDto visitOfDeletedContact = creator.createVisit(person2.toReference());
    VisitDto visitOfDeletedCase = creator.createVisit(person5.toReference());
    List<VisitDto> visits = getVisitFacade().getAllActiveVisitsAfter(date);
    assertThat(visits, hasSize(3));
    // TODO change once visits are synchronized to app
    assertThat(visits, not(contains(visitOfPureCase)));
    assertThat(visits, not(contains(visitOfDeletedContact)));
    assertThat(visits, not(contains(visitOfDeletedCase)));
    List<VisitDto> visitsBatched = getVisitFacade().getAllActiveVisitsAfter(date, 2, null);
    assertThat(visitsBatched, hasSize(2));
    assertTrue(visitsBatched.get(0).getChangeDate().getTime() <= visitsBatched.get(1).getChangeDate().getTime());
    date = new Date();
    TimeUnit.MILLISECONDS.sleep(1);
    visitWithChanges.getSymptoms().setAbdominalPain(SymptomState.YES);
    visitWithChanges = getVisitFacade().saveVisit(visitWithChanges);
    visits = getVisitFacade().getAllActiveVisitsAfter(date);
    assertThat(visits, hasSize(1));
    assertThat(visits, contains(visitWithChanges));
}
Also used : CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonDto(de.symeda.sormas.api.person.PersonDto) UserDto(de.symeda.sormas.api.user.UserDto) ContactDto(de.symeda.sormas.api.contact.ContactDto) TestDataCreator(de.symeda.sormas.backend.TestDataCreator) ExternalVisitDto(de.symeda.sormas.api.visit.ExternalVisitDto) VisitDto(de.symeda.sormas.api.visit.VisitDto) Date(java.util.Date) AbstractBeanTest(de.symeda.sormas.backend.AbstractBeanTest) Test(org.junit.Test)

Aggregations

CaseDataDto (de.symeda.sormas.api.caze.CaseDataDto)395 Test (org.junit.Test)287 AbstractBeanTest (de.symeda.sormas.backend.AbstractBeanTest)239 PersonDto (de.symeda.sormas.api.person.PersonDto)174 Date (java.util.Date)159 UserDto (de.symeda.sormas.api.user.UserDto)140 ContactDto (de.symeda.sormas.api.contact.ContactDto)102 SampleDto (de.symeda.sormas.api.sample.SampleDto)74 UserReferenceDto (de.symeda.sormas.api.user.UserReferenceDto)62 RDCFEntities (de.symeda.sormas.backend.TestDataCreator.RDCFEntities)58 LocalDate (java.time.LocalDate)57 CaseCriteria (de.symeda.sormas.api.caze.CaseCriteria)43 TestDataCreator (de.symeda.sormas.backend.TestDataCreator)43 RDCF (de.symeda.sormas.backend.TestDataCreator.RDCF)43 List (java.util.List)42 Disease (de.symeda.sormas.api.Disease)40 PersonReferenceDto (de.symeda.sormas.api.person.PersonReferenceDto)36 PathogenTestDto (de.symeda.sormas.api.sample.PathogenTestDto)36 ArrayList (java.util.ArrayList)35 SimilarContactDto (de.symeda.sormas.api.contact.SimilarContactDto)34