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