Merge branch 'RED-9717' into 'master'
RED-9717 - Add warnings on approval Closes RED-9717 See merge request redactmanager/persistence-service!632
This commit is contained in:
commit
4eeee75f33
@ -26,6 +26,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.BadRe
|
|||||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException;
|
import com.iqser.red.service.persistence.management.v1.processor.exception.NotAllowedException;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles;
|
import com.iqser.red.service.persistence.management.v1.processor.roles.ApplicationRoles;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.ApprovalVerificationService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusMapper;
|
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusMapper;
|
||||||
@ -42,6 +43,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
|
|||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.NotificationType;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.NotificationType;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.ApproveResponse;
|
||||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||||
|
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
@ -64,6 +66,7 @@ public class StatusController implements StatusResource {
|
|||||||
private final AccessControlService accessControlService;
|
private final AccessControlService accessControlService;
|
||||||
private final NotificationPersistenceService notificationPersistenceService;
|
private final NotificationPersistenceService notificationPersistenceService;
|
||||||
private final DossierACLService dossierACLService;
|
private final DossierACLService dossierACLService;
|
||||||
|
private final ApprovalVerificationService approvalVerificationService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -299,31 +302,40 @@ public class StatusController implements StatusResource {
|
|||||||
|
|
||||||
|
|
||||||
@PreAuthorize("hasAuthority('" + SET_STATUS_APPROVED + "')")
|
@PreAuthorize("hasAuthority('" + SET_STATUS_APPROVED + "')")
|
||||||
public void setStatusApproved(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {
|
public ApproveResponse setStatusApproved(@PathVariable(DOSSIER_ID) String dossierId,
|
||||||
|
@PathVariable(FILE_ID) String fileId,
|
||||||
|
@RequestParam(value = FORCE_REQUEST_PARAM, required = false, defaultValue = "false") boolean force) {
|
||||||
|
|
||||||
accessControlService.checkAccessPermissionsToDossier(dossierId);
|
accessControlService.checkAccessPermissionsToDossier(dossierId);
|
||||||
accessControlService.verifyUserIsApprover(dossierId);
|
accessControlService.verifyUserIsApprover(dossierId);
|
||||||
setStatusApprovedForFile(dossierId, fileId);
|
ApproveResponse approveResponse = new ApproveResponse(false, new HashMap<>());
|
||||||
auditPersistenceService.audit(AuditRequest.builder()
|
if (!force) {
|
||||||
.userId(KeycloakSecurity.getUserId())
|
approveResponse = approvalVerificationService.verifyApprovalOfFile(dossierId, fileId);
|
||||||
.objectId(fileId)
|
|
||||||
.category(AuditCategory.DOCUMENT.name())
|
|
||||||
.message("Document status was changed to Approved")
|
|
||||||
.details(Map.of(DOSSIER_ID, dossierId))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
var dossier = dossierACLService.enhanceDossierWithACLData(dossierManagementService.getDossierById(dossierId, false, false));
|
|
||||||
if (!dossier.getOwnerId().equals(KeycloakSecurity.getUserId())) {
|
|
||||||
|
|
||||||
var fileStatus = fileStatusManagementService.getFileStatus(fileId);
|
|
||||||
|
|
||||||
notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
|
||||||
.userId(dossier.getOwnerId())
|
|
||||||
.issuerId(KeycloakSecurity.getUserId())
|
|
||||||
.notificationType(NotificationType.DOCUMENT_APPROVED.name())
|
|
||||||
.target(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, FILE_NAME, fileStatus.getFilename()))
|
|
||||||
.build());
|
|
||||||
}
|
}
|
||||||
|
if (!approveResponse.isHasWarnings()) {
|
||||||
|
setStatusApprovedForFile(dossierId, fileId);
|
||||||
|
auditPersistenceService.audit(AuditRequest.builder()
|
||||||
|
.userId(KeycloakSecurity.getUserId())
|
||||||
|
.objectId(fileId)
|
||||||
|
.category(AuditCategory.DOCUMENT.name())
|
||||||
|
.message("Document status was changed to Approved")
|
||||||
|
.details(Map.of(DOSSIER_ID, dossierId))
|
||||||
|
.build());
|
||||||
|
|
||||||
|
var dossier = dossierACLService.enhanceDossierWithACLData(dossierManagementService.getDossierById(dossierId, false, false));
|
||||||
|
if (!dossier.getOwnerId().equals(KeycloakSecurity.getUserId())) {
|
||||||
|
|
||||||
|
var fileStatus = fileStatusManagementService.getFileStatus(fileId);
|
||||||
|
|
||||||
|
notificationPersistenceService.insertNotification(AddNotificationRequest.builder()
|
||||||
|
.userId(dossier.getOwnerId())
|
||||||
|
.issuerId(KeycloakSecurity.getUserId())
|
||||||
|
.notificationType(NotificationType.DOCUMENT_APPROVED.name())
|
||||||
|
.target(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, FILE_NAME, fileStatus.getFilename()))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return approveResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -398,14 +410,22 @@ public class StatusController implements StatusResource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@PreAuthorize("hasAuthority('" + SET_STATUS_APPROVED + "')")
|
@PreAuthorize("hasAuthority('" + SET_STATUS_APPROVED + "')")
|
||||||
public void setStatusApprovedForList(String dossierId, List<String> fileIds) {
|
public List<ApproveResponse> setStatusApprovedForList(String dossierId,
|
||||||
|
List<String> fileIds,
|
||||||
|
@RequestParam(value = FORCE_REQUEST_PARAM, required = false, defaultValue = "false") boolean force) {
|
||||||
|
|
||||||
|
List<ApproveResponse> approveResponses = new ArrayList<>();
|
||||||
accessControlService.checkAccessPermissionsToDossier(dossierId);
|
accessControlService.checkAccessPermissionsToDossier(dossierId);
|
||||||
accessControlService.verifyUserIsApprover(dossierId);
|
accessControlService.verifyUserIsApprover(dossierId);
|
||||||
|
|
||||||
dossierManagementService.getDossierById(dossierId, false, false);
|
dossierManagementService.getDossierById(dossierId, false, false);
|
||||||
|
|
||||||
fileIds.forEach(fileId -> setStatusApproved(dossierId, fileId));
|
if (fileIds.size() > 50) {
|
||||||
|
throw new BadRequestException("Maximum amount of files that can be approved at once is 50.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fileIds.forEach(fileId -> approveResponses.add(setStatusApproved(dossierId, fileId, force)));
|
||||||
|
return approveResponses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
|||||||
|
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.ApproveResponse;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
@ -35,6 +36,7 @@ public interface StatusResource {
|
|||||||
String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";
|
String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";
|
||||||
|
|
||||||
String ASSIGNEE_ID_REQUEST_PARAM = "assigneeId";
|
String ASSIGNEE_ID_REQUEST_PARAM = "assigneeId";
|
||||||
|
String FORCE_REQUEST_PARAM = "force";
|
||||||
|
|
||||||
String DELETED_PATH = "/softdeleted";
|
String DELETED_PATH = "/softdeleted";
|
||||||
|
|
||||||
@ -105,11 +107,13 @@ public interface StatusResource {
|
|||||||
@RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);
|
@RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);
|
||||||
|
|
||||||
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
@PostMapping(value = STATUS_REST_PATH + "/approved" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE)
|
@PostMapping(value = STATUS_REST_PATH + "/approved" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE)
|
||||||
@Operation(summary = "Sets the status APPROVED for a file.", description = "None")
|
@Operation(summary = "Sets the status APPROVED for a file.", description = "None")
|
||||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||||
void setStatusApproved(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
ApproveResponse setStatusApproved(@PathVariable(DOSSIER_ID) String dossierId,
|
||||||
|
@PathVariable(FILE_ID) String fileId,
|
||||||
|
@RequestParam(value = FORCE_REQUEST_PARAM, required = false, defaultValue = "false") boolean force);
|
||||||
|
|
||||||
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
@ -139,11 +143,13 @@ public interface StatusResource {
|
|||||||
@RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);
|
@RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);
|
||||||
|
|
||||||
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
@PostMapping(value = STATUS_REST_PATH + "/approved" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
|
@PostMapping(value = STATUS_REST_PATH + "/approved" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@Operation(summary = "Sets the status APPROVED for a list of files.", description = "None")
|
@Operation(summary = "Sets the status APPROVED for a list of files.", description = "None")
|
||||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||||
void setStatusApprovedForList(@PathVariable(DOSSIER_ID) String dossierId, @RequestBody List<String> fileIds);
|
List<ApproveResponse> setStatusApprovedForList(@PathVariable(DOSSIER_ID) String dossierId,
|
||||||
|
@RequestBody List<String> fileIds,
|
||||||
|
@RequestParam(value = FORCE_REQUEST_PARAM, required = false, defaultValue = "false") boolean force);
|
||||||
|
|
||||||
|
|
||||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||||
|
|||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.iqser.red.service.persistence.management.v1.processor.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.LegalBasisEntity;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.LegalBasisMappingPersistenceService;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.ApproveResponse;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.WarningModel;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.WarningType;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||||
|
public class ApprovalVerificationService {
|
||||||
|
|
||||||
|
EntityLogService entityLogService;
|
||||||
|
LegalBasisMappingPersistenceService legalBasisMappingPersistenceService;
|
||||||
|
DossierRepository dossierRepository;
|
||||||
|
|
||||||
|
|
||||||
|
public ApproveResponse verifyApprovalOfFile(String dossierId, String fileId) {
|
||||||
|
|
||||||
|
ApproveResponse approveResponse = new ApproveResponse();
|
||||||
|
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, true);
|
||||||
|
List<EntityLogEntry> entityLogEntries = entityLog.getEntityLogEntry();
|
||||||
|
List<LegalBasisEntity> legalBasisMappings = legalBasisMappingPersistenceService.getLegalBasisMapping(dossierRepository.findDossierTemplateId(dossierId));
|
||||||
|
|
||||||
|
for (EntityLogEntry entry : entityLogEntries) {
|
||||||
|
if (entry.getState().equals(EntryState.APPLIED) && !entry.getEntryType().equals(EntryType.IMAGE) && !entry.getEntryType().equals(EntryType.IMAGE_HINT)) {
|
||||||
|
if (StringUtils.isEmpty(entry.getLegalBasis())) {
|
||||||
|
addWarning(entry, fileId, WarningType.LEGAL_BASIS_MISSING, approveResponse);
|
||||||
|
} else {
|
||||||
|
var legalBasisEntity = legalBasisMappings.stream()
|
||||||
|
.filter(mapping -> mapping.getReason().equals(entry.getLegalBasis()))
|
||||||
|
.findFirst();
|
||||||
|
if (legalBasisEntity.isEmpty() || StringUtils.isEmpty(legalBasisEntity.get().getTechnicalName())) {
|
||||||
|
addWarning(entry, fileId, WarningType.UNMAPPED_JUSTIFICATION, approveResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entry.getState().equals(EntryState.PENDING)) {
|
||||||
|
addWarning(entry, fileId, WarningType.PENDING_CHANGE, approveResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
approveResponse.setHasWarnings(approveResponse.getFileWarnings() != null && !approveResponse.getFileWarnings().isEmpty());
|
||||||
|
return approveResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void addWarning(EntityLogEntry entry, String fileId, WarningType warningType, ApproveResponse approveResponse) {
|
||||||
|
|
||||||
|
approveResponse.addFileWarning(fileId,
|
||||||
|
WarningModel.builder()
|
||||||
|
.id(entry.getId())
|
||||||
|
.pages(entry.getPositions()
|
||||||
|
.stream()
|
||||||
|
.map(Position::getPageNumber)
|
||||||
|
.collect(Collectors.toSet()))
|
||||||
|
.value(shortenValue(entry.getValue()))
|
||||||
|
.warningType(warningType)
|
||||||
|
.type(entry.getType())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private String shortenValue(String value) {
|
||||||
|
|
||||||
|
if (value.length() > 100) {
|
||||||
|
return value.substring(0, 97) + "...";
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,189 @@
|
|||||||
|
package com.iqser.red.service.peristence.v1.server.integration.tests;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||||
|
|
||||||
|
import com.iqser.red.service.peristence.v1.server.integration.client.FileClient;
|
||||||
|
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider;
|
||||||
|
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
|
||||||
|
import com.iqser.red.service.peristence.v1.server.integration.service.FileTesterAndProvider;
|
||||||
|
import com.iqser.red.service.peristence.v1.server.integration.service.TypeProvider;
|
||||||
|
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.LegalBasisEntity;
|
||||||
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.LegalBasisMappingPersistenceService;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.ApproveResponse;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.warning.WarningType;
|
||||||
|
|
||||||
|
public class ApprovalTest extends AbstractPersistenceServerServiceTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DossierTemplateTesterAndProvider dossierTemplateTesterAndProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FileTesterAndProvider fileTesterAndProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DossierTesterAndProvider dossierTesterAndProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TypeProvider typeProvider;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FileClient fileClient;
|
||||||
|
|
||||||
|
@SpyBean
|
||||||
|
private LegalBasisMappingPersistenceService legalBasisMappingPersistenceService;
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApprovalNoWarnings() {
|
||||||
|
|
||||||
|
DossierTemplateModel dossierTemplateModel = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
Dossier dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplateModel);
|
||||||
|
FileStatus file = fileTesterAndProvider.testAndProvideFile(dossier, "file");
|
||||||
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||||
|
|
||||||
|
when(legalBasisMappingPersistenceService.getLegalBasisMapping(anyString())).thenReturn(List.of(LegalBasisEntity.builder()
|
||||||
|
.technicalName("legal_basis")
|
||||||
|
.reason("legalBasis")
|
||||||
|
.build()));
|
||||||
|
EntityLog entityLog = new EntityLog();
|
||||||
|
entityLog.setEntityLogEntry(List.of(EntityLogEntry.builder()
|
||||||
|
.id("id1")
|
||||||
|
.positions(List.of(new Position(1, 1, 1, 1, 1)))
|
||||||
|
.state(EntryState.APPLIED)
|
||||||
|
.legalBasis("legalBasis")
|
||||||
|
.entryType(EntryType.ENTITY)
|
||||||
|
.value("value")
|
||||||
|
.build()));
|
||||||
|
when(entityLogService.getEntityLog(anyString(), anyString(), anyBoolean())).thenReturn(entityLog);
|
||||||
|
|
||||||
|
ApproveResponse approveResponse = fileClient.setStatusApproved(dossier.getId(), file.getFileId(), false);
|
||||||
|
|
||||||
|
assertFalse(approveResponse.isHasWarnings());
|
||||||
|
assertTrue(approveResponse.getFileWarnings().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApprovalWithWarnings() {
|
||||||
|
|
||||||
|
DossierTemplateModel dossierTemplateModel = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
Dossier dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplateModel);
|
||||||
|
FileStatus file = fileTesterAndProvider.testAndProvideFile(dossier, "file");
|
||||||
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||||
|
|
||||||
|
EntityLog entityLog = new EntityLog();
|
||||||
|
entityLog.setEntityLogEntry(List.of(EntityLogEntry.builder()
|
||||||
|
.id("id1")
|
||||||
|
.positions(List.of(new Position(1, 1, 1, 1, 1)))
|
||||||
|
.state(EntryState.APPLIED)
|
||||||
|
.entryType(EntryType.ENTITY)
|
||||||
|
.value("value")
|
||||||
|
.build(),
|
||||||
|
EntityLogEntry.builder()
|
||||||
|
.id("id2")
|
||||||
|
.positions(List.of(new Position(1, 1, 1, 1, 2)))
|
||||||
|
.state(EntryState.PENDING)
|
||||||
|
.entryType(EntryType.ENTITY)
|
||||||
|
.legalBasis("legalBasis")
|
||||||
|
.value("value")
|
||||||
|
.build()));
|
||||||
|
|
||||||
|
when(entityLogService.getEntityLog(anyString(), anyString(), anyBoolean())).thenReturn(entityLog);
|
||||||
|
|
||||||
|
ApproveResponse approveResponse = fileClient.setStatusApproved(dossier.getId(), file.getFileId(), false);
|
||||||
|
|
||||||
|
assertTrue(approveResponse.isHasWarnings());
|
||||||
|
assertFalse(approveResponse.getFileWarnings().isEmpty());
|
||||||
|
assertEquals(approveResponse.getFileWarnings()
|
||||||
|
.get(file.getFileId())
|
||||||
|
.stream()
|
||||||
|
.filter(c -> c.getWarningType().equals(WarningType.PENDING_CHANGE))
|
||||||
|
.count(), 1);
|
||||||
|
assertEquals(approveResponse.getFileWarnings()
|
||||||
|
.get(file.getFileId())
|
||||||
|
.stream()
|
||||||
|
.filter(c -> c.getWarningType().equals(WarningType.LEGAL_BASIS_MISSING))
|
||||||
|
.count(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testApprovalWithWarningValueTooLoong() {
|
||||||
|
|
||||||
|
DossierTemplateModel dossierTemplateModel = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
Dossier dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplateModel);
|
||||||
|
FileStatus file = fileTesterAndProvider.testAndProvideFile(dossier, "file");
|
||||||
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||||
|
|
||||||
|
EntityLog entityLog = new EntityLog();
|
||||||
|
entityLog.setEntityLogEntry(List.of(EntityLogEntry.builder()
|
||||||
|
.id("id2")
|
||||||
|
.positions(List.of(new Position(1, 1, 1, 1, 2)))
|
||||||
|
.state(EntryState.PENDING)
|
||||||
|
.legalBasis("legalBasis")
|
||||||
|
.value(StringUtils.repeat("a", 1000))
|
||||||
|
.build()));
|
||||||
|
|
||||||
|
when(entityLogService.getEntityLog(anyString(), anyString(), anyBoolean())).thenReturn(entityLog);
|
||||||
|
|
||||||
|
ApproveResponse approveResponse = fileClient.setStatusApproved(dossier.getId(), file.getFileId(), false);
|
||||||
|
|
||||||
|
assertTrue(approveResponse.isHasWarnings());
|
||||||
|
assertFalse(approveResponse.getFileWarnings().isEmpty());
|
||||||
|
assertEquals(approveResponse.getFileWarnings()
|
||||||
|
.get(file.getFileId())
|
||||||
|
.get(0).getValue().length(), 100);
|
||||||
|
assertEquals(approveResponse.getFileWarnings()
|
||||||
|
.get(file.getFileId())
|
||||||
|
.get(0).getWarningType(), WarningType.PENDING_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForceApprovalWithIssues() {
|
||||||
|
|
||||||
|
DossierTemplateModel dossierTemplateModel = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
Dossier dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplateModel);
|
||||||
|
FileStatus file = fileTesterAndProvider.testAndProvideFile(dossier, "file");
|
||||||
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||||
|
|
||||||
|
EntityLog entityLog = new EntityLog();
|
||||||
|
entityLog.setEntityLogEntry(List.of(EntityLogEntry.builder()
|
||||||
|
.id("id2")
|
||||||
|
.positions(List.of(new Position(1, 1, 1, 1, 2)))
|
||||||
|
.state(EntryState.PENDING)
|
||||||
|
.legalBasis("legalBasis")
|
||||||
|
.value(StringUtils.repeat("a", 1000))
|
||||||
|
.build()));
|
||||||
|
|
||||||
|
when(entityLogService.getEntityLog(anyString(), anyString(), anyBoolean())).thenReturn(entityLog);
|
||||||
|
|
||||||
|
ApproveResponse approveResponse = fileClient.setStatusApproved(dossier.getId(), file.getFileId(), true);
|
||||||
|
|
||||||
|
assertFalse(approveResponse.isHasWarnings());
|
||||||
|
assertTrue(approveResponse.getFileWarnings().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -255,7 +255,7 @@ public class DownloadPreparationTest extends AbstractPersistenceServerServiceTes
|
|||||||
|
|
||||||
fileTesterAndProvider.markFileAsProcessed(getDossierId(), getFileId());
|
fileTesterAndProvider.markFileAsProcessed(getDossierId(), getFileId());
|
||||||
|
|
||||||
fileClient.setStatusApproved(getDossierId(), getFileId());
|
fileClient.setStatusApproved(getDossierId(), getFileId(), true);
|
||||||
|
|
||||||
assertThatTestFileIsApproved();
|
assertThatTestFileIsApproved();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,7 +83,7 @@ public class DownloadTest extends AbstractPersistenceServerServiceTest {
|
|||||||
|
|
||||||
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file2.getFileId());
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file2.getFileId());
|
||||||
|
|
||||||
fileClient.setStatusApproved(dossier.getId(), file2.getId());
|
fileClient.setStatusApproved(dossier.getId(), file2.getId(), true);
|
||||||
var file22 = fileClient.getFileStatus(dossier.getId(), file2.getId());
|
var file22 = fileClient.getFileStatus(dossier.getId(), file2.getId());
|
||||||
assertThat(file22.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
assertThat(file22.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
||||||
|
|
||||||
|
|||||||
@ -299,7 +299,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
|||||||
assertThat(loadedFile.getLastApprover()).isEqualTo(userId);
|
assertThat(loadedFile.getLastApprover()).isEqualTo(userId);
|
||||||
|
|
||||||
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||||
fileClient.setStatusApproved(dossier.getId(), file.getId());
|
fileClient.setStatusApproved(dossier.getId(), file.getId(), true);
|
||||||
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
|
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
|
||||||
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
||||||
assertThat(loadedFile.getAssignee()).isEqualTo(userId);
|
assertThat(loadedFile.getAssignee()).isEqualTo(userId);
|
||||||
@ -322,7 +322,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
|||||||
assertThat(loadedFile.getLastReviewer()).isEqualTo(userId);
|
assertThat(loadedFile.getLastReviewer()).isEqualTo(userId);
|
||||||
assertThat(loadedFile.getLastApprover()).isEqualTo(altUserId);
|
assertThat(loadedFile.getLastApprover()).isEqualTo(altUserId);
|
||||||
|
|
||||||
fileClient.setStatusApproved(dossier.getId(), file.getId());
|
fileClient.setStatusApproved(dossier.getId(), file.getId(), true);
|
||||||
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
|
loadedFile = fileClient.getFileStatus(dossier.getId(), file.getId());
|
||||||
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
||||||
assertThat(loadedFile.getAssignee()).isEqualTo(userId);
|
assertThat(loadedFile.getAssignee()).isEqualTo(userId);
|
||||||
|
|||||||
@ -373,7 +373,7 @@ public class ReportTemplateTest extends AbstractPersistenceServerServiceTest {
|
|||||||
var file = fileTesterAndProvider.testAndProvideFile(dossier);
|
var file = fileTesterAndProvider.testAndProvideFile(dossier);
|
||||||
|
|
||||||
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||||
fileClient.setStatusApproved(dossier.getId(), file.getId());
|
fileClient.setStatusApproved(dossier.getId(), file.getId(), true);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
var availableTemplates = reportTemplateClient.getAvailableReportTemplates(dossier.getDossierTemplateId());
|
var availableTemplates = reportTemplateClient.getAvailableReportTemplates(dossier.getDossierTemplateId());
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
package com.iqser.red.service.persistence.service.v1.api.shared.model.warning;
|
||||||
|
|
||||||
|
import static com.iqser.red.service.persistence.service.v1.api.shared.model.warning.WarningsComparatorUtils.WARNING_MODEL_COMPARATOR;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class ApproveResponse {
|
||||||
|
|
||||||
|
private boolean hasWarnings;
|
||||||
|
|
||||||
|
private Map<String, List<WarningModel>> fileWarnings = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
public void addFileWarning(String fileId, WarningModel warningModel) {
|
||||||
|
|
||||||
|
if (fileWarnings.containsKey(fileId)) {
|
||||||
|
fileWarnings.get(fileId).add(warningModel);
|
||||||
|
} else {
|
||||||
|
List<WarningModel> warningModels = new ArrayList<>();
|
||||||
|
warningModels.add(warningModel);
|
||||||
|
fileWarnings.put(fileId, warningModels);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileWarnings.get(fileId).sort(WARNING_MODEL_COMPARATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package com.iqser.red.service.persistence.service.v1.api.shared.model.warning;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class WarningModel {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
private Set<Integer> pages;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private WarningType warningType;
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.iqser.red.service.persistence.service.v1.api.shared.model.warning;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum WarningType {
|
||||||
|
|
||||||
|
PENDING_CHANGE("pending change"),
|
||||||
|
LEGAL_BASIS_MISSING("legal basis missing"),
|
||||||
|
UNMAPPED_JUSTIFICATION("unmapped justification");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.iqser.red.service.persistence.service.v1.api.shared.model.warning;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class WarningsComparatorUtils {
|
||||||
|
|
||||||
|
|
||||||
|
public static final Comparator<Set<Integer>> LIST_COMPARATOR = Comparator.comparingInt(Collections::min);
|
||||||
|
|
||||||
|
public static final Comparator<WarningModel> WARNING_MODEL_COMPARATOR = (wm1, wm2) -> LIST_COMPARATOR.compare(wm1.getPages(), wm2.getPages());
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user