/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages ) { errorMessages = new List<string>(); string updateValue = GetAttributeValue( action, "Value" ); Guid? valueGuid = updateValue.AsGuidOrNull(); if ( valueGuid.HasValue ) { updateValue = action.GetWorklowAttributeValue( valueGuid.Value ); } else { updateValue = updateValue.ResolveMergeFields( GetMergeFields( action ) ); } string personAttribute = GetAttributeValue( action, "PersonAttribute" ); Guid guid = personAttribute.AsGuid(); if (!guid.IsEmpty()) { var attribute = AttributeCache.Read( guid, rockContext ); if ( attribute != null ) { string value = GetAttributeValue( action, "Person" ); guid = value.AsGuid(); if ( !guid.IsEmpty() ) { var attributePerson = AttributeCache.Read( guid, rockContext ); if ( attributePerson != null ) { string attributePersonValue = action.GetWorklowAttributeValue( guid ); if ( !string.IsNullOrWhiteSpace( attributePersonValue ) ) { if ( attributePerson.FieldType.Class == "Rock.Field.Types.PersonFieldType" ) { Guid personAliasGuid = attributePersonValue.AsGuid(); if ( !personAliasGuid.IsEmpty() ) { var person = new PersonAliasService( rockContext ).Queryable() .Where( a => a.Guid.Equals( personAliasGuid ) ) .Select( a => a.Person ) .FirstOrDefault(); if ( person != null ) { // update person attribute person.LoadAttributes(); string originalValue = person.GetAttributeValue( attribute.Key ); // Handle encrypted text fields as well. if ( attribute.FieldType.Field is Field.Types.EncryptedTextFieldType ) { updateValue = Security.Encryption.EncryptString( updateValue ); } Rock.Attribute.Helper.SaveAttributeValue( person, attribute, updateValue, rockContext ); if ( ( originalValue ?? string.Empty ).Trim() != ( updateValue ?? string.Empty ).Trim() ) { var changes = new List<string>(); string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( updateValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, updateValue, attribute.QualifierValues, false ); } History.EvaluateChange( changes, attribute.Name, formattedOriginalValue, formattedNewValue, attribute.FieldType.Field.IsSensitive() ); if ( changes.Any() ) { HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), person.Id, changes ); } } action.AddLogEntry( string.Format( "Set '{0}' attribute to '{1}'.", attribute.Name, updateValue ) ); return true; } else { errorMessages.Add( string.Format( "Person could not be found for selected value ('{0}')!", guid.ToString() ) ); } } } else { errorMessages.Add( "The attribute used to provide the person was not of type 'Person'." ); } } } } } else { errorMessages.Add( string.Format( "Person attribute could not be found for '{0}'!", guid.ToString() ) ); } } else { errorMessages.Add( string.Format( "Selected person attribute ('{0}') was not a valid Guid!", personAttribute ) ); } errorMessages.ForEach( m => action.AddLogEntry( m, true ) ); return true; }