Merge branch 'RED-9474' into 'master'
RED-9474 - Revert only local manual changes for an annotation Closes RED-9474 See merge request redactmanager/persistence-service!590
This commit is contained in:
commit
b83207f715
@ -71,12 +71,13 @@ public class ManualRedactionController implements ManualRedactionResource {
|
|||||||
public void undo(@PathVariable(DOSSIER_ID) String dossierId,
|
public void undo(@PathVariable(DOSSIER_ID) String dossierId,
|
||||||
@PathVariable(FILE_ID) String fileId,
|
@PathVariable(FILE_ID) String fileId,
|
||||||
@RequestBody Set<String> annotationIds,
|
@RequestBody Set<String> annotationIds,
|
||||||
@RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed) {
|
@RequestParam(value = "includeOnlyUnprocessed", required = false, defaultValue = FALSE) boolean includeOnlyUnprocessed,
|
||||||
|
@RequestParam(value = "includeOnlyLocal", required = false, defaultValue = FALSE) boolean includeOnlyLocal) {
|
||||||
|
|
||||||
accessControlService.checkDossierExistenceAndAccessPermissionsToDossier(dossierId);
|
accessControlService.checkDossierExistenceAndAccessPermissionsToDossier(dossierId);
|
||||||
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
|
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
|
||||||
accessControlService.verifyUserIsApprover(dossierId);
|
accessControlService.verifyUserIsApprover(dossierId);
|
||||||
manualRedactionUndoService.undo(dossierId, fileId, annotationIds, includeUnprocessed);
|
manualRedactionUndoService.undo(dossierId, fileId, annotationIds, includeOnlyUnprocessed, includeOnlyLocal);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.iqser.red.service.persistence.service.v1.api.external.resource;
|
package com.iqser.red.service.persistence.service.v1.api.external.resource;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@ -15,7 +14,6 @@ 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.CommentResponse;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationComments;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationComments;
|
||||||
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.ManualRedactionResponse;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactionResponse;
|
||||||
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.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.AddCommentRequestModel;
|
||||||
@ -57,7 +55,8 @@ public interface ManualRedactionResource {
|
|||||||
void undo(@PathVariable(DOSSIER_ID) String dossierId,
|
void undo(@PathVariable(DOSSIER_ID) String dossierId,
|
||||||
@PathVariable(FILE_ID) String fileId,
|
@PathVariable(FILE_ID) String fileId,
|
||||||
@RequestBody Set<String> annotationIds,
|
@RequestBody Set<String> annotationIds,
|
||||||
@RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed);
|
@RequestParam(value = "includeOnlyUnprocessed", required = false, defaultValue = FALSE) boolean includeOnlyUnprocessed,
|
||||||
|
@RequestParam(value = "includeOnlyLocal", required = false, defaultValue = FALSE) boolean includeOnlyLocal);
|
||||||
|
|
||||||
|
|
||||||
@ResponseStatus(value = HttpStatus.OK)
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
|
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.BaseAnnotation;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -23,6 +22,8 @@ public class ManualChangesQueryOptions {
|
|||||||
private boolean includeDeletions = false;
|
private boolean includeDeletions = false;
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Set<Class<? extends BaseAnnotation>> excludedClasses = Collections.emptySet();
|
private Set<Class<? extends BaseAnnotation>> excludedClasses = Collections.emptySet();
|
||||||
|
@Builder.Default
|
||||||
|
private List<String> annotationIds = Collections.emptyList();
|
||||||
|
|
||||||
|
|
||||||
public static ManualChangesQueryOptions allWithoutDeleted() {
|
public static ManualChangesQueryOptions allWithoutDeleted() {
|
||||||
@ -42,6 +43,11 @@ public class ManualChangesQueryOptions {
|
|||||||
return ManualChangesQueryOptions.builder().includeDeletions(false).includeDictChanges(true).includeOnlyUnprocessed(true).build();
|
return ManualChangesQueryOptions.builder().includeDeletions(false).includeDictChanges(true).includeOnlyUnprocessed(true).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ManualChangesQueryOptions unprocessedOnlyForIds(List<String> annotationIds) {
|
||||||
|
|
||||||
|
return ManualChangesQueryOptions.builder().includeDeletions(false).includeDictChanges(true).includeOnlyUnprocessed(true).annotationIds(annotationIds).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static ManualChangesQueryOptions localChangesOnly() {
|
public static ManualChangesQueryOptions localChangesOnly() {
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ public class EntityLogMongoWrapperService {
|
|||||||
List<EntityLogEntry> entityLogEntries = entityLogMongoService.findEntityLogEntriesByIds(dossierId, fileId, ids);
|
List<EntityLogEntry> entityLogEntries = entityLogMongoService.findEntityLogEntriesByIds(dossierId, fileId, ids);
|
||||||
if (includeUnprocessed) {
|
if (includeUnprocessed) {
|
||||||
DossierEntity dossier = dossierService.getDossierById(dossierId);
|
DossierEntity dossier = dossierService.getDossierById(dossierId);
|
||||||
ManualRedactions unprocessedManualRedactions = manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.unprocessedOnly(), ids);
|
ManualRedactions unprocessedManualRedactions = manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.unprocessedOnlyForIds(ids));
|
||||||
entityLogEntries = entityLogMergeService.mergeEntityLogEntries(unprocessedManualRedactions, entityLogEntries.stream().map(EntityLogEntry::getId).toList(), dossier, fileId);
|
entityLogEntries = entityLogMergeService.mergeEntityLogEntries(unprocessedManualRedactions, entityLogEntries.stream().map(EntityLogEntry::getId).toList(), dossier, fileId);
|
||||||
}
|
}
|
||||||
return entityLogEntries;
|
return entityLogEntries;
|
||||||
|
|||||||
@ -4,9 +4,7 @@ import static com.knecon.fforesight.databasetenantcommons.providers.utils.MagicC
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.springframework.dao.EmptyResultDataAccessException;
|
import org.springframework.dao.EmptyResultDataAccessException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -49,11 +47,11 @@ public class ManualRedactionProviderService {
|
|||||||
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||||
|
|
||||||
|
|
||||||
|
public void convertUnprocessedAddToDictionariesToLocalChanges(String fileId) {
|
||||||
|
|
||||||
public void convertUnprocessedAddToDictionariesToLocalChanges(String fileId){
|
|
||||||
var unprocessedManualAdds = addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.unprocessedOnly());
|
var unprocessedManualAdds = addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.unprocessedOnly());
|
||||||
for (var unprocessedManualAdd : unprocessedManualAdds){
|
for (var unprocessedManualAdd : unprocessedManualAdds) {
|
||||||
if (unprocessedManualAdd.isAddToDictionary() || unprocessedManualAdd.isAddToAllDossiers()){
|
if (unprocessedManualAdd.isAddToDictionary() || unprocessedManualAdd.isAddToAllDossiers()) {
|
||||||
unprocessedManualAdd.setAddToDictionary(false);
|
unprocessedManualAdd.setAddToDictionary(false);
|
||||||
unprocessedManualAdd.setAddToAllDossiers(false);
|
unprocessedManualAdd.setAddToAllDossiers(false);
|
||||||
unprocessedManualAdd.setLegalBasis("");
|
unprocessedManualAdd.setLegalBasis("");
|
||||||
@ -65,12 +63,6 @@ public class ManualRedactionProviderService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public ManualRedactions getManualRedactions(String fileId, ManualChangesQueryOptions options) {
|
public ManualRedactions getManualRedactions(String fileId, ManualChangesQueryOptions options) {
|
||||||
return getManualRedactions(fileId, options, Collections.emptyList());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public ManualRedactions getManualRedactions(String fileId, ManualChangesQueryOptions options, List<String> annotationIds) {
|
|
||||||
|
|
||||||
Set<ManualRedactionEntry> entriesToAdd;
|
Set<ManualRedactionEntry> entriesToAdd;
|
||||||
Set<IdRemoval> removals;
|
Set<IdRemoval> removals;
|
||||||
@ -121,15 +113,6 @@ public class ManualRedactionProviderService {
|
|||||||
legalBasisChanges = Collections.emptySet();
|
legalBasisChanges = Collections.emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!annotationIds.isEmpty()){
|
|
||||||
return new ManualRedactions(removals.stream().filter(r -> annotationIds.contains(r.getAnnotationId())).collect(Collectors.toSet()),
|
|
||||||
entriesToAdd.stream().filter(r -> annotationIds.contains(r.getAnnotationId())).collect(Collectors.toSet()),
|
|
||||||
forceRedactions.stream().filter(r -> annotationIds.contains(r.getAnnotationId())).collect(Collectors.toSet()),
|
|
||||||
recategorizations.stream().filter(r -> annotationIds.contains(r.getAnnotationId())).collect(Collectors.toSet()),
|
|
||||||
legalBasisChanges.stream().filter(r -> annotationIds.contains(r.getAnnotationId())).collect(Collectors.toSet()),
|
|
||||||
resizeRedactions.stream().filter(r -> annotationIds.contains(r.getAnnotationId())).collect(Collectors.toSet()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ManualRedactions(removals, entriesToAdd, forceRedactions, recategorizations, legalBasisChanges, resizeRedactions);
|
return new ManualRedactions(removals, entriesToAdd, forceRedactions, recategorizations, legalBasisChanges, resizeRedactions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity;
|
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
|
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
|
||||||
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.exception.BadRequestException;
|
||||||
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.model.ManualChangesQueryOptions;
|
import com.iqser.red.service.persistence.management.v1.processor.model.ManualChangesQueryOptions;
|
||||||
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService;
|
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService;
|
||||||
@ -72,31 +73,56 @@ public class ManualRedactionUndoService {
|
|||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void undo(String dossierId, String fileId, Set<String> annotationIds, boolean includeUnprocessed) {
|
public void undo(String dossierId, String fileId, Set<String> annotationIds, boolean includeOnlyUnprocessed, boolean includeOnlyLocal) {
|
||||||
|
|
||||||
// undo the latest manual redaction for each annotationId
|
// undo the manual redaction for each annotationId
|
||||||
ManualRedactions manualRedactions = getManualRedactions(fileId);
|
ManualRedactions manualRedactions = getManualRedactions(fileId, includeOnlyUnprocessed, includeOnlyLocal, new ArrayList<>(annotationIds));
|
||||||
|
|
||||||
Map<String, ManualRedactionWrapperModel> manualRedactionWrappers = getLatestManualRedactionsForAnnotationIds(manualRedactions, annotationIds);
|
Map<String, List<ManualRedactionWrapperModel>> manualRedactionWrappers = groupAndSortManualRedactionsForAnnotationIds(manualRedactions, annotationIds);
|
||||||
|
|
||||||
if (manualRedactionWrappers.isEmpty()) {
|
if (manualRedactionWrappers.isEmpty()) {
|
||||||
throw new NotFoundException(String.format("ManualRedaction with annotationIds %s could not be found.", annotationIds));
|
throw new NotFoundException(String.format("ManualRedaction with annotationIds %s could not be found.", annotationIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
undoManualRedactionEntries(dossierId, fileId, manualRedactionWrappers);
|
for (String annotationId : manualRedactionWrappers.keySet()) {
|
||||||
undoIdRemovals(dossierId, fileId, manualRedactionWrappers);
|
manualRedactionWrappers.get(annotationId)
|
||||||
undoForceRedactions(dossierId, fileId, manualRedactionWrappers);
|
.stream()
|
||||||
undoRecategorization(dossierId, fileId, manualRedactionWrappers, includeUnprocessed);
|
.forEach(manualChange -> {
|
||||||
undoLegalBasisChange(dossierId, fileId, manualRedactionWrappers);
|
if (manualChange.getItem() instanceof ManualRedactionEntry) {
|
||||||
undoResize(dossierId, fileId, manualRedactionWrappers);
|
undoManualRedactionEntry(dossierId, fileId, annotationId);
|
||||||
|
} else if (manualChange.getItem() instanceof IdRemoval) {
|
||||||
|
undoIdRemoval(dossierId, fileId, annotationId);
|
||||||
|
} else if (manualChange.getItem() instanceof ManualResizeRedaction) {
|
||||||
|
undoResizeEntry(dossierId, fileId, annotationId);
|
||||||
|
} else if (manualChange.getItem() instanceof ManualLegalBasisChange) {
|
||||||
|
undoLegalBasisChangeEntry(dossierId, fileId, annotationId);
|
||||||
|
} else if (manualChange.getItem() instanceof ManualRecategorization) {
|
||||||
|
undoRecategorizationEntry(dossierId, fileId, annotationId, includeOnlyUnprocessed);
|
||||||
|
} else if (manualChange.getItem() instanceof ManualForceRedaction) {
|
||||||
|
undoForceRedactionEntry(dossierId, fileId, annotationId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
reprocess(dossierId, fileId);
|
reprocess(dossierId, fileId);
|
||||||
fileStatusPersistenceService.setLastManualChangeDate(fileId, OffsetDateTime.now());
|
fileStatusPersistenceService.setLastManualChangeDate(fileId, OffsetDateTime.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ManualRedactions getManualRedactions(String fileId) {
|
private ManualRedactions getManualRedactions(String fileId, boolean includeOnlyUnprocessed, boolean includeOnlyLocal, List<String> annotationIds) {
|
||||||
|
|
||||||
return manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.allWithoutDeleted());
|
var fileStatus = fileStatusService.getStatus(fileId);
|
||||||
|
if (fileStatus.isExcludedFromAutomaticAnalysis() && !includeOnlyUnprocessed) { // analysis is disabled, only unprocessed changes can be reverted
|
||||||
|
throw new BadRequestException("Only unprocessed manual redactions can be reverted. includeOnlyUnprocessed must be set to true");
|
||||||
|
}
|
||||||
|
|
||||||
|
ManualChangesQueryOptions options = ManualChangesQueryOptions.builder()
|
||||||
|
.includeDeletions(false)
|
||||||
|
.includeDictChanges(!includeOnlyLocal)
|
||||||
|
.includeOnlyUnprocessed(includeOnlyUnprocessed)
|
||||||
|
.annotationIds(annotationIds)
|
||||||
|
.build();
|
||||||
|
return manualRedactionProviderService.getManualRedactions(fileId, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -106,236 +132,112 @@ public class ManualRedactionUndoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void undoResize(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers) {
|
private void undoResizeEntry(String dossierId, String fileId, String annotationId) {
|
||||||
|
|
||||||
List<String> manualResizeRedactions = manualRedactionWrappers.values()
|
|
||||||
.stream()
|
|
||||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualResizeRedaction)
|
|
||||||
.map(ManualRedactionWrapperModel::getId)
|
|
||||||
.toList();
|
|
||||||
if (!manualResizeRedactions.isEmpty()) {
|
|
||||||
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 deleteResizeRedaction(String dossierId, String fileId, List<String> annotationIds) {
|
|
||||||
|
|
||||||
OffsetDateTime now = OffsetDateTime.now();
|
OffsetDateTime now = OffsetDateTime.now();
|
||||||
for (var annotationId : annotationIds) {
|
resizeRedactionPersistenceService.softDelete(fileId, annotationId, now);
|
||||||
resizeRedactionPersistenceService.softDelete(fileId, annotationId, now);
|
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) {
|
private void undoLegalBasisChangeEntry(String dossierId, String fileId, String annotationId) {
|
||||||
|
|
||||||
List<String> manualLegalBasisChanges = manualRedactionWrappers.values()
|
legalBasisChangePersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
||||||
.stream()
|
auditPersistenceService.audit(AuditRequest.builder()
|
||||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualLegalBasisChange)
|
.userId(KeycloakSecurity.getUserId())
|
||||||
.map(ManualRedactionWrapperModel::getId)
|
.objectId(fileId)
|
||||||
.toList();
|
.category(AuditCategory.DOCUMENT.name())
|
||||||
if (!manualLegalBasisChanges.isEmpty()) {
|
.message("Undo of legal basis change was done.")
|
||||||
|
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||||
deleteLegalBasisChange(dossierId, fileId, manualLegalBasisChanges);
|
.build());
|
||||||
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 deleteLegalBasisChange(String dossierId, String fileId, List<String> annotationIds) {
|
private void undoRecategorizationEntry(String dossierId, String fileId, String annotationId, boolean includeUnprocessed) {
|
||||||
|
|
||||||
for (var annotationId : annotationIds) {
|
|
||||||
legalBasisChangePersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void undoRecategorization(String dossierId, String fileId, Map<String, ManualRedactionWrapperModel> manualRedactionWrappers, boolean includeUnprocessed) {
|
|
||||||
|
|
||||||
List<String> manualRecategorizations = manualRedactionWrappers.values()
|
|
||||||
.stream()
|
|
||||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRecategorization)
|
|
||||||
.map(ManualRedactionWrapperModel::getId)
|
|
||||||
.toList();
|
|
||||||
if (!manualRecategorizations.isEmpty()) {
|
|
||||||
|
|
||||||
deleteRecategorization(dossierId, fileId, manualRecategorizations, includeUnprocessed);
|
|
||||||
manualRecategorizations.forEach(annotationId -> auditPersistenceService.audit(AuditRequest.builder()
|
|
||||||
.userId(KeycloakSecurity.getUserId())
|
|
||||||
.objectId(fileId)
|
|
||||||
.category(AuditCategory.DOCUMENT.name())
|
|
||||||
.message("Undo of manual recategorization was done.")
|
|
||||||
.details(Map.of(DOSSIER_ID,
|
|
||||||
dossierId,
|
|
||||||
FILE_ID,
|
|
||||||
fileId,
|
|
||||||
ANNOTATION_ID,
|
|
||||||
annotationId))
|
|
||||||
.build()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void deleteRecategorization(String dossierId, String fileId, List<String> annotationIds, boolean includeUnprocessed) {
|
|
||||||
|
|
||||||
dossierPersistenceService.getAndValidateDossier(dossierId);
|
|
||||||
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, includeUnprocessed);
|
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, includeUnprocessed);
|
||||||
|
|
||||||
for (var annotationId : annotationIds) {
|
ManualRecategorizationEntity recategorizationEntity = recategorizationPersistenceService.findRecategorization(fileId, annotationId);
|
||||||
ManualRecategorizationEntity recategorizationEntity = recategorizationPersistenceService.findRecategorization(fileId, annotationId);
|
String originalValue = getEntityLogEntry(entityLog, annotationId).getValue();
|
||||||
String originalValue = getEntityLogEntry(entityLog, annotationId).getValue();
|
manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, recategorizationEntity.getTypeIdsOfDictionariesWithDelete());
|
||||||
manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, recategorizationEntity.getTypeIdsOfDictionariesWithDelete());
|
manualRedactionDictionaryUpdateHandler.revertAddToDictionary(originalValue,
|
||||||
manualRedactionDictionaryUpdateHandler.revertAddToDictionary(originalValue,
|
DictionaryEntryType.ENTRY,
|
||||||
DictionaryEntryType.ENTRY,
|
fileId,
|
||||||
fileId,
|
dossierId,
|
||||||
dossierId,
|
recategorizationEntity.getTypeIdsOfDictionariesWithAdd());
|
||||||
recategorizationEntity.getTypeIdsOfDictionariesWithAdd());
|
recategorizationEntity.setTypeIdsOfDictionariesWithAdd(Collections.emptySet());
|
||||||
recategorizationEntity.setTypeIdsOfDictionariesWithAdd(Collections.emptySet());
|
recategorizationEntity.setTypeIdsOfDictionariesWithDelete(Collections.emptySet());
|
||||||
recategorizationEntity.setTypeIdsOfDictionariesWithDelete(Collections.emptySet());
|
recategorizationEntity.setSoftDeletedTime(OffsetDateTime.now());
|
||||||
recategorizationEntity.setSoftDeletedTime(OffsetDateTime.now());
|
recategorizationPersistenceService.saveAndFlush(recategorizationEntity);
|
||||||
recategorizationPersistenceService.saveAndFlush(recategorizationEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
auditPersistenceService.audit(AuditRequest.builder()
|
||||||
|
.userId(KeycloakSecurity.getUserId())
|
||||||
|
.objectId(fileId)
|
||||||
|
.category(AuditCategory.DOCUMENT.name())
|
||||||
|
.message("Undo of manual 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) {
|
private void undoForceRedactionEntry(String dossierId, String fileId, String annotationId) {
|
||||||
|
|
||||||
List<String> manualForceRedactions = manualRedactionWrappers.values()
|
|
||||||
.stream()
|
|
||||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualForceRedaction)
|
|
||||||
.map(ManualRedactionWrapperModel::getId)
|
|
||||||
.toList();
|
|
||||||
if (!manualForceRedactions.isEmpty()) {
|
|
||||||
|
|
||||||
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 deleteForceRedaction(String dossierId, String fileId, List<String> annotationIds) {
|
|
||||||
|
|
||||||
var now = OffsetDateTime.now();
|
var now = OffsetDateTime.now();
|
||||||
|
forceRedactionPersistenceService.softDelete(fileId, annotationId, now);
|
||||||
for (var annotationId : annotationIds) {
|
auditPersistenceService.audit(AuditRequest.builder()
|
||||||
forceRedactionPersistenceService.softDelete(fileId, annotationId, now);
|
.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) {
|
private void undoIdRemoval(String dossierId, String fileId, String annotationId) {
|
||||||
|
|
||||||
List<String> idRemovals = manualRedactionWrappers.values()
|
|
||||||
.stream()
|
|
||||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof IdRemoval)
|
|
||||||
.map(ManualRedactionWrapperModel::getId)
|
|
||||||
.toList();
|
|
||||||
if (!idRemovals.isEmpty()) {
|
|
||||||
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 deleteRemoveRedaction(String dossierId, String fileId, List<String> annotationIds) {
|
|
||||||
|
|
||||||
dossierPersistenceService.getAndValidateDossier(dossierId);
|
|
||||||
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, true);
|
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, true);
|
||||||
|
|
||||||
for (String annotationId : annotationIds) {
|
IdRemovalEntity removeRedaction = removeRedactionPersistenceService.findRemoveRedaction(fileId, annotationId);
|
||||||
|
String originalValue = getEntityLogEntry(entityLog, annotationId).getValue();
|
||||||
|
boolean dictionaryChanged = manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, removeRedaction);
|
||||||
|
removeRedactionPersistenceService.updateModifiedDictionaries(fileId, annotationId, dictionaryChanged, Collections.emptySet());
|
||||||
|
removeRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
||||||
|
|
||||||
IdRemovalEntity removeRedaction = removeRedactionPersistenceService.findRemoveRedaction(fileId, annotationId);
|
auditPersistenceService.audit(AuditRequest.builder()
|
||||||
String originalValue = getEntityLogEntry(entityLog, annotationId).getValue();
|
.userId(KeycloakSecurity.getUserId())
|
||||||
boolean dictionaryChanged = manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, removeRedaction);
|
.objectId(fileId)
|
||||||
removeRedactionPersistenceService.updateModifiedDictionaries(fileId, annotationId, dictionaryChanged, Collections.emptySet());
|
.category(AuditCategory.DOCUMENT.name())
|
||||||
removeRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
.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) {
|
private void undoManualRedactionEntry(String dossierId, String fileId, String annotationId) {
|
||||||
|
|
||||||
List<String> manualRedactionEntries = manualRedactionWrappers.values()
|
ManualRedactionEntryEntity addRedaction = addRedactionPersistenceService.findAddRedaction(fileId, annotationId);
|
||||||
.stream()
|
|
||||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRedactionEntry)
|
|
||||||
.map(ManualRedactionWrapperModel::getId)
|
|
||||||
.toList();
|
|
||||||
if (!manualRedactionEntries.isEmpty()) {
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
boolean dictionaryChanged = manualRedactionDictionaryUpdateHandler.revertAddToDictionary(fileId, dossierId, addRedaction);
|
||||||
|
addRedactionPersistenceService.updateModifiedDictionaries(fileId, annotationId, dictionaryChanged, null);
|
||||||
|
addRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
||||||
|
|
||||||
private void deleteAddRedaction(String dossierId, String fileId, List<String> annotationIds) {
|
auditPersistenceService.audit(AuditRequest.builder()
|
||||||
|
.userId(KeycloakSecurity.getUserId())
|
||||||
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
|
.objectId(fileId)
|
||||||
|
.category(AuditCategory.DOCUMENT.name())
|
||||||
for (String annotationId : annotationIds) {
|
.message("Undo of manual add redaction was done.")
|
||||||
|
.details(Map.of(DOSSIER_ID, dossierId, FILE_ID, fileId, ANNOTATION_ID, annotationId))
|
||||||
ManualRedactionEntryEntity addRedaction = addRedactionPersistenceService.findAddRedaction(fileId, annotationId);
|
.build());
|
||||||
|
|
||||||
boolean dictionaryChanged = manualRedactionDictionaryUpdateHandler.revertAddToDictionary(fileId, dossier.getId(), addRedaction);
|
|
||||||
addRedactionPersistenceService.updateModifiedDictionaries(fileId, annotationId, dictionaryChanged, null);
|
|
||||||
addRedactionPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,13 +252,13 @@ public class ManualRedactionUndoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Map<String, ManualRedactionWrapperModel> getLatestManualRedactionsForAnnotationIds(ManualRedactions manualRedactions, Set<String> annotationIds) {
|
private Map<String, List<ManualRedactionWrapperModel>> groupAndSortManualRedactionsForAnnotationIds(ManualRedactions manualRedactions, Set<String> annotationIds) {
|
||||||
|
|
||||||
Map<String, ManualRedactionWrapperModel> result = new HashMap<>();
|
Map<String, List<ManualRedactionWrapperModel>> result = new HashMap<>();
|
||||||
annotationIds.forEach(annotationId -> {
|
annotationIds.forEach(annotationId -> {
|
||||||
var last = getLatestManualRedactionForAnnotationId(manualRedactions, annotationId);
|
var manualRedactionsForId = getLatestManualRedactionForAnnotationId(manualRedactions, annotationId);
|
||||||
if (last != null) {
|
if (manualRedactionsForId != null) {
|
||||||
result.put(annotationId, last);
|
result.put(annotationId, manualRedactionsForId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -364,7 +266,21 @@ public class ManualRedactionUndoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private ManualRedactionWrapperModel getLatestManualRedactionForAnnotationId(ManualRedactions manualRedactions, String annotationId) {
|
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.get(0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<ManualRedactionWrapperModel> getLatestManualRedactionForAnnotationId(ManualRedactions manualRedactions, String annotationId) {
|
||||||
|
|
||||||
final List<ManualRedactionWrapperModel> manualRedactionWrappers = new ArrayList<>();
|
final List<ManualRedactionWrapperModel> manualRedactionWrappers = new ArrayList<>();
|
||||||
|
|
||||||
@ -402,7 +318,7 @@ public class ManualRedactionUndoService {
|
|||||||
.sorted(Comparator.comparing(ManualRedactionWrapperModel::getDate, Comparator.nullsLast(Comparator.reverseOrder())))
|
.sorted(Comparator.comparing(ManualRedactionWrapperModel::getDate, Comparator.nullsLast(Comparator.reverseOrder())))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return sortedManualRedactionWrappers.isEmpty() ? null : sortedManualRedactionWrappers.get(0);
|
return sortedManualRedactionWrappers.isEmpty() ? null : sortedManualRedactionWrappers;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,7 +83,14 @@ public class AddRedactionPersistenceService {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public List<ManualRedactionEntryEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
public List<ManualRedactionEntryEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
||||||
|
|
||||||
return manualRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
if (options.getAnnotationIds().isEmpty()) {
|
||||||
|
return manualRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
||||||
|
}
|
||||||
|
return manualRedactionRepository.findByFileIdAndOptionsAndAnnotationIds(fileId,
|
||||||
|
options.isIncludeDeletions(),
|
||||||
|
options.isIncludeOnlyUnprocessed(),
|
||||||
|
options.isIncludeDictChanges(),
|
||||||
|
options.getAnnotationIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,10 @@ public class ForceRedactionPersistenceService {
|
|||||||
|
|
||||||
public List<ManualForceRedactionEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
public List<ManualForceRedactionEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
||||||
|
|
||||||
return forceRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed());
|
if (options.getAnnotationIds().isEmpty()) {
|
||||||
|
return forceRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed());
|
||||||
|
}
|
||||||
|
return forceRedactionRepository.findByFileIdAndOptionsAndAnnotationIds(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.getAnnotationIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
||||||
|
|||||||
@ -81,7 +81,10 @@ public class LegalBasisChangePersistenceService {
|
|||||||
|
|
||||||
public List<ManualLegalBasisChangeEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
public List<ManualLegalBasisChangeEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
||||||
|
|
||||||
return legalBasisChangeRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed());
|
if (options.getAnnotationIds().isEmpty()) {
|
||||||
|
return legalBasisChangeRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed());
|
||||||
|
}
|
||||||
|
return legalBasisChangeRepository.findByFileIdAndOptionsAndAnnotationIds(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.getAnnotationIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
||||||
|
|||||||
@ -89,7 +89,10 @@ public class RecategorizationPersistenceService {
|
|||||||
|
|
||||||
public List<ManualRecategorizationEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
public List<ManualRecategorizationEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
||||||
|
|
||||||
return recategorizationRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
if (options.getAnnotationIds().isEmpty()) {
|
||||||
|
return recategorizationRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
||||||
|
}
|
||||||
|
return recategorizationRepository.findByFileIdAndOptionsAndAnnotationIds(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges(), options.getAnnotationIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
||||||
|
|||||||
@ -49,7 +49,10 @@ public class RemoveRedactionPersistenceService {
|
|||||||
|
|
||||||
public List<IdRemovalEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
public List<IdRemovalEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
||||||
|
|
||||||
return removeRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
if (options.getAnnotationIds().isEmpty()) {
|
||||||
|
return removeRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
||||||
|
}
|
||||||
|
return removeRedactionRepository.findByFileIdAndOptionsAndAnnotationIds(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges(), options.getAnnotationIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
public int softDeleteByFileIds(List<String> fileIds, OffsetDateTime softDeletionTime) {
|
||||||
|
|||||||
@ -101,7 +101,10 @@ public class ResizeRedactionPersistenceService {
|
|||||||
|
|
||||||
public List<ManualResizeRedactionEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
public List<ManualResizeRedactionEntity> findEntriesByFileIdAndOptions(String fileId, ManualChangesQueryOptions options) {
|
||||||
|
|
||||||
return resizeRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
if (options.getAnnotationIds().isEmpty()) {
|
||||||
|
return resizeRedactionRepository.findByFileIdAndOptions(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges());
|
||||||
|
}
|
||||||
|
return resizeRedactionRepository.findByFileIdAndOptionsAndAnnotationIds(fileId, options.isIncludeDeletions(), options.isIncludeOnlyUnprocessed(), options.isIncludeDictChanges(), options.getAnnotationIds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,20 @@ public interface ForceRedactionRepository extends JpaRepository<ManualForceRedac
|
|||||||
@Param("unprocessed") boolean unprocessed);
|
@Param("unprocessed") boolean unprocessed);
|
||||||
|
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
select m
|
||||||
|
from ManualForceRedactionEntity m
|
||||||
|
where m.id.fileId = :fileId
|
||||||
|
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
|
||||||
|
and (:includeDeletions = true or m.softDeletedTime is null)
|
||||||
|
and m.id.annotationId in (:annotationIds)
|
||||||
|
""")
|
||||||
|
List<ManualForceRedactionEntity> findByFileIdAndOptionsAndAnnotationIds(@Param("fileId") String fileId,
|
||||||
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
|
@Param("unprocessed") boolean unprocessed,
|
||||||
|
@Param("annotationIds") List<String> annotationIds);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualForceRedactionEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
@Query("update ManualForceRedactionEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
||||||
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds, @Param("softDeletedTime") OffsetDateTime softDeletedTime);
|
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds, @Param("softDeletedTime") OffsetDateTime softDeletedTime);
|
||||||
|
|||||||
@ -47,6 +47,19 @@ public interface LegalBasisChangeRepository extends JpaRepository<ManualLegalBas
|
|||||||
@Param("includeDeletions") boolean includeDeletions,
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
@Param("unprocessed") boolean unprocessed);
|
@Param("unprocessed") boolean unprocessed);
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
select m
|
||||||
|
from ManualLegalBasisChangeEntity m
|
||||||
|
where m.id.fileId = :fileId
|
||||||
|
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
|
||||||
|
and (:includeDeletions = true or m.softDeletedTime is null)
|
||||||
|
and m.id.annotationId in (:annotationIds)
|
||||||
|
""")
|
||||||
|
List<ManualLegalBasisChangeEntity> findByFileIdAndOptionsAndAnnotationIds(@Param("fileId") String fileId,
|
||||||
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
|
@Param("unprocessed") boolean unprocessed,
|
||||||
|
@Param("annotationIds") List<String> annotationIds);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualLegalBasisChangeEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
@Query("update ManualLegalBasisChangeEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
||||||
|
|||||||
@ -51,6 +51,21 @@ public interface ManualRedactionRepository extends JpaRepository<ManualRedaction
|
|||||||
@Param("unprocessed") boolean unprocessed,
|
@Param("unprocessed") boolean unprocessed,
|
||||||
@Param("includeDictChanges") boolean includeDictChanges);
|
@Param("includeDictChanges") boolean includeDictChanges);
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
select m
|
||||||
|
from ManualRedactionEntryEntity m
|
||||||
|
where m.id.fileId = :fileId
|
||||||
|
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
|
||||||
|
and (:includeDeletions = true or m.softDeletedTime is null)
|
||||||
|
and (:includeDictChanges = true or (m.addToDictionary = false and m.addToAllDossiers = false))
|
||||||
|
and m.id.annotationId in (:annotationIds)
|
||||||
|
""")
|
||||||
|
List<ManualRedactionEntryEntity> findByFileIdAndOptionsAndAnnotationIds(@Param("fileId") String fileId,
|
||||||
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
|
@Param("unprocessed") boolean unprocessed,
|
||||||
|
@Param("includeDictChanges") boolean includeDictChanges,
|
||||||
|
@Param("annotationIds") List<String> annotationIds);
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
@Query("update ManualRedactionEntryEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
||||||
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
||||||
|
|||||||
@ -49,6 +49,23 @@ public interface RecategorizationRepository extends JpaRepository<ManualRecatego
|
|||||||
@Param("unprocessed") boolean unprocessed,
|
@Param("unprocessed") boolean unprocessed,
|
||||||
@Param("includeDictChanges") boolean includeDictChanges);
|
@Param("includeDictChanges") boolean includeDictChanges);
|
||||||
|
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
select m
|
||||||
|
from ManualRecategorizationEntity m
|
||||||
|
where m.id.fileId = :fileId
|
||||||
|
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
|
||||||
|
and (:includeDeletions = true or m.softDeletedTime is null)
|
||||||
|
and (:includeDictChanges = true or (m.addToDictionary = false and m.addToAllDossiers = false))
|
||||||
|
and m.id.annotationId in (:annotationIds)
|
||||||
|
""")
|
||||||
|
List<ManualRecategorizationEntity> findByFileIdAndOptionsAndAnnotationIds(@Param("fileId") String fileId,
|
||||||
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
|
@Param("unprocessed") boolean unprocessed,
|
||||||
|
@Param("includeDictChanges") boolean includeDictChanges,
|
||||||
|
@Param("annotationIds") List<String> annotationIds);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualRecategorizationEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
@Query("update ManualRecategorizationEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
||||||
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
||||||
|
|||||||
@ -49,6 +49,21 @@ public interface RemoveRedactionRepository extends JpaRepository<IdRemovalEntity
|
|||||||
@Param("unprocessed") boolean unprocessed,
|
@Param("unprocessed") boolean unprocessed,
|
||||||
@Param("includeDictChanges") boolean includeDictChanges);
|
@Param("includeDictChanges") boolean includeDictChanges);
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
select m
|
||||||
|
from IdRemovalEntity m
|
||||||
|
where m.id.fileId = :fileId
|
||||||
|
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
|
||||||
|
and (:includeDeletions = true or m.softDeletedTime is null)
|
||||||
|
and (:includeDictChanges = true or (m.removeFromDictionary = false and m.removeFromAllDossiers = false))
|
||||||
|
and m.id.annotationId in (:annotationIds)
|
||||||
|
""")
|
||||||
|
List<IdRemovalEntity> findByFileIdAndOptionsAndAnnotationIds(@Param("fileId") String fileId,
|
||||||
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
|
@Param("unprocessed") boolean unprocessed,
|
||||||
|
@Param("includeDictChanges") boolean includeDictChanges,
|
||||||
|
@Param("annotationIds") List<String> annotationIds);
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update IdRemovalEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
@Query("update IdRemovalEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
||||||
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
||||||
|
|||||||
@ -57,6 +57,23 @@ public interface ResizeRedactionRepository extends JpaRepository<ManualResizeRed
|
|||||||
@Param("unprocessed") boolean unprocessed,
|
@Param("unprocessed") boolean unprocessed,
|
||||||
@Param("includeDictChanges") boolean includeDictChanges);
|
@Param("includeDictChanges") boolean includeDictChanges);
|
||||||
|
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
select m
|
||||||
|
from ManualResizeRedactionEntity m
|
||||||
|
where m.id.fileId = :fileId
|
||||||
|
and ((:unprocessed = true and m.processedDate is null) or :unprocessed = false)
|
||||||
|
and (:includeDeletions = true or m.softDeletedTime is null)
|
||||||
|
and (:includeDictChanges = true or (m.updateDictionary = false and m.addToAllDossiers = false))
|
||||||
|
and m.id.annotationId in (:annotationIds)
|
||||||
|
""")
|
||||||
|
List<ManualResizeRedactionEntity> findByFileIdAndOptionsAndAnnotationIds(@Param("fileId") String fileId,
|
||||||
|
@Param("includeDeletions") boolean includeDeletions,
|
||||||
|
@Param("unprocessed") boolean unprocessed,
|
||||||
|
@Param("includeDictChanges") boolean includeDictChanges,
|
||||||
|
@Param("annotationIds") List<String> annotationIds);
|
||||||
|
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("update ManualResizeRedactionEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
@Query("update ManualResizeRedactionEntity m set m.softDeletedTime = :softDeletedTime where m.id.fileId in (:fileIds) and m.softDeletedTime is null")
|
||||||
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
int softDeleteByFileIds(@Param("fileIds") List<String> fileIds,
|
||||||
|
|||||||
@ -366,7 +366,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
|
|||||||
dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId());
|
dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
assertThat(dossierDictionary.getEntries()).isEmpty();
|
assertThat(dossierDictionary.getEntries()).isEmpty();
|
||||||
|
|
||||||
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of("AnnotationId"), false);
|
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of("AnnotationId"), false, false);
|
||||||
|
|
||||||
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
||||||
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder("Luke Skywalker", "Darth Vader");
|
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder("Luke Skywalker", "Darth Vader");
|
||||||
@ -1244,7 +1244,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
|
|||||||
dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
assertThat(dossierDictionary2.getEntries()).isEmpty();
|
assertThat(dossierDictionary2.getEntries()).isEmpty();
|
||||||
|
|
||||||
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of(annotationId), false);
|
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of(annotationId), false, false);
|
||||||
|
|
||||||
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
||||||
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder(lukeSkywalker, darthVader);
|
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder(lukeSkywalker, darthVader);
|
||||||
@ -1258,6 +1258,131 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testManualRecategorizeAndUndoOnlyManualChanges() {
|
||||||
|
|
||||||
|
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||||
|
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
|
||||||
|
var file = fileTesterAndProvider.testAndProvideFile(dossier);
|
||||||
|
|
||||||
|
var type = typeProvider.testAndProvideType(dossierTemplate);
|
||||||
|
var type2 = typeProvider.testAndProvideType(dossierTemplate, dossier, "test2", false, 66);
|
||||||
|
|
||||||
|
var entries = new ArrayList<String>();
|
||||||
|
|
||||||
|
var lukeSkywalker = "Luke Skywalker";
|
||||||
|
var darthVader = "Darth Vader";
|
||||||
|
entries.add(lukeSkywalker);
|
||||||
|
entries.add(darthVader);
|
||||||
|
dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), entries, false, null, DictionaryEntryType.ENTRY);
|
||||||
|
|
||||||
|
dictionaryClient.addEntry(type.getType(), type.getDossierTemplateId(), List.of(lukeSkywalker), false, dossier.getId(), DictionaryEntryType.ENTRY);
|
||||||
|
|
||||||
|
Dictionary dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
||||||
|
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder(lukeSkywalker, darthVader);
|
||||||
|
Dictionary dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
|
assertThat(dossierDictionary.getEntries()).containsExactlyInAnyOrder(lukeSkywalker);
|
||||||
|
|
||||||
|
Dictionary dossierTemplateDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), null);
|
||||||
|
assertThat(dossierTemplateDictionary2.getEntries()).isEmpty();
|
||||||
|
Dictionary dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
|
assertThat(dossierDictionary2.getEntries()).isEmpty();
|
||||||
|
|
||||||
|
var annotationId = "AnnotationId";
|
||||||
|
var entityLog = new EntityLog(1,
|
||||||
|
1,
|
||||||
|
List.of(EntityLogEntry.builder()
|
||||||
|
.id(annotationId)
|
||||||
|
.type(type.getType())
|
||||||
|
.value(lukeSkywalker)
|
||||||
|
.dictionaryEntry(true)
|
||||||
|
.entryType(EntryType.ENTITY)
|
||||||
|
.state(EntryState.APPLIED)
|
||||||
|
.build()),
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog);
|
||||||
|
|
||||||
|
when(entityLogService.getEntityLog(any(), any(), anyBoolean())).thenReturn(entityLog);
|
||||||
|
|
||||||
|
manualRedactionClient.recategorizeBulk(dossier.getId(),
|
||||||
|
file.getId(),
|
||||||
|
Set.of(RecategorizationRequestModel.builder()
|
||||||
|
.type(type2.getType())
|
||||||
|
.annotationId(annotationId)
|
||||||
|
.addToDictionary(true)
|
||||||
|
.addToAllDossiers(true)
|
||||||
|
.legalBasis("")
|
||||||
|
.section("section")
|
||||||
|
.value(lukeSkywalker)
|
||||||
|
.build()),
|
||||||
|
false);
|
||||||
|
|
||||||
|
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
||||||
|
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder(darthVader);
|
||||||
|
dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
|
assertThat(dossierDictionary.getEntries()).isEmpty();
|
||||||
|
|
||||||
|
dossierTemplateDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), null);
|
||||||
|
assertThat(dossierTemplateDictionary2.getEntries()).containsExactlyInAnyOrder(lukeSkywalker);
|
||||||
|
dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
|
assertThat(dossierDictionary2.getEntries()).isEmpty();
|
||||||
|
|
||||||
|
// try to undo only local changes, but there are none for the requested annotationId
|
||||||
|
String errorMessage = assertThrows(FeignException.NotFound.class,
|
||||||
|
() -> manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of(annotationId), false, true)).getMessage();
|
||||||
|
assertTrue(errorMessage.contains("ManualRedaction with annotationIds [AnnotationId] could not be found"));
|
||||||
|
|
||||||
|
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
||||||
|
assertThat(dossierTemplateDictionary.getEntries()).containsExactlyInAnyOrder(darthVader);
|
||||||
|
dossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
|
assertThat(dossierDictionary.getEntries()).isEmpty();
|
||||||
|
|
||||||
|
dossierTemplateDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), null);
|
||||||
|
assertThat(dossierTemplateDictionary2.getEntries()).containsExactlyInAnyOrder(lukeSkywalker);
|
||||||
|
dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
|
assertThat(dossierDictionary2.getEntries()).isEmpty();
|
||||||
|
|
||||||
|
var resizeRedactionRequestModel = ResizeRedactionRequestModel.builder()
|
||||||
|
.annotationId(annotationId)
|
||||||
|
.value(lukeSkywalker + " resized")
|
||||||
|
.updateDictionary(false)
|
||||||
|
.addToAllDossiers(false)
|
||||||
|
.positions(List.of(Rectangle.builder().page(1).height(1).width(2).topLeftX(1).topLeftY(1).build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ManualRedactionResponse response = manualRedactionClient.resizeRedactionBulk(dossier.getId(), file.getId(), Set.of(resizeRedactionRequestModel), false);
|
||||||
|
|
||||||
|
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
|
||||||
|
|
||||||
|
assertEquals(allManualRedactions.getResizeRedactions().size(), 1);
|
||||||
|
assertEquals(allManualRedactions.getEntriesToAdd().size(), 1);
|
||||||
|
assertEquals(allManualRedactions.getRecategorizations().size(), 1);
|
||||||
|
var entryToResize = allManualRedactions.getResizeRedactions()
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.get();
|
||||||
|
var entryToAdd = allManualRedactions.getEntriesToAdd()
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.get();
|
||||||
|
assertFalse(entryToAdd.isAddToDictionary());
|
||||||
|
assertFalse(entryToAdd.isAddToDossierDictionary());
|
||||||
|
assertEquals(entryToAdd.getAnnotationId(), entryToResize.getAnnotationId());
|
||||||
|
|
||||||
|
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of(annotationId, entryToResize.getAnnotationId()), false, true);
|
||||||
|
|
||||||
|
allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
|
||||||
|
|
||||||
|
assertEquals(allManualRedactions.getResizeRedactions().size(), 0);
|
||||||
|
assertEquals(allManualRedactions.getEntriesToAdd().size(), 0);
|
||||||
|
assertEquals(allManualRedactions.getRecategorizations().size(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManualRecategorizeAndUndoDossierLevelOnly() {
|
public void testManualRecategorizeAndUndoDossierLevelOnly() {
|
||||||
|
|
||||||
@ -1330,7 +1455,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
|
|||||||
dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
dossierDictionary2 = dictionaryClient.getDictionaryForType(type2.getType(), type.getDossierTemplateId(), dossier.getId());
|
||||||
assertThat(dossierDictionary2.getEntries()).containsExactlyInAnyOrder(lukeSkywalker);
|
assertThat(dossierDictionary2.getEntries()).containsExactlyInAnyOrder(lukeSkywalker);
|
||||||
|
|
||||||
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of(annotationId), false);
|
manualRedactionClient.undo(dossier.getId(), file.getFileId(), Set.of(annotationId), false, false);
|
||||||
|
|
||||||
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
dossierTemplateDictionary = dictionaryClient.getDictionaryForType(type.getType(), type.getDossierTemplateId(), null);
|
||||||
assertThat(dossierTemplateDictionary.getEntries()).isEmpty();
|
assertThat(dossierTemplateDictionary.getEntries()).isEmpty();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user