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.roles.ApplicationRoles;
|
||||
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.FileStatusManagementService;
|
||||
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.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.warning.ApproveResponse;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
@ -64,6 +66,7 @@ public class StatusController implements StatusResource {
|
||||
private final AccessControlService accessControlService;
|
||||
private final NotificationPersistenceService notificationPersistenceService;
|
||||
private final DossierACLService dossierACLService;
|
||||
private final ApprovalVerificationService approvalVerificationService;
|
||||
|
||||
|
||||
@Override
|
||||
@ -299,31 +302,40 @@ public class StatusController implements StatusResource {
|
||||
|
||||
|
||||
@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.verifyUserIsApprover(dossierId);
|
||||
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());
|
||||
ApproveResponse approveResponse = new ApproveResponse(false, new HashMap<>());
|
||||
if (!force) {
|
||||
approveResponse = approvalVerificationService.verifyApprovalOfFile(dossierId, fileId);
|
||||
}
|
||||
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
|
||||
@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.verifyUserIsApprover(dossierId);
|
||||
|
||||
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.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.responses.ApiResponse;
|
||||
@ -35,6 +36,7 @@ public interface StatusResource {
|
||||
String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";
|
||||
|
||||
String ASSIGNEE_ID_REQUEST_PARAM = "assigneeId";
|
||||
String FORCE_REQUEST_PARAM = "force";
|
||||
|
||||
String DELETED_PATH = "/softdeleted";
|
||||
|
||||
@ -105,11 +107,13 @@ public interface StatusResource {
|
||||
@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)
|
||||
@Operation(summary = "Sets the status APPROVED for a file.", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void setStatusApproved(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
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)
|
||||
@ -139,11 +143,13 @@ public interface StatusResource {
|
||||
@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)
|
||||
@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")})
|
||||
void setStatusApprovedForList(@PathVariable(DOSSIER_ID) String dossierId, @RequestBody List<String> fileIds);
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Dossier not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
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)
|
||||
|
||||
@ -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());
|
||||
|
||||
fileClient.setStatusApproved(getDossierId(), getFileId());
|
||||
fileClient.setStatusApproved(getDossierId(), getFileId(), true);
|
||||
|
||||
assertThatTestFileIsApproved();
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ public class DownloadTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
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());
|
||||
assertThat(file22.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
||||
|
||||
|
||||
@ -299,7 +299,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
||||
assertThat(loadedFile.getLastApprover()).isEqualTo(userId);
|
||||
|
||||
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());
|
||||
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
||||
assertThat(loadedFile.getAssignee()).isEqualTo(userId);
|
||||
@ -322,7 +322,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
||||
assertThat(loadedFile.getLastReviewer()).isEqualTo(userId);
|
||||
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());
|
||||
assertThat(loadedFile.getWorkflowStatus()).isEqualTo(WorkflowStatus.APPROVED);
|
||||
assertThat(loadedFile.getAssignee()).isEqualTo(userId);
|
||||
|
||||
@ -373,7 +373,7 @@ public class ReportTemplateTest extends AbstractPersistenceServerServiceTest {
|
||||
var file = fileTesterAndProvider.testAndProvideFile(dossier);
|
||||
|
||||
fileTesterAndProvider.markFileAsProcessed(dossier.getId(), file.getFileId());
|
||||
fileClient.setStatusApproved(dossier.getId(), file.getId());
|
||||
fileClient.setStatusApproved(dossier.getId(), file.getId(), true);
|
||||
|
||||
// Act & Assert
|
||||
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