Beispiel #1
0
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public static void SetValue(string key, string value)
        {
            var rockContext      = new Rock.Data.RockContext();
            var attributeService = new AttributeService(rockContext);
            var attribute        = attributeService.GetSystemSetting(key);

            if (attribute == null)
            {
                attribute             = new Rock.Model.Attribute();
                attribute.FieldTypeId = FieldTypeCache.Get(new Guid(SystemGuid.FieldType.TEXT)).Id;
                attribute.EntityTypeQualifierColumn = Rock.Model.Attribute.SYSTEM_SETTING_QUALIFIER;
                attribute.EntityTypeQualifierValue  = string.Empty;
                attribute.Key          = key;
                attribute.Name         = key.SplitCase();
                attribute.DefaultValue = value;
                attributeService.Add(attribute);
            }
            else
            {
                attribute.DefaultValue = value;
            }

            // NOTE: Service Layer will automatically update this Cache (see Attribute.cs UpdateCache)
            rockContext.SaveChanges();

            if (key == Rock.SystemKey.SystemSetting.START_DAY_OF_WEEK)
            {
                RockDateTime.FirstDayOfWeek = value.ConvertToEnumOrNull <DayOfWeek>() ?? RockDateTime.DefaultFirstDayOfWeek;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Displays the edit list.
        /// </summary>
        private void DisplayEditList()
        {
            lEditHeader.Text = GetAttributeValue("EditHeader");
            lEditFooter.Text = GetAttributeValue("EditFooter");

            if (_definedType != null)
            {
                using (var rockContext = new RockContext())
                {
                    var entityType  = EntityTypeCache.Get("Rock.Model.DefinedValue");
                    var definedType = new DefinedTypeService(rockContext).Get(_definedType.Id);
                    if (definedType != null && entityType != null)
                    {
                        var attributeService = new AttributeService(rockContext);
                        var attributes       = new AttributeService(rockContext)
                                               .GetByEntityTypeQualifier(entityType.Id, "DefinedTypeId", definedType.Id.ToString(), false)
                                               .ToList();

                        // Verify (and create if necessary) the "Is Link" attribute
                        if (!attributes.Any(a => a.Key == "IsLink"))
                        {
                            var fieldType = FieldTypeCache.Get(Rock.SystemGuid.FieldType.BOOLEAN);
                            if (entityType != null && fieldType != null)
                            {
                                var attribute = new Rock.Model.Attribute();
                                attributeService.Add(attribute);
                                attribute.EntityTypeId = entityType.Id;
                                attribute.EntityTypeQualifierColumn = "DefinedTypeId";
                                attribute.EntityTypeQualifierValue  = definedType.Id.ToString();
                                attribute.FieldTypeId  = fieldType.Id;
                                attribute.Name         = "Is Link";
                                attribute.Key          = "IsLink";
                                attribute.Description  = "Flag indicating if value is a link (vs Header)";
                                attribute.IsGridColumn = true;
                                attribute.DefaultValue = true.ToString();

                                var qualifier1 = new AttributeQualifier();
                                qualifier1.Key   = "truetext";
                                qualifier1.Value = "Yes";
                                attribute.AttributeQualifiers.Add(qualifier1);

                                var qualifier2 = new AttributeQualifier();
                                qualifier2.Key   = "falsetext";
                                qualifier2.Value = "No";
                                attribute.AttributeQualifiers.Add(qualifier2);

                                rockContext.SaveChanges();
                            }
                        }
                    }
                }

                BindGrid();

                pnlView.Visible = false;
                pnlEdit.Visible = true;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            using (new UnitOfWorkScope())
            {
                RockTransactionScope.WrapTransaction(() =>
                {
                    var attributeService           = new AttributeService();
                    Rock.Model.Attribute attribute = null;

                    // remove old qualifier values in case they changed
                    if (edtAttribute.AttributeId.HasValue)
                    {
                        AttributeQualifierService attributeQualifierService = new AttributeQualifierService();
                        foreach (var oldQualifier in attributeQualifierService.GetByAttributeId(edtAttribute.AttributeId.Value).ToList())
                        {
                            attributeQualifierService.Delete(oldQualifier, CurrentPersonId);
                            attributeQualifierService.Save(oldQualifier, CurrentPersonId);
                        }
                        attribute = attributeService.Get(edtAttribute.AttributeId.Value);
                    }

                    if (attribute == null)
                    {
                        attribute = new Rock.Model.Attribute();
                        attributeService.Add(attribute, CurrentPersonId);
                    }

                    if (_configuredType)
                    {
                        attribute.EntityTypeId = _entityTypeId;
                        attribute.EntityTypeQualifierColumn = _entityQualifierColumn;
                        attribute.EntityTypeQualifierValue  = _entityQualifierValue;
                    }
                    else
                    {
                        attribute.EntityTypeId = ddlAttrEntityType.SelectedValueAsInt();
                        attribute.EntityTypeQualifierColumn = tbAttrQualifierField.Text;
                        attribute.EntityTypeQualifierValue  = tbAttrQualifierValue.Text;
                    }

                    edtAttribute.GetAttributeProperties(attribute);

                    // Controls will show warnings
                    if (!attribute.IsValid)
                    {
                        return;
                    }

                    Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                    attributeService.Save(attribute, CurrentPersonId);
                });
            }

            BindGrid();

            pnlDetails.Visible = false;
            pnlList.Visible    = true;
        }
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="currentPersonId">The current person id.</param>
        /// <param name="saveValue">if set to <c>true</c> [save value].</param>
        public void SetValue(string key, string value, int?currentPersonId, bool saveValue)
        {
            if (saveValue)
            {
                using (new Rock.Data.UnitOfWorkScope())
                {
                    // Save new value
                    var attributeValueService = new AttributeValueService();
                    var attributeValue        = attributeValueService.GetGlobalAttributeValue(key);

                    if (attributeValue == null)
                    {
                        var attributeService = new AttributeService();
                        var attribute        = attributeService.GetGlobalAttribute(key);
                        if (attribute == null)
                        {
                            attribute             = new Rock.Model.Attribute();
                            attribute.FieldTypeId = FieldTypeCache.Read(new Guid(SystemGuid.FieldType.TEXT)).Id;
                            attribute.EntityTypeQualifierColumn = string.Empty;
                            attribute.EntityTypeQualifierValue  = string.Empty;
                            attribute.Key  = key;
                            attribute.Name = key.SplitCase();
                            attributeService.Add(attribute, currentPersonId);
                            attributeService.Save(attribute, currentPersonId);

                            Attributes.Add(AttributeCache.Read(attribute.Id));
                        }

                        attributeValue = new AttributeValue();
                        attributeValueService.Add(attributeValue, currentPersonId);
                        attributeValue.IsSystem    = false;
                        attributeValue.AttributeId = attribute.Id;

                        if (!AttributeValues.Keys.Contains(key))
                        {
                            AttributeValues.Add(key, new KeyValuePair <string, string>(attribute.Name, value));
                        }
                    }

                    attributeValue.Value = value;
                    attributeValueService.Save(attributeValue, currentPersonId);
                }
            }

            var attributeCache = Attributes.FirstOrDefault(a => a.Key.Equals(key, StringComparison.OrdinalIgnoreCase));

            if (attributeCache != null)   // (Should never be null)
            {
                if (AttributeValues.Keys.Contains(key))
                {
                    AttributeValues[key] = new KeyValuePair <string, string>(attributeCache.Name, value);
                }
                else
                {
                    AttributeValues.Add(key, new KeyValuePair <string, string>(attributeCache.Name, value));
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Saves the attribute value.
        /// </summary>
        /// <param name="workflow">The workflow.</param>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="fieldType">Type of the field.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="qualifiers">The qualifiers.</param>
        /// <returns></returns>
        private static bool SaveAttributeValue(Rock.Model.Workflow workflow, string key, string value,
                                               FieldTypeCache fieldType, RockContext rockContext, Dictionary <string, string> qualifiers = null)
        {
            bool createdNewAttribute = false;

            if (workflow.Attributes.ContainsKey(key))
            {
                workflow.SetAttributeValue(key, value);
            }
            else
            {
                // Read the attribute
                var attributeService = new AttributeService(rockContext);
                var attribute        = attributeService
                                       .Get(workflow.TypeId, "WorkflowTypeId", workflow.WorkflowTypeId.ToString())
                                       .Where(a => a.Key == key)
                                       .FirstOrDefault();

                // If workflow attribute doesn't exist, create it
                // ( should only happen first time a background check is processed for given workflow type)
                if (attribute == null)
                {
                    attribute = new Rock.Model.Attribute();
                    attribute.EntityTypeId = workflow.TypeId;
                    attribute.EntityTypeQualifierColumn = "WorkflowTypeId";
                    attribute.EntityTypeQualifierValue  = workflow.WorkflowTypeId.ToString();
                    attribute.Name        = key.SplitCase();
                    attribute.Key         = key;
                    attribute.FieldTypeId = fieldType.Id;
                    attributeService.Add(attribute);

                    if (qualifiers != null)
                    {
                        foreach (var keyVal in qualifiers)
                        {
                            var qualifier = new Rock.Model.AttributeQualifier();
                            qualifier.Key   = keyVal.Key;
                            qualifier.Value = keyVal.Value;
                            attribute.AttributeQualifiers.Add(qualifier);
                        }
                    }

                    createdNewAttribute = true;
                }

                // Set the value for this action's instance to the current time
                var attributeValue = new Rock.Model.AttributeValue();
                attributeValue.Attribute = attribute;
                attributeValue.EntityId  = workflow.Id;
                attributeValue.Value     = value;
                new AttributeValueService(rockContext).Add(attributeValue);
            }

            return(createdNewAttribute);
        }
Beispiel #6
0
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="saveValue">if set to <c>true</c> [save value].</param>
        /// <param name="rockContext">The rock context.</param>
        public void SetValue(string key, string value, bool saveValue, RockContext rockContext)
        {
            if (saveValue)
            {
                // Save new value
                rockContext = rockContext ?? new RockContext();
                var attributeValueService = new AttributeValueService(rockContext);
                var attributeValue        = attributeValueService.GetGlobalAttributeValue(key);

                if (attributeValue == null)
                {
                    var attributeService = new AttributeService(rockContext);
                    var attribute        = attributeService.GetGlobalAttribute(key);
                    if (attribute == null)
                    {
                        attribute = new Model.Attribute
                        {
                            FieldTypeId = FieldTypeCache.Get(new Guid(SystemGuid.FieldType.TEXT)).Id,
                            EntityTypeQualifierColumn = string.Empty,
                            EntityTypeQualifierValue  = string.Empty,
                            Key  = key,
                            Name = key.SplitCase()
                        };
                        attributeService.Add(attribute);
                        rockContext.SaveChanges();
                    }

                    attributeValue = new AttributeValue
                    {
                        IsSystem    = false,
                        AttributeId = attribute.Id
                    };
                    attributeValueService.Add(attributeValue);
                }

                attributeValue.Value = value;
                rockContext.SaveChanges();
            }

            lock ( _obj )
            {
                _attributeIds = null;
            }

            AttributeValues.AddOrUpdate(key, value, (k, v) => value);

            var attributeCache = Attributes.FirstOrDefault(a => a.Key.Equals(key, StringComparison.OrdinalIgnoreCase));

            if (attributeCache != null)
            {
                value = attributeCache.FieldType.Field.FormatValue(null, value, attributeCache.QualifierValues, false);
            }
            AttributeValuesFormatted.AddOrUpdate(key, value, (k, v) => value);
        }
Beispiel #7
0
        /// <summary>
        /// Handles the Click event of the btnSaveWorkflowTypeAttribute control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSaveWorkflowTypeAttribute_Click(object sender, EventArgs e)
        {
            Attribute        attribute        = null;
            AttributeService attributeService = new AttributeService();

            if (edtWorkflowTypeAttributes.AttributeId.HasValue)
            {
                attribute = attributeService.Get(edtWorkflowTypeAttributes.AttributeId.Value);
            }

            if (attribute == null)
            {
                attribute = new Attribute();
            }

            edtWorkflowTypeAttributes.GetAttributeProperties(attribute);

            // Controls will show warnings
            if (!attribute.IsValid)
            {
                return;
            }

            RockTransactionScope.WrapTransaction(() =>
            {
                if (attribute.Id.Equals(0))
                {
                    attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(typeof(Workflow)).Id;
                    attribute.EntityTypeQualifierColumn = "WorkflowTypeId";
                    attribute.EntityTypeQualifierValue  = hfWorkflowTypeId.Value;
                    attributeService.Add(attribute, CurrentPersonId);
                }

                Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                attributeService.Save(attribute, CurrentPersonId);
            });

            pnlDetails.Visible = true;
            pnlWorkflowTypeAttributes.Visible = false;

            // reload page so that other blocks respond to any data that was changed
            var qryParams = new Dictionary <string, string>();

            qryParams["workflowTypeId"] = hfWorkflowTypeId.Value;
            NavigateToPage(this.CurrentPage.Guid, qryParams);
        }
        /// <summary>
        /// Adds/Updates any attributes that were defined in web.config 's rockConfig section
        /// This is usually used for Plugin Components that need to get any changed values from web.config before startup
        /// </summary>
        private static void UpdateAttributesFromRockConfig(RockContext rockContext)
        {
            var rockConfig = RockConfig.Config;

            if (rockConfig.AttributeValues.Count > 0)
            {
                foreach (AttributeValueConfig attributeValueConfig in rockConfig.AttributeValues)
                {
                    AttributeService      attributeService      = new AttributeService(rockContext);
                    AttributeValueService attributeValueService = new AttributeValueService(rockContext);
                    var attribute = attributeService.Get(
                        attributeValueConfig.EntityTypeId.AsInteger(),
                        attributeValueConfig.EntityTypeQualifierColumm,
                        attributeValueConfig.EntityTypeQualifierValue,
                        attributeValueConfig.AttributeKey);

                    if (attribute == null)
                    {
                        attribute              = new Rock.Model.Attribute();
                        attribute.FieldTypeId  = FieldTypeCache.Get(new Guid(Rock.SystemGuid.FieldType.TEXT)).Id;
                        attribute.EntityTypeId = attributeValueConfig.EntityTypeId.AsInteger();
                        attribute.EntityTypeQualifierColumn = attributeValueConfig.EntityTypeQualifierColumm;
                        attribute.EntityTypeQualifierValue  = attributeValueConfig.EntityTypeQualifierValue;
                        attribute.Key  = attributeValueConfig.AttributeKey;
                        attribute.Name = attributeValueConfig.AttributeKey.SplitCase();
                        attributeService.Add(attribute);
                        rockContext.SaveChanges();
                    }

                    var attributeValue = attributeValueService.GetByAttributeIdAndEntityId(attribute.Id, attributeValueConfig.EntityId.AsInteger());
                    if (attributeValue == null && !string.IsNullOrWhiteSpace(attributeValueConfig.Value))
                    {
                        attributeValue             = new Rock.Model.AttributeValue();
                        attributeValue.AttributeId = attribute.Id;
                        attributeValue.EntityId    = attributeValueConfig.EntityId.AsInteger();
                        attributeValueService.Add(attributeValue);
                    }

                    if (attributeValue.Value != attributeValueConfig.Value)
                    {
                        attributeValue.Value = attributeValueConfig.Value;
                        rockContext.SaveChanges();
                    }
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public static void SetValue(string key, string value)
        {
            var rockContext      = new Rock.Data.RockContext();
            var attributeService = new AttributeService(rockContext);
            var attribute        = attributeService.GetSystemSetting(key);

            bool isNew = false;

            if (attribute == null)
            {
                attribute             = new Rock.Model.Attribute();
                attribute.FieldTypeId = FieldTypeCache.Read(new Guid(SystemGuid.FieldType.TEXT)).Id;
                attribute.EntityTypeQualifierColumn = Rock.Model.Attribute.SYSTEM_SETTING_QUALIFIER;
                attribute.EntityTypeQualifierValue  = string.Empty;
                attribute.Key          = key;
                attribute.Name         = key.SplitCase();
                attribute.DefaultValue = value;
                attributeService.Add(attribute);
                isNew = true;
            }
            else
            {
                attribute.DefaultValue = value;
            }

            rockContext.SaveChanges();

            AttributeCache.Flush(attribute.Id);
            if (isNew)
            {
                AttributeCache.FlushEntityAttributes();
            }

            var settings       = SystemSettings.Read();
            var attributeCache = settings.Attributes.FirstOrDefault(a => a.Key.Equals(key, StringComparison.OrdinalIgnoreCase));

            if (attributeCache != null)
            {
                attributeCache.DefaultValue = value;
            }
            else
            {
                settings.Attributes.Add(AttributeCache.Read(attribute.Id));
            }
        }
Beispiel #10
0
        /// <summary>
        /// Handles the Click event of the btnSaveDefinedTypeAttribute control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSaveDefinedTypeAttribute_Click(object sender, EventArgs e)
        {
            Attribute attribute = null;

            AttributeService attributeService = new AttributeService();

            if (edtDefinedTypeAttributes.AttributeId.HasValue)
            {
                attribute = attributeService.Get(edtDefinedTypeAttributes.AttributeId.Value);
            }

            if (attribute == null)
            {
                attribute = new Attribute();
            }

            edtDefinedTypeAttributes.GetAttributeProperties(attribute);

            // Controls will show warnings
            if (!attribute.IsValid)
            {
                return;
            }

            RockTransactionScope.WrapTransaction(() =>
            {
                if (attribute.Id.Equals(0))
                {
                    attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(typeof(DefinedValue)).Id;
                    attribute.EntityTypeQualifierColumn = "DefinedTypeId";
                    attribute.EntityTypeQualifierValue  = hfDefinedTypeId.Value;
                    attributeService.Add(attribute, CurrentPersonId);
                }

                Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                attributeService.Save(attribute, CurrentPersonId);
            });

            pnlDetails.Visible = true;
            pnlDefinedTypeAttributes.Visible = false;

            BindDefinedTypeAttributesGrid();
            BindDefinedValuesGrid();
        }
Beispiel #11
0
        /// <summary>
        /// Handles the Click event of the btnSaveAttribute control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSaveAttribute_Click(object sender, EventArgs e)
        {
            using (new Rock.Data.UnitOfWorkScope())
            {
                var attributeService          = new AttributeService();
                var attributeQualifierService = new AttributeQualifierService();

                Rock.Model.Attribute attribute;

                int attributeId = ((hfIdAttribute.Value) != null && hfIdAttribute.Value != String.Empty) ? Int32.Parse(hfIdAttribute.Value) : 0;
                if (attributeId == 0)
                {
                    attribute              = new Rock.Model.Attribute();
                    attribute.IsSystem     = false;
                    attribute.EntityTypeId = _entityTypeId;
                    attribute.EntityTypeQualifierColumn = _entityQualifier;
                    attribute.EntityTypeQualifierValue  = hfIdType.Value;
                    attributeService.Add(attribute, CurrentPersonId);
                }
                else
                {
                    Rock.Web.Cache.AttributeCache.Flush(attributeId);
                    attribute = attributeService.Get(attributeId);
                }

                attribute.Key          = tbAttributeKey.Text;
                attribute.Name         = tbAttributeName.Text;
                attribute.Category     = tbAttributeCategory.Text;
                attribute.Description  = tbAttributeDescription.Text;
                attribute.FieldTypeId  = Int32.Parse(ddlAttributeFieldType.SelectedValue);
                attribute.DefaultValue = tbAttributeDefaultValue.Text;
                attribute.IsGridColumn = cbAttributeGridColumn.Checked;
                attribute.IsRequired   = cbAttributeRequired.Checked;

                attributeService.Save(attribute, CurrentPersonId);
            }

            rGridAttribute_Bind(hfIdType.Value);

            modalAttributes.Hide();
        }
Beispiel #12
0
        private static void CreateAttribute(string name, WorkflowAction action, RockContext rockContext)
        {
            Rock.Model.Attribute newAttribute = new Rock.Model.Attribute();
            newAttribute.Key         = name;
            newAttribute.Name        = name;
            newAttribute.FieldTypeId = FieldTypeCache.Get(new Guid(Rock.SystemGuid.FieldType.TEXT)).Id;
            newAttribute.Order       = 0;
            newAttribute.AttributeQualifiers.Add(new AttributeQualifier()
            {
                Key = "ispassword", Value = "False"
            });
            newAttribute.EntityTypeId = EntityTypeCache.Get(action.Activity.Workflow.GetType()).Id;
            newAttribute.EntityTypeQualifierColumn = "WorkflowTypeId";
            newAttribute.EntityTypeQualifierValue  = action.Activity.Workflow.WorkflowType.Id.ToString();
            AttributeService attributeService = new AttributeService(rockContext);

            attributeService.Add(newAttribute);
            rockContext.SaveChanges();
            AttributeCache.RemoveEntityAttributes();

            action.Activity.Workflow.LoadAttributes();
        }
Beispiel #13
0
        /// <summary>
        /// Ensures the tracked attributes exists.
        /// </summary>
        /// <param name="trackedAttributeKey">The tracked attribute key.</param>
        /// <param name="trackedAttributeName">Name of the tracked attribute.</param>
        /// <param name="fieldTypeGuid">The field type unique identifier.</param>
        private void EnsureTrackedAttributeExists(string trackedAttributeKey, string trackedAttributeName, Guid fieldTypeGuid)
        {
            var entityTypeIdPerson = EntityTypeCache.GetId <Rock.Model.Person>();
            var fieldTypeId        = FieldTypeCache.GetId(fieldTypeGuid);

            if (!entityTypeIdPerson.HasValue || !fieldTypeId.HasValue)
            {
                // shouldn't happen, but just in case
                return;
            }

            var rockContext = new RockContext();

            var attributeService = new AttributeService(rockContext);

            var trackedAttribute = attributeService.GetByEntityTypeId(entityTypeIdPerson.Value).Where(a => a.Key == trackedAttributeKey).FirstOrDefault();

            if (trackedAttribute == null)
            {
                trackedAttribute = new Rock.Model.Attribute();
                trackedAttribute.EntityTypeId = entityTypeIdPerson;
                trackedAttribute.Key          = trackedAttributeKey;
                trackedAttribute.Name         = trackedAttributeName;
                trackedAttribute.FieldTypeId  = fieldTypeId.Value;
                attributeService.Add(trackedAttribute);
                rockContext.SaveChanges();
            }
            else
            {
                if (trackedAttribute.FieldTypeId != fieldTypeId.Value)
                {
                    trackedAttribute.FieldTypeId = fieldTypeId.Value;
                    rockContext.SaveChanges();
                }
            }
        }
Beispiel #14
0
        protected void btnSave_Click(object sender, EventArgs e)
        {
            hfAreaGroupClicked.Value = "true";

            using (var rockContext = new RockContext())
            {
                var attributeService = new AttributeService(rockContext);

                if (checkinArea.Visible)
                {
                    var groupTypeService = new GroupTypeService(rockContext);
                    var groupType        = groupTypeService.Get(checkinArea.GroupTypeGuid);
                    if (groupType != null)
                    {
                        groupType.LoadAttributes(rockContext);
                        checkinArea.GetGroupTypeValues(groupType);

                        if (groupType.IsValid)
                        {
                            rockContext.SaveChanges();
                            groupType.SaveAttributeValues(rockContext);

                            // rebuild the CheckinLabel attributes from the UI (brute-force)
                            foreach (var labelAttribute in CheckinArea.GetCheckinLabelAttributes(groupType.Attributes))
                            {
                                var attribute = attributeService.Get(labelAttribute.Value.Guid);
                                attributeService.Delete(attribute);
                            }

                            // Make sure default role is set
                            if (!groupType.DefaultGroupRoleId.HasValue && groupType.Roles.Any())
                            {
                                groupType.DefaultGroupRoleId = groupType.Roles.First().Id;
                            }

                            rockContext.SaveChanges();

                            int labelOrder            = 0;
                            int binaryFileFieldTypeID = FieldTypeCache.Get(Rock.SystemGuid.FieldType.LABEL.AsGuid()).Id;
                            foreach (var checkinLabelAttributeInfo in checkinArea.CheckinLabels)
                            {
                                var attribute = new Rock.Model.Attribute();
                                attribute.AttributeQualifiers.Add(new AttributeQualifier {
                                    Key = "binaryFileType", Value = Rock.SystemGuid.BinaryFiletype.CHECKIN_LABEL
                                });
                                attribute.Guid         = Guid.NewGuid();
                                attribute.FieldTypeId  = binaryFileFieldTypeID;
                                attribute.EntityTypeId = EntityTypeCache.GetId(typeof(GroupType));
                                attribute.EntityTypeQualifierColumn = "Id";
                                attribute.EntityTypeQualifierValue  = groupType.Id.ToString();
                                attribute.DefaultValue = checkinLabelAttributeInfo.BinaryFileGuid.ToString();
                                attribute.Key          = checkinLabelAttributeInfo.AttributeKey;
                                attribute.Name         = checkinLabelAttributeInfo.FileName;
                                attribute.Order        = labelOrder++;

                                if (!attribute.IsValid)
                                {
                                    return;
                                }

                                attributeService.Add(attribute);
                            }

                            rockContext.SaveChanges();

                            Rock.CheckIn.KioskDevice.Clear();

                            nbSaveSuccess.Visible = true;
                            BuildRows();
                        }
                        else
                        {
                            ShowInvalidResults(groupType.ValidationResults);
                        }
                    }
                }

                if (checkinGroup.Visible)
                {
                    var groupService         = new GroupService(rockContext);
                    var groupLocationService = new GroupLocationService(rockContext);

                    var group = groupService.Get(checkinGroup.GroupGuid);
                    if (group != null)
                    {
                        group.LoadAttributes(rockContext);
                        checkinGroup.GetGroupValues(group);

                        // populate groupLocations with whatever is currently in the grid, with just enough info to repopulate it and save it later
                        var newLocationIds = checkinGroup.Locations.Select(l => l.LocationId).ToList();
                        foreach (var groupLocation in group.GroupLocations.Where(l => !newLocationIds.Contains(l.LocationId)).ToList())
                        {
                            groupLocation.GroupLocationScheduleConfigs.Clear();

                            groupLocationService.Delete(groupLocation);
                            group.GroupLocations.Remove(groupLocation);
                        }

                        var existingLocationIds = group.GroupLocations.Select(g => g.LocationId).ToList();
                        foreach (var item in checkinGroup.Locations.Where(l => !existingLocationIds.Contains(l.LocationId)).ToList())
                        {
                            var groupLocation = new GroupLocation();
                            groupLocation.LocationId = item.LocationId;
                            group.GroupLocations.Add(groupLocation);
                        }

                        // Set the new order
                        foreach (var item in checkinGroup.Locations.OrderBy(l => l.Order).ToList())
                        {
                            var groupLocation = group.GroupLocations.FirstOrDefault(gl => gl.LocationId == item.LocationId);
                            groupLocation.Order = item.Order ?? 0;
                        }

                        if (group.IsValid)
                        {
                            rockContext.SaveChanges();
                            group.SaveAttributeValues(rockContext);

                            Rock.CheckIn.KioskDevice.Clear();
                            nbSaveSuccess.Visible = true;
                            BuildRows();
                        }
                        else
                        {
                            ShowInvalidResults(group.ValidationResults);
                        }
                    }
                }
            }

            hfIsDirty.Value = "false";
        }
Beispiel #15
0
        /// <summary>
        /// Saves any attribute edits made to an attribute
        /// </summary>
        /// <param name="newAttribute">The new attribute.</param>
        /// <param name="entityTypeId">The entity type identifier.</param>
        /// <param name="entityTypeQualifierColumn">The entity type qualifier column.</param>
        /// <param name="entityTypeQualifierValue">The entity type qualifier value.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        /// <remarks>
        /// If a rockContext value is included, this method will save any previous changes made to the context
        /// </remarks>
        public static Rock.Model.Attribute SaveAttributeEdits(Rock.Model.Attribute newAttribute, int?entityTypeId, string entityTypeQualifierColumn, string entityTypeQualifierValue, RockContext rockContext = null)
        {
            rockContext = rockContext ?? new RockContext();

            var internalAttributeService  = new AttributeService(rockContext);
            var attributeQualifierService = new AttributeQualifierService(rockContext);
            var categoryService           = new CategoryService(rockContext);

            // If attribute is not valid, return null
            if (!newAttribute.IsValid)
            {
                return(null);
            }

            // Create a attribute model that will be saved
            Rock.Model.Attribute attribute = null;

            // Check to see if this was an existing or new attribute
            if (newAttribute.Id > 0)
            {
                // If editing an existing attribute, remove all the old qualifiers in case they were changed
                foreach (var oldQualifier in attributeQualifierService.GetByAttributeId(newAttribute.Id).ToList())
                {
                    attributeQualifierService.Delete(oldQualifier);
                }
                rockContext.SaveChanges();

                // Then re-load the existing attribute
                attribute = internalAttributeService.Get(newAttribute.Id);
            }

            if (attribute == null)
            {
                // If the attribute didn't exist, create it
                attribute = new Rock.Model.Attribute();
                internalAttributeService.Add(attribute);
            }
            else
            {
                // If it did exist, set the new attribute ID and GUID since we're copying all properties in the next step
                newAttribute.Id   = attribute.Id;
                newAttribute.Guid = attribute.Guid;
            }

            // Copy all the properties from the new attribute to the attribute model
            attribute.CopyPropertiesFrom(newAttribute);

            // Add any qualifiers
            foreach (var qualifier in newAttribute.AttributeQualifiers)
            {
                attribute.AttributeQualifiers.Add(new AttributeQualifier {
                    Key = qualifier.Key, Value = qualifier.Value, IsSystem = qualifier.IsSystem
                });
            }

            // Add any categories
            attribute.Categories.Clear();
            foreach (var category in newAttribute.Categories)
            {
                attribute.Categories.Add(categoryService.Get(category.Id));
            }

            attribute.EntityTypeId = entityTypeId;
            attribute.EntityTypeQualifierColumn = entityTypeQualifierColumn;
            attribute.EntityTypeQualifierValue  = entityTypeQualifierValue;

            rockContext.SaveChanges();

            if (attribute != null)
            {
                Rock.Web.Cache.AttributeCache.Flush(attribute.Id);

                // If this is a global attribute, flush all global attributes
                if (!entityTypeId.HasValue && entityTypeQualifierColumn == string.Empty && entityTypeQualifierValue == string.Empty)
                {
                    Rock.Web.Cache.GlobalAttributesCache.Flush();
                }
            }

            return(attribute);
        }
Beispiel #16
0
        /// <summary>
        /// Maps the specified folder.
        /// </summary>
        /// <param name="folder">The folder.</param>
        /// <param name="ministryFileType">Type of the ministry file.</param>
        public int Map(ZipArchive folder, BinaryFileType ministryFileType)
        {
            var lookupContext         = new RockContext();
            var personEntityTypeId    = EntityTypeCache.GetId <Person>();
            var binaryFileTypeService = new BinaryFileTypeService(lookupContext);
            var fileFieldTypeId       = FieldTypeCache.Get(Rock.SystemGuid.FieldType.FILE.AsGuid(), lookupContext).Id;
            var backgroundFieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.BACKGROUNDCHECK.AsGuid(), lookupContext).Id;

            var existingAttributes = new AttributeService(lookupContext).GetByFieldTypeId(fileFieldTypeId)
                                     .Where(a => a.EntityTypeId == personEntityTypeId)
                                     .ToDictionary(a => a.Key, a => a);

            var backgroundCheckFileAttributes = new AttributeService(lookupContext).GetByFieldTypeId(backgroundFieldTypeId)
                                                .Where(a => a.EntityTypeId == personEntityTypeId)
                                                .ToDictionary(a => a.Key, a => a);

            foreach (var backgroundCheckFileAttribute in backgroundCheckFileAttributes)
            {
                if (!existingAttributes.ContainsKey(backgroundCheckFileAttribute.Key))
                {
                    existingAttributes.Add(backgroundCheckFileAttribute.Key, backgroundCheckFileAttribute.Value);
                }
            }

            var emptyJsonObject = "{}";
            var newFileList     = new List <DocumentKeys>();

            var completedItems = 0;
            var totalRows      = folder.Entries.Count;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying ministry document import ({0:N0} found)", totalRows));

            foreach (var file in folder.Entries.OrderBy(f => f.Name))
            {
                var fileExtension = Path.GetExtension(file.Name);
                if (FileTypeBlackList.Contains(fileExtension))
                {
                    LogException("Binary File Import", string.Format("{0} filetype not allowed ({1})", fileExtension, file.Name));
                    continue;
                }

                var nameWithoutExtension = file.Name.ReplaceLastOccurrence(fileExtension, string.Empty);
                var parsedFileName       = nameWithoutExtension.Split('_');
                // Ministry docs should follow this pattern:
                // 0. Firstname
                // 1. Lastname
                // 2. ForeignId
                // 3. Filename
                // 4. Doc Id
                if (parsedFileName.Length < 3)
                {
                    break;
                }

                var personForeignId = parsedFileName[2].AsType <int?>();
                var personKeys      = ImportedPeople.FirstOrDefault(p => p.PersonForeignId == personForeignId);
                if (personKeys != null)
                {
                    var attributeName     = string.Empty;
                    var documentForeignId = string.Empty;
                    if (parsedFileName.Count() > 4)
                    {
                        attributeName     = parsedFileName[3];
                        documentForeignId = parsedFileName[4];
                    }
                    else
                    {
                        var filename = parsedFileName[3].ReplaceLastOccurrence(fileExtension, string.Empty);
                        attributeName     = Regex.Replace(filename, "\\d{4,}[.\\w]+$", string.Empty);
                        documentForeignId = Regex.Match(filename, "\\d+$").Value;
                    }

                    // append "Document" to attribute name to create unique attributes
                    // this matches core attribute "Background Check Document"
                    attributeName = !attributeName.EndsWith("Document", StringComparison.OrdinalIgnoreCase) ? string.Format("{0} Document", attributeName) : attributeName;
                    var attributeKey = attributeName.RemoveSpecialCharacters();

                    Attribute fileAttribute           = null;
                    var       attributeBinaryFileType = ministryFileType;
                    if (!existingAttributes.ContainsKey(attributeKey))
                    {
                        fileAttribute = new Attribute
                        {
                            FieldTypeId  = fileFieldTypeId,
                            EntityTypeId = personEntityTypeId,
                            EntityTypeQualifierColumn = string.Empty,
                            EntityTypeQualifierValue  = string.Empty,
                            Key          = attributeKey,
                            Name         = attributeName,
                            Description  = string.Format("{0} created by binary file import", attributeName),
                            IsGridColumn = false,
                            IsMultiValue = false,
                            IsRequired   = false,
                            AllowSearch  = false,
                            IsSystem     = false,
                            Order        = 0
                        };

                        fileAttribute.AttributeQualifiers.Add(new AttributeQualifier()
                        {
                            Key   = "binaryFileType",
                            Value = ministryFileType.Guid.ToString()
                        });

                        lookupContext.Attributes.Add(fileAttribute);
                        lookupContext.SaveChanges();

                        existingAttributes.Add(fileAttribute.Key, fileAttribute);
                    }
                    else
                    {
                        // if attribute already exists in Rock, override default file type with the Rock-specified file type
                        fileAttribute = existingAttributes[attributeKey];
                        var attributeBinaryFileTypeGuid = fileAttribute.AttributeQualifiers.FirstOrDefault(q => q.Key.Equals("binaryFileType"));
                        if (attributeBinaryFileTypeGuid != null)
                        {
                            attributeBinaryFileType = binaryFileTypeService.Get(attributeBinaryFileTypeGuid.Value.AsGuid());
                        }
                    }

                    var rockFile = new Rock.Model.BinaryFile
                    {
                        IsSystem               = false,
                        IsTemporary            = false,
                        MimeType               = GetMIMEType(file.Name),
                        BinaryFileTypeId       = attributeBinaryFileType.Id,
                        FileName               = file.Name,
                        Description            = string.Format("Imported as {0}", file.Name),
                        CreatedDateTime        = file.LastWriteTime.DateTime,
                        ModifiedDateTime       = file.LastWriteTime.DateTime,
                        CreatedByPersonAliasId = ImportPersonAliasId,
                        ForeignKey             = documentForeignId,
                        ForeignId              = documentForeignId.AsIntegerOrNull()
                    };

                    rockFile.SetStorageEntityTypeId(attributeBinaryFileType.StorageEntityTypeId);
                    rockFile.StorageEntitySettings = emptyJsonObject;

                    if (attributeBinaryFileType.AttributeValues != null)
                    {
                        rockFile.StorageEntitySettings = attributeBinaryFileType.AttributeValues
                                                         .ToDictionary(a => a.Key, v => v.Value.Value).ToJson();
                    }

                    // use base stream instead of file stream to keep the byte[]
                    // NOTE: if byte[] converts to a string it will corrupt the stream
                    using (var fileContent = new StreamReader(file.Open()))
                    {
                        rockFile.ContentStream = new MemoryStream(fileContent.BaseStream.ReadBytesToEnd());
                    }

                    newFileList.Add(new DocumentKeys()
                    {
                        PersonId    = personKeys.PersonId,
                        AttributeId = fileAttribute.Id,
                        File        = rockFile
                    });

                    completedItems++;

                    if (completedItems % percentage < 1)
                    {
                        var percentComplete = completedItems / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} ministry document files imported ({1}% complete).", completedItems, percentComplete));
                    }

                    if (completedItems % ReportingNumber < 1)
                    {
                        SaveFiles(newFileList);

                        // Reset list
                        newFileList.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newFileList.Any())
            {
                SaveFiles(newFileList);
            }

            ReportProgress(100, string.Format("Finished documents import: {0:N0} ministry documents imported.", completedItems));
            return(completedItems);
        }
Beispiel #17
0
        /// <summary>
        /// Maps the people attributes to date/text attributes.
        /// Also converts attribute comments to person notes.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapAttribute(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext = new RockContext();
            var personService = new PersonService(lookupContext);

            var personAttributes       = new AttributeService(lookupContext).GetByEntityTypeId(PersonEntityTypeId).Include("Categories").AsNoTracking().ToList();
            var importedAttributeCount = lookupContext.AttributeValues.Count(v => v.Attribute.EntityTypeId == PersonEntityTypeId && v.ForeignKey != null);
            var baptizedHereAttribute  = personAttributes.FirstOrDefault(a => a.Key.Equals("BaptizedHere", StringComparison.InvariantCultureIgnoreCase));
            var newBenevolences        = new List <BenevolenceRequest>();
            var peopleToUpdate         = new Dictionary <int, Person>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completedItems = 0;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, $"Verifying attribute import ({totalRows:N0} found, {importedAttributeCount:N0} already exist).");

            foreach (var row in tableData.OrderBy(r => r["Attribute_Name"]).ThenByDescending(r => r["Start_Date"] != null).ThenBy(r => r["Start_Date"]).ThenBy(r => r["End_Date"]).Where(r => r != null))
            {
                // add the new attribute
                var attributeGroupName = row["Attribute_Group_Name"] as string;
                var attributeName      = row["Attribute_Name"] as string;
                var attributeDate      = row["Start_Date"] as DateTime?;
                attributeDate = attributeDate ?? row["End_Date"] as DateTime?;
                var attributeComment = row["Comment"] as string;
                var attributeCreator = row["Staff_Individual_ID"] as int?;
                int?campusId         = null;

                if (attributeGroupName.IsNullOrWhiteSpace() && attributeName.IsNullOrWhiteSpace())
                {
                    continue;
                }

                // strip attribute group name (will become a category)
                if (attributeGroupName.Any(n => ValidDelimiters.Contains(n)))
                {
                    campusId = campusId ?? GetCampusId(attributeGroupName);
                    if (campusId.HasValue)
                    {
                        attributeGroupName = StripPrefix(attributeGroupName, campusId);
                    }
                }

                // strip attribute name
                if (attributeName.Any(n => ValidDelimiters.Contains(n)))
                {
                    campusId = campusId ?? GetCampusId(attributeName);
                    if (campusId.HasValue)
                    {
                        attributeName = StripPrefix(attributeName, campusId);
                    }
                }

                var personBaptizedHere     = false;
                var isBenevolenceAttribute = false;
                if (attributeName.StartsWith("Baptism", StringComparison.CurrentCultureIgnoreCase))
                {   // match the core Baptism attribute
                    attributeName      = "Baptism Date";
                    personBaptizedHere = attributeCreator.HasValue;
                }
                else if (attributeName.StartsWith("Benevolence", StringComparison.CurrentCultureIgnoreCase))
                {   // set a flag to create benevolence items
                    isBenevolenceAttribute = true;
                    attributeName          = attributeName.Replace("Benevolence", string.Empty).Trim();
                }
                else if (string.IsNullOrWhiteSpace(attributeName))
                {
                    attributeName = attributeGroupName;
                }

                Attribute primaryAttribute = null, campusAttribute = null;
                // don't create custom attributes for benevolence items
                if (!isBenevolenceAttribute)
                {
                    // create attributes if they don't exist
                    var attributeKey = attributeName.RemoveSpecialCharacters();
                    primaryAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals(attributeKey, StringComparison.CurrentCultureIgnoreCase));
                    if (primaryAttribute == null)
                    {
                        primaryAttribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, $"{attributeKey} imported {ImportDateTime}",
                                                              attributeGroupName, attributeName, attributeKey, attributeDate.HasValue ? DateFieldTypeId : TextFieldTypeId, importPersonAliasId: ImportPersonAliasId
                                                              );

                        personAttributes.Add(primaryAttribute);
                    }
                    // attribute already exists, add the new category
                    else if (!primaryAttribute.Categories.Any(c => c.Name.Equals(attributeGroupName)))
                    {
                        var attributeCategory = GetCategory(lookupContext, AttributeEntityTypeId, null, attributeGroupName, false, "EntityTypeId", PersonEntityTypeId.ToString());
                        primaryAttribute.Categories.Add(attributeCategory);
                    }

                    // only create a campus attribute if there was a campus prefix
                    campusAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals($"{attributeKey}Campus", StringComparison.CurrentCultureIgnoreCase));
                    if (campusAttribute == null && campusId.HasValue)
                    {
                        campusAttribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, $"{attributeKey}Campus imported {ImportDateTime}",
                                                             attributeGroupName, $"{attributeName} Campus", $"{attributeKey}Campus", CampusFieldTypeId
                                                             );

                        personAttributes.Add(campusAttribute);
                    }
                }

                // make sure we have a valid person to assign to
                var individualId   = row["Individual_Id"] as int?;
                var matchingPerson = GetPersonKeys(individualId, null, includeVisitors: false);
                if (matchingPerson != null)
                {
                    var person = !peopleToUpdate.ContainsKey(matchingPerson.PersonId)
                        ? personService.Queryable(includeDeceased: true).FirstOrDefault(p => p.Id == matchingPerson.PersonId)
                        : peopleToUpdate[matchingPerson.PersonId];

                    if (person != null)
                    {
                        int?creatorAliasId = null;
                        var noteCreator    = GetPersonKeys(attributeCreator);
                        if (noteCreator != null)
                        {
                            creatorAliasId = noteCreator.PersonAliasId;
                        }

                        if (!isBenevolenceAttribute)
                        {
                            // could have multiple attributes assigned to this person, don't overwrite previous
                            if (person.Attributes == null || person.AttributeValues == null)
                            {
                                person.Attributes      = new Dictionary <string, AttributeCache>();
                                person.AttributeValues = new Dictionary <string, AttributeValueCache>();
                            }

                            var attributeValue = attributeDate.HasValue ? attributeDate.Value.ToString("yyyy-MM-dd") : attributeComment;
                            if (string.IsNullOrWhiteSpace(attributeValue))
                            {
                                // add today's date so that the attribute at least gets a value
                                attributeValue = RockDateTime.Now.ToString("yyyy-MM-dd");
                            }

                            AddEntityAttributeValue(lookupContext, primaryAttribute, person, attributeValue);

                            if (personBaptizedHere)
                            {
                                AddEntityAttributeValue(lookupContext, baptizedHereAttribute, person, "Yes");
                            }

                            // Add the campus attribute value
                            if (campusAttribute != null && campusId.HasValue)
                            {
                                var campus = CampusList.FirstOrDefault(c => c.Id.Equals(campusId));
                                AddEntityAttributeValue(lookupContext, campusAttribute, person, campus.Guid.ToString());
                            }

                            // convert the attribute comment to a person note
                            if (!string.IsNullOrWhiteSpace(attributeComment))
                            {
                                // add the note to the person
                                AddEntityNote(lookupContext, PersonEntityTypeId, person.Id, attributeName, attributeComment, false, false,
                                              attributeGroupName, null, true, attributeDate, $"Imported {ImportDateTime}", creatorAliasId);
                            }
                        }
                        // benevolences require a date
                        else if (attributeDate.HasValue)
                        {
                            var requestText = !string.IsNullOrWhiteSpace(attributeComment) ? attributeComment : "N/A";
                            var benevolence = new BenevolenceRequest
                            {
                                CampusId                 = campusId,
                                RequestDateTime          = attributeDate.Value,
                                FirstName                = person.FirstName,
                                LastName                 = person.LastName,
                                Email                    = person.Email,
                                RequestedByPersonAliasId = person.PrimaryAliasId,
                                ConnectionStatusValueId  = person.ConnectionStatusValueId,
                                CaseWorkerPersonAliasId  = creatorAliasId,
                                RequestStatusValueId     = ParseBenevolenceStatus(attributeName),
                                RequestText              = requestText,
                                CreatedDateTime          = attributeDate.Value,
                                ModifiedDateTime         = attributeDate.Value,
                                CreatedByPersonAliasId   = creatorAliasId,
                                ModifiedByPersonAliasId  = ImportPersonAliasId,
                                ForeignKey               = $"Benevolence imported {ImportDateTime}"
                            };

                            newBenevolences.Add(benevolence);
                        }

                        // store the person lookup for this batch
                        if (!peopleToUpdate.ContainsKey(matchingPerson.PersonId))
                        {
                            peopleToUpdate.Add(matchingPerson.PersonId, person);
                        }
                        else
                        {
                            peopleToUpdate[matchingPerson.PersonId] = person;
                        }
                    }
                }

                completedItems++;
                if (completedItems % percentage < 1)
                {
                    var percentComplete = completedItems / percentage;
                    ReportProgress(percentComplete, $"{completedItems:N0} attributes imported ({percentComplete}% complete).");
                }

                if (completedItems % ReportingNumber < 1)
                {
                    SaveAttributes(peopleToUpdate);
                    SaveBenevolenceRequests(newBenevolences);

                    // reset so context doesn't bloat
                    lookupContext.Dispose();
                    lookupContext = new RockContext();
                    personService = new PersonService(lookupContext);
                    peopleToUpdate.Clear();
                    newBenevolences.Clear();
                    ReportPartialProgress();
                }
            }

            SaveAttributes(peopleToUpdate);
            SaveBenevolenceRequests(newBenevolences);

            ReportProgress(100, $"Finished attribute import: {completedItems:N0} attributes imported.");
        }
Beispiel #18
0
        /// <summary>
        /// Maps the requirement data.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapRequirement(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext          = new RockContext();
            var importedAttributeCount = lookupContext.AttributeValues.Count(v => v.Attribute.EntityTypeId == PersonEntityTypeId && v.ForeignKey != null);
            var personAttributes       = new AttributeService(lookupContext).GetByEntityTypeId(PersonEntityTypeId)
                                         .Include("Categories").Include("AttributeQualifiers").AsNoTracking().ToList();
            var backgroundCheckedAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals("BackgroundChecked", StringComparison.CurrentCultureIgnoreCase));
            var peopleToUpdate             = new Dictionary <int, Person>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completedItems = 0;
            var percentage     = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying requirement import ({0:N0} found, {1:N0} already exist).", totalRows, importedAttributeCount));

            foreach (var row in tableData.OrderBy(r => r["Requirement_Date"]).ThenByDescending(r => r["Individual_ID"]).Where(r => r != null))
            {
                var individualId          = row["Individual_ID"] as int?;
                var requirementName       = row["Requirement_Name"] as string;
                var requirementDateString = row["Requirement_Date"] as string;
                var requirementStatus     = row["Requirement_Status_Name"] as string;
                var isConfidential        = row["Is_Confidential"] as bool?;
                var requirementDate       = requirementDateString.AsDateTime();

                var confidentialCategory = isConfidential == true ? "Confidential" : string.Empty;
                // create the requirement date
                var attributeName            = string.Format("{0} Date", requirementName);
                var requirementDateAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals(attributeName.RemoveSpecialCharacters()) && a.FieldTypeId == DateFieldTypeId);
                if (requirementDateAttribute == null)
                {
                    requirementDateAttribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, string.Format("{0} imported {1}", attributeName, ImportDateTime),
                                                                  confidentialCategory, attributeName, attributeName.RemoveSpecialCharacters(), DateFieldTypeId, importPersonAliasId: ImportPersonAliasId);
                    personAttributes.Add(requirementDateAttribute);
                }

                // create the requirement status
                attributeName = string.Format("{0} Result", requirementName);
                var requirementResultAttribute = personAttributes.FirstOrDefault(a => a.Key.Equals(attributeName.RemoveSpecialCharacters()) && a.FieldTypeId == SingleSelectFieldTypeId);
                if (requirementResultAttribute == null)
                {
                    requirementResultAttribute = AddEntityAttribute(lookupContext, PersonEntityTypeId, string.Empty, string.Empty, string.Format("{0} imported {1}", attributeName, ImportDateTime),
                                                                    confidentialCategory, attributeName, attributeName.RemoveSpecialCharacters(), SingleSelectFieldTypeId, importPersonAliasId: ImportPersonAliasId);
                    personAttributes.Add(requirementResultAttribute);
                }

                // add any custom qualifiers
                var valuesQualifier = requirementResultAttribute.AttributeQualifiers.FirstOrDefault(q => q.Key.Equals("values", StringComparison.CurrentCultureIgnoreCase));
                if (valuesQualifier != null && !valuesQualifier.Value.Contains(requirementStatus))
                {
                    valuesQualifier = AddAttributeQualifier(lookupContext, requirementResultAttribute.Id, requirementStatus);
                }

                // make sure we have a valid person to assign to
                var matchingPerson = GetPersonKeys(individualId, null, includeVisitors: false);
                if (matchingPerson != null)
                {
                    var person = !peopleToUpdate.ContainsKey(matchingPerson.PersonId)
                        ? lookupContext.People.AsQueryable().AsNoTracking().FirstOrDefault(p => p.Id == matchingPerson.PersonId)
                        : peopleToUpdate[matchingPerson.PersonId];

                    if (person != null)
                    {
                        // could have multiple attributes assigned to this person, don't overwrite previous
                        if (person.Attributes == null || person.AttributeValues == null)
                        {
                            person.Attributes      = new Dictionary <string, AttributeCache>();
                            person.AttributeValues = new Dictionary <string, AttributeValueCache>();
                        }

                        AddEntityAttributeValue(lookupContext, requirementResultAttribute, person, requirementStatus);

                        if (requirementDate.HasValue)
                        {
                            AddEntityAttributeValue(lookupContext, requirementDateAttribute, person, requirementDate.Value.ToString("yyyy-MM-dd"));
                        }

                        if (requirementName.StartsWith("Background Check", StringComparison.CurrentCultureIgnoreCase))
                        {
                            AddEntityAttributeValue(lookupContext, backgroundCheckedAttribute, person, "True");
                        }

                        // add all the person changes to the batch
                        if (!peopleToUpdate.ContainsKey(matchingPerson.PersonId))
                        {
                            peopleToUpdate.Add(matchingPerson.PersonId, person);
                        }
                        else
                        {
                            peopleToUpdate[matchingPerson.PersonId] = person;
                        }
                    }
                }

                completedItems++;
                if (completedItems % percentage < 1)
                {
                    var percentComplete = completedItems / percentage;
                    ReportProgress(percentComplete, $"{completedItems:N0} requirements imported ({percentComplete}% complete).");
                }

                if (completedItems % ReportingNumber < 1)
                {
                    SaveAttributes(peopleToUpdate);

                    // reset so context doesn't bloat
                    lookupContext.Dispose();
                    lookupContext = new RockContext();
                    peopleToUpdate.Clear();
                    ReportPartialProgress();
                }
            }

            SaveAttributes(peopleToUpdate);

            ReportProgress(100, $"Finished requirement import: {completedItems:N0} requirements imported.");
        }
Beispiel #19
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            using (new UnitOfWorkScope())
            {
                var attributeService          = new AttributeService();
                var attributeQualifierService = new AttributeQualifierService();

                Rock.Model.Attribute attribute;

                int attributeId = 0;
                if (hfId.Value != string.Empty && !int.TryParse(hfId.Value, out attributeId))
                {
                    attributeId = 0;
                }

                if (attributeId == 0)
                {
                    attribute              = new Rock.Model.Attribute();
                    attribute.IsSystem     = false;
                    attribute.EntityTypeId = _entityTypeId;
                    attribute.EntityTypeQualifierColumn = _entityQualifierColumn;
                    attribute.EntityTypeQualifierValue  = _entityQualifierValue;
                    attributeService.Add(attribute, CurrentPersonId);
                }
                else
                {
                    AttributeCache.Flush(attributeId);
                    attribute = attributeService.Get(attributeId);
                }

                attribute.Key         = tbKey.Text;
                attribute.Name        = tbName.Text;
                attribute.Category    = tbCategory.Text;
                attribute.Description = tbDescription.Text;
                attribute.FieldTypeId = int.Parse(ddlFieldType.SelectedValue);

                var fieldType = FieldTypeCache.Read(attribute.FieldTypeId);

                foreach (var oldQualifier in attribute.AttributeQualifiers.ToList())
                {
                    attributeQualifierService.Delete(oldQualifier, CurrentPersonId);
                }

                attribute.AttributeQualifiers.Clear();

                List <Control> configControls = new List <Control>();
                foreach (var key in fieldType.Field.ConfigurationKeys())
                {
                    configControls.Add(phFieldTypeQualifiers.FindControl("configControl_" + key));
                }

                foreach (var configValue in fieldType.Field.ConfigurationValues(configControls))
                {
                    AttributeQualifier qualifier = new AttributeQualifier();
                    qualifier.IsSystem = false;
                    qualifier.Key      = configValue.Key;
                    qualifier.Value    = configValue.Value.Value ?? string.Empty;
                    attribute.AttributeQualifiers.Add(qualifier);
                }

                attribute.DefaultValue = tbDefaultValue.Text;
                attribute.IsMultiValue = cbMultiValue.Checked;
                attribute.IsRequired   = cbRequired.Checked;

                attributeService.Save(attribute, CurrentPersonId);
            }

            BindGrid();

            pnlDetails.Visible = false;
            pnlList.Visible    = true;
        }
Beispiel #20
0
        protected void btnSave_Click(object sender, EventArgs e)
        {
            RockContext rockContext = new RockContext();

            rockContext.WrapTransaction(() =>
            {
                WidgityTypeService widgityTypeService = new WidgityTypeService(rockContext);
                AttributeService attributeService     = new AttributeService(rockContext);
                WidgityType widgityType = GetWidgityType(widgityTypeService);

                if (widgityType.Id == 0)
                {
                    widgityTypeService.Add(widgityType);
                }

                widgityType.Name                = tbName.Text;
                widgityType.Description         = tbDescription.Text;
                widgityType.EnabledLavaCommands = lcCommands.SelectedValue;
                widgityType.Icon                = tbIcon.Text;
                widgityType.Markdown            = ceMarkup.Text;
                widgityType.HasItems            = cbHasItems.Checked;
                var _ = widgityType.EntityTypes.ToList(); //Attach the entity types to context
                widgityType.EntityTypes = new EntityTypeService(rockContext).GetByIds(lbEntityTypes.SelectedValuesAsInt).ToList();
                widgityType.CategoryId  = pCategory.SelectedValueAsId();
                rockContext.SaveChanges();

                //Widgity Attributes
                var widgityEntityTypeId = EntityTypeCache.Get(typeof(Widgity)).Id;

                var actualAttributes = attributeService.Queryable()
                                       .Where(a => a.EntityTypeId == widgityEntityTypeId && a.EntityTypeQualifierValue == widgityType.Id.ToString())
                                       .OrderBy(a => a.Order)
                                       .ToList();

                //Remove deleted attributes
                foreach (var attribute in actualAttributes)
                {
                    if (!WidgityAttributes.Where(a => a.Guid == attribute.Guid).Any())
                    {
                        attributeService.Delete(attribute);
                    }
                }

                //Update db from viewstate
                foreach (var attribute in WidgityAttributes)
                {
                    if (attribute.Id == 0)
                    {
                        attribute.Order = WidgityAttributes.IndexOf(attribute);
                        attribute.EntityTypeQualifierValue = widgityType.Id.ToString();
                        attributeService.Add(attribute);
                    }
                    else
                    {
                        var trackedAttribute = actualAttributes.Where(a => a.Guid == attribute.Guid).FirstOrDefault();
                        trackedAttribute.CopyPropertiesFrom(attribute);
                        foreach (var qualifier in trackedAttribute.AttributeQualifiers)
                        {
                            var value = attribute.AttributeQualifiers.Where(q => q.Key == qualifier.Key).FirstOrDefault();
                            if (value != null)
                            {
                                qualifier.Value = value.Value;
                            }
                        }
                        trackedAttribute.Order = WidgityAttributes.IndexOf(attribute);
                    }
                }
                rockContext.SaveChanges();


                //Widgity Item Attributes
                var widgityItemEntityTypeId = EntityTypeCache.Get(typeof(WidgityItem)).Id;

                var actualItemAttributes = attributeService.Queryable()
                                           .Where(a => a.EntityTypeId == widgityItemEntityTypeId && a.EntityTypeQualifierValue == widgityType.Id.ToString())
                                           .OrderBy(a => a.Order)
                                           .ToList();

                //Remove deleted attributes
                foreach (var attribute in actualItemAttributes)
                {
                    if (!WidgityItemAttributes.Where(a => a.Guid == attribute.Guid).Any())
                    {
                        attributeService.Delete(attribute);
                    }
                }

                //Update db from viewstate
                foreach (var attribute in WidgityItemAttributes)
                {
                    if (attribute.Id == 0)
                    {
                        attribute.Order = WidgityItemAttributes.IndexOf(attribute);
                        attribute.EntityTypeQualifierValue = widgityType.Id.ToString();
                        attributeService.Add(attribute);
                    }
                    else
                    {
                        var trackedAttribute = actualItemAttributes.Where(a => a.Guid == attribute.Guid).FirstOrDefault();
                        trackedAttribute.CopyPropertiesFrom(attribute);
                        foreach (var qualifier in trackedAttribute.AttributeQualifiers)
                        {
                            var value = attribute.AttributeQualifiers.Where(q => q.Key == qualifier.Key).FirstOrDefault();
                            if (value != null)
                            {
                                qualifier.Value = value.Value;
                            }
                        }
                        trackedAttribute.Order = WidgityItemAttributes.IndexOf(attribute);
                    }
                }
                rockContext.SaveChanges();
            });
            WidgityTypeCache.Clear();
            WidgityCache.Clear();
            WidgityItemCache.Clear();
            NavigateToParentPage();
        }
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            MarketingCampaignAdType        marketingCampaignAdType;
            MarketingCampaignAdTypeService marketingCampaignAdTypeService = new MarketingCampaignAdTypeService();

            int marketingCampaignAdTypeId = int.Parse(hfMarketingCampaignAdTypeId.Value);

            if (marketingCampaignAdTypeId == 0)
            {
                marketingCampaignAdType = new MarketingCampaignAdType();
                marketingCampaignAdTypeService.Add(marketingCampaignAdType, CurrentPersonId);
            }
            else
            {
                marketingCampaignAdType = marketingCampaignAdTypeService.Get(marketingCampaignAdTypeId);
            }

            marketingCampaignAdType.Name          = tbName.Text;
            marketingCampaignAdType.DateRangeType = (DateRangeTypeEnum)int.Parse(ddlDateRangeType.SelectedValue);

            // check for duplicates
            if (marketingCampaignAdTypeService.Queryable().Count(a => a.Name.Equals(marketingCampaignAdType.Name, StringComparison.OrdinalIgnoreCase) && !a.Id.Equals(marketingCampaignAdType.Id)) > 0)
            {
                tbName.ShowErrorMessage(WarningMessage.DuplicateFoundMessage("name", MarketingCampaignAdType.FriendlyTypeName));
                return;
            }

            if (!marketingCampaignAdType.IsValid)
            {
                // Controls will render the error messages
                return;
            }

            RockTransactionScope.WrapTransaction(() =>
            {
                marketingCampaignAdTypeService.Save(marketingCampaignAdType, CurrentPersonId);

                // get it back to make sure we have a good Id for it for the Attributes
                marketingCampaignAdType = marketingCampaignAdTypeService.Get(marketingCampaignAdType.Guid);

                // delete AdTypeAttributes that are no longer configured in the UI
                AttributeService attributeService = new AttributeService();
                var qry = attributeService.GetByEntityTypeId(new MarketingCampaignAd().TypeId).AsQueryable()
                          .Where(a => a.EntityTypeQualifierColumn.Equals("MarketingCampaignAdTypeId", StringComparison.OrdinalIgnoreCase) &&
                                 a.EntityTypeQualifierValue.Equals(marketingCampaignAdType.Id.ToString()));

                var deletedAttributes = from attr in qry
                                        where !(from d in AttributesState
                                                select d.Guid).Contains(attr.Guid)
                                        select attr;

                deletedAttributes.ToList().ForEach(a =>
                {
                    var attr = attributeService.Get(a.Guid);
                    attributeService.Delete(attr, CurrentPersonId);
                    attributeService.Save(attr, CurrentPersonId);
                });

                // add/update the AdTypes that are assigned in the UI
                foreach (var attributeState in AttributesState)
                {
                    Attribute attribute = qry.FirstOrDefault(a => a.Guid.Equals(attributeState.Guid));
                    if (attribute == null)
                    {
                        attribute = attributeState.ToModel();
                        attributeService.Add(attribute, CurrentPersonId);
                    }
                    else
                    {
                        attributeState.Id = attribute.Id;
                        attributeState.CopyToModel(attribute);
                    }

                    attribute.EntityTypeQualifierColumn = "MarketingCampaignAdTypeId";
                    attribute.EntityTypeQualifierValue  = marketingCampaignAdType.Id.ToString();
                    attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(new MarketingCampaignAd().TypeName).Id;
                    attributeService.Save(attribute, CurrentPersonId);
                }
            });

            BindGrid();
            pnlDetails.Visible = false;
            pnlList.Visible    = true;
        }
Beispiel #22
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            using (new UnitOfWorkScope())
            {
                GroupType        groupType;
                GroupTypeService groupTypeService = new GroupTypeService();
                AttributeService attributeService = new AttributeService();

                int groupTypeId = int.Parse(hfGroupTypeId.Value);

                if (groupTypeId == 0)
                {
                    groupType = new GroupType();
                    groupTypeService.Add(groupType, CurrentPersonId);
                }
                else
                {
                    groupType = groupTypeService.Get(groupTypeId);
                }

                groupType.Name = tbName.Text;

                groupType.Description             = tbDescription.Text;
                groupType.GroupTerm               = tbGroupTerm.Text;
                groupType.GroupMemberTerm         = tbGroupMemberTerm.Text;
                groupType.DefaultGroupRoleId      = ddlDefaultGroupRole.SelectedValueAsInt();
                groupType.ShowInGroupList         = cbShowInGroupList.Checked;
                groupType.ShowInNavigation        = cbShowInNavigation.Checked;
                groupType.IconCssClass            = tbIconCssClass.Text;
                groupType.IconSmallFileId         = imgIconSmall.BinaryFileId;
                groupType.IconLargeFileId         = imgIconLarge.BinaryFileId;
                groupType.TakesAttendance         = cbTakesAttendance.Checked;
                groupType.AttendanceRule          = ddlAttendanceRule.SelectedValueAsEnum <AttendanceRule>();
                groupType.AttendancePrintTo       = ddlAttendancePrintTo.SelectedValueAsEnum <PrintTo>();
                groupType.LocationSelectionMode   = ddlLocationSelectionMode.SelectedValueAsEnum <LocationPickerMode>();
                groupType.GroupTypePurposeValueId = ddlGroupTypePurpose.SelectedValueAsInt();
                groupType.AllowMultipleLocations  = cbAllowMultipleLocations.Checked;
                groupType.InheritedGroupTypeId    = gtpInheritedGroupType.SelectedGroupTypeId;

                groupType.ChildGroupTypes = new List <GroupType>();
                groupType.ChildGroupTypes.Clear();
                foreach (var item in ChildGroupTypesDictionary)
                {
                    var childGroupType = groupTypeService.Get(item.Key);
                    if (childGroupType != null)
                    {
                        groupType.ChildGroupTypes.Add(childGroupType);
                    }
                }

                DefinedValueService definedValueService = new DefinedValueService();

                groupType.LocationTypes = new List <GroupTypeLocationType>();
                groupType.LocationTypes.Clear();
                foreach (var item in LocationTypesDictionary)
                {
                    var locationType = definedValueService.Get(item.Key);
                    if (locationType != null)
                    {
                        groupType.LocationTypes.Add(new GroupTypeLocationType {
                            LocationTypeValueId = locationType.Id
                        });
                    }
                }

                if (!groupType.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                RockTransactionScope.WrapTransaction(() =>
                {
                    groupTypeService.Save(groupType, CurrentPersonId);

                    // get it back to make sure we have a good Id for it for the Attributes
                    groupType = groupTypeService.Get(groupType.Guid);

                    /* Take care of Group Type Attributes */

                    // delete GroupTypeAttributes that are no longer configured in the UI
                    var groupTypeAttributesQry = attributeService.Get(new GroupType().TypeId, "Id", groupType.Id.ToString());
                    var selectedAttributes     = GroupTypeAttributesState.Select(a => a.Guid);
                    foreach (var attr in groupTypeAttributesQry.Where(a => !selectedAttributes.Contains(a.Guid)))
                    {
                        Rock.Web.Cache.AttributeCache.Flush(attr.Id);
                        attributeService.Delete(attr, CurrentPersonId);
                        attributeService.Save(attr, CurrentPersonId);
                    }

                    string qualifierValue = groupType.Id.ToString();

                    // add/update the GroupTypeAttributes that are assigned in the UI
                    foreach (var attributeState in GroupTypeAttributesState
                             .Where(a =>
                                    a.EntityTypeQualifierValue == null ||
                                    a.EntityTypeQualifierValue.Trim() == string.Empty ||
                                    a.EntityTypeQualifierValue.Equals(qualifierValue)))
                    {
                        // remove old qualifiers in case they changed
                        var qualifierService = new AttributeQualifierService();
                        foreach (var oldQualifier in qualifierService.GetByAttributeId(attributeState.Id).ToList())
                        {
                            qualifierService.Delete(oldQualifier, CurrentPersonId);
                            qualifierService.Save(oldQualifier, CurrentPersonId);
                        }

                        Attribute attribute = groupTypeAttributesQry.FirstOrDefault(a => a.Guid.Equals(attributeState.Guid));
                        if (attribute == null)
                        {
                            attribute = attributeState.Clone() as Rock.Model.Attribute;
                            attributeService.Add(attribute, CurrentPersonId);
                        }
                        else
                        {
                            attributeState.Id = attribute.Id;
                            attribute.FromDictionary(attributeState.ToDictionary());

                            foreach (var qualifier in attributeState.AttributeQualifiers)
                            {
                                attribute.AttributeQualifiers.Add(qualifier.Clone() as AttributeQualifier);
                            }
                        }

                        attribute.EntityTypeQualifierColumn = "Id";
                        attribute.EntityTypeQualifierValue  = qualifierValue;
                        attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(typeof(GroupType)).Id;
                        Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                        attributeService.Save(attribute, CurrentPersonId);
                    }

                    /* Take care of Group Attributes */

                    // delete GroupAttributes that are no longer configured in the UI
                    var groupAttributesQry = attributeService.Get(new Group().TypeId, "GroupTypeId", groupType.Id.ToString());
                    selectedAttributes     = GroupAttributesState.Select(a => a.Guid);
                    foreach (var attr in groupAttributesQry.Where(a => !selectedAttributes.Contains(a.Guid)))
                    {
                        Rock.Web.Cache.AttributeCache.Flush(attr.Id);
                        attributeService.Delete(attr, CurrentPersonId);
                        attributeService.Save(attr, CurrentPersonId);
                    }

                    // add/update the GroupAttributes that are assigned in the UI
                    foreach (var attributeState in GroupAttributesState
                             .Where(a =>
                                    a.EntityTypeQualifierValue == null ||
                                    a.EntityTypeQualifierValue.Trim() == string.Empty ||
                                    a.EntityTypeQualifierValue.Equals(qualifierValue)))
                    {
                        // remove old qualifiers in case they changed
                        var qualifierService = new AttributeQualifierService();
                        foreach (var oldQualifier in qualifierService.GetByAttributeId(attributeState.Id).ToList())
                        {
                            qualifierService.Delete(oldQualifier, CurrentPersonId);
                            qualifierService.Save(oldQualifier, CurrentPersonId);
                        }

                        Attribute attribute = groupAttributesQry.FirstOrDefault(a => a.Guid.Equals(attributeState.Guid));
                        if (attribute == null)
                        {
                            attribute = attributeState.Clone() as Rock.Model.Attribute;
                            attributeService.Add(attribute, CurrentPersonId);
                        }
                        else
                        {
                            attributeState.Id = attribute.Id;
                            attribute.FromDictionary(attributeState.ToDictionary());

                            foreach (var qualifier in attributeState.AttributeQualifiers)
                            {
                                attribute.AttributeQualifiers.Add(qualifier.Clone() as AttributeQualifier);
                            }
                        }

                        attribute.EntityTypeQualifierColumn = "GroupTypeId";
                        attribute.EntityTypeQualifierValue  = qualifierValue;
                        attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(typeof(Group)).Id;
                        Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                        attributeService.Save(attribute, CurrentPersonId);
                    }
                });
            }
            NavigateToParentPage();
        }
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            bool hasValidationErrors = false;

            var rockContext = new RockContext();

            GroupTypeService     groupTypeService     = new GroupTypeService(rockContext);
            GroupService         groupService         = new GroupService(rockContext);
            AttributeService     attributeService     = new AttributeService(rockContext);
            GroupLocationService groupLocationService = new GroupLocationService(rockContext);

            int parentGroupTypeId = hfParentGroupTypeId.ValueAsInt();

            var groupTypeUIList = new List <GroupType>();

            foreach (var checkinGroupTypeEditor in phCheckinGroupTypes.Controls.OfType <CheckinGroupTypeEditor>().ToList())
            {
                var groupType = checkinGroupTypeEditor.GetCheckinGroupType();
                groupTypeUIList.Add(groupType);
            }

            var groupTypeDBList = new List <GroupType>();

            var groupTypesToDelete = new List <GroupType>();
            var groupsToDelete     = new List <Group>();

            var groupTypesToAddUpdate = new List <GroupType>();
            var groupsToAddUpdate     = new List <Group>();

            GroupType parentGroupTypeDB = groupTypeService.Get(parentGroupTypeId);
            GroupType parentGroupTypeUI = parentGroupTypeDB.Clone(false);

            parentGroupTypeUI.ChildGroupTypes = groupTypeUIList;

            PopulateDeleteLists(groupTypesToDelete, groupsToDelete, parentGroupTypeDB, parentGroupTypeUI);
            PopulateAddUpdateLists(groupTypesToAddUpdate, groupsToAddUpdate, parentGroupTypeUI);

            int binaryFileFieldTypeID = FieldTypeCache.Read(Rock.SystemGuid.FieldType.BINARY_FILE.AsGuid()).Id;
            int binaryFileTypeId      = new BinaryFileTypeService(rockContext).Get(new Guid(Rock.SystemGuid.BinaryFiletype.CHECKIN_LABEL)).Id;

            RockTransactionScope.WrapTransaction(() =>
            {
                // delete in reverse order to get deepest child items first
                groupsToDelete.Reverse();
                foreach (var groupToDelete in groupsToDelete)
                {
                    groupService.Delete(groupToDelete);
                }

                // delete in reverse order to get deepest child items first
                groupTypesToDelete.Reverse();
                foreach (var groupTypeToDelete in groupTypesToDelete)
                {
                    groupTypeService.Delete(groupTypeToDelete);
                }

                rockContext.SaveChanges();

                // Add/Update grouptypes and groups that are in the UI
                // Note:  We'll have to save all the groupTypes without changing the DB value of ChildGroupTypes, then come around again and save the ChildGroupTypes
                // since the ChildGroupTypes may not exist in the database yet
                foreach (GroupType groupTypeUI in groupTypesToAddUpdate)
                {
                    GroupType groupTypeDB = groupTypeService.Get(groupTypeUI.Guid);
                    if (groupTypeDB == null)
                    {
                        groupTypeDB      = new GroupType();
                        groupTypeDB.Id   = 0;
                        groupTypeDB.Guid = groupTypeUI.Guid;
                    }

                    groupTypeDB.Name  = groupTypeUI.Name;
                    groupTypeDB.Order = groupTypeUI.Order;
                    groupTypeDB.InheritedGroupTypeId = groupTypeUI.InheritedGroupTypeId;

                    groupTypeDB.Attributes      = groupTypeUI.Attributes;
                    groupTypeDB.AttributeValues = groupTypeUI.AttributeValues;

                    if (groupTypeDB.Id == 0)
                    {
                        groupTypeService.Add(groupTypeDB);
                    }

                    if (!groupTypeDB.IsValid)
                    {
                        hasValidationErrors = true;
                        CheckinGroupTypeEditor groupTypeEditor = phCheckinGroupTypes.ControlsOfTypeRecursive <CheckinGroupTypeEditor>().First(a => a.GroupTypeGuid == groupTypeDB.Guid);
                        groupTypeEditor.ForceContentVisible    = true;

                        return;
                    }

                    rockContext.SaveChanges();

                    groupTypeDB.SaveAttributeValues();

                    // get fresh from database to make sure we have Id so we can update the CheckinLabel Attributes
                    groupTypeDB = groupTypeService.Get(groupTypeDB.Guid);

                    // rebuild the CheckinLabel attributes from the UI (brute-force)
                    foreach (var labelAttributeDB in CheckinGroupTypeEditor.GetCheckinLabelAttributes(groupTypeDB))
                    {
                        var attribute = attributeService.Get(labelAttributeDB.Value.Guid);
                        Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                        attributeService.Delete(attribute);
                    }
                    rockContext.SaveChanges();

                    foreach (var checkinLabelAttributeInfo in GroupTypeCheckinLabelAttributesState[groupTypeUI.Guid])
                    {
                        var attribute = new Rock.Model.Attribute();
                        attribute.AttributeQualifiers.Add(new AttributeQualifier {
                            Key = "binaryFileType", Value = binaryFileTypeId.ToString()
                        });
                        attribute.Guid         = Guid.NewGuid();
                        attribute.FieldTypeId  = binaryFileFieldTypeID;
                        attribute.EntityTypeId = EntityTypeCache.GetId(typeof(GroupType));
                        attribute.EntityTypeQualifierColumn = "Id";
                        attribute.EntityTypeQualifierValue  = groupTypeDB.Id.ToString();
                        attribute.DefaultValue = checkinLabelAttributeInfo.BinaryFileId.ToString();
                        attribute.Key          = checkinLabelAttributeInfo.AttributeKey;
                        attribute.Name         = checkinLabelAttributeInfo.FileName;

                        if (!attribute.IsValid)
                        {
                            hasValidationErrors = true;
                            CheckinGroupTypeEditor groupTypeEditor = phCheckinGroupTypes.ControlsOfTypeRecursive <CheckinGroupTypeEditor>().First(a => a.GroupTypeGuid == groupTypeDB.Guid);
                            groupTypeEditor.ForceContentVisible    = true;

                            return;
                        }

                        attributeService.Add(attribute);
                    }
                    rockContext.SaveChanges();
                }

                // Add/Update Groups
                foreach (var groupUI in groupsToAddUpdate)
                {
                    Group groupDB = groupService.Get(groupUI.Guid);
                    if (groupDB == null)
                    {
                        groupDB      = new Group();
                        groupDB.Guid = groupUI.Guid;
                    }

                    groupDB.Name = groupUI.Name;

                    // delete any GroupLocations that were removed in the UI
                    foreach (var groupLocationDB in groupDB.GroupLocations.ToList())
                    {
                        if (!groupUI.GroupLocations.Select(a => a.LocationId).Contains(groupLocationDB.LocationId))
                        {
                            groupLocationService.Delete(groupLocationDB);
                        }
                    }

                    // add any GroupLocations that were added in the UI
                    foreach (var groupLocationUI in groupUI.GroupLocations)
                    {
                        if (!groupDB.GroupLocations.Select(a => a.LocationId).Contains(groupLocationUI.LocationId))
                        {
                            GroupLocation groupLocationDB = new GroupLocation {
                                LocationId = groupLocationUI.LocationId
                            };
                            groupDB.GroupLocations.Add(groupLocationDB);
                        }
                    }

                    groupDB.Order = groupUI.Order;

                    // get GroupTypeId from database in case the groupType is new
                    groupDB.GroupTypeId     = groupTypeService.Get(groupUI.GroupType.Guid).Id;
                    groupDB.Attributes      = groupUI.Attributes;
                    groupDB.AttributeValues = groupUI.AttributeValues;

                    if (groupDB.Id == 0)
                    {
                        groupService.Add(groupDB);
                    }

                    if (!groupDB.IsValid)
                    {
                        hasValidationErrors             = true;
                        hasValidationErrors             = true;
                        CheckinGroupEditor groupEditor  = phCheckinGroupTypes.ControlsOfTypeRecursive <CheckinGroupEditor>().First(a => a.GroupGuid == groupDB.Guid);
                        groupEditor.ForceContentVisible = true;

                        return;
                    }

                    rockContext.SaveChanges();

                    groupDB.SaveAttributeValues();
                }

                /* now that we have all the grouptypes saved, now lets go back and save them again with the current UI ChildGroupTypes */

                // save main parentGroupType with current UI ChildGroupTypes
                parentGroupTypeDB.ChildGroupTypes = new List <GroupType>();
                parentGroupTypeDB.ChildGroupTypes.Clear();
                foreach (var childGroupTypeUI in parentGroupTypeUI.ChildGroupTypes)
                {
                    var childGroupTypeDB = groupTypeService.Get(childGroupTypeUI.Guid);
                    parentGroupTypeDB.ChildGroupTypes.Add(childGroupTypeDB);
                }

                rockContext.SaveChanges();

                // loop thru all the other GroupTypes in the UI and save their childgrouptypes
                foreach (var groupTypeUI in groupTypesToAddUpdate)
                {
                    var groupTypeDB             = groupTypeService.Get(groupTypeUI.Guid);
                    groupTypeDB.ChildGroupTypes = new List <GroupType>();
                    groupTypeDB.ChildGroupTypes.Clear();
                    foreach (var childGroupTypeUI in groupTypeUI.ChildGroupTypes)
                    {
                        var childGroupTypeDB = groupTypeService.Get(childGroupTypeUI.Guid);
                        groupTypeDB.ChildGroupTypes.Add(childGroupTypeDB);
                    }
                }

                rockContext.SaveChanges();
            });

            if (!hasValidationErrors)
            {
                NavigateToParentPage();
            }
        }
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            Group group;
            bool  wasSecurityRole = false;

            using (new UnitOfWorkScope())
            {
                GroupService     groupService     = new GroupService();
                AttributeService attributeService = new AttributeService();

                int groupId = int.Parse(hfGroupId.Value);

                if (groupId == 0)
                {
                    group          = new Group();
                    group.IsSystem = false;
                    group.Name     = string.Empty;
                }
                else
                {
                    group           = groupService.Get(groupId);
                    wasSecurityRole = group.IsSecurityRole;
                }

                if ((ddlGroupType.SelectedValueAsInt() ?? 0) == 0)
                {
                    ddlGroupType.ShowErrorMessage(Rock.Constants.WarningMessage.CannotBeBlank(GroupType.FriendlyTypeName));
                    return;
                }

                group.Name           = tbName.Text;
                group.Description    = tbDescription.Text;
                group.CampusId       = ddlCampus.SelectedValue.Equals(None.IdValue) ? (int?)null : int.Parse(ddlCampus.SelectedValue);
                group.GroupTypeId    = int.Parse(ddlGroupType.SelectedValue);
                group.ParentGroupId  = gpParentGroup.SelectedValue.Equals(None.IdValue) ? (int?)null : int.Parse(gpParentGroup.SelectedValue);
                group.IsSecurityRole = cbIsSecurityRole.Checked;
                group.IsActive       = cbIsActive.Checked;

                if (group.ParentGroupId == group.Id)
                {
                    gpParentGroup.ShowErrorMessage("Group cannot be a Parent Group of itself.");
                    return;
                }

                group.LoadAttributes();

                Rock.Attribute.Helper.GetEditValues(phGroupAttributes, group);

                if (!Page.IsValid)
                {
                    return;
                }

                if (!group.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                RockTransactionScope.WrapTransaction(() =>
                {
                    if (group.Id.Equals(0))
                    {
                        groupService.Add(group, CurrentPersonId);
                    }

                    groupService.Save(group, CurrentPersonId);
                    Rock.Attribute.Helper.SaveAttributeValues(group, CurrentPersonId);

                    /* Take care of Group Member Attributes */

                    // delete GroupMemberAttributes that are no longer configured in the UI
                    string qualifierValue        = group.Id.ToString();
                    var groupMemberAttributesQry = attributeService.GetByEntityTypeId(new GroupMember().TypeId).AsQueryable()
                                                   .Where(a => a.EntityTypeQualifierColumn.Equals("GroupId", StringComparison.OrdinalIgnoreCase) &&
                                                          a.EntityTypeQualifierValue.Equals(qualifierValue));

                    var deletedGroupMemberAttributes = from attr in groupMemberAttributesQry
                                                       where !(from d in GroupMemberAttributesState
                                                               select d.Guid).Contains(attr.Guid)
                                                       select attr;

                    deletedGroupMemberAttributes.ToList().ForEach(a =>
                    {
                        var attr = attributeService.Get(a.Guid);
                        Rock.Web.Cache.AttributeCache.Flush(attr.Id);
                        attributeService.Delete(attr, CurrentPersonId);
                        attributeService.Save(attr, CurrentPersonId);
                    });

                    // add/update the GroupMemberAttributes that are assigned in the UI
                    foreach (var attributeState in GroupMemberAttributesState)
                    {
                        // remove old qualifiers in case they changed
                        var qualifierService = new AttributeQualifierService();
                        foreach (var oldQualifier in qualifierService.GetByAttributeId(attributeState.Id).ToList())
                        {
                            qualifierService.Delete(oldQualifier, CurrentPersonId);
                            qualifierService.Save(oldQualifier, CurrentPersonId);
                        }

                        Attribute attribute = groupMemberAttributesQry.FirstOrDefault(a => a.Guid.Equals(attributeState.Guid));
                        if (attribute == null)
                        {
                            attribute = attributeState.Clone() as Rock.Model.Attribute;
                            attributeService.Add(attribute, CurrentPersonId);
                        }
                        else
                        {
                            attributeState.Id = attribute.Id;
                            attribute.FromDictionary(attributeState.ToDictionary());

                            foreach (var qualifier in attributeState.AttributeQualifiers)
                            {
                                attribute.AttributeQualifiers.Add(qualifier.Clone() as AttributeQualifier);
                            }
                        }

                        attribute.EntityTypeQualifierColumn = "GroupId";
                        attribute.EntityTypeQualifierValue  = group.Id.ToString();
                        attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(typeof(GroupMember)).Id;
                        Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                        attributeService.Save(attribute, CurrentPersonId);
                    }
                });
            }

            if (group != null && wasSecurityRole)
            {
                if (!group.IsSecurityRole)
                {
                    // if this group was a SecurityRole, but no longer is, flush
                    Rock.Security.Role.Flush(group.Id);
                    Rock.Security.Authorization.Flush();
                }
            }
            else
            {
                if (group.IsSecurityRole)
                {
                    // new security role, flush
                    Rock.Security.Authorization.Flush();
                }
            }

            var qryParams = new Dictionary <string, string>();

            qryParams["groupId"] = group.Id.ToString();

            NavigateToPage(this.CurrentPage.Guid, qryParams);
        }
Beispiel #25
0
        /// <summary>
        /// Loads the group data.
        /// </summary>
        /// <param name="csvData">The CSV data.</param>
        private int LoadGroup(CSVInstance csvData)
        {
            // Required variables
            var lookupContext    = new RockContext();
            var locationService  = new LocationService(lookupContext);
            var groupTypeService = new GroupTypeService(lookupContext);

            var topicTypes = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.SMALL_GROUP_TOPIC), lookupContext).DefinedValues;

            var numImportedGroups = ImportedGroups.Count();

            var newGroupLocations = new Dictionary <GroupLocation, string>();
            var currentGroup      = new Group();

            // Look for custom attributes in the Individual file
            var allFields        = csvData.TableNodes.FirstOrDefault().Children.Select((node, index) => new { node = node, index = index }).ToList();
            var customAttributes = allFields
                                   .Where(f => f.index > GroupCapacity)
                                   .ToDictionary(f => f.index, f => f.node.Name);

            var groupAttributes = new AttributeService(lookupContext).GetByEntityTypeId(new Group().TypeId).ToList();
            var completed       = 0;

            ReportProgress(0, $"Starting group import ({numImportedGroups:N0} already exist).");

            string[] row;
            // Uses a look-ahead enumerator: this call will move to the next record immediately
            while ((row = csvData.Database.FirstOrDefault()) != null)
            {
                var rowGroupKey = row[GroupId];

                //
                // Determine if we are still working with the same group or not.
                //
                if (rowGroupKey != null && rowGroupKey != currentGroup.ForeignKey)
                {
                    currentGroup = LoadGroupBasic(lookupContext, rowGroupKey, row[GroupName], row[GroupCreatedDate], row[GroupType], row[GroupParentGroupId], row[GroupActive], row[GroupDescription]);

                    //
                    // Set the group campus
                    //
                    var campusName = row[GroupCampus];
                    if (!string.IsNullOrWhiteSpace(campusName))
                    {
                        var groupCampus = CampusList.FirstOrDefault(c => c.Name.Equals(campusName, StringComparison.InvariantCultureIgnoreCase) ||
                                                                    c.ShortCode.Equals(campusName, StringComparison.InvariantCultureIgnoreCase));
                        if (groupCampus == null)
                        {
                            groupCampus = new Campus
                            {
                                IsSystem  = false,
                                Name      = campusName,
                                ShortCode = campusName.RemoveWhitespace(),
                                IsActive  = true
                            };
                            lookupContext.Campuses.Add(groupCampus);
                            lookupContext.SaveChanges(DisableAuditing);
                            CampusList.Add(groupCampus);
                        }

                        currentGroup.CampusId = groupCampus.Id;
                    }

                    //
                    // If the group type has one or more location types defined then import the
                    // primary address as the first location type.
                    //
                    var groupType = groupTypeService.Get(currentGroup.GroupTypeId);
                    if (groupType.LocationTypes.Count > 0 && (!string.IsNullOrWhiteSpace(row[GroupAddress]) || !string.IsNullOrWhiteSpace(row[GroupNamedLocation])) && currentGroup.GroupLocations.Count == 0)
                    {
                        var primaryLocationTypeId = groupType.LocationTypes.ToList()[0].LocationTypeValueId;

                        var grpAddress  = row[GroupAddress];
                        var grpAddress2 = row[GroupAddress2];
                        var grpCity     = row[GroupCity];
                        var grpState    = row[GroupState];
                        var grpZip      = row[GroupZip];
                        var grpCountry  = row[GroupCountry];

                        var namedLocation = row[GroupNamedLocation];

                        if (string.IsNullOrWhiteSpace(namedLocation))
                        {
                            var primaryAddress = locationService.Get(grpAddress, grpAddress2, grpCity, grpState, grpZip, grpCountry, verifyLocation: false);

                            if (primaryAddress != null)
                            {
                                var primaryLocation = new GroupLocation
                                {
                                    LocationId               = primaryAddress.Id,
                                    IsMailingLocation        = true,
                                    IsMappedLocation         = true,
                                    GroupLocationTypeValueId = primaryLocationTypeId
                                };
                                newGroupLocations.Add(primaryLocation, rowGroupKey);
                            }
                        }
                        else
                        {
                            var primaryAddress = locationService.Queryable().FirstOrDefault(l => l.Name.Equals(namedLocation) || l.ForeignKey.Equals(namedLocation));
                            if (primaryAddress != null)
                            {
                                var primaryLocation = new GroupLocation
                                {
                                    LocationId               = primaryAddress.Id,
                                    IsMailingLocation        = true,
                                    IsMappedLocation         = true,
                                    GroupLocationTypeValueId = primaryLocationTypeId
                                };
                                newGroupLocations.Add(primaryLocation, rowGroupKey);
                            }
                            else
                            {
                                LogException("Group Import", string.Format("The named location {0} was not found and will not be mapped.", namedLocation));
                            }
                        }
                    }

                    //
                    // If the group type has two or more location types defined then import the
                    // secondary address as the group type's second location type.
                    //
                    if (groupType.LocationTypes.Count > 1 && !string.IsNullOrWhiteSpace(row[GroupSecondaryAddress]) && currentGroup.GroupLocations.Count < 2)
                    {
                        var secondaryLocationTypeId = groupType.LocationTypes.ToList()[1].LocationTypeValueId;

                        var grpSecondAddress  = row[GroupSecondaryAddress];
                        var grpSecondAddress2 = row[GroupSecondaryAddress2];
                        var grpSecondCity     = row[GroupSecondaryCity];
                        var grpSecondState    = row[GroupSecondaryState];
                        var grpSecondZip      = row[GroupSecondaryZip];
                        var grpSecondCountry  = row[GroupSecondaryCountry];

                        var secondaryAddress = locationService.Get(grpSecondAddress, grpSecondAddress2, grpSecondCity, grpSecondState, grpSecondZip, grpSecondCountry, verifyLocation: false);

                        if (secondaryAddress != null)
                        {
                            var secondaryLocation = new GroupLocation
                            {
                                LocationId               = secondaryAddress.Id,
                                IsMailingLocation        = true,
                                IsMappedLocation         = true,
                                GroupLocationTypeValueId = secondaryLocationTypeId
                            };
                            newGroupLocations.Add(secondaryLocation, rowGroupKey);
                        }
                    }

                    //
                    // Set the group's sorting order.
                    //
                    var groupOrder = 9999;
                    int.TryParse(row[GroupOrder], out groupOrder);
                    currentGroup.Order = groupOrder;

                    //
                    // Set the group's capacity
                    //
                    var capacity = row[GroupCapacity].AsIntegerOrNull();
                    if (capacity.HasValue)
                    {
                        currentGroup.GroupCapacity = capacity;

                        if (groupType.GroupCapacityRule == GroupCapacityRule.None)
                        {
                            groupType.GroupCapacityRule = GroupCapacityRule.Hard;
                        }
                    }

                    //
                    // Set the group's schedule
                    //
                    if (!string.IsNullOrWhiteSpace(row[GroupDayOfWeek]))
                    {
                        DayOfWeek dayEnum;
                        if (Enum.TryParse(row[GroupDayOfWeek], true, out dayEnum))
                        {
                            if (groupType.AllowedScheduleTypes != ScheduleType.Weekly)
                            {
                                groupType.AllowedScheduleTypes = ScheduleType.Weekly;
                            }
                            var day  = dayEnum;
                            var time = row[GroupTime].AsDateTime();
                            currentGroup.ScheduleId = AddNamedSchedule(lookupContext, string.Empty, string.Empty, day, time, null, rowGroupKey).Id;
                        }
                    }

                    //
                    // Assign Attributes
                    //
                    if (customAttributes.Any())
                    {
                        lookupContext.SaveChanges();

                        foreach (var attributePair in customAttributes)
                        {
                            var pairs                  = attributePair.Value.Split('^');
                            var categoryName           = string.Empty;
                            var attributeName          = string.Empty;
                            var attributeTypeString    = string.Empty;
                            var attributeForeignKey    = string.Empty;
                            var definedValueForeignKey = string.Empty;
                            var fieldTypeId            = TextFieldTypeId;

                            if (pairs.Length == 1)
                            {
                                attributeName = pairs[0];
                            }
                            else if (pairs.Length == 2)
                            {
                                attributeName       = pairs[0];
                                attributeTypeString = pairs[1];
                            }
                            else if (pairs.Length >= 3)
                            {
                                categoryName  = pairs[1];
                                attributeName = pairs[2];
                                if (pairs.Length >= 4)
                                {
                                    attributeTypeString = pairs[3];
                                }
                                if (pairs.Length >= 5)
                                {
                                    attributeForeignKey = pairs[4];
                                }
                                if (pairs.Length >= 6)
                                {
                                    definedValueForeignKey = pairs[5];
                                }
                            }

                            var definedValueForeignId = definedValueForeignKey.AsType <int?>();

                            //
                            // Translate the provided attribute type into one we know about.
                            //
                            fieldTypeId = GetAttributeFieldType(attributeTypeString);

                            Rock.Model.Attribute currentAttribute = null;
                            if (string.IsNullOrEmpty(attributeName))
                            {
                                LogException("Group Attribute", string.Format("Group Attribute Name cannot be blank '{0}'.", attributePair.Value));
                            }
                            else
                            {
                                if (string.IsNullOrWhiteSpace(attributeForeignKey))
                                {
                                    attributeForeignKey = string.Format("Bulldozer_{0}_{1}_{2}", groupType.Id, categoryName.RemoveWhitespace(), attributeName.RemoveWhitespace()).Left(100);
                                }
                                currentAttribute = groupAttributes.FirstOrDefault(a =>
                                                                                  a.Name.Equals(attributeName, StringComparison.OrdinalIgnoreCase) &&
                                                                                  a.FieldTypeId == fieldTypeId &&
                                                                                  a.EntityTypeId == currentGroup.TypeId &&
                                                                                  a.EntityTypeQualifierValue == groupType.Id.ToString()
                                                                                  );
                                if (currentAttribute == null)
                                {
                                    currentAttribute = AddEntityAttribute(lookupContext, currentGroup.TypeId, "GroupTypeId", groupType.Id.ToString(), attributeForeignKey, categoryName, attributeName, string.Empty, fieldTypeId, true, definedValueForeignId, definedValueForeignKey, attributeTypeString: attributeTypeString);
                                    groupAttributes.Add(currentAttribute);
                                }

                                var attributeValue = row[attributePair.Key];
                                if (!string.IsNullOrEmpty(attributeValue))
                                {
                                    AddEntityAttributeValue(lookupContext, currentAttribute, currentGroup, row[attributePair.Key], null, true);
                                }
                            }
                        }
                    }

                    //
                    // Changes to groups need to be saved right away since one group
                    // will reference another group.
                    //
                    lookupContext.SaveChanges();

                    //
                    // Keep the user informed as to what is going on and save in batches.
                    //
                    completed++;
                    if (completed % (ReportingNumber * 10) < 1)
                    {
                        ReportProgress(0, $"{completed:N0} groups imported.");
                    }

                    if (completed % ReportingNumber < 1)
                    {
                        SaveGroupLocations(newGroupLocations);
                        ReportPartialProgress();

                        // Reset lookup context
                        lookupContext.SaveChanges();
                        lookupContext    = new RockContext();
                        locationService  = new LocationService(lookupContext);
                        groupTypeService = new GroupTypeService(lookupContext);
                        newGroupLocations.Clear();
                    }
                }
            }

            //
            // Check to see if any rows didn't get saved to the database
            //
            if (newGroupLocations.Any())
            {
                SaveGroupLocations(newGroupLocations);
            }

            lookupContext.SaveChanges();
            lookupContext.Dispose();

            ReportProgress(0, $"Finished group import: {completed:N0} groups added or updated.");

            return(completed);
        }
Beispiel #26
0
        /// <summary>
        /// Verifies the attributes.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="categoryId">The category identifier.</param>
        private void VerifyAttributes(RockContext context, int categoryId)
        {
            var  attributeService = new AttributeService(context);
            var  category         = new CategoryService(context).Get(categoryId);
            bool hasChanges       = false;

            var serverUrl          = attributeService.GetGlobalAttribute(SERVER_URL_KEY);
            var serverRootPath     = attributeService.GetGlobalAttribute(SERVER_ROOT_PATH_KEY);
            var contentManagerUser = attributeService.GetGlobalAttribute(CONTENT_MANAGER_USER_KEY);
            var contentManagerPwd  = attributeService.GetGlobalAttribute(CONTENT_MANAGER_PWD_KEY);
            var browserUser        = attributeService.GetGlobalAttribute(BROWSER_USER_KEY);
            var browserPwd         = attributeService.GetGlobalAttribute(BROWSER_PWD_KEY);

            if (serverUrl == null)
            {
                serverUrl             = new Rock.Model.Attribute();
                serverUrl.FieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.URL_LINK).Id;
                serverUrl.IsSystem    = false;
                serverUrl.Name        = "Reporting Service URL";
                serverUrl.Description = "URL to the SQL Reporting Services Reporting Server endpoint.";
                serverUrl.Key         = SERVER_URL_KEY;
                serverUrl.IsRequired  = false;
                serverUrl.AllowSearch = false;
                serverUrl.Categories.Add(category);
                attributeService.Add(serverUrl);
                hasChanges = true;
            }

            if (serverRootPath == null)
            {
                serverRootPath             = new Rock.Model.Attribute();
                serverRootPath.FieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.TEXT).Id;
                serverRootPath.IsSystem    = false;
                serverRootPath.Name        = "Reporting Service Root Folder";
                serverRootPath.Key         = SERVER_ROOT_PATH_KEY;
                serverRootPath.Description = "Root/Base folder for Rock reports in reporting services.";
                serverRootPath.IsRequired  = false;
                serverRootPath.AllowSearch = false;
                serverRootPath.Categories.Add(category);
                attributeService.Add(serverRootPath);
                hasChanges = true;
            }

            if (contentManagerUser == null)
            {
                contentManagerUser             = new Rock.Model.Attribute();
                contentManagerUser.FieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.TEXT).Id;
                contentManagerUser.Name        = "Reporting Service - Content Manager Username";
                contentManagerUser.Key         = CONTENT_MANAGER_USER_KEY;
                contentManagerUser.Description = "The Reporting Server Content Manager (Report Administrator) User Name. (i.e. domain\\user format)";
                contentManagerUser.IsRequired  = false;
                contentManagerUser.AllowSearch = false;
                contentManagerUser.Categories.Add(category);
                attributeService.Add(contentManagerUser);
                hasChanges = true;
            }

            if (contentManagerPwd == null)
            {
                contentManagerPwd             = new Rock.Model.Attribute();
                contentManagerPwd.FieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.ENCRYPTED_TEXT).Id;
                contentManagerPwd.Name        = "Reporting Service - Content Manager Password";
                contentManagerPwd.Key         = CONTENT_MANAGER_PWD_KEY;
                contentManagerPwd.Description = "The Content Manager Password.";
                contentManagerPwd.IsRequired  = false;
                contentManagerPwd.AllowSearch = false;
                contentManagerPwd.Categories.Add(category);
                contentManagerPwd.AttributeQualifiers.Add(new AttributeQualifier {
                    IsSystem = false, Key = "ispassword", Value = bool.TrueString
                });
                attributeService.Add(contentManagerPwd);
                hasChanges = true;
            }

            if (browserUser == null)
            {
                browserUser             = new Rock.Model.Attribute();
                browserUser.FieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.ENCRYPTED_TEXT).Id;
                browserUser.Name        = "Reporting Service - Browser User";
                browserUser.Key         = BROWSER_USER_KEY;
                browserUser.Description = "The Reporting Server Browser (Report Viewer) User Name. (i.e. domain\\user format)";
                browserUser.IsRequired  = false;
                browserUser.AllowSearch = false;
                browserUser.Categories.Add(category);
                attributeService.Add(browserUser);
                hasChanges = true;
            }

            if (browserPwd == null)
            {
                browserPwd             = new Rock.Model.Attribute();
                browserPwd.FieldTypeId = FieldTypeCache.Get(Rock.SystemGuid.FieldType.ENCRYPTED_TEXT).Id;
                browserPwd.Name        = "Reporting Service - Browser Password";
                browserPwd.Key         = BROWSER_PWD_KEY;
                browserPwd.Description = "The Reporting Server Browser Password.";
                browserPwd.IsRequired  = false;
                browserPwd.AllowSearch = false;
                browserPwd.Categories.Add(category);
                browserPwd.AttributeQualifiers.Add(new AttributeQualifier {
                    IsSystem = false, Key = "ispassword", Value = bool.TrueString
                });
                attributeService.Add(browserPwd);
                hasChanges = true;
            }

            if (hasChanges)
            {
                context.SaveChanges();
                GlobalAttributesCache.Clear();
            }
        }
Beispiel #27
0
        /// <summary>
        /// Maps the specified folder.
        /// </summary>
        /// <param name="folder">The folder.</param>
        /// <param name="ministryFileType">Type of the ministry file.</param>
        /// <param name="storageProvider">The storage provider.</param>
        public void Map(ZipArchive folder, BinaryFileType ministryFileType, ProviderComponent storageProvider)
        {
            var lookupContext      = new RockContext();
            var personEntityTypeId = EntityTypeCache.GetId <Person>();
            var fileFieldTypeId    = FieldTypeCache.Read(Rock.SystemGuid.FieldType.FILE.AsGuid(), lookupContext).Id;

            var existingAttributes = new AttributeService(lookupContext).GetByFieldTypeId(fileFieldTypeId)
                                     .Where(a => a.EntityTypeId == personEntityTypeId)
                                     .ToDictionary(a => a.Key, a => a.Id);

            var emptyJsonObject = "{}";
            var newFileList     = new List <DocumentKeys>();

            int completed  = 0;
            int totalRows  = folder.Entries.Count;
            int percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, string.Format("Verifying files import ({0:N0} found.", totalRows));

            foreach (var file in folder.Entries)
            {
                var fileExtension = Path.GetExtension(file.Name);
                var fileMimeType  = Extensions.GetMIMEType(file.Name);
                if (BinaryFileComponent.FileTypeBlackList.Contains(fileExtension))
                {
                    LogException("Binary File Import", string.Format("{0} filetype not allowed ({1})", fileExtension, file.Name));
                    continue;
                }
                else if (fileMimeType == null)
                {
                    LogException("Binary File Import", string.Format("{0} filetype not recognized ({1})", fileExtension, file.Name));
                    continue;
                }

                string[] parsedFileName = file.Name.Split('_');
                // Ministry docs should follow this pattern:
                // 0. Firstname
                // 1. Lastname
                // 2. ForeignId
                // 3. Filename

                var personForeignId = parsedFileName[2].AsType <int?>();
                var personKeys      = BinaryFileComponent.ImportedPeople.FirstOrDefault(p => p.IndividualId == personForeignId);
                if (personKeys != null)
                {
                    var rockFile = new Rock.Model.BinaryFile();
                    rockFile.IsSystem         = false;
                    rockFile.IsTemporary      = false;
                    rockFile.FileName         = file.Name;
                    rockFile.MimeType         = fileMimeType;
                    rockFile.BinaryFileTypeId = ministryFileType.Id;
                    rockFile.CreatedDateTime  = file.LastWriteTime.DateTime;
                    rockFile.ModifiedDateTime = ImportDateTime;
                    rockFile.Description      = string.Format("Imported as {0}", file.Name);
                    rockFile.SetStorageEntityTypeId(ministryFileType.StorageEntityTypeId);
                    rockFile.StorageEntitySettings = emptyJsonObject;

                    if (ministryFileType.AttributeValues.Any())
                    {
                        rockFile.StorageEntitySettings = ministryFileType.AttributeValues
                                                         .ToDictionary(a => a.Key, v => v.Value.Value).ToJson();
                    }

                    // use base stream instead of file stream to keep the byte[]
                    // NOTE: if byte[] converts to a string it will corrupt the stream
                    using (var fileContent = new StreamReader(file.Open()))
                    {
                        rockFile.ContentStream = new MemoryStream(fileContent.BaseStream.ReadBytesToEnd());
                    }

                    var attributePattern = "[A-Za-z0-9-]+";
                    var attributeName    = Regex.Match(parsedFileName[3].RemoveWhitespace(), attributePattern);
                    var attributeKey     = attributeName.Value.RemoveWhitespace();

                    // change key to default key for Background Check Documents
                    if (attributeKey == "BackgroundCheck")
                    {
                        attributeKey = "BackgroundCheckDocument";
                    }

                    if (!existingAttributes.ContainsKey(attributeKey))
                    {
                        var newAttribute = new Attribute();
                        newAttribute.FieldTypeId  = fileFieldTypeId;
                        newAttribute.EntityTypeId = personEntityTypeId;
                        newAttribute.EntityTypeQualifierColumn = string.Empty;
                        newAttribute.EntityTypeQualifierValue  = string.Empty;
                        newAttribute.Key              = attributeKey;
                        newAttribute.Name             = attributeName.Value;
                        newAttribute.Description      = attributeName.Value + " created by binary file import";
                        newAttribute.CreatedDateTime  = ImportDateTime;
                        newAttribute.ModifiedDateTime = ImportDateTime;
                        newAttribute.IsGridColumn     = false;
                        newAttribute.IsMultiValue     = false;
                        newAttribute.IsRequired       = false;
                        newAttribute.AllowSearch      = false;
                        newAttribute.IsSystem         = false;
                        newAttribute.Order            = 0;

                        newAttribute.AttributeQualifiers.Add(new AttributeQualifier()
                        {
                            Key   = "binaryFileType",
                            Value = ministryFileType.Guid.ToString()
                        });

                        lookupContext.Attributes.Add(newAttribute);
                        lookupContext.SaveChanges();

                        existingAttributes.Add(newAttribute.Key, newAttribute.Id);
                    }

                    newFileList.Add(new DocumentKeys()
                    {
                        PersonId    = personKeys.PersonId,
                        AttributeId = existingAttributes[attributeKey],
                        File        = rockFile
                    });

                    completed++;
                    if (completed % percentage < 1)
                    {
                        int percentComplete = completed / percentage;
                        ReportProgress(percentComplete, string.Format("{0:N0} files imported ({1}% complete).", completed, percentComplete));
                    }
                    else if (completed % ReportingNumber < 1)
                    {
                        SaveFiles(newFileList, storageProvider);

                        // Reset list
                        newFileList.Clear();
                        ReportPartialProgress();
                    }
                }
            }

            if (newFileList.Any())
            {
                SaveFiles(newFileList, storageProvider);
            }

            ReportProgress(100, string.Format("Finished files import: {0:N0} addresses imported.", completed));
        }
Beispiel #28
0
        /// <summary>
        /// Adds or Updates a <see cref="Rock.Model.Attribute" /> item for the attribute.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="entityTypeId">The entity type id.</param>
        /// <param name="entityQualifierColumn">The entity qualifier column.</param>
        /// <param name="entityQualifierValue">The entity qualifier value.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        /// <remarks>
        /// If a rockContext value is included, this method will save any previous changes made to the context
        /// </remarks>
        private static bool UpdateAttribute(FieldAttribute property, int?entityTypeId, string entityQualifierColumn, string entityQualifierValue, RockContext rockContext = null)
        {
            bool updated = false;

            rockContext = rockContext ?? new RockContext();

            var attributeService          = new AttributeService(rockContext);
            var attributeQualifierService = new AttributeQualifierService(rockContext);
            var fieldTypeService          = new FieldTypeService(rockContext);
            var categoryService           = new CategoryService(rockContext);

            var propertyCategories = property.Category.SplitDelimitedValues(false).ToList();

            // Look for an existing attribute record based on the entity, entityQualifierColumn and entityQualifierValue
            Model.Attribute attribute = attributeService.Get(entityTypeId, entityQualifierColumn, entityQualifierValue, property.Key);
            if (attribute == null)
            {
                // If an existing attribute record doesn't exist, create a new one
                updated = true;

                attribute = new Model.Attribute();
                attribute.EntityTypeId = entityTypeId;
                attribute.EntityTypeQualifierColumn = entityQualifierColumn;
                attribute.EntityTypeQualifierValue  = entityQualifierValue;
                attribute.Key          = property.Key;
                attribute.IconCssClass = string.Empty;
                attribute.IsGridColumn = false;
            }
            else
            {
                // Check to see if the existing attribute record needs to be updated
                if (attribute.Name != property.Name ||
                    attribute.DefaultValue != property.DefaultValue ||
                    attribute.Description != property.Description ||
                    attribute.Order != property.Order ||
                    attribute.FieldType.Assembly != property.FieldTypeAssembly ||
                    attribute.FieldType.Class != property.FieldTypeClass ||
                    attribute.IsRequired != property.IsRequired)
                {
                    updated = true;
                }

                // Check category
                else if (attribute.Categories.Select(c => c.Name).Except(propertyCategories).Any() ||
                         propertyCategories.Except(attribute.Categories.Select(c => c.Name)).Any())
                {
                    updated = true;
                }

                // Check the qualifier values
                else if (attribute.AttributeQualifiers.Select(q => q.Key).Except(property.FieldConfigurationValues.Select(c => c.Key)).Any() ||
                         property.FieldConfigurationValues.Select(c => c.Key).Except(attribute.AttributeQualifiers.Select(q => q.Key)).Any())
                {
                    updated = true;
                }
                else
                {
                    foreach (var attributeQualifier in attribute.AttributeQualifiers)
                    {
                        if (!property.FieldConfigurationValues.ContainsKey(attributeQualifier.Key) ||
                            property.FieldConfigurationValues[attributeQualifier.Key].Value != attributeQualifier.Value)
                        {
                            updated = true;
                            break;
                        }
                    }
                }
            }

            if (updated)
            {
                // Update the attribute
                attribute.Name         = property.Name;
                attribute.Description  = property.Description;
                attribute.DefaultValue = property.DefaultValue;
                attribute.Order        = property.Order;
                attribute.IsRequired   = property.IsRequired;

                attribute.Categories.Clear();
                if (propertyCategories.Any())
                {
                    foreach (string propertyCategory in propertyCategories)
                    {
                        int attributeEntityTypeId = EntityTypeCache.Read(typeof(Rock.Model.Attribute)).Id;
                        var category = categoryService.Get(propertyCategory, attributeEntityTypeId, "EntityTypeId", entityTypeId.ToString()).FirstOrDefault();
                        if (category == null)
                        {
                            category              = new Category();
                            category.Name         = propertyCategory;
                            category.EntityTypeId = attributeEntityTypeId;
                            category.EntityTypeQualifierColumn = "EntityTypeId";
                            category.EntityTypeQualifierValue  = entityTypeId.ToString();
                            category.Order = 0;
                        }
                        attribute.Categories.Add(category);
                    }
                }

                foreach (var qualifier in attribute.AttributeQualifiers.ToList())
                {
                    attributeQualifierService.Delete(qualifier);
                }
                attribute.AttributeQualifiers.Clear();

                foreach (var configValue in property.FieldConfigurationValues)
                {
                    var qualifier = new Model.AttributeQualifier();
                    qualifier.Key   = configValue.Key;
                    qualifier.Value = configValue.Value.Value;
                    attribute.AttributeQualifiers.Add(qualifier);
                }

                // Try to set the field type by searching for an existing field type with the same assembly and class name
                if (attribute.FieldType == null || attribute.FieldType.Assembly != property.FieldTypeAssembly ||
                    attribute.FieldType.Class != property.FieldTypeClass)
                {
                    attribute.FieldType = fieldTypeService.Queryable().FirstOrDefault(f =>
                                                                                      f.Assembly == property.FieldTypeAssembly &&
                                                                                      f.Class == property.FieldTypeClass);
                }

                // If this is a new attribute, add it, otherwise remove the exiting one from the cache
                if (attribute.Id == 0)
                {
                    attributeService.Add(attribute);
                }
                else
                {
                    AttributeCache.Flush(attribute.Id);
                }

                rockContext.SaveChanges();

                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #29
0
        /// <summary>
        /// Handles the Click event of the btnSave control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void btnSave_Click(object sender, EventArgs e)
        {
            using (new UnitOfWorkScope())
            {
                BinaryFileType        binaryFileType;
                BinaryFileTypeService binaryFileTypeService = new BinaryFileTypeService();
                AttributeService      attributeService      = new AttributeService();

                int binaryFileTypeId = int.Parse(hfBinaryFileTypeId.Value);

                if (binaryFileTypeId == 0)
                {
                    binaryFileType = new BinaryFileType();
                    binaryFileTypeService.Add(binaryFileType, CurrentPersonId);
                }
                else
                {
                    binaryFileType = binaryFileTypeService.Get(binaryFileTypeId);
                }

                binaryFileType.Name            = tbName.Text;
                binaryFileType.Description     = tbDescription.Text;
                binaryFileType.IconCssClass    = tbIconCssClass.Text;
                binaryFileType.IconSmallFileId = imgIconSmall.ImageId;
                binaryFileType.IconLargeFileId = imgIconLarge.ImageId;

                if (!string.IsNullOrWhiteSpace(cpStorageType.SelectedValue))
                {
                    var entityTypeService = new EntityTypeService();
                    var storageEntityType = entityTypeService.Get(new Guid(cpStorageType.SelectedValue));

                    if (storageEntityType != null)
                    {
                        binaryFileType.StorageEntityTypeId = storageEntityType.Id;
                    }
                }

                if (!binaryFileType.IsValid)
                {
                    // Controls will render the error messages
                    return;
                }

                RockTransactionScope.WrapTransaction(() =>
                {
                    binaryFileTypeService.Save(binaryFileType, CurrentPersonId);

                    // get it back to make sure we have a good Id for it for the Attributes
                    binaryFileType = binaryFileTypeService.Get(binaryFileType.Guid);

                    /* Take care of Binary File Attributes */

                    // delete BinaryFileAttributes that are no longer configured in the UI
                    string qualifierValue       = binaryFileType.Id.ToString();
                    var BinaryFileAttributesQry = attributeService.GetByEntityTypeId(new BinaryFile().TypeId).AsQueryable()
                                                  .Where(a => a.EntityTypeQualifierColumn.Equals("BinaryFileTypeId", StringComparison.OrdinalIgnoreCase) &&
                                                         a.EntityTypeQualifierValue.Equals(qualifierValue));

                    var deletedBinaryFileAttributes = from attr in BinaryFileAttributesQry
                                                      where !(from d in BinaryFileAttributesState
                                                              select d.Guid).Contains(attr.Guid)
                                                      select attr;

                    deletedBinaryFileAttributes.ToList().ForEach(a =>
                    {
                        var attr = attributeService.Get(a.Guid);
                        Rock.Web.Cache.AttributeCache.Flush(attr.Id);
                        attributeService.Delete(attr, CurrentPersonId);
                        attributeService.Save(attr, CurrentPersonId);
                    });

                    // add/update the BinaryFileAttributes that are assigned in the UI
                    foreach (var attributeState in BinaryFileAttributesState)
                    {
                        // remove old qualifiers in case they changed
                        var qualifierService = new AttributeQualifierService();
                        foreach (var oldQualifier in qualifierService.GetByAttributeId(attributeState.Id).ToList())
                        {
                            qualifierService.Delete(oldQualifier, CurrentPersonId);
                            qualifierService.Save(oldQualifier, CurrentPersonId);
                        }

                        Attribute attribute = BinaryFileAttributesQry.FirstOrDefault(a => a.Guid.Equals(attributeState.Guid));
                        if (attribute == null)
                        {
                            attribute = attributeState.Clone() as Rock.Model.Attribute;
                            attributeService.Add(attribute, CurrentPersonId);
                        }
                        else
                        {
                            attributeState.Id = attribute.Id;
                            attribute.FromDictionary(attributeState.ToDictionary());

                            foreach (var qualifier in attributeState.AttributeQualifiers)
                            {
                                attribute.AttributeQualifiers.Add(qualifier.Clone() as AttributeQualifier);
                            }
                        }

                        attribute.EntityTypeQualifierColumn = "BinaryFileTypeId";
                        attribute.EntityTypeQualifierValue  = binaryFileType.Id.ToString();
                        attribute.EntityTypeId = Rock.Web.Cache.EntityTypeCache.Read(typeof(BinaryFile)).Id;
                        Rock.Web.Cache.AttributeCache.Flush(attribute.Id);
                        attributeService.Save(attribute, CurrentPersonId);
                    }
                });
            }

            NavigateToParentPage();
        }
        /// <summary>
        /// Adds a new form field or updates an existing form field in the form.
        /// This will also handle creating the attribute if a new form field must
        /// be created.
        /// </summary>
        /// <param name="actionForm">The <see cref="WorkflowActionForm"/> being updated.</param>
        /// <param name="workflowType">The <see cref="WorkflowType"/> being updated.</param>
        /// <param name="attributeService">The database service that provides access to attributes.</param>
        /// <param name="formAttributeService">The database service that provides access to form attributes.</param>
        /// <param name="formSection">The <see cref="WorkflowActionFormSection"/> being updated.</param>
        /// <param name="field">The field view model that contains the source information.</param>
        /// <param name="nextAttributeOrder">The next attribute Order value to use when adding a new attribute.</param>
        /// <returns>The <see cref="WorkflowActionFormAttribute"/> that was either created or updated.</returns>
        private static WorkflowActionFormAttribute AddOrUpdateFormField(WorkflowActionForm actionForm, WorkflowType workflowType, AttributeService attributeService, WorkflowActionFormAttributeService formAttributeService, WorkflowActionFormSection formSection, FormFieldViewModel field, List <FormFieldViewModel> formFields, ref int nextAttributeOrder)
        {
            var fieldType = FieldTypeCache.Get(field.FieldTypeGuid);

            // If the field type or its C# component could not be found then
            // we abort with a hard error. We need it to convert data.
            if (fieldType == null || fieldType.Field == null)
            {
                throw new Exception($"Field type '{field.FieldTypeGuid}' not found.");
            }

            var formField = actionForm.FormAttributes.FirstOrDefault(a => a.Attribute.Guid == field.Guid);

            // If the form field was not found then create a new attribute and
            // new form field.
            if (formField == null)
            {
                var attribute = new Rock.Model.Attribute
                {
                    Guid         = field.Guid,
                    EntityTypeId = EntityTypeCache.Get <Rock.Model.Workflow>().Id,
                    EntityTypeQualifierColumn = nameof(Rock.Model.Workflow.WorkflowTypeId),
                    EntityTypeQualifierValue  = workflowType.Id.ToString(),
                    FieldTypeId = fieldType.Id,
                    IsSystem    = true,
                    Order       = nextAttributeOrder++
                };

                formField = new WorkflowActionFormAttribute
                {
                    Attribute = attribute
                };

                actionForm.FormAttributes.Add(formField);
                attributeService.Add(attribute);
                formAttributeService.Add(formField);
            }

            // Convert the attribute configuration into values that can be stored
            // in the database.
            var configurationValues = fieldType.Field.GetPrivateConfigurationValues(field.ConfigurationValues);

            // Update all the standard properties.
            formField.ActionFormSection      = formSection;
            formField.Attribute.DefaultValue = fieldType.Field.GetPrivateEditValue(field.DefaultValue, configurationValues);
            formField.Attribute.Description  = field.Description;
            formField.Attribute.IsRequired   = field.IsRequired;
            formField.IsRequired             = field.IsRequired;
            formField.Attribute.IsGridColumn = field.IsShowOnGrid;
            formField.Attribute.Key          = field.Key;
            formField.Attribute.Name         = field.Name;
            formField.ColumnSize             = field.Size;
            formField.IsVisible            = true;
            formField.HideLabel            = field.IsHideLabel;
            formField.FieldVisibilityRules = field.VisibilityRule?.FromViewModel(formFields);

            // Add or update the attribute qualifiers. Do not delete any old ones.
            foreach (var kvp in configurationValues)
            {
                var qualifier = formField.Attribute.AttributeQualifiers.FirstOrDefault(q => q.Key == kvp.Key);

                if (qualifier == null)
                {
                    formField.Attribute.AttributeQualifiers.Add(new AttributeQualifier
                    {
                        IsSystem = false,
                        Key      = kvp.Key,
                        Value    = kvp.Value ?? string.Empty
                    });
                }
                else
                {
                    qualifier.Value = kvp.Value ?? string.Empty;
                }
            }

            return(formField);
        }