package com.constellio.app.modules.rm.extensions.schema; import static com.constellio.model.services.search.query.logical.LogicalSearchQueryOperators.from; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.constellio.app.modules.rm.services.RMSchemasRecordsServices; import com.constellio.app.modules.rm.wrappers.ContainerRecord; import com.constellio.app.modules.rm.wrappers.StorageSpace; import com.constellio.app.services.factories.AppLayerFactory; import com.constellio.data.utils.KeyListMap; import com.constellio.data.utils.dev.Toggle; import com.constellio.model.extensions.behaviors.RecordExtension; import com.constellio.model.extensions.events.records.RecordInCreationBeforeSaveEvent; import com.constellio.model.extensions.events.records.RecordInModificationBeforeSaveEvent; import com.constellio.model.extensions.events.records.TransactionExecutionBeforeSaveEvent; import com.constellio.model.frameworks.validation.ValidationErrors; import com.constellio.model.services.search.SearchServices; public class RMAvailableCapacityExtension extends RecordExtension { public static final String INSUFFICIENT_CONTAINER_RECORD_CAPACITY_ERROR = "insufficientContainerRecordCapacityError"; public static final String INSUFFICIENT_STORAGE_SPACE_CAPACITY_ERROR = "insufficientStorageSpaceCapacityError"; SearchServices searchServices; RMSchemasRecordsServices rm; public RMAvailableCapacityExtension(String collection, AppLayerFactory appLayerFactory) { this.rm = new RMSchemasRecordsServices(collection, appLayerFactory); this.searchServices = appLayerFactory.getModelLayerFactory().newSearchServices(); } @Override public void transactionExecutionBeforeSave(TransactionExecutionBeforeSaveEvent event) { if (event.isOnlySchemaType(ContainerRecord.SCHEMA_TYPE) && !event.isNewRecordImport()) { validateContainerRecord(event.getValidationErrors(), rm.wrapContainerRecords(event.getTransaction().getRecords())); } } @Override public void recordInCreationBeforeSave(RecordInCreationBeforeSaveEvent event) { if (event.isSingleRecordTransaction() && event.isSchemaType(StorageSpace.SCHEMA_TYPE) && !event.isNewRecordImport()) { validateStorageSpace(event.getValidationErrors(), rm.wrapStorageSpace(event.getRecord())); } } @Override public void recordInModificationBeforeSave(RecordInModificationBeforeSaveEvent event) { if (event.isSingleRecordTransaction() && event.isSchemaType(StorageSpace.SCHEMA_TYPE)) { validateStorageSpace(event.getValidationErrors(), rm.wrapStorageSpace(event.getRecord())); } } private void validateContainerRecord(ValidationErrors errors, List<ContainerRecord> containerRecords) { KeyListMap<String, ContainerRecord> containerRecordsInMap = new KeyListMap<>(); for (ContainerRecord containerRecord : containerRecords) { if (containerRecord.getStorageSpace() != null) { containerRecordsInMap.add(containerRecord.getStorageSpace(), containerRecord); } } for (Map.Entry<String, List<ContainerRecord>> entry : containerRecordsInMap.getMapEntries()) { StorageSpace storageSpace = rm.getStorageSpace(entry.getKey()); validateContainerRecord(errors, storageSpace, entry.getValue()); } } private void validateContainerRecord(ValidationErrors errors, StorageSpace storageSpace, List<ContainerRecord> containerRecords) { if (storageSpace.getCapacity() != null && storageSpace.getLinearSizeEntered() == null && Toggle.STORAGE_SPACE_CAPACITIY_VALIDATION.isEnabled()) { long totalCapacity = 0; List<ContainerRecord> containerRecordsAtSameLevel = rm.searchContainerRecords(from(rm.containerRecord.schemaType()) .where(rm.containerRecord.storageSpace()).isEqualTo(storageSpace.getId()) .andWhere(rm.containerRecord.capacity()).isNotNull()); Set<String> ids = new HashSet<>(); for (ContainerRecord containerRecord : containerRecords) { ids.add(containerRecord.getId()); if (containerRecord.getCapacity() != null) { totalCapacity += containerRecord.getCapacity().longValue(); } } for (ContainerRecord record : containerRecordsAtSameLevel) { if (!ids.contains(record.getId())) { totalCapacity += record.getCapacity(); } } if (totalCapacity > storageSpace.getCapacity()) { Map<String, Object> parameters = new HashMap<>(); parameters.put("storageSpace", storageSpace.getTitle()); errors.add(RMAvailableCapacityExtension.class, INSUFFICIENT_CONTAINER_RECORD_CAPACITY_ERROR, parameters); } } } private void validateStorageSpace(ValidationErrors errors, StorageSpace storageSpace) { if (storageSpace.getParentStorageSpace() != null) { StorageSpace parentStorageSpace = rm.getStorageSpace(storageSpace.getParentStorageSpace()); if (parentStorageSpace.getCapacity() != null && parentStorageSpace.getLinearSizeEntered() == null && storageSpace.getCapacity() != null && Toggle.STORAGE_SPACE_CAPACITIY_VALIDATION.isEnabled()) { List<StorageSpace> storageSpacesAtSameLevel = rm.searchStorageSpaces(from(rm.storageSpace.schemaType()) .where(rm.storageSpace.parentStorageSpace()).isEqualTo(parentStorageSpace.getId()) .andWhere(rm.storageSpace.capacity()).isNotNull()); long totalCapacity = storageSpace.getCapacity(); for (StorageSpace record : storageSpacesAtSameLevel) { if (!record.getId().equals(storageSpace.getId())) { totalCapacity += record.getCapacity(); } } if (totalCapacity > parentStorageSpace.getCapacity()) { Map<String, Object> parameters = new HashMap<>(); parameters.put("storageSpace", parentStorageSpace.getTitle()); errors.add(RMAvailableCapacityExtension.class, INSUFFICIENT_STORAGE_SPACE_CAPACITY_ERROR, parameters); } } } } }