001// -------------------------------------------------------------------------------- 002// Copyright 2002-2026 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.control.user.training.server.command; 018 019import com.echothree.control.user.training.common.form.CreateTrainingClassForm; 020import com.echothree.model.control.core.common.MimeTypeUsageTypes; 021import com.echothree.model.control.core.server.logic.MimeTypeLogic; 022import com.echothree.model.control.party.common.PartyTypes; 023import com.echothree.model.control.security.common.SecurityRoleGroups; 024import com.echothree.model.control.security.common.SecurityRoles; 025import com.echothree.model.control.training.server.control.TrainingControl; 026import com.echothree.model.control.uom.common.UomConstants; 027import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic; 028import com.echothree.model.control.workeffort.common.workeffort.TrainingConstants; 029import com.echothree.model.control.workeffort.server.control.WorkEffortControl; 030import com.echothree.model.data.user.common.pk.UserVisitPK; 031import com.echothree.model.data.workeffort.server.entity.WorkEffortScope; 032import com.echothree.util.common.message.ExecutionErrors; 033import com.echothree.util.common.validation.FieldDefinition; 034import com.echothree.util.common.validation.FieldType; 035import com.echothree.util.common.command.BaseResult; 036import com.echothree.util.server.control.BaseSimpleCommand; 037import com.echothree.util.server.control.CommandSecurityDefinition; 038import com.echothree.util.server.control.PartyTypeDefinition; 039import com.echothree.util.server.control.SecurityRoleDefinition; 040import com.echothree.util.server.persistence.Session; 041import java.util.List; 042import javax.enterprise.context.Dependent; 043 044@Dependent 045public class CreateTrainingClassCommand 046 extends BaseSimpleCommand<CreateTrainingClassForm> { 047 048 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 049 private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS; 050 051 static { 052 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 053 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 054 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 055 new SecurityRoleDefinition(SecurityRoleGroups.TrainingClass.name(), SecurityRoles.Create.name()) 056 )) 057 )); 058 059 FORM_FIELD_DEFINITIONS = List.of( 060 new FieldDefinition("TrainingClassName", FieldType.ENTITY_NAME, true, null, null), 061 new FieldDefinition("EstimatedReadingTime", FieldType.UNSIGNED_LONG, false, null, null), 062 new FieldDefinition("EstimatedReadingTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 063 new FieldDefinition("ReadingTimeAllowed", FieldType.UNSIGNED_LONG, false, null, null), 064 new FieldDefinition("ReadingTimeAllowedUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 065 new FieldDefinition("EstimatedTestingTime", FieldType.UNSIGNED_LONG, false, null, null), 066 new FieldDefinition("EstimatedTestingTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 067 new FieldDefinition("TestingTimeAllowed", FieldType.UNSIGNED_LONG, false, null, null), 068 new FieldDefinition("TestingTimeAllowedUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 069 new FieldDefinition("RequiredCompletionTime", FieldType.UNSIGNED_LONG, false, null, null), 070 new FieldDefinition("RequiredCompletionTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 071 new FieldDefinition("WorkEffortScopeName", FieldType.ENTITY_NAME, false, null, null), 072 new FieldDefinition("DefaultPercentageToPass", FieldType.FRACTIONAL_PERCENT, false, null, null), 073 new FieldDefinition("OverallQuestionCount", FieldType.UNSIGNED_INTEGER, false, null, null), 074 new FieldDefinition("TestingValidityTime", FieldType.UNSIGNED_LONG, false, null, null), 075 new FieldDefinition("TestingValidityTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 076 new FieldDefinition("ExpiredRetentionTime", FieldType.UNSIGNED_LONG, false, null, null), 077 new FieldDefinition("ExpiredRetentionTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null), 078 new FieldDefinition("AlwaysReassignOnExpiration", FieldType.BOOLEAN, true, null, null), 079 new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null), 080 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 081 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L), 082 new FieldDefinition("OverviewMimeTypeName", FieldType.MIME_TYPE, false, null, null), 083 new FieldDefinition("Overview", FieldType.STRING, false, null, null), 084 new FieldDefinition("IntroductionMimeTypeName", FieldType.MIME_TYPE, false, null, null), 085 new FieldDefinition("Introduction", FieldType.STRING, false, null, null) 086 ); 087 } 088 089 /** Creates a new instance of CreateTrainingClassCommand */ 090 public CreateTrainingClassCommand() { 091 super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false); 092 } 093 094 @Override 095 protected BaseResult execute() { 096 var trainingControl = Session.getModelController(TrainingControl.class); 097 var trainingClassName = form.getTrainingClassName(); 098 var trainingClass = trainingControl.getTrainingClassByName(trainingClassName); 099 100 if(trainingClass == null) { 101 var mimeTypeLogic = MimeTypeLogic.getInstance(); 102 var overview = form.getOverview(); 103 var overviewMimeType = mimeTypeLogic.checkMimeType(this, form.getOverviewMimeTypeName(), overview, MimeTypeUsageTypes.TEXT.name(), 104 ExecutionErrors.MissingRequiredOverviewMimeTypeName.name(), ExecutionErrors.MissingRequiredOverview.name(), 105 ExecutionErrors.UnknownOverviewMimeTypeName.name(), ExecutionErrors.UnknownOverviewMimeTypeUsage.name()); 106 107 if(!hasExecutionErrors()) { 108 var introduction = form.getIntroduction(); 109 var introductionMimeType = mimeTypeLogic.checkMimeType(this, form.getIntroductionMimeTypeName(), introduction, MimeTypeUsageTypes.TEXT.name(), 110 ExecutionErrors.MissingRequiredIntroductionMimeTypeName.name(), ExecutionErrors.MissingRequiredIntroduction.name(), 111 ExecutionErrors.UnknownIntroductionMimeTypeName.name(), ExecutionErrors.UnknownIntroductionMimeTypeUsage.name()); 112 113 if(!hasExecutionErrors()) { 114 var unitOfMeasureTypeLogic = UnitOfMeasureTypeLogic.getInstance(); 115 var estimatedReadingTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 116 form.getEstimatedReadingTime(), form.getEstimatedReadingTimeUnitOfMeasureTypeName(), 117 null, ExecutionErrors.MissingRequiredEstimatedReadingTime.name(), null, ExecutionErrors.MissingRequiredEstimatedReadingTimeUnitOfMeasureTypeName.name(), 118 null, ExecutionErrors.UnknownEstimatedReadingTimeUnitOfMeasureTypeName.name()); 119 120 if(!hasExecutionErrors()) { 121 var readingTimeAllowed = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 122 form.getReadingTimeAllowed(), form.getReadingTimeAllowedUnitOfMeasureTypeName(), 123 null, ExecutionErrors.MissingRequiredReadingTimeAllowed.name(), null, ExecutionErrors.MissingRequiredReadingTimeAllowedUnitOfMeasureTypeName.name(), 124 null, ExecutionErrors.UnknownReadingTimeAllowedUnitOfMeasureTypeName.name()); 125 126 if(!hasExecutionErrors()) { 127 var estimatedTestingTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 128 form.getEstimatedTestingTime(), form.getEstimatedTestingTimeUnitOfMeasureTypeName(), 129 null, ExecutionErrors.MissingRequiredEstimatedTestingTime.name(), null, ExecutionErrors.MissingRequiredEstimatedTestingTimeUnitOfMeasureTypeName.name(), 130 null, ExecutionErrors.UnknownEstimatedTestingTimeUnitOfMeasureTypeName.name()); 131 132 if(!hasExecutionErrors()) { 133 var testingTimeAllowed = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 134 form.getTestingTimeAllowed(), form.getTestingTimeAllowedUnitOfMeasureTypeName(), 135 null, ExecutionErrors.MissingRequiredTestingTimeAllowed.name(), null, ExecutionErrors.MissingRequiredTestingTimeAllowedUnitOfMeasureTypeName.name(), 136 null, ExecutionErrors.UnknownTestingTimeAllowedUnitOfMeasureTypeName.name()); 137 138 if(!hasExecutionErrors()) { 139 var requiredCompletionTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 140 form.getRequiredCompletionTime(), form.getRequiredCompletionTimeUnitOfMeasureTypeName(), 141 null, ExecutionErrors.MissingRequiredRequiredCompletionTime.name(), null, ExecutionErrors.MissingRequiredRequiredCompletionTimeUnitOfMeasureTypeName.name(), 142 null, ExecutionErrors.UnknownRequiredCompletionTimeUnitOfMeasureTypeName.name()); 143 144 if(!hasExecutionErrors()) { 145 var workEffortScopeName = form.getWorkEffortScopeName(); 146 WorkEffortScope workEffortScope = null; 147 148 if(workEffortScopeName != null) { 149 var workEffortControl = Session.getModelController(WorkEffortControl.class); 150 var workEffortType = workEffortControl.getWorkEffortTypeByName(TrainingConstants.WorkEffortType_TRAINING); 151 152 if(workEffortType != null) { 153 workEffortScope = workEffortControl.getWorkEffortScopeByName(workEffortType, workEffortScopeName); 154 155 if(workEffortScope == null) { 156 addExecutionError(ExecutionErrors.UnknownWorkEffortScopeName.name(), TrainingConstants.WorkEffortType_TRAINING, 157 workEffortScopeName); 158 } 159 } else { 160 addExecutionError(ExecutionErrors.UnknownWorkEffortTypeName.name(), TrainingConstants.WorkEffortType_TRAINING); 161 } 162 } 163 164 if(!hasExecutionErrors()) { 165 var testingValidityTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 166 form.getTestingValidityTime(), form.getTestingValidityTimeUnitOfMeasureTypeName(), 167 null, ExecutionErrors.MissingRequiredTestingValidityTime.name(), null, ExecutionErrors.MissingRequiredTestingValidityTimeUnitOfMeasureTypeName.name(), 168 null, ExecutionErrors.UnknownTestingValidityTimeUnitOfMeasureTypeName.name()); 169 170 if(!hasExecutionErrors()) { 171 var expiredRetentionTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME, 172 form.getExpiredRetentionTime(), form.getExpiredRetentionTimeUnitOfMeasureTypeName(), 173 null, ExecutionErrors.MissingRequiredExpiredRetentionTime.name(), null, ExecutionErrors.MissingRequiredExpiredRetentionTimeUnitOfMeasureTypeName.name(), 174 null, ExecutionErrors.UnknownExpiredRetentionTimeUnitOfMeasureTypeName.name()); 175 176 if(!hasExecutionErrors()) { 177 var createdBy = getPartyPK(); 178 var strDefaultPercentageToPass = form.getDefaultPercentageToPass(); 179 var defaultPercentageToPass = strDefaultPercentageToPass == null ? null : Integer.valueOf(strDefaultPercentageToPass); 180 var strOverallQuestionCount = form.getOverallQuestionCount(); 181 var overallQuestionCount = strOverallQuestionCount == null ? null : Integer.valueOf(strOverallQuestionCount); 182 var alwaysReassignOnExpiration = Boolean.valueOf(form.getAlwaysReassignOnExpiration()); 183 var isDefault = Boolean.valueOf(form.getIsDefault()); 184 var sortOrder = Integer.valueOf(form.getSortOrder()); 185 var description = form.getDescription(); 186 187 trainingClass = trainingControl.createTrainingClass(trainingClassName, estimatedReadingTime, 188 readingTimeAllowed, estimatedTestingTime, testingTimeAllowed, requiredCompletionTime, 189 workEffortScope, defaultPercentageToPass, overallQuestionCount, testingValidityTime, 190 expiredRetentionTime, alwaysReassignOnExpiration, isDefault, sortOrder, createdBy); 191 192 if(description != null || overview != null || introduction != null) { 193 trainingControl.createTrainingClassTranslation(trainingClass, getPreferredLanguage(), description, 194 overviewMimeType, overview, introductionMimeType, introduction, createdBy); 195 } 196 } 197 } 198 } 199 } 200 } 201 } 202 } 203 } 204 } 205 } 206 } else { 207 addExecutionError(ExecutionErrors.DuplicateTrainingClassName.name(), trainingClassName); 208 } 209 210 return null; 211 } 212 213}