public ChangeTaskHelper(ApprovalCommandService generalCommandService, ApprovalCommandMapper approvalCommandMapper, LanguageChangeDetails languageChangeDetails, MovingChangeDetail movingChangeDetail, SecurityChangeDetail securityChangeDetail, ExpirationChangeDetails expirationChangeDetails) { _generalCommandService = generalCommandService; _approvalCommandMapper = approvalCommandMapper; _languageChangeDetails = languageChangeDetails; _movingChangeDetail = movingChangeDetail; _securityChangeDetail = securityChangeDetail; _expirationChangeDetails = expirationChangeDetails; }
public void CompleteChanges(RockContext rockContext = null) { SecurityChangeDetail securityChangeDetail = new SecurityChangeDetail { ChangeRequestId = this.Id, ChangeDetails = new List <string>() }; if (rockContext == null) { rockContext = new RockContext(); } using (var dbContextTransaction = rockContext.Database.BeginTransaction()) { try { IEntity entity = GetEntity(EntityTypeId, EntityId, rockContext); //Make changes foreach (var changeRecord in ChangeRecords.Where(r => r.WasApplied != true && r.IsRejected == false)) { var targetEntity = entity; if (changeRecord.RelatedEntityTypeId.HasValue) { if (changeRecord.RelatedEntityId.HasValue && !(changeRecord.RelatedEntityId == 0 || changeRecord.Action == ChangeRecordAction.Create)) { //existing entity targetEntity = GetEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.RelatedEntityId.Value, rockContext); } else { //new entity targetEntity = CreateNewEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.NewValue, rockContext); changeRecord.RelatedEntityId = targetEntity.Id; //if we add a phone number add that to the change list if (targetEntity?.GetType() == typeof(PhoneNumber)) { var number = targetEntity as PhoneNumber; var numberType = DefinedValueCache.GetValue(number.NumberTypeValueId.Value); securityChangeDetail.ChangeDetails.Add(string.Format("Added {0} phone number {1}", numberType, number.NumberFormatted)); } } } //Some times entitities can be deleted (such as a binary file being cleaned up) //And cannot update, delete or change and attribute on it anymore if (targetEntity == null) { continue; } //Remove records marked as delete if (changeRecord.Action == ChangeRecordAction.Delete) { DeleteEntity(targetEntity, rockContext); } else if (changeRecord.Action == ChangeRecordAction.Attribute) { UpdateAttribute(targetEntity, changeRecord.Property, changeRecord.NewValue, rockContext); } else if (changeRecord.Property.IsNotNullOrWhiteSpace()) { PropertyInfo prop = targetEntity.GetType().GetProperty(changeRecord.Property, BindingFlags.Public | BindingFlags.Instance); if (prop != null && prop.PropertyType.GetInterfaces().Any(i => i.IsInterface && i.GetInterfaces().Contains(typeof(IEntity)))) { PropertyInfo propId = targetEntity.GetType().GetProperty(changeRecord.Property + "Id", BindingFlags.Public | BindingFlags.Instance); var newObject = changeRecord.NewValue.FromJsonOrNull <BasicEntity>(); prop.SetValue(targetEntity, null, null); if (newObject != null) { propId.SetValue(targetEntity, newObject.Id); } else { propId.SetValue(targetEntity, null, null); } } else { SetProperty(targetEntity, prop, changeRecord.NewValue); } } changeRecord.WasApplied = true; //Check to see if the email address was changed var targetEntityType = targetEntity?.GetType(); if (targetEntityType?.BaseType == typeof(Person) && // is a person changeRecord.Property == "Email" && // and changed email changeRecord.OldValue.IsNotNullOrWhiteSpace() && //old value isn't blank changeRecord.NewValue.IsNotNullOrWhiteSpace() //new value isn't blank ) { securityChangeDetail.ChangeDetails.Add(string.Format("Changed email address from {0} to {1}", changeRecord.OldValue, changeRecord.NewValue)); securityChangeDetail.CurrentEmail = changeRecord.NewValue; securityChangeDetail.PreviousEmail = changeRecord.OldValue; } //Check to see if the phone number was changed if (targetEntityType?.BaseType == typeof(PhoneNumber) && //is a phonenuumber changeRecord.Property == "Number" //is a number change ) { var number = targetEntity as PhoneNumber; var numberType = DefinedValueCache.GetValue(number.NumberTypeValueId.Value); securityChangeDetail.ChangeDetails.Add(string.Format("Changed {0} phone number from {1} to {2}", numberType, PhoneNumber.FormattedNumber(PhoneNumber.DefaultCountryCode(), changeRecord.OldValue), PhoneNumber.FormattedNumber(PhoneNumber.DefaultCountryCode(), changeRecord.NewValue))); } } //Undo Changes foreach (var changeRecord in ChangeRecords.Where(r => r.WasApplied == true && r.IsRejected == true)) { var targetEntity = entity; if (changeRecord.RelatedEntityTypeId.HasValue && changeRecord.Action != ChangeRecordAction.Delete) { if (changeRecord.RelatedEntityId.HasValue && changeRecord.Action != ChangeRecordAction.Create) { //existing entity targetEntity = GetEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.RelatedEntityId.Value, rockContext); } else { //This was a created entity that we must now murder in cold blood. targetEntity = GetEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.RelatedEntityId.Value, rockContext); DeleteEntity(targetEntity, rockContext); changeRecord.WasApplied = false; continue; } } //Undelete if (changeRecord.RelatedEntityTypeId.HasValue && changeRecord.Action == ChangeRecordAction.Delete) { targetEntity = CreateNewEntity(changeRecord.RelatedEntityTypeId.Value, changeRecord.OldValue, rockContext); changeRecord.RelatedEntityId = targetEntity.Id; } else if (changeRecord.Action == ChangeRecordAction.Attribute) { UpdateAttribute(targetEntity, changeRecord.Property, changeRecord.OldValue, rockContext); } //Property changes else if (changeRecord.Property.IsNotNullOrWhiteSpace()) { PropertyInfo prop = targetEntity?.GetType()?.GetProperty(changeRecord.Property, BindingFlags.Public | BindingFlags.Instance); if (targetEntity == null || prop == null) { //Entity was probably deleted after the change request continue; } if (prop.PropertyType.GetInterfaces().Any(i => i.IsInterface && i.GetInterfaces().Contains(typeof(IEntity)))) { PropertyInfo propId = targetEntity.GetType().GetProperty(changeRecord.Property + "Id", BindingFlags.Public | BindingFlags.Instance); var oldObject = changeRecord.OldValue.FromJsonOrNull <BasicEntity>(); prop.SetValue(targetEntity, null, null); if (oldObject != null) { propId.SetValue(targetEntity, oldObject.Id); } else { propId.SetValue(targetEntity, null, null); } } else { SetProperty(targetEntity, prop, changeRecord.OldValue); } } changeRecord.WasApplied = false; } rockContext.SaveChanges(); dbContextTransaction.Commit(); if (entity.GetType()?.BaseType == typeof(Person) && securityChangeDetail.ChangeDetails.Any()) { var workflowGuid = GlobalAttributesCache.Get().GetValue("ChangeManagerSecurityWorkflow").AsGuidOrNull(); this.LaunchWorkflow(workflowGuid, "Change Request Security Notice", new Dictionary <string, string> { { "ChangeDetail", securityChangeDetail.ToJson() } }); } } catch (Exception e) { dbContextTransaction.Rollback(); throw new Exception("Exception occured durring saving changes.", e); } } }