RED-7317: mark LegalBasisChange as processed in DB after analysis #104
@ -29,8 +29,8 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "manual_image_recategorization")
|
||||
public class ManualImageRecategorizationEntity implements IBaseAnnotation {
|
||||
@Table(name = "manual_recategorization")
|
||||
public class ManualRecategorizationEntity implements IBaseAnnotation {
|
||||
|
||||
@EmbeddedId
|
||||
private AnnotationEntityId id;
|
||||
@ -7,8 +7,6 @@ import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
@ -19,8 +17,8 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.CommentPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ForceRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ImageRecategorizationPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.LegalBasisChangePersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.RecategorizationPersistenceService;
|
||||
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.shared.model.common.JSONPrimitive;
|
||||
@ -30,6 +28,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
|
||||
import com.iqser.red.service.search.v1.model.IndexMessageType;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -49,7 +48,7 @@ public class FileService {
|
||||
private final ViewedPagesPersistenceService viewedPagesPersistenceService;
|
||||
private final FileManagementStorageService fileManagementStorageService;
|
||||
private final DossierPersistenceService dossierPersistenceService;
|
||||
private final ImageRecategorizationPersistenceService recategorizationPersistenceService;
|
||||
private final RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
private final LegalBasisChangePersistenceService legalBasisChangePersistenceService;
|
||||
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||
private final IndexingService indexingService;
|
||||
|
||||
@ -31,13 +31,12 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.CommentPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ForceRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ImageRecategorizationPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.LegalBasisChangePersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.RecategorizationPersistenceService;
|
||||
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.management.v1.processor.settings.FileManagementServiceSettings;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.FileModelMapper;
|
||||
import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AnalyzeResult;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.FileAttribute;
|
||||
@ -47,6 +46,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;
|
||||
import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -64,7 +64,7 @@ public class FileStatusService {
|
||||
private final ManualRedactionProviderService manualRedactionProviderService;
|
||||
private final FileManagementStorageService fileManagementStorageService;
|
||||
private final LegalBasisChangePersistenceService legalBasisChangePersistenceService;
|
||||
private final ImageRecategorizationPersistenceService imageRecategorizationPersistenceService;
|
||||
private final RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
private final CommentPersistenceService commentPersistenceService;
|
||||
private final ForceRedactionPersistenceService forceRedactionPersistenceService;
|
||||
private final RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||
@ -687,8 +687,8 @@ public class FileStatusService {
|
||||
removeRedactions.forEach(f -> removeRedactionPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));
|
||||
|
||||
// wipe image recat
|
||||
var imageRecategorizations = imageRecategorizationPersistenceService.findRecategorizations(fileId, false);
|
||||
imageRecategorizations.forEach(f -> imageRecategorizationPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));// wipe image recat
|
||||
var imageRecategorizations = recategorizationPersistenceService.findRecategorizations(fileId, false);
|
||||
imageRecategorizations.forEach(f -> recategorizationPersistenceService.softDelete(fileId, f.getId().getAnnotationId(), now));// wipe image recat
|
||||
|
||||
// wipe resize redactions
|
||||
var resizeRedactions = resizeRedactionPersistenceService.findResizeRedactions(fileId, false);
|
||||
|
||||
@ -18,8 +18,8 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.CommentPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ForceRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.ImageRecategorizationPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.LegalBasisChangePersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.RecategorizationPersistenceService;
|
||||
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.management.v1.processor.utils.ManualImageRecategorizationMapper;
|
||||
@ -29,8 +29,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualImageRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
|
||||
|
||||
@ -46,7 +46,7 @@ public class ManualRedactionProviderService {
|
||||
private final RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||
private final ForceRedactionPersistenceService forceRedactionPersistenceService;
|
||||
private final CommentPersistenceService commentPersistenceService;
|
||||
private final ImageRecategorizationPersistenceService recategorizationPersistenceService;
|
||||
private final RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
private final LegalBasisChangePersistenceService legalBasisChangePersistenceService;
|
||||
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||
|
||||
@ -60,8 +60,8 @@ public class ManualRedactionProviderService {
|
||||
|
||||
Set<ManualForceRedaction> forceRedactions = convert(forceRedactionPersistenceService.findForceRedactions(fileId, false), ManualForceRedaction.class);
|
||||
|
||||
Set<ManualImageRecategorization> recategorizations = new HashSet<>(convert(recategorizationPersistenceService.findRecategorizations(fileId, false),
|
||||
ManualImageRecategorization.class,
|
||||
Set<ManualRecategorization> recategorizations = new HashSet<>(convert(recategorizationPersistenceService.findRecategorizations(fileId, false),
|
||||
ManualRecategorization.class,
|
||||
new ManualImageRecategorizationMapper()));
|
||||
|
||||
Set<ManualLegalBasisChange> legalBasisChanges = convert(legalBasisChangePersistenceService.findLegalBasisChanges(fileId, false), ManualLegalBasisChange.class);
|
||||
@ -80,7 +80,7 @@ public class ManualRedactionProviderService {
|
||||
|
||||
|
||||
@Transactional
|
||||
public ManualRedactionEntry getAddRedaction(String fileId, String annotationId){
|
||||
public ManualRedactionEntry getAddRedaction(String fileId, String annotationId) {
|
||||
|
||||
return convert(addRedactionPersistenceService.findAddRedaction(fileId, annotationId), ManualRedactionEntry.class, new ManualRedactionMapper());
|
||||
}
|
||||
@ -92,16 +92,16 @@ public class ManualRedactionProviderService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Transactional(noRollbackFor = {EmptyResultDataAccessException.class})
|
||||
public void hardDeleteManualRedactions(String fileId, String annotationId) {
|
||||
addRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
removeRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
forceRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
recategorizationPersistenceService.hardDelete(fileId, annotationId);
|
||||
legalBasisChangePersistenceService.hardDelete(fileId, annotationId);
|
||||
resizeRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
commentPersistenceService.hardDelete(fileId, annotationId);
|
||||
|
||||
addRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
removeRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
forceRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
recategorizationPersistenceService.hardDelete(fileId, annotationId);
|
||||
legalBasisChangePersistenceService.hardDelete(fileId, annotationId);
|
||||
resizeRedactionPersistenceService.hardDelete(fileId, annotationId);
|
||||
commentPersistenceService.hardDelete(fileId, annotationId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,8 +20,8 @@ import com.iqser.red.service.persistence.management.v1.processor.service.Redacti
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.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.RecategorizationPersistenceService;
|
||||
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.shared.model.annotations.AddRedactionRequest;
|
||||
@ -53,7 +53,7 @@ public class ManualRedactionService {
|
||||
RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||
ForceRedactionPersistenceService forceRedactionPersistenceService;
|
||||
CommentService commentService;
|
||||
ImageRecategorizationPersistenceService recategorizationPersistenceService;
|
||||
RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
LegalBasisChangePersistenceService legalBasisChangePersistenceService;
|
||||
ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||
FileStatusService fileStatusService;
|
||||
@ -356,8 +356,8 @@ public class ManualRedactionService {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (manualRedactions.getImageRecategorization() != null) {
|
||||
manualRedactions.getImageRecategorization().forEach(e -> {
|
||||
if (manualRedactions.getRecategorizations() != null) {
|
||||
manualRedactions.getRecategorizations().forEach(e -> {
|
||||
if (!e.getStatus().equals(AnnotationStatus.REQUESTED) && e.getProcessedDate() == null) {
|
||||
recategorizationPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
|
||||
}
|
||||
@ -370,6 +370,13 @@ public class ManualRedactionService {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (manualRedactions.getLegalBasisChanges() != null) {
|
||||
manualRedactions.getLegalBasisChanges().forEach(e -> {
|
||||
if (!e.getStatus().equals(AnnotationStatus.REQUESTED) && e.getProcessedDate() == null) {
|
||||
resizeRedactionPersistenceService.markAsProcessed(e.getAnnotationId(), e.getFileId());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ import org.springframework.stereotype.Service;
|
||||
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.ManualImageRecategorizationEntity;
|
||||
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.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.AnalysisFlagsCalculationService;
|
||||
@ -28,8 +28,8 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.AddRedactionPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.annotations.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.RecategorizationPersistenceService;
|
||||
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.shared.model.AuditCategory;
|
||||
@ -37,8 +37,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualImageRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
|
||||
@ -61,7 +61,7 @@ public class ManualRedactionUndoService {
|
||||
AuditPersistenceService auditPersistenceService;
|
||||
FileStatusService fileStatusService;
|
||||
AnalysisFlagsCalculationService analysisFlagsCalculationService;
|
||||
ImageRecategorizationPersistenceService recategorizationPersistenceService;
|
||||
RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
DossierPersistenceService dossierPersistenceService;
|
||||
AddRedactionPersistenceService addRedactionPersistenceService;
|
||||
RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||
@ -171,7 +171,7 @@ public class ManualRedactionUndoService {
|
||||
|
||||
List<String> manualImageRecategorizations = manualRedactionWrappers.values()
|
||||
.stream()
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualImageRecategorization)
|
||||
.filter(manualRedactionWrapper -> manualRedactionWrapper.getItem() instanceof ManualRecategorization)
|
||||
.map(ManualRedactionWrapperModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
if (!manualImageRecategorizations.isEmpty()) {
|
||||
@ -194,13 +194,18 @@ public class ManualRedactionUndoService {
|
||||
RedactionLog redactionLog = redactionLogService.getRedactionLog(dossierId, fileId);
|
||||
|
||||
for (var annotationId : annotationIds) {
|
||||
ManualImageRecategorizationEntity recategorizationEntity = recategorizationPersistenceService.findRecategorization(fileId, annotationId);
|
||||
ManualRecategorizationEntity recategorizationEntity = recategorizationPersistenceService.findRecategorization(fileId, annotationId);
|
||||
String originalValue = getRedactionLogEntry(redactionLog, annotationId).getValue();
|
||||
manualRedactionDictionaryUpdateHandler.revertRemoveFromDictionary(originalValue, dossierId, fileId, recategorizationEntity.getTypeIdsOfDictionariesWithDelete());
|
||||
manualRedactionDictionaryUpdateHandler.revertAddToDictionary(originalValue, DictionaryEntryType.ENTRY, fileId, dossierId, recategorizationEntity.getTypeIdsOfDictionariesWithAdd());
|
||||
manualRedactionDictionaryUpdateHandler.revertAddToDictionary(originalValue,
|
||||
DictionaryEntryType.ENTRY,
|
||||
fileId,
|
||||
dossierId,
|
||||
recategorizationEntity.getTypeIdsOfDictionariesWithAdd());
|
||||
recategorizationPersistenceService.updateStatus(fileId, annotationId, AnnotationStatus.APPROVED, false, Collections.emptySet(), Collections.emptySet());
|
||||
recategorizationPersistenceService.softDelete(fileId, annotationId, OffsetDateTime.now());
|
||||
} analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
|
||||
}
|
||||
analysisFlagsCalculationService.calculateFlags(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
@ -345,7 +350,7 @@ public class ManualRedactionUndoService {
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
manualRedactions.getImageRecategorization()
|
||||
manualRedactions.getRecategorizations()
|
||||
.stream()
|
||||
.filter(item -> item.getSoftDeletedTime() == null && item.getAnnotationId().equals(annotationId))
|
||||
.forEach(item -> manualRedactionWrappers.add(new ManualRedactionWrapperModel(item.getAnnotationId(), item.getRequestDate(), item)));
|
||||
|
||||
@ -10,9 +10,9 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualImageRecategorizationEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ImageRecategorizationRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RecategorizationRequest;
|
||||
|
||||
@ -22,19 +22,19 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ImageRecategorizationPersistenceService {
|
||||
public class RecategorizationPersistenceService {
|
||||
|
||||
private final ImageRecategorizationRepository imageRecategorizationRepository;
|
||||
private final RecategorizationRepository recategorizationRepository;
|
||||
|
||||
|
||||
public void insert(String fileId, RecategorizationRequest recategorizationRequest) {
|
||||
|
||||
ManualImageRecategorizationEntity manualImageRecategorization = new ManualImageRecategorizationEntity();
|
||||
ManualRecategorizationEntity manualImageRecategorization = new ManualRecategorizationEntity();
|
||||
manualImageRecategorization.setId(new AnnotationEntityId(recategorizationRequest.getAnnotationId(), fileId));
|
||||
BeanUtils.copyProperties(recategorizationRequest, manualImageRecategorization);
|
||||
manualImageRecategorization.setRequestDate(OffsetDateTime.now());
|
||||
manualImageRecategorization.setTypeId(recategorizationRequest.getDossierTemplateTypeId());
|
||||
imageRecategorizationRepository.saveAndFlush(manualImageRecategorization);
|
||||
recategorizationRepository.saveAndFlush(manualImageRecategorization);
|
||||
|
||||
}
|
||||
|
||||
@ -42,9 +42,10 @@ public class ImageRecategorizationPersistenceService {
|
||||
@Transactional
|
||||
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus) {
|
||||
|
||||
imageRecategorizationRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
|
||||
recategorizationRepository.updateStatus(new AnnotationEntityId(annotationId, fileId), annotationStatus);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void updateStatus(String fileId,
|
||||
String annotationId,
|
||||
@ -53,7 +54,7 @@ public class ImageRecategorizationPersistenceService {
|
||||
Set<String> typeIdsOfDictionaryWithAdd,
|
||||
Set<String> typeIdsOfDictionaryWithDelete) {
|
||||
|
||||
ManualImageRecategorizationEntity addRedaction = imageRecategorizationRepository.findById(new AnnotationEntityId(annotationId, fileId))
|
||||
ManualRecategorizationEntity addRedaction = recategorizationRepository.findById(new AnnotationEntityId(annotationId, fileId))
|
||||
.orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));
|
||||
|
||||
addRedaction.setStatus(annotationStatus);
|
||||
@ -61,41 +62,41 @@ public class ImageRecategorizationPersistenceService {
|
||||
addRedaction.setTypeIdsOfDictionariesWithAdd(typeIdsOfDictionaryWithAdd);
|
||||
addRedaction.setTypeIdsOfDictionariesWithDelete(typeIdsOfDictionaryWithDelete);
|
||||
|
||||
imageRecategorizationRepository.saveAndFlush(addRedaction);
|
||||
recategorizationRepository.saveAndFlush(addRedaction);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void hardDelete(String fileId, String annotationId) {
|
||||
|
||||
imageRecategorizationRepository.deleteByIdIs(new AnnotationEntityId(annotationId, fileId));
|
||||
recategorizationRepository.deleteByIdIs(new AnnotationEntityId(annotationId, fileId));
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void softDelete(String fileId, String annotationId, OffsetDateTime softDeleteTime) {
|
||||
|
||||
imageRecategorizationRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), softDeleteTime);
|
||||
recategorizationRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), softDeleteTime);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void undelete(String fileId, String annotationId) {
|
||||
|
||||
imageRecategorizationRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), null);
|
||||
recategorizationRepository.updateSoftDelete(new AnnotationEntityId(annotationId, fileId), null);
|
||||
}
|
||||
|
||||
|
||||
public ManualImageRecategorizationEntity findRecategorization(String fileId, String annotationId) {
|
||||
public ManualRecategorizationEntity findRecategorization(String fileId, String annotationId) {
|
||||
|
||||
return imageRecategorizationRepository.findByIdAndNotSoftDeleted(new AnnotationEntityId(annotationId, fileId))
|
||||
return recategorizationRepository.findByIdAndNotSoftDeleted(new AnnotationEntityId(annotationId, fileId))
|
||||
.orElseThrow(() -> new NotFoundException("Unknown file/annotation combination: " + fileId + "/" + annotationId));
|
||||
}
|
||||
|
||||
|
||||
public List<ManualImageRecategorizationEntity> findRecategorizations(String fileId, boolean includeDeletions) {
|
||||
public List<ManualRecategorizationEntity> findRecategorizations(String fileId, boolean includeDeletions) {
|
||||
|
||||
return imageRecategorizationRepository.findByFileIdIncludeDeletions(fileId, includeDeletions);
|
||||
return recategorizationRepository.findByFileIdIncludeDeletions(fileId, includeDeletions);
|
||||
|
||||
}
|
||||
|
||||
@ -103,7 +104,7 @@ public class ImageRecategorizationPersistenceService {
|
||||
@Transactional
|
||||
public void markAsProcessed(String annotationId, String fileId) {
|
||||
|
||||
imageRecategorizationRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
recategorizationRepository.markAsProcessed(new AnnotationEntityId(annotationId, fileId), OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,7 +13,6 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.RectangleEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ManualRedactionRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ResizeRedactionRepository;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
|
||||
@ -27,8 +26,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@RequiredArgsConstructor
|
||||
public class ResizeRedactionPersistenceService {
|
||||
|
||||
private final ManualRedactionRepository manualRedactionRepository;
|
||||
|
||||
private final ResizeRedactionRepository resizeRedactionRepository;
|
||||
|
||||
|
||||
@ -56,6 +53,7 @@ public class ResizeRedactionPersistenceService {
|
||||
resizeRedactionRepository.updateSurroundingText(id, textBefore, textAfter);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void updateStatus(String fileId, String annotationId, AnnotationStatus annotationStatus, Set<String> typeIdsOfModifiedDictionaries) {
|
||||
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
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.ManualImageRecategorizationEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
|
||||
|
||||
public interface ImageRecategorizationRepository extends JpaRepository<ManualImageRecategorizationEntity, AnnotationEntityId>, AnnotationEntityRepository {
|
||||
|
||||
@Modifying(clearAutomatically = true)
|
||||
@Query("update ManualImageRecategorizationEntity mir set mir.status = :annotationStatus " + "where mir.id = :annotationEntityId")
|
||||
void updateStatus(AnnotationEntityId annotationEntityId, AnnotationStatus annotationStatus);
|
||||
|
||||
|
||||
@Modifying
|
||||
@Query("update ManualImageRecategorizationEntity mir set mir.softDeletedTime = :softDeletedTime " + "where mir.id = :annotationEntityId")
|
||||
void updateSoftDelete(AnnotationEntityId annotationEntityId, OffsetDateTime softDeletedTime);
|
||||
|
||||
|
||||
@Query("select mir from ManualImageRecategorizationEntity mir where mir.id = :annotationEntityId and mir.softDeletedTime is null")
|
||||
Optional<ManualImageRecategorizationEntity> findByIdAndNotSoftDeleted(AnnotationEntityId annotationEntityId);
|
||||
|
||||
|
||||
@Query("select mir from ManualImageRecategorizationEntity mir where mir.id.fileId = :fileId and (:includeDeletions = true or mir.softDeletedTime is null)")
|
||||
List<ManualImageRecategorizationEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
|
||||
|
||||
|
||||
@Modifying
|
||||
@Query("update ManualImageRecategorizationEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId")
|
||||
void markAsProcessed(AnnotationEntityId annotationEntityId, OffsetDateTime processedDate);
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
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.ManualRecategorizationEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationStatus;
|
||||
|
||||
public interface RecategorizationRepository extends JpaRepository<ManualRecategorizationEntity, AnnotationEntityId>, AnnotationEntityRepository {
|
||||
|
||||
@Modifying(clearAutomatically = true)
|
||||
@Query("update ManualRecategorizationEntity mir set mir.status = :annotationStatus " + "where mir.id = :annotationEntityId")
|
||||
void updateStatus(AnnotationEntityId annotationEntityId, AnnotationStatus annotationStatus);
|
||||
|
||||
|
||||
@Modifying
|
||||
@Query("update ManualRecategorizationEntity mir set mir.softDeletedTime = :softDeletedTime " + "where mir.id = :annotationEntityId")
|
||||
void updateSoftDelete(AnnotationEntityId annotationEntityId, OffsetDateTime softDeletedTime);
|
||||
|
||||
|
||||
@Query("select mir from ManualRecategorizationEntity mir where mir.id = :annotationEntityId and mir.softDeletedTime is null")
|
||||
Optional<ManualRecategorizationEntity> findByIdAndNotSoftDeleted(AnnotationEntityId annotationEntityId);
|
||||
|
||||
|
||||
@Query("select mir from ManualRecategorizationEntity mir where mir.id.fileId = :fileId and (:includeDeletions = true or mir.softDeletedTime is null)")
|
||||
List<ManualRecategorizationEntity> findByFileIdIncludeDeletions(String fileId, boolean includeDeletions);
|
||||
|
||||
|
||||
@Modifying
|
||||
@Query("update ManualRecategorizationEntity mir set mir.processedDate = :processedDate where mir.id = :annotationEntityId")
|
||||
void markAsProcessed(AnnotationEntityId annotationEntityId, OffsetDateTime processedDate);
|
||||
|
||||
}
|
||||
@ -2,15 +2,15 @@ package com.iqser.red.service.persistence.management.v1.processor.utils;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualImageRecategorizationEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualImageRecategorization;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRecategorizationEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
|
||||
|
||||
public class ManualImageRecategorizationMapper implements BiConsumer<ManualImageRecategorizationEntity, ManualImageRecategorization> {
|
||||
public class ManualImageRecategorizationMapper implements BiConsumer<ManualRecategorizationEntity, ManualRecategorization> {
|
||||
|
||||
@Override
|
||||
public void accept(ManualImageRecategorizationEntity manualImageRecategorizationEntity, ManualImageRecategorization manualRedactionEntry) {
|
||||
public void accept(ManualRecategorizationEntity manualRecategorizationEntity, ManualRecategorization manualRedactionEntry) {
|
||||
|
||||
manualRedactionEntry.setType(manualImageRecategorizationEntity.getTypeId().substring(0, manualImageRecategorizationEntity.getTypeId().indexOf(":")));
|
||||
manualRedactionEntry.setType(manualRecategorizationEntity.getTypeId().substring(0, manualRecategorizationEntity.getTypeId().indexOf(":")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -157,4 +157,3 @@ databaseChangeLog:
|
||||
file: db/changelog/tenant/107-add-last-layout-processed-column.yaml
|
||||
- include:
|
||||
file: db/changelog/tenant/108-added-dictionary-changes-to-manual-recategorization.yaml
|
||||
|
||||
|
||||
@ -1,4 +1,11 @@
|
||||
databaseChangeLog:
|
||||
- changeSet:
|
||||
id: change-table-name-image-recategorization
|
||||
author: kilian
|
||||
changes:
|
||||
- renameTable:
|
||||
oldTableName: manual_image_recategorization
|
||||
newTableName: manual_recategorization
|
||||
- changeSet:
|
||||
id: added-dictionary-changes-to-manual-recategorization
|
||||
author: kilian
|
||||
@ -8,13 +15,13 @@ databaseChangeLog:
|
||||
- column:
|
||||
name: add_to_dictionary
|
||||
type: BOOLEAN
|
||||
tableName: manual_image_recategorization
|
||||
tableName: manual_recategorization
|
||||
- addColumn:
|
||||
columns:
|
||||
- column:
|
||||
name: add_to_all_dossiers
|
||||
type: BOOLEAN
|
||||
tableName: manual_image_recategorization
|
||||
tableName: manual_recategorization
|
||||
- changeSet:
|
||||
id: added-dictionary-changes-to-manual-recategorization-2
|
||||
author: kilian
|
||||
@ -24,12 +31,12 @@ databaseChangeLog:
|
||||
- column:
|
||||
constraints:
|
||||
nullable: false
|
||||
name: manual_image_recategorization_entity_annotation_id
|
||||
name: manual_recategorization_entity_annotation_id
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
constraints:
|
||||
nullable: false
|
||||
name: manual_image_recategorization_entity_file_id
|
||||
name: manual_recategorization_entity_file_id
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: type_ids_of_dictionaries_with_add
|
||||
@ -40,12 +47,12 @@ databaseChangeLog:
|
||||
- column:
|
||||
constraints:
|
||||
nullable: false
|
||||
name: manual_image_recategorization_entity_annotation_id
|
||||
name: manual_recategorization_entity_annotation_id
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
constraints:
|
||||
nullable: false
|
||||
name: manual_image_recategorization_entity_file_id
|
||||
name: manual_recategorization_entity_file_id
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: type_ids_of_dictionaries_with_delete
|
||||
@ -56,7 +63,7 @@ databaseChangeLog:
|
||||
author: kilian
|
||||
changes:
|
||||
- addForeignKeyConstraint:
|
||||
baseColumnNames: manual_image_recategorization_entity_annotation_id, manual_image_recategorization_entity_file_id
|
||||
baseColumnNames: manual_recategorization_entity_annotation_id, manual_recategorization_entity_file_id
|
||||
baseTableName: manual_recategorization_type_ids_of_dictionaries_with_add
|
||||
constraintName: fk_manual_recategorization_to_dictionary_add
|
||||
deferrable: false
|
||||
@ -64,10 +71,10 @@ databaseChangeLog:
|
||||
onDelete: NO ACTION
|
||||
onUpdate: NO ACTION
|
||||
referencedColumnNames: annotation_id, file_id
|
||||
referencedTableName: manual_image_recategorization
|
||||
referencedTableName: manual_recategorization
|
||||
validate: true
|
||||
- addForeignKeyConstraint:
|
||||
baseColumnNames: manual_image_recategorization_entity_annotation_id, manual_image_recategorization_entity_file_id
|
||||
baseColumnNames: manual_recategorization_entity_annotation_id, manual_recategorization_entity_file_id
|
||||
baseTableName: manual_recategorization_type_ids_of_dictionaries_with_delete
|
||||
constraintName: fk_manual_recategorization_to_dictionary_delete
|
||||
deferrable: false
|
||||
@ -75,5 +82,5 @@ databaseChangeLog:
|
||||
onDelete: NO ACTION
|
||||
onUpdate: NO ACTION
|
||||
referencedColumnNames: annotation_id, file_id
|
||||
referencedTableName: manual_image_recategorization
|
||||
referencedTableName: manual_recategorization
|
||||
validate: true
|
||||
@ -81,9 +81,9 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.ViewedPagesRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.WatermarkRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ForceRedactionRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ImageRecategorizationRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.LegalBasisChangeRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.ManualRedactionRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RecategorizationRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.annotationentity.RemoveRedactionRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.EntryRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalsePositiveEntryRepository;
|
||||
@ -155,7 +155,7 @@ public abstract class AbstractPersistenceServerServiceTest {
|
||||
@Autowired
|
||||
protected LegalBasisChangeRepository legalBasisChangeRepository;
|
||||
@Autowired
|
||||
protected ImageRecategorizationRepository imageRecategorizationRepository;
|
||||
protected RecategorizationRepository recategorizationRepository;
|
||||
@Autowired
|
||||
protected WatermarkRepository watermarkRepository;
|
||||
@Autowired
|
||||
@ -240,7 +240,6 @@ public abstract class AbstractPersistenceServerServiceTest {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setupOptimize() {
|
||||
|
||||
@ -389,7 +388,7 @@ public abstract class AbstractPersistenceServerServiceTest {
|
||||
forceRedactionRepository.deleteAll();
|
||||
removeRedactionRepository.deleteAll();
|
||||
legalBasisChangeRepository.deleteAll();
|
||||
imageRecategorizationRepository.deleteAll();
|
||||
recategorizationRepository.deleteAll();
|
||||
legalBasisMappingRepository.deleteAll();
|
||||
ruleSetRepository.deleteAll();
|
||||
fileRepository.deleteAll();
|
||||
|
||||
@ -8,8 +8,8 @@ import java.util.Set;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.IdRemoval;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualForceRedaction;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualImageRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualLegalBasisChange;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRecategorization;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualResizeRedaction;
|
||||
|
||||
@ -34,7 +34,7 @@ public class ManualRedactions {
|
||||
private Set<ManualForceRedaction> forceRedactions = new HashSet<>();
|
||||
|
||||
@Builder.Default
|
||||
private Set<ManualImageRecategorization> imageRecategorization = new HashSet<>();
|
||||
private Set<ManualRecategorization> recategorizations = new HashSet<>();
|
||||
|
||||
@Builder.Default
|
||||
private Set<ManualLegalBasisChange> legalBasisChanges = new HashSet<>();
|
||||
|
||||
@ -12,20 +12,20 @@ import lombok.NoArgsConstructor;
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ManualImageRecategorization extends BaseAnnotation {
|
||||
public class ManualRecategorization extends BaseAnnotation {
|
||||
|
||||
private String type;
|
||||
|
||||
|
||||
@Builder
|
||||
public ManualImageRecategorization(String annotationId,
|
||||
String fileId,
|
||||
String user,
|
||||
AnnotationStatus status,
|
||||
OffsetDateTime requestDate,
|
||||
OffsetDateTime processedDate,
|
||||
OffsetDateTime softDeletedTime,
|
||||
String type) {
|
||||
public ManualRecategorization(String annotationId,
|
||||
String fileId,
|
||||
String user,
|
||||
AnnotationStatus status,
|
||||
OffsetDateTime requestDate,
|
||||
OffsetDateTime processedDate,
|
||||
OffsetDateTime softDeletedTime,
|
||||
String type) {
|
||||
|
||||
super(annotationId, fileId, user, status, requestDate, processedDate, softDeletedTime);
|
||||
this.type = type;
|
||||
Loading…
x
Reference in New Issue
Block a user