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