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.model.control.training.server.logic; 018 019import com.echothree.control.user.training.common.spec.TrainingClassUniversalSpec; 020import com.echothree.model.control.core.common.ComponentVendors; 021import com.echothree.model.control.core.common.EntityTypes; 022import com.echothree.model.control.core.common.exception.InvalidParameterCountException; 023import com.echothree.model.control.core.server.logic.EntityInstanceLogic; 024import com.echothree.model.control.training.common.exception.CannotDeleteTrainingClassInUseException; 025import com.echothree.model.control.training.common.exception.DuplicateTrainingClassNameException; 026import com.echothree.model.control.training.common.exception.UnknownDefaultTrainingClassException; 027import com.echothree.model.control.training.common.exception.UnknownTrainingClassNameException; 028import com.echothree.model.control.training.server.control.TrainingControl; 029import com.echothree.model.data.core.server.entity.MimeType; 030import com.echothree.model.data.party.server.entity.Language; 031import com.echothree.model.data.training.server.entity.TrainingClass; 032import com.echothree.model.data.workeffort.server.entity.WorkEffortScope; 033import com.echothree.util.common.message.ExecutionErrors; 034import com.echothree.util.common.persistence.BasePK; 035import com.echothree.util.server.control.BaseLogic; 036import com.echothree.util.server.message.ExecutionErrorAccumulator; 037import com.echothree.util.server.persistence.EntityPermission; 038import javax.enterprise.context.ApplicationScoped; 039import javax.enterprise.inject.spi.CDI; 040import javax.inject.Inject; 041 042@ApplicationScoped 043public class TrainingClassLogic 044 extends BaseLogic { 045 046 @Inject 047 private TrainingControl trainingControl; 048 049 @Inject 050 EntityInstanceLogic entityInstanceLogic; 051 052 protected TrainingClassLogic() { 053 super(); 054 } 055 056 public static TrainingClassLogic getInstance() { 057 return CDI.current().select(TrainingClassLogic.class).get(); 058 } 059 060 public TrainingClass createTrainingClass(final ExecutionErrorAccumulator eea, final String trainingClassName, 061 final Long estimatedReadingTime, final Long readingTimeAllowed, final Long estimatedTestingTime, 062 final Long testingTimeAllowed, final Long requiredCompletionTime, final WorkEffortScope workEffortScope, 063 final Integer defaultPercentageToPass, final Integer overallQuestionCount, final Long testingValidityTime, 064 final Long expiredRetentionTime, final Boolean alwaysReassignOnExpiration, final Boolean isDefault, 065 final Integer sortOrder, final Language language, final String description, 066 final MimeType overviewMimeType, final String overview, 067 final MimeType introductionMimeType, final String introduction, 068 final BasePK createdBy) { 069 var trainingClass = trainingControl.getTrainingClassByName(trainingClassName); 070 071 if(trainingClass == null) { 072 trainingClass = trainingControl.createTrainingClass(trainingClassName, estimatedReadingTime, 073 readingTimeAllowed, estimatedTestingTime, testingTimeAllowed, requiredCompletionTime, 074 workEffortScope, defaultPercentageToPass, overallQuestionCount, testingValidityTime, 075 expiredRetentionTime, alwaysReassignOnExpiration, isDefault, sortOrder, createdBy); 076 077 if(description != null || overview != null || introduction != null) { 078 trainingControl.createTrainingClassTranslation(trainingClass, language, description, 079 overviewMimeType, overview, introductionMimeType, introduction, createdBy); 080 } 081 } else { 082 handleExecutionError(DuplicateTrainingClassNameException.class, eea, ExecutionErrors.DuplicateTrainingClassName.name(), trainingClassName); 083 } 084 085 return trainingClass; 086 } 087 088 private TrainingClass getTrainingClassByName(final ExecutionErrorAccumulator eea, final String trainingClassName, 089 final boolean allowDefault, final EntityPermission entityPermission) { 090 TrainingClass trainingClass = null; 091 092 if(trainingClassName == null) { 093 if(allowDefault) { 094 trainingClass = trainingControl.getDefaultTrainingClass(entityPermission); 095 096 if(trainingClass == null) { 097 handleExecutionError(UnknownDefaultTrainingClassException.class, eea, ExecutionErrors.UnknownDefaultTrainingClass.name()); 098 } 099 } else { 100 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 101 } 102 } else { 103 trainingClass = trainingControl.getTrainingClassByName(trainingClassName, entityPermission); 104 105 if(trainingClass == null) { 106 handleExecutionError(UnknownTrainingClassNameException.class, eea, ExecutionErrors.UnknownTrainingClassName.name(), trainingClassName); 107 } 108 } 109 110 return trainingClass; 111 } 112 113 public TrainingClass getTrainingClassByName(final ExecutionErrorAccumulator eea, final String trainingClassName, 114 final boolean allowDefault) { 115 return getTrainingClassByName(eea, trainingClassName, allowDefault, EntityPermission.READ_ONLY); 116 } 117 118 public TrainingClass getTrainingClassByNameForUpdate(final ExecutionErrorAccumulator eea, final String trainingClassName, 119 final boolean allowDefault) { 120 return getTrainingClassByName(eea, trainingClassName, allowDefault, EntityPermission.READ_WRITE); 121 } 122 123 public TrainingClass getTrainingClassByUniversalSpec(final ExecutionErrorAccumulator eea, 124 final TrainingClassUniversalSpec universalSpec, final boolean allowDefault, final EntityPermission entityPermission) { 125 TrainingClass trainingClass = null; 126 var trainingClassName = universalSpec.getTrainingClassName(); 127 var parameterCount = (trainingClassName == null ? 0 : 1) + entityInstanceLogic.countPossibleEntitySpecs(universalSpec); 128 129 switch(parameterCount) { 130 case 0 -> trainingClass = getTrainingClassByName(eea, null, allowDefault, entityPermission); 131 case 1 -> { 132 if(trainingClassName == null) { 133 var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec, 134 ComponentVendors.ECHO_THREE.name(), EntityTypes.TrainingClass.name()); 135 136 if(eea == null || !eea.hasExecutionErrors()) { 137 trainingClass = trainingControl.getTrainingClassByEntityInstance(entityInstance, entityPermission); 138 } 139 } else { 140 trainingClass = getTrainingClassByName(eea, trainingClassName, false, entityPermission); 141 } 142 } 143 default -> 144 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 145 } 146 147 return trainingClass; 148 } 149 150 public TrainingClass getTrainingClassByUniversalSpec(final ExecutionErrorAccumulator eea, 151 final TrainingClassUniversalSpec universalSpec, final boolean allowDefault) { 152 return getTrainingClassByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY); 153 } 154 155 public TrainingClass getTrainingClassByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, 156 final TrainingClassUniversalSpec universalSpec, final boolean allowDefault) { 157 return getTrainingClassByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE); 158 } 159 160 public void deleteTrainingClass(final ExecutionErrorAccumulator eea, final TrainingClass trainingClass, 161 final BasePK deletedBy) { 162 var trainingClassSectionCount = trainingControl.countTrainingClassSectionsByTrainingClass(trainingClass); 163 164 if(trainingClassSectionCount == 0) { 165 trainingControl.deleteTrainingClass(trainingClass, deletedBy); 166 } else { 167 handleExecutionError(CannotDeleteTrainingClassInUseException.class, eea, ExecutionErrors.CannotDeleteTrainingClassInUse.name(), 168 trainingClass.getLastDetail().getTrainingClassName()); 169 } 170 } 171 172}