Merge branch 'master' into feature/RED-10342
# Conflicts: # persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/FileAttributeConfigPersistenceService.java # persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileAttributeTest.java
This commit is contained in:
commit
fac80bbc5c
@ -357,9 +357,9 @@ public class DictionaryController implements DictionaryResource {
|
||||
public void changeFlags(@PathVariable(TYPE_PARAMETER_NAME) String type,
|
||||
@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@PathVariable(value = DOSSIER_ID_PARAMETER_NAME) String dossierId,
|
||||
@RequestParam(value = "addToDictionary") boolean addToDictionary) {
|
||||
@RequestParam(value = "addToDictionaryAction") boolean addToDictionaryAction) {
|
||||
|
||||
dictionaryService.changeAddToDictionary(type, dossierTemplateId, dossierId, addToDictionary);
|
||||
dictionaryService.changeAddToDictionary(type, dossierTemplateId, dossierId, addToDictionaryAction);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.DossierAttributeConfigMapper;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierAttributeConfigEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
|
||||
@ -52,7 +53,7 @@ public class DossierAttributesController implements DossierAttributesResource {
|
||||
var result = MagicConverter.convert(dossierAttributeConfigPersistenceService.setDossierAttributesConfig(dossierTemplateId,
|
||||
MagicConverter.convert(dossierAttributesConfig.getDossierAttributeConfigs(),
|
||||
DossierAttributeConfigEntity.class)),
|
||||
DossierAttributeConfig.class);
|
||||
DossierAttributeConfig.class, new DossierAttributeConfigMapper());
|
||||
auditPersistenceService.insertRecord(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierTemplateId)
|
||||
@ -72,7 +73,7 @@ public class DossierAttributesController implements DossierAttributesResource {
|
||||
var result = MagicConverter.convert(dossierAttributeConfigPersistenceService.addOrUpdateDossierAttribute(dossierTemplateId,
|
||||
MagicConverter.convert(dossierAttribute,
|
||||
DossierAttributeConfigEntity.class)),
|
||||
DossierAttributeConfig.class);
|
||||
DossierAttributeConfig.class, new DossierAttributeConfigMapper());
|
||||
auditPersistenceService.insertRecord(AuditRequest.builder()
|
||||
.userId(KeycloakSecurity.getUserId())
|
||||
.objectId(dossierTemplateId)
|
||||
@ -118,7 +119,7 @@ public class DossierAttributesController implements DossierAttributesResource {
|
||||
public DossierAttributesConfig getDossierAttributesConfig(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) {
|
||||
|
||||
var result = dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId);
|
||||
return new DossierAttributesConfig(MagicConverter.convert(result, DossierAttributeConfig.class));
|
||||
return new DossierAttributesConfig(MagicConverter.convert(result, DossierAttributeConfig.class, new DossierAttributeConfigMapper()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.model.websocket.FileEventType;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.websocket.WebsocketService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.FileAttributeConfigMapper;
|
||||
import com.knecon.fforesight.keycloakcommons.security.KeycloakSecurity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.FileAttributesGeneralConfigurationEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileAttributeConfigEntity;
|
||||
@ -74,7 +75,9 @@ public class FileAttributesController implements FileAttributesResource {
|
||||
.filenameMappingColumnHeaderName(fileAttributesConfig.getFilenameMappingColumnHeaderName())
|
||||
.delimiter(fileAttributesConfig.getDelimiter())
|
||||
.encoding(fileAttributesConfig.getEncoding())
|
||||
.fileAttributeConfigs(MagicConverter.convert(fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId), FileAttributeConfig.class))
|
||||
.fileAttributeConfigs(MagicConverter.convert(fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId),
|
||||
FileAttributeConfig.class,
|
||||
new FileAttributeConfigMapper()))
|
||||
.build();
|
||||
|
||||
}
|
||||
@ -96,7 +99,7 @@ public class FileAttributesController implements FileAttributesResource {
|
||||
dossierTemplateId))
|
||||
.build());
|
||||
|
||||
return MagicConverter.convert(result, FileAttributeConfig.class);
|
||||
return MagicConverter.convert(result, FileAttributeConfig.class, new FileAttributeConfigMapper());
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +148,7 @@ public class FileAttributesController implements FileAttributesResource {
|
||||
.filenameMappingColumnHeaderName(generalConfig.getFilenameMappingColumnHeaderName())
|
||||
.delimiter(generalConfig.getDelimiter())
|
||||
.encoding(generalConfig.getEncoding())
|
||||
.fileAttributeConfigs(MagicConverter.convert(fileAttributeConfigs, FileAttributeConfig.class))
|
||||
.fileAttributeConfigs(MagicConverter.convert(fileAttributeConfigs, FileAttributeConfig.class, new FileAttributeConfigMapper()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@ -223,7 +223,7 @@ public interface DictionaryResource {
|
||||
void changeFlags(@PathVariable(TYPE_PARAMETER_NAME) String type,
|
||||
@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@PathVariable(DOSSIER_ID_PARAMETER_NAME) String dossierId,
|
||||
@RequestParam(value = "addToDictionary") boolean addToDictionary);
|
||||
@RequestParam(value = "addToDictionaryAction") boolean addToDictionaryAction);
|
||||
|
||||
|
||||
@PostMapping(value = DICTIONARY_REST_PATH + DIFFERENCE + DOSSIER_TEMPLATE_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
|
||||
@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierAttributeConfigEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierAttributeConfigPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.DossierAttributeConfigMapper;
|
||||
import com.iqser.red.service.persistence.service.v1.api.internal.resources.DossierAttributesConfigResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierAttributeConfig;
|
||||
|
||||
@ -27,7 +28,7 @@ public class DossierAttributesConfigInternalController implements DossierAttribu
|
||||
@Override
|
||||
public List<DossierAttributeConfig> getDossierAttributes(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) {
|
||||
|
||||
return convert(dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId), DossierAttributeConfig.class);
|
||||
return convert(dossierAttributeConfigPersistenceService.getDossierAttributes(dossierTemplateId), DossierAttributeConfig.class, new DossierAttributeConfigMapper());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.FileAttributeConfigPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.FileAttributeConfigMapper;
|
||||
import com.iqser.red.service.persistence.service.v1.api.internal.resources.FileAttributesConfigResource;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeConfig;
|
||||
|
||||
@ -25,7 +26,7 @@ public class FileAttributesConfigInternalController implements FileAttributesCon
|
||||
@Override
|
||||
public List<FileAttributeConfig> getFileAttributeConfigs(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId) {
|
||||
|
||||
return convert(fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId), FileAttributeConfig.class);
|
||||
return convert(fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplateId), FileAttributeConfig.class, new FileAttributeConfigMapper());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -53,6 +53,8 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.LegalBasisMappingPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.ReportTemplatePersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.DossierAttributeConfigMapper;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.FileAttributeConfigMapper;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.FileSystemBackedArchiver;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.utils.StorageIdUtils;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
|
||||
@ -183,13 +185,16 @@ public class DossierTemplateExportService {
|
||||
fileSystemBackedArchiver.addEntries(new FileSystemBackedArchiver.ArchiveModel(folder,
|
||||
getFilename(ExportFilename.DOSSIER_ATTRIBUTES_CONFIG, JSON_EXT),
|
||||
objectMapper.writeValueAsBytes(convert(dossierAttributesConfig,
|
||||
DossierAttributeConfig.class))));
|
||||
DossierAttributeConfig.class,
|
||||
new DossierAttributeConfigMapper()))));
|
||||
|
||||
// add file attribute configs
|
||||
List<FileAttributeConfigEntity> fileAttributeConfigList = fileAttributeConfigPersistenceService.getFileAttributes(dossierTemplate.getId());
|
||||
fileSystemBackedArchiver.addEntries(new FileSystemBackedArchiver.ArchiveModel(folder,
|
||||
getFilename(ExportFilename.FILE_ATTRIBUTE_CONFIG, JSON_EXT),
|
||||
objectMapper.writeValueAsBytes(convert(fileAttributeConfigList, FileAttributeConfig.class))));
|
||||
objectMapper.writeValueAsBytes(convert(fileAttributeConfigList,
|
||||
FileAttributeConfig.class,
|
||||
new FileAttributeConfigMapper()))));
|
||||
|
||||
// add legal basis mapping
|
||||
List<LegalBasisEntity> legalBasisMappingList = legalBasisMappingPersistenceService.getLegalBasisMapping(dossierTemplate.getId());
|
||||
|
||||
@ -494,9 +494,9 @@ public class DictionaryService {
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('" + ADD_UPDATE_DICTIONARY_TYPE + "')")
|
||||
public void changeAddToDictionary(String type, String dossierTemplateId, String dossierId, boolean addToDictionary) {
|
||||
public void changeAddToDictionary(String type, String dossierTemplateId, String dossierId, boolean addToDictionaryAction) {
|
||||
|
||||
dictionaryPersistenceService.updateAddToDictionary(toTypeId(type, dossierTemplateId, dossierId), addToDictionary);
|
||||
dictionaryPersistenceService.updateAddToDictionary(toTypeId(type, dossierTemplateId, dossierId), addToDictionaryAction);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ import com.iqser.red.service.persistence.management.v1.processor.service.persist
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.DossierPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.LegalBasisMappingPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.RulesPersistenceService;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.settings.FileManagementServiceSettings;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
|
||||
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.dossier.file.ErrorCode;
|
||||
@ -50,6 +51,7 @@ public class ReanalysisRequiredStatusService {
|
||||
DossierPersistenceService dossierPersistenceService;
|
||||
LegalBasisMappingPersistenceService legalBasisMappingPersistenceService;
|
||||
ComponentMappingService componentMappingService;
|
||||
FileManagementServiceSettings settings;
|
||||
|
||||
|
||||
public FileModel enhanceFileStatusWithAnalysisRequirements(FileModel fileModel) {
|
||||
@ -65,7 +67,12 @@ public class ReanalysisRequiredStatusService {
|
||||
Map<String, DossierEntity> dossierMap = new HashMap<>();
|
||||
Map<String, Map<String, Integer>> componentMappingVersionMap = new HashMap<>();
|
||||
fileModels.forEach(entry -> {
|
||||
var analysisRequiredResult = computeAnalysisRequired(entry, ignoreProcessingStates, dossierTemplateVersionMap, dossierVersionMap, dossierMap, componentMappingVersionMap);
|
||||
var analysisRequiredResult = computeAnalysisRequired(entry,
|
||||
ignoreProcessingStates,
|
||||
dossierTemplateVersionMap,
|
||||
dossierVersionMap,
|
||||
dossierMap,
|
||||
componentMappingVersionMap);
|
||||
entry.setReanalysisRequired(analysisRequiredResult.isReanalysisRequired());
|
||||
entry.setFullAnalysisRequired(analysisRequiredResult.isFullAnalysisRequired());
|
||||
entry.setComponentReanalysisRequired(analysisRequiredResult.isComponentReanalysisRequired());
|
||||
@ -123,7 +130,7 @@ public class ReanalysisRequiredStatusService {
|
||||
if (fileStatus.getLastFileAttributeChange() != null && fileStatus.getLastProcessed().isBefore(fileStatus.getLastFileAttributeChange())) {
|
||||
return new AnalysisRequiredResult(true, false);
|
||||
} else {
|
||||
return requiresReanalysisBasedOnVersionDifference(fileStatus, dossier, dossierTemplateVersionMap, dossierVersionMap,componentMappingVersionMap);
|
||||
return requiresReanalysisBasedOnVersionDifference(fileStatus, dossier, dossierTemplateVersionMap, dossierVersionMap, componentMappingVersionMap);
|
||||
}
|
||||
default:
|
||||
return new AnalysisRequiredResult(false, false);
|
||||
@ -134,14 +141,18 @@ public class ReanalysisRequiredStatusService {
|
||||
}
|
||||
|
||||
|
||||
private AnalysisRequiredResult computeAnalysisRequiredForErrorState(DossierEntity dossier,FileModel fileStatus, Map<String, Map<VersionType, Long>> dossierTemplateVersionMap){
|
||||
private AnalysisRequiredResult computeAnalysisRequiredForErrorState(DossierEntity dossier,
|
||||
FileModel fileStatus,
|
||||
Map<String, Map<VersionType, Long>> dossierTemplateVersionMap) {
|
||||
|
||||
Map<VersionType, Long> dossierTemplateVersions = dossierTemplateVersionMap.computeIfAbsent(dossier.getDossierTemplateId(),
|
||||
k -> buildVersionData(dossier.getDossierTemplateId()));
|
||||
var rulesVersionMatches = fileStatus.getRulesVersion() == dossierTemplateVersions.getOrDefault(RULES, -1L);
|
||||
var componentRulesVersionMatches = fileStatus.getComponentRulesVersion() == dossierTemplateVersions.getOrDefault(COMPONENT_RULES, -1L);
|
||||
|
||||
var isRuleExecutionTimeout = fileStatus.getFileErrorInfo() != null && fileStatus.getFileErrorInfo().getErrorCode() != null && fileStatus.getFileErrorInfo().getErrorCode().equals(
|
||||
ErrorCode.RULES_EXECUTION_TIMEOUT);
|
||||
var isRuleExecutionTimeout = fileStatus.getFileErrorInfo() != null && fileStatus.getFileErrorInfo().getErrorCode() != null && fileStatus.getFileErrorInfo()
|
||||
.getErrorCode()
|
||||
.equals(ErrorCode.RULES_EXECUTION_TIMEOUT);
|
||||
|
||||
var fullAnalysisRequired = (!rulesVersionMatches || !componentRulesVersionMatches) && !isRuleExecutionTimeout;
|
||||
|
||||
@ -153,7 +164,7 @@ public class ReanalysisRequiredStatusService {
|
||||
DossierEntity dossier,
|
||||
Map<String, Map<VersionType, Long>> dossierTemplateVersionMap,
|
||||
Map<String, Long> dossierVersionMap,
|
||||
Map<String, Map<String,Integer>> componentMappingVersionMap) {
|
||||
Map<String, Map<String, Integer>> componentMappingVersionMap) {
|
||||
|
||||
// get relevant versions
|
||||
Map<VersionType, Long> dossierTemplateVersions = dossierTemplateVersionMap.computeIfAbsent(dossier.getDossierTemplateId(),
|
||||
@ -162,7 +173,8 @@ public class ReanalysisRequiredStatusService {
|
||||
Map<String, Integer> componentMappingVersions = componentMappingVersionMap.computeIfAbsent(dossier.getDossierTemplateId(),
|
||||
k -> componentMappingService.getMetaDataByDossierTemplateId(dossier.getDossierTemplateId())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(ComponentMappingMetadata::getName, ComponentMappingMetadata::getVersion)));
|
||||
.collect(Collectors.toMap(ComponentMappingMetadata::getName,
|
||||
ComponentMappingMetadata::getVersion)));
|
||||
|
||||
Long dossierDictionaryVersion = dossierVersionMap.computeIfAbsent(fileStatus.getDossierId(), k -> getDossierVersionData(fileStatus.getDossierId()));
|
||||
|
||||
@ -177,22 +189,23 @@ public class ReanalysisRequiredStatusService {
|
||||
var dossierDictionaryVersionMatches = Math.max(fileStatus.getDossierDictionaryVersion(), 0) == dossierDictionaryVersion;
|
||||
|
||||
var reanalysisRequired = !dictionaryVersionMatches || !dossierDictionaryVersionMatches || !mappingVersionAllMatch;
|
||||
var fullAnalysisRequired = !rulesVersionMatches || !componentRulesVersionMatches || !legalBasisVersionMatches || !aiVersionMatches;
|
||||
var fullAnalysisRequired = !rulesVersionMatches || !componentRulesVersionMatches || !legalBasisVersionMatches || (settings.isLlmNerServiceEnabled() && !aiVersionMatches);
|
||||
var componentReanalysisRequired = !dateFormatsVersionMatches;
|
||||
|
||||
if (reanalysisRequired || fullAnalysisRequired || componentReanalysisRequired) {
|
||||
|
||||
log.debug(buildMessage(fileStatus,
|
||||
rulesVersionMatches,
|
||||
dossierTemplateVersions,
|
||||
componentRulesVersionMatches,
|
||||
dateFormatsVersionMatches,
|
||||
dictionaryVersionMatches,
|
||||
legalBasisVersionMatches,
|
||||
dossierDictionaryVersionMatches,
|
||||
dossierDictionaryVersion,
|
||||
mappingVersionAllMatch,
|
||||
componentMappingVersions));
|
||||
rulesVersionMatches,
|
||||
dossierTemplateVersions,
|
||||
componentRulesVersionMatches,
|
||||
dateFormatsVersionMatches,
|
||||
dictionaryVersionMatches,
|
||||
legalBasisVersionMatches,
|
||||
dossierDictionaryVersionMatches,
|
||||
dossierDictionaryVersion,
|
||||
mappingVersionAllMatch,
|
||||
componentMappingVersions,
|
||||
aiVersionMatches));
|
||||
}
|
||||
return new AnalysisRequiredResult(reanalysisRequired, fullAnalysisRequired, componentReanalysisRequired);
|
||||
|
||||
@ -202,14 +215,15 @@ public class ReanalysisRequiredStatusService {
|
||||
private String buildMessage(FileModel fileStatus,
|
||||
boolean rulesVersionMatches,
|
||||
Map<VersionType, Long> dossierTemplateVersions,
|
||||
boolean versionMatches,
|
||||
boolean componentRulesVersionMatches,
|
||||
boolean dateFormatsVersionMatches,
|
||||
boolean dictionaryVersionMatches,
|
||||
boolean legalBasisVersionMatches,
|
||||
boolean dossierDictionaryVersionMatches,
|
||||
Long dossierDictionaryVersion,
|
||||
boolean mappingVersionAllMatch,
|
||||
Map<String, Integer> componentMappingVersions) {
|
||||
Map<String, Integer> componentMappingVersions,
|
||||
boolean aiVersionMatches) {
|
||||
|
||||
StringBuilder messageBuilder = new StringBuilder();
|
||||
messageBuilder.append("For file: ").append(fileStatus.getId()).append("-").append(fileStatus.getFilename()).append(" analysis is required because -> ");
|
||||
@ -264,6 +278,21 @@ public class ReanalysisRequiredStatusService {
|
||||
needComma = true;
|
||||
}
|
||||
|
||||
if (!dateFormatsVersionMatches) {
|
||||
if (needComma) {
|
||||
messageBuilder.append(", ");
|
||||
}
|
||||
messageBuilder.append("dateFormatsVersions: ").append(fileStatus.getDateFormatsVersion()).append("/").append(dossierTemplateVersions.getOrDefault(DATE_FORMATS, -1L));
|
||||
needComma = true;
|
||||
}
|
||||
|
||||
if (settings.isLlmNerServiceEnabled() && !aiVersionMatches) {
|
||||
if (needComma) {
|
||||
messageBuilder.append(", ");
|
||||
}
|
||||
messageBuilder.append("aiVersions: ").append(fileStatus.getAiCreationVersion()).append("/").append(dossierTemplateVersions.getOrDefault(AI_CREATION, 0L));
|
||||
}
|
||||
|
||||
return messageBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.configuration.TypeEntity;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
|
||||
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierRepository;
|
||||
@ -357,12 +358,14 @@ public class DictionaryPersistenceService {
|
||||
|
||||
|
||||
@Transactional
|
||||
public void updateAddToDictionary(String typeId, boolean addToDictionary) {
|
||||
public void updateAddToDictionary(String typeId, boolean addToDictionaryAction) {
|
||||
|
||||
var typeEntity = getType(typeId);
|
||||
if (typeEntity.isDossierDictionaryOnly()) {
|
||||
typeEntity.setAddToDictionaryAction(addToDictionary);
|
||||
typeEntity.setAddToDictionaryAction(addToDictionaryAction);
|
||||
typeRepository.saveAndFlush(typeEntity);
|
||||
} else {
|
||||
throw new BadRequestException("The addToDictionaryAction flag can only be adjusted for dossierDictionaryOnly-types.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ public class DossierAttributeConfigPersistenceService {
|
||||
dossierAttributeConfig.setDossierTemplate(dossierTemplate);
|
||||
if (dossierAttributeConfig.getId() == null) {
|
||||
dossierAttributeConfig.setId(UUID.randomUUID().toString());
|
||||
setPlaceholder(dossierAttributeConfig);
|
||||
checkAndSetPlaceholder(dossierAttributeConfig);
|
||||
uniqueLabelAndPlaceholder(dossierAttributeConfig);
|
||||
return dossierAttributeConfigRepository.save(dossierAttributeConfig);
|
||||
} else {
|
||||
@ -74,12 +74,13 @@ public class DossierAttributeConfigPersistenceService {
|
||||
config.setEditable(dossierAttributeConfig.isEditable());
|
||||
config.setDisplayedInDossierList(dossierAttributeConfig.isDisplayedInDossierList());
|
||||
config.setFilterable(dossierAttributeConfig.isFilterable());
|
||||
setPlaceholder(config);
|
||||
checkAndSetPlaceholder(dossierAttributeConfig);
|
||||
config.setPlaceholder(dossierAttributeConfig.getPlaceholder());
|
||||
uniqueLabelAndPlaceholder(dossierAttributeConfig);
|
||||
return dossierAttributeConfigRepository.save(config);
|
||||
} else {
|
||||
dossierAttributeConfig.setId(UUID.randomUUID().toString());
|
||||
setPlaceholder(dossierAttributeConfig);
|
||||
checkAndSetPlaceholder(dossierAttributeConfig);
|
||||
uniqueLabelAndPlaceholder(dossierAttributeConfig);
|
||||
return dossierAttributeConfigRepository.save(dossierAttributeConfig);
|
||||
}
|
||||
@ -94,12 +95,25 @@ public class DossierAttributeConfigPersistenceService {
|
||||
}
|
||||
|
||||
|
||||
private void setPlaceholder(DossierAttributeConfigEntity dossierAttributeConfig) {
|
||||
private void checkAndSetPlaceholder(DossierAttributeConfigEntity dossierAttributeConfig) {
|
||||
|
||||
String placeholder = "{{dossier.attribute." + StringUtils.remove(WordUtils.capitalizeFully(dossierAttributeConfig.getLabel(), ' '), " ") + "}}";
|
||||
dossierAttributeConfig.setPlaceholder(placeholder);
|
||||
if (StringUtils.isEmpty(dossierAttributeConfig.getPlaceholder())) {
|
||||
String placeholder = "{{dossier.attribute." + StringUtils.remove(WordUtils.capitalizeFully(dossierAttributeConfig.getLabel(), ' '), " ") + "}}";
|
||||
dossierAttributeConfig.setPlaceholder(placeholder);
|
||||
} else {
|
||||
uniquePlaceholder(dossierAttributeConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private void uniquePlaceholder(DossierAttributeConfigEntity dossierAttributesConfig) {
|
||||
getDossierAttributes(dossierAttributesConfig.getDossierTemplate().getId()).stream()
|
||||
.filter(d -> !d.getId().equals(dossierAttributesConfig.getId()))
|
||||
.forEach(other -> {
|
||||
if (other.getPlaceholder().equalsIgnoreCase(dossierAttributesConfig.getPlaceholder())) {
|
||||
throw new ConflictException("Placeholder already exists. " + dossierAttributesConfig.getPlaceholder());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uniqueLabelAndPlaceholder(DossierAttributeConfigEntity dossierAttributesConfig) {
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ public class FileAttributeConfigPersistenceService {
|
||||
}
|
||||
if (fileAttributeConfig.getId() == null) {
|
||||
fileAttributeConfig.setId(UUID.randomUUID().toString());
|
||||
setPlaceholder(fileAttributeConfig);
|
||||
checkAndSetPlaceholder(fileAttributeConfig);
|
||||
uniqueLabelAndPlaceholder(fileAttributeConfig);
|
||||
return fileAttributeConfigRepository.save(fileAttributeConfig);
|
||||
} else {
|
||||
@ -132,12 +132,13 @@ public class FileAttributeConfigPersistenceService {
|
||||
config.setPrimaryAttribute(fileAttributeConfig.isPrimaryAttribute());
|
||||
config.setFilterable(fileAttributeConfig.isFilterable());
|
||||
config.setIncludeInCsvExport(fileAttributeConfig.isIncludeInCsvExport());
|
||||
setPlaceholder(config);
|
||||
checkAndSetPlaceholder(fileAttributeConfig);
|
||||
config.setPlaceholder(fileAttributeConfig.getPlaceholder());
|
||||
uniqueLabelAndPlaceholder(fileAttributeConfig);
|
||||
return fileAttributeConfigRepository.save(config);
|
||||
} else {
|
||||
fileAttributeConfig.setId(UUID.randomUUID().toString());
|
||||
setPlaceholder(fileAttributeConfig);
|
||||
checkAndSetPlaceholder(fileAttributeConfig);
|
||||
uniqueLabelAndPlaceholder(fileAttributeConfig);
|
||||
return fileAttributeConfigRepository.save(fileAttributeConfig);
|
||||
}
|
||||
@ -152,12 +153,25 @@ public class FileAttributeConfigPersistenceService {
|
||||
}
|
||||
|
||||
|
||||
private void setPlaceholder(FileAttributeConfigEntity fileAttributeConfig) {
|
||||
private void checkAndSetPlaceholder(FileAttributeConfigEntity fileAttributeConfig) {
|
||||
|
||||
String placeholder = "{{file.attribute." + StringUtils.remove(WordUtils.capitalizeFully(fileAttributeConfig.getLabel(), ' '), " ") + "}}";
|
||||
fileAttributeConfig.setPlaceholder(placeholder);
|
||||
if (StringUtils.isEmpty(fileAttributeConfig.getPlaceholder())) {
|
||||
String placeholder = "{{file.attribute." + StringUtils.remove(WordUtils.capitalizeFully(fileAttributeConfig.getLabel(), ' '), " ") + "}}";
|
||||
fileAttributeConfig.setPlaceholder(placeholder);
|
||||
} else {
|
||||
uniquePlaceholder(fileAttributeConfig);
|
||||
}
|
||||
}
|
||||
|
||||
private void uniquePlaceholder(FileAttributeConfigEntity fileAttributeConfig) {
|
||||
getFileAttributes(fileAttributeConfig.getDossierTemplate().getId()).stream()
|
||||
.filter(d -> !d.getId().equals(fileAttributeConfig.getId()))
|
||||
.forEach(other -> {
|
||||
if (other.getPlaceholder().equalsIgnoreCase(fileAttributeConfig.getPlaceholder())) {
|
||||
throw new ConflictException("Placeholder already exists.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uniqueLabelAndPlaceholder(FileAttributeConfigEntity fileAttributeConfig) {
|
||||
|
||||
|
||||
@ -737,11 +737,14 @@ public class FileStatusPersistenceService {
|
||||
|
||||
fileRepository.setAiCreationVersion(fileId, aiCreationVersion);
|
||||
}
|
||||
|
||||
|
||||
public List<FileEntity> findAllByIds(Set<String> fileIds) {
|
||||
|
||||
return fileRepository.findAllById(fileIds);
|
||||
}
|
||||
|
||||
|
||||
public List<FileEntity> findAllDossierIdAndIds(String dossierId, Set<String> fileIds) {
|
||||
|
||||
return fileRepository.findAllDossierIdAndIds(dossierId, fileIds);
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.utils;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.DossierAttributeConfigEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierAttributeConfig;
|
||||
|
||||
public class DossierAttributeConfigMapper implements BiConsumer<DossierAttributeConfigEntity, DossierAttributeConfig> {
|
||||
|
||||
@Override
|
||||
public void accept(DossierAttributeConfigEntity dossierAttributeConfigEntity, DossierAttributeConfig dossierAttributeConfig) {
|
||||
|
||||
dossierAttributeConfig.setDossierTemplateId(dossierAttributeConfigEntity.getDossierTemplate().getId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.iqser.red.service.persistence.management.v1.processor.utils;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.iqser.red.service.persistence.management.v1.processor.entity.dossier.FileAttributeConfigEntity;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeConfig;
|
||||
|
||||
public class FileAttributeConfigMapper implements BiConsumer<FileAttributeConfigEntity, FileAttributeConfig> {
|
||||
|
||||
@Override
|
||||
public void accept(FileAttributeConfigEntity fileAttributeConfigEntity, FileAttributeConfig fileAttributeConfig) {
|
||||
|
||||
fileAttributeConfig.setDossierTemplateId(fileAttributeConfigEntity.getDossierTemplate().getId());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1183,7 +1183,7 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
var type = dictionaryClient.addType(createTypeValue);
|
||||
|
||||
List<TypeValue> customTypes = dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier.getId(), false).getTypes()
|
||||
List<TypeValue> customTypes = dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier.getId(), false).getTypes()
|
||||
.stream()
|
||||
.filter(t -> !t.isSystemManaged())
|
||||
.toList();
|
||||
@ -1213,7 +1213,7 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
|
||||
@Test
|
||||
void testRecreateTypeAndCheckMergedDictionary() {
|
||||
void testRecreateTypeAndCheckMergedDictionary() {
|
||||
|
||||
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "TestDossier");
|
||||
@ -1240,7 +1240,10 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
|
||||
UpdateEntries updateEntries = new UpdateEntries(newDossierEntries, allEntries);
|
||||
dictionaryClient.updateEntries(type.getType(), type.getDossierTemplateId(), updateEntries, dossier.getId(), DictionaryEntryType.ENTRY);
|
||||
|
||||
List<DictionaryEntryEntity> deleted = entryRepository.findAll().stream().filter(DictionaryEntryEntity::isDeleted).toList();
|
||||
List<DictionaryEntryEntity> deleted = entryRepository.findAll()
|
||||
.stream()
|
||||
.filter(DictionaryEntryEntity::isDeleted)
|
||||
.toList();
|
||||
assertEquals(3, deleted.size());
|
||||
|
||||
var updatedDossierDictionary = dictionaryClient.getDictionaryForType(type.getType(), dossierTemplate.getId(), dossier.getId());
|
||||
@ -1257,7 +1260,10 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
assertEquals(2, deletedType1Entities.size());
|
||||
|
||||
deleted = entryRepository.findAll().stream().filter(DictionaryEntryEntity::isDeleted).toList();
|
||||
deleted = entryRepository.findAll()
|
||||
.stream()
|
||||
.filter(DictionaryEntryEntity::isDeleted)
|
||||
.toList();
|
||||
assertEquals(2, deleted.size());
|
||||
|
||||
// recreation
|
||||
@ -1265,7 +1271,10 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
dictionaryClient.addEntry(type2.getType(), type2.getDossierTemplateId(), templateEntries, false, null, DictionaryEntryType.ENTRY);
|
||||
|
||||
deleted = entryRepository.findAll().stream().filter(DictionaryEntryEntity::isDeleted).toList();
|
||||
deleted = entryRepository.findAll()
|
||||
.stream()
|
||||
.filter(DictionaryEntryEntity::isDeleted)
|
||||
.toList();
|
||||
assertEquals(0, deleted.size());
|
||||
|
||||
deletedType1Entities = typeRepository.findAllTypesByDossierTemplateIdOrDossierId(dossierTemplate.getId(), dossier.getId())
|
||||
@ -1292,6 +1301,72 @@ public class DictionaryTest extends AbstractPersistenceServerServiceTest {
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChangeFlagsSuccessful() {
|
||||
|
||||
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||
var dossier1 = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "Dossier1");
|
||||
|
||||
var type1 = dictionaryClient.addType(CreateTypeValue.builder()
|
||||
.type("test_change_flags_true")
|
||||
.label("Test Change Flags True")
|
||||
.hexColor("#123456")
|
||||
.rank(100)
|
||||
.hint(false)
|
||||
.hasDictionary(true)
|
||||
.caseInsensitive(false)
|
||||
.recommendation(false)
|
||||
.addToDictionaryAction(false)
|
||||
.dossierTemplateId(dossierTemplate.getId())
|
||||
.dossierDictionaryOnly(true)
|
||||
.build());
|
||||
dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier1.getId(), false);
|
||||
|
||||
|
||||
dictionaryClient.changeFlags(type1.getType(), dossierTemplate.getId(), dossier1.getId(), true);
|
||||
|
||||
String compositeTypeId1 = type1.getType() + ":" + dossierTemplate.getId() + ":" + dossier1.getId();
|
||||
var updatedTypeEntity1 = typeRepository.findById(compositeTypeId1)
|
||||
.orElseThrow(() -> new AssertionError("Type entity not found in repository"));
|
||||
|
||||
assertThat(updatedTypeEntity1.isAddToDictionaryAction()).isTrue();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testChangeFlagsUnsuccessful() {
|
||||
|
||||
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||
var dossier2 = dossierTesterAndProvider.provideTestDossier(dossierTemplate, "Dossier2");
|
||||
|
||||
var type2 = dictionaryClient.addType(CreateTypeValue.builder()
|
||||
.type("test_change_flags_false")
|
||||
.label("Test Change Flags False")
|
||||
.hexColor("#654321")
|
||||
.rank(101)
|
||||
.hint(false)
|
||||
.hasDictionary(true)
|
||||
.caseInsensitive(false)
|
||||
.recommendation(false)
|
||||
.addToDictionaryAction(false)
|
||||
.dossierTemplateId(dossierTemplate.getId())
|
||||
.dossierDictionaryOnly(false)
|
||||
.build());
|
||||
dictionaryClient.getAllTypes(dossierTemplate.getId(), dossier2.getId(), false);
|
||||
|
||||
|
||||
assertThatThrownBy(() -> dictionaryClient.changeFlags(type2.getType(), dossierTemplate.getId(), dossier2.getId(), true))
|
||||
.isInstanceOf(FeignException.BadRequest.class)
|
||||
.hasMessageContaining("The addToDictionaryAction flag can only be adjusted for dossierDictionaryOnly-types.");
|
||||
|
||||
String compositeTypeId2 = type2.getType() + ":" + dossierTemplate.getId() + ":" + dossier2.getId();
|
||||
var typeEntity2 = typeRepository.findById(compositeTypeId2)
|
||||
.orElseThrow(() -> new AssertionError("Type entity not found in repository"));
|
||||
|
||||
assertThat(typeEntity2.isAddToDictionaryAction()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
private static final class ListContentWithoutOrderAndWithoutDuplicatesComparator<T> implements Comparator<List<? extends T>> {
|
||||
|
||||
@SuppressWarnings("SuspiciousMethodCalls")
|
||||
|
||||
@ -51,15 +51,24 @@ public class DossierAttributeTest extends AbstractPersistenceServerServiceTest {
|
||||
attribute.setEditable(true);
|
||||
attribute.setType(DossierAttributeType.TEXT);
|
||||
|
||||
dossierAttributeConfigClient.addOrUpdateDossierAttributeConfig(dossier.getDossierTemplateId(), attribute);
|
||||
var created = dossierAttributeConfigClient.addOrUpdateDossierAttributeConfig(dossier.getDossierTemplateId(), attribute);
|
||||
assertThat(created.getPlaceholder()).isEqualTo("{{dossier.attribute.Test}}");
|
||||
loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
|
||||
assertThat(loadedAttributes.getDossierAttributeConfigs()).isNotEmpty();
|
||||
assertThat(loadedAttributes.getDossierAttributeConfigs().get(0).getDossierTemplateId()).isEqualTo(dossier.getDossierTemplateId());
|
||||
|
||||
attribute.setId(created.getId());
|
||||
attribute.setLabel("updated test");
|
||||
var updated = dossierAttributeConfigClient.addOrUpdateDossierAttributeConfig(dossier.getDossierTemplateId(), attribute);
|
||||
assertThat(updated.getLabel()).isEqualTo("updated test");
|
||||
assertThat(updated.getPlaceholder()).isEqualTo("{{dossier.attribute.UpdatedTest}}");
|
||||
|
||||
attribute.setPlaceholder("{{dossier.attribute.MyOwnPlaceholder}}");
|
||||
updated = dossierAttributeConfigClient.addOrUpdateDossierAttributeConfig(dossier.getDossierTemplateId(), attribute);
|
||||
assertThat(updated.getLabel()).isEqualTo("updated test");
|
||||
assertThat(updated.getPlaceholder()).isEqualTo("{{dossier.attribute.MyOwnPlaceholder}}");
|
||||
|
||||
|
||||
dossierAttributeConfigClient.setDossierAttributesConfig(dossier.getDossierTemplateId(), new DossierAttributesConfig());
|
||||
loadedAttributes = dossierAttributeConfigClient.getDossierAttributesConfig(dossier.getDossierTemplateId());
|
||||
assertThat(loadedAttributes.getDossierAttributeConfigs()).isEmpty();
|
||||
|
||||
@ -88,9 +88,10 @@ public class FileAttributeTest extends AbstractPersistenceServerServiceTest {
|
||||
assertThat(loadedConfig.getEncoding()).isEqualTo(ASCII_ENCODING);
|
||||
|
||||
List<FileAttributeConfig> configs = new ArrayList<>();
|
||||
String myOwnPlaceholder = "{{file.attribute.MyOwnPlaceholder}}";
|
||||
configs.add(FileAttributeConfig.builder().csvColumnHeader("Name").primaryAttribute(true).label("Name").build());
|
||||
configs.add(FileAttributeConfig.builder().csvColumnHeader("Attribute A").primaryAttribute(true).label("Attribute A").build());
|
||||
FileAttributeConfig attributeB = FileAttributeConfig.builder().csvColumnHeader("Attribute B").primaryAttribute(true).label("Attribute B").includeInCsvExport(true).build();
|
||||
FileAttributeConfig attributeB = FileAttributeConfig.builder().csvColumnHeader("Attribute B").primaryAttribute(true).label("Attribute B").placeholder(myOwnPlaceholder).includeInCsvExport(true).build();
|
||||
configs.add(attributeB);
|
||||
configs.add(FileAttributeConfig.builder().csvColumnHeader("Attribute C").primaryAttribute(false).label("Attribute C").build());
|
||||
configs.add(FileAttributeConfig.builder().csvColumnHeader("Attribute D").primaryAttribute(false).label("Attribute D").build());
|
||||
@ -104,6 +105,7 @@ public class FileAttributeTest extends AbstractPersistenceServerServiceTest {
|
||||
.findAny()
|
||||
.get();
|
||||
assertThat(primaryAttribute.getLabel()).isEqualTo(attributeB.getLabel());
|
||||
assertThat(primaryAttribute.getPlaceholder()).isEqualTo(attributeB.getPlaceholder());
|
||||
assertTrue(primaryAttribute.isIncludeInCsvExport());
|
||||
|
||||
fileAttributeConfigClient.deleteFileAttribute(dossier.getDossierTemplateId(),
|
||||
@ -123,6 +125,7 @@ public class FileAttributeTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
loadedConfigs = fileAttributeConfigClient.getFileAttributesConfiguration(dossier.getDossierTemplateId()).getFileAttributeConfigs();
|
||||
assertThat(loadedConfigs.size()).isEqualTo(3);
|
||||
assertThat(loadedConfigs.get(0).getDossierTemplateId()).isEqualTo(dossier.getDossierTemplateId());
|
||||
|
||||
FileAttributeConfig newConfig = new FileAttributeConfig();
|
||||
newConfig.setPrimaryAttribute(true);
|
||||
@ -130,6 +133,8 @@ public class FileAttributeTest extends AbstractPersistenceServerServiceTest {
|
||||
var created = fileAttributeConfigClient.addOrUpdateFileAttribute(dossier.getDossierTemplateId(), newConfig);
|
||||
loadedConfigs = fileAttributeConfigClient.getFileAttributesConfiguration(dossier.getDossierTemplateId()).getFileAttributeConfigs();
|
||||
assertThat(loadedConfigs.size()).isEqualTo(4);
|
||||
assertThat(created.getPlaceholder()).isEqualTo("{{file.attribute.TestAttribute}}");
|
||||
assertThat(created.getCsvColumnHeader()).isNull();
|
||||
|
||||
newConfig.setId(created.getId());
|
||||
newConfig.setLabel("Test Attribute Update");
|
||||
@ -141,6 +146,14 @@ public class FileAttributeTest extends AbstractPersistenceServerServiceTest {
|
||||
assertTrue(updated.isIncludeInCsvExport());
|
||||
assertThat(updated.getPlaceholder()).isEqualTo("{{file.attribute.TestAttributeUpdate}}");
|
||||
|
||||
newConfig.setPlaceholder(myOwnPlaceholder);
|
||||
var e = assertThrows(FeignException.class,
|
||||
() -> fileAttributeConfigClient.addOrUpdateFileAttribute(dossier.getDossierTemplateId(), newConfig));
|
||||
assertEquals(409, e.status());
|
||||
newConfig.setPlaceholder("{{file.attribute.TestAttributeUpdate2}}");
|
||||
updated = fileAttributeConfigClient.addOrUpdateFileAttribute(dossier.getDossierTemplateId(), newConfig);
|
||||
assertThat(updated.getPlaceholder()).isEqualTo("{{file.attribute.TestAttributeUpdate2}}");
|
||||
|
||||
assertThat(fileClient.getFileStatus(dossier.getId(), file.getId()).getLastFileAttributeChange()).isNull();
|
||||
|
||||
fileAttributeClient.setFileAttributes(dossier.getId(), file.getId(), new FileAttributes(Map.of(updated.getId(), "Lorem Ipsum")));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user