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.core.server.command; 018 019import com.echothree.control.user.core.common.edit.CoreEditFactory; 020import com.echothree.control.user.core.common.edit.EntityAttributeEdit; 021import com.echothree.control.user.core.common.form.EditEntityAttributeForm; 022import com.echothree.control.user.core.common.result.CoreResultFactory; 023import com.echothree.control.user.core.common.result.EditEntityAttributeResult; 024import com.echothree.control.user.core.common.spec.EntityAttributeUniversalSpec; 025import com.echothree.model.control.core.common.EntityAttributeTypes; 026import com.echothree.model.control.core.server.logic.EntityAttributeLogic; 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.sequence.common.SequenceTypes; 031import com.echothree.model.control.sequence.server.control.SequenceControl; 032import com.echothree.model.control.sequence.server.logic.SequenceTypeLogic; 033import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic; 034import com.echothree.model.data.core.server.entity.EntityAttribute; 035import com.echothree.model.data.sequence.server.entity.Sequence; 036import com.echothree.model.data.uom.server.entity.UnitOfMeasureType; 037import com.echothree.model.data.user.common.pk.UserVisitPK; 038import com.echothree.util.common.form.ValidationResult; 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.server.control.BaseAbstractEditCommand; 043import com.echothree.util.server.control.CommandSecurityDefinition; 044import com.echothree.util.server.control.PartyTypeDefinition; 045import com.echothree.util.server.control.SecurityRoleDefinition; 046import com.echothree.util.server.validation.Validator; 047import java.util.List; 048import javax.enterprise.context.Dependent; 049import javax.inject.Inject; 050 051@Dependent 052public class EditEntityAttributeCommand 053 extends BaseAbstractEditCommand<EntityAttributeUniversalSpec, EntityAttributeEdit, EditEntityAttributeResult, EntityAttribute, EntityAttribute> { 054 055 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 056 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 057 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 058 059 static { 060 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 061 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 062 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 063 new SecurityRoleDefinition(SecurityRoleGroups.EntityAttribute.name(), SecurityRoles.Edit.name()) 064 )) 065 )); 066 067 SPEC_FIELD_DEFINITIONS = List.of( 068 new FieldDefinition("EntityRef", FieldType.ENTITY_REF, false, null, null), 069 new FieldDefinition("Uuid", FieldType.UUID, false, null, null), 070 new FieldDefinition("ComponentVendorName", FieldType.ENTITY_NAME, false, null, null), 071 new FieldDefinition("EntityTypeName", FieldType.ENTITY_TYPE_NAME, false, null, null), 072 new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, false, null, null) 073 ); 074 075 EDIT_FIELD_DEFINITIONS = List.of( 076 new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, true, null, null), 077 new FieldDefinition("TrackRevisions", FieldType.BOOLEAN, true, null, null), 078 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 079 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L) 080 ); 081 } 082 083 @Inject 084 SequenceControl sequenceControl; 085 086 @Inject 087 EntityAttributeLogic entityAttributeLogic; 088 089 @Inject 090 SequenceTypeLogic sequenceTypeLogic; 091 092 @Inject 093 UnitOfMeasureTypeLogic unitOfMeasureTypeLogic; 094 095 096 /** Creates a new instance of EditEntityAttributeCommand */ 097 public EditEntityAttributeCommand() { 098 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 099 } 100 101 @Override 102 protected ValidationResult validateEdit(Validator validator) { 103 var validationResult = validator.validate(edit, getEditFieldDefinitions()); 104 105 if(!validationResult.getHasErrors()) { 106 entityAttribute = entityAttributeLogic.getEntityAttributeByUniversalSpec(this, 107 spec); 108 109 if(!hasExecutionErrors()) { 110 var entityAttributeType = entityAttribute.getLastDetail().getEntityAttributeType(); 111 112 validationResult = CreateEntityAttributeCommand.AdditionalEntityAttributeValidation(edit, validator, entityAttributeType); 113 } 114 } 115 116 return validationResult; 117 } 118 119 @Override 120 public EditEntityAttributeResult getResult() { 121 return CoreResultFactory.getEditEntityAttributeResult(); 122 } 123 124 @Override 125 public EntityAttributeEdit getEdit() { 126 return CoreEditFactory.getEntityAttributeEdit(); 127 } 128 129 EntityAttribute entityAttribute = null; 130 131 @Override 132 public EntityAttribute getEntity(EditEntityAttributeResult result) { 133 entityAttribute = entityAttributeLogic.getEntityAttributeByUniversalSpec(this, 134 spec, editModeToEntityPermission(editMode)); 135 136 return entityAttribute; 137 } 138 139 @Override 140 public EntityAttribute getLockEntity(EntityAttribute entityAttribute) { 141 return entityAttribute; 142 } 143 144 @Override 145 public void fillInResult(EditEntityAttributeResult result, EntityAttribute entityAttribute) { 146 147 result.setEntityAttribute(coreControl.getEntityAttributeTransfer(getUserVisit(), entityAttribute, null)); 148 } 149 150 Sequence entityListItemSequence = null; 151 UnitOfMeasureType unitOfMeasureType = null; 152 153 @Override 154 public void doLock(EntityAttributeEdit edit, EntityAttribute entityAttribute) { 155 var entityAttributeDescription = coreControl.getEntityAttributeDescription(entityAttribute, getPreferredLanguage()); 156 var entityAttributeDetail = entityAttribute.getLastDetail(); 157 var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 158 var entityAttributeType = EntityAttributeTypes.valueOf(entityAttributeTypeName); 159 160 edit.setEntityAttributeName(entityAttributeDetail.getEntityAttributeName()); 161 edit.setTrackRevisions(entityAttributeDetail.getTrackRevisions().toString()); 162 edit.setSortOrder(entityAttributeDetail.getSortOrder().toString()); 163 164 switch(entityAttributeType) { 165 case BLOB -> { 166 var entityAttributeBlob = coreControl.getEntityAttributeBlobForUpdate(entityAttribute); 167 168 edit.setCheckContentWebAddress(entityAttributeBlob.getCheckContentWebAddress().toString()); 169 } 170 case STRING -> { 171 var entityAttributeString = coreControl.getEntityAttributeStringForUpdate(entityAttribute); 172 173 if(entityAttributeString != null) { 174 edit.setValidationPattern(entityAttributeString.getValidationPattern()); 175 } 176 } 177 case INTEGER -> { 178 var entityAttributeInteger = coreControl.getEntityAttributeIntegerForUpdate(entityAttribute); 179 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 180 181 if(entityAttributeInteger != null) { 182 edit.setUpperLimitIntegerValue(entityAttributeInteger.getUpperLimitIntegerValue().toString()); 183 edit.setUpperRangeIntegerValue(entityAttributeInteger.getUpperRangeIntegerValue().toString()); 184 edit.setLowerRangeIntegerValue(entityAttributeInteger.getLowerRangeIntegerValue().toString()); 185 edit.setLowerLimitIntegerValue(entityAttributeInteger.getLowerLimitIntegerValue().toString()); 186 } 187 188 if(entityAttributeNumeric != null) { 189 unitOfMeasureType = entityAttributeNumeric.getUnitOfMeasureType(); 190 191 if(unitOfMeasureType != null) { 192 var unitOfMeasureTypeDetail = unitOfMeasureType.getLastDetail(); 193 194 edit.setUnitOfMeasureKindName(unitOfMeasureTypeDetail.getUnitOfMeasureKind().getLastDetail().getUnitOfMeasureKindName()); 195 edit.setUnitOfMeasureTypeName(unitOfMeasureTypeDetail.getUnitOfMeasureTypeName()); 196 } 197 } 198 } 199 case LONG -> { 200 var entityAttributeLong = coreControl.getEntityAttributeLongForUpdate(entityAttribute); 201 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 202 203 if(entityAttributeLong != null) { 204 edit.setUpperLimitLongValue(entityAttributeLong.getUpperLimitLongValue().toString()); 205 edit.setUpperRangeLongValue(entityAttributeLong.getUpperRangeLongValue().toString()); 206 edit.setLowerRangeLongValue(entityAttributeLong.getLowerRangeLongValue().toString()); 207 edit.setLowerLimitLongValue(entityAttributeLong.getLowerLimitLongValue().toString()); 208 } 209 210 if(entityAttributeNumeric != null) { 211 unitOfMeasureType = entityAttributeNumeric.getUnitOfMeasureType(); 212 213 if(unitOfMeasureType != null) { 214 var unitOfMeasureTypeDetail = unitOfMeasureType.getLastDetail(); 215 216 edit.setUnitOfMeasureKindName(unitOfMeasureTypeDetail.getUnitOfMeasureKind().getLastDetail().getUnitOfMeasureKindName()); 217 edit.setUnitOfMeasureTypeName(unitOfMeasureTypeDetail.getUnitOfMeasureTypeName()); 218 } 219 } 220 } 221 case LISTITEM, MULTIPLELISTITEM -> { 222 var entityAttributeListItem = coreControl.getEntityAttributeListItemForUpdate(entityAttribute); 223 224 if(entityAttributeListItem != null) { 225 entityListItemSequence = entityAttributeListItem.getEntityListItemSequence(); 226 227 edit.setEntityListItemSequenceName(entityListItemSequence == null ? null : entityListItemSequence.getLastDetail().getSequenceName()); 228 } 229 } 230 default -> { 231 } 232 } 233 234 if(entityAttributeDescription != null) { 235 edit.setDescription(entityAttributeDescription.getDescription()); 236 } 237 } 238 239 @Override 240 public void canUpdate(EntityAttribute entityAttribute) { 241 var entityAttributeName = edit.getEntityAttributeName(); 242 var duplicateEntityAttribute = coreControl.getEntityAttributeByName(entityAttribute.getLastDetail().getEntityType(), 243 entityAttributeName); 244 245 if(duplicateEntityAttribute == null || entityAttribute.equals(duplicateEntityAttribute)) { 246 var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 247 var entityListItemSequenceName = entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name()) 248 || entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name()) ? 249 edit.getEntityListItemSequenceName() : null; 250 251 if(entityListItemSequenceName != null) { 252 var sequenceType = sequenceTypeLogic.getSequenceTypeByName(this, SequenceTypes.ENTITY_LIST_ITEM.name()); 253 254 if(!hasExecutionErrors()) { 255 entityListItemSequence = sequenceControl.getSequenceByName(sequenceType, entityListItemSequenceName); 256 257 if(entityListItemSequence == null) { 258 addExecutionError(ExecutionErrors.UnknownEntityListItemSequenceName.name(), entityListItemSequenceName); 259 } 260 } 261 } 262 263 if(!hasExecutionErrors()) { 264 var unitOfMeasureKindName = edit.getUnitOfMeasureKindName(); 265 var unitOfMeasureTypeName = edit.getUnitOfMeasureTypeName(); 266 var parameterCount = (unitOfMeasureKindName == null ? 0 : 1) + (unitOfMeasureTypeName == null ? 0 : 1); 267 268 if(parameterCount == 0 || parameterCount == 2) { 269 if(parameterCount == 2) { 270 unitOfMeasureType = unitOfMeasureTypeLogic.getUnitOfMeasureTypeByName(this, unitOfMeasureKindName, unitOfMeasureTypeName); 271 } 272 } else { 273 addExecutionError(ExecutionErrors.InvalidParameterCount.name()); 274 } 275 } 276 } else { 277 addExecutionError(ExecutionErrors.DuplicateEntityAttributeName.name(), entityAttributeName); 278 } 279 } 280 281 @Override 282 public void doUpdate(EntityAttribute entityAttribute) { 283 var partyPK = getPartyPK(); 284 var entityAttributeDetailValue = coreControl.getEntityAttributeDetailValueForUpdate(entityAttribute); 285 var entityAttributeDescription = coreControl.getEntityAttributeDescriptionForUpdate(entityAttribute, getPreferredLanguage()); 286 var strCheckContentWebAddress = edit.getCheckContentWebAddress(); 287 var checkContentWebAddress = strCheckContentWebAddress == null ? null : Boolean.valueOf(strCheckContentWebAddress); 288 var validationPattern = edit.getValidationPattern(); 289 var strUpperRangeIntegerValue = edit.getUpperRangeIntegerValue(); 290 var upperRangeIntegerValue = strUpperRangeIntegerValue == null ? null : Integer.valueOf(strUpperRangeIntegerValue); 291 var strUpperLimitIntegerValue = edit.getUpperLimitIntegerValue(); 292 var upperLimitIntegerValue = strUpperLimitIntegerValue == null ? null : Integer.valueOf(strUpperLimitIntegerValue); 293 var strLowerLimitIntegerValue = edit.getLowerLimitIntegerValue(); 294 var lowerLimitIntegerValue = strLowerLimitIntegerValue == null ? null : Integer.valueOf(strLowerLimitIntegerValue); 295 var strLowerRangeIntegerValue = edit.getLowerRangeIntegerValue(); 296 var lowerRangeIntegerValue = strLowerRangeIntegerValue == null ? null : Integer.valueOf(strLowerRangeIntegerValue); 297 var strUpperRangeLongValue = edit.getUpperRangeLongValue(); 298 var upperRangeLongValue = strUpperRangeLongValue == null ? null : Long.valueOf(strUpperRangeLongValue); 299 var strUpperLimitLongValue = edit.getUpperLimitLongValue(); 300 var upperLimitLongValue = strUpperLimitLongValue == null ? null : Long.valueOf(strUpperLimitLongValue); 301 var strLowerLimitLongValue = edit.getLowerLimitLongValue(); 302 var lowerLimitLongValue = strLowerLimitLongValue == null ? null : Long.valueOf(strLowerLimitLongValue); 303 var strLowerRangeLongValue = edit.getLowerRangeLongValue(); 304 var lowerRangeLongValue = strLowerRangeLongValue == null ? null : Long.valueOf(strLowerRangeLongValue); 305 var description = edit.getDescription(); 306 307 entityAttributeDetailValue.setEntityAttributeName(edit.getEntityAttributeName()); 308 entityAttributeDetailValue.setTrackRevisions(Boolean.valueOf(edit.getTrackRevisions())); 309 entityAttributeDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder())); 310 311 entityAttributeLogic.updateEntityAttributeFromValue(session, entityAttributeDetailValue, partyPK); 312 313 var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 314 var entityAttributeType = EntityAttributeTypes.valueOf(entityAttributeTypeName); 315 316 switch(entityAttributeType) { 317 case BLOB -> { 318 var entityAttributeBlobValue = coreControl.getEntityAttributeBlobValueForUpdate(entityAttribute); 319 320 entityAttributeBlobValue.setCheckContentWebAddress(checkContentWebAddress); 321 coreControl.updateEntityAttributeBlobFromValue(entityAttributeBlobValue, partyPK); 322 } 323 case STRING -> { 324 var entityAttributeString = coreControl.getEntityAttributeStringForUpdate(entityAttribute); 325 326 if(entityAttributeString == null && validationPattern != null) { 327 coreControl.createEntityAttributeString(entityAttribute, validationPattern, partyPK); 328 } else if(entityAttributeString != null) { 329 if(validationPattern == null) { 330 coreControl.deleteEntityAttributeString(entityAttributeString, partyPK); 331 } else { 332 var entityAttributeStringValue = coreControl.getEntityAttributeStringValue(entityAttributeString); 333 334 entityAttributeStringValue.setValidationPattern(validationPattern); 335 coreControl.updateEntityAttributeStringFromValue(entityAttributeStringValue, partyPK); 336 } 337 } 338 } 339 case INTEGER -> { 340 var entityAttributeInteger = coreControl.getEntityAttributeIntegerForUpdate(entityAttribute); 341 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 342 343 if(entityAttributeInteger == null && (upperRangeIntegerValue != null || upperLimitIntegerValue != null || lowerLimitIntegerValue != null || lowerRangeIntegerValue != null)) { 344 coreControl.createEntityAttributeInteger(entityAttribute, upperRangeIntegerValue, upperLimitIntegerValue, lowerLimitIntegerValue, lowerRangeIntegerValue, partyPK); 345 } else if(entityAttributeInteger != null) { 346 if(upperRangeIntegerValue == null && upperLimitIntegerValue == null && lowerLimitIntegerValue == null && lowerRangeIntegerValue == null) { 347 coreControl.deleteEntityAttributeInteger(entityAttributeInteger, partyPK); 348 } else { 349 var entityAttributeIntegerValue = coreControl.getEntityAttributeIntegerValue(entityAttributeInteger); 350 351 entityAttributeIntegerValue.setUpperRangeIntegerValue(upperRangeIntegerValue); 352 entityAttributeIntegerValue.setUpperLimitIntegerValue(upperLimitIntegerValue); 353 entityAttributeIntegerValue.setLowerLimitIntegerValue(lowerLimitIntegerValue); 354 entityAttributeIntegerValue.setLowerRangeIntegerValue(lowerRangeIntegerValue); 355 coreControl.updateEntityAttributeIntegerFromValue(entityAttributeIntegerValue, partyPK); 356 } 357 } 358 359 if(entityAttributeNumeric == null && unitOfMeasureType != null) { 360 coreControl.createEntityAttributeNumeric(entityAttribute, unitOfMeasureType, partyPK); 361 } else if(entityAttributeNumeric != null) { 362 if(unitOfMeasureType == null) { 363 coreControl.deleteEntityAttributeNumeric(entityAttributeNumeric, partyPK); 364 } else { 365 var entityAttributeNumericValue = coreControl.getEntityAttributeNumericValue(entityAttributeNumeric); 366 367 entityAttributeNumericValue.setUnitOfMeasureTypePK(unitOfMeasureType.getPrimaryKey()); 368 coreControl.updateEntityAttributeNumericFromValue(entityAttributeNumericValue, partyPK); 369 } 370 } 371 } 372 case LONG -> { 373 var entityAttributeLong = coreControl.getEntityAttributeLongForUpdate(entityAttribute); 374 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 375 376 if(entityAttributeLong == null && (upperRangeLongValue != null || upperLimitLongValue != null || lowerLimitLongValue != null || lowerRangeLongValue != null)) { 377 coreControl.createEntityAttributeLong(entityAttribute, upperRangeLongValue, upperLimitLongValue, lowerLimitLongValue, lowerRangeLongValue, partyPK); 378 } else if(entityAttributeLong != null) { 379 if(upperRangeLongValue == null && upperLimitLongValue == null && lowerLimitLongValue == null && lowerRangeLongValue == null) { 380 coreControl.deleteEntityAttributeLong(entityAttributeLong, partyPK); 381 } else { 382 var entityAttributeLongValue = coreControl.getEntityAttributeLongValue(entityAttributeLong); 383 384 entityAttributeLongValue.setUpperRangeLongValue(upperRangeLongValue); 385 entityAttributeLongValue.setUpperLimitLongValue(upperLimitLongValue); 386 entityAttributeLongValue.setLowerLimitLongValue(lowerLimitLongValue); 387 entityAttributeLongValue.setLowerRangeLongValue(lowerRangeLongValue); 388 coreControl.updateEntityAttributeLongFromValue(entityAttributeLongValue, partyPK); 389 } 390 } 391 392 if(entityAttributeNumeric == null && unitOfMeasureType != null) { 393 coreControl.createEntityAttributeNumeric(entityAttribute, unitOfMeasureType, partyPK); 394 } else if(entityAttributeNumeric != null) { 395 if(unitOfMeasureType == null) { 396 coreControl.deleteEntityAttributeNumeric(entityAttributeNumeric, partyPK); 397 } else { 398 var entityAttributeNumericValue = coreControl.getEntityAttributeNumericValue(entityAttributeNumeric); 399 400 entityAttributeNumericValue.setUnitOfMeasureTypePK(unitOfMeasureType.getPrimaryKey()); 401 coreControl.updateEntityAttributeNumericFromValue(entityAttributeNumericValue, partyPK); 402 } 403 } 404 } 405 case LISTITEM, MULTIPLELISTITEM -> { 406 var entityAttributeListItem = coreControl.getEntityAttributeListItemForUpdate(entityAttribute); 407 408 if(entityAttributeListItem == null && entityListItemSequence != null) { 409 coreControl.createEntityAttributeListItem(entityAttribute, entityListItemSequence, partyPK); 410 } else if(entityAttributeListItem != null) { 411 if(entityListItemSequence == null) { 412 coreControl.deleteEntityAttributeListItem(entityAttributeListItem, partyPK); 413 } else { 414 var entityAttributeListItemValue = coreControl.getEntityAttributeListItemValue(entityAttributeListItem); 415 416 entityAttributeListItemValue.setEntityListItemSequencePK(entityListItemSequence.getPrimaryKey()); 417 coreControl.updateEntityAttributeListItemFromValue(entityAttributeListItemValue, partyPK); 418 } 419 } 420 } 421 default -> { 422 } 423 } 424 425 if(entityAttributeDescription == null && description != null) { 426 coreControl.createEntityAttributeDescription(entityAttribute, getPreferredLanguage(), description, partyPK); 427 } else if(entityAttributeDescription != null) { 428 if(description == null) { 429 coreControl.deleteEntityAttributeDescription(entityAttributeDescription, partyPK); 430 } else { 431 var entityAttributeDescriptionValue = coreControl.getEntityAttributeDescriptionValue(entityAttributeDescription); 432 433 entityAttributeDescriptionValue.setDescription(description); 434 coreControl.updateEntityAttributeDescriptionFromValue(entityAttributeDescriptionValue, partyPK); 435 } 436 } 437 } 438 439}