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