/// <summary>
        /// Shows the detail.
        /// </summary>
        /// <param name="benevolenceTypeId">The benevolence type identifier.</param>
        private void ShowDetail(int benevolenceTypeId)
        {
            pnlDetails.Visible = true;
            var             rockContext     = new RockContext();
            BenevolenceType benevolenceType = null;

            if (benevolenceTypeId != 0)
            {
                benevolenceType   = new BenevolenceTypeService(new RockContext()).Get(benevolenceTypeIdPageParameter);
                lActionTitle.Text = ActionTitle.Edit(BenevolenceType.FriendlyTypeName).FormatAsHtmlTitle();
                pdAuditDetails.SetEntity(benevolenceType, ResolveRockUrl("~"));
            }

            if (benevolenceType == null)
            {
                benevolenceType = new BenevolenceType
                {
                    Id                   = 0,
                    IsActive             = true,
                    ShowFinancialResults = true
                };

                lActionTitle.Text = ActionTitle.Add(BenevolenceType.FriendlyTypeName).FormatAsHtmlTitle();

                // hide the panel drawer that show created and last modified dates
                pdAuditDetails.Visible = false;
            }

            tbName.Text                    = benevolenceType.Name;
            tbDescription.Text             = benevolenceType.Description;
            ceLavaTemplate.Text            = benevolenceType.RequestLavaTemplate;
            cbShowFinancialResults.Checked = benevolenceType.ShowFinancialResults;
            cbIsActive.Checked             = benevolenceType.IsActive;

            // render UI based on Authorized and IsSystem
            bool readOnly = false;

            nbEditModeMessage.Text = string.Empty;

            if (!IsUserAuthorized(Authorization.EDIT))
            {
                readOnly = true;
                nbEditModeMessage.Text = EditModeMessage.ReadOnlyEditActionNotAllowed(BenevolenceType.FriendlyTypeName);
            }

            if (readOnly)
            {
                lActionTitle.Text = ActionTitle.View(BenevolenceType.FriendlyTypeName);
                btnCancel.Text    = "Close";
            }

            tbName.ReadOnly         = readOnly;
            tbDescription.ReadOnly  = readOnly;
            ceLavaTemplate.ReadOnly = readOnly;
            cbIsActive.Enabled      = !readOnly;

            SetHighlightLabelVisibility(benevolenceType, readOnly);

            btnSave.Visible = !readOnly;
        }
        /// <summary>
        /// Handles the Delete event of the gBenevolenceType control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param>
        protected void gBenevolenceType_Delete(object sender, RowEventArgs e)
        {
            using (var rockContext = new RockContext())
            {
                rockContext.WrapTransaction(action: () =>
                {
                    var benevolenceWorkflowService = new BenevolenceWorkflowService(rockContext);
                    var benevolenceTypeService     = new BenevolenceTypeService(rockContext);
                    var authService = new AuthService(rockContext);
                    BenevolenceType benevolenceType = benevolenceTypeService.Get(e.RowKeyId);

                    if (benevolenceType != null)
                    {
                        // Do not allow deletions if the person is not authorized
                        if (!benevolenceType.IsAuthorized(Authorization.ADMINISTRATE, this.CurrentPerson))
                        {
                            mdGridWarning.Show("You are not authorized to delete this Benevolence type.", ModalAlertType.Information);
                            return;
                        }

                        // var benevolenceRequests = new Service<BenevolenceRequest>( rockContext ).Queryable().All( a => a.BenevolenceTypeId == BenevolenceType.Id );
                        var benevolenceRequests       = benevolenceType.BenevolenceRequests.ToList();
                        var benevolenceRequestService = new BenevolenceRequestService(rockContext);

                        string errorMessageBenevolenceRequest = string.Empty;

                        foreach (var benvolenceRequest in benevolenceRequests)
                        {
                            if (!benevolenceRequestService.CanDelete(benvolenceRequest, out errorMessageBenevolenceRequest))
                            {
                                mdGridWarning.Show(errorMessageBenevolenceRequest, ModalAlertType.Information);
                                return;
                            }

                            benevolenceRequestService.Delete(benvolenceRequest);
                        }

                        // Save deleting the benevolence requests for the benevolence type id
                        rockContext.SaveChanges();

                        string errorMessageBenevolenceType;
                        if (!benevolenceTypeService.CanDelete(benevolenceType, out errorMessageBenevolenceType))
                        {
                            mdGridWarning.Show(errorMessageBenevolenceType, ModalAlertType.Information);
                            return;
                        }

                        benevolenceTypeService.Delete(benevolenceType);
                        rockContext.SaveChanges();

                        // ToDo: benevolenceWorkflowService.RemoveCachedTriggers();
                    }
                });
            }

            BindGrid();
        }
        /// <summary>
        /// Gets the Benevolence types.
        /// </summary>
        /// <returns></returns>
        private List <BenevolenceType> GetBenevolenceTypes(RockContext rockContext)
        {
            var allBenevolenceTypes = new BenevolenceTypeService(rockContext).Queryable()
                                      .OrderBy(g => g.Name)
                                      .ToList();

            var authorizedBenevolenceTypes = new List <BenevolenceType>();

            foreach (var benevolenceType in allBenevolenceTypes)
            {
                if (UserCanEdit || benevolenceType.IsAuthorized(Authorization.VIEW, CurrentPerson))
                {
                    authorizedBenevolenceTypes.Add(benevolenceType);
                }
            }

            return(authorizedBenevolenceTypes);
        }
        /// <summary>
        /// Initializes the workflow grid.
        /// </summary>
        /// <param name="benevolenceTypeId">The benevolence type identifier.</param>
        private void InitializeWorkflowGrid(int benevolenceTypeId)
        {
            BenevolenceType benevolenceType = null;
            var             rockContext     = new RockContext();

            if (!benevolenceTypeId.Equals(0))
            {
                benevolenceType = new BenevolenceTypeService(rockContext).Get(benevolenceTypeId);
            }

            if (benevolenceType == null)
            {
                benevolenceType = new BenevolenceType {
                    Id = 0
                };
            }

            WorkflowStateModel = new List <BenevolenceWorkflow>();
            foreach (var benevolenceWorkflow in benevolenceType.BenevolenceWorkflows)
            {
                var modelState = new BenevolenceWorkflow
                {
                    Id   = benevolenceWorkflow.Id,
                    Guid = benevolenceWorkflow.Guid,
                    BenevolenceTypeId = benevolenceTypeId,
                    QualifierValue    = benevolenceWorkflow.QualifierValue,
                    TriggerType       = benevolenceWorkflow.TriggerType,
                    WorkflowTypeId    = benevolenceWorkflow.WorkflowTypeId,
                    WorkflowType      = benevolenceWorkflow.WorkflowType
                };

                WorkflowStateModel.Add(modelState);
            }

            gBenevolenceTypeWorkflows.DataKeyNames      = new string[] { "Guid" };
            gBenevolenceTypeWorkflows.Actions.ShowAdd   = true;
            gBenevolenceTypeWorkflows.Actions.AddClick += gBenevolenceTypeWorkflows_Add;
            gBenevolenceTypeWorkflows.GridRebind       += gBenevolenceTypeWorkflows_GridRebind;
        }
        /// <summary>
        /// Handles the filter display for each saved user value
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The e.</param>
        protected void rFilter_DisplayFilterValue(object sender, GridFilter.DisplayFilterValueArgs e)
        {
            switch (e.Key)
            {
            case "Start Date":
            case "End Date":
                var dateTime = e.Value.AsDateTime();
                if (dateTime.HasValue)
                {
                    e.Value = dateTime.Value.ToShortDateString();
                }
                else
                {
                    e.Value = null;
                }

                return;

            case "First Name":
                return;

            case "Last Name":
                return;

            case "Campus":
            {
                int?campusId = e.Value.AsIntegerOrNull();
                if (campusId.HasValue)
                {
                    e.Value = CampusCache.Get(campusId.Value).Name;
                }

                return;
            }

            case "Government ID":
                return;

            case "Case Worker":
                int?personAliasId = e.Value.AsIntegerOrNull();
                if (personAliasId.HasValue)
                {
                    var personAlias = new PersonAliasService(new RockContext()).Get(personAliasId.Value);
                    if (personAlias != null)
                    {
                        e.Value = personAlias.Person.FullName;
                    }
                }

                return;

            case "Result":
            case "Status":
                var definedValueId = e.Value.AsIntegerOrNull();
                if (definedValueId.HasValue)
                {
                    var definedValue = DefinedValueCache.Get(definedValueId.Value);
                    if (definedValue != null)
                    {
                        e.Value = definedValue.Value;
                    }
                }

                return;

            case "Benevolence Types":
                var benevolencTypeValueIds = e.Value.SplitDelimitedValues().Select(v => v.ToIntSafe())?.ToList();
                if (benevolencTypeValueIds?.Count() > 0)
                {
                    var benevolenceTypes = new BenevolenceTypeService(new RockContext()).GetByIds(benevolencTypeValueIds);
                    if (benevolenceTypes != null)
                    {
                        e.Value = benevolenceTypes.Select(v => v.Name).ToList().AsDelimited(", ");
                    }
                }

                return;

            default:
                e.Value = string.Empty;
                return;
            }
        }
        /// <summary>
        /// Updates the trigger qualifiers.
        /// </summary>
        private void UpdateTriggerQualifiers()
        {
            RockContext rockContext = new RockContext();

            string[] qualifierValues = new string[2];

            var  workflowTypeStateObj           = WorkflowStateModel.FirstOrDefault(l => l.Guid.Equals(hfWorkflowGuid.Value.AsGuid()));
            var  benevolenceWorkflowTriggerType = ddlTriggerType.SelectedValueAsEnum <BenevolenceWorkflowTriggerType>();
            int  benevolenceTypeId           = PageParameter("BenevolenceTypeId").AsInteger();
            var  benevolenceType             = new BenevolenceTypeService(rockContext).Get(benevolenceTypeId);
            bool isPrimaryQualifierVisible   = false;
            bool isSecondaryQualifierVisible = false;

            switch (benevolenceWorkflowTriggerType)
            {
            case BenevolenceWorkflowTriggerType.RequestStarted:
            case BenevolenceWorkflowTriggerType.CaseworkerAssigned:
            case BenevolenceWorkflowTriggerType.Manual:
            {
                ddlPrimaryQualifier.Visible = isPrimaryQualifierVisible = false;
                ddlPrimaryQualifier.Items.Clear();
                ddlSecondaryQualifier.Visible = isSecondaryQualifierVisible = false;
                ddlSecondaryQualifier.Items.Clear();
                break;
            }

            case BenevolenceWorkflowTriggerType.StatusChanged:
            {
                var benevolenceStatusTypes = DefinedTypeCache.Get(Rock.SystemGuid.DefinedType.BENEVOLENCE_REQUEST_STATUS.AsGuid()).DefinedValues;

                ddlPrimaryQualifier.Label   = "From";
                ddlPrimaryQualifier.Visible = isPrimaryQualifierVisible = true;
                ddlPrimaryQualifier.Items.Clear();
                ddlPrimaryQualifier.Items.Add(new ListItem(string.Empty, string.Empty));
                foreach (var status in benevolenceStatusTypes)
                {
                    ddlPrimaryQualifier.Items.Add(new ListItem(status.Value, status.Id.ToString().ToUpper()));
                }

                ddlSecondaryQualifier.Label   = "To";
                ddlSecondaryQualifier.Visible = isSecondaryQualifierVisible = true;
                ddlSecondaryQualifier.Items.Clear();
                ddlSecondaryQualifier.Items.Add(new ListItem(string.Empty, string.Empty));
                foreach (var status in benevolenceStatusTypes)
                {
                    ddlSecondaryQualifier.Items.Add(new ListItem(status.Value, status.Id.ToString().ToUpper()));
                }

                break;
            }
            }

            if (workflowTypeStateObj != null)
            {
                if (workflowTypeStateObj.TriggerType == ddlTriggerType.SelectedValueAsEnum <BenevolenceWorkflowTriggerType>())
                {
                    qualifierValues = workflowTypeStateObj.QualifierValue.SplitDelimitedValues("|");

                    /*
                     *  Visible property of ddlPrimaryQualifier and ddlSecondaryQualifier don't reflect the new assigned value till the request complete.
                     *  That is the reason isPrimaryQualifierVisible & isSecondaryQualifierVisible are introduced to potentially fix the issue raised in #2029
                     *  https://github.com/SparkDevNetwork/Rock/issues/2029
                     */
                    if (isPrimaryQualifierVisible && qualifierValues.Length > 1)
                    {
                        ddlPrimaryQualifier.SelectedValue = qualifierValues[1];
                    }

                    if (isSecondaryQualifierVisible && qualifierValues.Length > 2)
                    {
                        ddlSecondaryQualifier.SelectedValue = qualifierValues[2];
                    }
                }
            }
        }
        /// <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)
        {
            Page.Validate();
            BenevolenceType benevolenceType = null;

            using (var rockContext = new RockContext())
            {
                var benevolenceService         = new BenevolenceTypeService(rockContext);
                var benevolenceWorkflowService = new BenevolenceWorkflowService(rockContext);

                var benevolenceTypeId = benevolenceTypeIdPageParameter;

                if (benevolenceTypeId != 0)
                {
                    benevolenceType = benevolenceService.Get(benevolenceTypeId);
                }

                if (benevolenceType == null)
                {
                    // Check for existing
                    var existingBenevolence = benevolenceService.Queryable()
                                              .Where(d => d.Name == tbName.Text)
                                              .FirstOrDefault();

                    if (existingBenevolence != null)
                    {
                        nbDuplicateDevice.Text    = $"A benevolence type already exists with the name '{existingBenevolence.Name}'. Please use a different benevolence type name.";
                        nbDuplicateDevice.Visible = true;
                    }
                    else
                    {
                        benevolenceType = new BenevolenceType();
                        benevolenceService.Add(benevolenceType);
                    }
                }

                if (benevolenceType != null)
                {
                    benevolenceType.Name                 = tbName.Text;
                    benevolenceType.Description          = tbDescription.Text;
                    benevolenceType.RequestLavaTemplate  = ceLavaTemplate.Text;
                    benevolenceType.ShowFinancialResults = cbShowFinancialResults.Checked;
                    benevolenceType.IsActive             = cbIsActive.Checked;

                    // remove any workflows that were removed in the UI
                    var uiWorkflows = WorkflowStateModel.Select(l => l.Guid);

                    foreach (var benevolenceWorkflow in benevolenceType.BenevolenceWorkflows.Where(l => !uiWorkflows.Contains(l.Guid)).ToList())
                    {
                        benevolenceType.BenevolenceWorkflows.Remove(benevolenceWorkflow);
                        benevolenceWorkflowService.Delete(benevolenceWorkflow);
                    }

                    // Add or Update workflows from the UI
                    foreach (var workflowStateModel in WorkflowStateModel)
                    {
                        BenevolenceWorkflow benevolenceWorkflow = benevolenceType.BenevolenceWorkflows
                                                                  .Where(b => !workflowStateModel.Guid.Equals(Guid.Empty) && b.Guid == workflowStateModel.Guid).FirstOrDefault();

                        if (benevolenceWorkflow == null)
                        {
                            benevolenceWorkflow = new BenevolenceWorkflow
                            {
                                BenevolenceTypeId = benevolenceTypeId
                            };
                            benevolenceType.BenevolenceWorkflows.Add(benevolenceWorkflow);
                        }

                        // Set the properties on the state model
                        benevolenceWorkflow.CopyPropertiesFrom(workflowStateModel);
                    }

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

                    rockContext.WrapTransaction(() =>
                    {
                        rockContext.SaveChanges();
                    });

                    BenevolenceWorkflowService.RemoveCachedTriggers();
                    NavigateToParentPage();
                }
            }
        }