001// -------------------------------------------------------------------------------- 002// Copyright 2002-2024 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.TrainingClassSectionEdit; 020import com.echothree.control.user.training.common.edit.TrainingEditFactory; 021import com.echothree.control.user.training.common.form.EditTrainingClassSectionForm; 022import com.echothree.control.user.training.common.result.EditTrainingClassSectionResult; 023import com.echothree.control.user.training.common.result.TrainingResultFactory; 024import com.echothree.control.user.training.common.spec.TrainingClassSectionSpec; 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.data.core.server.entity.MimeType; 032import com.echothree.model.data.training.server.entity.TrainingClass; 033import com.echothree.model.data.training.server.entity.TrainingClassSection; 034import com.echothree.model.data.training.server.entity.TrainingClassSectionDetail; 035import com.echothree.model.data.training.server.entity.TrainingClassSectionTranslation; 036import com.echothree.model.data.training.server.value.TrainingClassSectionDetailValue; 037import com.echothree.model.data.training.server.value.TrainingClassSectionTranslationValue; 038import com.echothree.model.data.user.common.pk.UserVisitPK; 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; 052 053public class EditTrainingClassSectionCommand 054 extends BaseAbstractEditCommand<TrainingClassSectionSpec, TrainingClassSectionEdit, EditTrainingClassSectionResult, TrainingClassSection, TrainingClassSection> { 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(Collections.unmodifiableList(Arrays.asList( 062 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 063 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList( 064 new SecurityRoleDefinition(SecurityRoleGroups.TrainingClassSection.name(), SecurityRoles.Edit.name()) 065 ))) 066 ))); 067 068 SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 069 new FieldDefinition("TrainingClassName", FieldType.ENTITY_NAME, true, null, null), 070 new FieldDefinition("TrainingClassSectionName", FieldType.ENTITY_NAME, true, null, null) 071 )); 072 073 EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 074 new FieldDefinition("TrainingClassSectionName", FieldType.ENTITY_NAME, true, null, null), 075 new FieldDefinition("PercentageToPass", FieldType.FRACTIONAL_PERCENT, false, null, null), 076 new FieldDefinition("QuestionCount", FieldType.UNSIGNED_INTEGER, false, null, null), 077 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 078 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L), 079 new FieldDefinition("OverviewMimeTypeName", FieldType.MIME_TYPE, false, null, null), 080 new FieldDefinition("Overview", FieldType.STRING, false, null, null), 081 new FieldDefinition("IntroductionMimeTypeName", FieldType.MIME_TYPE, false, null, null), 082 new FieldDefinition("Introduction", FieldType.STRING, false, null, null) 083 )); 084 } 085 086 /** Creates a new instance of EditTrainingClassSectionCommand */ 087 public EditTrainingClassSectionCommand(UserVisitPK userVisitPK, EditTrainingClassSectionForm form) { 088 super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 089 } 090 091 @Override 092 public EditTrainingClassSectionResult getResult() { 093 return TrainingResultFactory.getEditTrainingClassSectionResult(); 094 } 095 096 @Override 097 public TrainingClassSectionEdit getEdit() { 098 return TrainingEditFactory.getTrainingClassSectionEdit(); 099 } 100 101 TrainingClass trainingClass; 102 103 @Override 104 public TrainingClassSection getEntity(EditTrainingClassSectionResult result) { 105 var trainingControl = Session.getModelController(TrainingControl.class); 106 TrainingClassSection trainingClassSection = null; 107 String trainingClassName = spec.getTrainingClassName(); 108 109 trainingClass = trainingControl.getTrainingClassByName(trainingClassName); 110 111 if(trainingClass != null) { 112 String trainingClassSectionName = spec.getTrainingClassSectionName(); 113 114 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 115 trainingClassSection = trainingControl.getTrainingClassSectionByName(trainingClass, trainingClassSectionName); 116 } else { // EditMode.UPDATE 117 trainingClassSection = trainingControl.getTrainingClassSectionByNameForUpdate(trainingClass, trainingClassSectionName); 118 } 119 120 if(trainingClassSection != null) { 121 result.setTrainingClassSection(trainingControl.getTrainingClassSectionTransfer(getUserVisit(), trainingClassSection)); 122 } else { 123 addExecutionError(ExecutionErrors.UnknownTrainingClassSectionName.name(), trainingClassName, trainingClassSectionName); 124 } 125 } else { 126 addExecutionError(ExecutionErrors.UnknownTrainingClassName.name(), trainingClassName); 127 } 128 129 return trainingClassSection; 130 } 131 132 @Override 133 public TrainingClassSection getLockEntity(TrainingClassSection trainingClassSection) { 134 return trainingClassSection; 135 } 136 137 @Override 138 public void fillInResult(EditTrainingClassSectionResult result, TrainingClassSection trainingClassSection) { 139 var trainingControl = Session.getModelController(TrainingControl.class); 140 141 result.setTrainingClassSection(trainingControl.getTrainingClassSectionTransfer(getUserVisit(), trainingClassSection)); 142 } 143 144 MimeType overviewMimeType; 145 MimeType introductionMimeType; 146 147 @Override 148 public void doLock(TrainingClassSectionEdit edit, TrainingClassSection trainingClassSection) { 149 var trainingControl = Session.getModelController(TrainingControl.class); 150 TrainingClassSectionTranslation trainingClassSectionTranslation = trainingControl.getTrainingClassSectionTranslation(trainingClassSection, getPreferredLanguage()); 151 TrainingClassSectionDetail trainingClassSectionDetail = trainingClassSection.getLastDetail(); 152 Integer questionCount = trainingClassSectionDetail.getQuestionCount(); 153 154 edit.setTrainingClassSectionName(trainingClassSectionDetail.getTrainingClassSectionName()); 155 edit.setPercentageToPass(PercentUtils.getInstance().formatFractionalPercent(trainingClassSectionDetail.getPercentageToPass())); 156 edit.setQuestionCount(questionCount == null? null: questionCount.toString()); 157 edit.setSortOrder(trainingClassSectionDetail.getSortOrder().toString()); 158 159 if(trainingClassSectionTranslation != null) { 160 overviewMimeType = trainingClassSectionTranslation.getOverviewMimeType(); 161 introductionMimeType = trainingClassSectionTranslation.getIntroductionMimeType(); 162 163 edit.setDescription(trainingClassSectionTranslation.getDescription()); 164 edit.setOverviewMimeTypeName(overviewMimeType == null? null: overviewMimeType.getLastDetail().getMimeTypeName()); 165 edit.setOverview(trainingClassSectionTranslation.getOverview()); 166 edit.setIntroductionMimeTypeName(introductionMimeType == null? null: introductionMimeType.getLastDetail().getMimeTypeName()); 167 edit.setIntroduction(trainingClassSectionTranslation.getIntroduction()); 168 } 169 } 170 171 @Override 172 public void canUpdate(TrainingClassSection trainingClassSection) { 173 var trainingControl = Session.getModelController(TrainingControl.class); 174 String trainingClassSectionName = edit.getTrainingClassSectionName(); 175 TrainingClassSection duplicateTrainingClassSection = trainingControl.getTrainingClassSectionByName(trainingClass, trainingClassSectionName); 176 177 if(duplicateTrainingClassSection != null && !trainingClassSection.equals(duplicateTrainingClassSection)) { 178 addExecutionError(ExecutionErrors.DuplicateTrainingClassSectionName.name(), trainingClassSectionName); 179 } else { 180 MimeTypeLogic mimeTypeLogic = MimeTypeLogic.getInstance(); 181 String overviewMimeTypeName = edit.getOverviewMimeTypeName(); 182 String overview = edit.getOverview(); 183 184 overviewMimeType = mimeTypeLogic.checkMimeType(this, overviewMimeTypeName, overview, MimeTypeUsageTypes.TEXT.name(), 185 ExecutionErrors.MissingRequiredOverviewMimeTypeName.name(), ExecutionErrors.MissingRequiredOverview.name(), 186 ExecutionErrors.UnknownOverviewMimeTypeName.name(), ExecutionErrors.UnknownOverviewMimeTypeUsage.name()); 187 188 if(!hasExecutionErrors()) { 189 String introductionMimeTypeName = edit.getIntroductionMimeTypeName(); 190 String introduction = edit.getIntroduction(); 191 192 introductionMimeType = mimeTypeLogic.checkMimeType(this, introductionMimeTypeName, introduction, MimeTypeUsageTypes.TEXT.name(), 193 ExecutionErrors.MissingRequiredIntroductionMimeTypeName.name(), ExecutionErrors.MissingRequiredIntroduction.name(), 194 ExecutionErrors.UnknownIntroductionMimeTypeName.name(), ExecutionErrors.UnknownIntroductionMimeTypeUsage.name()); 195 } 196 } 197 } 198 199 @Override 200 public void doUpdate(TrainingClassSection trainingClassSection) { 201 var trainingControl = Session.getModelController(TrainingControl.class); 202 var partyPK = getPartyPK(); 203 TrainingClassSectionDetailValue trainingClassSectionDetailValue = trainingControl.getTrainingClassSectionDetailValueForUpdate(trainingClassSection); 204 TrainingClassSectionTranslation trainingClassSectionTranslation = trainingControl.getTrainingClassSectionTranslationForUpdate(trainingClassSection, getPreferredLanguage()); 205 String percentageToPass = edit.getPercentageToPass(); 206 String questionCount = edit.getQuestionCount(); 207 String description = edit.getDescription(); 208 String overview = edit.getOverview(); 209 String introduction = edit.getIntroduction(); 210 211 trainingClassSectionDetailValue.setTrainingClassSectionName(edit.getTrainingClassSectionName()); 212 trainingClassSectionDetailValue.setPercentageToPass(percentageToPass == null ? null : Integer.valueOf(percentageToPass)); 213 trainingClassSectionDetailValue.setQuestionCount(questionCount == null ? null : Integer.valueOf(questionCount)); 214 trainingClassSectionDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder())); 215 216 trainingControl.updateTrainingClassSectionFromValue(trainingClassSectionDetailValue, partyPK); 217 218 if(trainingClassSectionTranslation == null && (description != null || overview != null || introduction != null)) { 219 trainingControl.createTrainingClassSectionTranslation(trainingClassSection, getPreferredLanguage(), description, overviewMimeType, overview, 220 introductionMimeType, introduction, partyPK); 221 } else if(trainingClassSectionTranslation != null && (description == null && overview == null && introduction == null)) { 222 trainingControl.deleteTrainingClassSectionTranslation(trainingClassSectionTranslation, partyPK); 223 } else if(trainingClassSectionTranslation != null && (description != null || overview != null || introduction != null)) { 224 TrainingClassSectionTranslationValue trainingClassSectionTranslationValue = trainingControl.getTrainingClassSectionTranslationValue(trainingClassSectionTranslation); 225 226 trainingClassSectionTranslationValue.setDescription(description); 227 trainingClassSectionTranslationValue.setOverviewMimeTypePK(overviewMimeType == null? null: overviewMimeType.getPrimaryKey()); 228 trainingClassSectionTranslationValue.setOverview(overview); 229 trainingClassSectionTranslationValue.setIntroductionMimeTypePK(introductionMimeType == null? null: introductionMimeType.getPrimaryKey()); 230 trainingClassSectionTranslationValue.setIntroduction(introduction); 231 trainingControl.updateTrainingClassSectionTranslationFromValue(trainingClassSectionTranslationValue, partyPK); 232 } 233 } 234 235}