Pull request #227: RED-3210 Approve all manual redactions if one is approved with the same value within the same file
Merge in RED/persistence-service from bugfix/RED-3210 to master * commit '30cdd3d6cd4feecaa0414719dd6fbb9aa8864aea': RED-3210 Approve all manual redactions if one is approved with the same value
This commit is contained in:
commit
9e763f194d
@ -1,5 +1,17 @@
|
|||||||
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations;
|
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.AnnotationEntityId;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
|
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
|
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.AddRedactionRequest;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
|
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 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 lombok.RequiredArgsConstructor;
|
||||||
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;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AddRedactionPersistenceService {
|
public class AddRedactionPersistenceService {
|
||||||
|
|
||||||
|
|
||||||
private final ManualRedactionRepository manualRedactionRepository;
|
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();
|
ManualRedactionEntryEntity manualRedactionEntry = new ManualRedactionEntryEntity();
|
||||||
manualRedactionEntry.setId(new AnnotationEntityId(annotationId, fileId));
|
manualRedactionEntry.setId(new AnnotationEntityId(annotationId, fileId));
|
||||||
@ -41,7 +44,6 @@ public class AddRedactionPersistenceService {
|
|||||||
manualRedactionEntry.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
manualRedactionEntry.setProcessedDate(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return manualRedactionRepository.save(manualRedactionEntry);
|
return manualRedactionRepository.save(manualRedactionEntry);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -49,9 +51,11 @@ public class AddRedactionPersistenceService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter) {
|
public void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter) {
|
||||||
|
|
||||||
manualRedactionRepository.updateSurroundingText(id, textBefore, textAfter);
|
manualRedactionRepository.updateSurroundingText(id, textBefore, textAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<RectangleEntity> convert(List<Rectangle> positions) {
|
private List<RectangleEntity> convert(List<Rectangle> positions) {
|
||||||
|
|
||||||
List<RectangleEntity> rectangleEntities = new ArrayList<>();
|
List<RectangleEntity> rectangleEntities = new ArrayList<>();
|
||||||
@ -67,8 +71,7 @@ public class AddRedactionPersistenceService {
|
|||||||
public ManualRedactionEntryEntity findAddRedaction(String fileId, String annotationId) {
|
public ManualRedactionEntryEntity findAddRedaction(String fileId, String annotationId) {
|
||||||
|
|
||||||
return manualRedactionRepository.findAddRedaction(new AnnotationEntityId(annotationId, fileId))
|
return manualRedactionRepository.findAddRedaction(new AnnotationEntityId(annotationId, fileId))
|
||||||
.orElseThrow(() ->
|
.orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));
|
||||||
new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -81,17 +84,21 @@ public class AddRedactionPersistenceService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void hardDelete(String fileId, String annotationId) {
|
public void hardDelete(String fileId, String annotationId) {
|
||||||
|
|
||||||
manualRedactionRepository.deleteById(new AnnotationEntityId(annotationId, fileId));
|
manualRedactionRepository.deleteById(new AnnotationEntityId(annotationId, fileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) {
|
public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) {
|
||||||
|
|
||||||
manualRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), softDeleteTime);
|
manualRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), softDeleteTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void undelete(String fileId, String annotationId) {
|
public void undelete(String fileId, String annotationId) {
|
||||||
|
|
||||||
manualRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), null);
|
manualRedactionRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +109,19 @@ public class AddRedactionPersistenceService {
|
|||||||
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
|
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@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);
|
manualRedactionRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus, isAddOrRemoveFromDictionary, isAddOrRemoveFromDossierDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void approveStatusForRequestedRedactionsWithSameValue(Set<String> fileIds, String value) {
|
||||||
|
|
||||||
|
manualRedactionRepository.updateStatus(fileIds, value, AnnotationStatus.REQUESTED, AnnotationStatus.APPROVED);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,55 @@
|
|||||||
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository;
|
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.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
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<ManualRedactionEntryEntity, AnnotationEntityId> {
|
public interface ManualRedactionRepository extends JpaRepository<ManualRedactionEntryEntity, AnnotationEntityId> {
|
||||||
|
|
||||||
List<ManualRedactionEntryEntity> findByIdFileId(String fileId);
|
List<ManualRedactionEntryEntity> findByIdFileId(String fileId);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeleteTime where m.id = :id")
|
@Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeleteTime where m.id = :id")
|
||||||
void updateSoftDelete(AnnotationEntityId id, OffsetDateTime softDeleteTime);
|
void updateSoftDelete(AnnotationEntityId id, OffsetDateTime softDeleteTime);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus where m.id = :id")
|
@Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus where m.id = :id")
|
||||||
void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus);
|
void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus," +
|
@Query("update ManualRedactionEntryEntity m set m.status = :annotationStatus, m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id")
|
||||||
" m.addToDictionary = :isAddOrRemoveFromDictionary, m.addToDossierDictionary = :isAddOrRemoveFromDossierDictionary where m.id = :id")
|
|
||||||
void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary,
|
void updateStatus(AnnotationEntityId id, AnnotationStatus annotationStatus, boolean isAddOrRemoveFromDictionary,
|
||||||
boolean isAddOrRemoveFromDossierDictionary);
|
boolean isAddOrRemoveFromDossierDictionary);
|
||||||
|
|
||||||
|
|
||||||
@Query("select m from ManualRedactionEntryEntity m where m.id = :id and m.softDeletedTime is null")
|
@Query("select m from ManualRedactionEntryEntity m where m.id = :id and m.softDeletedTime is null")
|
||||||
Optional<ManualRedactionEntryEntity> findAddRedaction(AnnotationEntityId id);
|
Optional<ManualRedactionEntryEntity> findAddRedaction(AnnotationEntityId id);
|
||||||
|
|
||||||
|
|
||||||
@Query("select m from ManualRedactionEntryEntity m where m.id.fileId = :fileId and (:includeDeletions = true or m.softDeletedTime is null)")
|
@Query("select m from ManualRedactionEntryEntity m where m.id.fileId = :fileId and (:includeDeletions = true or m.softDeletedTime is null)")
|
||||||
List<ManualRedactionEntryEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
|
List<ManualRedactionEntryEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualRedactionEntryEntity m set m.textBefore = :textBefore, m.textAfter = :textAfter where m.id = :id")
|
@Query("update ManualRedactionEntryEntity m set m.textBefore = :textBefore, m.textAfter = :textAfter where m.id = :id")
|
||||||
void updateSurroundingText(AnnotationEntityId id, String textBefore, String textAfter);
|
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<String> fileIds, String filterValue, AnnotationStatus filterStatus,
|
||||||
|
AnnotationStatus newStatus);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
package com.iqser.red.service.peristence.v1.server.service;
|
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.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.FileStatusPersistenceService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ViewedPagesPersistenceService;
|
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.annotations.AnnotationStatus;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.WorkflowStatus;
|
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 com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -26,6 +27,7 @@ public class AnalysisFlagsCalculationService {
|
|||||||
private final RedactionLogService redactionLogService;
|
private final RedactionLogService redactionLogService;
|
||||||
private final ViewedPagesPersistenceService viewedPagesPersistenceService;
|
private final ViewedPagesPersistenceService viewedPagesPersistenceService;
|
||||||
|
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
public void calculateFlags(String dossierId, String fileId) {
|
public void calculateFlags(String dossierId, String fileId) {
|
||||||
|
|
||||||
@ -36,7 +38,8 @@ public class AnalysisFlagsCalculationService {
|
|||||||
|
|
||||||
var viewedPagesForCurrentAssignee = viewedPagesPersistenceService.findViewedPages(fileId, file.getAssignee());
|
var viewedPagesForCurrentAssignee = viewedPagesPersistenceService.findViewedPages(fileId, file.getAssignee());
|
||||||
|
|
||||||
Map<Integer, OffsetDateTime> viewedPages = viewedPagesForCurrentAssignee.stream().collect(Collectors.toMap(ViewedPageEntity::getPage, ViewedPageEntity::getViewedTime));
|
Map<Integer, OffsetDateTime> viewedPages = viewedPagesForCurrentAssignee.stream()
|
||||||
|
.collect(Collectors.toMap(ViewedPageEntity::getPage, ViewedPageEntity::getViewedTime));
|
||||||
|
|
||||||
boolean hasRedactions = false;
|
boolean hasRedactions = false;
|
||||||
boolean hasHints = false;
|
boolean hasHints = false;
|
||||||
@ -54,6 +57,14 @@ public class AnalysisFlagsCalculationService {
|
|||||||
|
|
||||||
String type = getType(entry.getType());
|
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()) {
|
if (!hasRedactions && entry.isRedacted()) {
|
||||||
hasRedactions = true;
|
hasRedactions = true;
|
||||||
}
|
}
|
||||||
@ -66,7 +77,9 @@ public class AnalysisFlagsCalculationService {
|
|||||||
hasImages = true;
|
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;
|
hasSuggestions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,13 +87,9 @@ public class AnalysisFlagsCalculationService {
|
|||||||
hasComments = true;
|
hasComments = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lastChange = entry.getChanges().isEmpty() ? null : entry.getChanges().get(entry.getChanges().size() - 1);
|
var viewedPage = entry.getPositions().isEmpty() ? null : viewedPages.get(entry.getPositions()
|
||||||
|
.get(0)
|
||||||
if(lastChange != null && (lastModification == null || lastChange.getDateTime().isAfter(lastModification))){
|
.getPage());
|
||||||
lastModification = lastChange.getDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
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())) {
|
if (file.getWorkflowStatus() != WorkflowStatus.APPROVED && lastChange != null && lastChange.getDateTime() != null && viewedPage != null && viewedPage.isBefore(lastChange.getDateTime())) {
|
||||||
hasUpdates = true;
|
hasUpdates = true;
|
||||||
@ -88,15 +97,9 @@ public class AnalysisFlagsCalculationService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
log.info("Flag Calculations for file: {} took: {}ms", fileId, System.currentTimeMillis() - startTime);
|
log.info("Flag Calculations for file: {} took: {}ms", fileId, System.currentTimeMillis() - startTime);
|
||||||
|
|
||||||
if (file.isHasRedactions() == hasRedactions &&
|
if (file.isHasRedactions() == hasRedactions && file.isHasHints() == hasHints && file.isHasImages() == hasImages && file.isHasSuggestions() == hasSuggestions && file.isHasAnnotationComments() == hasComments && file.isHasUpdates() == hasUpdates) {
|
||||||
file.isHasHints() == hasHints &&
|
|
||||||
file.isHasImages() == hasImages &&
|
|
||||||
file.isHasSuggestions() == hasSuggestions &&
|
|
||||||
file.isHasAnnotationComments() == hasComments &&
|
|
||||||
file.isHasUpdates() == hasUpdates) {
|
|
||||||
log.info("Nothing Changed for file: {}", fileId);
|
log.info("Nothing Changed for file: {}", fileId);
|
||||||
} else {
|
} else {
|
||||||
fileStatusPersistenceService.updateFlags(fileId, hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates);
|
fileStatusPersistenceService.updateFlags(fileId, hasRedactions, hasHints, hasImages, hasSuggestions, hasComments, hasUpdates);
|
||||||
@ -107,18 +110,16 @@ public class AnalysisFlagsCalculationService {
|
|||||||
lastModification = lastManualRedactionTime;
|
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);
|
fileStatusPersistenceService.setLastAnnotationModificationDateForFile(fileId, lastModification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String getType(String typeId) {
|
private String getType(String typeId) {
|
||||||
|
|
||||||
return typeId.split(":")[0];
|
return typeId.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,22 @@
|
|||||||
package com.iqser.red.service.peristence.v1.server.service;
|
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.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.common.hash.HashFunction;
|
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.controller.DictionaryController;
|
||||||
import com.iqser.red.service.peristence.v1.server.utils.ManualRedactionMapper;
|
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.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.entity.dossier.DossierEntity;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
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.ConflictException;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
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.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.FileStatusPersistenceService;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.*;
|
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.annotations.*;
|
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.ManualRedactionEntry;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualResizeRedaction;
|
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;
|
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.MessageType;
|
||||||
import com.iqser.red.service.redaction.v1.model.RedactionLog;
|
import com.iqser.red.service.redaction.v1.model.RedactionLog;
|
||||||
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
||||||
|
|
||||||
import feign.FeignException;
|
import feign.FeignException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -47,6 +75,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ty
|
|||||||
public class ManualRedactionService {
|
public class ManualRedactionService {
|
||||||
|
|
||||||
private final DossierPersistenceService dossierPersistenceService;
|
private final DossierPersistenceService dossierPersistenceService;
|
||||||
|
private final DossierTemplatePersistenceService dossierTemplatePersistenceService;
|
||||||
private final AddRedactionPersistenceService addRedactionPersistenceService;
|
private final AddRedactionPersistenceService addRedactionPersistenceService;
|
||||||
private final RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
private final RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||||
private final ForceRedactionPersistenceService forceRedactionPersistenceService;
|
private final ForceRedactionPersistenceService forceRedactionPersistenceService;
|
||||||
@ -114,6 +143,7 @@ public class ManualRedactionService {
|
|||||||
return ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build();
|
return ManualAddResponse.builder().annotationId(annotationId).commentId(commentId).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ManualAddResponse addRemoveRedaction(String dossierId, String fileId,
|
public ManualAddResponse addRemoveRedaction(String dossierId, String fileId,
|
||||||
RemoveRedactionRequest removeRedactionRequest) {
|
RemoveRedactionRequest removeRedactionRequest) {
|
||||||
|
|
||||||
@ -275,6 +305,7 @@ public class ManualRedactionService {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CommentEntity addComment(String fileId, String annotationId, CommentRequest commentRequest) {
|
public CommentEntity addComment(String fileId, String annotationId, CommentRequest commentRequest) {
|
||||||
|
|
||||||
var createdComment = addComment(fileId, annotationId, commentRequest.getText(), commentRequest.getUser());
|
var createdComment = addComment(fileId, annotationId, commentRequest.getText(), commentRequest.getUser());
|
||||||
@ -466,6 +497,8 @@ public class ManualRedactionService {
|
|||||||
|
|
||||||
if (annotationStatus == AnnotationStatus.APPROVED) {
|
if (annotationStatus == AnnotationStatus.APPROVED) {
|
||||||
removeFromDictionary(buildTypeId(redactionLogEntry, dossier), redactionLogEntry.getValue(), dossierId, fileId);
|
removeFromDictionary(buildTypeId(redactionLogEntry, dossier), redactionLogEntry.getValue(), dossierId, fileId);
|
||||||
|
approveStatusForRedactionsWithSameValue(dossier, false, true, redactionLogEntry.getValue());
|
||||||
|
|
||||||
} else if (annotationStatus == AnnotationStatus.DECLINED) {
|
} else if (annotationStatus == AnnotationStatus.DECLINED) {
|
||||||
|
|
||||||
// if it was previously approved, revert the delete
|
// 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,
|
public void updateResizeRedactionStatus(String dossierId, String fileId, String annotationId,
|
||||||
AnnotationStatus annotationStatus) {
|
AnnotationStatus annotationStatus) {
|
||||||
|
|
||||||
@ -574,12 +580,33 @@ public class ManualRedactionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@SuppressWarnings("PMD")
|
||||||
public void updateSurroundingText(String fileId, ManualRedactions manualRedactions) {
|
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 ? )
|
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
|
||||||
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()));
|
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) {
|
private void reprocess(String dossierId, String fileId) {
|
||||||
|
|
||||||
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
|
fileStatusService.setStatusReprocess(dossierId, fileId, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,6 +647,7 @@ public class ManualRedactionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void handleAddToDictionary(String fileId, String annotationId, String typeId, String value,
|
private void handleAddToDictionary(String fileId, String annotationId, String typeId, String value,
|
||||||
AnnotationStatus status, boolean addToDictionary, boolean addToDossierDictionary,
|
AnnotationStatus status, boolean addToDictionary, boolean addToDossierDictionary,
|
||||||
boolean revert, String dossierId) {
|
boolean revert, String dossierId) {
|
||||||
@ -760,4 +800,30 @@ public class ManualRedactionService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void approveStatusForRedactionsWithSameValue(DossierEntity dossier, boolean addToDictionary,
|
||||||
|
boolean addToDossierDictionary, String value) {
|
||||||
|
|
||||||
|
List<DossierEntity> dossiers = new ArrayList<>();
|
||||||
|
if (addToDictionary) {
|
||||||
|
dossiers = dossierTemplatePersistenceService.getDossierTemplate(dossier.getDossierTemplateId())
|
||||||
|
.getDossiers();
|
||||||
|
|
||||||
|
}
|
||||||
|
if (addToDossierDictionary) {
|
||||||
|
dossiers.add(dossier);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user