Ejemplo n.º 1
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)
        {
            Metric metric;

            var                   rockContext           = new RockContext();
            MetricService         metricService         = new MetricService(rockContext);
            MetricCategoryService metricCategoryService = new MetricCategoryService(rockContext);
            MetricValueService    metricValueService    = new MetricValueService(rockContext);
            bool                  deleteValuesOnSave    = sender == btnDeleteValuesAndSave;

            int metricId = hfMetricId.Value.AsInteger();

            if (metricId == 0)
            {
                metric = new Metric();
            }
            else
            {
                metric = metricService.Get(metricId);
            }

            metric.Title             = tbTitle.Text;
            metric.Subtitle          = tbSubtitle.Text;
            metric.Description       = tbDescription.Text;
            metric.IconCssClass      = tbIconCssClass.Text;
            metric.SourceValueTypeId = ddlSourceType.SelectedValueAsId();
            metric.XAxisLabel        = tbXAxisLabel.Text;
            metric.YAxisLabel        = tbYAxisLabel.Text;
            metric.IsCumulative      = cbIsCumulative.Checked;

            var origEntityType = metric.EntityTypeId.HasValue ? EntityTypeCache.Read(metric.EntityTypeId.Value) : null;
            var newEntityType  = etpEntityType.SelectedEntityTypeId.HasValue ? EntityTypeCache.Read(etpEntityType.SelectedEntityTypeId.Value) : null;

            if (origEntityType != null && !deleteValuesOnSave)
            {
                if (newEntityType == null || newEntityType.Id != origEntityType.Id)
                {
                    // if the EntityTypeId of this metric has changed to NULL or to another EntityType, warn about the EntityId values being wrong
                    bool hasEntityValues = metricValueService.Queryable().Any(a => a.MetricId == metric.Id && a.EntityId.HasValue);

                    if (hasEntityValues)
                    {
                        nbEntityTypeChanged.Text = string.Format(
                            "Warning: You can't change the series partition to {0} when there are values associated with {1}. Do you want to delete existing values?",
                            newEntityType != null ? newEntityType.FriendlyName : "<none>",
                            origEntityType.FriendlyName);
                        mdEntityTypeChanged.Show();
                        nbEntityTypeChanged.Visible = true;
                        return;
                    }
                }
            }

            metric.EntityTypeId = etpEntityType.SelectedEntityTypeId;

            int sourceTypeDataView = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_DATAVIEW.AsGuid()).Id;
            int sourceTypeSQL      = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_SQL.AsGuid()).Id;

            var personService        = new PersonService(rockContext);
            var metricChampionPerson = personService.Get(ppMetricChampionPerson.SelectedValue ?? 0);

            metric.MetricChampionPersonAliasId = metricChampionPerson != null ? metricChampionPerson.PrimaryAliasId : null;
            var adminPerson = personService.Get(ppAdminPerson.SelectedValue ?? 0);

            metric.AdminPersonAliasId = adminPerson != null ? adminPerson.PrimaryAliasId : null;

            if (metric.SourceValueTypeId == sourceTypeSQL)
            {
                metric.SourceSql = ceSourceSql.Text;
            }
            else
            {
                metric.SourceSql = string.Empty;
            }

            if (metric.SourceValueTypeId == sourceTypeDataView)
            {
                metric.DataViewId = ddlDataView.SelectedValueAsId();
            }
            else
            {
                metric.DataViewId = null;
            }

            var scheduleSelectionType = rblScheduleSelect.SelectedValueAsEnum <ScheduleSelectionType>();

            if (scheduleSelectionType == ScheduleSelectionType.NamedSchedule)
            {
                metric.ScheduleId = ddlSchedule.SelectedValueAsId();
            }
            else
            {
                metric.ScheduleId = hfUniqueScheduleId.ValueAsInt();
            }

            if (!Page.IsValid)
            {
                return;
            }

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

            if (!cpMetricCategories.SelectedValuesAsInt().Any())
            {
                cpMetricCategories.ShowErrorMessage("Must select at least one category");
                return;
            }

            // do a WrapTransaction since we are doing multiple SaveChanges()
            rockContext.WrapTransaction(() =>
            {
                var scheduleService          = new ScheduleService(rockContext);
                var schedule                 = scheduleService.Get(metric.ScheduleId ?? 0);
                int metricScheduleCategoryId = new CategoryService(rockContext).Get(Rock.SystemGuid.Category.SCHEDULE_METRICS.AsGuid()).Id;
                if (schedule == null)
                {
                    schedule = new Schedule();

                    // make it an "Unnamed" metrics schedule
                    schedule.Name       = string.Empty;
                    schedule.CategoryId = metricScheduleCategoryId;
                }

                // if the schedule was a unique schedule (configured in the Metric UI, set the schedule's ical content to the schedule builder UI's value
                if (scheduleSelectionType == ScheduleSelectionType.Unique)
                {
                    schedule.iCalendarContent = sbSchedule.iCalendarContent;
                }

                if (!schedule.HasSchedule() && scheduleSelectionType == ScheduleSelectionType.Unique)
                {
                    // don't save as a unique schedule if the schedule doesn't do anything
                    schedule = null;
                }
                else
                {
                    if (schedule.Id == 0)
                    {
                        scheduleService.Add(schedule);

                        // save to make sure we have a scheduleId
                        rockContext.SaveChanges();
                    }
                }

                if (schedule != null)
                {
                    metric.ScheduleId = schedule.Id;
                }
                else
                {
                    metric.ScheduleId = null;
                }

                if (metric.Id == 0)
                {
                    metricService.Add(metric);

                    // save to make sure we have a metricId
                    rockContext.SaveChanges();
                }

                // update MetricCategories for Metric
                metric.MetricCategories = metric.MetricCategories ?? new List <MetricCategory>();
                var selectedCategoryIds = cpMetricCategories.SelectedValuesAsInt();

                // delete any categories that were removed
                foreach (var metricCategory in metric.MetricCategories.ToList())
                {
                    if (!selectedCategoryIds.Contains(metricCategory.CategoryId))
                    {
                        metricCategoryService.Delete(metricCategory);
                    }
                }

                // add any categories that were added
                foreach (int categoryId in selectedCategoryIds)
                {
                    if (!metric.MetricCategories.Any(a => a.CategoryId == categoryId))
                    {
                        metricCategoryService.Add(new MetricCategory {
                            CategoryId = categoryId, MetricId = metric.Id
                        });
                    }
                }

                rockContext.SaveChanges();

                // delete MetricValues associated with the old entityType if they confirmed the EntityType change
                if (deleteValuesOnSave)
                {
                    metricValueService.DeleteRange(metricValueService.Queryable().Where(a => a.MetricId == metric.Id && a.EntityId.HasValue));

                    // since there could be 1000s of values that got deleted, do a SaveChanges that skips PrePostProcessing
                    rockContext.SaveChanges(true);
                }

                // delete any orphaned Unnamed metric schedules
                var metricIdSchedulesQry = metricService.Queryable().Select(a => a.ScheduleId);
                int?metricScheduleId     = schedule != null ? schedule.Id : (int?)null;
                var orphanedSchedules    = scheduleService.Queryable()
                                           .Where(a => a.CategoryId == metricScheduleCategoryId && a.Name == string.Empty && a.Id != (metricScheduleId ?? 0))
                                           .Where(s => !metricIdSchedulesQry.Any(m => m == s.Id));
                foreach (var item in orphanedSchedules)
                {
                    scheduleService.Delete(item);
                }

                if (orphanedSchedules.Any())
                {
                    rockContext.SaveChanges();
                }
            });

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

            qryParams["MetricId"] = metric.Id.ToString();
            if (hfMetricCategoryId.ValueAsInt() == 0)
            {
                int?parentCategoryId = PageParameter("ParentCategoryId").AsIntegerOrNull();
                int?metricCategoryId = new MetricCategoryService(new RockContext()).Queryable().Where(a => a.MetricId == metric.Id && a.CategoryId == parentCategoryId).Select(a => a.Id).FirstOrDefault();
                hfMetricCategoryId.Value = metricCategoryId.ToString();
            }

            qryParams["MetricCategoryId"] = hfMetricCategoryId.Value;
            qryParams["ExpandedIds"]      = PageParameter("ExpandedIds");

            NavigateToPage(RockPage.Guid, qryParams);
        }