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.TrainingClassAnswerEdit; 020import com.echothree.control.user.training.common.edit.TrainingEditFactory; 021import com.echothree.control.user.training.common.form.EditTrainingClassAnswerForm; 022import com.echothree.control.user.training.common.result.EditTrainingClassAnswerResult; 023import com.echothree.control.user.training.common.result.TrainingResultFactory; 024import com.echothree.control.user.training.common.spec.TrainingClassAnswerSpec; 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.TrainingClassAnswer; 034import com.echothree.model.data.training.server.entity.TrainingClassAnswerDetail; 035import com.echothree.model.data.training.server.entity.TrainingClassAnswerTranslation; 036import com.echothree.model.data.training.server.entity.TrainingClassQuestion; 037import com.echothree.model.data.training.server.entity.TrainingClassSection; 038import com.echothree.model.data.training.server.value.TrainingClassAnswerDetailValue; 039import com.echothree.model.data.training.server.value.TrainingClassAnswerTranslationValue; 040import com.echothree.model.data.user.common.pk.UserVisitPK; 041import com.echothree.util.common.message.ExecutionErrors; 042import com.echothree.util.common.validation.FieldDefinition; 043import com.echothree.util.common.validation.FieldType; 044import com.echothree.util.common.command.EditMode; 045import com.echothree.util.server.control.BaseAbstractEditCommand; 046import com.echothree.util.server.control.CommandSecurityDefinition; 047import com.echothree.util.server.control.PartyTypeDefinition; 048import com.echothree.util.server.control.SecurityRoleDefinition; 049import com.echothree.util.server.persistence.Session; 050import java.util.Arrays; 051import java.util.Collections; 052import java.util.List; 053 054public class EditTrainingClassAnswerCommand 055 extends BaseAbstractEditCommand<TrainingClassAnswerSpec, TrainingClassAnswerEdit, EditTrainingClassAnswerResult, TrainingClassAnswer, TrainingClassAnswer> { 056 057 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 058 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 059 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 060 061 static { 062 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(Collections.unmodifiableList(Arrays.asList( 063 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 064 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), Collections.unmodifiableList(Arrays.asList( 065 new SecurityRoleDefinition(SecurityRoleGroups.TrainingClassAnswer.name(), SecurityRoles.Edit.name()) 066 ))) 067 ))); 068 069 SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 070 new FieldDefinition("TrainingClassName", FieldType.ENTITY_NAME, true, null, null), 071 new FieldDefinition("TrainingClassSectionName", FieldType.ENTITY_NAME, true, null, null), 072 new FieldDefinition("TrainingClassQuestionName", FieldType.ENTITY_NAME, true, null, null), 073 new FieldDefinition("TrainingClassAnswerName", FieldType.ENTITY_NAME, true, null, null) 074 )); 075 076 EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList( 077 new FieldDefinition("TrainingClassAnswerName", FieldType.ENTITY_NAME, true, null, null), 078 new FieldDefinition("IsCorrect", FieldType.BOOLEAN, true, null, null), 079 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 080 new FieldDefinition("AnswerMimeTypeName", FieldType.MIME_TYPE, false, null, null), 081 new FieldDefinition("Answer", FieldType.STRING, false, null, null), 082 new FieldDefinition("SelectedMimeTypeName", FieldType.MIME_TYPE, false, null, null), 083 new FieldDefinition("Selected", FieldType.STRING, false, null, null) 084 )); 085 } 086 087 /** Creates a new instance of EditTrainingClassAnswerCommand */ 088 public EditTrainingClassAnswerCommand(UserVisitPK userVisitPK, EditTrainingClassAnswerForm form) { 089 super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 090 } 091 092 @Override 093 public EditTrainingClassAnswerResult getResult() { 094 return TrainingResultFactory.getEditTrainingClassAnswerResult(); 095 } 096 097 @Override 098 public TrainingClassAnswerEdit getEdit() { 099 return TrainingEditFactory.getTrainingClassAnswerEdit(); 100 } 101 102 TrainingClassQuestion trainingClassQuestion; 103 104 @Override 105 public TrainingClassAnswer getEntity(EditTrainingClassAnswerResult result) { 106 var trainingControl = Session.getModelController(TrainingControl.class); 107 TrainingClassAnswer trainingClassAnswer = null; 108 String trainingClassName = spec.getTrainingClassName(); 109 TrainingClass trainingClass = trainingControl.getTrainingClassByName(trainingClassName); 110 111 if(trainingClass != null) { 112 String trainingClassSectionName = spec.getTrainingClassSectionName(); 113 TrainingClassSection trainingClassSection = trainingControl.getTrainingClassSectionByName(trainingClass, trainingClassSectionName); 114 115 if(trainingClassSection != null) { 116 String trainingClassQuestionName = spec.getTrainingClassQuestionName(); 117 118 trainingClassQuestion = trainingControl.getTrainingClassQuestionByName(trainingClassSection, trainingClassQuestionName); 119 120 if(trainingClassQuestion != null) { 121 String trainingClassAnswerName = spec.getTrainingClassAnswerName(); 122 123 if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) { 124 trainingClassAnswer = trainingControl.getTrainingClassAnswerByName(trainingClassQuestion, trainingClassAnswerName); 125 } else { // EditMode.UPDATE 126 trainingClassAnswer = trainingControl.getTrainingClassAnswerByNameForUpdate(trainingClassQuestion, trainingClassAnswerName); 127 } 128 129 if(trainingClassAnswer != null) { 130 result.setTrainingClassAnswer(trainingControl.getTrainingClassAnswerTransfer(getUserVisit(), trainingClassAnswer)); 131 } else { 132 addExecutionError(ExecutionErrors.UnknownTrainingClassAnswerName.name(), trainingClassName, trainingClassSectionName, 133 trainingClassQuestionName, trainingClassAnswerName); 134 } 135 } else { 136 addExecutionError(ExecutionErrors.UnknownTrainingClassQuestionName.name(), trainingClassName, trainingClassSectionName, 137 trainingClassQuestionName); 138 } 139 } else { 140 addExecutionError(ExecutionErrors.UnknownTrainingClassSectionName.name(), trainingClassName, trainingClassSectionName); 141 } 142 } else { 143 addExecutionError(ExecutionErrors.UnknownTrainingClassName.name(), trainingClassName); 144 } 145 146 return trainingClassAnswer; 147 } 148 149 @Override 150 public TrainingClassAnswer getLockEntity(TrainingClassAnswer trainingClassAnswer) { 151 return trainingClassAnswer; 152 } 153 154 @Override 155 public void fillInResult(EditTrainingClassAnswerResult result, TrainingClassAnswer trainingClassAnswer) { 156 var trainingControl = Session.getModelController(TrainingControl.class); 157 158 result.setTrainingClassAnswer(trainingControl.getTrainingClassAnswerTransfer(getUserVisit(), trainingClassAnswer)); 159 } 160 161 MimeType answerMimeType; 162 MimeType selectedMimeType; 163 164 @Override 165 public void doLock(TrainingClassAnswerEdit edit, TrainingClassAnswer trainingClassAnswer) { 166 var trainingControl = Session.getModelController(TrainingControl.class); 167 TrainingClassAnswerTranslation trainingClassAnswerTranslation = trainingControl.getTrainingClassAnswerTranslation(trainingClassAnswer, getPreferredLanguage()); 168 TrainingClassAnswerDetail trainingClassAnswerDetail = trainingClassAnswer.getLastDetail(); 169 170 edit.setTrainingClassAnswerName(trainingClassAnswerDetail.getTrainingClassAnswerName()); 171 edit.setIsCorrect(trainingClassAnswerDetail.getIsCorrect().toString()); 172 edit.setSortOrder(trainingClassAnswerDetail.getSortOrder().toString()); 173 174 if(trainingClassAnswerTranslation != null) { 175 answerMimeType = trainingClassAnswerTranslation.getAnswerMimeType(); 176 selectedMimeType = trainingClassAnswerTranslation.getSelectedMimeType(); 177 178 edit.setAnswerMimeTypeName(answerMimeType == null? null: answerMimeType.getLastDetail().getMimeTypeName()); 179 edit.setAnswer(trainingClassAnswerTranslation.getAnswer()); 180 edit.setSelectedMimeTypeName(selectedMimeType == null? null: selectedMimeType.getLastDetail().getMimeTypeName()); 181 edit.setSelected(trainingClassAnswerTranslation.getSelected()); 182 } 183 } 184 185 @Override 186 public void canUpdate(TrainingClassAnswer trainingClassAnswer) { 187 var trainingControl = Session.getModelController(TrainingControl.class); 188 String trainingClassAnswerName = edit.getTrainingClassAnswerName(); 189 TrainingClassAnswer duplicateTrainingClassAnswer = trainingControl.getTrainingClassAnswerByName(trainingClassQuestion, trainingClassAnswerName); 190 191 if(duplicateTrainingClassAnswer != null && !trainingClassAnswer.equals(duplicateTrainingClassAnswer)) { 192 addExecutionError(ExecutionErrors.DuplicateTrainingClassAnswerName.name(), trainingClassAnswerName); 193 } else { 194 MimeTypeLogic mimeTypeLogic = MimeTypeLogic.getInstance(); 195 String answerMimeTypeName = edit.getAnswerMimeTypeName(); 196 String answer = edit.getAnswer(); 197 198 answerMimeType = mimeTypeLogic.checkMimeType(this, answerMimeTypeName, answer, MimeTypeUsageTypes.TEXT.name(), 199 ExecutionErrors.MissingRequiredAnswerMimeTypeName.name(), ExecutionErrors.MissingRequiredAnswer.name(), 200 ExecutionErrors.UnknownAnswerMimeTypeName.name(), ExecutionErrors.UnknownAnswerMimeTypeUsage.name()); 201 202 if(!hasExecutionErrors()) { 203 String selected = edit.getSelected(); 204 205 selectedMimeType = mimeTypeLogic.checkMimeType(this, edit.getSelectedMimeTypeName(), selected, MimeTypeUsageTypes.TEXT.name(), 206 ExecutionErrors.MissingRequiredSelectedMimeTypeName.name(), ExecutionErrors.MissingRequiredSelected.name(), 207 ExecutionErrors.UnknownSelectedMimeTypeName.name(), ExecutionErrors.UnknownSelectedMimeTypeUsage.name()); 208 209 if(!hasExecutionErrors()) { 210 if(answer == null && selected != null) { 211 addExecutionError(ExecutionErrors.MissingRequiredAnswerMimeTypeName.name()); 212 addExecutionError(ExecutionErrors.MissingRequiredAnswer.name()); 213 } 214 } 215 } 216 } 217 } 218 219 @Override 220 public void doUpdate(TrainingClassAnswer trainingClassAnswer) { 221 var trainingControl = Session.getModelController(TrainingControl.class); 222 var partyPK = getPartyPK(); 223 TrainingClassAnswerDetailValue trainingClassAnswerDetailValue = trainingControl.getTrainingClassAnswerDetailValueForUpdate(trainingClassAnswer); 224 TrainingClassAnswerTranslation trainingClassAnswerTranslation = trainingControl.getTrainingClassAnswerTranslationForUpdate(trainingClassAnswer, getPreferredLanguage()); 225 String answer = edit.getAnswer(); 226 String selected = edit.getSelected(); 227 228 trainingClassAnswerDetailValue.setTrainingClassAnswerName(edit.getTrainingClassAnswerName()); 229 trainingClassAnswerDetailValue.setIsCorrect(Boolean.valueOf(edit.getIsCorrect())); 230 trainingClassAnswerDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder())); 231 232 trainingControl.updateTrainingClassAnswerFromValue(trainingClassAnswerDetailValue, partyPK); 233 234 if(trainingClassAnswerTranslation == null && (answer != null || selected != null)) { 235 trainingControl.createTrainingClassAnswerTranslation(trainingClassAnswer, getPreferredLanguage(), answerMimeType, answer, selectedMimeType, 236 selected, partyPK); 237 } else if(trainingClassAnswerTranslation != null && (answer == null && selected == null)) { 238 trainingControl.deleteTrainingClassAnswerTranslation(trainingClassAnswerTranslation, partyPK); 239 } else if(trainingClassAnswerTranslation != null && (answer != null || selected != null)) { 240 TrainingClassAnswerTranslationValue trainingClassAnswerTranslationValue = trainingControl.getTrainingClassAnswerTranslationValue(trainingClassAnswerTranslation); 241 242 trainingClassAnswerTranslationValue.setAnswerMimeTypePK(answerMimeType == null? null: answerMimeType.getPrimaryKey()); 243 trainingClassAnswerTranslationValue.setAnswer(answer); 244 trainingClassAnswerTranslationValue.setSelectedMimeTypePK(selectedMimeType == null? null: selectedMimeType.getPrimaryKey()); 245 trainingClassAnswerTranslationValue.setSelected(selected); 246 trainingControl.updateTrainingClassAnswerTranslationFromValue(trainingClassAnswerTranslationValue, partyPK); 247 } 248 } 249 250}