From 30cdd3d6cd4feecaa0414719dd6fbb9aa8864aea Mon Sep 17 00:00:00 2001 From: Philipp Schramm Date: Thu, 10 Feb 2022 20:00:20 +0100 Subject: [PATCH] RED-3210 Approve all manual redactions if one is approved with the same value --- .../AddRedactionPersistenceService.java | 48 ++++-- .../repository/ManualRedactionRepository.java | 36 ++-- .../AnalysisFlagsCalculationService.java | 59 +++---- .../service/ManualRedactionService.java | 162 ++++++++++++------ 4 files changed, 201 insertions(+), 104 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/AddRedactionPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/AddRedactionPersistenceService.java index 454bf3cff..cb811a000 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/AddRedactionPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/AddRedactionPersistenceService.java @@ -1,5 +1,17 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations; +import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.transaction.Transactional; + +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity; @@ -8,27 +20,18 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist import com.iqser.red.service.persistence.service.v1.api.model.annotations.AddRedactionRequest; import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus; import com.iqser.red.service.persistence.service.v1.api.model.annotations.Rectangle; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.BeanUtils; -import org.springframework.stereotype.Service; -import javax.transaction.Transactional; -import java.time.OffsetDateTime; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class AddRedactionPersistenceService { - private final ManualRedactionRepository manualRedactionRepository; - public ManualRedactionEntryEntity insert(String fileId, String annotationId, AddRedactionRequest addRedactionRequest) { + public ManualRedactionEntryEntity insert(String fileId, String annotationId, + AddRedactionRequest addRedactionRequest) { ManualRedactionEntryEntity manualRedactionEntry = new ManualRedactionEntryEntity(); manualRedactionEntry.setId(new AnnotationEntityId(annotationId, fileId)); @@ -41,7 +44,6 @@ public class AddRedactionPersistenceService { manualRedactionEntry.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)); } - return manualRedactionRepository.save(manualRedactionEntry); } @@ -49,9 +51,11 @@ public class AddRedactionPersistenceService { @Transactional public void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter) { + manualRedactionRepository.updateSurroundingText(id, textBefore, textAfter); } + private List convert(List positions) { List rectangleEntities = new ArrayList<>(); @@ -67,8 +71,7 @@ public class AddRedactionPersistenceService { public ManualRedactionEntryEntity findAddRedaction(String fileId, String annotationId) { return manualRedactionRepository.findAddRedaction(new AnnotationEntityId(annotationId, fileId)) - .orElseThrow(() -> - new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); + .orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId)); } @@ -81,17 +84,21 @@ public class AddRedactionPersistenceService { @Transactional public void hardDelete(String fileId, String annotationId) { + manualRedactionRepository.deleteById(new AnnotationEntityId(annotationId, fileId)); } @Transactional public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) { + manualRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), softDeleteTime); } + @Transactional public void undelete(String fileId, String annotationId) { + manualRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), null); } @@ -102,10 +109,19 @@ public class AddRedactionPersistenceService { manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus); } + @Transactional - public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary, boolean isAddOrRemoveFromDossierDictionary) { + public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, + boolean isAddOrRemoveFromDictionary, boolean isAddOrRemoveFromDossierDictionary) { manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus, isAddOrRemoveFromDictionary, isAddOrRemoveFromDossierDictionary); } + + @Transactional + public void approveStatusForRequestedRedactionsWithSameValue(Set fileIds, String value) { + + manualRedactionRepository.updateStatus(fileIds, value, AnnotationStatus.REQUESTED, AnnotationStatus.APPROVED); + } + } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java index 10c793f59..3c896e280 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/ManualRedactionRepository.java @@ -1,41 +1,55 @@ package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository; -import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; -import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; -import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; - import java.time.OffsetDateTime; import java.util.List; import java.util.Optional; +import java.util.Set; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus; public interface ManualRedactionRepository extends JpaRepository { List findByIdFileId(String fileId); + @Modifying @Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeleteTime where m.id = :id") void updateSoftDelete(AnnotationEntityId id, OffsetDateTime softDeleteTime); + @Modifying @Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus where m.id = :id") void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus); + @Modifying - @Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus," + - " m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id") - void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary, - boolean isAddOrRemoveFromDossierDictionary); + @Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus, m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id") + void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary, + boolean isAddOrRemoveFromDossierDictionary); + @Query("select m from ManualRedactionEntryEntity m where m.id = :id and m.softDeletedTime is null") Optional findAddRedaction(AnnotationEntityId id); + @Query("select m from ManualRedactionEntryEntity m where m.id.fileId = :fileId and (:includeDeletions = true or m.softDeletedTime is null)") List findByFileIdIncludeDeletions(String fileId, boolean includeDeletions); + @Modifying @Query("update ManualRedactionEntryEntity m set m.textBefore = :textBefore, m.textAfter = :textAfter where m.id = :id") void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter); + + + @Modifying + @Query("update ManualRedactionEntryEntity m set m.status = :newStatus where m.id.fileId in :fileIds and m.value = :filterValue and m.addToDictionary = true and m.status = :filterStatus ") + void updateStatus(Set fileIds, String filterValue, AnnotationStatus filterStatus, + AnnotationStatus newStatus); + } diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/AnalysisFlagsCalculationService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/AnalysisFlagsCalculationService.java index 2fd5c478e..8bf2cfb8b 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/AnalysisFlagsCalculationService.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/AnalysisFlagsCalculationService.java @@ -1,21 +1,22 @@ package com.iqser.red.service.peristence.v1.server.service; +import java.time.OffsetDateTime; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ViewedPageEntity; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService; import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus; +import com.iqser.red.service.redaction.v1.model.ChangeType; import com.iqser.red.service.redaction.v1.model.RedactionLogEntry; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; - -import java.time.OffsetDateTime; -import java.util.Map; -import java.util.stream.Collectors; - @Slf4j @Service @@ -26,6 +27,7 @@ public class AnalysisFlagsCalculationService { private final RedactionLogService redactionLogService; private final ViewedPagesPersistenceService viewedPagesPersistenceService; + @Async public void calculateFlags(String dossierId, String fileId) { @@ -36,7 +38,8 @@ public class AnalysisFlagsCalculationService { var viewedPagesForCurrentAssignee = viewedPagesPersistenceService.findViewedPages(fileId, file.getAssignee()); - Map viewedPages = viewedPagesForCurrentAssignee.stream().collect(Collectors.toMap(ViewedPageEntity::getPage, ViewedPageEntity::getViewedTime)); + Map viewedPages = viewedPagesForCurrentAssignee.stream() + .collect(Collectors.toMap(ViewedPageEntity::getPage, ViewedPageEntity::getViewedTime)); boolean hasRedactions = false; boolean hasHints = false; @@ -54,6 +57,14 @@ public class AnalysisFlagsCalculationService { String type = getType(entry.getType()); + var lastChange = entry.getChanges().isEmpty() ? null : entry.getChanges() + .get(entry.getChanges().size() - 1); + + if (lastChange != null && (lastModification == null || lastChange.getDateTime() + .isAfter(lastModification))) { + lastModification = lastChange.getDateTime(); + } + if (!hasRedactions && entry.isRedacted()) { hasRedactions = true; } @@ -66,7 +77,9 @@ public class AnalysisFlagsCalculationService { hasImages = true; } - if (!hasSuggestions && entry.getManualChanges().stream().anyMatch(e -> e.getAnnotationStatus() == AnnotationStatus.REQUESTED)) { + if (!hasSuggestions && lastChange != null && lastChange.getType() != ChangeType.REMOVED && entry.getManualChanges() + .stream() + .anyMatch(e -> e.getAnnotationStatus() == AnnotationStatus.REQUESTED)) { hasSuggestions = true; } @@ -74,13 +87,9 @@ public class AnalysisFlagsCalculationService { hasComments = true; } - var lastChange = entry.getChanges().isEmpty() ? null : entry.getChanges().get(entry.getChanges().size() - 1); - - if(lastChange != null && (lastModification == null || lastChange.getDateTime().isAfter(lastModification))){ - lastModification = lastChange.getDateTime(); - } - - var viewedPage = entry.getPositions().isEmpty() ? null : viewedPages.get(entry.getPositions().get(0).getPage()); + var viewedPage = entry.getPositions().isEmpty() ? null : viewedPages.get(entry.getPositions() + .get(0) + .getPage()); if (file.getWorkflowStatus() != WorkflowStatus.APPROVED && lastChange != null && lastChange.getDateTime() != null && viewedPage != null && viewedPage.isBefore(lastChange.getDateTime())) { hasUpdates = true; @@ -88,37 +97,29 @@ public class AnalysisFlagsCalculationService { } - log.info("Flag Calculations for file: {} took: {}ms", fileId, System.currentTimeMillis() - startTime); - if (file.isHasRedactions() == hasRedactions && - file.isHasHints() == hasHints && - file.isHasImages() == hasImages && - file.isHasSuggestions() == hasSuggestions && - file.isHasAnnotationComments() == hasComments && - file.isHasUpdates() == hasUpdates) { + if (file.isHasRedactions() == hasRedactions && file.isHasHints() == hasHints && file.isHasImages() == hasImages && file.isHasSuggestions() == hasSuggestions && file.isHasAnnotationComments() == hasComments && file.isHasUpdates() == hasUpdates) { log.info("Nothing Changed for file: {}", fileId); } else { fileStatusPersistenceService.updateFlags(fileId, hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates); } OffsetDateTime lastManualRedactionTime = file.getLastManualRedaction(); - if(lastModification == null || lastManualRedactionTime != null && lastManualRedactionTime.isAfter(lastModification)){ + if (lastModification == null || lastManualRedactionTime != null && lastManualRedactionTime.isAfter(lastModification)) { lastModification = lastManualRedactionTime; } - if(lastModification != null && (file.getAnnotationModificationDate() == null || file.getAnnotationModificationDate().isBefore(lastModification))) { + if (lastModification != null && (file.getAnnotationModificationDate() == null || file.getAnnotationModificationDate() + .isBefore(lastModification))) { fileStatusPersistenceService.setLastAnnotationModificationDateForFile(fileId, lastModification); } } - private String getType(String typeId) { + return typeId.split(":")[0]; } - - - } diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/ManualRedactionService.java b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/ManualRedactionService.java index 5bf096e01..c9149111a 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/ManualRedactionService.java +++ b/persistence-service-v1/persistence-service-server-v1/src/main/java/com/iqser/red/service/peristence/v1/server/service/ManualRedactionService.java @@ -1,5 +1,22 @@ package com.iqser.red.service.peristence.v1.server.service; +import static com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter.convert; +import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId; + +import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; + +import javax.transaction.Transactional; + +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.hash.HashFunction; @@ -8,15 +25,38 @@ import com.iqser.red.service.peristence.v1.server.configuration.MessagingConfigu import com.iqser.red.service.peristence.v1.server.controller.DictionaryController; import com.iqser.red.service.peristence.v1.server.utils.ManualRedactionMapper; import com.iqser.red.service.peristence.v1.server.utils.ManualResizeRedactionMapper; -import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.*; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.CommentEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualForceRedactionEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualImageRecategorizationEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualLegalBasisChangeEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; +import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity; import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity; import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException; import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException; import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService; import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileStatusPersistenceService; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.*; -import com.iqser.red.service.persistence.service.v1.api.model.annotations.*; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.CommentPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ForceRedactionPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ImageRecategorizationPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.LegalBasisChangePersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.RemoveRedactionPersistenceService; +import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ResizeRedactionPersistenceService; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.AddRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.CommentRequest; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.ForceRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.ImageRecategorizationRequest; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.LegalBasisChangeRequest; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualAddResponse; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualRedactions; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.RemoveRedactionRequest; +import com.iqser.red.service.persistence.service.v1.api.model.annotations.ResizeRedactionRequest; import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualRedactionEntry; import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualResizeRedaction; import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.ProcessingStatus; @@ -24,22 +64,10 @@ import com.iqser.red.service.redaction.v1.model.AnalyzeRequest; import com.iqser.red.service.redaction.v1.model.MessageType; import com.iqser.red.service.redaction.v1.model.RedactionLog; import com.iqser.red.service.redaction.v1.model.RedactionLogEntry; + import feign.FeignException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.amqp.rabbit.core.RabbitTemplate; -import org.springframework.stereotype.Service; - -import javax.transaction.Transactional; -import java.nio.charset.StandardCharsets; -import java.time.OffsetDateTime; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import static com.iqser.red.service.persistence.management.v1.processor.utils.MagicConverter.convert; -import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId; @Slf4j @Service @@ -47,6 +75,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ty public class ManualRedactionService { private final DossierPersistenceService dossierPersistenceService; + private final DossierTemplatePersistenceService dossierTemplatePersistenceService; private final AddRedactionPersistenceService addRedactionPersistenceService; private final RemoveRedactionPersistenceService removeRedactionPersistenceService; private final ForceRedactionPersistenceService forceRedactionPersistenceService; @@ -114,6 +143,7 @@ public class ManualRedactionService { return ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build(); } + public ManualAddResponse addRemoveRedaction(String dossierId, String fileId, RemoveRedactionRequest removeRedactionRequest) { @@ -275,6 +305,7 @@ public class ManualRedactionService { .build(); } + public CommentEntity addComment(String fileId, String annotationId, CommentRequest commentRequest) { var createdComment = addComment(fileId, annotationId, commentRequest.getText(), commentRequest.getUser()); @@ -466,6 +497,8 @@ public class ManualRedactionService { if (annotationStatus == AnnotationStatus.APPROVED) { removeFromDictionary(buildTypeId(redactionLogEntry, dossier), redactionLogEntry.getValue(), dossierId, fileId); + approveStatusForRedactionsWithSameValue(dossier, false, true, redactionLogEntry.getValue()); + } else if (annotationStatus == AnnotationStatus.DECLINED) { // if it was previously approved, revert the delete @@ -530,33 +563,6 @@ public class ManualRedactionService { } - @SuppressWarnings("PMD") - public void updateAddRedactionStatus(String dossierId, String fileId, String annotationId, - AnnotationStatus annotationStatus) { - - dossierPersistenceService.getAndValidateDossier(dossierId); - - ManualRedactionEntryEntity manualRedactionEntry = addRedactionPersistenceService.findAddRedaction(fileId, annotationId); - if (manualRedactionEntry.isAddToDictionary() || manualRedactionEntry.isAddToDossierDictionary()) { - if (annotationStatus == AnnotationStatus.APPROVED) { - addToDictionary(manualRedactionEntry.getTypeId(), manualRedactionEntry.getValue(), dossierId, fileId); - } else if (annotationStatus == AnnotationStatus.DECLINED) { - // if it was previously approved, revert the add - if (manualRedactionEntry.getStatus() == AnnotationStatus.APPROVED) { - removeFromDictionary(manualRedactionEntry.getTypeId(), manualRedactionEntry.getValue(), dossierId, fileId); - } - } - } - - addRedactionPersistenceService.updateStatus(fileId, annotationId, annotationStatus); - - boolean hasSuggestions = calculateHasSuggestions(fileId); - fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); - - analysisFlagsCalculationService.calculateFlags(dossierId, fileId); - } - - public void updateResizeRedactionStatus(String dossierId, String fileId, String annotationId, AnnotationStatus annotationStatus) { @@ -574,12 +580,33 @@ public class ManualRedactionService { } - @Transactional - public void updateSurroundingText(String fileId, ManualRedactions manualRedactions) { + @SuppressWarnings("PMD") + public void updateAddRedactionStatus(String dossierId, String fileId, String annotationId, + AnnotationStatus annotationStatus) { - // These are marked as processed once surrounding text is computed ( TBD if this is correct ? ) - manualRedactions.getEntriesToAdd().forEach(e -> addRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter())); - manualRedactions.getResizeRedactions().forEach(e -> resizeRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter())); + var dossier = dossierPersistenceService.getAndValidateDossier(dossierId); + + ManualRedactionEntryEntity manualRedactionEntry = addRedactionPersistenceService.findAddRedaction(fileId, annotationId); + if (manualRedactionEntry.isAddToDictionary() || manualRedactionEntry.isAddToDossierDictionary()) { + if (annotationStatus == AnnotationStatus.APPROVED) { + addToDictionary(manualRedactionEntry.getTypeId(), manualRedactionEntry.getValue(), dossierId, fileId); + + approveStatusForRedactionsWithSameValue(dossier, manualRedactionEntry.isAddToDictionary(), manualRedactionEntry.isAddToDossierDictionary(), manualRedactionEntry.getValue()); + + } else if (annotationStatus == AnnotationStatus.DECLINED) { + // if it was previously approved, revert the add + if (manualRedactionEntry.getStatus() == AnnotationStatus.APPROVED) { + removeFromDictionary(manualRedactionEntry.getTypeId(), manualRedactionEntry.getValue(), dossierId, fileId); + } + } + } + + addRedactionPersistenceService.updateStatus(fileId, annotationId, annotationStatus); + + boolean hasSuggestions = calculateHasSuggestions(fileId); + fileStatusPersistenceService.setUpdateLastManualRedactionAndHasSuggestions(fileId, OffsetDateTime.now(), hasSuggestions); + + analysisFlagsCalculationService.calculateFlags(dossierId, fileId); } @@ -594,7 +621,19 @@ public class ManualRedactionService { } + @Transactional + public void updateSurroundingText(String fileId, ManualRedactions manualRedactions) { + + // These are marked as processed once surrounding text is computed ( TBD if this is correct ? ) + manualRedactions.getEntriesToAdd() + .forEach(e -> addRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter())); + manualRedactions.getResizeRedactions() + .forEach(e -> resizeRedactionPersistenceService.updateSurroundingText(new AnnotationEntityId(e.getAnnotationId(), fileId), e.getTextBefore(), e.getTextAfter())); + } + + private void reprocess(String dossierId, String fileId) { + fileStatusService.setStatusReprocess(dossierId, fileId, 2); } @@ -608,6 +647,7 @@ public class ManualRedactionService { } } + private void handleAddToDictionary(String fileId, String annotationId, String typeId, String value, AnnotationStatus status, boolean addToDictionary, boolean addToDossierDictionary, boolean revert, String dossierId) { @@ -760,4 +800,30 @@ public class ManualRedactionService { } + + private void approveStatusForRedactionsWithSameValue(DossierEntity dossier, boolean addToDictionary, + boolean addToDossierDictionary, String value) { + + List dossiers = new ArrayList<>(); + if (addToDictionary) { + dossiers = dossierTemplatePersistenceService.getDossierTemplate(dossier.getDossierTemplateId()) + .getDossiers(); + + } + if (addToDossierDictionary) { + dossiers.add(dossier); + } + + Set fileIds = new HashSet<>(); + for (DossierEntity d : dossiers) { + var files = fileStatusService.getDossierStatus(d.getId()); + files.forEach(f -> fileIds.add(f.getId())); + } + + if (!fileIds.isEmpty()) { + log.debug("Approve status for requested redactions with same value '{}' for files {}", value, fileIds); + addRedactionPersistenceService.approveStatusForRequestedRedactionsWithSameValue(fileIds, value); + } + } + }