SEBSERV-160 fixed "In Use" for selection
This commit is contained in:
		
							parent
							
								
									8b9eebfe5b
								
							
						
					
					
						commit
						6396afa53b
					
				
					 7 changed files with 65 additions and 9 deletions
				
			
		|  | @ -26,12 +26,15 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; | |||
| import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM_CONFIGURATION_MAP; | ||||
| import ch.ethz.seb.sebserver.gbl.model.Entity; | ||||
| import ch.ethz.seb.sebserver.gbl.model.GrantEntity; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType; | ||||
| import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus; | ||||
| 
 | ||||
| @JsonIgnoreProperties(ignoreUnknown = true) | ||||
| public final class ExamConfigurationMap implements GrantEntity { | ||||
| 
 | ||||
|     private static final String ARR_EXAM_STATUS = "examStatus"; | ||||
| 
 | ||||
|     public static final String ATTR_CONFIRM_ENCRYPT_SECRET = "confirm_encrypt_secret"; | ||||
| 
 | ||||
|     public static final String FILTER_ATTR_EXAM_ID = "examId"; | ||||
|  | @ -60,6 +63,9 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|     @JsonProperty(EXAM.ATTR_TYPE) | ||||
|     public final ExamType examType; | ||||
| 
 | ||||
|     @JsonProperty(ARR_EXAM_STATUS) | ||||
|     public final ExamStatus examStatus; | ||||
| 
 | ||||
|     @NotNull(message = "examConfigurationMap:configurationNodeId:notNull") | ||||
|     @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID) | ||||
|     public final Long configurationNodeId; | ||||
|  | @ -91,6 +97,7 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|             @JsonProperty(QuizData.QUIZ_ATTR_DESCRIPTION) final String examDescription, | ||||
|             @JsonProperty(QuizData.QUIZ_ATTR_START_TIME) final DateTime examStartTime, | ||||
|             @JsonProperty(EXAM.ATTR_TYPE) final ExamType examType, | ||||
|             @JsonProperty(ARR_EXAM_STATUS) final ExamStatus examStatus, | ||||
|             @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID) final Long configurationNodeId, | ||||
|             @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_USER_NAMES) final String userNames, | ||||
|             @JsonProperty(EXAM_CONFIGURATION_MAP.ATTR_ENCRYPT_SECRET) final CharSequence encryptSecret, | ||||
|  | @ -106,6 +113,7 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|         this.examDescription = examDescription; | ||||
|         this.examStartTime = examStartTime; | ||||
|         this.examType = examType; | ||||
|         this.examStatus = examStatus; | ||||
|         this.configurationNodeId = configurationNodeId; | ||||
|         this.userNames = userNames; | ||||
|         this.encryptSecret = encryptSecret; | ||||
|  | @ -125,6 +133,7 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|         this.examDescription = postParams.getString(QuizData.QUIZ_ATTR_DESCRIPTION); | ||||
|         this.examStartTime = postParams.getDateTime(QuizData.QUIZ_ATTR_START_TIME); | ||||
|         this.examType = postParams.getEnum(EXAM.ATTR_TYPE, ExamType.class); | ||||
|         this.examStatus = postParams.getEnum(ARR_EXAM_STATUS, ExamStatus.class); | ||||
| 
 | ||||
|         this.configurationNodeId = postParams.getLong(Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID); | ||||
|         this.userNames = postParams.getString(Domain.EXAM_CONFIGURATION_MAP.ATTR_USER_NAMES); | ||||
|  | @ -149,6 +158,7 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|         this.examDescription = null; | ||||
|         this.examStartTime = null; | ||||
|         this.examType = null; | ||||
|         this.examStatus = null; | ||||
|         this.configurationNodeId = configurationNodeId; | ||||
|         this.userNames = userNames; | ||||
|         this.encryptSecret = null; | ||||
|  | @ -205,6 +215,10 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|         return this.examType; | ||||
|     } | ||||
| 
 | ||||
|     public ExamStatus getExamStatus() { | ||||
|         return this.examStatus; | ||||
|     } | ||||
| 
 | ||||
|     public Long getConfigurationNodeId() { | ||||
|         return this.configurationNodeId; | ||||
|     } | ||||
|  | @ -250,6 +264,7 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
|                 this.examDescription, | ||||
|                 this.examStartTime, | ||||
|                 this.examType, | ||||
|                 this.examStatus, | ||||
|                 this.configurationNodeId, | ||||
|                 this.userNames, | ||||
|                 Constants.EMPTY_NOTE, | ||||
|  | @ -296,7 +311,7 @@ public final class ExamConfigurationMap implements GrantEntity { | |||
| 
 | ||||
|     public static ExamConfigurationMap createNew(final Exam exam) { | ||||
|         return new ExamConfigurationMap( | ||||
|                 null, exam.institutionId, exam.id, exam.name, exam.description, exam.startTime, exam.type, | ||||
|                 null, exam.institutionId, exam.id, exam.name, exam.description, exam.startTime, exam.type, exam.status, | ||||
|                 null, null, null, null, null, null, null); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -87,7 +87,7 @@ public class SEBExamConfigBatchStateChangePopup extends AbstractBatchActionWizar | |||
|                 FORM_STATUS_TEXT_KEY, | ||||
|                 targetStateName, | ||||
|                 () -> this.pageService.getResourceService() | ||||
|                         .examConfigStatusResources(false)) | ||||
|                         .examConfigStatusResourcesAll()) | ||||
|                 .readonly(readonly)); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType; | |||
| import ch.ethz.seb.sebserver.gbl.model.Domain; | ||||
| import ch.ethz.seb.sebserver.gbl.model.EntityKey; | ||||
| import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap; | ||||
| import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; | ||||
| import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigKey; | ||||
|  | @ -173,6 +174,16 @@ public class SEBExamConfigForm implements TemplateComposer { | |||
|                 .call() | ||||
|                 .map(names -> names != null && !names.isEmpty()) | ||||
|                 .getOr(Boolean.FALSE); | ||||
|         final boolean hasRunningExam = isAttachedToExam && this.restService | ||||
|                 .getBuilder(GetExamConfigMappingsPage.class) | ||||
|                 .withQueryParam(ExamConfigurationMap.FILTER_ATTR_CONFIG_ID, examConfig.getModelId()) | ||||
|                 .call() | ||||
|                 .map(res -> res.content | ||||
|                         .stream() | ||||
|                         .filter(map -> map.examStatus == ExamStatus.RUNNING) | ||||
|                         .findAny() | ||||
|                         .isPresent()) | ||||
|                 .getOr(false); | ||||
| 
 | ||||
|         // new PageContext with actual EntityKey | ||||
|         final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey()); | ||||
|  | @ -223,7 +234,7 @@ public class SEBExamConfigForm implements TemplateComposer { | |||
|                         Domain.CONFIGURATION_NODE.ATTR_STATUS, | ||||
|                         FORM_STATUS_TEXT_KEY, | ||||
|                         examConfig.status.name(), | ||||
|                         () -> resourceService.examConfigStatusResources(isAttachedToExam)) | ||||
|                         () -> resourceService.examConfigStatusResources(isAttachedToExam, hasRunningExam)) | ||||
|                         .withEmptyCellSeparation(!isReadonly)) | ||||
|                 .buildFor((isNew) | ||||
|                         ? this.restService.getRestCall(NewExamConfig.class) | ||||
|  | @ -297,7 +308,7 @@ public class SEBExamConfigForm implements TemplateComposer { | |||
|                 .withEntityKey(entityKey) | ||||
|                 .withExec(formHandle::processFormSave) | ||||
|                 .ignoreMoveAwayFromEdit() | ||||
|                 .withConfirm(() -> stateChangeConfirm(isAttachedToExam, formHandle)) | ||||
|                 .withConfirm(() -> stateChangeConfirm(hasRunningExam, formHandle)) | ||||
|                 .publishIf(() -> !isReadonly) | ||||
| 
 | ||||
|                 .newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_CANCEL_MODIFY) | ||||
|  | @ -436,17 +447,17 @@ public class SEBExamConfigForm implements TemplateComposer { | |||
|     } | ||||
| 
 | ||||
|     private LocTextKey stateChangeConfirm( | ||||
|             final boolean isAttachedToExam, | ||||
|             final boolean hasRunningExam, | ||||
|             final FormHandle<ConfigurationNode> formHandle) { | ||||
| 
 | ||||
|         if (isAttachedToExam) { | ||||
|         if (hasRunningExam) { | ||||
|             final String fieldValue = formHandle | ||||
|                     .getForm() | ||||
|                     .getFieldValue(Domain.CONFIGURATION_NODE.ATTR_STATUS); | ||||
| 
 | ||||
|             if (fieldValue != null) { | ||||
|                 final ConfigurationStatus state = ConfigurationStatus.valueOf(fieldValue); | ||||
|                 if (state != ConfigurationStatus.IN_USE) { | ||||
|                 if (state != ConfigurationStatus.IN_USE && state != ConfigurationStatus.ARCHIVED) { | ||||
|                     return SAVE_CONFIRM_STATE_CHANGE_WHILE_ATTACHED; | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -471,7 +471,20 @@ public class ResourceService { | |||
|                 .collect(Collectors.toList()); | ||||
|     } | ||||
| 
 | ||||
|     public List<Tuple<String>> examConfigStatusResources(final boolean isAttachedToExam) { | ||||
|     public List<Tuple<String>> examConfigStatusResourcesAll() { | ||||
|         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, final boolean hasRunningExam) { | ||||
|         return Arrays.stream(ConfigurationStatus.values()) | ||||
|                 .filter(status -> { | ||||
|                     if (isAttachedToExam) { | ||||
|  | @ -480,6 +493,7 @@ public class ResourceService { | |||
|                         return status != ConfigurationStatus.IN_USE; | ||||
|                     } | ||||
|                 }) | ||||
|                 .filter(status -> !hasRunningExam || status != ConfigurationStatus.ARCHIVED) | ||||
|                 .map(type -> new Tuple3<>( | ||||
|                         type.name(), | ||||
|                         this.i18nSupport.getText(EXAMCONFIG_STATUS_PREFIX + type.name()), | ||||
|  |  | |||
|  | @ -442,6 +442,7 @@ public class ExamConfigurationMapDAOImpl implements ExamConfigurationMapDAO { | |||
|                     (exam != null) ? exam.description : null, | ||||
|                     (exam != null) ? exam.startTime : null, | ||||
|                     (exam != null) ? exam.type : ExamType.UNDEFINED, | ||||
|                     (exam != null) ? exam.status : null, | ||||
|                     record.getConfigurationNodeId(), | ||||
|                     record.getUserNames(), | ||||
|                     record.getEncryptSecret(), | ||||
|  |  | |||
|  | @ -136,6 +136,7 @@ public class ExamConfigServiceImpl implements ExamConfigService { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public Result<Long> getFollowupConfigurationId(final Long examConfigNodeId) { | ||||
|         return this.configurationDAO.getFollowupConfigurationId(examConfigNodeId); | ||||
|     } | ||||
|  | @ -443,6 +444,20 @@ public class ExamConfigServiceImpl implements ExamConfigService { | |||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // if changing to "In Use" check config is mapped for at least one exam | ||||
|             if (configurationNode.status == ConfigurationStatus.IN_USE && | ||||
|                     existingNode.status != ConfigurationStatus.IN_USE) { | ||||
| 
 | ||||
|                 if (this.examConfigurationMapDAO | ||||
|                         .getExamIdsForConfigNodeId(configurationNode.id) | ||||
|                         .getOr(Collections.emptyList()) | ||||
|                         .isEmpty()) { | ||||
|                     throw new APIMessageException( | ||||
|                             APIMessage.ErrorMessage.INTEGRITY_VALIDATION | ||||
|                                     .of("Exam configuration has no reference to any exam.")); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return configurationNode; | ||||
| 
 | ||||
|         }); | ||||
|  |  | |||
|  | @ -209,7 +209,7 @@ public class ModelObjectJSONGenerator { | |||
|         System.out.println(writerWithDefaultPrettyPrinter.writeValueAsString(domainObject)); | ||||
| 
 | ||||
|         domainObject = new ExamConfigurationMap( | ||||
|                 1L, 1L, 1L, "examName", "examDescription", DateTime.now(), ExamType.BYOD, | ||||
|                 1L, 1L, 1L, "examName", "examDescription", DateTime.now(), ExamType.BYOD, ExamStatus.RUNNING, | ||||
|                 1L, "userNames", "encryptSecret", "confirmEncryptSecret", "configName", "configDescription", | ||||
|                 ConfigurationStatus.IN_USE); | ||||
|         System.out.println(domainObject.getClass().getSimpleName() + ":"); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti