SEBSERV-260 new ARCHIVED state for exam configurations
This commit is contained in:
parent
3afed86efa
commit
f9eb0b2535
9 changed files with 68 additions and 17 deletions
|
@ -39,7 +39,8 @@ public final class ConfigurationNode implements GrantEntity {
|
|||
public enum ConfigurationStatus {
|
||||
CONSTRUCTION,
|
||||
READY_TO_USE,
|
||||
IN_USE
|
||||
IN_USE,
|
||||
ARCHIVED
|
||||
}
|
||||
|
||||
@JsonProperty(CONFIGURATION_NODE.ATTR_ID)
|
||||
|
|
|
@ -95,7 +95,7 @@ public class SEBExamConfigList implements TemplateComposer {
|
|||
this.statusFilter = new TableFilterAttribute(
|
||||
CriteriaType.SINGLE_SELECTION,
|
||||
ConfigurationNode.FILTER_ATTR_STATUS,
|
||||
this.resourceService::examConfigStatusResources);
|
||||
this.resourceService::examConfigStatusFilterResources);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -450,8 +450,17 @@ public class ResourceService {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Tuple<String>> examConfigStatusResources() {
|
||||
return examConfigStatusResources(false);
|
||||
public List<Tuple<String>> examConfigStatusFilterResources() {
|
||||
return Arrays.stream(ConfigurationStatus.values())
|
||||
.map(type -> new Tuple3<>(
|
||||
type.name(),
|
||||
this.i18nSupport.getText(EXAMCONFIG_STATUS_PREFIX + type.name()),
|
||||
Utils.formatLineBreaks(this.i18nSupport.getText(
|
||||
this.i18nSupport.getText(EXAMCONFIG_STATUS_PREFIX + type.name())
|
||||
+ Constants.TOOLTIP_TEXT_KEY_SUFFIX,
|
||||
StringUtils.EMPTY))))
|
||||
.sorted(RESOURCE_COMPARATOR)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Tuple<String>> examConfigStatusResources(final boolean isAttachedToExam) {
|
||||
|
|
|
@ -181,7 +181,7 @@ public final class PageAction {
|
|||
if (confirmMessage != null) {
|
||||
this.pageContext.applyConfirmDialog(confirmMessage,
|
||||
confirm -> callback.accept((confirm)
|
||||
? exec()
|
||||
? exec().onError(error -> this.pageContext.notifyUnexpectedError(error))
|
||||
: Result.ofRuntimeError("Confirm denied")));
|
||||
} else {
|
||||
callback.accept(exec());
|
||||
|
|
|
@ -67,6 +67,13 @@ public interface ExamConfigurationMapDAO extends
|
|||
* @return Result referencing the List of exam identifiers (PK) for a given configuration identifier */
|
||||
Result<Collection<Long>> getExamIdsForConfigId(Long configurationId);
|
||||
|
||||
Result<Boolean> checkForDeletion(Long configurationNodeId);
|
||||
/** Use this to check if a specified exam configuration don't have any relations
|
||||
* to an currently active exam, meaning in upcoming or running state.
|
||||
* Exams in finished state are not active and will not go into account here.
|
||||
*
|
||||
* @param configurationNodeId the identifier of exam configuration to check
|
||||
* @return Result refer to true if config has no relations to active exams, or false of it has or refer to an error
|
||||
* if happened */
|
||||
Result<Boolean> checkNoActiveExamReferences(Long configurationNodeId);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.function.Function;
|
|||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.mybatis.dynamic.sql.SqlBuilder;
|
||||
import org.mybatis.dynamic.sql.select.MyBatis3SelectModelAdapter;
|
||||
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
|
||||
|
@ -123,17 +124,15 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
|
|||
.on(InstitutionRecordDynamicSqlSupport.id,
|
||||
SqlBuilder.equalTo(ConfigurationNodeRecordDynamicSqlSupport.institutionId))
|
||||
.where(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.status,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getConfigNodeStatus()))
|
||||
ConfigurationNodeRecordDynamicSqlSupport.institutionId,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getInstitutionId()))
|
||||
: this.configurationNodeRecordMapper
|
||||
.selectByExample()
|
||||
.where(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.status,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getConfigNodeStatus()));
|
||||
ConfigurationNodeRecordDynamicSqlSupport.institutionId,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getInstitutionId()));
|
||||
|
||||
return whereClause.and(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.institutionId,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getInstitutionId()))
|
||||
whereClause
|
||||
.and(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.name,
|
||||
SqlBuilder.isLikeWhenPresent(filterMap.getName()))
|
||||
|
@ -145,7 +144,20 @@ public class ConfigurationNodeDAOImpl implements ConfigurationNodeDAO {
|
|||
SqlBuilder.isEqualToWhenPresent(filterMap.getConfigNodeType()))
|
||||
.and(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.templateId,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getConfigNodeTemplateId()))
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getConfigNodeTemplateId()));
|
||||
|
||||
final String status = filterMap.getConfigNodeStatus();
|
||||
if (StringUtils.isBlank(status)) {
|
||||
whereClause.and(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.status,
|
||||
SqlBuilder.isNotEqualToWhenPresent(ConfigurationStatus.ARCHIVED.name()));
|
||||
} else {
|
||||
whereClause.and(
|
||||
ConfigurationNodeRecordDynamicSqlSupport.status,
|
||||
SqlBuilder.isEqualToWhenPresent(filterMap.getConfigNodeStatus()));
|
||||
}
|
||||
|
||||
return whereClause
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
|
|
|
@ -375,7 +375,7 @@ public class ExamConfigurationMapDAOImpl implements ExamConfigurationMapDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Boolean> checkForDeletion(final Long configurationNodeId) {
|
||||
public Result<Boolean> checkNoActiveExamReferences(final Long configurationNodeId) {
|
||||
return Result.tryCatch(() -> !this.examConfigurationMapRecordMapper.selectByExample()
|
||||
.where(
|
||||
ExamConfigurationMapRecordDynamicSqlSupport.configurationNodeId,
|
||||
|
|
|
@ -511,13 +511,34 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
|
|||
"The Type of ConfigurationNode cannot change after creation");
|
||||
}
|
||||
return e;
|
||||
});
|
||||
})
|
||||
.map(this::checkChangeToArchived);
|
||||
}
|
||||
|
||||
private ConfigurationNode checkChangeToArchived(final ConfigurationNode entity) {
|
||||
if (entity.status == ConfigurationStatus.ARCHIVED) {
|
||||
// check if we have a change to archived
|
||||
final ConfigurationNode persistentNode = this.configurationNodeDAO
|
||||
.byPK(entity.id)
|
||||
.getOrThrow();
|
||||
// yes we have
|
||||
if (persistentNode.status != ConfigurationStatus.ARCHIVED) {
|
||||
// check if this is possible (no upcoming or running exams involved)
|
||||
if (!this.examConfigurationMapDAO.checkNoActiveExamReferences(entity.id).getOr(false)) {
|
||||
throw new APIMessageException(
|
||||
APIMessage.ErrorMessage.INTEGRITY_VALIDATION
|
||||
.of("Exam configuration has references to at least one upcoming or running exam."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result<ConfigurationNode> validForDelete(final ConfigurationNode entity) {
|
||||
return Result.tryCatch(() -> {
|
||||
if (!this.examConfigurationMapDAO.checkForDeletion(entity.id).getOr(false)) {
|
||||
if (!this.examConfigurationMapDAO.checkNoActiveExamReferences(entity.id).getOr(false)) {
|
||||
throw new APIMessageException(
|
||||
APIMessage.ErrorMessage.INTEGRITY_VALIDATION
|
||||
.of("Exam configuration has references to at least one upcoming or running exam."));
|
||||
|
|
|
@ -863,6 +863,7 @@ sebserver.examconfig.form.attached-to.tooltip=This SEB exam configuration is cur
|
|||
sebserver.examconfig.status.CONSTRUCTION=Under Construction
|
||||
sebserver.examconfig.status.READY_TO_USE=Ready To Use
|
||||
sebserver.examconfig.status.IN_USE=In Use
|
||||
sebserver.examconfig.status.ARCHIVED=Archived
|
||||
|
||||
sebserver.examconfig.props.from.unpublished.message=Note: There are unpublished changes to this Settings. Use 'Save/Publish Settings' to make sure the settings are active.
|
||||
sebserver.examconfig.props.from.title=SEB Settings ({0})
|
||||
|
|
Loading…
Reference in a new issue