/// <summary> /// Handles the Click event of the btnEdit 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 btnEdit_Click(object sender, EventArgs e) { MetricService metricService = new MetricService(new RockContext()); Metric metric = metricService.Get(hfMetricId.Value.AsInteger()); ShowEditDetails(metric); }
/// <summary> /// Handles the Click event of the lbEdit 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 lbEdit_Click(object sender, EventArgs e) { var metricService = new MetricService(); var metric = metricService.Get(hfMetricId.ValueAsInt()); ShowEdit(metric); }
/// <summary> /// Handles the Click event of the btnCancel 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 btnCancel_Click(object sender, EventArgs e) { if (hfMetricId.Value.Equals("0")) { int?parentCategoryId = PageParameter("ParentCategoryId").AsIntegerOrNull(); if (parentCategoryId.HasValue) { // Cancelling on Add, and we know the parentCategoryId, so we are probably in treeview mode, so navigate to the current page var qryParams = new Dictionary <string, string>(); qryParams["CategoryId"] = parentCategoryId.ToString(); NavigateToPage(RockPage.Guid, qryParams); } else { // Cancelling on Add. Return to Grid NavigateToParentPage(); } } else { // Cancelling on Edit. Return to Details MetricService metricService = new MetricService(new RockContext()); Metric metric = metricService.Get(hfMetricId.Value.AsInteger()); ShowReadonlyDetails(metric); } }
/// <summary> /// Returns the field's current value(s) /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="value">Information about the value</param> /// <param name="configurationValues">The configuration values.</param> /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param> /// <returns></returns> public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed) { string formattedValue = string.Empty; if (!string.IsNullOrWhiteSpace(value)) { var valueParts = value.Split('|'); if (valueParts.Length > 0) { var service = new MetricService(new RockContext()); var metric = service.Get(new Guid(valueParts[0])); if (metric != null) { formattedValue = metric.Title; var entityType = EntityTypeCache.Read(metric.EntityTypeId ?? 0); if (entityType != null && entityType.SingleValueFieldType != null) { if (valueParts.Length > 1) { formattedValue = string.Format("{0} - EntityId:{1}", metric.Title, valueParts[1].AsIntegerOrNull()); } } } } } return(base.FormatValue(parentControl, formattedValue, null, condensed)); }
/// <summary> /// Handles the Delete event of the gMetrics 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 gMetrics_Delete(object sender, RowEventArgs e) { var metricService = new MetricService(); Metric metric = metricService.Get((int)e.RowKeyValue); if (metric != null) { metricService.Delete(metric, CurrentPersonId); metricService.Save(metric, CurrentPersonId); } BindGrid(); }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e) { using (new Rock.Data.UnitOfWorkScope()) { int metricId = hfMetricId.ValueAsInt(); var metricService = new MetricService(); Metric metric = null; if (metricId == 0) { metric = new Metric(); metric.IsSystem = false; metricService.Add(metric, CurrentPersonId); } else { metric = metricService.Get(metricId); } metric.Category = tbCategory.Text; metric.Title = tbTitle.Text; metric.Subtitle = tbSubtitle.Text; metric.Description = tbDescription.Text; metric.MinValue = tbMinValue.Text.AsType <int?>(); metric.MaxValue = tbMaxValue.Text.AsType <int?>(); metric.Type = cbType.Checked; metric.CollectionFrequencyValueId = Int32.Parse(ddlCollectionFrequency.SelectedValue); metric.Source = tbSource.Text; metric.SourceSQL = tbSourceSQL.Text; if (!metric.IsValid) { // Controls will render the error messages return; } metricService.Save(metric, CurrentPersonId); hfMetricId.SetValue(metric.Id); } var savedMetric = new MetricService().Get(hfMetricId.ValueAsInt()); ShowReadOnly(savedMetric); }
/// <summary> /// Handles the Click event of the btnDelete 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 btnDelete_Click(object sender, EventArgs e) { var rockContext = new RockContext(); MetricService metricService = new MetricService(rockContext); Metric metric = metricService.Get(hfMetricId.Value.AsInteger()); // intentionally get metricCategory with new RockContext() so we don't confuse SaveChanges() int?parentCategoryId = null; var metricCategory = new MetricCategoryService(new RockContext()).Get(hfMetricCategoryId.ValueAsInt()); if (metricCategory != null) { parentCategoryId = metricCategory.CategoryId; } if (metric != null) { string errorMessage; if (!metricService.CanDelete(metric, out errorMessage)) { mdDeleteWarning.Show(errorMessage, ModalAlertType.Information); return; } metricService.Delete(metric); rockContext.SaveChanges(); } var qryParams = new Dictionary <string, string>(); if (parentCategoryId != null) { qryParams["CategoryId"] = parentCategoryId.ToString(); } NavigateToPage(RockPage.Guid, qryParams); }
/// <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); }
/// <summary> /// Handles the Click event of the lbSave 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 lbSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); rockContext.WrapTransaction(() => { if (contextEntity is Person) { var personService = new PersonService(rockContext); var changes = new History.HistoryChangeList(); var _person = personService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _person.ForeignKey, tbForeignKey.Text); _person.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _person.ForeignGuid.ToString(), tbForeignGuid.Text); _person.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _person.ForeignId.ToString(), tbForeignId.Text); _person.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), _person.Id, changes); } } } else if (contextEntity is FinancialAccount) { var accountService = new FinancialAccountService(rockContext); var _account = accountService.Get(contextEntity.Id); _account.ForeignKey = tbForeignKey.Text; _account.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _account.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is FinancialBatch) { var batchService = new FinancialBatchService(rockContext); var changes = new History.HistoryChangeList(); var _batch = batchService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _batch.ForeignKey, tbForeignKey.Text); _batch.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _batch.ForeignGuid.ToString(), tbForeignGuid.Text); _batch.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _batch.ForeignId.ToString(), tbForeignId.Text); _batch.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(FinancialBatch), Rock.SystemGuid.Category.HISTORY_FINANCIAL_BATCH.AsGuid(), _batch.Id, changes); } } } else if (contextEntity is FinancialPledge) { var pledgeService = new FinancialPledgeService(rockContext); var _pledge = pledgeService.Get(contextEntity.Id); _pledge.ForeignKey = tbForeignKey.Text; _pledge.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _pledge.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is FinancialTransaction) { var transactionService = new FinancialTransactionService(rockContext); var changes = new History.HistoryChangeList(); var _transaction = transactionService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _transaction.ForeignKey, tbForeignKey.Text); _transaction.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _transaction.ForeignGuid.ToString(), tbForeignGuid.Text); _transaction.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _transaction.ForeignId.ToString(), tbForeignId.Text); _transaction.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(FinancialTransaction), Rock.SystemGuid.Category.HISTORY_FINANCIAL_TRANSACTION.AsGuid(), _transaction.Id, changes); } } } else if (contextEntity is FinancialScheduledTransaction) { var transactionScheduledService = new FinancialScheduledTransactionService(rockContext); var _scheduledTransaction = transactionScheduledService.Get(contextEntity.Id); _scheduledTransaction.ForeignKey = tbForeignKey.Text; _scheduledTransaction.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _scheduledTransaction.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is Group) { var groupService = new GroupService(rockContext); var _group = groupService.Get(contextEntity.Id); _group.ForeignKey = tbForeignKey.Text; _group.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _group.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is GroupMember) { var groupMemberService = new GroupMemberService(rockContext); var changes = new History.HistoryChangeList(); var _groupMember = groupMemberService.Get(contextEntity.Id); History.EvaluateChange(changes, "Foreign Key", _groupMember.ForeignKey, tbForeignKey.Text); _groupMember.ForeignKey = tbForeignKey.Text; History.EvaluateChange(changes, "Foreign Guid", _groupMember.ForeignGuid.ToString(), tbForeignGuid.Text); _groupMember.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); History.EvaluateChange(changes, "Foreign Id", _groupMember.ForeignId.ToString(), tbForeignId.Text); _groupMember.ForeignId = tbForeignId.Text.AsType <int?>(); if (rockContext.SaveChanges() > 0) { if (changes.Any()) { HistoryService.SaveChanges( rockContext, typeof(GroupMember), Rock.SystemGuid.Category.HISTORY_PERSON_GROUP_MEMBERSHIP.AsGuid(), _groupMember.Id, changes); } } } else if (contextEntity is Metric) { var metricService = new MetricService(rockContext); var _metric = metricService.Get(contextEntity.Id); _metric.ForeignKey = tbForeignKey.Text; _metric.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _metric.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is Location) { var locationService = new LocationService(rockContext); var _location = locationService.Get(contextEntity.Id); _location.ForeignKey = tbForeignKey.Text; _location.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _location.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is PrayerRequest) { var prayerRequestService = new PrayerRequestService(rockContext); var _request = prayerRequestService.Get(contextEntity.Id); _request.ForeignKey = tbForeignKey.Text; _request.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _request.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is ContentChannel) { var contentChannelService = new ContentChannelService(rockContext); var _channel = contentChannelService.Get(contextEntity.Id); _channel.ForeignKey = tbForeignKey.Text; _channel.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _channel.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } else if (contextEntity is ContentChannelItem) { var contentChannelItemService = new ContentChannelItemService(rockContext); var _item = contentChannelItemService.Get(contextEntity.Id); _item.ForeignKey = tbForeignKey.Text; _item.ForeignGuid = tbForeignGuid.Text.AsType <Guid?>(); _item.ForeignId = tbForeignId.Text.AsType <int?>(); rockContext.SaveChanges(); } }); Page.Response.Redirect(Page.Request.Url.ToString(), true); }
/// <summary> /// Shows the detail. /// </summary> /// <param name="itemKey">The item key.</param> /// <param name="itemKeyValue">The item key value.</param> /// <param name="parentCategoryId">The parent category id.</param> public void ShowDetail(string itemKey, int itemKeyValue, int?parentCategoryId) { pnlDetails.Visible = false; if (!itemKey.Equals("MetricId")) { return; } var rockContext = new RockContext(); var metricService = new MetricService(rockContext); Metric metric = null; if (!itemKeyValue.Equals(0)) { metric = metricService.Get(itemKeyValue); } else { metric = new Metric { Id = 0, IsSystem = false }; metric.MetricCategories = new List <MetricCategory>(); if (parentCategoryId.HasValue) { var metricCategory = new MetricCategory { CategoryId = parentCategoryId.Value }; metricCategory.Category = metricCategory.Category ?? new CategoryService(rockContext).Get(metricCategory.CategoryId); metric.MetricCategories.Add(metricCategory); } } if (metric == null || !metric.IsAuthorized(Authorization.VIEW, CurrentPerson)) { return; } pnlDetails.Visible = true; hfMetricId.Value = metric.Id.ToString(); // render UI based on Authorized and IsSystem bool readOnly = false; nbEditModeMessage.Text = string.Empty; if (metric.IsSystem) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.ReadOnlySystem(Metric.FriendlyTypeName); } btnSecurity.Visible = metric.IsAuthorized(Authorization.ADMINISTRATE, CurrentPerson); btnSecurity.Title = metric.Title; btnSecurity.EntityId = metric.Id; if (readOnly) { btnEdit.Visible = false; btnDelete.Visible = false; ShowReadonlyDetails(metric); } else { btnEdit.Visible = true; string errorMessage = string.Empty; btnDelete.Visible = metricService.CanDelete(metric, out errorMessage); if (metric.Id > 0) { ShowReadonlyDetails(metric); } else { ShowEditDetails(metric); } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var metricSourceValueTypeDataviewGuid = Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_DATAVIEW.AsGuid(); var metricSourceValueTypeSqlGuid = Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_SQL.AsGuid(); var metricsQry = new MetricService(new RockContext()).Queryable().AsNoTracking().Where( a => a.ScheduleId.HasValue && a.SourceValueTypeId.HasValue && (a.SourceValueType.Guid == metricSourceValueTypeDataviewGuid || a.SourceValueType.Guid == metricSourceValueTypeSqlGuid)); var metricIdList = metricsQry.OrderBy(a => a.Title).ThenBy(a => a.Subtitle).Select(a => a.Id).ToList(); var metricExceptions = new List <Exception>(); int metricsCalculated = 0; int metricValuesCalculated = 0; Metric metric = null; foreach (var metricId in metricIdList) { try { using (var rockContextForMetricEntity = new RockContext()) { var metricService = new MetricService(rockContextForMetricEntity); metric = metricService.Get(metricId); var lastRunDateTime = metric.LastRunDateTime ?? metric.CreatedDateTime ?? metric.ModifiedDateTime; if (lastRunDateTime.HasValue) { var currentDateTime = RockDateTime.Now; // get all the schedule times that were supposed to run since that last time it was scheduled to run var scheduledDateTimesToProcess = metric.Schedule.GetScheduledStartTimes(lastRunDateTime.Value, currentDateTime).Where(a => a > lastRunDateTime.Value).ToList(); foreach (var scheduleDateTime in scheduledDateTimesToProcess) { using (var rockContextForMetricValues = new RockContext()) { var metricPartitions = new MetricPartitionService(rockContextForMetricValues).Queryable().Where(a => a.MetricId == metric.Id).ToList(); var metricValueService = new MetricValueService(rockContextForMetricValues); List <ResultValue> resultValues = new List <ResultValue>(); bool getMetricValueDateTimeFromResultSet = false; if (metric.SourceValueType.Guid == metricSourceValueTypeDataviewGuid) { // get the metric value from the DataView if (metric.DataView != null) { var errorMessages = new List <string>(); var qry = metric.DataView.GetQuery(null, null, out errorMessages); if (metricPartitions.Count > 1 || metricPartitions.First().EntityTypeId.HasValue) { throw new NotImplementedException("Partitioned Metrics using DataViews is not supported."); } else { var resultValue = new ResultValue(); resultValue.Value = Convert.ToDecimal(qry.Count()); resultValue.Partitions = new List <ResultValuePartition>(); resultValue.MetricValueDateTime = scheduleDateTime; resultValues.Add(resultValue); } } } else if (metric.SourceValueType.Guid == metricSourceValueTypeSqlGuid) { //// calculate the metricValue using the results from the SQL //// assume SQL is in one of the following forms: //// -- "SELECT Count(*), Partion0EntityId, Partion1EntityId, Partion2EntityId,.. FROM ..." //// -- "SELECT Count(*), [MetricValueDateTime], Partion0EntityId, Partion1EntityId, Partion2EntityId,.. FROM ..." if (!string.IsNullOrWhiteSpace(metric.SourceSql)) { string formattedSql = metric.SourceSql.ResolveMergeFields(metric.GetMergeObjects(scheduleDateTime)); var tableResult = DbService.GetDataTable(formattedSql, System.Data.CommandType.Text, null); if (tableResult.Columns.Count >= 2 && tableResult.Columns[1].ColumnName == "MetricValueDateTime") { getMetricValueDateTimeFromResultSet = true; } foreach (var row in tableResult.Rows.OfType <System.Data.DataRow>()) { var resultValue = new ResultValue(); resultValue.Value = Convert.ToDecimal(row[0]); if (getMetricValueDateTimeFromResultSet) { resultValue.MetricValueDateTime = Convert.ToDateTime(row[1]); } else { resultValue.MetricValueDateTime = scheduleDateTime; } resultValue.Partitions = new List <ResultValuePartition>(); int partitionPosition = 0; int partitionFieldIndex = getMetricValueDateTimeFromResultSet ? 2 : 1; int partitionColumnCount = tableResult.Columns.Count - 1; while (partitionFieldIndex <= partitionColumnCount) { resultValue.Partitions.Add(new ResultValuePartition { PartitionPosition = partitionPosition, EntityId = row[partitionFieldIndex] as int? }); partitionPosition++; partitionFieldIndex++; } resultValues.Add(resultValue); } } } metric.LastRunDateTime = scheduleDateTime; metricsCalculated++; metricValuesCalculated += resultValues.Count(); if (resultValues.Any()) { List <MetricValue> metricValuesToAdd = new List <MetricValue>(); foreach (var resultValue in resultValues) { var metricValue = new MetricValue(); metricValue.MetricId = metric.Id; metricValue.MetricValueDateTime = resultValue.MetricValueDateTime; metricValue.MetricValueType = MetricValueType.Measure; metricValue.YValue = resultValue.Value; metricValue.CreatedDateTime = RockDateTime.Now; metricValue.ModifiedDateTime = RockDateTime.Now; metricValue.MetricValuePartitions = new List <MetricValuePartition>(); var metricPartitionsByPosition = metricPartitions.OrderBy(a => a.Order).ToList(); if (!resultValue.Partitions.Any() && metricPartitionsByPosition.Count() == 1 && !metricPartitionsByPosition[0].EntityTypeId.HasValue) { // a metric with just the default partition (not partitioned by Entity) var metricPartition = metricPartitionsByPosition[0]; var metricValuePartition = new MetricValuePartition(); metricValuePartition.MetricPartition = metricPartition; metricValuePartition.MetricPartitionId = metricPartition.Id; metricValuePartition.MetricValue = metricValue; metricValuePartition.EntityId = null; metricValue.MetricValuePartitions.Add(metricValuePartition); } else { foreach (var partitionResult in resultValue.Partitions) { if (metricPartitionsByPosition.Count > partitionResult.PartitionPosition) { var metricPartition = metricPartitionsByPosition[partitionResult.PartitionPosition]; var metricValuePartition = new MetricValuePartition(); metricValuePartition.MetricPartition = metricPartition; metricValuePartition.MetricPartitionId = metricPartition.Id; metricValuePartition.MetricValue = metricValue; metricValuePartition.EntityId = partitionResult.EntityId; metricValue.MetricValuePartitions.Add(metricValuePartition); } } } if (metricValue.MetricValuePartitions == null || !metricValue.MetricValuePartitions.Any()) { // shouldn't happen, but just in case throw new Exception("MetricValue requires at least one Partition Value"); } else { metricValuesToAdd.Add(metricValue); } } // if a single metricValueDateTime was specified, delete any existing metric values for this date and refresh with the current results var dbTransaction = rockContextForMetricValues.Database.BeginTransaction(); if (getMetricValueDateTimeFromResultSet) { var metricValueDateTimes = metricValuesToAdd.Select(a => a.MetricValueDateTime).Distinct().ToList(); foreach (var metricValueDateTime in metricValueDateTimes) { bool alreadyHasMetricValues = metricValueService.Queryable().Where(a => a.MetricId == metric.Id && a.MetricValueDateTime == metricValueDateTime).Any(); if (alreadyHasMetricValues) { // use direct SQL to clean up any existing metric values rockContextForMetricValues.Database.ExecuteSqlCommand(@" DELETE FROM MetricValuePartition WHERE MetricValueId IN ( SELECT Id FROM MetricValue WHERE MetricId = @metricId AND MetricValueDateTime = @metricValueDateTime ) ", new SqlParameter("@metricId", metric.Id), new SqlParameter("@metricValueDateTime", metricValueDateTime)); rockContextForMetricValues.Database.ExecuteSqlCommand(@" DELETE FROM MetricValue WHERE MetricId = @metricId AND MetricValueDateTime = @metricValueDateTime ", new SqlParameter("@metricId", metric.Id), new SqlParameter("@metricValueDateTime", metricValueDateTime)); } } } metricValueService.AddRange(metricValuesToAdd); // disable savechanges PrePostProcessing since there could be hundreds or thousands of metric values getting inserted/updated rockContextForMetricValues.SaveChanges(true); dbTransaction.Commit(); } rockContextForMetricEntity.SaveChanges(); } } } } } catch (Exception ex) { metricExceptions.Add(new Exception(string.Format("Exception when calculating metric for {0} ", metric), ex)); } } context.Result = string.Format("Calculated a total of {0} metric values for {1} metrics", metricValuesCalculated, metricsCalculated); if (metricExceptions.Any()) { throw new AggregateException("One or more metric calculations failed ", metricExceptions); } }
public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; var rockContext = new RockContext(); var jobService = new ServiceJobService(rockContext); GroupService groupService = new GroupService(rockContext); CategoryService categoryService = new CategoryService(rockContext); MetricService metricService = new MetricService(rockContext); var metricCategories = MetricCategoriesFieldAttribute.GetValueAsGuidPairs(dataMap.GetString("Metrics")); DateRange dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange")); var systemEmail = dataMap.GetString("Email").AsGuidOrNull(); if (!systemEmail.HasValue) { throw new Exception("System Email is required!"); } // get job type id int jobId = Convert.ToInt16(context.JobDetail.Description); var job = jobService.Get(jobId); DateTime _midnightToday = RockDateTime.Today.AddDays(1); var currentDateTime = RockDateTime.Now; int recipients = 0; Group notificationGroup = groupService.Get(dataMap.GetString("NotificationGroup").AsGuid()); List <MetricCount> metricCounts = CampusCache.All().Select(c => new MetricCount() { Campus = c, TotalEntered = 0, TotalMetrics = 0 }).ToList(); List <Metric> metrics = new List <Metric>(); // If we have some reasonable data, go ahead and run the job if (notificationGroup != null && metricCategories.Count > 0 && dateRange.Start.HasValue && dateRange.End.HasValue) { foreach (MetricCategoryPair metricCategoryPair in metricCategories) { Metric metric = metricService.Get(metricCategoryPair.MetricGuid); metrics.Add(metric); // Split this by campus partition if (metric.MetricPartitions.Any(mp => mp.EntityType.Name.Contains("Campus"))) { foreach (CampusCache campus in CampusCache.All()) { // Check to see if we also have a schedule partition if (metric.MetricPartitions.Any(mp => mp.EntityType.Name.Contains("Schedule"))) { var services = GetServices(campus, dataMap, dateRange); metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalMetrics += services.Count; foreach (var service in services) { var hasValues = metric.MetricValues.Where(mv => mv.MetricValuePartitions.Any(mvp => mvp.MetricPartition.EntityType.Name.Contains("Campus") && mvp.EntityId == campus.Id) && mv.MetricValuePartitions.Any(mvp => mvp.MetricPartition.EntityType.Name.Contains("Schedule") && mvp.EntityId == service.Id) && mv.MetricValueDateTime >= dateRange.Start.Value && mv.MetricValueDateTime <= dateRange.End.Value).Any(); if (hasValues) { metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalEntered++; } } } else { // Add totals for metrics and, if values are entered, metrics entered. metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalMetrics++; var hasValues = metric.MetricValues.Where(mv => mv.MetricValuePartitions.Any(mvp => mvp.MetricPartition.EntityType.Name.Contains("Campus") && mvp.EntityId == campus.Id) && mv.MetricValueDateTime >= dateRange.Start.Value && mv.MetricValueDateTime <= dateRange.End.Value).Any(); if (hasValues) { metricCounts.Where(mc => mc.Campus == campus).FirstOrDefault().TotalEntered++; } } } } } // Create the merge fields var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("MetricCounts", metricCounts); mergeFields.Add("Metrics", metrics); mergeFields.Add("DateRange", dateRange.ToString()); mergeFields.Add("LastRunDate", job.LastSuccessfulRunDateTime); // Setup the email and send it out! RockEmailMessage message = new RockEmailMessage(systemEmail.Value); message.AdditionalMergeFields = mergeFields; foreach (GroupMember member in notificationGroup.Members) { message.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(member.Person.Email, mergeFields)); recipients++; } message.SendSeperatelyToEachRecipient = true; message.Send(); } context.Result = string.Format("Sent " + recipients + " metric entry digest emails."); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var dataMap = context.JobDetail.JobDataMap; var commandTimeout = dataMap.GetString(AttributeKey.CommandTimeout).AsIntegerOrNull() ?? 300; var metricSourceValueTypeDataviewGuid = Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_DATAVIEW.AsGuid(); var metricSourceValueTypeSqlGuid = Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_SQL.AsGuid(); var metricSourceValueTypeLavaGuid = Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_LAVA.AsGuid(); Guid[] calculatedSourceTypes = new Guid[] { metricSourceValueTypeDataviewGuid, metricSourceValueTypeSqlGuid, metricSourceValueTypeLavaGuid }; var metricsQry = new MetricService(new RockContext()).Queryable().AsNoTracking().Where( a => a.ScheduleId.HasValue && a.SourceValueTypeId.HasValue && calculatedSourceTypes.Contains(a.SourceValueType.Guid)); var metricIdList = metricsQry.OrderBy(a => a.Title).ThenBy(a => a.Subtitle).Select(a => a.Id).ToList(); var metricExceptions = new List <Exception>(); int metricsCalculated = 0; int metricValuesCalculated = 0; Metric metric = null; foreach (var metricId in metricIdList) { try { using (var rockContextForMetricEntity = new RockContext()) { rockContextForMetricEntity.Database.CommandTimeout = commandTimeout; var metricService = new MetricService(rockContextForMetricEntity); metric = metricService.Get(metricId); /* Get the last time the metric has run, if it has never run then set it as the first day of the current week to give it a chance to run now. * NOTE: This is being used instead of Min Date to prevent a schedule with a start date of months or years back from running for each period since then. * This would be the case for the "out-of-the-box" Rock daily metrics "Active Records", "Active Families", and "Active Connection Requests" if they * have never run before. Or if a new user created metric uses a schedule that has an older start date. */ DateTime currentDateTime = RockDateTime.Now; DateTime?startOfWeek = currentDateTime.StartOfWeek(RockDateTime.FirstDayOfWeek); DateTime?lastRunDateTime = metric.LastRunDateTime ?? startOfWeek; // get all the schedule times that were supposed to run since that last time it was scheduled to run var scheduledDateTimesToProcess = metric.Schedule.GetScheduledStartTimes(lastRunDateTime.Value, currentDateTime).Where(a => a > lastRunDateTime.Value).ToList(); foreach (var scheduleDateTime in scheduledDateTimesToProcess) { using (var rockContextForMetricValues = new RockContext()) { rockContextForMetricValues.Database.CommandTimeout = commandTimeout; var metricPartitions = new MetricPartitionService(rockContextForMetricValues).Queryable().Where(a => a.MetricId == metric.Id).ToList(); var metricValueService = new MetricValueService(rockContextForMetricValues); List <ResultValue> resultValues = new List <ResultValue>(); bool getMetricValueDateTimeFromResultSet = false; if (metric.SourceValueType.Guid == metricSourceValueTypeDataviewGuid) { // get the metric value from the DataView if (metric.DataView != null) { bool parseCampusPartition = metricPartitions.Count == 1 && metric.AutoPartitionOnPrimaryCampus && metric.DataView.EntityTypeId == Web.Cache.EntityTypeCache.GetId(SystemGuid.EntityType.PERSON) && metricPartitions[0].EntityTypeId == Web.Cache.EntityTypeCache.GetId(SystemGuid.EntityType.CAMPUS); // Dataview metrics can be partitioned by campus only and AutoPartitionOnPrimaryCampus must be selected. if (metricPartitions.Count > 1 || (metricPartitions[0].EntityTypeId.HasValue && parseCampusPartition == false)) { throw new NotImplementedException("Partitioned Metrics using DataViews is only supported for Person data views using a single partition of type 'Campus' with 'Auto Partition on Primary Campus' checked. Any other dataview partition configuration is not supported."); } Stopwatch stopwatch = Stopwatch.StartNew(); var qry = metric.DataView.GetQuery(new DataViewGetQueryArgs()); if (parseCampusPartition) { // Create a dictionary of campus IDs with a person count var campusPartitionValues = new Dictionary <int, int>(); foreach (var person in qry.ToList()) { var iPerson = ( Person )person; var campusId = iPerson.GetCampus()?.Id ?? -1; campusPartitionValues.TryGetValue(campusId, out var currentCount); campusPartitionValues[campusId] = currentCount + 1; } // Use the dictionary to create the ResultValues for each campus (partition) foreach (var campusPartitionValue in campusPartitionValues) { var resultValue = new ResultValue { MetricValueDateTime = scheduleDateTime, Partitions = new List <ResultValuePartition>(), Value = campusPartitionValue.Value }; int?entityId = campusPartitionValue.Key; if (entityId == -1) { entityId = null; } resultValue.Partitions.Add(new ResultValuePartition { PartitionPosition = 0, EntityId = entityId }); resultValues.Add(resultValue); } } else { // Put the entire set in one result since there is no partition resultValues.Add(new ResultValue { Value = Convert.ToDecimal(qry.Count()), MetricValueDateTime = scheduleDateTime, Partitions = new List <ResultValuePartition>() }); } stopwatch.Stop(); DataViewService.AddRunDataViewTransaction(metric.DataView.Id, Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds)); } } else if (metric.SourceValueType.Guid == metricSourceValueTypeSqlGuid) { //// calculate the metricValue using the results from the SQL //// assume SQL is in one of the following forms: //// -- "SELECT Count(*) FROM ..." //// -- "SELECT Count(*), [MetricValueDateTime] FROM ..." //// -- "SELECT Count(*), Partition0EntityId, Partition1EntityId, Partition2EntityId,.. FROM ..." //// -- "SELECT Count(*), [MetricValueDateTime], Partition0EntityId, Partition1EntityId, Partition2EntityId,.. FROM ..." if (!string.IsNullOrWhiteSpace(metric.SourceSql)) { string formattedSql = metric.SourceSql.ResolveMergeFields(metric.GetMergeObjects(scheduleDateTime)); var tableResult = DbService.GetDataTable(formattedSql, System.Data.CommandType.Text, null); if (tableResult.Columns.Count >= 2 && tableResult.Columns[1].ColumnName == "MetricValueDateTime") { getMetricValueDateTimeFromResultSet = true; } foreach (var row in tableResult.Rows.OfType <System.Data.DataRow>()) { var resultValue = new ResultValue(); resultValue.Value = Convert.ToDecimal(row[0] == DBNull.Value ? 0 : row[0]); if (getMetricValueDateTimeFromResultSet) { resultValue.MetricValueDateTime = Convert.ToDateTime(row[1]); } else { resultValue.MetricValueDateTime = scheduleDateTime; } resultValue.Partitions = new List <ResultValuePartition>(); int partitionPosition = 0; int partitionFieldIndex = getMetricValueDateTimeFromResultSet ? 2 : 1; int partitionColumnCount = tableResult.Columns.Count - 1; while (partitionFieldIndex <= partitionColumnCount) { resultValue.Partitions.Add(new ResultValuePartition { PartitionPosition = partitionPosition, EntityId = row[partitionFieldIndex] as int? }); partitionPosition++; partitionFieldIndex++; } resultValues.Add(resultValue); } } } else if (metric.SourceValueType.Guid == metricSourceValueTypeLavaGuid) { //// calculate the metricValue using the results from Lava //// assume Lava Output is in one of the following forms: //// A single Count //// 42 //// A List of Count, MetricValueDateTime //// 42, 1/1/2017 //// 40, 1/2/2017 //// 49, 1/3/2017 //// A List of Count, Partition0EntityId, Partition1EntityId, Partition2EntityId //// 42, 201, 450, 654 //// 42, 202, 450, 654 //// 42, 203, 450, 654 //// A List of Count, MetricValueDateTime, Partition0EntityId, Partition1EntityId, Partition2EntityId //// 42, 1/1/2017, 201, 450, 654 //// 42, 1/2/2017, 202, 450, 654 //// 42, 1/3/2017, 203, 450, 654 if (!string.IsNullOrWhiteSpace(metric.SourceLava)) { var mergeObjects = metric.GetMergeObjects(scheduleDateTime); string lavaResult = metric.SourceLava.ResolveMergeFields(mergeObjects, enabledLavaCommands: "All", throwExceptionOnErrors: true); List <string> resultLines = lavaResult.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries) .Select(a => a.Trim()).Where(a => !string.IsNullOrEmpty(a)).ToList(); List <string[]> resultList = resultLines.Select(a => a.SplitDelimitedValues()).ToList(); if (resultList.Any()) { if (resultList[0].Length >= 2) { // if the value of the data in the 2nd column is a Date, assume that is is the MetricValueDateTime if (resultList[0][1].AsDateTime().HasValue) { getMetricValueDateTimeFromResultSet = true; } } } foreach (var row in resultList) { var resultValue = new ResultValue(); resultValue.Value = row[0].AsDecimal(); if (getMetricValueDateTimeFromResultSet) { resultValue.MetricValueDateTime = row[1].AsDateTime() ?? scheduleDateTime; } else { resultValue.MetricValueDateTime = scheduleDateTime; } resultValue.Partitions = new List <ResultValuePartition>(); int partitionPosition = 0; int partitionFieldIndex = getMetricValueDateTimeFromResultSet ? 2 : 1; int partitionColumnCount = row.Length - 1; while (partitionFieldIndex <= partitionColumnCount) { resultValue.Partitions.Add(new ResultValuePartition { PartitionPosition = partitionPosition, EntityId = row[partitionFieldIndex].AsIntegerOrNull() }); partitionPosition++; partitionFieldIndex++; } resultValues.Add(resultValue); } } } metric.LastRunDateTime = scheduleDateTime; metricsCalculated++; metricValuesCalculated += resultValues.Count(); if (resultValues.Any()) { List <MetricValue> metricValuesToAdd = new List <MetricValue>(); foreach (var resultValue in resultValues) { var metricValue = new MetricValue(); metricValue.MetricId = metric.Id; metricValue.MetricValueDateTime = resultValue.MetricValueDateTime; metricValue.MetricValueType = MetricValueType.Measure; metricValue.YValue = resultValue.Value; metricValue.CreatedDateTime = RockDateTime.Now; metricValue.ModifiedDateTime = RockDateTime.Now; metricValue.MetricValuePartitions = new List <MetricValuePartition>(); var metricPartitionsByPosition = metricPartitions.OrderBy(a => a.Order).ToList(); if (!resultValue.Partitions.Any() && metricPartitionsByPosition.Count() == 1 && !metricPartitionsByPosition[0].EntityTypeId.HasValue) { // a metric with just the default partition (not partitioned by Entity) var metricPartition = metricPartitionsByPosition[0]; var metricValuePartition = new MetricValuePartition(); metricValuePartition.MetricPartition = metricPartition; metricValuePartition.MetricPartitionId = metricPartition.Id; metricValuePartition.MetricValue = metricValue; metricValuePartition.EntityId = null; metricValue.MetricValuePartitions.Add(metricValuePartition); } else { foreach (var partitionResult in resultValue.Partitions) { if (metricPartitionsByPosition.Count > partitionResult.PartitionPosition) { var metricPartition = metricPartitionsByPosition[partitionResult.PartitionPosition]; var metricValuePartition = new MetricValuePartition(); metricValuePartition.MetricPartition = metricPartition; metricValuePartition.MetricPartitionId = metricPartition.Id; metricValuePartition.MetricValue = metricValue; metricValuePartition.EntityId = partitionResult.EntityId; metricValue.MetricValuePartitions.Add(metricValuePartition); } } } if (metricValue.MetricValuePartitions == null || !metricValue.MetricValuePartitions.Any()) { // shouldn't happen, but just in case throw new Exception("MetricValue requires at least one Partition Value"); } else { metricValuesToAdd.Add(metricValue); } } // if a single metricValueDateTime was specified, delete any existing metric values for this date and refresh with the current results var dbTransaction = rockContextForMetricValues.Database.BeginTransaction(); if (getMetricValueDateTimeFromResultSet) { var metricValueDateTimes = metricValuesToAdd.Select(a => a.MetricValueDateTime).Distinct().ToList(); foreach (var metricValueDateTime in metricValueDateTimes) { bool alreadyHasMetricValues = metricValueService.Queryable().Where(a => a.MetricId == metric.Id && a.MetricValueDateTime == metricValueDateTime).Any(); if (alreadyHasMetricValues) { // use direct SQL to clean up any existing metric values rockContextForMetricValues.Database.ExecuteSqlCommand(@" DELETE FROM MetricValuePartition WHERE MetricValueId IN ( SELECT Id FROM MetricValue WHERE MetricId = @metricId AND MetricValueDateTime = @metricValueDateTime ) ", new SqlParameter("@metricId", metric.Id), new SqlParameter("@metricValueDateTime", metricValueDateTime)); rockContextForMetricValues.Database.ExecuteSqlCommand(@" DELETE FROM MetricValue WHERE MetricId = @metricId AND MetricValueDateTime = @metricValueDateTime ", new SqlParameter("@metricId", metric.Id), new SqlParameter("@metricValueDateTime", metricValueDateTime)); } } } metricValueService.AddRange(metricValuesToAdd); // disable savechanges PrePostProcessing since there could be hundreds or thousands of metric values getting inserted/updated rockContextForMetricValues.SaveChanges(true); dbTransaction.Commit(); } rockContextForMetricEntity.SaveChanges(); } } } } catch (Exception ex) { metricExceptions.Add(new Exception($"Exception when calculating metric for {metric}: {ex.Message}", ex)); } } context.Result = string.Format("Calculated a total of {0} metric values for {1} metrics", metricValuesCalculated, metricsCalculated); if (metricExceptions.Any()) { throw new AggregateException("One or more metric calculations failed ", metricExceptions); } }
/// <summary> /// Updates the entity type controls. /// </summary> private void UpdateEntityTypeControls() { var metricService = new MetricService(new RockContext()); var metric = metricService.Get(this.MetricId ?? 0); _phEntityTypeEntityIdValue.Controls.Clear(); string fieldTypeName = null; Control entityTypeEditControl = null; if (metric != null) { var entityType = EntityTypeCache.Read(metric.EntityTypeId ?? 0); if (entityType != null && entityType.SingleValueFieldType != null) { fieldTypeName = entityType.SingleValueFieldType.Name; entityTypeEditControl = entityType.SingleValueFieldType.Field.EditControl(new Dictionary <string, Field.ConfigurationValue>(), string.Format("{0}_{1}_Picker", this.ID, fieldTypeName)); } } // only set the _entityTypeEditControl is needs to be if (_entityTypeEditControl == null || !_entityTypeEditControl.GetType().Equals(entityTypeEditControl.GetType()) || _entityTypeEditControl.ID != entityTypeEditControl.ID) { _entityTypeEditControl = entityTypeEditControl; } if (_entityTypeEditControl != null) { var rockControlWrapper = new RockControlWrapper(); rockControlWrapper.Label = string.Format("{0} filter", fieldTypeName); rockControlWrapper.Help = string.Format( "Either select a specific {0}, or select 'Get from page context' to determine the {0} based on the page context. Leave {0} blank to show values for all {1}", fieldTypeName, fieldTypeName.Pluralize()); rockControlWrapper.ID = string.Format("{0}_{1}", this.ID, "rockControlWrapper"); _phEntityTypeEntityIdValue.Controls.Add(rockControlWrapper); if (_rblSelectOrContext == null) { _rblSelectOrContext = new RockRadioButtonList(); _rblSelectOrContext.ID = string.Format("{0}_{1}", this.ID, "rblSelectOrContext"); _rblSelectOrContext.RepeatDirection = RepeatDirection.Horizontal; _rblSelectOrContext.Items.Add(new ListItem("Select " + fieldTypeName, "0")); _rblSelectOrContext.Items.Add(new ListItem("Get from page context", "1")); _rblSelectOrContext.AutoPostBack = true; _rblSelectOrContext.SelectedIndexChanged += rblSelectOrContext_SelectedIndexChanged; } else { _rblSelectOrContext.Items[0].Text = "Select " + fieldTypeName; } rockControlWrapper.Controls.Add(_rblSelectOrContext); if (string.IsNullOrEmpty(_rblSelectOrContext.SelectedValue)) { // might have to get the SelectedValue since we re-created the control after Load() _rblSelectOrContext.SelectedValue = this.Page.Request.Params[_rblSelectOrContext.UniqueID]; } if (string.IsNullOrEmpty(_rblSelectOrContext.SelectedValue)) { // if not set from either what it was, or from PageContext, default it to "Get from page context" _rblSelectOrContext.SelectedValue = "1"; } _entityTypeEditControl.Visible = _rblSelectOrContext.SelectedValue.AsIntegerOrNull() == 0; rockControlWrapper.Controls.Add(_entityTypeEditControl); if (_cbCombine == null) { _cbCombine = new RockCheckBox(); _cbCombine.ID = string.Format("{0}_{1}", this.ID, "cbCombine"); } _cbCombine.Text = "Combine multiple values to one line when showing values for multiple " + fieldTypeName.Pluralize(); rockControlWrapper.Controls.Add(_cbCombine); } }
/// <summary> /// Shows the detail. /// </summary> /// <param name="metricId">The metric identifier.</param> /// <param name="parentCategoryId">The parent category id.</param> public void ShowDetail(int metricId, int?parentCategoryId) { pnlDetails.Visible = false; var rockContext = new RockContext(); var metricService = new MetricService(rockContext); Metric metric = null; if (!metricId.Equals(0)) { metric = metricService.Get(metricId); } if (metric == null) { metric = new Metric { Id = 0, IsSystem = false }; metric.SourceValueTypeId = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.METRIC_SOURCE_VALUE_TYPE_MANUAL.AsGuid()).Id; metric.MetricCategories = new List <MetricCategory>(); if (parentCategoryId.HasValue) { var metricCategory = new MetricCategory { CategoryId = parentCategoryId.Value }; metricCategory.Category = metricCategory.Category ?? new CategoryService(rockContext).Get(metricCategory.CategoryId); metric.MetricCategories.Add(metricCategory); } } if (!metric.IsAuthorized(Authorization.VIEW, CurrentPerson)) { return; } pnlDetails.Visible = true; hfMetricId.Value = metric.Id.ToString(); // render UI based on Authorized and IsSystem bool readOnly = false; nbEditModeMessage.Text = string.Empty; if (metric.IsSystem) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.ReadOnlySystem(Metric.FriendlyTypeName); } if (!UserCanEdit && !metric.IsAuthorized(Authorization.EDIT, CurrentPerson)) { readOnly = true; nbEditModeMessage.Text = EditModeMessage.NotAuthorizedToEdit(Metric.FriendlyTypeName); } bool canAdministrate = UserCanAdministrate || metric.IsAuthorized(Authorization.ADMINISTRATE, CurrentPerson); if (canAdministrate) { btnSecurity.Visible = true; btnSecurity.Title = metric.Title; btnSecurity.EntityId = metric.Id; } else { btnSecurity.Visible = false; } if (readOnly) { btnEdit.Visible = false; btnDelete.Visible = false; ShowReadonlyDetails(metric); } else { btnEdit.Visible = true; string errorMessage = string.Empty; btnDelete.Visible = metricService.CanDelete(metric, out errorMessage); if (metric.Id > 0) { ShowReadonlyDetails(metric); } else { ShowEditDetails(metric); } } }
protected override void ExecuteTest() { service = new MetricService<SomeMetricInstanceSetRequest>(metricMetadataTreeService, metricDataService, metricInstanceTreeFactory, metricNodeResolver); metricBase = service.Get(suppliedMetricInstanceSetRequest); }
/// <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); int metricId = hfMetricId.Value.AsInteger(false) ?? 0; 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; metric.EntityTypeId = etpEntityType.SelectedEntityTypeId; 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; metric.SourceSql = ceSourceSql.Text; metric.DataViewId = ddlDataView.SelectedValueAsId(); if (rblScheduleSelect.SelectedValueAsEnum <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() RockTransactionScope.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; } schedule.iCalendarContent = sbSchedule.iCalendarContent; if (schedule.Id == 0) { scheduleService.Add(schedule); // save to make sure we have a scheduleId rockContext.SaveChanges(); } metric.ScheduleId = schedule.Id; 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) { 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 any orphaned Unnamed metric schedules var metricIdSchedulesQry = metricService.Queryable().Select(a => a.ScheduleId); var orphanedSchedules = scheduleService.Queryable() .Where(a => a.CategoryId == metricScheduleCategoryId && a.Name == string.Empty && a.Id != schedule.Id) .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").AsInteger(); 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; NavigateToPage(RockPage.Guid, qryParams); }