RED-7317: add getComment Endpoint
* moved manual redaction undo code
This commit is contained in:
parent
0b173ec930
commit
d1d5331202
@ -8,8 +8,6 @@ import static com.iqser.red.service.persistence.management.v1.processor.roles.Ac
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -20,10 +18,10 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionUndoService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.external.resource.ManualRedactionResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
@ -31,20 +29,14 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.CommentResp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.CommentRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Comments;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualAddResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualImageRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddCommentRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ForceRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.LegalBasisChangeRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ManualRedactionWrapperModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequestModel;
|
||||
@ -62,182 +54,20 @@ public class ManualRedactionController implements ManualRedactionResource {
|
||||
private static final String DOSSIER_ID = "dossierId";
|
||||
private static final String ANNOTATION_ID = "annotationId";
|
||||
private final ManualRedactionService manualRedactionService;
|
||||
private final ManualRedactionUndoService manualRedactionUndoService;
|
||||
private final DossierManagementService dossierManagementService;
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
private final AccessControlService accessControlService;
|
||||
|
||||
|
||||
private ManualRedactionWrapperModel getLatestManualRedactionForAnnotationId(ManualRedactions manualRedactions, String annotationId) {
|
||||
|
||||
final List<ManualRedactionWrapperModel> manualRedactionWrappers = new ArrayList<>();
|
||||
|
||||
manualRedactions.getEntriesToAdd()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getImageRecategorization()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getIdsToRemove()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getForceRedactions()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getLegalBasisChanges()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getResizeRedactions()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
var sortedManualRedactionWrappers = manualRedactionWrappers.stream()
|
||||
.sorted(Comparator.comparing(ManualRedactionWrapperModel::getDate, Comparator.nullsLast(Comparator.reverseOrder())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return sortedManualRedactionWrappers.isEmpty() ? null : sortedManualRedactionWrappers.get(0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + DELETE_MANUAL_REDACTION + "')")
|
||||
public void undo(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set<String> annotationIds) {
|
||||
|
||||
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
|
||||
accessControlService.verifyUserIsApprover(dossierId);
|
||||
manualRedactionUndoService.undo(dossierId, fileId, annotationIds);
|
||||
|
||||
ManualRedactions manualRedactions = manualRedactionService.getManualRedactions(fileId);
|
||||
|
||||
Map<String, ManualRedactionWrapperModel> manualRedactionWrappers = getLatestManualRedactionsForAnnotationIds(manualRedactions, annotationIds);
|
||||
|
||||
if (manualRedactionWrappers.isEmpty()) {
|
||||
throw new NotFoundException(String.format("ManualRedaction with annotationIds %s could not be found.", annotationIds));
|
||||
}
|
||||
|
||||
List<String> manualRedactionEntries = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRedactionEntry)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualRedactionEntries.isEmpty()) {
|
||||
manualRedactionService.deleteAddRedaction(dossierId, fileId, manualRedactionEntries);
|
||||
manualRedactionEntries.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual add redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
|
||||
List<String> idRemovals = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof IdRemoval)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!idRemovals.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteRemoveRedaction(dossierId, fileId, idRemovals);
|
||||
idRemovals.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual remove redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
|
||||
List<String> manualForceRedactions = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualForceRedaction)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualForceRedactions.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteForceRedaction(dossierId, fileId, manualForceRedactions);
|
||||
manualForceRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual force redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
|
||||
List<String> manualImageRecategorizations = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualImageRecategorization)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualImageRecategorizations.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteImageRecategorization(dossierId, fileId, manualImageRecategorizations);
|
||||
manualImageRecategorizations.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual image recategorization was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
|
||||
List<String> manualLegalBasisChanges = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualLegalBasisChange)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualLegalBasisChanges.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteLegalBasisChange(dossierId, fileId, manualLegalBasisChanges);
|
||||
manualLegalBasisChanges.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of legal basis change was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
|
||||
List<String> manualResizeRedactions = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualResizeRedaction)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualResizeRedactions.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteResizeRedaction(dossierId, fileId, manualResizeRedactions);
|
||||
manualResizeRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual resize redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<String, ManualRedactionWrapperModel> getLatestManualRedactionsForAnnotationIds(ManualRedactions manualRedactions, Set<String> annotationIds) {
|
||||
|
||||
Map<String, ManualRedactionWrapperModel> result = new HashMap<>();
|
||||
annotationIds.forEach(annotationId -> {
|
||||
var last = getLatestManualRedactionForAnnotationId(manualRedactions, annotationId);
|
||||
if (last != null) {
|
||||
result.put(annotationId, last);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -270,6 +100,13 @@ public class ManualRedactionController implements ManualRedactionResource {
|
||||
return manualRedactionService.getManualRedactions(fileId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + READ_MANUAL_REDACTIONS + "')")
|
||||
public Comments getComments(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId) {
|
||||
|
||||
return manualRedactionService.getComments(fileId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + ADD_COMMENT + "')")
|
||||
|
||||
@ -13,13 +13,14 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.CommentResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Comments;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualAddResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddCommentRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ForceRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.LegalBasisChangeRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequestModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequestModel;
|
||||
|
||||
@ -132,4 +133,12 @@ public interface ManualRedactionResource {
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
|
||||
|
||||
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
@GetMapping(value = MANUAL_REDACTION_REST_PATH + "/comments" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Returns the comments for a specific file", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
|
||||
Comments getComments(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
|
||||
}
|
||||
|
||||
@ -9,7 +9,9 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -45,7 +47,9 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.BaseManualRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Comment;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.CommentRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Comments;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ForceRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.LegalBasisChangeRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualAddResponse;
|
||||
@ -55,6 +59,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RemoveRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
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.type.DictionaryEntryType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLog;
|
||||
@ -104,16 +109,10 @@ public class ManualRedactionService {
|
||||
|
||||
String annotationId = hashFunction.hashString(fileId + addRedactionRequest, StandardCharsets.UTF_8).toString();
|
||||
|
||||
if (addRedactionRequest.isAddToDictionary()) {
|
||||
Set<String> typeIdsOfModifiedDictionaries = manualRedactionDictionaryUpdateHandler.handleAddToDictionary(fileId, dossierId, addRedactionRequest);
|
||||
addRedactionPersistenceService.updateStatus(fileId, annotationId, addRedactionRequest.getStatus(), true, typeIdsOfModifiedDictionaries);
|
||||
} else {
|
||||
addRedactionPersistenceService.updateStatus(fileId, annotationId, addRedactionRequest.getStatus(), false, null);
|
||||
}
|
||||
|
||||
addRedactionPersistenceService.insert(fileId, annotationId, addRedactionRequest);
|
||||
manualRedactionDictionaryUpdateHandler.handleAddToDictionary(fileId, annotationId, addRedactionRequest);
|
||||
|
||||
Long commentId = addComment(fileId, annotationId, addRedactionRequest.getComment(), addRedactionRequest.getUser()).getId();
|
||||
Long commentId = addCommentAndGetId(fileId, annotationId, addRedactionRequest.getComment(), addRedactionRequest.getUser());
|
||||
|
||||
response.add(ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build());
|
||||
}
|
||||
@ -160,6 +159,15 @@ public class ManualRedactionService {
|
||||
}
|
||||
|
||||
|
||||
private Long addCommentAndGetId(String fileId, String annotationId, String comment, String user) {
|
||||
|
||||
if (comment == null) {
|
||||
return null;
|
||||
}
|
||||
return addComment(fileId, annotationId, comment, user).getId();
|
||||
}
|
||||
|
||||
|
||||
private CommentEntity addComment(String fileId, String annotationId, String comment, String user) {
|
||||
|
||||
if (comment == null) {
|
||||
@ -242,7 +250,7 @@ public class ManualRedactionService {
|
||||
log.info("add removeRedaction for file {} and annotation {}", fileId, removeRedactionRequest.getAnnotationId());
|
||||
IdRemoval idRemoval = MagicConverter.convert(removeRedactionPersistenceService.insert(fileId, removeRedactionRequest), IdRemoval.class);
|
||||
|
||||
Long commentId = addComment(fileId, removeRedactionRequest.getAnnotationId(), removeRedactionRequest.getComment(), removeRedactionRequest.getUser()).getId();
|
||||
Long commentId = addCommentAndGetId(fileId, removeRedactionRequest.getAnnotationId(), removeRedactionRequest.getComment(), removeRedactionRequest.getUser());
|
||||
boolean matchingEntryFound = false;
|
||||
if (!removeRedactionRequest.isRemoveFromDictionary() && AnnotationStatus.APPROVED.equals(removeRedactionRequest.getStatus())) {
|
||||
try {
|
||||
@ -255,7 +263,6 @@ public class ManualRedactionService {
|
||||
requiresReAnalysis = requiresReAnalysis || matchingEntryFound;
|
||||
}
|
||||
|
||||
|
||||
boolean removedFromDictionary = handleRemoveFromDictionary(getRedactionLogEntry(redactionLog, removeRedactionRequest.getAnnotationId()),
|
||||
dossier,
|
||||
fileId,
|
||||
@ -293,7 +300,7 @@ public class ManualRedactionService {
|
||||
if (!idRemoval.getStatus().equals(AnnotationStatus.APPROVED)) {
|
||||
return false;
|
||||
}
|
||||
if (idRemoval.isRemoveFromDictionary()) {
|
||||
if (!idRemoval.isRemoveFromDictionary()) {
|
||||
removeRedactionPersistenceService.updateStatus(fileId, annotationId, idRemoval.getStatus(), false, Collections.emptySet());
|
||||
return false;
|
||||
}
|
||||
@ -373,7 +380,7 @@ public class ManualRedactionService {
|
||||
for (var forceRedactionRequest : forceRedactionRequests) {
|
||||
forceRedactionPersistenceService.insert(fileId, forceRedactionRequest);
|
||||
|
||||
Long commentId = addComment(fileId, forceRedactionRequest.getAnnotationId(), forceRedactionRequest.getComment(), forceRedactionRequest.getUser()).getId();
|
||||
Long commentId = addCommentAndGetId(fileId, forceRedactionRequest.getAnnotationId(), forceRedactionRequest.getComment(), forceRedactionRequest.getUser());
|
||||
|
||||
requiresReanalysis = requiresReanalysis || forceRedactionRequest.isApproved();
|
||||
response.add(ManualAddResponse.builder().annotationId(forceRedactionRequest.getAnnotationId()).commentId(commentId).build());
|
||||
@ -398,7 +405,7 @@ public class ManualRedactionService {
|
||||
for (var legalBasisChangeRequest : legalBasisChangeRequests) {
|
||||
legalBasisChangePersistenceService.insert(fileId, legalBasisChangeRequest);
|
||||
|
||||
Long commentId = addComment(fileId, legalBasisChangeRequest.getAnnotationId(), legalBasisChangeRequest.getComment(), legalBasisChangeRequest.getUser()).getId();
|
||||
Long commentId = addCommentAndGetId(fileId, legalBasisChangeRequest.getAnnotationId(), legalBasisChangeRequest.getComment(), legalBasisChangeRequest.getUser());
|
||||
|
||||
response.add(ManualAddResponse.builder().annotationId(legalBasisChangeRequest.getAnnotationId()).commentId(commentId).build());
|
||||
}
|
||||
@ -412,19 +419,19 @@ public class ManualRedactionService {
|
||||
public List<ManualAddResponse> addRecategorization(String dossierId, String fileId, List<RecategorizationRequest> recategorizationRequests) {
|
||||
|
||||
var response = new ArrayList<ManualAddResponse>();
|
||||
var actionPerformed = false;
|
||||
var requiresReanalysis = false;
|
||||
dossierPersistenceService.getAndValidateDossier(dossierId);
|
||||
|
||||
for (var recategorizationRequest : recategorizationRequests) {
|
||||
recategorizationPersistenceService.insert(fileId, recategorizationRequest);
|
||||
|
||||
Long commentId = addComment(fileId, recategorizationRequest.getAnnotationId(), recategorizationRequest.getComment(), recategorizationRequest.getUser()).getId();
|
||||
Long commentId = addCommentAndGetId(fileId, recategorizationRequest.getAnnotationId(), recategorizationRequest.getComment(), recategorizationRequest.getUser());
|
||||
|
||||
actionPerformed = actionPerformed || recategorizationRequest.getStatus().equals(AnnotationStatus.APPROVED);
|
||||
requiresReanalysis = requiresReanalysis || recategorizationRequest.getStatus().equals(AnnotationStatus.APPROVED);
|
||||
|
||||
response.add(ManualAddResponse.builder().annotationId(recategorizationRequest.getAnnotationId()).commentId(commentId).build());
|
||||
}
|
||||
if (actionPerformed) {
|
||||
if (requiresReanalysis) {
|
||||
reprocess(dossierId, fileId);
|
||||
}
|
||||
|
||||
@ -448,17 +455,19 @@ public class ManualRedactionService {
|
||||
public void deleteAddRedaction(String dossierId, String fileId, List<String> annotationIds) {
|
||||
|
||||
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
|
||||
var changedDictionary = false;
|
||||
var requiresReanalysis = false;
|
||||
|
||||
for (String annotationId : annotationIds) {
|
||||
|
||||
ManualRedactionEntryEntity addRedaction = getAddRedaction(fileId, annotationId);
|
||||
|
||||
changedDictionary = manualRedactionDictionaryUpdateHandler.revertAddToDictionary(fileId, dossier.getId(), addRedaction) || changedDictionary;
|
||||
boolean dictionaryChanged = manualRedactionDictionaryUpdateHandler.revertAddToDictionary(fileId, dossier.getId(), addRedaction);
|
||||
requiresReanalysis = requiresReanalysis || dictionaryChanged;
|
||||
addRedactionPersistenceService.updateStatus(fileId, annotationId, AnnotationStatus.APPROVED, false, null);
|
||||
addRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
||||
}
|
||||
|
||||
if (changedDictionary) {
|
||||
if (requiresReanalysis) {
|
||||
reprocess(dossierId, fileId);
|
||||
}
|
||||
|
||||
@ -471,7 +480,7 @@ public class ManualRedactionService {
|
||||
|
||||
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
|
||||
var requiresReanalysis = false;
|
||||
RedactionLog redactionLog = redactionLogService.getRedactionLog(dossierId, fileId, true, true);
|
||||
RedactionLog redactionLog = redactionLogService.getRedactionLog(dossierId, fileId);
|
||||
|
||||
for (String annotationId : annotationIds) {
|
||||
|
||||
@ -522,38 +531,48 @@ public class ManualRedactionService {
|
||||
|
||||
|
||||
@Transactional
|
||||
public void deleteImageRecategorization(String dossierId, String fileId, List<String> annotationIds) {
|
||||
public void deleteRecategorization(String dossierId, String fileId, List<String> annotationIds) {
|
||||
|
||||
var actionPerformed = false;
|
||||
var requiresReanalysis = false;
|
||||
for (var annotationId : annotationIds) {
|
||||
var imageRecategorization = getImageRecategorization(fileId, annotationId);
|
||||
var imageRecategorization = getRecategorization(fileId, annotationId);
|
||||
|
||||
recategorizationPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
||||
|
||||
actionPerformed = actionPerformed || !AnnotationStatus.REQUESTED.equals(imageRecategorization.getStatus());
|
||||
requiresReanalysis = requiresReanalysis || !AnnotationStatus.REQUESTED.equals(imageRecategorization.getStatus());
|
||||
}
|
||||
|
||||
if (actionPerformed) {
|
||||
if (requiresReanalysis) {
|
||||
reprocess(dossierId, fileId);
|
||||
}
|
||||
analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
private ManualImageRecategorizationEntity getImageRecategorization(String fileId, String annotationId) {
|
||||
private ManualImageRecategorizationEntity getRecategorization(String fileId, String annotationId) {
|
||||
|
||||
return recategorizationPersistenceService.findRecategorization(fileId, annotationId);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void deleteComment(String fileId, List<Long> commentIds) {
|
||||
public void deleteComment(String dossierId, String fileId, List<Long> commentIds) {
|
||||
|
||||
for (var commentId : commentIds) {
|
||||
commentPersistenceService.softDelete(commentId, OffsetDateTime.now());
|
||||
}
|
||||
// update indicator
|
||||
fileStatusPersistenceService.updateHasComments(fileId, commentPersistenceService.fileHasComments(fileId));
|
||||
// if file is currently not analyzing, we can quickly change the redaction log, else we must wait for the analysis to finish.
|
||||
if (!fileStatusService.getStatus(fileId).getProcessingStatus().equals(ProcessingStatus.PROCESSED)) {
|
||||
reprocess(dossierId, fileId);
|
||||
return;
|
||||
}
|
||||
fileStatusService.setStatusProcessing(fileId);
|
||||
RedactionLog redactionLog = redactionLogService.getRedactionLog(dossierId, fileId);
|
||||
redactionLog.getRedactionLogEntry().forEach(entry -> entry.getComments().removeIf(comment -> commentIds.contains(comment.getId())));
|
||||
fileManagementStorageService.storeRedactionLog(dossierId, fileId, redactionLog);
|
||||
fileStatusService.setStatusProcessed(fileId);
|
||||
}
|
||||
|
||||
|
||||
@ -573,14 +592,14 @@ public class ManualRedactionService {
|
||||
|
||||
List<ManualAddResponse> response = new ArrayList<>();
|
||||
|
||||
RedactionLog redactionLog = redactionLogService.getRedactionLog(dossierId, fileId, true, true);
|
||||
RedactionLog redactionLog = redactionLogService.getRedactionLog(dossierId, fileId);
|
||||
|
||||
for (ResizeRedactionRequest resizeRedactionRequest : resizeRedactionRequests) {
|
||||
|
||||
var resizeRedaction = resizeRedactionPersistenceService.insert(fileId, resizeRedactionRequest);
|
||||
|
||||
if (resizeRedactionRequest.getComment() != null) {
|
||||
Long commentId = addComment(fileId, resizeRedactionRequest.getAnnotationId(), resizeRedactionRequest.getComment(), resizeRedactionRequest.getUser()).getId();
|
||||
Long commentId = addCommentAndGetId(fileId, resizeRedactionRequest.getAnnotationId(), resizeRedactionRequest.getComment(), resizeRedactionRequest.getUser());
|
||||
response.add(ManualAddResponse.builder().annotationId(resizeRedactionRequest.getAnnotationId()).commentId(commentId).build());
|
||||
}
|
||||
|
||||
@ -675,7 +694,7 @@ public class ManualRedactionService {
|
||||
|
||||
|
||||
@Transactional
|
||||
public void updateProcessedDate(String fileId, ManualRedactions manualRedactions) {
|
||||
public void updateProcessedDate(ManualRedactions manualRedactions) {
|
||||
|
||||
if (manualRedactions != null) {
|
||||
|
||||
@ -717,4 +736,13 @@ public class ManualRedactionService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Comments getComments(String fileId) {
|
||||
|
||||
return new Comments(commentPersistenceService.findCommentsByFileID(fileId, false)
|
||||
.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, entry -> MagicConverter.convert(entry.getValue(), Comment.class))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,247 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.manualredactions;
|
||||
|
||||
import static com.iqser.red.service.persistence.service.v1.api.external.resource.ManualRedactionResource.ANNOTATION_ID;
|
||||
import static com.iqser.red.service.persistence.service.v1.api.external.resource.ManualRedactionResource.DOSSIER_ID;
|
||||
import static com.iqser.red.service.persistence.service.v1.api.external.resource.ManualRedactionResource.FILE_ID;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualImageRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ManualRedactionWrapperModel;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ManualRedactionUndoService {
|
||||
|
||||
private final ManualRedactionService manualRedactionService;
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
private final FileStatusService fileStatusService;
|
||||
|
||||
|
||||
public void undo(String dossierId, String fileId, Set<String> annotationIds) {
|
||||
|
||||
// undo the latest manual redaction for each annotationId
|
||||
ManualRedactions manualRedactions = manualRedactionService.getManualRedactions(fileId);
|
||||
|
||||
Map<String, ManualRedactionWrapperModel> manualRedactionWrappers = getLatestManualRedactionsForAnnotationIds(manualRedactions, annotationIds);
|
||||
|
||||
if (manualRedactionWrappers.isEmpty()) {
|
||||
throw new NotFoundException(String.format("ManualRedaction with annotationIds %s could not be found.", annotationIds));
|
||||
}
|
||||
|
||||
undoManualRedactionEntries(dossierId, fileId, manualRedactionWrappers);
|
||||
undoIdRemovals(dossierId, fileId, manualRedactionWrappers);
|
||||
undoForceRedactions(dossierId, fileId, manualRedactionWrappers);
|
||||
undoRecategorization(dossierId, fileId, manualRedactionWrappers);
|
||||
undoLegalBasisChange(dossierId, fileId, manualRedactionWrappers);
|
||||
undoResize(dossierId, fileId, manualRedactionWrappers);
|
||||
reprocess(dossierId, fileId);
|
||||
}
|
||||
|
||||
private void reprocess(String dossierId, String fileId) {
|
||||
|
||||
fileStatusService.setStatusReprocessForManual(dossierId, fileId, true);
|
||||
}
|
||||
|
||||
|
||||
private void undoResize(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
||||
|
||||
List<String> manualResizeRedactions = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualResizeRedaction)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualResizeRedactions.isEmpty()) {
|
||||
manualRedactionService.deleteResizeRedaction(dossierId, fileId, manualResizeRedactions);
|
||||
manualResizeRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual resize redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void undoLegalBasisChange(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
||||
|
||||
List<String> manualLegalBasisChanges = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualLegalBasisChange)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualLegalBasisChanges.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteLegalBasisChange(dossierId, fileId, manualLegalBasisChanges);
|
||||
manualLegalBasisChanges.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of legal basis change was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void undoRecategorization(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
||||
|
||||
List<String> manualImageRecategorizations = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualImageRecategorization)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualImageRecategorizations.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteRecategorization(dossierId, fileId, manualImageRecategorizations);
|
||||
manualImageRecategorizations.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual image recategorization was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void undoForceRedactions(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
||||
|
||||
List<String> manualForceRedactions = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualForceRedaction)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualForceRedactions.isEmpty()) {
|
||||
|
||||
manualRedactionService.deleteForceRedaction(dossierId, fileId, manualForceRedactions);
|
||||
manualForceRedactions.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual force redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void undoIdRemovals(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
||||
|
||||
List<String> idRemovals = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof IdRemoval)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!idRemovals.isEmpty()) {
|
||||
manualRedactionService.deleteRemoveRedaction(dossierId, fileId, idRemovals);
|
||||
idRemovals.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual remove redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void undoManualRedactionEntries(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
||||
|
||||
List<String> manualRedactionEntries = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRedactionEntry)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualRedactionEntries.isEmpty()) {
|
||||
manualRedactionService.deleteAddRedaction(dossierId, fileId, manualRedactionEntries);
|
||||
manualRedactionEntries.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(fileId)
|
||||
.category(AuditCategory.DOCUMENT.name())
|
||||
.message("Undo of manual add redaction was done.")
|
||||
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<String, ManualRedactionWrapperModel> getLatestManualRedactionsForAnnotationIds(ManualRedactions manualRedactions, Set<String> annotationIds) {
|
||||
|
||||
Map<String, ManualRedactionWrapperModel> result = new HashMap<>();
|
||||
annotationIds.forEach(annotationId -> {
|
||||
var last = getLatestManualRedactionForAnnotationId(manualRedactions, annotationId);
|
||||
if (last != null) {
|
||||
result.put(annotationId, last);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private ManualRedactionWrapperModel getLatestManualRedactionForAnnotationId(ManualRedactions manualRedactions, String annotationId) {
|
||||
|
||||
final List<ManualRedactionWrapperModel> manualRedactionWrappers = new ArrayList<>();
|
||||
|
||||
manualRedactions.getEntriesToAdd()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getImageRecategorization()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getIdsToRemove()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getForceRedactions()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getLegalBasisChanges()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getResizeRedactions()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
var sortedManualRedactionWrappers = manualRedactionWrappers.stream()
|
||||
.sorted(Comparator.comparing(ManualRedactionWrapperModel::getDate, Comparator.nullsLast(Comparator.reverseOrder())))
|
||||
.toList();
|
||||
|
||||
return sortedManualRedactionWrappers.isEmpty() ? null : sortedManualRedactionWrappers.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.iqser.red.service.persistence.service.v1.api.shared.model.annotations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Comments {
|
||||
|
||||
Map<String, List<Comment>> comments;
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user