Search in sources :

Example 1 with PersonReferenceDto

use of de.symeda.sormas.api.person.PersonReferenceDto 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 2 with PersonReferenceDto

use of de.symeda.sormas.api.person.PersonReferenceDto in project SORMAS-Project by hzi-braunschweig.

the class EventParticipantImporter method insertColumnEntryIntoData.

/**
 * Inserts the entry of a single cell into the eventparticipant or its person.
 */
private void insertColumnEntryIntoData(EventParticipantDto eventParticipant, PersonDto person, String entry, String[] entryHeaderPath) throws InvalidColumnException, ImportErrorException {
    Object currentElement = eventParticipant;
    for (int i = 0; i < entryHeaderPath.length; i++) {
        String headerPathElementName = entryHeaderPath[i];
        try {
            if (i != entryHeaderPath.length - 1) {
                currentElement = new PropertyDescriptor(headerPathElementName, currentElement.getClass()).getReadMethod().invoke(currentElement);
                // Set the current element to the created person
                if (currentElement instanceof PersonReferenceDto) {
                    currentElement = person;
                }
            } else if (EventParticipantExportDto.BIRTH_DATE.equals(headerPathElementName)) {
                BirthDateDto birthDateDto = PersonHelper.parseBirthdate(entry, currentUser.getLanguage());
                if (birthDateDto != null) {
                    person.setBirthdateDD(birthDateDto.getDateOfBirthDD());
                    person.setBirthdateMM(birthDateDto.getDateOfBirthMM());
                    person.setBirthdateYYYY(birthDateDto.getDateOfBirthYYYY());
                }
            } else {
                PropertyDescriptor pd = new PropertyDescriptor(headerPathElementName, currentElement.getClass());
                Class<?> propertyType = pd.getPropertyType();
                // according to the types of the eventparticipant or person fields
                if (executeDefaultInvoke(pd, currentElement, entry, entryHeaderPath)) {
                    continue;
                } else if (propertyType.isAssignableFrom(DistrictReferenceDto.class)) {
                    List<DistrictReferenceDto> district = FacadeProvider.getDistrictFacade().getByName(entry, ImporterPersonHelper.getRegionBasedOnDistrict(pd.getName(), null, person, currentElement), false);
                    if (district.isEmpty()) {
                        throw new ImportErrorException(I18nProperties.getValidationError(Validations.importEntryDoesNotExistDbOrRegion, entry, buildEntityProperty(entryHeaderPath)));
                    } else if (district.size() > 1) {
                        throw new ImportErrorException(I18nProperties.getValidationError(Validations.importDistrictNotUnique, entry, buildEntityProperty(entryHeaderPath)));
                    } else {
                        pd.getWriteMethod().invoke(currentElement, district.get(0));
                    }
                } else if (propertyType.isAssignableFrom(CommunityReferenceDto.class)) {
                    List<CommunityReferenceDto> community = FacadeProvider.getCommunityFacade().getByName(entry, ImporterPersonHelper.getPersonDistrict(pd.getName(), person), false);
                    if (community.isEmpty()) {
                        throw new ImportErrorException(I18nProperties.getValidationError(Validations.importEntryDoesNotExistDbOrDistrict, entry, buildEntityProperty(entryHeaderPath)));
                    } else if (community.size() > 1) {
                        throw new ImportErrorException(I18nProperties.getValidationError(Validations.importCommunityNotUnique, entry, buildEntityProperty(entryHeaderPath)));
                    } else {
                        pd.getWriteMethod().invoke(currentElement, community.get(0));
                    }
                } else if (propertyType.isAssignableFrom(FacilityReferenceDto.class)) {
                    DataHelper.Pair<DistrictReferenceDto, CommunityReferenceDto> infrastructureData = ImporterPersonHelper.getPersonDistrictAndCommunity(pd.getName(), person);
                    List<FacilityReferenceDto> facility = FacadeProvider.getFacilityFacade().getByNameAndType(entry, infrastructureData.getElement0(), infrastructureData.getElement1(), getTypeOfFacility(pd.getName(), currentElement), false);
                    if (facility.isEmpty()) {
                        if (infrastructureData.getElement1() != null) {
                            throw new ImportErrorException(I18nProperties.getValidationError(Validations.importEntryDoesNotExistDbOrCommunity, entry, buildEntityProperty(entryHeaderPath)));
                        } else {
                            throw new ImportErrorException(I18nProperties.getValidationError(Validations.importEntryDoesNotExistDbOrDistrict, entry, buildEntityProperty(entryHeaderPath)));
                        }
                    } else if (facility.size() > 1 && infrastructureData.getElement1() == null) {
                        throw new ImportErrorException(I18nProperties.getValidationError(Validations.importFacilityNotUniqueInDistrict, entry, buildEntityProperty(entryHeaderPath)));
                    } else if (facility.size() > 1 && infrastructureData.getElement1() != null) {
                        throw new ImportErrorException(I18nProperties.getValidationError(Validations.importFacilityNotUniqueInCommunity, entry, buildEntityProperty(entryHeaderPath)));
                    } else {
                        pd.getWriteMethod().invoke(currentElement, facility.get(0));
                    }
                } else {
                    throw new UnsupportedOperationException(I18nProperties.getValidationError(Validations.importPropertyTypeNotAllowed, propertyType.getName()));
                }
            }
        } catch (IntrospectionException e) {
            throw new InvalidColumnException(buildEntityProperty(entryHeaderPath));
        } catch (InvocationTargetException | IllegalAccessException e) {
            throw new ImportErrorException(I18nProperties.getValidationError(Validations.importErrorInColumn, buildEntityProperty(entryHeaderPath)));
        } catch (IllegalArgumentException e) {
            throw new ImportErrorException(entry, buildEntityProperty(entryHeaderPath));
        } catch (ImportErrorException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("Unexpected error when trying to import an eventparticipant: " + e.getMessage(), e);
            throw new ImportErrorException(I18nProperties.getValidationError(Validations.importCasesUnexpectedError));
        }
    }
    ImportLineResultDto<EventParticipantDto> constraintErrors = validateConstraints(eventParticipant);
    if (constraintErrors.isError()) {
        throw new ImportErrorException(constraintErrors.getMessage());
    }
}
Also used : FacilityReferenceDto(de.symeda.sormas.api.infrastructure.facility.FacilityReferenceDto) PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) IntrospectionException(java.beans.IntrospectionException) DataHelper(de.symeda.sormas.api.utils.DataHelper) CommunityReferenceDto(de.symeda.sormas.api.infrastructure.community.CommunityReferenceDto) List(java.util.List) ArrayList(java.util.ArrayList) PropertyDescriptor(java.beans.PropertyDescriptor) ImportErrorException(de.symeda.sormas.api.importexport.ImportErrorException) EventParticipantDto(de.symeda.sormas.api.event.EventParticipantDto) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvalidColumnException(de.symeda.sormas.api.importexport.InvalidColumnException) CsvValidationException(com.opencsv.exceptions.CsvValidationException) ImportErrorException(de.symeda.sormas.api.importexport.ImportErrorException) IntrospectionException(java.beans.IntrospectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ValidationRuntimeException(de.symeda.sormas.api.utils.ValidationRuntimeException) IOException(java.io.IOException) InvalidColumnException(de.symeda.sormas.api.importexport.InvalidColumnException) BirthDateDto(de.symeda.sormas.api.caze.BirthDateDto)

Example 3 with PersonReferenceDto

use of de.symeda.sormas.api.person.PersonReferenceDto in project SORMAS-Project by hzi-braunschweig.

the class ContactDto method build.

public static ContactDto build() {
    final ContactDto contact = new ContactDto();
    contact.setUuid(DataHelper.createUuid());
    contact.setPerson(new PersonReferenceDto(DataHelper.createUuid()));
    contact.setReportDateTime(new Date());
    contact.setContactClassification(ContactClassification.UNCONFIRMED);
    contact.setContactStatus(ContactStatus.ACTIVE);
    contact.setEpiData(EpiDataDto.build());
    contact.setHealthConditions(HealthConditionsDto.build());
    return contact;
}
Also used : PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) Date(java.util.Date)

Example 4 with PersonReferenceDto

use of de.symeda.sormas.api.person.PersonReferenceDto in project SORMAS-Project by hzi-braunschweig.

the class EntityDtoAccessHelperTest method readReferencedEntityDto.

@Test
public void readReferencedEntityDto() {
    IReferenceDtoResolver referenceDtoResolver = new EntityDtoAccessHelper.IReferenceDtoResolver() {

        @Override
        public EntityDto resolve(ReferenceDto referenceDto) {
            if (referenceDto != null && "GHIJKL".equals(referenceDto.getUuid())) {
                return personDto;
            }
            return null;
        }
    };
    assertNull(EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.firstName", null));
    caseDataDto.setPerson(personReferenceDto);
    assertNull(EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.firstName", null));
    assertEquals("Tenzing", EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.firstName", referenceDtoResolver));
    assertEquals(26, EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.BirthdateDD", referenceDtoResolver));
    assertEquals(11, EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.BirthdateMM", referenceDtoResolver));
    assertEquals(1973, EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.BirthdateYYYY", referenceDtoResolver));
    assertEquals("+49 681 1234", EntityDtoAccessHelper.getPropertyPathValue(caseDataDto, "person.phone", referenceDtoResolver));
}
Also used : PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) IReferenceDtoResolver(de.symeda.sormas.api.EntityDtoAccessHelper.IReferenceDtoResolver) Test(org.junit.Test)

Example 5 with PersonReferenceDto

use of de.symeda.sormas.api.person.PersonReferenceDto in project SORMAS-Project by hzi-braunschweig.

the class EntityDtoAccessHelperTest method setup.

@Before
public void setup() {
    caseDataDto = new CaseDataDto();
    caseDataDto.setDisease(Disease.DENGUE);
    caseDataDto.setUuid("ABCDEF");
    hospitalizationDto = new HospitalizationDto();
    hospitalizationDto.setDischargeDate(new Date(1600387200000L));
    hospitalizationDto.setIsolated(YesNoUnknown.NO);
    personReferenceDto = new PersonReferenceDto();
    personReferenceDto.setUuid("GHIJKL");
    personDto = new PersonDto();
    personDto.setUuid("GHIJKL");
    personDto.setFirstName("Tenzing");
    personDto.setLastName("Mike");
    personDto.setBirthdateDD(26);
    personDto.setBirthdateMM(11);
    personDto.setBirthdateYYYY(1973);
    personDto.setPhone("+49 681 1234");
    LocationDto address = new LocationDto();
    address.setStreet("Elm Street");
    personDto.setAddress(address);
    referenceDtoResolver = new IReferenceDtoResolver() {

        @Override
        public EntityDto resolve(ReferenceDto referenceDto) {
            if (referenceDto != null && "GHIJKL".equals(referenceDto.getUuid())) {
                return personDto;
            }
            return null;
        }
    };
}
Also used : PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) PersonDto(de.symeda.sormas.api.person.PersonDto) HospitalizationDto(de.symeda.sormas.api.hospitalization.HospitalizationDto) PersonReferenceDto(de.symeda.sormas.api.person.PersonReferenceDto) IReferenceDtoResolver(de.symeda.sormas.api.EntityDtoAccessHelper.IReferenceDtoResolver) Date(java.util.Date) LocationDto(de.symeda.sormas.api.location.LocationDto) Before(org.junit.Before)

Aggregations

PersonReferenceDto (de.symeda.sormas.api.person.PersonReferenceDto)38 Test (org.junit.Test)26 UserReferenceDto (de.symeda.sormas.api.user.UserReferenceDto)22 CaseDataDto (de.symeda.sormas.api.caze.CaseDataDto)17 AbstractBeanTest (de.symeda.sormas.backend.AbstractBeanTest)16 Date (java.util.Date)16 ContactDto (de.symeda.sormas.api.contact.ContactDto)12 PersonDto (de.symeda.sormas.api.person.PersonDto)9 ArrayList (java.util.ArrayList)9 RDCF (de.symeda.sormas.backend.TestDataCreator.RDCF)8 SormasToSormasTest (de.symeda.sormas.backend.sormastosormas.SormasToSormasTest)8 LocalDate (java.time.LocalDate)8 SimilarContactDto (de.symeda.sormas.api.contact.SimilarContactDto)6 RDCFEntities (de.symeda.sormas.backend.TestDataCreator.RDCFEntities)6 UserDto (de.symeda.sormas.api.user.UserDto)5 CaseReferenceDto (de.symeda.sormas.api.caze.CaseReferenceDto)4 ImmunizationDto (de.symeda.sormas.api.immunization.ImmunizationDto)4 TaskDto (de.symeda.sormas.api.task.TaskDto)4 BirthDateDto (de.symeda.sormas.api.caze.BirthDateDto)3 CasePersonDto (de.symeda.sormas.api.caze.CasePersonDto)3