RED-9255: attempt to delete the entire imported dossier template, if any exception happens during import #627
@ -381,7 +381,6 @@ public class DossierController implements DossierResource {
|
||||
throw new AccessDeniedException("Can not delete dossier that is owned by a different user");
|
||||
}
|
||||
|
||||
|
||||
dossierManagementService.softDeleteDossier(dossierId);
|
||||
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
@ -450,7 +449,7 @@ public class DossierController implements DossierResource {
|
||||
@PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')")
|
||||
public List<Dossier> getSoftDeletedDossiers() {
|
||||
|
||||
var dossiers = dossierManagementService.getSoftDeletedDossiers()
|
||||
var dossiers = dossierManagementService.getSoftDeletedDossiers()
|
||||
.stream()
|
||||
.map(dossierACLService::enhanceDossierWithACLData)
|
||||
.collect(Collectors.toList());
|
||||
@ -463,7 +462,7 @@ public class DossierController implements DossierResource {
|
||||
@PostFilter("hasPermission(filterObject.id, 'Dossier', 'VIEW_OBJECT')")
|
||||
public List<Dossier> getArchivedDossiers() {
|
||||
|
||||
var dossiers = dossierManagementService.getArchivedDossiers()
|
||||
var dossiers = dossierManagementService.getArchivedDossiers()
|
||||
.stream()
|
||||
.map(dossierACLService::enhanceDossierWithACLData)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@ -24,13 +24,15 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier.DossierACLService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ExportDownloadRequest;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.service.DossierTemplateExportService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.service.DossierTemplateImportService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateManagementService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateStatsService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.AuditPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.users.UserService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.external.resource.DossierTemplateResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
|
||||
@ -42,7 +44,6 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplateStats;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplateStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ExportDownloadRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ImportDossierTemplateRequest;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
|
||||
@ -61,7 +62,8 @@ public class DossierTemplateController implements DossierTemplateResource {
|
||||
private final AuditPersistenceService auditPersistenceService;
|
||||
private final DossierManagementService dossierManagementService;
|
||||
private final DossierACLService dossierACLService;
|
||||
private final UserService userService;
|
||||
private final DossierTemplateImportService dossierTemplateImportService;
|
||||
private final DossierTemplateExportService dossierTemplateExportService;
|
||||
|
||||
|
||||
@Override
|
||||
@ -125,7 +127,7 @@ public class DossierTemplateController implements DossierTemplateResource {
|
||||
throw new ConflictException("Can not delete dossier template because there are dossiers based on it");
|
||||
}
|
||||
|
||||
dossierTemplateManagementService.deleteDossierTemplate(dossierTemplateId, userId);
|
||||
dossierTemplateManagementService.softDeleteDossierTemplate(dossierTemplateId, userId);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierTemplateId)
|
||||
@ -150,7 +152,7 @@ public class DossierTemplateController implements DossierTemplateResource {
|
||||
throw new ConflictException("Can not delete dossier template because there are dossiers based on it");
|
||||
}
|
||||
|
||||
dossierTemplateManagementService.deleteDossierTemplate(dossierTemplateId, userId);
|
||||
dossierTemplateManagementService.softDeleteDossierTemplate(dossierTemplateId, userId);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierTemplateId)
|
||||
@ -224,15 +226,16 @@ public class DossierTemplateController implements DossierTemplateResource {
|
||||
|
||||
try {
|
||||
ExportDownloadRequest request = ExportDownloadRequest.builder().dossierTemplateId(dossierTemplateId).userId(KeycloakSecurity.getUserId()).build();
|
||||
var response = dossierTemplateManagementService.prepareExportDownload(request);
|
||||
dossierTemplateManagementService.validateDossierTemplateForDuplicateRanks(request.getDossierTemplateId());
|
||||
String storageId = dossierTemplateExportService.prepareExportDownload(request);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(response.getValue())
|
||||
.objectId(storageId)
|
||||
.category(AuditCategory.DOWNLOAD.name())
|
||||
.message("Export Download was prepared")
|
||||
.details(Map.of("dossierTemplateId", request.getDossierTemplateId()))
|
||||
.build());
|
||||
return new DownloadResponse(response.getValue());
|
||||
return new DownloadResponse(storageId);
|
||||
} catch (FeignException e) {
|
||||
throw processFeignException(e);
|
||||
}
|
||||
@ -265,15 +268,15 @@ public class DossierTemplateController implements DossierTemplateResource {
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.archive(file.getBytes())
|
||||
.build();
|
||||
DossierTemplate loadedDossierTemplate = dossierTemplateManagementService.importDossierTemplate(request);
|
||||
String importedDossierTemplateId = dossierTemplateImportService.importDossierTemplate(request);
|
||||
auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(loadedDossierTemplate.getId())
|
||||
.objectId(importedDossierTemplateId)
|
||||
.category(AuditCategory.DOSSIER_TEMPLATE.name())
|
||||
.message("Dossier template was imported")
|
||||
.details(Map.of("dossierTemplateId", loadedDossierTemplate.getId()))
|
||||
.details(Map.of("dossierTemplateId", importedDossierTemplateId))
|
||||
.build());
|
||||
return convert(loadedDossierTemplate);
|
||||
return convert(dossierTemplateManagementService.getDossierTemplate(importedDossierTemplateId));
|
||||
} catch (IOException e) {
|
||||
throw new BadRequestException(e.getMessage(), e);
|
||||
} catch (FeignException e) {
|
||||
|
||||
@ -37,7 +37,10 @@ public class EntityLogController implements EntityLogResource {
|
||||
|
||||
accessControlService.checkViewPermissionsToDossier(dossierId);
|
||||
accessControlService.validateFileResourceExistence(fileId);
|
||||
return entityLogResponseMapper.toLogResponse(entityLogService.getEntityLog(dossierId, fileId, excludedTypes == null ? new ArrayList<>() : excludedTypes, includeUnprocessed));
|
||||
return entityLogResponseMapper.toLogResponse(entityLogService.getEntityLog(dossierId,
|
||||
fileId,
|
||||
excludedTypes == null ? new ArrayList<>() : excludedTypes,
|
||||
includeUnprocessed));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -276,11 +276,7 @@ public class ManualRedactionController implements ManualRedactionResource {
|
||||
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
|
||||
accessControlService.verifyUserIsMemberOrApprover(dossierId);
|
||||
|
||||
List<ManualAddResponse> responseList = manualRedactionService.addRecategorization(dossierId,
|
||||
fileId,
|
||||
dossier,
|
||||
recategorizationRequests,
|
||||
includeUnprocessed);
|
||||
List<ManualAddResponse> responseList = manualRedactionService.addRecategorization(dossierId, fileId, dossier, recategorizationRequests, includeUnprocessed);
|
||||
|
||||
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
|
||||
@ -27,34 +27,37 @@ public class DownloadControllerV2 implements DownloadResource {
|
||||
private final DownloadController downloadController;
|
||||
private final DownloadStatusPersistenceService downloadStatusPersistenceService;
|
||||
|
||||
|
||||
@Transactional
|
||||
public DownloadStatusList getDownloadStatusList() {
|
||||
|
||||
var downloads = downloadStatusPersistenceService.getStatusesByUser(KeycloakSecurity.getUserId());
|
||||
|
||||
return new DownloadStatusList(downloads.stream().map(
|
||||
status ->
|
||||
DownloadStatus.builder()
|
||||
.id(status.getUuid()) // This is a workaround the real id is the storageId.
|
||||
.userId(status.getUserId())
|
||||
.filename(status.getFilename())
|
||||
.mimeType(status.getMimeType())
|
||||
.errorCause(status.getErrorCause())
|
||||
.status(status.getStatus())
|
||||
.creationDate(status.getCreationDate())
|
||||
.lastDownload(status.getLastDownload())
|
||||
.fileSize(status.getFileSize())
|
||||
.dossierId(status.getDossier() != null ? status.getDossier().getId() : null)
|
||||
.fileIds(status.getFiles()
|
||||
.stream()
|
||||
.map(FileEntity::getId)
|
||||
.toList())
|
||||
.downloadFileTypes(status.getDownloadFileTypes()
|
||||
.stream()
|
||||
.toList())
|
||||
.reportTemplateIds(status.getReports().stream().map(ReportTemplateEntity::getTemplateId).toList())
|
||||
.build()).toList()
|
||||
);
|
||||
return new DownloadStatusList(downloads.stream()
|
||||
.map(status -> DownloadStatus.builder()
|
||||
.id(status.getUuid()) // This is a workaround the real id is the storageId.
|
||||
.userId(status.getUserId())
|
||||
.filename(status.getFilename())
|
||||
.mimeType(status.getMimeType())
|
||||
.errorCause(status.getErrorCause())
|
||||
.status(status.getStatus())
|
||||
.creationDate(status.getCreationDate())
|
||||
.lastDownload(status.getLastDownload())
|
||||
.fileSize(status.getFileSize())
|
||||
.dossierId(status.getDossier() != null ? status.getDossier().getId() : null)
|
||||
.fileIds(status.getFiles()
|
||||
.stream()
|
||||
.map(FileEntity::getId)
|
||||
.toList())
|
||||
.downloadFileTypes(status.getDownloadFileTypes()
|
||||
.stream()
|
||||
.toList())
|
||||
.reportTemplateIds(status.getReports()
|
||||
.stream()
|
||||
.map(ReportTemplateEntity::getTemplateId)
|
||||
.toList())
|
||||
.build())
|
||||
.toList());
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +84,10 @@ public class DownloadControllerV2 implements DownloadResource {
|
||||
.downloadFileTypes(status.getDownloadFileTypes()
|
||||
.stream()
|
||||
.toList())
|
||||
.reportTemplateIds(status.getReports().stream().map(ReportTemplateEntity::getTemplateId).toList())
|
||||
.reportTemplateIds(status.getReports()
|
||||
.stream()
|
||||
.map(ReportTemplateEntity::getTemplateId)
|
||||
.toList())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@ -34,11 +34,13 @@ public interface ComponentMapper {
|
||||
|
||||
List<ComponentLogEntryValue> toComponentLogEntries(List<ComponentValue> values);
|
||||
|
||||
|
||||
Component toComponent(ComponentLogEntry entry);
|
||||
|
||||
|
||||
List<Component> toComponents(List<ComponentLogEntry> entries);
|
||||
|
||||
|
||||
ComponentLogEntry toComponentLogEntry(Component component);
|
||||
|
||||
|
||||
|
||||
@ -49,9 +49,7 @@ public interface ComponentLogResource {
|
||||
@PostMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Adds overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void addOverride(@PathVariable(DOSSIER_ID) String dossierId,
|
||||
@PathVariable(FILE_ID) String fileId,
|
||||
@RequestBody ComponentsOverrides componentsOverrides);
|
||||
void addOverride(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody ComponentsOverrides componentsOverrides);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ -59,8 +57,7 @@ public interface ComponentLogResource {
|
||||
@GetMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Gets overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
|
||||
ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId,
|
||||
@PathVariable(FILE_ID) String fileId);
|
||||
ComponentsOverrides getOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ -68,8 +65,6 @@ public interface ComponentLogResource {
|
||||
@PostMapping(value = COMPONENT_LOG_PATH + OVERRIDE_PATH + "/revert" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Reverts overrides for components", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found"), @ApiResponse(responseCode = "403", description = "Forbidden")})
|
||||
void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId,
|
||||
@PathVariable(FILE_ID) String fileId,
|
||||
@RequestBody RevertOverrideRequest revertOverrideRequest);
|
||||
void revertOverrides(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RevertOverrideRequest revertOverrideRequest);
|
||||
|
||||
}
|
||||
|
||||
@ -55,7 +55,9 @@ public interface EntityLogResource {
|
||||
@GetMapping(value = ENTITY_LOG_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE + "/pages", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Gets the entity log for a fileId with all entities found on the given page numbers", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "The dossier / file / entity log is not found.")})
|
||||
EntityLogResponse getEntityLogWithEntriesOnPages(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestParam(value = "pageNumbers", defaultValue = "") List<Integer> pageNumbers);
|
||||
EntityLogResponse getEntityLogWithEntriesOnPages(@PathVariable(DOSSIER_ID) String dossierId,
|
||||
@PathVariable(FILE_ID) String fileId,
|
||||
@RequestParam(value = "pageNumbers", defaultValue = "") List<Integer> pageNumbers);
|
||||
|
||||
|
||||
@GetMapping(value = ENTITY_LOG_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE + ANALYSIS_NUMBER_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
|
||||
@ -56,15 +56,15 @@ public interface SupportResource {
|
||||
@PostMapping(value = REANALYSIS_REST_PATH + DOSSIER_TEMPLATE_DOSSIER_TEMPLATE_ID_PATH_VARIABLE)
|
||||
@Operation(summary = "Reanalyze all files in dossier template", description = """
|
||||
## Reanalyze Files Endpoint
|
||||
|
||||
|
||||
Use this endpoint to reanalyze all files in a specified Dossier Template. The reanalysis process can be tailored using various filtering options provided in the request body.
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
- **DossierTemplateId**: Specifies the Dossier Template whose files need to be reanalyzed.
|
||||
|
||||
|
||||
### Request Body Configuration Options
|
||||
|
||||
|
||||
- **dossierIds**: List of dossier IDs to filter. If empty, all dossiers are selected for reanalysis.
|
||||
- **fileIds**: List of file IDs to filter. If empty, all files are selected for reanalysis.
|
||||
- **repeatStructureAnalysis**: Boolean. If true, layout parsing and named entity recognition will be repeated.
|
||||
@ -120,16 +120,16 @@ public interface SupportResource {
|
||||
+ DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Exports all dossiers and files from a given Dossier Template.", description = """
|
||||
## Export Files Endpoint
|
||||
|
||||
|
||||
Use this endpoint to export a full Dossier Template, including all configurations, dossiers, and files.
|
||||
The endpoint returns a String storageId, which is used to query the DownloadController for the export zip archive's status and to download the archive.
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
|
||||
- **DossierTemplateId**: Specifies the Dossier Template to be exported.
|
||||
|
||||
|
||||
### Request Body Configuration Options
|
||||
|
||||
|
||||
- **dossierIds**: List of dossier IDs to filter. If empty, all dossiers are selected.
|
||||
- **fileIds**: List of file IDs to filter. If empty, all files are selected.
|
||||
- **excludeLayoutFiles**: Boolean. If true, excludes DOCUMENT_STRUCTURE/_PAGES/_TEXT/_POSITIONS, SIMPLIFIED_TEXT, and NER_ENTITIES files.
|
||||
|
||||
@ -22,4 +22,5 @@ public class BulkDownloadRequest {
|
||||
private Set<DownloadFileType> downloadFileTypes = new HashSet<>();
|
||||
private String redactionPreviewColor;
|
||||
private List<String> fileIds = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
@ -19,4 +19,5 @@ public class ComponentOverrideList {
|
||||
String fileId;
|
||||
|
||||
List<Component> componentOverrides = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
@ -14,5 +14,6 @@ import lombok.NoArgsConstructor;
|
||||
@AllArgsConstructor
|
||||
public class DossierAttributeDefinitionList {
|
||||
|
||||
private List<DossierAttributeDefinition> dossierAttributeDefinitions= new ArrayList<>();
|
||||
private List<DossierAttributeDefinition> dossierAttributeDefinitions = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
@ -15,4 +15,5 @@ import lombok.NoArgsConstructor;
|
||||
public class DossierStatusDefinitionList {
|
||||
|
||||
private List<DossierStatusDefinition> dossierStatusDefinitions = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
@ -89,8 +89,8 @@ public interface DossierResource {
|
||||
@Operation(summary = "Update or set attributes for a specific dossier.", description = "None")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Dossier attributes successfully updated."), @ApiResponse(responseCode = "404", description = "Not found")})
|
||||
void setDossierAttributes(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of a dossier template", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
|
||||
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of a dossier", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@RequestBody DossierAttributes dossierAttributes);
|
||||
@Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of a dossier", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
|
||||
@RequestBody DossierAttributes dossierAttributes);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
|
||||
@ -415,7 +415,7 @@ paths:
|
||||
post:
|
||||
operationId: uploadMapping
|
||||
summary: Upload a new component mapping to a DossierTemplate.
|
||||
description: |
|
||||
description: |
|
||||
Use this endpoint to upload a new component mapping to a specific DossierTemplate.
|
||||
|
||||
#### File Requirements
|
||||
@ -434,7 +434,7 @@ paths:
|
||||
- The component mapping file can be utilized in component rules to relate components to existing master data.
|
||||
|
||||
#### Example
|
||||
|
||||
|
||||
| search_value | mapped_value |
|
||||
|--------------|--------------|
|
||||
| Alice | Manager |
|
||||
@ -595,9 +595,9 @@ paths:
|
||||
- Component Definitions
|
||||
summary: Create new component definitions
|
||||
description: |
|
||||
Create new component definitions for a given dossier template. The component will have a technical name which is automatically converted to snake case
|
||||
that can't be updated after the creation. The rank is used to determine the order in which the components are displayed. The component's rank will
|
||||
automatically be appended at the end based on the current number of components of this dossier template.
|
||||
Create new component definitions for a given dossier template. The component will have a technical name which is automatically converted to snake case
|
||||
that can't be updated after the creation. The rank is used to determine the order in which the components are displayed. The component's rank will
|
||||
automatically be appended at the end based on the current number of components of this dossier template.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/dossierTemplateId'
|
||||
requestBody:
|
||||
@ -890,7 +890,7 @@ paths:
|
||||
summary: Retrieve a list of dossiers based on a specific dossier template.
|
||||
description: |
|
||||
By default, this endpoint provides a list of all *active* dossiers that are based on a specific dossier template.
|
||||
|
||||
|
||||
It returns an object containing an array of dossier objects under the key `dossiers`. Each dossier object contains
|
||||
an identifier, a name, a description, an owner, and other fields with further details about the dossier.
|
||||
|
||||
@ -2184,7 +2184,7 @@ components:
|
||||
A toggle to determine the deletion mode for a dossier:
|
||||
- `true`: The dossier will be permanently deleted and can't be restored.
|
||||
- `false` (default): Soft-delete, allowing restoration within the application-configured retention period.
|
||||
|
||||
|
||||
Using this parameter, you can also permanently delete a previously soft-deleted dossier during its retention period.
|
||||
|
||||
> **Note:** Deleting a dossier also deletes all associated files.
|
||||
@ -2202,7 +2202,7 @@ components:
|
||||
- `true`: The file will be permanently deleted and can't be restored.
|
||||
- `false` (default): Soft-delete, allowing restoration within the retention period, provided its parent dossier
|
||||
hasn't been deleted. If the parent dossier has been deleted meanwhile, it needs to be restored first.
|
||||
|
||||
|
||||
Using this parameter, you can also permanently delete a previously soft-deleted file during its retention period.
|
||||
permanentlyDeleteFiles:
|
||||
name: deletePermanently
|
||||
@ -3324,7 +3324,7 @@ components:
|
||||
- a0044ae9-ddca-4f97-b0a1-3cb2517dbf39
|
||||
- c2e33246-e50a-4c43-831c-6789a5637db8
|
||||
- 6123fa16-6943-4b74-8524-54b0046a0ce6
|
||||
approverIds: []
|
||||
approverIds: [ ]
|
||||
reportTemplateIds:
|
||||
- daadea5f-917b-482a-b7d2-e65afe8f80ca
|
||||
- 8130acf6-4910-4123-827c-caacd8111402
|
||||
@ -3495,7 +3495,7 @@ components:
|
||||
- technicalName
|
||||
- displayName
|
||||
ComponentDefinitionUpdateRequest:
|
||||
description: |
|
||||
description: |
|
||||
The ComponentDefinitionUpdateRequest object represents a request to update a component definition within a dossier template.
|
||||
Only the display name and description can be updated.
|
||||
example:
|
||||
@ -4627,10 +4627,10 @@ components:
|
||||
authorizationCode:
|
||||
authorizationUrl: /auth/realms/{workspaceId}/protocol/openid-connect/auth
|
||||
tokenUrl: /auth/realms/{workspaceId}/protocol/openid-connect/token
|
||||
scopes: {}
|
||||
scopes: { }
|
||||
password:
|
||||
tokenUrl: /auth/realms/{workspaceId}/protocol/openid-connect/token
|
||||
scopes: {}
|
||||
scopes: { }
|
||||
clientCredentials:
|
||||
tokenUrl: /auth/realms/{workspaceId}/protocol/openid-connect/token
|
||||
scopes: {}
|
||||
scopes: { }
|
||||
@ -31,7 +31,7 @@ servers:
|
||||
- url: https://app.redactmanager.com
|
||||
description: RedactManager Cloud Service
|
||||
security:
|
||||
- FF-OAUTH: []
|
||||
- FF-OAUTH: [ ]
|
||||
tags:
|
||||
- name: 1. Dossier Templates
|
||||
description: Operations related to dossier templates.
|
||||
@ -258,7 +258,7 @@ paths:
|
||||
summary: Retrieve a list of dossiers based on a specific dossier template.
|
||||
description: |
|
||||
By default, this endpoint provides a list of all *active* dossiers that are based on a specific dossier template.
|
||||
|
||||
|
||||
It returns an object containing an array of dossier objects under the key `dossiers`. Each dossier object contains
|
||||
an identifier, a name, a description, an owner, and other fields with further details about the dossier.
|
||||
|
||||
@ -1309,7 +1309,7 @@ components:
|
||||
A toggle to determine the deletion mode for a dossier:
|
||||
- `true`: The dossier will be permanently deleted and can't be restored.
|
||||
- `false` (default): Soft-delete, allowing restoration within the application-configured retention period.
|
||||
|
||||
|
||||
Using this parameter, you can also permanently delete a previously soft-deleted dossier during its retention period.
|
||||
|
||||
> **Note:** Deleting a dossier also deletes all associated files.
|
||||
@ -1327,7 +1327,7 @@ components:
|
||||
- `true`: The file will be permanently deleted and can't be restored.
|
||||
- `false` (default): Soft-delete, allowing restoration within the retention period, provided its parent dossier
|
||||
hasn't been deleted. If the parent dossier has been deleted meanwhile, it needs to be restored first.
|
||||
|
||||
|
||||
Using this parameter, you can also permanently delete a previously soft-deleted file during its retention period.
|
||||
permanentlyDeleteFiles:
|
||||
name: deletePermanently
|
||||
@ -3171,10 +3171,10 @@ components:
|
||||
authorizationCode:
|
||||
authorizationUrl: /auth/realms/{workspaceId}/protocol/openid-connect/auth
|
||||
tokenUrl: /auth/realms/{workspaceId}/protocol/openid-connect/token
|
||||
scopes: {}
|
||||
scopes: { }
|
||||
password:
|
||||
tokenUrl: /auth/realms/{workspaceId}/protocol/openid-connect/token
|
||||
scopes: {}
|
||||
scopes: { }
|
||||
clientCredentials:
|
||||
tokenUrl: /auth/realms/{workspaceId}/protocol/openid-connect/token
|
||||
scopes: {}
|
||||
scopes: { }
|
||||
@ -1,6 +1,5 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -253,12 +253,12 @@ public class MessagingConfiguration {
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "persistence-service", name = "migrateOnly", havingValue = "false")
|
||||
public Queue ocrResponseQueue() {
|
||||
|
||||
return QueueBuilder.durable(OCR_RESPONSE_QUEUE)
|
||||
.build();
|
||||
return QueueBuilder.durable(OCR_RESPONSE_QUEUE).build();
|
||||
}
|
||||
|
||||
|
||||
@ -266,8 +266,7 @@ public class MessagingConfiguration {
|
||||
@ConditionalOnProperty(prefix = "persistence-service", name = "migrateOnly", havingValue = "false")
|
||||
public Queue ocrDLQ() {
|
||||
|
||||
return QueueBuilder.durable(OCR_DLQ)
|
||||
.build();
|
||||
return QueueBuilder.durable(OCR_DLQ).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBro
|
||||
|
||||
}
|
||||
|
||||
|
||||
private Optional<String> extractTenantId(Message<?> message) {
|
||||
|
||||
StompHeaderAccessor sha = StompHeaderAccessor.wrap(message);
|
||||
|
||||
@ -11,6 +11,7 @@ import com.iqser.red.service.persistence.management.v1.processor.dataexchange.mo
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierCreatorService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.CreateOrUpdateDossierRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
|
||||
|
||||
|
||||
@ -100,18 +100,17 @@ public class DossierTemplateExportService {
|
||||
RabbitTemplate rabbitTemplate;
|
||||
|
||||
|
||||
public JSONPrimitive<String> prepareExportDownload(ExportDownloadRequest request) {
|
||||
public String prepareExportDownload(ExportDownloadRequest request) {
|
||||
|
||||
var mimeType = "application/zip";
|
||||
|
||||
dossierTemplatePersistenceService.validateDossierTemplateForDuplicateRanks(request.getDossierTemplateId());
|
||||
String downloadFilename = request.getDossierTemplateId() + ".zip";
|
||||
String storageId = StorageIdUtils.getStorageId(request.getUserId(), request.getDossierTemplateId());
|
||||
|
||||
downloadStatusPersistenceService.createStatus(request.getUserId(), storageId, downloadFilename, mimeType);
|
||||
addToExportDownloadQueue(ExportDownloadMessage.builder().dossierTemplateId(request.getDossierTemplateId()).storageId(storageId).userId(request.getUserId()).build(), 1);
|
||||
|
||||
return new JSONPrimitive<>(storageId);
|
||||
return storageId;
|
||||
}
|
||||
|
||||
|
||||
@ -123,6 +122,7 @@ public class DossierTemplateExportService {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Observed(name = "DossierTemplateExportService", contextualName = "export-dossier-template")
|
||||
public long createDownloadArchive(ExportDownloadMessage downloadJob) throws IOException {
|
||||
|
||||
@ -142,6 +142,7 @@ public class DossierTemplateExportService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Observed(name = "DossierTemplateExportService", contextualName = "write-dossier-template-to-archive")
|
||||
public void addDossierTemplateToArchive(FileSystemBackedArchiver fileSystemBackedArchiver, String folder, DossierTemplateEntity dossierTemplate) throws IOException {
|
||||
|
||||
|
||||
@ -21,6 +21,11 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ComponentMappingImportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ImportTemplateResult;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.TemplateImportInfo;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.zipreaders.DossierTemplateArchiveReader;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.zipreaders.ZipEntryIterator;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.ColorsEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.FileAttributesGeneralConfigurationEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.WatermarkEntity;
|
||||
@ -29,15 +34,12 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierStatusEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileAttributeConfigEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.ReportTemplateEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ComponentMappingImportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ImportTemplateResult;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.TemplateImportInfo;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.zipreaders.DossierTemplateArchiveReader;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.zipreaders.ZipEntryIterator;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ColorsService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ComponentMappingService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateManagementService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ReportTemplateService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.RulesValidationService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.WatermarkService;
|
||||
@ -56,11 +58,14 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.WatermarkMo
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentDefinition;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentDefinitionAddRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.component.ComponentMappingMetadata;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierAttributeConfig;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplate;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplateStatus;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.ReportTemplateUploadRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.Colors;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.CreateOrUpdateDossierStatusRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierStatusInfo;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeConfig;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ImportDossierTemplateRequest;
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsValidation;
|
||||
import com.iqser.red.storage.commons.service.StorageService;
|
||||
@ -84,6 +89,7 @@ public class DossierTemplateImportService {
|
||||
LegalBasisMappingPersistenceService legalBasisMappingPersistenceService;
|
||||
RulesPersistenceService rulesPersistenceService;
|
||||
DossierTemplatePersistenceService dossierTemplatePersistenceService;
|
||||
DossierTemplateManagementService dossierTemplateManagementService;
|
||||
DossierAttributeConfigPersistenceService dossierAttributeConfigPersistenceService;
|
||||
FileAttributeConfigPersistenceService fileAttributeConfigPersistenceService;
|
||||
ColorsService colorsService;
|
||||
@ -121,11 +127,13 @@ public class DossierTemplateImportService {
|
||||
return dossierTemplateArchiveReader.buildResult();
|
||||
}
|
||||
|
||||
|
||||
@Observed(name = "DossierTemplateImportService", contextualName = "import-template")
|
||||
public TemplateImportInfo importDossierTemplate(ImportTemplateResult request) {
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
String dossierTemplateId;
|
||||
String dossierTemplateId = null;
|
||||
|
||||
var dossierTemplateMeta = request.getDossierTemplate();
|
||||
|
||||
TemplateImportInfo templateImportInfo = TemplateImportInfo.builder().build();
|
||||
@ -137,220 +145,277 @@ public class DossierTemplateImportService {
|
||||
}
|
||||
|
||||
if (existingDossierTemplate != null) {
|
||||
dossierTemplateId = existingDossierTemplate.getId();
|
||||
dossierTemplateId = updateExistingDossierTemplate(request, existingDossierTemplate, dossierTemplateMeta, templateImportInfo);
|
||||
templateImportInfo.setDossierTemplateId(dossierTemplateId);
|
||||
|
||||
// override the existing dossier template
|
||||
updateDossierTemplateMeta(existingDossierTemplate, dossierTemplateMeta, request.getUserId());
|
||||
dossierTemplateRepository.save(existingDossierTemplate);
|
||||
long elapsedTime = System.currentTimeMillis() - start;
|
||||
log.info("Finished update of existing dossier template in {} ms for: {}", elapsedTime, dossierTemplateId);
|
||||
return templateImportInfo;
|
||||
}
|
||||
|
||||
existingDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(existingDossierTemplate)
|
||||
.name()));
|
||||
try {
|
||||
importNewDossierTemplate(request, dossierTemplateMeta, templateImportInfo);
|
||||
long elapsedTime = System.currentTimeMillis() - start;
|
||||
log.info("Finished import dossier template in {} ms for: {}", elapsedTime, templateImportInfo.getDossierTemplateId());
|
||||
|
||||
// set colors
|
||||
this.setColors(dossierTemplateId, request.getColors());
|
||||
|
||||
// set watermarks
|
||||
if (CollectionUtils.isNotEmpty(request.getWatermarks())) {
|
||||
Set<String> toSetWatermarks = request.getWatermarks()
|
||||
.stream()
|
||||
.map(WatermarkModel::getName)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
var currentWatermarkConfigs = watermarkService.getWatermarksForDossierTemplateId(dossierTemplateId);
|
||||
Set<WatermarkEntity> configsToRemove = currentWatermarkConfigs.stream()
|
||||
.filter(c -> !toSetWatermarks.contains(c.getName()))
|
||||
.collect(Collectors.toSet());
|
||||
var watermarkNameToEntity = currentWatermarkConfigs.stream()
|
||||
.collect(Collectors.toMap(WatermarkEntity::getName, Function.identity()));
|
||||
|
||||
request.getWatermarks()
|
||||
.forEach(watermark -> {
|
||||
log.info("watermark to add: " + watermark.getName());
|
||||
Long initialId = watermark.getId();
|
||||
if (!watermarkNameToEntity.isEmpty() && watermarkNameToEntity.get(watermark.getName()) != null) {
|
||||
|
||||
watermark.setId(watermarkNameToEntity.get(watermark.getName()).getId());
|
||||
} else {
|
||||
watermark.setId(null);
|
||||
}
|
||||
watermark.setDossierTemplateId(dossierTemplateId);
|
||||
var entity = watermarkService.createOrUpdateWatermark(watermark);
|
||||
templateImportInfo.getLongMapping().put(initialId, entity.getId());
|
||||
});
|
||||
configsToRemove.forEach(watermark -> watermarkService.deleteWatermark(watermark.getId()));
|
||||
} catch (Exception e) {
|
||||
log.error("Error with message: {} occurred during import, undo import", e.getMessage(), e);
|
||||
if (templateImportInfo != null && templateImportInfo.getDossierTemplateId() != null) {
|
||||
dossierTemplateManagementService.deleteDossierTemplateCompletely(templateImportInfo.getDossierTemplateId());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
// dossier status
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierStatusInfos())) {
|
||||
this.updateDossierStates(request, dossierTemplateId);
|
||||
} else { // no states to add, delete current states
|
||||
List<DossierStatusInfo> currentStates = dossierStatusPersistenceService.getAllDossierStatusForTemplate(dossierTemplateId);
|
||||
currentStates.forEach(state -> dossierStatusPersistenceService.deleteDossierStatus(state.getId(), null));
|
||||
}
|
||||
return templateImportInfo;
|
||||
}
|
||||
|
||||
// update dossier attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierAttributesConfigs())) {
|
||||
this.updateDossierAttributes(request, dossierTemplateId, templateImportInfo);
|
||||
} else { // no dossier attributes to add, but delete existing ones
|
||||
var currentConfigs = dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId);
|
||||
currentConfigs.forEach(da -> dossierAttributeConfigPersistenceService.deleteDossierAttribute(da.getId()));
|
||||
}
|
||||
|
||||
//update file attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getFileAttributesConfigs())) {
|
||||
this.updateFileAttributes(request, dossierTemplateId, templateImportInfo);
|
||||
} else { // no file attributes to add, but delete existing
|
||||
var currentConfigs = fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId);
|
||||
currentConfigs.forEach(fa -> fileAttributeConfigPersistenceService.deleteFileAttribute(fa.getId()));
|
||||
}
|
||||
private void importNewDossierTemplate(ImportTemplateResult request, DossierTemplate dossierTemplateMeta, TemplateImportInfo templateImportInfo) {
|
||||
|
||||
entityTypeImportService.updateTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
|
||||
String dossierTemplateId;
|
||||
// creates new dossier template
|
||||
if (StringUtils.isEmpty(dossierTemplateMeta.getName())) {
|
||||
throw new ConflictException("DossierTemplate name must be set");
|
||||
}
|
||||
this.validateDossierTemplateName(dossierTemplateMeta);
|
||||
DossierTemplateEntity dossierTemplateEntity = new DossierTemplateEntity();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
|
||||
this.updateComponents(request, dossierTemplateId);
|
||||
} else { // no components to add, but remove existing ones
|
||||
List<ComponentDefinitionEntity> currentComponents = componentDefinitionPersistenceService.findComponentsByDossierTemplateId(dossierTemplateId);
|
||||
this.deleteComponents(currentComponents);
|
||||
}
|
||||
// order is important
|
||||
BeanUtils.copyProperties(dossierTemplateMeta, dossierTemplateEntity);
|
||||
dossierTemplateEntity.setId(UUID.randomUUID().toString());
|
||||
dossierTemplateEntity.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
dossierTemplateEntity.setCreatedBy(request.getUserId());
|
||||
//set rules
|
||||
|
||||
//set report templates
|
||||
var existingReports = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplateId);
|
||||
var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplateEntity);
|
||||
loadedDossierTemplate.setDossierTemplateStatus(dossierTemplatePersistenceService.computeDossierTemplateStatus(loadedDossierTemplate));
|
||||
dossierTemplateId = loadedDossierTemplate.getId();
|
||||
templateImportInfo.setDossierTemplateId(dossierTemplateId);
|
||||
// set colors
|
||||
this.updateColors(dossierTemplateId, request.getColors());
|
||||
|
||||
List<String> reportsUpdated = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(request.getReportTemplateUploadRequests())) {
|
||||
request.getReportTemplateUploadRequests()
|
||||
.forEach(reportRequest -> {
|
||||
reportRequest.setDossierTemplateId(dossierTemplateId);
|
||||
var report = reportTemplateService.uploadTemplate(reportRequest);
|
||||
reportsUpdated.add(report.getTemplateId());
|
||||
});
|
||||
}
|
||||
|
||||
// delete the reports that were not in the import
|
||||
existingReports.forEach(r -> {
|
||||
String storageId = r.getStorageId();
|
||||
if (!reportsUpdated.contains(r.getTemplateId())) {
|
||||
storageService.deleteObject(TenantContext.getTenantId(), storageId);
|
||||
reportTemplatePersistenceService.delete(r.getTemplateId());
|
||||
}
|
||||
});
|
||||
|
||||
// set legal basis
|
||||
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
|
||||
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
|
||||
} else { // delete existing
|
||||
legalBasisMappingPersistenceService.deleteLegalBasis(dossierTemplateId);
|
||||
}
|
||||
|
||||
} else {
|
||||
// creates new dossier template
|
||||
if (StringUtils.isEmpty(dossierTemplateMeta.getName())) {
|
||||
throw new ConflictException("DossierTemplate name must be set");
|
||||
}
|
||||
this.validateDossierTemplateName(dossierTemplateMeta);
|
||||
DossierTemplateEntity dossierTemplateEntity = new DossierTemplateEntity();
|
||||
|
||||
// order is important
|
||||
BeanUtils.copyProperties(dossierTemplateMeta, dossierTemplateEntity);
|
||||
dossierTemplateEntity.setId(UUID.randomUUID().toString());
|
||||
dossierTemplateEntity.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
dossierTemplateEntity.setCreatedBy(request.getUserId());
|
||||
//set rules
|
||||
|
||||
var loadedDossierTemplate = dossierTemplateRepository.save(dossierTemplateEntity);
|
||||
loadedDossierTemplate.setDossierTemplateStatus(dossierTemplatePersistenceService.computeDossierTemplateStatus(loadedDossierTemplate));
|
||||
|
||||
dossierTemplateId = loadedDossierTemplate.getId();
|
||||
// set colors
|
||||
this.setColors(dossierTemplateId, request.getColors());
|
||||
|
||||
// set watermarks
|
||||
if (CollectionUtils.isNotEmpty(request.getWatermarks())) {
|
||||
request.getWatermarks()
|
||||
.forEach(watermark -> {
|
||||
Long initialId = watermark.getId();
|
||||
watermark.setDossierTemplateId(dossierTemplateId);
|
||||
watermark.setId(null);
|
||||
var en = watermarkService.createOrUpdateWatermark(watermark);
|
||||
templateImportInfo.getLongMapping().put(initialId, en.getId());
|
||||
});
|
||||
}
|
||||
|
||||
// dossier status
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierStatusInfos())) {
|
||||
request.getDossierStatusInfos()
|
||||
.forEach(state -> {
|
||||
state.setId(null);
|
||||
this.updateDossierStatus(dossierTemplateId, state);
|
||||
});
|
||||
}
|
||||
|
||||
//set dossier attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierAttributesConfigs())) {
|
||||
request.getDossierAttributesConfigs()
|
||||
.forEach(da -> {
|
||||
String initialId = da.getId();
|
||||
da.setId(null); // in order to create a new dossier attribute
|
||||
var e = dossierAttributeConfigPersistenceService.addOrUpdateDossierAttribute(dossierTemplateId, convert(da, DossierAttributeConfigEntity.class));
|
||||
templateImportInfo.getIdMapping().put(initialId, e.getId());
|
||||
});
|
||||
}
|
||||
|
||||
//set file attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getFileAttributesConfigs())) {
|
||||
request.getFileAttributesConfigs()
|
||||
.forEach(fa -> {
|
||||
String initialId = fa.getId();
|
||||
fa.setId(null); // in order to force creation of new file attribute
|
||||
var e = fileAttributeConfigPersistenceService.addOrUpdateFileAttribute(dossierTemplateId, convert(fa, FileAttributeConfigEntity.class));
|
||||
templateImportInfo.getIdMapping().put(initialId, e.getId());
|
||||
});
|
||||
}
|
||||
|
||||
//set types
|
||||
entityTypeImportService.importEntityTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
|
||||
|
||||
// set components
|
||||
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
|
||||
for (ComponentDefinition componentDefinition : request.getComponentDefinitions()) {
|
||||
ComponentDefinitionAddRequest componentDefinitionAddRequest = ComponentDefinitionAddRequest.builder()
|
||||
.displayName(componentDefinition.getDisplayName())
|
||||
.description(componentDefinition.getDescription())
|
||||
.technicalName(componentDefinition.getTechnicalName())
|
||||
.build();
|
||||
componentDefinitionPersistenceService.insert(componentDefinitionAddRequest, componentDefinition.getRank(), dossierTemplateId);
|
||||
}
|
||||
}
|
||||
|
||||
//set report templates
|
||||
if (CollectionUtils.isNotEmpty(request.getReportTemplateUploadRequests())) {
|
||||
request.getReportTemplateUploadRequests()
|
||||
.forEach(reportRequest -> {
|
||||
reportRequest.setDossierTemplateId(dossierTemplateId);
|
||||
reportTemplateService.uploadTemplate(reportRequest);
|
||||
});
|
||||
}
|
||||
// set legal basis
|
||||
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
|
||||
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
|
||||
// set watermarks
|
||||
if (CollectionUtils.isNotEmpty(request.getWatermarks())) {
|
||||
for (WatermarkModel watermark : request.getWatermarks()) {
|
||||
Long initialId = watermark.getId();
|
||||
watermark.setDossierTemplateId(dossierTemplateId);
|
||||
watermark.setId(null);
|
||||
var en = watermarkService.createOrUpdateWatermark(watermark);
|
||||
templateImportInfo.getLongMapping().put(initialId, en.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// dossier status
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierStatusInfos())) {
|
||||
for (DossierStatusInfo state : request.getDossierStatusInfos()) {
|
||||
state.setId(null);
|
||||
this.updateDossierStatus(dossierTemplateId, state);
|
||||
}
|
||||
}
|
||||
|
||||
//set dossier attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierAttributesConfigs())) {
|
||||
for (DossierAttributeConfig da : request.getDossierAttributesConfigs()) {
|
||||
String initialId = da.getId();
|
||||
da.setId(null); // in order to create a new dossier attribute
|
||||
var e = dossierAttributeConfigPersistenceService.addOrUpdateDossierAttribute(dossierTemplateId, convert(da, DossierAttributeConfigEntity.class));
|
||||
templateImportInfo.getIdMapping().put(initialId, e.getId());
|
||||
}
|
||||
}
|
||||
|
||||
//set file attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getFileAttributesConfigs())) {
|
||||
for (FileAttributeConfig fa : request.getFileAttributesConfigs()) {
|
||||
String initialId = fa.getId();
|
||||
fa.setId(null); // in order to force creation of new file attribute
|
||||
var e = fileAttributeConfigPersistenceService.addOrUpdateFileAttribute(dossierTemplateId, convert(fa, FileAttributeConfigEntity.class));
|
||||
templateImportInfo.getIdMapping().put(initialId, e.getId());
|
||||
}
|
||||
}
|
||||
|
||||
//set types
|
||||
entityTypeImportService.importEntityTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
|
||||
|
||||
// set components
|
||||
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
|
||||
for (ComponentDefinition componentDefinition : request.getComponentDefinitions()) {
|
||||
ComponentDefinitionAddRequest componentDefinitionAddRequest = ComponentDefinitionAddRequest.builder()
|
||||
.displayName(componentDefinition.getDisplayName())
|
||||
.description(componentDefinition.getDescription())
|
||||
.technicalName(componentDefinition.getTechnicalName())
|
||||
.build();
|
||||
componentDefinitionPersistenceService.insert(componentDefinitionAddRequest, componentDefinition.getRank(), dossierTemplateId);
|
||||
}
|
||||
}
|
||||
|
||||
//set report templates
|
||||
if (CollectionUtils.isNotEmpty(request.getReportTemplateUploadRequests())) {
|
||||
for (ReportTemplateUploadRequest reportRequest : request.getReportTemplateUploadRequests()) {
|
||||
reportRequest.setDossierTemplateId(dossierTemplateId);
|
||||
reportTemplateService.uploadTemplate(reportRequest);
|
||||
}
|
||||
}
|
||||
// set legal basis
|
||||
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
|
||||
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
|
||||
}
|
||||
setRulesWhenCompiled(request, dossierTemplateId);
|
||||
setComponentMappings(dossierTemplateId, request.getComponentMappings());
|
||||
setFileAttributeGeneralConfig(request, dossierTemplateId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void setFileAttributeGeneralConfig(ImportTemplateResult request, String dossierTemplateId) {
|
||||
// file attribute general configuration
|
||||
if (request.getFileAttributesGeneralConfiguration() != null) {
|
||||
fileAttributeConfigPersistenceService.setFileAttributesGeneralConfig(dossierTemplateId,
|
||||
convert(request.getFileAttributesGeneralConfiguration(),
|
||||
FileAttributesGeneralConfigurationEntity.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String updateExistingDossierTemplate(ImportTemplateResult request,
|
||||
DossierTemplateEntity existingDossierTemplate,
|
||||
DossierTemplate dossierTemplateMeta,
|
||||
TemplateImportInfo templateImportInfo) {
|
||||
|
||||
String dossierTemplateId;
|
||||
dossierTemplateId = existingDossierTemplate.getId();
|
||||
updateDossierTemplateMeta(existingDossierTemplate, dossierTemplateMeta, request.getUserId());
|
||||
dossierTemplateRepository.save(existingDossierTemplate);
|
||||
existingDossierTemplate.setDossierTemplateStatus(DossierTemplateStatus.valueOf(dossierTemplatePersistenceService.computeDossierTemplateStatus(existingDossierTemplate)
|
||||
.name()));
|
||||
updateColors(dossierTemplateId, request.getColors());
|
||||
updateWatermarks(request, templateImportInfo, dossierTemplateId);
|
||||
updateDossiers(request, dossierTemplateId);
|
||||
updateDossierAttributes(request, templateImportInfo, dossierTemplateId);
|
||||
updateFileAttributes(request, templateImportInfo, dossierTemplateId);
|
||||
entityTypeImportService.updateTypes(dossierTemplateId, null, request.getEntityTypeImportModel());
|
||||
updateComponents(request, dossierTemplateId);
|
||||
var existingReports = reportTemplatePersistenceService.findByDossierTemplateId(dossierTemplateId);
|
||||
updateReports(request, dossierTemplateId, existingReports);
|
||||
updateLegalBasis(request, dossierTemplateId);
|
||||
setRulesWhenCompiled(request, dossierTemplateId);
|
||||
setComponentMappings(dossierTemplateId, request.getComponentMappings());
|
||||
setFileAttributeGeneralConfig(request, dossierTemplateId);
|
||||
return dossierTemplateId;
|
||||
}
|
||||
|
||||
templateImportInfo.setDossierTemplateId(dossierTemplateId);
|
||||
|
||||
long elapsedTime = System.currentTimeMillis() - start;
|
||||
log.info("Finished import dossier template : {} for: {}", elapsedTime, dossierTemplateId);
|
||||
return templateImportInfo;
|
||||
private void updateLegalBasis(ImportTemplateResult request, String dossierTemplateId) {
|
||||
// set legal basis
|
||||
if (CollectionUtils.isNotEmpty(request.getLegalBases())) {
|
||||
legalBasisMappingPersistenceService.setLegalBasisMapping(dossierTemplateId, request.getLegalBases());
|
||||
} else { // delete existing
|
||||
legalBasisMappingPersistenceService.deleteLegalBasis(dossierTemplateId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateReports(ImportTemplateResult request, String dossierTemplateId, List<ReportTemplateEntity> existingReports) {
|
||||
|
||||
List<String> reportsUpdated = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(request.getReportTemplateUploadRequests())) {
|
||||
for (ReportTemplateUploadRequest reportRequest : request.getReportTemplateUploadRequests()) {
|
||||
reportRequest.setDossierTemplateId(dossierTemplateId);
|
||||
var report = reportTemplateService.uploadTemplate(reportRequest);
|
||||
reportsUpdated.add(report.getTemplateId());
|
||||
}
|
||||
}
|
||||
|
||||
// delete the reports that were not in the import
|
||||
existingReports.forEach(r -> {
|
||||
String storageId = r.getStorageId();
|
||||
if (!reportsUpdated.contains(r.getTemplateId())) {
|
||||
storageService.deleteObject(TenantContext.getTenantId(), storageId);
|
||||
reportTemplatePersistenceService.delete(r.getTemplateId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void updateComponents(ImportTemplateResult request, String dossierTemplateId) {
|
||||
|
||||
if (CollectionUtils.isNotEmpty(request.getComponentDefinitions())) {
|
||||
request.getComponentDefinitions()
|
||||
.forEach(componentDefinition -> {
|
||||
componentDefinition.setDossierTemplateId(dossierTemplateId);
|
||||
componentDefinitionPersistenceService.insert(MagicConverter.convert(componentDefinition, ComponentDefinitionEntity.class));
|
||||
});
|
||||
} else { // no components to add, but remove existing ones
|
||||
List<ComponentDefinitionEntity> currentComponents = componentDefinitionPersistenceService.findComponentsByDossierTemplateId(dossierTemplateId);
|
||||
currentComponents.forEach(componentDefinition -> {
|
||||
componentDefinitionPersistenceService.delete(componentDefinition.getId());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateFileAttributes(ImportTemplateResult request, TemplateImportInfo templateImportInfo, String dossierTemplateId) {
|
||||
//update file attributes
|
||||
if (CollectionUtils.isNotEmpty(request.getFileAttributesConfigs())) {
|
||||
this.updateFileAttributes(request, dossierTemplateId, templateImportInfo);
|
||||
} else { // no file attributes to add, but delete existing
|
||||
var currentConfigs = fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId);
|
||||
currentConfigs.forEach(fa -> fileAttributeConfigPersistenceService.deleteFileAttribute(fa.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateWatermarks(ImportTemplateResult request, TemplateImportInfo templateImportInfo, String dossierTemplateId) {
|
||||
// set watermarks
|
||||
if (CollectionUtils.isNotEmpty(request.getWatermarks())) {
|
||||
Set<String> toSetWatermarks = request.getWatermarks()
|
||||
.stream()
|
||||
.map(WatermarkModel::getName)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
var currentWatermarkConfigs = watermarkService.getWatermarksForDossierTemplateId(dossierTemplateId);
|
||||
Set<WatermarkEntity> configsToRemove = currentWatermarkConfigs.stream()
|
||||
.filter(c -> !toSetWatermarks.contains(c.getName()))
|
||||
.collect(Collectors.toSet());
|
||||
var watermarkNameToEntity = currentWatermarkConfigs.stream()
|
||||
.collect(Collectors.toMap(WatermarkEntity::getName, Function.identity()));
|
||||
|
||||
for (WatermarkModel watermarkModel : request.getWatermarks()) {
|
||||
log.info("watermark to add: " + watermarkModel.getName());
|
||||
Long initialId = watermarkModel.getId();
|
||||
if (!watermarkNameToEntity.isEmpty() && watermarkNameToEntity.get(watermarkModel.getName()) != null) {
|
||||
|
||||
watermarkModel.setId(watermarkNameToEntity.get(watermarkModel.getName()).getId());
|
||||
} else {
|
||||
watermarkModel.setId(null);
|
||||
}
|
||||
watermarkModel.setDossierTemplateId(dossierTemplateId);
|
||||
var entity = watermarkService.createOrUpdateWatermark(watermarkModel);
|
||||
templateImportInfo.getLongMapping().put(initialId, entity.getId());
|
||||
}
|
||||
configsToRemove.forEach(watermark -> watermarkService.deleteWatermark(watermark.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateDossiers(ImportTemplateResult request, String dossierTemplateId) {
|
||||
// dossier status
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierStatusInfos())) {
|
||||
this.updateDossierStates(request, dossierTemplateId);
|
||||
} else { // no states to add, delete current states
|
||||
List<DossierStatusInfo> currentStates = dossierStatusPersistenceService.getAllDossierStatusForTemplate(dossierTemplateId);
|
||||
currentStates.forEach(state -> dossierStatusPersistenceService.deleteDossierStatus(state.getId(), null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateDossierAttributes(ImportTemplateResult request, TemplateImportInfo templateImportInfo, String dossierTemplateId) {
|
||||
|
||||
if (CollectionUtils.isNotEmpty(request.getDossierAttributesConfigs())) {
|
||||
this.updateDossierAttributes(request, dossierTemplateId, templateImportInfo);
|
||||
} else { // no dossier attributes to add, but delete existing ones
|
||||
var currentConfigs = dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId);
|
||||
currentConfigs.forEach(da -> dossierAttributeConfigPersistenceService.deleteDossierAttribute(da.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -434,7 +499,7 @@ public class DossierTemplateImportService {
|
||||
}
|
||||
|
||||
|
||||
private void setColors(String dossierTemplateId, Colors requestedColors) {
|
||||
private void updateColors(String dossierTemplateId, Colors requestedColors) {
|
||||
// set colors
|
||||
if (requestedColors != null) {
|
||||
ColorsEntity colorsEntity = convert(requestedColors, ColorsEntity.class);
|
||||
@ -529,24 +594,6 @@ public class DossierTemplateImportService {
|
||||
}
|
||||
|
||||
|
||||
private void updateComponents(ImportTemplateResult request, String dossierTemplateId) {
|
||||
|
||||
request.getComponentDefinitions()
|
||||
.forEach(componentDefinition -> {
|
||||
componentDefinition.setDossierTemplateId(dossierTemplateId);
|
||||
componentDefinitionPersistenceService.insert(MagicConverter.convert(componentDefinition, ComponentDefinitionEntity.class));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void deleteComponents(List<ComponentDefinitionEntity> componentDefinitionEntities) {
|
||||
|
||||
componentDefinitionEntities.forEach(componentDefinition -> {
|
||||
componentDefinitionPersistenceService.delete(componentDefinition.getId());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void validateDossierTemplateName(DossierTemplate dossierTemplateMeta) {
|
||||
|
||||
int nameSuffix = 0;
|
||||
|
||||
@ -41,6 +41,7 @@ public class EntityTypeExportService {
|
||||
ObjectMapper mapper;
|
||||
EntryPersistenceService entryPersistenceService;
|
||||
|
||||
|
||||
@Observed(name = "EntityTypeExportService", contextualName = "export-entity-type")
|
||||
public void addEntityTypeToArchive(FileSystemBackedArchiver fileSystemBackedArchiver, TypeEntity typeEntity, String folder) throws JsonProcessingException {
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import com.iqser.red.service.persistence.management.v1.processor.dataexchange.mo
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.TemplateImportInfo;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.ReportTemplateEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateManagementService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.ImportResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
|
||||
@ -32,6 +33,7 @@ public class FileExchangeImportService {
|
||||
FileExchangeArchivalService fileExchangeArchivalService;
|
||||
ReportTemplatePersistenceService reportTemplateService;
|
||||
ObservationRegistry registry;
|
||||
DossierTemplateManagementService dossierTemplateManagementService;
|
||||
|
||||
|
||||
@Observed(name = "FileExchangeImportService", contextualName = "import-files")
|
||||
@ -68,11 +70,18 @@ public class FileExchangeImportService {
|
||||
.stream()
|
||||
.map(ReportTemplateEntity::getTemplateId)
|
||||
.toList();
|
||||
|
||||
for (Dossier dossierToImport : fileExchangeImportModel.getDossiers()) {
|
||||
dossierImportService.importDossier(fileExchangeImportModel, userId, dossierToImport, templateImportInfo, allReportTemplateIds);
|
||||
try {
|
||||
for (Dossier dossierToImport : fileExchangeImportModel.getDossiers()) {
|
||||
dossierImportService.importDossier(fileExchangeImportModel, userId, dossierToImport, templateImportInfo, allReportTemplateIds);
|
||||
}
|
||||
return templateImportInfo.getDossierTemplateId();
|
||||
} catch (Exception e) {
|
||||
log.error("Error with message {} ocurred, deleting imported dossier template again.", e.getMessage());
|
||||
if (templateImportInfo.getDossierTemplateId() != null) {
|
||||
dossierTemplateManagementService.deleteDossierTemplateCompletely(templateImportInfo.getDossierTemplateId());
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return templateImportInfo.getDossierTemplateId();
|
||||
}
|
||||
|
||||
|
||||
@ -90,5 +99,4 @@ public class FileExchangeImportService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -39,29 +39,29 @@ public class ManualChangesExportService {
|
||||
|
||||
ManualChangesExportModel exportModel = new ManualChangesExportModel();
|
||||
exportModel.setManualAddExportModels(addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.all())
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
exportModel.setManualRemoveExportModels(removeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.all())
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
exportModel.setManualForceExportModels(forceRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.all())
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
exportModel.setManualLegalBasisChangeExportModels(legalBasisChangePersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.all())
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
exportModel.setManualRecategorizationExportModels(recategorizationPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.all())
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
exportModel.setManualResizeExportModels(resizeRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.all())
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
.stream()
|
||||
.map(mapper::toModel)
|
||||
.toList());
|
||||
return exportModel;
|
||||
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ public class ZipEntryIterator implements Iterator<ZipEntryData>, AutoCloseable {
|
||||
|
||||
double compressionRatio = (double) totalSizeEntry / nextEntry.getCompressedSize();
|
||||
if (compressionRatio > compressionThresholdRatio) {
|
||||
throw new BadRequestException("ZIP-Bomb detected (compressionRatio). " + compressionRatio + "/" + compressionThresholdRatio );
|
||||
throw new BadRequestException("ZIP-Bomb detected (compressionRatio). " + compressionRatio + "/" + compressionThresholdRatio);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
|
||||
@ -4,7 +4,6 @@ import java.io.Serializable;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -2,6 +2,8 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
@ -9,9 +11,6 @@ import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.annotations;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -3,6 +3,8 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.annotat
|
||||
import java.io.Serializable;
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
@ -11,9 +13,6 @@ import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -4,6 +4,8 @@ import java.time.OffsetDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONMapConverter;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
@ -13,9 +15,6 @@ import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONMapConverter;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -4,7 +4,6 @@ import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -8,7 +8,6 @@ import jakarta.persistence.Id;
|
||||
import jakarta.persistence.PrePersist;
|
||||
import jakarta.persistence.PreUpdate;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -6,7 +6,6 @@ import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -6,7 +6,6 @@ import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
@ -7,9 +9,6 @@ import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.DigitalSignatureType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.DigitalSignatureType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.configuration;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.MapsId;
|
||||
import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -2,7 +2,6 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.configu
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Embeddable;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -3,11 +3,15 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.configu
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -2,6 +2,9 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.configu
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
@ -9,10 +12,6 @@ import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -2,6 +2,11 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.configu
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.HorizontalTextAlignment;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.VerticalTextAlignment;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.WatermarkOrientation;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
@ -13,12 +18,6 @@ import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierTemplateEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.HorizontalTextAlignment;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.VerticalTextAlignment;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.WatermarkOrientation;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -4,8 +4,6 @@ import java.time.OffsetDateTime;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.UniqueConstraint;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.dossier;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributeType;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
@ -7,9 +9,6 @@ import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierAttributeType;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -7,7 +7,6 @@ import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -6,6 +6,17 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.WatermarkEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONDownloadFileTypeConverter;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONStringSetConverter;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierVisibility;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
@ -19,18 +30,6 @@ import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.WatermarkEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONDownloadFileTypeConverter;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONStringSetConverter;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DownloadFileType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.DossierVisibility;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -3,6 +3,9 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.dossier
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
@ -11,10 +14,6 @@ import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.dossier;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeType;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
@ -7,10 +10,6 @@ import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeType;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -7,7 +7,6 @@ import jakarta.persistence.Embeddable;
|
||||
import jakarta.persistence.EmbeddedId;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@ -4,6 +4,8 @@ import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
@ -11,9 +13,6 @@ import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -1,17 +1,21 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.entity.download;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionResultDetail;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONDownloadRedactionFileDetailsConverter;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
@Builder
|
||||
|
||||
@ -2,13 +2,12 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.index;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.utils.SuppressFBWarnings;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -6,7 +6,6 @@ import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -2,7 +2,12 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.migrati
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.SaasMigrationStatus;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -4,6 +4,8 @@ import java.time.OffsetDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONMapConverter;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
@ -12,11 +14,7 @@ import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.SequenceGenerator;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.JSONMapConverter;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -3,18 +3,17 @@ package com.iqser.red.service.persistence.management.v1.processor.entity.notific
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.EmailNotificationType;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.notification.EmailNotificationType;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@ -7,7 +7,6 @@ import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.IdClass;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@ -2,8 +2,6 @@ package com.iqser.red.service.persistence.management.v1.processor.jobs;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.*;
|
||||
|
||||
import org.quartz.CronExpression;
|
||||
import org.quartz.CronScheduleBuilder;
|
||||
import org.quartz.JobBuilder;
|
||||
@ -13,6 +11,15 @@ import org.quartz.TriggerBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.AnalysisFlagCalculationSchedulerJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.AutomaticAnalysisJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.DeletedFilesCleanupJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.DownloadCleanupJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.DownloadReadyJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.KeyCloakUserSyncJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.SendNotificationEmailJob;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.job.SyncUserPermissionsJob;
|
||||
|
||||
@Configuration
|
||||
public class CreateJobsConfiguration {
|
||||
|
||||
|
||||
@ -13,4 +13,5 @@ import lombok.NoArgsConstructor;
|
||||
public class LifecycleProperties {
|
||||
|
||||
private String basePackage;
|
||||
|
||||
}
|
||||
@ -8,6 +8,12 @@ import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualAddExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualForceExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualLegalBasisChangeExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualRecategorizationExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualRemoveExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualResizeExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.AnnotationEntityId;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.IdRemovalEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualForceRedactionEntity;
|
||||
@ -16,12 +22,6 @@ import com.iqser.red.service.persistence.management.v1.processor.entity.annotati
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualResizeRedactionEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualAddExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualForceExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualLegalBasisChangeExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualRecategorizationExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualRemoveExportModel;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.manualchanges.ManualResizeExportModel;
|
||||
|
||||
@Mapper
|
||||
public interface ManualChangesExportMapper {
|
||||
@ -74,7 +74,8 @@ public interface ManualChangesExportMapper {
|
||||
@AfterMapping
|
||||
default void setFileStatusAndId(ManualLegalBasisChangeExportModel model,
|
||||
@MappingTarget ManualLegalBasisChangeEntity.ManualLegalBasisChangeEntityBuilder entity,
|
||||
@Context FileEntity file, @Context String userId) {
|
||||
@Context FileEntity file,
|
||||
@Context String userId) {
|
||||
|
||||
AnnotationEntityId annotationEntityId = new AnnotationEntityId(model.getAnnotationId(), file.getId());
|
||||
entity.id(annotationEntityId);
|
||||
@ -86,7 +87,8 @@ public interface ManualChangesExportMapper {
|
||||
@AfterMapping
|
||||
default void setFileStatusAndId(ManualRecategorizationExportModel model,
|
||||
@MappingTarget ManualRecategorizationEntity.ManualRecategorizationEntityBuilder entity,
|
||||
@Context FileEntity file, @Context String userId) {
|
||||
@Context FileEntity file,
|
||||
@Context String userId) {
|
||||
|
||||
AnnotationEntityId annotationEntityId = new AnnotationEntityId(model.getAnnotationId(), file.getId());
|
||||
entity.id(annotationEntityId);
|
||||
@ -96,7 +98,10 @@ public interface ManualChangesExportMapper {
|
||||
|
||||
|
||||
@AfterMapping
|
||||
default void setFileStatusAndId(ManualAddExportModel model, @MappingTarget ManualRedactionEntryEntity.ManualRedactionEntryEntityBuilder entity, @Context FileEntity file, @Context String userId) {
|
||||
default void setFileStatusAndId(ManualAddExportModel model,
|
||||
@MappingTarget ManualRedactionEntryEntity.ManualRedactionEntryEntityBuilder entity,
|
||||
@Context FileEntity file,
|
||||
@Context String userId) {
|
||||
|
||||
AnnotationEntityId annotationEntityId = new AnnotationEntityId(model.getAnnotationId(), file.getId());
|
||||
entity.id(annotationEntityId);
|
||||
@ -106,7 +111,10 @@ public interface ManualChangesExportMapper {
|
||||
|
||||
|
||||
@AfterMapping
|
||||
default void setFileStatusAndId(ManualResizeExportModel model, @MappingTarget ManualResizeRedactionEntity.ManualResizeRedactionEntityBuilder entity, @Context FileEntity file, @Context String userId) {
|
||||
default void setFileStatusAndId(ManualResizeExportModel model,
|
||||
@MappingTarget ManualResizeRedactionEntity.ManualResizeRedactionEntityBuilder entity,
|
||||
@Context FileEntity file,
|
||||
@Context String userId) {
|
||||
|
||||
AnnotationEntityId annotationEntityId = new AnnotationEntityId(model.getAnnotationId(), file.getId());
|
||||
entity.id(annotationEntityId);
|
||||
@ -116,7 +124,10 @@ public interface ManualChangesExportMapper {
|
||||
|
||||
|
||||
@AfterMapping
|
||||
default void setFileStatusAndId(ManualForceExportModel model, @MappingTarget ManualForceRedactionEntity.ManualForceRedactionEntityBuilder entity, @Context FileEntity file, @Context String userId) {
|
||||
default void setFileStatusAndId(ManualForceExportModel model,
|
||||
@MappingTarget ManualForceRedactionEntity.ManualForceRedactionEntityBuilder entity,
|
||||
@Context FileEntity file,
|
||||
@Context String userId) {
|
||||
|
||||
AnnotationEntityId annotationEntityId = new AnnotationEntityId(model.getAnnotationId(), file.getId());
|
||||
entity.id(annotationEntityId);
|
||||
|
||||
@ -18,4 +18,5 @@ public class ComponentOverride {
|
||||
|
||||
String name;
|
||||
List<ComponentLogEntryValue> componentOverrideValues = new ArrayList<>();
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
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.ManualRedactionEntry;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@ -21,7 +21,9 @@ public class AnalyseEvent {
|
||||
private int numberOfPagesToOCR;
|
||||
private int numberOfOCRedPages;
|
||||
|
||||
|
||||
public AnalyseEvent(String dossierId, String fileId, AnalyseStatus analyseStatus, Integer analysisNumber, OffsetDateTime timestamp) {
|
||||
|
||||
this.dossierId = dossierId;
|
||||
this.fileId = fileId;
|
||||
this.analyseStatus = analyseStatus;
|
||||
|
||||
@ -10,6 +10,8 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DossierEvent {
|
||||
|
||||
private String dossierId;
|
||||
private DossierEventType dossierEventType;
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.model.websocket;
|
||||
|
||||
public enum DossierEventType {
|
||||
CREATE, UPDATE, SOFT_DELETE, HARD_DELETE, UNDELETE, ARCHIVE, UNARCHIVE
|
||||
CREATE,
|
||||
UPDATE,
|
||||
SOFT_DELETE,
|
||||
HARD_DELETE,
|
||||
UNDELETE,
|
||||
ARCHIVE,
|
||||
UNARCHIVE
|
||||
}
|
||||
|
||||
@ -16,4 +16,5 @@ public class DownloadEvent {
|
||||
private String downloadId;
|
||||
private String userId;
|
||||
private DownloadStatusValue status;
|
||||
|
||||
}
|
||||
|
||||
@ -15,5 +15,4 @@ public class FileEvent {
|
||||
private String fileId;
|
||||
private FileEventType fileEventType;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.model.websocket;
|
||||
|
||||
public enum FileEventType {
|
||||
CREATE, UPDATE, SOFT_DELETE, HARD_DELETE, UNDELETE
|
||||
CREATE,
|
||||
UPDATE,
|
||||
SOFT_DELETE,
|
||||
HARD_DELETE,
|
||||
UNDELETE
|
||||
}
|
||||
|
||||
@ -12,4 +12,5 @@ import lombok.NoArgsConstructor;
|
||||
public class NotificationEvent {
|
||||
|
||||
private String userId;
|
||||
|
||||
}
|
||||
|
||||
@ -222,6 +222,13 @@ public class ComponentMappingService {
|
||||
}
|
||||
|
||||
|
||||
public void deleteByDossierTemplateId(String dossierTemplateId) {
|
||||
|
||||
componentMappingPersistenceService.getByDossierTemplateId(dossierTemplateId)
|
||||
.forEach(cm -> componentMappingPersistenceService.deleteById(dossierTemplateId, cm.getId()));
|
||||
}
|
||||
|
||||
|
||||
private static class CSVSorter implements Comparator<String[]> {
|
||||
|
||||
@Override
|
||||
|
||||
@ -33,6 +33,7 @@ import com.iqser.red.service.persistence.management.v1.processor.utils.TypeMappe
|
||||
import com.iqser.red.service.persistence.management.v1.processor.validation.DictionaryValidator;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.Type;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.TypeRankSummary;
|
||||
import com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
@ -237,10 +238,11 @@ public class DictionaryManagementService {
|
||||
|
||||
@Transactional
|
||||
public void addEntries(String typeId, List<String> entries, boolean removeCurrent, boolean ignoreInvalidEntries, DictionaryEntryType dictionaryEntryType) {
|
||||
|
||||
addEntries(typeId, entries, removeCurrent, ignoreInvalidEntries, dictionaryEntryType, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Transactional
|
||||
public void addEntries(String typeId, List<String> entries, boolean removeCurrent, boolean ignoreInvalidEntries, DictionaryEntryType dictionaryEntryType, boolean isImport) {
|
||||
|
||||
@ -403,6 +405,12 @@ public class DictionaryManagementService {
|
||||
}
|
||||
|
||||
|
||||
public void hardDeleteByDossierTemplateId(String dossierTemplateId) {
|
||||
|
||||
dictionaryPersistenceService.hardDeleteTypesByDossierTemplateId(dossierTemplateId);
|
||||
}
|
||||
|
||||
|
||||
public long getCurrentVersion(String typeId) {
|
||||
|
||||
Type typeResult = MagicConverter.convert(dictionaryPersistenceService.getType(typeId), Type.class);
|
||||
@ -432,4 +440,10 @@ public class DictionaryManagementService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public List<TypeRankSummary> getTypeRankSummaryList(String dossierTemplateId) {
|
||||
|
||||
return dictionaryPersistenceService.getTypeRankSummaryList(dossierTemplateId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -132,7 +132,8 @@ public class DictionaryService {
|
||||
if (entriesToDelete != null && !entriesToDelete.isEmpty()) {
|
||||
deleteGlobalEntries(type, dossierTemplateId, entriesToDelete, dictionaryEntryType);
|
||||
}
|
||||
if (entriesToAdd != null && !entriesToAdd.isEmpty() && !entriesToAdd.stream().allMatch(String::isEmpty)) {
|
||||
if (entriesToAdd != null && !entriesToAdd.isEmpty() && !entriesToAdd.stream()
|
||||
.allMatch(String::isEmpty)) {
|
||||
addGlobalEntries(type, dossierTemplateId, entriesToAdd, false, dictionaryEntryType);
|
||||
}
|
||||
}
|
||||
@ -150,7 +151,8 @@ public class DictionaryService {
|
||||
if (entriesToDelete != null && !entriesToDelete.isEmpty()) {
|
||||
deleteDossierEntries(type, dossierTemplateId, entriesToDelete, dossierId, dictionaryEntryType);
|
||||
}
|
||||
if (entriesToAdd != null && !entriesToAdd.isEmpty() && !entriesToAdd.stream().allMatch(String::isEmpty)) {
|
||||
if (entriesToAdd != null && !entriesToAdd.isEmpty() && !entriesToAdd.stream()
|
||||
.allMatch(String::isEmpty)) {
|
||||
addDossierEntries(type, dossierTemplateId, entriesToAdd, false, dossierId, dictionaryEntryType);
|
||||
}
|
||||
}
|
||||
@ -487,6 +489,7 @@ public class DictionaryService {
|
||||
return MagicConverter.convert(colorsService.getColors(dossierTemplateId), Colors.class);
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('" + ADD_UPDATE_DICTIONARY_TYPE + "')")
|
||||
public void changeAddToDictionary(String type, String dossierTemplateId, String dossierId, boolean addToDictionary) {
|
||||
|
||||
|
||||
@ -44,6 +44,14 @@ public class DossierDeletionService {
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void deleteAllDossiersInTemplate(String dossierId) {
|
||||
|
||||
fileDeletionService.hardDeleteFilesAndDataByDossierId(dossierId);
|
||||
dossierService.hardDeleteDossier(dossierId);
|
||||
}
|
||||
|
||||
|
||||
public void hardDeleteFileDataAndIndexUpdates(String dossierId, List<String> fileIds) {
|
||||
|
||||
fileDeletionService.hardDeleteFileDataAndIndexUpdates(dossierId, fileIds);
|
||||
|
||||
@ -23,6 +23,7 @@ public class DossierIdFileIdRequestValidator {
|
||||
DossierManagementService dossierManagementService;
|
||||
FileStatusManagementService fileStatusManagementService;
|
||||
|
||||
|
||||
@Observed(name = "DossierIdFileIdRequestValidator", contextualName = "validate-request")
|
||||
public void validateRequestOrThrow404(String dossierTemplateId, Set<String> dossierIds, Set<String> fileIds) {
|
||||
|
||||
|
||||
@ -64,8 +64,9 @@ public class DossierManagementService {
|
||||
|
||||
List<FileModel> fileStatuses = fileStatusService.getDossierStatus(dossierId);
|
||||
var relevantFileIds = fileStatuses.stream()
|
||||
.filter(fileStatus -> fileStatus.getDeleted() == null).map(FileModel::getId).toList();
|
||||
|
||||
.filter(fileStatus -> fileStatus.getDeleted() == null)
|
||||
.map(FileModel::getId)
|
||||
.toList();
|
||||
|
||||
dossierDeletionService.softDeleteDossier(dossierId, relevantFileIds, now);
|
||||
fileDeletionService.reindexDeletedFiles(dossierId, relevantFileIds);
|
||||
@ -119,6 +120,7 @@ public class DossierManagementService {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public Set<String> getAllDossierIdsForDossierTemplateId(String dossierTemplateId) {
|
||||
|
||||
@ -208,7 +210,10 @@ public class DossierManagementService {
|
||||
|
||||
for (String dossierId : dossierIds) {
|
||||
|
||||
List<String> fileIds = fileStatusService.getDossierStatus(dossierId).stream().map(FileModel::getId).collect(Collectors.toList());
|
||||
List<String> fileIds = fileStatusService.getDossierStatus(dossierId)
|
||||
.stream()
|
||||
.map(FileModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
dossierDeletionService.hardDeleteDossier(dossierId, fileIds);
|
||||
dossierDeletionService.hardDeleteFileDataAndIndexUpdates(dossierId, fileIds);
|
||||
}
|
||||
@ -221,10 +226,13 @@ public class DossierManagementService {
|
||||
for (String dossierId : dossierIds) {
|
||||
var dossier = dossierService.getDossierById(dossierId);
|
||||
List<FileModel> fileStatuses = fileStatusService.getDossierStatus(dossierId);
|
||||
var relevantFileIds = fileStatuses.stream().filter(fileStatus -> fileStatus.getDeleted() != null && (fileStatus.getDeleted().equals(dossier.getSoftDeletedTime()) || fileStatus.getDeleted()
|
||||
.isAfter(dossier.getSoftDeletedTime()))).map(FileModel::getId).collect(Collectors.toList());
|
||||
var relevantFileIds = fileStatuses.stream()
|
||||
.filter(fileStatus -> fileStatus.getDeleted() != null && (fileStatus.getDeleted().equals(dossier.getSoftDeletedTime()) || fileStatus.getDeleted()
|
||||
.isAfter(dossier.getSoftDeletedTime())))
|
||||
.map(FileModel::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
dossierDeletionService.undeleteDossier(dossierId,relevantFileIds,dossier.getSoftDeletedTime());
|
||||
dossierDeletionService.undeleteDossier(dossierId, relevantFileIds, dossier.getSoftDeletedTime());
|
||||
dossierDeletionService.reindexUndeletedFiles(dossier.getDossierTemplateId(), dossierId, relevantFileIds);
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.acl.custom.dossier.DossierACLService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
@ -153,6 +154,7 @@ public class DossierService {
|
||||
return dossierPersistenceService.findAllDossiersForDossierTemplateId(dossierTemplateId);
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getAllDossierIdsForDossierTemplateId(String dossierTemplateId) {
|
||||
|
||||
return dossierPersistenceService.findAllDossierIdsForDossierTemplateId(dossierTemplateId);
|
||||
|
||||
@ -92,7 +92,6 @@ public class DossierTemplateCloneService {
|
||||
}
|
||||
|
||||
DossierTemplateEntity clonedDossierTemplate = DossierTemplateEntity.copyDossierTemplateEntityWithoutChildEntities(dossierTemplate.get());
|
||||
dossierTemplatePersistenceService.validateDossierTemplateForDuplicateRanks(dossierTemplateId);
|
||||
OffsetDateTime now = OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS);
|
||||
clonedDossierTemplate.setId(UUID.randomUUID().toString());
|
||||
clonedDossierTemplate.setName(cloneDossierTemplateRequest.getName());
|
||||
|
||||
@ -3,18 +3,15 @@ package com.iqser.red.service.persistence.management.v1.processor.service;
|
||||
import static com.knecon.fforesight.databasetenantcommons.providers.utils.MagicConverter.convert;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.service.DossierTemplateExportService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.service.DossierTemplateImportService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.CloneDossierTemplateRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.CreateOrUpdateDossierTemplateRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplate;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.dataexchange.models.ExportDownloadRequest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ImportDossierTemplateRequest;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -24,10 +21,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@RequiredArgsConstructor
|
||||
public class DossierTemplateManagementService {
|
||||
|
||||
private final DossierTemplateExportService dossierTemplateExportService;
|
||||
private final DossierTemplateImportService dossierTemplateImportService;
|
||||
private final DossierTemplatePersistenceService dossierTemplatePersistenceService;
|
||||
private final DossierTemplateCloneService dossierTemplateCloneService;
|
||||
private final DossierDeletionService dossierDeletionService;
|
||||
private final DictionaryManagementService dictionaryManagementService;
|
||||
private final ComponentMappingService componentMappingService;
|
||||
|
||||
|
||||
public DossierTemplate createOrUpdateDossierTemplate(CreateOrUpdateDossierTemplateRequest dossierTemplate) {
|
||||
@ -48,29 +46,40 @@ public class DossierTemplateManagementService {
|
||||
}
|
||||
|
||||
|
||||
public void deleteDossierTemplate(String dossierTemplateId, String deletingUserId) {
|
||||
public void deleteDossierTemplateCompletely(String dossierTemplateId) {
|
||||
|
||||
dossierTemplatePersistenceService.deleteDossierTemplate(dossierTemplateId, deletingUserId);
|
||||
dictionaryManagementService.hardDeleteByDossierTemplateId(dossierTemplateId);
|
||||
componentMappingService.deleteByDossierTemplateId(dossierTemplateId);
|
||||
dossierDeletionService.deleteAllDossiersInTemplate(dossierTemplateId);
|
||||
dossierTemplatePersistenceService.deleteDossierTemplate(dossierTemplateId);
|
||||
}
|
||||
|
||||
|
||||
public void softDeleteDossierTemplate(String dossierTemplateId, String userId) {
|
||||
|
||||
dossierTemplatePersistenceService.softDeleteDossierTemplate(dossierTemplateId, userId);
|
||||
}
|
||||
|
||||
|
||||
public DossierTemplate cloneDossierTemplate(String dossierTemplateId, CloneDossierTemplateRequest cloneDossierTemplateRequest) {
|
||||
|
||||
validateDossierTemplateForDuplicateRanks(dossierTemplateId);
|
||||
return convert(dossierTemplateCloneService.cloneDossierTemplate(dossierTemplateId, cloneDossierTemplateRequest), DossierTemplate.class);
|
||||
}
|
||||
|
||||
|
||||
public JSONPrimitive<String> prepareExportDownload(ExportDownloadRequest request) {
|
||||
public void validateDossierTemplateForDuplicateRanks(String dossierTemplateId) {
|
||||
|
||||
return dossierTemplateExportService.prepareExportDownload(request);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public DossierTemplate importDossierTemplate(ImportDossierTemplateRequest request) {
|
||||
|
||||
String dossierTemplateId = dossierTemplateImportService.importDossierTemplate(request);
|
||||
return convert(dossierTemplatePersistenceService.getDossierTemplate(dossierTemplateId), DossierTemplate.class);
|
||||
var duplicateRanks = dictionaryManagementService.getTypeRankSummaryList(dossierTemplateId)
|
||||
.stream()
|
||||
.filter(t -> t.getTypesCount() > 1)
|
||||
.toList();
|
||||
if (!duplicateRanks.isEmpty()) {
|
||||
String errorMessage = "Duplicate ranks found in dossier template " + dossierTemplateId + "\n" + duplicateRanks.stream()
|
||||
.map(t -> String.format(" Rank %d has %d entries", t.getRank(), t.getTypesCount()))
|
||||
.collect(Collectors.joining("\n"));
|
||||
throw new BadRequestException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -37,7 +37,12 @@ public class EntityLogMongoWrapperService {
|
||||
if (includeUnprocessed) {
|
||||
DossierEntity dossier = dossierService.getDossierById(dossierId);
|
||||
ManualRedactions unprocessedManualRedactions = manualRedactionProviderService.getManualRedactions(fileId, ManualChangesQueryOptions.unprocessedOnly(), 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;
|
||||
}
|
||||
@ -47,4 +52,5 @@ public class EntityLogMongoWrapperService {
|
||||
|
||||
return String.format("EntityLogEntry does not exist for annotationId ID \"%s\"!", annotationId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ public class EntityLogService {
|
||||
return entityLog;
|
||||
}
|
||||
|
||||
|
||||
@Observed(name = "EntityLogService", contextualName = "get-entity-log")
|
||||
public EntityLog getEntityLog(String dossierId, String fileId, boolean includeUnProcessed) {
|
||||
|
||||
@ -52,6 +53,8 @@ public class EntityLogService {
|
||||
postProcessEntityLog(dossierId, fileId, entityLog, includeUnProcessed);
|
||||
return entityLog;
|
||||
}
|
||||
|
||||
|
||||
@Observed(name = "EntityLogService", contextualName = "get-entity-log")
|
||||
public EntityLog getEntityLog(String dossierId, String fileId, List<String> excludedTypes, boolean includeUnProcessed) {
|
||||
|
||||
|
||||
@ -16,28 +16,34 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
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.service.persistence.repository.FileAttributesRepository;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
|
||||
import com.iqser.red.service.search.v1.model.IndexMessageType;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
|
||||
public class FileDeletionService {
|
||||
|
||||
private final CommentPersistenceService commentPersistenceService;
|
||||
private final ViewedPagesPersistenceService viewedPagesPersistenceService;
|
||||
private final AddRedactionPersistenceService addRedactionPersistenceService;
|
||||
private final ForceRedactionPersistenceService forceRedactionPersistenceService;
|
||||
private final RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||
private final RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
private final LegalBasisChangePersistenceService legalBasisChangePersistenceService;
|
||||
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||
private final FileStatusPersistenceService fileStatusPersistenceService;
|
||||
private final FileManagementStorageService fileManagementStorageService;
|
||||
private final IndexingService indexingService;
|
||||
CommentPersistenceService commentPersistenceService;
|
||||
ViewedPagesPersistenceService viewedPagesPersistenceService;
|
||||
AddRedactionPersistenceService addRedactionPersistenceService;
|
||||
ForceRedactionPersistenceService forceRedactionPersistenceService;
|
||||
RemoveRedactionPersistenceService removeRedactionPersistenceService;
|
||||
RecategorizationPersistenceService recategorizationPersistenceService;
|
||||
LegalBasisChangePersistenceService legalBasisChangePersistenceService;
|
||||
ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||
FileStatusPersistenceService fileStatusPersistenceService;
|
||||
FileManagementStorageService fileManagementStorageService;
|
||||
IndexingService indexingService;
|
||||
FileAttributesRepository fileAttributesRepository;
|
||||
|
||||
|
||||
@Transactional
|
||||
@ -83,6 +89,8 @@ public class FileDeletionService {
|
||||
private void hardDeleteFileData(String dossierId, List<String> fileIds) {
|
||||
|
||||
fileIds.forEach(fileId -> {
|
||||
fileManagementStorageService.deleteEntityLog(dossierId, fileId);
|
||||
fileManagementStorageService.deleteComponentLog(dossierId, fileId);
|
||||
Arrays.stream(FileType.values())
|
||||
.forEach(fileType -> {
|
||||
try {
|
||||
@ -137,11 +145,22 @@ public class FileDeletionService {
|
||||
// delete all viewed pages for all files
|
||||
viewedPagesPersistenceService.deleteForFiles(fileIds);
|
||||
|
||||
fileAttributesRepository.deleteByFileIds(fileIds);
|
||||
|
||||
fileStatusPersistenceService.hardDeleteFiles(fileIds);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void hardDeleteFilesAndDataByDossierId(String dossierId) {
|
||||
|
||||
List<String> fileIds = fileStatusPersistenceService.getStatusIdsForDossier(dossierId);
|
||||
hardDeleteFileData(dossierId, fileIds);
|
||||
hardDeleteFiles(fileIds);
|
||||
}
|
||||
|
||||
|
||||
public void reindexDeletedFiles(String dossierId, Collection<String> relevantFileIds) {
|
||||
|
||||
relevantFileIds.forEach(fileId -> {
|
||||
|
||||
@ -20,6 +20,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.RedactionLog;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.imported.ImportedRedactions;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionGrid;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.ComponentLogMongoService;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.EntityLogMongoService;
|
||||
import com.iqser.red.storage.commons.exception.StorageException;
|
||||
import com.iqser.red.storage.commons.exception.StorageObjectDoesNotExist;
|
||||
@ -40,6 +41,8 @@ public class FileManagementStorageService {
|
||||
|
||||
private final EntityLogMongoService entityLogMongoService;
|
||||
|
||||
private final ComponentLogMongoService componentLogMongoService;
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public byte[] getStoredObjectBytes(String dossierId, String fileId, FileType fileType) {
|
||||
@ -145,6 +148,7 @@ public class FileManagementStorageService {
|
||||
entityLogMongoService.saveEntityLog(dossierId, fileId, entityLog);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void insertEntityLog(String dossierId, String fileId, EntityLog entityLog) {
|
||||
|
||||
@ -217,6 +221,12 @@ public class FileManagementStorageService {
|
||||
}
|
||||
|
||||
|
||||
public void deleteComponentLog(String dossierId, String fileId) {
|
||||
|
||||
componentLogMongoService.deleteComponentLog(dossierId, fileId);
|
||||
}
|
||||
|
||||
|
||||
public void deleteEntityLog(String dossierId, String fileId) {
|
||||
|
||||
entityLogMongoService.deleteEntityLog(dossierId, fileId);
|
||||
|
||||
@ -38,11 +38,13 @@ public class FileStatusManagementService {
|
||||
return fileStatusService.getAllFiles();
|
||||
}
|
||||
|
||||
|
||||
public List<FileModel> getAllDossierTemplateStatus(String dossierTemplateId) {
|
||||
|
||||
return fileStatusService.getDossierTemplateStatus(dossierTemplateId);
|
||||
}
|
||||
|
||||
|
||||
public List<FileModel> getDossierStatus(String dossierId) {
|
||||
|
||||
return fileStatusService.getDossierStatus(dossierId)
|
||||
@ -52,7 +54,6 @@ public class FileStatusManagementService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<FileModel> getAllDossierStatus(String dossierId) {
|
||||
|
||||
return fileStatusService.getDossierStatus(dossierId);
|
||||
|
||||
@ -95,6 +95,7 @@ public class FileStatusService {
|
||||
|
||||
WebsocketService websocketService;
|
||||
|
||||
|
||||
@Transactional
|
||||
public List<FileModel> getAllRelevantStatusesForReanalysisScheduler() {
|
||||
|
||||
@ -125,6 +126,7 @@ public class FileStatusService {
|
||||
return reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(convertedList);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public List<FileModel> getDossierTemplateStatus(String dossierTemplateId) {
|
||||
|
||||
@ -133,6 +135,7 @@ public class FileStatusService {
|
||||
return reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(convertedList);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public List<FileModel> getAllFiles() {
|
||||
|
||||
@ -141,6 +144,7 @@ public class FileStatusService {
|
||||
return reanalysisRequiredStatusService.enhanceFileStatusWithAnalysisRequirements(convertedList);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public List<FileModel> getAllErrorFiles() {
|
||||
|
||||
@ -202,7 +206,6 @@ public class FileStatusService {
|
||||
var dossier = dossierPersistenceService.getAndValidateDossier(dossierId);
|
||||
var fileEntity = fileStatusPersistenceService.getStatus(fileId);
|
||||
|
||||
|
||||
if (!fileManagementStorageService.objectExists(dossierId, fileId, FileType.ORIGIN)) {
|
||||
addToPreprocessingQueue(dossierId, fileId, fileEntity.getFilename());
|
||||
sendReadOnlyAnalysisEvent(dossierId, fileId, fileEntity);
|
||||
@ -302,14 +305,24 @@ public class FileStatusService {
|
||||
}
|
||||
|
||||
|
||||
private void sendAnalysisEvent(String dossierId, String fileId, FileEntity fileEntity){
|
||||
if(fileEntity.getProcessingStatus().equals(ProcessingStatus.UNPROCESSED) || fileEntity.getProcessingStatus().equals(ProcessingStatus.ERROR) || fileEntity.getProcessingStatus().equals(ProcessingStatus.REPROCESS) || fileEntity.getProcessingStatus().equals(ProcessingStatus.PROCESSED)){
|
||||
private void sendAnalysisEvent(String dossierId, String fileId, FileEntity fileEntity) {
|
||||
|
||||
if (fileEntity.getProcessingStatus().equals(ProcessingStatus.UNPROCESSED)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.ERROR)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.REPROCESS)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.PROCESSED)) {
|
||||
websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.PROCESSING, fileEntity.getNumberOfAnalyses() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendReadOnlyAnalysisEvent(String dossierId, String fileId, FileEntity fileEntity){
|
||||
if(fileEntity.getProcessingStatus().equals(ProcessingStatus.UNPROCESSED) || fileEntity.getProcessingStatus().equals(ProcessingStatus.ERROR) || fileEntity.getProcessingStatus().equals(ProcessingStatus.REPROCESS) || fileEntity.getProcessingStatus().equals(ProcessingStatus.PROCESSED) || fileEntity.getProcessingStatus().equals(ProcessingStatus.OCR_PROCESSING)){
|
||||
|
||||
private void sendReadOnlyAnalysisEvent(String dossierId, String fileId, FileEntity fileEntity) {
|
||||
|
||||
if (fileEntity.getProcessingStatus().equals(ProcessingStatus.UNPROCESSED)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.ERROR)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.REPROCESS)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.PROCESSED)
|
||||
|| fileEntity.getProcessingStatus().equals(ProcessingStatus.OCR_PROCESSING)) {
|
||||
websocketService.sendAnalysisEvent(dossierId, fileId, AnalyseStatus.READ_ONLY_PROCESSING, fileEntity.getNumberOfAnalyses() + 1);
|
||||
}
|
||||
}
|
||||
@ -536,7 +549,8 @@ public class FileStatusService {
|
||||
|
||||
public void setStatusSuccessful(String dossierId, String fileId, AnalyzeResult analyzeResult) {
|
||||
|
||||
fileStatusPersistenceService.updateProcessingStatus(dossierId, fileId,
|
||||
fileStatusPersistenceService.updateProcessingStatus(dossierId,
|
||||
fileId,
|
||||
analyzeResult.getNumberOfPages(),
|
||||
analyzeResult.getDictionaryVersion(),
|
||||
analyzeResult.getRulesVersion(),
|
||||
@ -621,6 +635,7 @@ public class FileStatusService {
|
||||
|
||||
|
||||
public void setStatusIndexingSuccessful(String fileId) {
|
||||
|
||||
fileStatusPersistenceService.setUpdateStatusIndexingSuccessful(fileId);
|
||||
FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId);
|
||||
websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE);
|
||||
@ -642,6 +657,7 @@ public class FileStatusService {
|
||||
|
||||
|
||||
public void updateFileModificationDate(String fileId, OffsetDateTime fileManipulationDate) {
|
||||
|
||||
fileStatusPersistenceService.updateFileModificationDate(fileId, fileManipulationDate);
|
||||
FileEntity fileStatus = fileStatusPersistenceService.getStatus(fileId);
|
||||
websocketService.sendFileEvent(fileStatus.getDossierId(), fileId, FileEventType.UPDATE);
|
||||
|
||||
@ -17,6 +17,7 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.Confl
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierTemplatePersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.WatermarkRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.ColorUtils;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.WatermarkModel;
|
||||
@ -35,7 +36,7 @@ public class WatermarkService {
|
||||
private final static int DEFAULT_OPACITY = 30;
|
||||
private final WatermarkRepository watermarkRepository;
|
||||
private final DossierRepository dossierRepository;
|
||||
private final DossierTemplatePersistenceService dossierTemplatePersistenceService;
|
||||
private final DossierTemplateRepository dossierTemplateRepository;
|
||||
|
||||
|
||||
@Transactional
|
||||
@ -70,7 +71,7 @@ public class WatermarkService {
|
||||
validateWatermarkNameIsUnique(watermark.getName(), loadedWatermark.get().getDossierTemplateId(), loadedWatermark.get().getId());
|
||||
BeanUtils.copyProperties(watermark, loadedWatermark.get(), "dossierTemplateId", "createdBy", "dateAdded", "dateModified");
|
||||
loadedWatermark.get().setDateModified(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
var dossierTemplate = dossierTemplatePersistenceService.getDossierTemplate(loadedWatermark.get().getDossierTemplateId());
|
||||
var dossierTemplate = dossierTemplateRepository.findById(watermark.getDossierTemplateId()).orElseThrow(() -> new NotFoundException("Dossier Template not found"));
|
||||
loadedWatermark.get().setDossierTemplate(dossierTemplate);
|
||||
return loadedWatermark.get();
|
||||
} else { // if not found by id -> add it as a new watermark
|
||||
@ -79,7 +80,7 @@ public class WatermarkService {
|
||||
WatermarkEntity watermarkEntity = new WatermarkEntity();
|
||||
BeanUtils.copyProperties(watermark, watermarkEntity, "id", "dateAdded", "dateModified");
|
||||
watermarkEntity.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
var dossierTemplate = dossierTemplatePersistenceService.getDossierTemplate(watermark.getDossierTemplateId());
|
||||
var dossierTemplate = dossierTemplateRepository.findById(watermark.getDossierTemplateId()).orElseThrow(() -> new NotFoundException("Dossier Template not found"));
|
||||
watermarkEntity.setDossierTemplate(dossierTemplate);
|
||||
return watermarkRepository.save(watermarkEntity);
|
||||
}
|
||||
@ -89,7 +90,7 @@ public class WatermarkService {
|
||||
WatermarkEntity watermarkEntity = new WatermarkEntity();
|
||||
BeanUtils.copyProperties(watermark, watermarkEntity, "id", "dateAdded", "dateModified");
|
||||
watermarkEntity.setDateAdded(OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS));
|
||||
var dossierTemplate = dossierTemplatePersistenceService.getDossierTemplate(watermark.getDossierTemplateId());
|
||||
var dossierTemplate = dossierTemplateRepository.findById(watermark.getDossierTemplateId()).orElseThrow(() -> new NotFoundException("Dossier Template not found"));
|
||||
watermarkEntity.setDossierTemplate(dossierTemplate);
|
||||
return watermarkRepository.save(watermarkEntity);
|
||||
}
|
||||
|
||||
@ -30,33 +30,44 @@ public class WebsocketService {
|
||||
|
||||
public void sendAnalysisEvent(String dossierId, String fileId, AnalyseStatus analyseStatus, int analysisNumber) {
|
||||
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/analysis-events", new AnalyseEvent(dossierId, fileId, analyseStatus, analysisNumber, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)));
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/analysis-events",
|
||||
new AnalyseEvent(dossierId, fileId, analyseStatus, analysisNumber, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS)));
|
||||
}
|
||||
|
||||
|
||||
public void sendOcrUpdateAnalysisEvent(String dossierId, String fileId, AnalyseStatus analyseStatus, int analysisNumber, int numberOfPagesToOCR, int numberOfOCRedPages) {
|
||||
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/analysis-events", new AnalyseEvent(dossierId, fileId, analyseStatus, analysisNumber, OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS), numberOfPagesToOCR, numberOfOCRedPages));
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/analysis-events",
|
||||
new AnalyseEvent(dossierId,
|
||||
fileId,
|
||||
analyseStatus,
|
||||
analysisNumber,
|
||||
OffsetDateTime.now().truncatedTo(ChronoUnit.MILLIS),
|
||||
numberOfPagesToOCR,
|
||||
numberOfOCRedPages));
|
||||
}
|
||||
|
||||
|
||||
public void sendDownloadEvent(String downloadId, String userId, DownloadStatusValue downloadStatusValue){
|
||||
public void sendDownloadEvent(String downloadId, String userId, DownloadStatusValue downloadStatusValue) {
|
||||
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/download-events", new DownloadEvent(downloadId, userId, downloadStatusValue));
|
||||
}
|
||||
|
||||
|
||||
public void sendFileEvent(String dossierId, String fileId, FileEventType fileEventType){
|
||||
public void sendFileEvent(String dossierId, String fileId, FileEventType fileEventType) {
|
||||
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/file-events", new FileEvent(dossierId, fileId, fileEventType));
|
||||
}
|
||||
|
||||
|
||||
public void sendDossierEvent(String dossierId, DossierEventType dossierEventType){
|
||||
public void sendDossierEvent(String dossierId, DossierEventType dossierEventType) {
|
||||
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/dossier-events", new DossierEvent(dossierId, dossierEventType));
|
||||
}
|
||||
|
||||
public void sendNotificationEvent(String userId){
|
||||
|
||||
public void sendNotificationEvent(String userId) {
|
||||
|
||||
template.convertAndSend("/topic/" + TenantContext.getTenantId() + "/notification-events", new NotificationEvent(userId));
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.download;
|
||||
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -47,10 +47,8 @@ import com.iqser.red.service.redaction.report.v1.api.model.StoredFileInformation
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
|
||||
@ -7,7 +7,6 @@ import java.util.stream.Collectors;
|
||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.ReportTemplateEntity;
|
||||
@ -39,7 +38,6 @@ public class DownloadProcessorService {
|
||||
downloadStatusPersistenceService.updateStatus(downloadJob.getStorageId(), DownloadStatusValue.GENERATING);
|
||||
websocketService.sendDownloadEvent(downloadJob.getStorageId(), downloadJob.getUserId(), DownloadStatusValue.GENERATING);
|
||||
|
||||
|
||||
var dossier = dossierService.getDossierById(downloadStatus.getFiles()
|
||||
.iterator().next().getDossierId());
|
||||
|
||||
|
||||
@ -2,18 +2,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service.downlo
|
||||
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration.X_ERROR_INFO_HEADER;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionMessage;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
@ -22,7 +11,17 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionMessage;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.configuration.MessagingConfiguration;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatusValue;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.download;
|
||||
|
||||
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionResultMessage;
|
||||
@ -11,12 +17,6 @@ import lombok.SneakyThrows;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.amqp.AmqpRejectAndDontRequeueException;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
|
||||
@ -2,7 +2,6 @@ package com.iqser.red.service.persistence.management.v1.processor.service.job;
|
||||
|
||||
import static com.iqser.red.service.persistence.management.v1.processor.utils.TenantUtils.isTenantReadyForPersistence;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
|
||||
@ -3,7 +3,6 @@ package com.iqser.red.service.persistence.management.v1.processor.service.job;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileDeletionService;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
@ -12,6 +11,7 @@ import org.springframework.stereotype.Service;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.ApplicationConfigService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.DossierService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileDeletionService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.TenantUtils;
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
@ -62,7 +62,7 @@ public class DeletedFilesCleanupJob implements Job {
|
||||
.isBefore(now.minusHours(applicationConfigurationEntity.getSoftDeleteCleanupTime()))) {
|
||||
|
||||
fileDeletionService.hardDeleteFile(file.getId());
|
||||
fileDeletionService.hardDeleteFileDataAndIndexUpdates(dossierEntity.getId(),file.getId());
|
||||
fileDeletionService.hardDeleteFileDataAndIndexUpdates(dossierEntity.getId(), file.getId());
|
||||
log.info("Hard deleted file with dossier id {} and file id {}", dossierEntity.getId(), file.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.service.job;
|
||||
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.download.DownloadCompressingService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.download.DownloadPreparationService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DownloadStatusPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadRedactionFileStatusRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.TenantUtils;
|
||||
@ -12,11 +16,6 @@ import com.knecon.fforesight.tenantcommons.TenantProvider;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
|
||||
@ -69,17 +69,17 @@ public class ManualRedactionDictionaryUpdateHandler {
|
||||
Set<String> typeIdsOfModifiedDictionaries) {
|
||||
|
||||
List<DictionaryEntry> dictionaryEntriesToUnDelete = dictionaryManagementService.getAllEntriesInDossierTemplate(manualRequestWithAddToDictionary.getDictionaryTypeId(),
|
||||
value,
|
||||
manualRequestWithAddToDictionary.getDictionaryEntryType());
|
||||
value,
|
||||
manualRequestWithAddToDictionary.getDictionaryEntryType());
|
||||
dictionaryEntriesToUnDelete.forEach(entry -> {
|
||||
typeIdsOfModifiedDictionaries.add(entry.getTypeId());
|
||||
addToDictionary(entry.getTypeId(), value, manualRequestWithAddToDictionary.getDossierId(), fileId, manualRequestWithAddToDictionary.getDictionaryEntryType());
|
||||
});
|
||||
addToDictionary(manualRequestWithAddToDictionary.getDictionaryTypeId(),
|
||||
value,
|
||||
manualRequestWithAddToDictionary.getDossierId(),
|
||||
fileId,
|
||||
manualRequestWithAddToDictionary.getDictionaryEntryType());
|
||||
value,
|
||||
manualRequestWithAddToDictionary.getDossierId(),
|
||||
fileId,
|
||||
manualRequestWithAddToDictionary.getDictionaryEntryType());
|
||||
typeIdsOfModifiedDictionaries.add(manualRequestWithAddToDictionary.getDictionaryTypeId());
|
||||
return typeIdsOfModifiedDictionaries;
|
||||
}
|
||||
@ -300,7 +300,8 @@ public class ManualRedactionDictionaryUpdateHandler {
|
||||
resizeRedactionsWithSameValue.forEach(resizeRedaction -> {
|
||||
var file = fileStatusPersistenceService.getStatus(resizeRedaction.getId().getFileId());
|
||||
var dossierForResizeRedaction = dossierPersistenceService.findByDossierId(file.getDossierId());
|
||||
if (!file.getWorkflowStatus().equals(WorkflowStatus.APPROVED) && dossierTemplateId.equals(dossierForResizeRedaction.getDossierTemplateId())
|
||||
if (!file.getWorkflowStatus().equals(WorkflowStatus.APPROVED)
|
||||
&& dossierTemplateId.equals(dossierForResizeRedaction.getDossierTemplateId())
|
||||
&& (resizeRedaction.isAddToAllDossiers() || resizeRedaction.getUpdateDictionary())) {
|
||||
resizeRedactionPersistenceService.hardDelete(resizeRedaction.getId().getFileId(), resizeRedaction.getId().getAnnotationId());
|
||||
}
|
||||
|
||||
@ -49,11 +49,11 @@ public class ManualRedactionProviderService {
|
||||
private final ResizeRedactionPersistenceService resizeRedactionPersistenceService;
|
||||
|
||||
|
||||
public void convertUnprocessedAddToDictionariesToLocalChanges(String fileId) {
|
||||
|
||||
public void convertUnprocessedAddToDictionariesToLocalChanges(String fileId){
|
||||
var unprocessedManualAdds = addRedactionPersistenceService.findEntriesByFileIdAndOptions(fileId, ManualChangesQueryOptions.unprocessedOnly());
|
||||
for (var unprocessedManualAdd : unprocessedManualAdds){
|
||||
if (unprocessedManualAdd.isAddToDictionary() || unprocessedManualAdd.isAddToAllDossiers()){
|
||||
for (var unprocessedManualAdd : unprocessedManualAdds) {
|
||||
if (unprocessedManualAdd.isAddToDictionary() || unprocessedManualAdd.isAddToAllDossiers()) {
|
||||
unprocessedManualAdd.setAddToDictionary(false);
|
||||
unprocessedManualAdd.setAddToAllDossiers(false);
|
||||
unprocessedManualAdd.setLegalBasis("");
|
||||
@ -65,6 +65,7 @@ public class ManualRedactionProviderService {
|
||||
|
||||
@Transactional
|
||||
public ManualRedactions getManualRedactions(String fileId, ManualChangesQueryOptions options) {
|
||||
|
||||
return getManualRedactions(fileId, options, Collections.emptyList());
|
||||
}
|
||||
|
||||
@ -121,13 +122,25 @@ public class ManualRedactionProviderService {
|
||||
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()));
|
||||
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);
|
||||
|
||||
@ -222,7 +222,6 @@ public class ManualRedactionService {
|
||||
removeRedactionRequest.getDossierTemplateId());
|
||||
}
|
||||
|
||||
|
||||
log.info("add removeRedaction for file {} and annotation {}", fileId, removeRedactionRequest.getAnnotationId());
|
||||
IdRemovalEntity idRemoval = removeRedactionPersistenceService.insert(fileId, removeRedactionRequest);
|
||||
|
||||
|
||||
@ -15,8 +15,11 @@ import com.iqser.red.service.persistence.management.v1.processor.exception.Confl
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.FileAttributesRepository;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.TypeRepository;
|
||||
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;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.dictionaryentry.FalseRecommendationEntryRepository;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionarySummaryResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.TypeRankSummary;
|
||||
|
||||
@ -34,6 +37,9 @@ public class DictionaryPersistenceService {
|
||||
private final DossierRepository dossierRepository;
|
||||
|
||||
private final EntryRepository entryRepository;
|
||||
private final FalsePositiveEntryRepository falsePositiveEntryRepository;
|
||||
private final FileAttributesRepository fileAttributesRepository;
|
||||
private final FalseRecommendationEntryRepository falseRecommendationEntryRepository;
|
||||
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRES_NEW) // This needs a single transaction because of the creation of types on the fly, otherwise add entries will fails
|
||||
@ -229,6 +235,7 @@ public class DictionaryPersistenceService {
|
||||
typeRepository.updateByIdSetIncrementVersionByOne(typeId);
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void setVersion(String typeId, long version) {
|
||||
|
||||
@ -328,4 +335,15 @@ public class DictionaryPersistenceService {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void hardDeleteTypesByDossierTemplateId(String dossierTemplateId) {
|
||||
|
||||
for (TypeEntity typeEntity : typeRepository.findAllByDossierTemplateId(dossierTemplateId)) {
|
||||
entryRepository.deleteAllByTypeId(typeEntity.getType());
|
||||
falsePositiveEntryRepository.deleteAllByTypeId(typeEntity.getType());
|
||||
falseRecommendationEntryRepository.deleteAllByTypeId(typeEntity.getType());
|
||||
typeRepository.deleteById(typeEntity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user