public string GetHtmlForBlock( int blockId, int? entityTypeId = null, int? entityId = null ) { RockContext rockContext = this.Service.Context as RockContext ?? new RockContext(); Block block = new BlockService( rockContext ).Get( blockId ); if ( block != null ) { block.LoadAttributes(); string liquidTemplate = block.GetAttributeValue( "LiquidTemplate" ); var metricCategoryPairList = Rock.Attribute.MetricCategoriesFieldAttribute.GetValueAsGuidPairs( block.GetAttributeValue( "MetricCategories" ) ); var metricGuids = metricCategoryPairList.Select( a => a.MetricGuid ).ToList(); bool roundYValues = block.GetAttributeValue( "RoundValues" ).AsBooleanOrNull() ?? true; MetricService metricService = new MetricService( rockContext ); var metrics = metricService.GetByGuids( metricGuids ); List<object> metricsData = new List<object>(); if ( metrics.Count() == 0 ) { return @"<div class='alert alert-warning'> Please select a metric in the block settings. </div>"; } MetricValueService metricValueService = new MetricValueService( rockContext ); DateTime firstDayOfYear = new DateTime( RockDateTime.Now.Year, 1, 1 ); DateTime currentDateTime = RockDateTime.Now; DateTime firstDayOfNextYear = new DateTime( RockDateTime.Now.Year + 1, 1, 1 ); foreach ( var metric in metrics ) { var metricYTDData = JsonConvert.DeserializeObject( metric.ToJson(), typeof( MetricYTDData ) ) as MetricYTDData; var qryMeasureValues = metricValueService.Queryable() .Where( a => a.MetricId == metricYTDData.Id ) .Where( a => a.MetricValueDateTime >= firstDayOfYear && a.MetricValueDateTime < currentDateTime ) .Where( a => a.MetricValueType == MetricValueType.Measure ); //// if an entityTypeId/EntityId filter was specified, and the entityTypeId is the same as the metrics.EntityTypeId, filter the values to the specified entityId //// Note: if a Metric or it's Metric Value doesn't have a context, include it regardless of Context setting if ( entityTypeId.HasValue && ( metric.EntityTypeId == entityTypeId || metric.EntityTypeId == null ) ) { if ( entityId.HasValue ) { qryMeasureValues = qryMeasureValues.Where( a => a.EntityId == entityId || a.EntityId == null ); } } var lastMetricValue = qryMeasureValues.OrderByDescending( a => a.MetricValueDateTime ).FirstOrDefault(); if ( lastMetricValue != null ) { metricYTDData.LastValue = lastMetricValue.YValue.HasValue ? Math.Round( lastMetricValue.YValue.Value, roundYValues ? 0 : 2 ) : (decimal?)null; metricYTDData.LastValueDate = lastMetricValue.MetricValueDateTime.HasValue ? lastMetricValue.MetricValueDateTime.Value.Date : DateTime.MinValue; } decimal? sum = qryMeasureValues.Sum( a => a.YValue ); metricYTDData.CumulativeValue = sum.HasValue ? Math.Round( sum.Value, roundYValues ? 0 : 2 ) : (decimal?)null; // figure out goal as of current date time by figuring out the slope of the goal var qryGoalValuesCurrentYear = metricValueService.Queryable() .Where( a => a.MetricId == metricYTDData.Id ) .Where( a => a.MetricValueDateTime >= firstDayOfYear && a.MetricValueDateTime < firstDayOfNextYear ) .Where( a => a.MetricValueType == MetricValueType.Goal ); // if an entityTypeId/EntityId filter was specified, and the entityTypeId is the same as the metrics.EntityTypeId, filter the values to the specified entityId if ( entityTypeId.HasValue && metric.EntityTypeId == entityTypeId ) { if ( entityId.HasValue ) { qryGoalValuesCurrentYear = qryGoalValuesCurrentYear.Where( a => a.EntityId == entityId ); } } MetricValue goalLineStartPoint = qryGoalValuesCurrentYear.Where( a => a.MetricValueDateTime <= currentDateTime ).OrderByDescending( a => a.MetricValueDateTime ).FirstOrDefault(); MetricValue goalLineEndPoint = qryGoalValuesCurrentYear.Where( a => a.MetricValueDateTime >= currentDateTime ).FirstOrDefault(); if ( goalLineStartPoint != null && goalLineEndPoint != null ) { var changeInX = goalLineEndPoint.DateTimeStamp - goalLineStartPoint.DateTimeStamp; var changeInY = goalLineEndPoint.YValue - goalLineStartPoint.YValue; if ( changeInX != 0 ) { decimal? slope = changeInY / changeInX; decimal goalValue = ( ( slope * ( currentDateTime.ToJavascriptMilliseconds() - goalLineStartPoint.DateTimeStamp ) ) + goalLineStartPoint.YValue ).Value; metricYTDData.GoalValue = Math.Round( goalValue, roundYValues ? 0 : 2 ); } } else { // if there isn't a both a start goal and end goal within the date range, there wouldn't be a goal line shown in a line chart, so don't display a goal in liquid either metricYTDData.GoalValue = null; } metricsData.Add( metricYTDData.ToLiquid() ); } Dictionary<string, object> mergeValues = new Dictionary<string, object>(); mergeValues.Add( "Metrics", metricsData ); string resultHtml = liquidTemplate.ResolveMergeFields( mergeValues ); // show liquid help for debug if ( block.GetAttributeValue( "EnableDebug" ).AsBoolean() ) { resultHtml += mergeValues.lavaDebugInfo(); } return resultHtml; } return string.Format( @"<div class='alert alert-danger'> unable to find block_id: {1} </div>", blockId ); }
/// <summary> /// Gets the metric values. /// </summary> /// <param name="isPrimary">if set to <c>true</c> [is primary].</param> /// <returns></returns> protected List<MetricValue> GetMetricValues( bool isPrimary ) { var rockContext = new RockContext(); var metricService = new MetricService( rockContext ); List<Guid> sourceGuids = null; var preKey = isPrimary ? string.Empty : "Comparison"; IQueryable<MetricValue> metricValues = null; var attributeValue = GetAttributeValue( preKey + "MetricSource" ); if ( string.IsNullOrWhiteSpace( attributeValue ) ) { attributeValue = string.Empty; } var pairs = MetricCategoriesFieldAttribute.GetValueAsGuidPairs( attributeValue ); sourceGuids = pairs.Select( p => p.MetricGuid ).ToList(); if ( sourceGuids.Any() ) { metricValues = metricService.GetByGuids( sourceGuids ).SelectMany( m => m.MetricValues ); } else { nbMetricWarning.Visible = true; pnlMetricDisplay.Visible = false; return null; } if ( GetAttributeValue( preKey + "RespectCampusContext" ).AsBoolean() ) { var campusContext = RockPage.GetCurrentContext( EntityTypeCache.Read( typeof( Campus ) ) ); if ( campusContext != null ) { metricValues = FilterMetricValuesByPartition( metricValues, "Campus", campusContext.Id ); } } if ( GetAttributeValue( preKey + "RespectGroupContext" ).AsBoolean() ) { var groupTypeContext = RockPage.GetCurrentContext( EntityTypeCache.Read( typeof( GroupType ) ) ); var groupContext = RockPage.GetCurrentContext( EntityTypeCache.Read( typeof( Group ) ) ); if ( groupContext != null ) { metricValues = FilterMetricValuesByPartition( metricValues, "Group", groupContext.Id ); } else if ( groupTypeContext != null ) { var groupTypeIds = new GroupTypeService( rockContext ).GetAllAssociatedDescendents( groupTypeContext.Id ).Select( gt => gt.Id ); var groupIds = new GroupService( rockContext ).Queryable().Where( g => groupTypeIds.Contains( g.GroupTypeId ) ).Select( g => g.Id ); metricValues = metricValues.Where( a => a.MetricValuePartitions.Any( mvp => mvp.MetricPartition.Label == "Group" && groupIds.Any( i => i == mvp.EntityId ) ) ); } } if ( GetAttributeValue( preKey + "RespectDateContext" ).AsBoolean() ) { var dateRangeString = RockPage.GetUserPreference( ContextPreferenceName ); if ( !string.IsNullOrWhiteSpace( dateRangeString ) ) { var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( dateRangeString ); metricValues = metricValues.Where( v => v.MetricValueDateTime >= dateRange.Start && v.MetricValueDateTime <= dateRange.End ); } } if ( GetAttributeValue( preKey + "RespectScheduleContext" ).AsBoolean() ) { var scheduleContext = RockPage.GetCurrentContext( EntityTypeCache.Read( typeof( Schedule ) ) ); if ( scheduleContext != null ) { metricValues = FilterMetricValuesByPartition( metricValues, "Schedule", scheduleContext.Id ); } } return metricValues.ToList(); }