Skip to content

Commit

Permalink
Merge pull request #105 from CaritasDeutschland/feature-delete-consul…
Browse files Browse the repository at this point in the history
…tant-admin-api

Feature delete consultant admin api
  • Loading branch information
mobo4b authored Feb 18, 2021
2 parents 2f2bc8f + bfa212c commit 4dbb8d5
Show file tree
Hide file tree
Showing 43 changed files with 728 additions and 258 deletions.
2 changes: 2 additions & 0 deletions api/useradminservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ paths:
description: BAD REQUEST - invalid/incomplete request
401:
description: UNAUTHORIZED - no/invalid role/authorization
404:
description: NOT FOUND - consultant not found
500:
description: INTERNAL SERVER ERROR - server encountered unexpected condition
security:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public ResponseEntity<Void> createConsultantAgency(@PathVariable String consulta
* Entry point to delete a consultant agency relation.
*
* @param consultantId Consultant Id (required)
* @param agencyId Agency Id (required)
* @param agencyId Agency Id (required)
*/
@Override
public ResponseEntity<Void> deleteConsultantAgency(String consultantId, Long agencyId) {
Expand All @@ -141,7 +141,8 @@ public ResponseEntity<Void> deleteConsultantAgency(String consultantId, Long age
*/
@Override
public ResponseEntity<Void> markConsultantForDeletion(@PathVariable String consultantId) {
return null;
this.consultantAdminFacade.markConsultantForDeletion(consultantId);
return new ResponseEntity<>(HttpStatus.OK);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,13 @@ public void changeAgencyType(Long agencyId, AgencyTypeDTO agencyTypeDTO) {
public void markConsultantAgencyForDeletion(String consultantId, Long agencyId) {
this.consultantAgencyAdminService.markConsultantAgencyForDeletion(consultantId, agencyId);
}

/**
* Marks the {@link Consultant} as deleted.
*
* @param consultantId the consultant id
*/
public void markConsultantForDeletion(String consultantId) {
this.consultantAdminService.markConsultantForDeletion(consultantId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class ConsultantWithWrongTeamConsultantFlagViolationReportRule implements
public List<ViolationDTO> generateViolations() {

List<ConsultantAgency> allConsultantAgencies = StreamSupport
.stream(consultantAgencyRepository.findAll().spliterator(), true)
.stream(consultantAgencyRepository.findAll().spliterator(), false)
.collect(Collectors.toList());

List<AgencyAdminResponseDTO> allAgencies = this.agencyAdminService.retrieveAllAgencies()
Expand All @@ -49,7 +49,7 @@ public List<ViolationDTO> generateViolations() {
ConsultantAgencyAnalyzer consultantAgencyAnalyzer =
new ConsultantAgencyAnalyzer(allConsultantAgencies, allAgencies);

return StreamSupport.stream(consultantRepository.findAll().spliterator(), true)
return StreamSupport.stream(consultantRepository.findAll().spliterator(), false)
.filter(Consultant::isTeamConsultant)
.filter(consultantAgencyAnalyzer::hasNoTeamAgencyAssigned)
.map(this::fromConsultant)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ public class InvalidAgencyForConsultantViolationReportRule implements ViolationR
@Override
public List<ViolationDTO> generateViolations() {
return retrieveAllDeletedAgencies().stream()
.map(consultantAgencyRepository::findByAgencyId)
.map(consultantAgencyRepository::findByAgencyIdAndDeleteDateIsNull)
.flatMap(Collection::stream)
.map(this::fromConsultantAgency)
.collect(Collectors.toList());
}

private List<Long> retrieveAllDeletedAgencies() {
return this.agencyAdminService.retrieveAllAgencies().parallelStream()
return this.agencyAdminService.retrieveAllAgencies().stream()
.filter(agencyAdminResponseDTO -> !"null".equals(agencyAdminResponseDTO.getDeleteDate()))
.map(AgencyAdminResponseDTO::getAgencyId)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class MissingAgencyForConsultantViolationReportRule implements ViolationR
*/
@Override
public List<ViolationDTO> generateViolations() {
return StreamSupport.stream(this.consultantRepository.findAll().spliterator(), true)
return StreamSupport.stream(this.consultantRepository.findAll().spliterator(), false)
.filter(consultant -> isEmpty(consultant.getConsultantAgencies()))
.map(this::fromConsultant)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ public class MissingRocketChatRoomForConsultantViolationReportRule implements Vi
*/
@Override
public List<ViolationDTO> generateViolations() {
return StreamSupport.stream(this.consultantRepository.findAll().spliterator(), true)
return StreamSupport.stream(this.consultantRepository.findAll().spliterator(), false)
.map(consultant -> this.sessionRepository
.findByConsultantAndStatus(consultant, SessionStatus.IN_PROGRESS))
.flatMap(Collection::parallelStream)
.flatMap(Collection::stream)
.map(this::fromMissingSession)
.filter(Objects::nonNull)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class MissingSessionAndChatForAskerViolationReportRule implements Violati
*/
@Override
public List<ViolationDTO> generateViolations() {
return StreamSupport.stream(this.userRepository.findAll().spliterator(), true)
return StreamSupport.stream(this.userRepository.findAll().spliterator(), false)
.filter(this::withoutSessionAndChat)
.map(this::fromUser)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ public class TeamConsultantWithoutRequiredFlagViolationReportRule implements Vio
@Override
public List<ViolationDTO> generateViolations() {
return retrieveAllTeamAgencies().stream()
.map(consultantAgencyRepository::findByAgencyId)
.map(consultantAgencyRepository::findByAgencyIdAndDeleteDateIsNull)
.flatMap(Collection::stream)
.filter(consultantAgency -> !consultantAgency.getConsultant().isTeamConsultant())
.map(this::fromConsultantAgency)
.collect(Collectors.toList());
}

private List<Long> retrieveAllTeamAgencies() {
return this.agencyAdminService.retrieveAllAgencies().parallelStream()
return this.agencyAdminService.retrieveAllAgencies().stream()
.filter(agencyAdminResponseDTO -> isTrue(agencyAdminResponseDTO.getTeamAgency()))
.map(AgencyAdminResponseDTO::getAgencyId)
.collect(Collectors.toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class ConsultantAgencyAnalyzer {
* @return true if no related agency is a team agency
*/
public boolean hasNoTeamAgencyAssigned(Consultant consultant) {
return allConsultantAgencies.parallelStream()
return allConsultantAgencies.stream()
.filter(assignedToConsultant(consultant))
.map(this::fromConsultantAgency)
.filter(Objects::nonNull)
Expand All @@ -40,7 +40,7 @@ private Predicate<ConsultantAgency> assignedToConsultant(Consultant consultant)
}

private AgencyAdminResponseDTO fromConsultantAgency(ConsultantAgency consultantAgency) {
return this.allAgencies.parallelStream()
return this.allAgencies.stream()
.filter(byConsultantAgency(consultantAgency))
.findFirst()
.orElse(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package de.caritas.cob.userservice.api.admin.service.agency;

import static de.caritas.cob.userservice.api.exception.httpresponses.customheader.HttpStatusExceptionReason.CONSULTANT_AGENCY_RELATION_DOES_NOT_EXIST;
import static de.caritas.cob.userservice.api.exception.httpresponses.customheader.HttpStatusExceptionReason.CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_HAS_OPEN_ENQUIRIES;
import static de.caritas.cob.userservice.api.exception.httpresponses.customheader.HttpStatusExceptionReason.CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_IS_STILL_ACTIVE;
import static de.caritas.cob.userservice.api.repository.session.SessionStatus.INITIAL;
import static de.caritas.cob.userservice.api.repository.session.SessionStatus.NEW;
import static de.caritas.cob.userservice.localdatetime.CustomLocalDateTime.nowInUtc;
import static java.util.Collections.singletonList;
import static java.util.Objects.isNull;
import static org.apache.commons.collections.CollectionUtils.isEmpty;
import static org.apache.commons.lang3.BooleanUtils.isFalse;

import de.caritas.cob.userservice.api.exception.AgencyServiceHelperException;
import de.caritas.cob.userservice.api.exception.httpresponses.BadRequestException;
Expand All @@ -29,7 +24,6 @@
import de.caritas.cob.userservice.api.service.helper.AgencyServiceHelper;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -46,6 +40,7 @@ public class ConsultantAgencyAdminService {
private final @NonNull SessionRepository sessionRepository;
private final @NonNull RemoveConsultantFromRocketChatService removeFromRocketChatService;
private final @NonNull AgencyServiceHelper agencyServiceHelper;
private final @NonNull ConsultantAgencyDeletionValidationService agencyDeletionValidationService;

/**
* Returns all Agencies for the given consultantId.
Expand All @@ -54,13 +49,13 @@ public class ConsultantAgencyAdminService {
* @return the list of agencies for the given consultant
*/
public ConsultantAgencyAdminResultDTO findConsultantAgencies(String consultantId) {
Optional<Consultant> consultant = consultantRepository.findById(consultantId);
Optional<Consultant> consultant = consultantRepository.findByIdAndDeleteDateIsNull(consultantId);
if (!consultant.isPresent()) {
throw new BadRequestException(
String.format("Consultant with id %s does not exist", consultantId));
}
List<ConsultantAgency> agencyList = consultantAgencyRepository
.findByConsultantId(consultantId);
.findByConsultantIdAndDeleteDateIsNull(consultantId);

return ConsultantAgencyAdminResultDTOBuilder
.getInstance()
Expand All @@ -76,7 +71,7 @@ public ConsultantAgencyAdminResultDTO findConsultantAgencies(String consultantId
*/
public void markAllAssignedConsultantsAsTeamConsultant(Long agencyId) {
List<ConsultantAgency> consultantAgencies = this.consultantAgencyRepository
.findByAgencyId(agencyId);
.findByAgencyIdAndDeleteDateIsNull(agencyId);
if (isEmpty(consultantAgencies)) {
throw new NotFoundException(String.format("Agency with id %s does not exist", agencyId));
}
Expand Down Expand Up @@ -109,7 +104,7 @@ public void removeConsultantsFromTeamSessionsByAgencyId(Long agencyId) {
this.removeFromRocketChatService.removeConsultantFromSessions(teamSessionsInProgress);
teamSessionsInProgress.forEach(this::changeSessionToNonTeamSession);

this.consultantRepository.findByConsultantAgenciesAgencyIdIn(singletonList(agencyId))
this.consultantRepository.findByConsultantAgenciesAgencyIdInAndDeleteDateIsNull(singletonList(agencyId))
.stream()
.filter(consultant -> noOtherTeamAgency(consultant, agencyId))
.forEach(this::removeTeamConsultantFlag);
Expand Down Expand Up @@ -149,7 +144,7 @@ private void removeTeamConsultantFlag(Consultant consultant) {
*/
public void markConsultantAgencyForDeletion(String consultantId, Long agencyId) {
List<ConsultantAgency> consultantAgencies =
this.consultantAgencyRepository.findByConsultantIdAndAgencyId(consultantId, agencyId);
this.consultantAgencyRepository.findByConsultantIdAndAgencyIdAndDeleteDateIsNull(consultantId, agencyId);
if (isEmpty(consultantAgencies)) {
throw new CustomValidationHttpStatusException(CONSULTANT_AGENCY_RELATION_DOES_NOT_EXIST);
}
Expand All @@ -159,53 +154,9 @@ public void markConsultantAgencyForDeletion(String consultantId, Long agencyId)
}

private void markAsDeleted(ConsultantAgency consultantAgency) {
validateForDeletion(consultantAgency);
this.agencyDeletionValidationService.validateForDeletion(consultantAgency);
consultantAgency.setDeleteDate(nowInUtc());
this.consultantAgencyRepository.save(consultantAgency);
}

private void validateForDeletion(ConsultantAgency consultantAgency) {
if (isTheLastConsultantInAgency(consultantAgency)) {
if (isAgencyStillActive(consultantAgency)) {
throw new CustomValidationHttpStatusException(
CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_IS_STILL_ACTIVE);
}
if (hasOpenEnquiries(consultantAgency)) {
throw new CustomValidationHttpStatusException(
CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_HAS_OPEN_ENQUIRIES);
}
}
}

private boolean isTheLastConsultantInAgency(ConsultantAgency consultantAgency) {
return this.consultantAgencyRepository.findByAgencyId(consultantAgency.getAgencyId())
.stream()
.filter(relation -> isNull(relation.getDeleteDate()))
.allMatch(sameConsultantAgencyRelation(consultantAgency));
}

private Predicate<ConsultantAgency> sameConsultantAgencyRelation(
ConsultantAgency consultantAgency) {
return relation -> relation.equals(consultantAgency);
}

private boolean isAgencyStillActive(ConsultantAgency consultantAgency) {
try {
AgencyDTO agency = this.agencyServiceHelper.getAgency(consultantAgency.getAgencyId());
return isFalse(agency.getOffline());
} catch (AgencyServiceHelperException e) {
throw new InternalServerErrorException(e.getMessage());
}
}

private boolean hasOpenEnquiries(ConsultantAgency consultantAgency) {
Long agencyId = consultantAgency.getAgencyId();
return hasSessionWithStatus(agencyId, NEW) || hasSessionWithStatus(agencyId, INITIAL);
}

private boolean hasSessionWithStatus(Long agencyId, SessionStatus status) {
return !this.sessionRepository.findByAgencyIdAndStatusAndConsultantIsNull(agencyId, status)
.isEmpty();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package de.caritas.cob.userservice.api.admin.service.agency;

import static de.caritas.cob.userservice.api.exception.httpresponses.customheader.HttpStatusExceptionReason.CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_HAS_OPEN_ENQUIRIES;
import static de.caritas.cob.userservice.api.exception.httpresponses.customheader.HttpStatusExceptionReason.CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_IS_STILL_ACTIVE;
import static de.caritas.cob.userservice.api.repository.session.SessionStatus.INITIAL;
import static de.caritas.cob.userservice.api.repository.session.SessionStatus.NEW;
import static java.util.Objects.isNull;
import static org.apache.commons.lang3.BooleanUtils.isFalse;

import de.caritas.cob.userservice.api.exception.AgencyServiceHelperException;
import de.caritas.cob.userservice.api.exception.httpresponses.CustomValidationHttpStatusException;
import de.caritas.cob.userservice.api.exception.httpresponses.InternalServerErrorException;
import de.caritas.cob.userservice.api.model.AgencyDTO;
import de.caritas.cob.userservice.api.repository.consultantagency.ConsultantAgency;
import de.caritas.cob.userservice.api.repository.consultantagency.ConsultantAgencyRepository;
import de.caritas.cob.userservice.api.repository.session.SessionRepository;
import de.caritas.cob.userservice.api.repository.session.SessionStatus;
import de.caritas.cob.userservice.api.service.helper.AgencyServiceHelper;
import java.util.function.Predicate;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ConsultantAgencyDeletionValidationService {

private final @NonNull ConsultantAgencyRepository consultantAgencyRepository;
private final @NonNull AgencyServiceHelper agencyServiceHelper;
private final @NonNull SessionRepository sessionRepository;

/**
* Validates if the given {@link ConsultantAgency} is valid to be deleted.
*
* @param consultantAgency the {@link ConsultantAgency} to be deleted
*/
public void validateForDeletion(ConsultantAgency consultantAgency) {
if (isTheLastConsultantInAgency(consultantAgency)) {
if (isAgencyStillActive(consultantAgency)) {
throw new CustomValidationHttpStatusException(
CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_IS_STILL_ACTIVE);
}
if (hasOpenEnquiries(consultantAgency)) {
throw new CustomValidationHttpStatusException(
CONSULTANT_IS_THE_LAST_OF_AGENCY_AND_AGENCY_HAS_OPEN_ENQUIRIES);
}
}
}

private boolean isTheLastConsultantInAgency(ConsultantAgency consultantAgency) {
return this.consultantAgencyRepository.findByAgencyIdAndDeleteDateIsNull(consultantAgency.getAgencyId())
.stream()
.filter(relation -> isNull(relation.getDeleteDate()))
.allMatch(sameConsultantAgencyRelation(consultantAgency));
}

private Predicate<ConsultantAgency> sameConsultantAgencyRelation(
ConsultantAgency consultantAgency) {
return relation -> relation.equals(consultantAgency);
}

private boolean isAgencyStillActive(ConsultantAgency consultantAgency) {
try {
AgencyDTO agency = this.agencyServiceHelper.getAgency(consultantAgency.getAgencyId());
return isFalse(agency.getOffline());
} catch (AgencyServiceHelperException e) {
throw new InternalServerErrorException(e.getMessage());
}
}

private boolean hasOpenEnquiries(ConsultantAgency consultantAgency) {
Long agencyId = consultantAgency.getAgencyId();
return hasSessionWithStatus(agencyId, NEW) || hasSessionWithStatus(agencyId, INITIAL);
}

private boolean hasSessionWithStatus(Long agencyId, SessionStatus status) {
return !this.sessionRepository.findByAgencyIdAndStatusAndConsultantIsNull(agencyId, status)
.isEmpty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ private List<Consultant> observeFromSession(Session session)
.stream()
.filter(notUserAndNotDirectlyAssignedConsultant(session))
.map(GroupMemberDTO::get_id)
.map(this.consultantRepository::findByRocketChatId)
.map(this.consultantRepository::findByRocketChatIdAndDeleteDateIsNull)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
Expand Down
Loading

0 comments on commit 4dbb8d5

Please sign in to comment.