001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 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.edit.TrainingClassEdit;
020import com.echothree.control.user.training.common.edit.TrainingEditFactory;
021import com.echothree.control.user.training.common.form.EditTrainingClassForm;
022import com.echothree.control.user.training.common.result.EditTrainingClassResult;
023import com.echothree.control.user.training.common.result.TrainingResultFactory;
024import com.echothree.control.user.training.common.spec.TrainingClassSpec;
025import com.echothree.model.control.core.common.MimeTypeUsageTypes;
026import com.echothree.model.control.core.server.logic.MimeTypeLogic;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.control.security.common.SecurityRoleGroups;
029import com.echothree.model.control.security.common.SecurityRoles;
030import com.echothree.model.control.training.server.control.TrainingControl;
031import com.echothree.model.control.uom.common.UomConstants;
032import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic;
033import com.echothree.model.control.workeffort.common.workeffort.TrainingConstants;
034import com.echothree.model.control.workeffort.server.control.WorkEffortControl;
035import com.echothree.model.data.core.server.entity.MimeType;
036import com.echothree.model.data.training.server.entity.TrainingClass;
037import com.echothree.model.data.user.common.pk.UserVisitPK;
038import com.echothree.model.data.workeffort.server.entity.WorkEffortScope;
039import com.echothree.util.common.message.ExecutionErrors;
040import com.echothree.util.common.validation.FieldDefinition;
041import com.echothree.util.common.validation.FieldType;
042import com.echothree.util.common.command.EditMode;
043import com.echothree.util.server.control.BaseAbstractEditCommand;
044import com.echothree.util.server.control.CommandSecurityDefinition;
045import com.echothree.util.server.control.PartyTypeDefinition;
046import com.echothree.util.server.control.SecurityRoleDefinition;
047import com.echothree.util.server.persistence.Session;
048import com.echothree.util.server.string.PercentUtils;
049import java.util.Arrays;
050import java.util.Collections;
051import java.util.List;
052import javax.enterprise.context.RequestScoped;
053
054@RequestScoped
055public class EditTrainingClassCommand
056        extends BaseAbstractEditCommand<TrainingClassSpec, TrainingClassEdit, EditTrainingClassResult, TrainingClass, TrainingClass> {
057    
058    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
059    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
060    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
061    
062    static {
063        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList(
064                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
065                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList(
066                        new SecurityRoleDefinition(SecurityRoleGroups.TrainingClass.name(), SecurityRoles.Edit.name())
067                        )))
068                )));
069
070        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
071                new FieldDefinition("TrainingClassName", FieldType.ENTITY_NAME, true, null, null)
072                ));
073
074        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
075                new FieldDefinition("TrainingClassName", FieldType.ENTITY_NAME, true, null, null),
076                new FieldDefinition("EstimatedReadingTime", FieldType.UNSIGNED_LONG, false, null, null),
077                new FieldDefinition("EstimatedReadingTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
078                new FieldDefinition("ReadingTimeAllowed", FieldType.UNSIGNED_LONG, false, null, null),
079                new FieldDefinition("ReadingTimeAllowedUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
080                new FieldDefinition("EstimatedTestingTime", FieldType.UNSIGNED_LONG, false, null, null),
081                new FieldDefinition("EstimatedTestingTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
082                new FieldDefinition("TestingTimeAllowed", FieldType.UNSIGNED_LONG, false, null, null),
083                new FieldDefinition("TestingTimeAllowedUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
084                new FieldDefinition("RequiredCompletionTime", FieldType.UNSIGNED_LONG, false, null, null),
085                new FieldDefinition("RequiredCompletionTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
086                new FieldDefinition("WorkEffortScopeName", FieldType.ENTITY_NAME, false, null, null),
087                new FieldDefinition("DefaultPercentageToPass", FieldType.FRACTIONAL_PERCENT, false, null, null),
088                new FieldDefinition("OverallQuestionCount", FieldType.UNSIGNED_INTEGER, false, null, null),
089                new FieldDefinition("TestingValidityTime", FieldType.UNSIGNED_LONG, false, null, null),
090                new FieldDefinition("TestingValidityTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
091                new FieldDefinition("ExpiredRetentionTime", FieldType.UNSIGNED_LONG, false, null, null),
092                new FieldDefinition("ExpiredRetentionTimeUnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
093                new FieldDefinition("AlwaysReassignOnExpiration", FieldType.BOOLEAN, true, null, null),
094                new FieldDefinition("IsDefault", FieldType.BOOLEAN, true, null, null),
095                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
096                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L),
097                new FieldDefinition("OverviewMimeTypeName", FieldType.MIME_TYPE, false, null, null),
098                new FieldDefinition("Overview", FieldType.STRING, false, null, null),
099                new FieldDefinition("IntroductionMimeTypeName", FieldType.MIME_TYPE, false, null, null),
100                new FieldDefinition("Introduction", FieldType.STRING, false, null, null)
101                ));
102    }
103    
104    /** Creates a new instance of EditTrainingClassCommand */
105    public EditTrainingClassCommand() {
106        super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
107    }
108    
109    @Override
110    public EditTrainingClassResult getResult() {
111        return TrainingResultFactory.getEditTrainingClassResult();
112    }
113
114    @Override
115    public TrainingClassEdit getEdit() {
116        return TrainingEditFactory.getTrainingClassEdit();
117    }
118
119    @Override
120    public TrainingClass getEntity(EditTrainingClassResult result) {
121        var trainingControl = Session.getModelController(TrainingControl.class);
122        TrainingClass trainingClass;
123        var trainingClassName = spec.getTrainingClassName();
124
125        if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
126            trainingClass = trainingControl.getTrainingClassByName(trainingClassName);
127        } else { // EditMode.UPDATE
128            trainingClass = trainingControl.getTrainingClassByNameForUpdate(trainingClassName);
129        }
130
131        if(trainingClass != null) {
132            result.setTrainingClass(trainingControl.getTrainingClassTransfer(getUserVisit(), trainingClass));
133        } else {
134            addExecutionError(ExecutionErrors.UnknownTrainingClassName.name(), trainingClassName);
135        }
136
137        return trainingClass;
138    }
139
140    @Override
141    public TrainingClass getLockEntity(TrainingClass trainingClass) {
142        return trainingClass;
143    }
144
145    @Override
146    public void fillInResult(EditTrainingClassResult result, TrainingClass trainingClass) {
147        var trainingControl = Session.getModelController(TrainingControl.class);
148
149        result.setTrainingClass(trainingControl.getTrainingClassTransfer(getUserVisit(), trainingClass));
150    }
151
152    MimeType overviewMimeType;
153    MimeType introductionMimeType;
154    
155    @Override
156    public void doLock(TrainingClassEdit edit, TrainingClass trainingClass) {
157        var trainingControl = Session.getModelController(TrainingControl.class);
158        var unitOfMeasureTypeLogic = UnitOfMeasureTypeLogic.getInstance();
159        var trainingClassTranslation = trainingControl.getTrainingClassTranslation(trainingClass, getPreferredLanguage());
160        var trainingClassDetail = trainingClass.getLastDetail();
161        var workEffortScope = trainingClassDetail.getWorkEffortScope();
162        var overallQuestionCount = trainingClassDetail.getOverallQuestionCount();
163        UnitOfMeasureTypeLogic.StringUnitOfMeasure stringUnitOfMeasure;
164
165        edit.setTrainingClassName(trainingClassDetail.getTrainingClassName());
166        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getEstimatedReadingTime());
167        edit.setEstimatedReadingTimeUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
168        edit.setEstimatedReadingTime(stringUnitOfMeasure.getValue());
169        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getReadingTimeAllowed());
170        edit.setReadingTimeAllowedUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
171        edit.setReadingTimeAllowed(stringUnitOfMeasure.getValue());
172        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getEstimatedTestingTime());
173        edit.setEstimatedTestingTimeUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
174        edit.setEstimatedTestingTime(stringUnitOfMeasure.getValue());
175        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getTestingTimeAllowed());
176        edit.setTestingTimeAllowedUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
177        edit.setTestingTimeAllowed(stringUnitOfMeasure.getValue());
178        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getRequiredCompletionTime());
179        edit.setRequiredCompletionTimeUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
180        edit.setRequiredCompletionTime(stringUnitOfMeasure.getValue());
181        edit.setWorkEffortScopeName(workEffortScope == null ? null : workEffortScope.getLastDetail().getWorkEffortScopeName());
182        edit.setDefaultPercentageToPass(PercentUtils.getInstance().formatFractionalPercent(trainingClassDetail.getDefaultPercentageToPass()));
183        edit.setOverallQuestionCount(overallQuestionCount == null? null: overallQuestionCount.toString());
184        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getTestingValidityTime());
185        edit.setTestingValidityTimeUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
186        edit.setTestingValidityTime(stringUnitOfMeasure.getValue());
187        stringUnitOfMeasure = unitOfMeasureTypeLogic.unitOfMeasureToString(this, UomConstants.UnitOfMeasureKindUseType_TIME, trainingClassDetail.getExpiredRetentionTime());
188        edit.setExpiredRetentionTimeUnitOfMeasureTypeName(stringUnitOfMeasure.getUnitOfMeasureTypeName());
189        edit.setExpiredRetentionTime(stringUnitOfMeasure.getValue());
190        edit.setAlwaysReassignOnExpiration(trainingClassDetail.getAlwaysReassignOnExpiration().toString());
191        edit.setIsDefault(trainingClassDetail.getIsDefault().toString());
192        edit.setSortOrder(trainingClassDetail.getSortOrder().toString());
193
194        if(trainingClassTranslation != null) {
195            overviewMimeType = trainingClassTranslation.getOverviewMimeType();
196            introductionMimeType = trainingClassTranslation.getIntroductionMimeType();
197
198            edit.setDescription(trainingClassTranslation.getDescription());
199            edit.setOverviewMimeTypeName(overviewMimeType == null? null: overviewMimeType.getLastDetail().getMimeTypeName());
200            edit.setOverview(trainingClassTranslation.getOverview());
201            edit.setIntroductionMimeTypeName(introductionMimeType == null? null: introductionMimeType.getLastDetail().getMimeTypeName());
202            edit.setIntroduction(trainingClassTranslation.getIntroduction());
203        }
204    }
205
206    Long estimatedReadingTime;
207    Long readingTimeAllowed;
208    Long estimatedTestingTime;
209    Long testingTimeAllowed;
210    Long requiredCompletionTime;
211    WorkEffortScope workEffortScope;
212    Long testingValidityTime;
213    Long expiredRetentionTime;
214    
215    @Override
216    public void canUpdate(TrainingClass trainingClass) {
217        var trainingControl = Session.getModelController(TrainingControl.class);
218        var trainingClassName = edit.getTrainingClassName();
219        var duplicateTrainingClass = trainingControl.getTrainingClassByName(trainingClassName);
220
221        if(duplicateTrainingClass != null && !trainingClass.equals(duplicateTrainingClass)) {
222            addExecutionError(ExecutionErrors.DuplicateTrainingClassName.name(), trainingClassName);
223        } else {
224            var mimeTypeLogic = MimeTypeLogic.getInstance();
225            var overviewMimeTypeName = edit.getOverviewMimeTypeName();
226            var overview = edit.getOverview();
227
228            overviewMimeType = mimeTypeLogic.checkMimeType(this, overviewMimeTypeName, overview, MimeTypeUsageTypes.TEXT.name(),
229                    ExecutionErrors.MissingRequiredOverviewMimeTypeName.name(), ExecutionErrors.MissingRequiredOverview.name(),
230                    ExecutionErrors.UnknownOverviewMimeTypeName.name(), ExecutionErrors.UnknownOverviewMimeTypeUsage.name());
231
232            if(!hasExecutionErrors()) {
233                var introductionMimeTypeName = edit.getIntroductionMimeTypeName();
234                var introduction = edit.getIntroduction();
235
236                introductionMimeType = mimeTypeLogic.checkMimeType(this, introductionMimeTypeName, introduction, MimeTypeUsageTypes.TEXT.name(),
237                        ExecutionErrors.MissingRequiredIntroductionMimeTypeName.name(), ExecutionErrors.MissingRequiredIntroduction.name(),
238                        ExecutionErrors.UnknownIntroductionMimeTypeName.name(), ExecutionErrors.UnknownIntroductionMimeTypeUsage.name());
239
240                if(!hasExecutionErrors()) {
241                    var unitOfMeasureTypeLogic = UnitOfMeasureTypeLogic.getInstance();
242
243                    estimatedReadingTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
244                            edit.getEstimatedReadingTime(), edit.getEstimatedReadingTimeUnitOfMeasureTypeName(),
245                            null, ExecutionErrors.MissingRequiredEstimatedReadingTime.name(), null, ExecutionErrors.MissingRequiredEstimatedReadingTimeUnitOfMeasureTypeName.name(),
246                            null, ExecutionErrors.UnknownEstimatedReadingTimeUnitOfMeasureTypeName.name());
247
248                    if(!hasExecutionErrors()) {
249                        readingTimeAllowed = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
250                                edit.getReadingTimeAllowed(), edit.getReadingTimeAllowedUnitOfMeasureTypeName(),
251                                null, ExecutionErrors.MissingRequiredReadingTimeAllowed.name(), null, ExecutionErrors.MissingRequiredReadingTimeAllowedUnitOfMeasureTypeName.name(),
252                                null, ExecutionErrors.UnknownReadingTimeAllowedUnitOfMeasureTypeName.name());
253
254                        if(!hasExecutionErrors()) {
255                            estimatedTestingTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
256                                    edit.getEstimatedTestingTime(), edit.getEstimatedTestingTimeUnitOfMeasureTypeName(),
257                                    null, ExecutionErrors.MissingRequiredEstimatedTestingTime.name(), null, ExecutionErrors.MissingRequiredEstimatedTestingTimeUnitOfMeasureTypeName.name(),
258                                    null, ExecutionErrors.UnknownEstimatedTestingTimeUnitOfMeasureTypeName.name());
259
260                            if(!hasExecutionErrors()) {
261                                testingTimeAllowed = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
262                                        edit.getTestingTimeAllowed(), edit.getTestingTimeAllowedUnitOfMeasureTypeName(),
263                                        null, ExecutionErrors.MissingRequiredTestingTimeAllowed.name(), null, ExecutionErrors.MissingRequiredTestingTimeAllowedUnitOfMeasureTypeName.name(),
264                                        null, ExecutionErrors.UnknownTestingTimeAllowedUnitOfMeasureTypeName.name());
265
266                                if(!hasExecutionErrors()) {
267                                    requiredCompletionTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
268                                            edit.getRequiredCompletionTime(), edit.getRequiredCompletionTimeUnitOfMeasureTypeName(),
269                                            null, ExecutionErrors.MissingRequiredRequiredCompletionTime.name(), null, ExecutionErrors.MissingRequiredRequiredCompletionTimeUnitOfMeasureTypeName.name(),
270                                            null, ExecutionErrors.UnknownRequiredCompletionTimeUnitOfMeasureTypeName.name());
271
272                                    if(!hasExecutionErrors()) {
273                                        var workEffortScopeName = edit.getWorkEffortScopeName();
274
275                                        if(workEffortScopeName != null) {
276                                            var workEffortControl = Session.getModelController(WorkEffortControl.class);
277                                            var workEffortType = workEffortControl.getWorkEffortTypeByName(TrainingConstants.WorkEffortType_TRAINING);
278
279                                            if(workEffortType != null) {
280                                                workEffortScope = workEffortControl.getWorkEffortScopeByName(workEffortType, workEffortScopeName);
281
282                                                if(workEffortScope == null) {
283                                                    addExecutionError(ExecutionErrors.UnknownWorkEffortScopeName.name(), TrainingConstants.WorkEffortType_TRAINING,
284                                                            workEffortScopeName);
285                                                }
286                                            } else {
287                                                addExecutionError(ExecutionErrors.UnknownWorkEffortTypeName.name(), TrainingConstants.WorkEffortType_TRAINING);
288                                            }
289                                        }
290
291                                        if(!hasExecutionErrors()) {
292                                            testingValidityTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
293                                                    edit.getTestingValidityTime(), edit.getTestingValidityTimeUnitOfMeasureTypeName(),
294                                                    null, ExecutionErrors.MissingRequiredTestingValidityTime.name(), null, ExecutionErrors.MissingRequiredTestingValidityTimeUnitOfMeasureTypeName.name(),
295                                                    null, ExecutionErrors.UnknownTestingValidityTimeUnitOfMeasureTypeName.name());
296
297                                            if(!hasExecutionErrors()) {
298                                                expiredRetentionTime = unitOfMeasureTypeLogic.checkUnitOfMeasure(this, UomConstants.UnitOfMeasureKindUseType_TIME,
299                                                        edit.getExpiredRetentionTime(), edit.getExpiredRetentionTimeUnitOfMeasureTypeName(),
300                                                        null, ExecutionErrors.MissingRequiredExpiredRetentionTime.name(), null, ExecutionErrors.MissingRequiredExpiredRetentionTimeUnitOfMeasureTypeName.name(),
301                                                        null, ExecutionErrors.UnknownExpiredRetentionTimeUnitOfMeasureTypeName.name());
302                                            }
303                                        }
304                                    }
305                                }
306                            }
307                        }
308                    }
309                }
310            }
311        }
312    }
313    
314    @Override
315    public void doUpdate(TrainingClass trainingClass) {
316        var trainingControl = Session.getModelController(TrainingControl.class);
317        var partyPK = getPartyPK();
318        var trainingClassDetailValue = trainingControl.getTrainingClassDetailValueForUpdate(trainingClass);
319        var trainingClassTranslation = trainingControl.getTrainingClassTranslationForUpdate(trainingClass, getPreferredLanguage());
320        var defaultPercentageToPass = edit.getDefaultPercentageToPass();
321        var overallQuestionCount = edit.getOverallQuestionCount();
322        var description = edit.getDescription();
323        var overview = edit.getOverview();
324        var introduction = edit.getIntroduction();
325
326        trainingClassDetailValue.setTrainingClassName(edit.getTrainingClassName());
327        trainingClassDetailValue.setEstimatedReadingTime(estimatedReadingTime);
328        trainingClassDetailValue.setReadingTimeAllowed(readingTimeAllowed);
329        trainingClassDetailValue.setEstimatedTestingTime(estimatedTestingTime);
330        trainingClassDetailValue.setTestingTimeAllowed(testingTimeAllowed);
331        trainingClassDetailValue.setRequiredCompletionTime(requiredCompletionTime);
332        trainingClassDetailValue.setWorkEffortScopePK(workEffortScope == null ? null : workEffortScope.getPrimaryKey());
333        trainingClassDetailValue.setDefaultPercentageToPass(defaultPercentageToPass == null? null: Integer.valueOf(defaultPercentageToPass));
334        trainingClassDetailValue.setOverallQuestionCount(overallQuestionCount == null? null: Integer.valueOf(overallQuestionCount));
335        trainingClassDetailValue.setTestingValidityTime(testingValidityTime);
336        trainingClassDetailValue.setExpiredRetentionTime(expiredRetentionTime);
337        trainingClassDetailValue.setAlwaysReassignOnExpiration(Boolean.valueOf(edit.getAlwaysReassignOnExpiration()));
338        trainingClassDetailValue.setIsDefault(Boolean.valueOf(edit.getIsDefault()));
339        trainingClassDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder()));
340
341        trainingControl.updateTrainingClassFromValue(trainingClassDetailValue, partyPK);
342
343        if(trainingClassTranslation == null && (description != null || overview != null || introduction != null)) {
344            trainingControl.createTrainingClassTranslation(trainingClass, getPreferredLanguage(), description, overviewMimeType, overview, introductionMimeType,
345                    introduction, partyPK);
346        } else if(trainingClassTranslation != null && (description == null && overview == null && introduction == null)) {
347            trainingControl.deleteTrainingClassTranslation(trainingClassTranslation, partyPK);
348        } else if(trainingClassTranslation != null && (description != null || overview != null || introduction != null)) {
349            var trainingClassTranslationValue = trainingControl.getTrainingClassTranslationValue(trainingClassTranslation);
350
351            trainingClassTranslationValue.setDescription(description);
352            trainingClassTranslationValue.setOverviewMimeTypePK(overviewMimeType == null? null: overviewMimeType.getPrimaryKey());
353            trainingClassTranslationValue.setOverview(overview);
354            trainingClassTranslationValue.setIntroductionMimeTypePK(introductionMimeType == null? null: introductionMimeType.getPrimaryKey());
355            trainingClassTranslationValue.setIntroduction(introduction);
356            trainingControl.updateTrainingClassTranslationFromValue(trainingClassTranslationValue, partyPK);
357        }
358    }
359
360}