/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls( Type entityType, FilterField filterControl ) { AccountPicker accountPicker = new AccountPicker(); accountPicker.AllowMultiSelect = true; accountPicker.ID = filterControl.ID + "_accountPicker"; accountPicker.AddCssClass( "js-account-picker" ); accountPicker.Label = "Accounts"; filterControl.Controls.Add( accountPicker ); SlidingDateRangePicker slidingDateRangePicker = new SlidingDateRangePicker(); slidingDateRangePicker.ID = filterControl.ID + "_slidingDateRangePicker"; slidingDateRangePicker.AddCssClass( "js-sliding-date-range" ); slidingDateRangePicker.Label = "Date Range"; slidingDateRangePicker.Help = "The date range of the transactions using the 'Sunday Date' of each transaction"; slidingDateRangePicker.Required = true; filterControl.Controls.Add( slidingDateRangePicker ); var controls = new Control[2] { accountPicker, slidingDateRangePicker }; return controls; }
/// <summary> /// Gets the help HTML that explains usage of the SlidingDateRange picker with examples /// </summary> /// <param name="currentDateTime">The current date time.</param> /// <returns></returns> public static string GetHelpHtml( DateTime currentDateTime ) { SlidingDateRangePicker helperPicker = new SlidingDateRangePicker(); SlidingDateRangeType[] slidingDateRangeTypesForHelp = new SlidingDateRangeType[] { SlidingDateRangeType.Current, SlidingDateRangeType.Previous, SlidingDateRangeType.Last, SlidingDateRangeType.Next, SlidingDateRangeType.Upcoming }; string helpHtml = @" <div class='slidingdaterange-help'> <p>A date range can either be a specific date range, or a sliding date range based on the current date and time.</p> <p>For a sliding date range, you can choose either <strong>current, previous, last, next, upcoming</strong> with a time period of <strong>hour, day, week, month, or year</strong>. Note that a week is Monday thru Sunday.</p> <br /> <ul class=''> <li><strong>Current</strong> - the time period that the current date/time is in</li> <li><strong>Previous</strong> - the time period(s) prior to the current period (does not include the current time period). For example, to see the most recent weekend, select 'Previous 1 Week'</li> <li><strong>Last</strong> - the last X time period(s) including the current until today. For example, to see so far this current week and prior week, select 'Last 2 weeks'</li> <li><strong>Next</strong> - the next X time period(s) including the rest of the current period. For example, to see the rest of the current month and the next full month after, select 'Next 2 months'</li> <li><strong>Upcoming</strong> - the upcoming X time period(s) not including the current time period.</li> </ul> <h3>Preview of the sliding date ranges</h3>"; foreach ( var slidingDateRangeType in slidingDateRangeTypesForHelp ) { helperPicker.SlidingDateRangeMode = slidingDateRangeType; helperPicker.NumberOfTimeUnits = 2; StringBuilder sb = new StringBuilder(); sb.AppendFormat( @"<h4>{0}</h4>", slidingDateRangeType.ConvertToString() ); sb.AppendLine( "<ul>" ); foreach ( var timeUnitType in Enum.GetValues( typeof( TimeUnitType ) ).OfType<TimeUnitType>() ) { helperPicker.TimeUnit = timeUnitType; sb.AppendFormat( @" <li> <span class='slidingdaterange-help-key'>{0} {1}</span> <span class='slidingdaterange-help-value'> - {2}</span> </li>", slidingDateRangeType != SlidingDateRangeType.Current ? helperPicker.NumberOfTimeUnits.ToString() : string.Empty, helperPicker.TimeUnit.ConvertToString().PluralizeIf( slidingDateRangeType != SlidingDateRangeType.Current && helperPicker.NumberOfTimeUnits > 1 ), SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( helperPicker.DelimitedValues ).ToStringAutomatic() ); } sb.AppendLine( "</ul>" ); helpHtml += sb.ToString(); } helpHtml += @" </div> "; return helpHtml; }
/// <summary> /// Gets the filter value control. /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="id">The identifier.</param> /// <param name="required">if set to <c>true</c> [required].</param> /// <param name="filterMode">The filter mode.</param> /// <returns></returns> public override Control FilterValueControl( Dictionary<string, ConfigurationValue> configurationValues, string id, bool required, FilterMode filterMode ) { var dateFiltersPanel = new Panel(); dateFiltersPanel.ID = string.Format( "{0}_dtFilterControls", id ); var datePickerPanel = new Panel(); dateFiltersPanel.Controls.Add( datePickerPanel ); var datePicker = new DatePicker(); datePicker.ID = string.Format( "{0}_dtPicker", id ); datePicker.DisplayCurrentOption = true; datePickerPanel.AddCssClass( "js-filter-control" ); datePickerPanel.Controls.Add( datePicker ); var slidingDateRangePicker = new SlidingDateRangePicker(); slidingDateRangePicker.ID = string.Format( "{0}_dtSlidingDateRange", id ); slidingDateRangePicker.AddCssClass("js-filter-control-between"); slidingDateRangePicker.Label = string.Empty; slidingDateRangePicker.PreviewLocation = SlidingDateRangePicker.DateRangePreviewLocation.Right; dateFiltersPanel.Controls.Add( slidingDateRangePicker ); return dateFiltersPanel; }
/// <summary> /// Creates the control(s) necessary for prompting user for a new value /// </summary> /// <param name="configurationValues">The configuration values.</param> /// <param name="id"></param> /// <returns> /// The control /// </returns> public override Control EditControl( System.Collections.Generic.Dictionary<string, ConfigurationValue> configurationValues, string id ) { var picker = new SlidingDateRangePicker { ID = id }; if ( configurationValues != null && configurationValues.ContainsKey( ENABLED_SLIDING_DATE_RANGE_TYPES ) ) { var selectedDateRangeTypes = configurationValues[ENABLED_SLIDING_DATE_RANGE_TYPES].Value.SplitDelimitedValues().Select( a => a.ConvertToEnum<SlidingDateRangePicker.SlidingDateRangeType>() ); picker.EnabledSlidingDateRangeTypes = selectedDateRangeTypes.ToArray(); } if ( configurationValues != null && configurationValues.ContainsKey( ENABLED_SLIDING_DATE_RANGE_UNITS ) ) { var selectedDateRangeUnits = configurationValues[ENABLED_SLIDING_DATE_RANGE_UNITS].Value.SplitDelimitedValues().Select( a => a.ConvertToEnum<SlidingDateRangePicker.TimeUnitType>() ); picker.EnabledSlidingDateRangeUnits = selectedDateRangeUnits.ToArray(); } return picker; }
/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls( Type entityType, FilterField filterControl ) { rp = new RegistrationTemplatePicker(); rp.ID = filterControl.ID + "_rp"; rp.Label = "RegistrationTemplate(s)"; rp.CssClass = "js-group-picker"; rp.AllowMultiSelect = true; rp.Help = "Select the registration templates that you want the registrants for. Leaving this blank will not restrict results to a registration template."; filterControl.Controls.Add( rp ); cbIncludeInactiveRegistrationInstances = new RockCheckBox(); cbIncludeInactiveRegistrationInstances.ID = filterControl.ID + "_cbIncludeInactiveRegistrationInstances"; cbIncludeInactiveRegistrationInstances.Text = "Include Inactive Registration Instances"; cbIncludeInactiveRegistrationInstances.CssClass = "js-include-inactive-groups"; cbIncludeInactiveRegistrationInstances.AutoPostBack = true; filterControl.Controls.Add( cbIncludeInactiveRegistrationInstances ); PanelWidget pwAdvanced = new PanelWidget(); filterControl.Controls.Add( pwAdvanced ); pwAdvanced.ID = filterControl.ID + "_pwAttributes"; pwAdvanced.Title = "Advanced Filters"; pwAdvanced.CssClass = "advanced-panel"; SlidingDateRangePicker registeredOnDateRangePicker = new SlidingDateRangePicker(); registeredOnDateRangePicker.ID = pwAdvanced.ID + "_addedOnDateRangePicker"; registeredOnDateRangePicker.AddCssClass( "js-sliding-date-range" ); registeredOnDateRangePicker.Label = "Date Registered:"; registeredOnDateRangePicker.Help = "Select the date range that the person was registered. Leaving this blank will not restrict results to a date range."; pwAdvanced.Controls.Add( registeredOnDateRangePicker ); return new Control[4] { rp, cbIncludeInactiveRegistrationInstances, registeredOnDateRangePicker, pwAdvanced }; }
/// <summary> /// Formats the selection. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override string FormatSelection( Type entityType, string selection ) { string result = "Registrant"; string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 1 ) { var rockContext = new RockContext(); var registrationTemplateGuids = selectionValues[0].Split( ',' ).AsGuidList(); var registrationTemplates = new RegistrationTemplateService( rockContext ).GetByGuids( registrationTemplateGuids ); SlidingDateRangePicker fakeSlidingDateRangePicker = null; bool includeInactiveRegistrationInstances = false; if ( selectionValues.Length >= 2 ) { includeInactiveRegistrationInstances = selectionValues[1].AsBooleanOrNull() ?? false; if ( selectionValues.Length >= 3 ) { fakeSlidingDateRangePicker = new SlidingDateRangePicker(); // convert comma delimited to pipe fakeSlidingDateRangePicker.DelimitedValues = selectionValues[2].Replace( ',', '|' ); } } if ( registrationTemplates != null ) { result = string.Format( registrationTemplates.Count() > 0 ? "In Registration Templates: {0}" : "In a Registration", registrationTemplates.Select( a => a.Name ).ToList().AsDelimited( ", ", " or " ) ); if ( includeInactiveRegistrationInstances ) { result += ", including inactive registration instances"; } if ( fakeSlidingDateRangePicker != null ) { result += string.Format( ", registered in Date Range: {0}", SlidingDateRangePicker.FormatDelimitedValues( fakeSlidingDateRangePicker.DelimitedValues ) ); } } } return result; }
/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls( System.Web.UI.Control parentControl ) { var comparisonControl = ComparisonHelper.ComparisonControl( ComparisonType.LessThan | ComparisonType.GreaterThanOrEqualTo | ComparisonType.EqualTo ); comparisonControl.ID = parentControl.ID + "_0"; parentControl.Controls.Add( comparisonControl ); var globalAttributes = Rock.Web.Cache.GlobalAttributesCache.Read(); NumberBox numberBoxAmount = new NumberBox(); numberBoxAmount.PrependText = globalAttributes.GetValue( "CurrencySymbol" ) ?? "$"; numberBoxAmount.NumberType = ValidationDataType.Currency; numberBoxAmount.ID = parentControl.ID + "_1"; numberBoxAmount.Label = "Amount"; parentControl.Controls.Add( numberBoxAmount ); AccountPicker accountPicker = new AccountPicker(); accountPicker.AllowMultiSelect = true; accountPicker.ID = parentControl.ID + "_accountPicker"; accountPicker.AddCssClass( "js-account-picker" ); accountPicker.Label = "Accounts"; parentControl.Controls.Add( accountPicker ); SlidingDateRangePicker slidingDateRangePicker = new SlidingDateRangePicker(); slidingDateRangePicker.ID = parentControl.ID + "_slidingDateRangePicker"; slidingDateRangePicker.AddCssClass( "js-sliding-date-range" ); slidingDateRangePicker.Label = "Date Range"; slidingDateRangePicker.Help = "The date range of the transactions using the transaction date of each transaction"; slidingDateRangePicker.Required = true; parentControl.Controls.Add( slidingDateRangePicker ); RockCheckBox cbCombineGiving = new RockCheckBox(); cbCombineGiving.ID = parentControl.ID + "_cbCombineGiving"; cbCombineGiving.Label = "Combine Giving"; cbCombineGiving.CssClass = "js-combine-giving"; cbCombineGiving.Help = "Combine individuals in the same giving group when calculating totals and reporting the list of individuals."; parentControl.Controls.Add( cbCombineGiving ); var controls = new Control[5] { comparisonControl, numberBoxAmount, accountPicker, slidingDateRangePicker, cbCombineGiving }; SetSelection( controls, string.Format( "{0}||||||", ComparisonType.GreaterThanOrEqualTo.ConvertToInt().ToString() ) ); return controls; }
/// <summary> /// Formats the selection for the InGroupFilter/NotInGroupFilter based on if we are in "Not" mode /// </summary> /// <param name="selection">The selection.</param> /// <param name="not">if set to <c>true</c> [not].</param> /// <returns></returns> public virtual string GroupFilterFormatSelection( string selection, bool not ) { string result = "Group Member"; string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 2 ) { var rockContext = new RockContext(); var groupGuids = selectionValues[0].Split( ',' ).AsGuidList(); var groups = new GroupService( rockContext ).GetByGuids( groupGuids ); var groupTypeRoleGuidList = selectionValues[1].Split( new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries ).Select( a => a.AsGuid() ).ToList(); var groupTypeRoles = new GroupTypeRoleService( rockContext ).Queryable().Where( a => groupTypeRoleGuidList.Contains( a.Guid ) ).ToList(); SlidingDateRangePicker fakeSlidingDateRangePicker = null; bool includeChildGroups = false; bool includeChildGroupsPlusDescendants = false; bool includeChildGroupsIncludeSelected = false; bool includeInactiveGroups = false; if ( selectionValues.Length >= 3 ) { includeChildGroups = selectionValues[2].AsBooleanOrNull() ?? false; if ( selectionValues.Length >= 6 ) { includeChildGroupsIncludeSelected = selectionValues[4].AsBooleanOrNull() ?? false; includeChildGroupsPlusDescendants = selectionValues[5].AsBooleanOrNull() ?? false; } if ( selectionValues.Length >= 7 ) { includeInactiveGroups = selectionValues[6].AsBooleanOrNull() ?? false; } if ( selectionValues.Length >= 8 ) { fakeSlidingDateRangePicker = new SlidingDateRangePicker(); // convert comma delimited to pipe fakeSlidingDateRangePicker.DelimitedValues = selectionValues[7].Replace( ',', '|' ); } } GroupMemberStatus? groupMemberStatus = null; if ( selectionValues.Length >= 4 ) { groupMemberStatus = selectionValues[3].ConvertToEnumOrNull<GroupMemberStatus>(); } if ( groups != null ) { result = string.Format( not ? "Not in groups: {0}" : "In groups: {0}", groups.Select( a => a.Name ).ToList().AsDelimited( ", ", " or " ) ); if ( includeChildGroups ) { if ( includeChildGroupsPlusDescendants ) { result += " or descendant groups"; } else { result += " or child groups"; } if ( includeInactiveGroups ) { result += ", including inactive groups"; } if ( !includeChildGroupsIncludeSelected ) { result += ", not including selected groups"; } } if ( groupTypeRoles.Count() > 0 ) { result += string.Format( ", with role(s): {0}", groupTypeRoles.Select( a => string.Format( "{0} ({1})", a.Name, a.GroupType.Name ) ).ToList().AsDelimited( "," ) ); } if ( groupMemberStatus.HasValue ) { result += string.Format( ", with member status: {0}", groupMemberStatus.ConvertToString() ); } if ( fakeSlidingDateRangePicker != null ) { result += string.Format( ", added to group in Date Range: {0}", SlidingDateRangePicker.FormatDelimitedValues( fakeSlidingDateRangePicker.DelimitedValues ) ); } } } return result; }
/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls( Type entityType, FilterField filterControl ) { gp = new GroupPicker(); gp.ID = filterControl.ID + "_gp"; gp.Label = "Group(s)"; gp.SelectItem += gp_SelectItem; gp.CssClass = "js-group-picker"; gp.AllowMultiSelect = true; filterControl.Controls.Add( gp ); cbChildGroups = new RockCheckBox(); cbChildGroups.ID = filterControl.ID + "_cbChildsGroups"; cbChildGroups.Text = "Include Child Group(s)"; cbChildGroups.CssClass = "js-include-child-groups"; cbChildGroups.AutoPostBack = true; cbChildGroups.CheckedChanged += gp_SelectItem; filterControl.Controls.Add( cbChildGroups ); cbIncludeSelectedGroup = new RockCheckBox(); cbIncludeSelectedGroup.ID = filterControl.ID + "_cbIncludeSelectedGroup"; cbIncludeSelectedGroup.Text = "Include Selected Group(s)"; cbIncludeSelectedGroup.CssClass = "js-include-selected-groups"; cbIncludeSelectedGroup.AutoPostBack = true; cbIncludeSelectedGroup.CheckedChanged += gp_SelectItem; filterControl.Controls.Add( cbIncludeSelectedGroup ); cbChildGroupsPlusDescendants = new RockCheckBox(); cbChildGroupsPlusDescendants.ID = filterControl.ID + "_cbChildGroupsPlusDescendants"; cbChildGroupsPlusDescendants.Text = "Include All Descendants(s)"; cbChildGroupsPlusDescendants.CssClass = "js-include-child-groups-descendants"; cbChildGroupsPlusDescendants.AutoPostBack = true; cbChildGroupsPlusDescendants.CheckedChanged += gp_SelectItem; filterControl.Controls.Add( cbChildGroupsPlusDescendants ); cbIncludeInactiveGroups = new RockCheckBox(); cbIncludeInactiveGroups.ID = filterControl.ID + "_cbIncludeInactiveGroups"; cbIncludeInactiveGroups.Text = "Include Inactive Groups"; cbIncludeInactiveGroups.CssClass = "js-include-inactive-groups"; cbIncludeInactiveGroups.AutoPostBack = true; cbIncludeInactiveGroups.CheckedChanged += gp_SelectItem; filterControl.Controls.Add( cbIncludeInactiveGroups ); cblRole = new RockCheckBoxList(); cblRole.Label = "with Group Member Role(s) (optional)"; cblRole.ID = filterControl.ID + "_cblRole"; cblRole.CssClass = "js-roles"; cblRole.Visible = false; filterControl.Controls.Add( cblRole ); RockDropDownList ddlGroupMemberStatus = new RockDropDownList(); ddlGroupMemberStatus.CssClass = "js-group-member-status"; ddlGroupMemberStatus.ID = filterControl.ID + "_ddlGroupMemberStatus"; ddlGroupMemberStatus.Label = "with Group Member Status"; ddlGroupMemberStatus.Help = "Select a specific group member status to only include group members with that status. Leaving this blank will return all members."; ddlGroupMemberStatus.BindToEnum<GroupMemberStatus>( true ); ddlGroupMemberStatus.SetValue( GroupMemberStatus.Active.ConvertToInt() ); filterControl.Controls.Add( ddlGroupMemberStatus ); PanelWidget pwAdvanced = new PanelWidget(); filterControl.Controls.Add( pwAdvanced ); pwAdvanced.ID = filterControl.ID + "_pwAttributes"; pwAdvanced.Title = "Advanced Filters"; pwAdvanced.CssClass = "advanced-panel"; SlidingDateRangePicker addedOnDateRangePicker = new SlidingDateRangePicker(); addedOnDateRangePicker.ID = pwAdvanced.ID + "_addedOnDateRangePicker"; addedOnDateRangePicker.AddCssClass( "js-sliding-date-range" ); addedOnDateRangePicker.Label = "Date Added:"; addedOnDateRangePicker.Help = "Select the date range that the person was added to the group. Leaving this blank will not restrict results to a date range."; pwAdvanced.Controls.Add( addedOnDateRangePicker ); return new Control[9] { gp, cbChildGroups, cbIncludeSelectedGroup, cbChildGroupsPlusDescendants, cblRole, ddlGroupMemberStatus, cbIncludeInactiveGroups, addedOnDateRangePicker, pwAdvanced }; }
/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls( Type entityType, FilterField filterControl ) { var pGroupPicker = new GroupPicker(); pGroupPicker.AllowMultiSelect = true; pGroupPicker.ID = filterControl.ID + "_pGroupPicker"; pGroupPicker.AddCssClass( "js-group-picker" ); filterControl.Controls.Add( pGroupPicker ); var cbChildGroups = new RockCheckBox(); cbChildGroups.ID = filterControl.ID + "_cbChildGroups"; cbChildGroups.AddCssClass( "js-child-groups" ); cbChildGroups.Text = "Include Child Groups"; filterControl.Controls.Add( cbChildGroups ); var ddlIntegerCompare = ComparisonHelper.ComparisonControl( ComparisonHelper.NumericFilterComparisonTypes ); ddlIntegerCompare.Label = "Attendance Count"; ddlIntegerCompare.ID = filterControl.ID + "_ddlIntegerCompare"; ddlIntegerCompare.AddCssClass( "js-filter-compare" ); filterControl.Controls.Add( ddlIntegerCompare ); var tbAttendedCount = new RockTextBox(); tbAttendedCount.ID = filterControl.ID + "_2"; tbAttendedCount.Label = " "; // give it whitespace label so it lines up nicely tbAttendedCount.AddCssClass( "js-attended-count" ); filterControl.Controls.Add( tbAttendedCount ); var slidingDateRangePicker = new SlidingDateRangePicker(); slidingDateRangePicker.Label = "Date Range"; slidingDateRangePicker.ID = filterControl.ID + "_slidingDateRangePicker"; slidingDateRangePicker.AddCssClass( "js-sliding-date-range" ); filterControl.Controls.Add( slidingDateRangePicker ); var controls = new Control[5] { pGroupPicker, cbChildGroups, ddlIntegerCompare, tbAttendedCount, slidingDateRangePicker }; // convert pipe to comma delimited var defaultDelimitedValues = slidingDateRangePicker.DelimitedValues.Replace( "|", "," ); var defaultCount = 4; // set the default values in case this is a newly added filter SetSelection( entityType, controls, string.Format( "{0}|{1}|{2}|{3}|false", string.Empty, ComparisonType.GreaterThanOrEqualTo.ConvertToInt().ToString(), defaultCount, defaultDelimitedValues ) ); return controls; }
/// <summary> /// Formats the selection. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override string FormatSelection( Type entityType, string selection ) { string result = "Giving Amount"; string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 4 ) { ComparisonType comparisonType = selectionValues[0].ConvertToEnum<ComparisonType>( ComparisonType.GreaterThanOrEqualTo ); decimal amount = selectionValues[1].AsDecimalOrNull() ?? 0.00M; string accountNames = string.Empty; if ( selectionValues.Length >= 5 ) { var accountGuids = selectionValues[4].Split( ',' ).Select( a => a.AsGuid() ).ToList(); accountNames = new FinancialAccountService( new RockContext() ).GetByGuids( accountGuids ).Select( a => a.Name ).ToList().AsDelimited( "," ); } bool combineGiving = false; if ( selectionValues.Length >= 6 ) { combineGiving = selectionValues[5].AsBooleanOrNull() ?? false; } SlidingDateRangePicker fakeSlidingDateRangePicker = new SlidingDateRangePicker(); if ( selectionValues.Length >= 7 ) { // convert comma delimited to pipe fakeSlidingDateRangePicker.DelimitedValues = selectionValues[6].Replace( ',', '|' ); } else { // if converting from a previous version of the selection var lowerValue = selectionValues[2].AsDateTime(); var upperValue = selectionValues[3].AsDateTime(); fakeSlidingDateRangePicker.SlidingDateRangeMode = SlidingDateRangePicker.SlidingDateRangeType.DateRange; fakeSlidingDateRangePicker.SetDateRangeModeValue( new DateRange( lowerValue, upperValue ) ); } result = string.Format( "{4}Giving amount total {0} {1} {2}. Date Range: {3}", comparisonType.ConvertToString().ToLower(), amount.ToString( "C" ), !string.IsNullOrWhiteSpace( accountNames ) ? " to accounts:" + accountNames : string.Empty, SlidingDateRangePicker.FormatDelimitedValues( fakeSlidingDateRangePicker.DelimitedValues ), combineGiving ? "Combined " : string.Empty); } return result; }
/// <summary> /// Creates the child controls. /// </summary> /// <returns></returns> public override Control[] CreateChildControls( Type entityType, FilterField filterControl ) { var gtpGroupType = new GroupTypePicker(); gtpGroupType.ID = filterControl.ID + "_0"; gtpGroupType.AddCssClass( "js-group-type" ); filterControl.Controls.Add( gtpGroupType ); gtpGroupType.UseGuidAsValue = true; gtpGroupType.GroupTypes = new GroupTypeService( new RockContext() ).Queryable().OrderBy(a => a.Name).ToList(); var cbChildGroupTypes = new RockCheckBox(); cbChildGroupTypes.ID = filterControl.ID + "_cbChildGroupTypes"; cbChildGroupTypes.AddCssClass( "js-child-group-types" ); cbChildGroupTypes.Text = "Include Child Group Types(s)"; filterControl.Controls.Add( cbChildGroupTypes ); var ddlIntegerCompare = ComparisonHelper.ComparisonControl( ComparisonHelper.NumericFilterComparisonTypes ); ddlIntegerCompare.Label = "Attendance Count"; ddlIntegerCompare.ID = filterControl.ID + "_ddlIntegerCompare"; ddlIntegerCompare.AddCssClass( "js-filter-compare" ); filterControl.Controls.Add( ddlIntegerCompare ); var tbAttendedCount = new RockTextBox(); tbAttendedCount.ID = filterControl.ID + "_2"; tbAttendedCount.Label = " "; // give it whitespace label so it lines up nicely tbAttendedCount.AddCssClass( "js-attended-count" ); filterControl.Controls.Add( tbAttendedCount ); var slidingDateRangePicker = new SlidingDateRangePicker(); slidingDateRangePicker.Label = "Date Range"; slidingDateRangePicker.ID = filterControl.ID + "_slidingDateRangePicker"; slidingDateRangePicker.AddCssClass( "js-sliding-date-range" ); filterControl.Controls.Add( slidingDateRangePicker ); var controls = new Control[5] { gtpGroupType, cbChildGroupTypes, ddlIntegerCompare, tbAttendedCount, slidingDateRangePicker }; // convert pipe to comma delimited var defaultDelimitedValues = slidingDateRangePicker.DelimitedValues.Replace( "|", "," ); var defaultCount = 4; // set the default values in case this is a newly added filter SetSelection( entityType, controls, string.Format( "{0}|{1}|{2}|{3}|false", gtpGroupType.Items.Count > 0 ? gtpGroupType.Items[0].Value : "0", ComparisonType.GreaterThanOrEqualTo.ConvertToInt().ToString(), defaultCount, defaultDelimitedValues ) ); return controls; }
/// <summary> /// Gets the expression. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="serviceInstance">The service instance.</param> /// <param name="parameterExpression">The parameter expression.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override Expression GetExpression( Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection ) { string[] options = selection.Split( '|' ); if ( options.Length < 4 ) { return null; } Guid groupTypeGuid = options[0].AsGuid(); ComparisonType comparisonType = options[1].ConvertToEnum<ComparisonType>( ComparisonType.GreaterThanOrEqualTo ); int? attended = options[2].AsIntegerOrNull(); string slidingDelimitedValues; if ( options[3].AsIntegerOrNull().HasValue ) { //// selection was from when it just simply a LastXWeeks instead of Sliding Date Range // Last X Weeks was treated as "LastXWeeks * 7" days, so we have to convert it to a SlidingDateRange of Days to keep consistent behavior int lastXWeeks = options[3].AsIntegerOrNull() ?? 1; var fakeSlidingDateRangePicker = new SlidingDateRangePicker(); fakeSlidingDateRangePicker.SlidingDateRangeMode = SlidingDateRangePicker.SlidingDateRangeType.Last; fakeSlidingDateRangePicker.TimeUnit = SlidingDateRangePicker.TimeUnitType.Day; fakeSlidingDateRangePicker.NumberOfTimeUnits = lastXWeeks * 7; slidingDelimitedValues = fakeSlidingDateRangePicker.DelimitedValues; } else { slidingDelimitedValues = options[3].Replace( ',', '|' ); } var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( slidingDelimitedValues ); bool includeChildGroupTypes = options.Length >= 5 ? options[4].AsBooleanOrNull() ?? false : false; var groupTypeService = new GroupTypeService( new RockContext() ); var groupType = groupTypeService.Get( groupTypeGuid ); List<int> groupTypeIds = new List<int>(); if ( groupType != null ) { groupTypeIds.Add( groupType.Id ); if ( includeChildGroupTypes ) { var childGroupTypes = groupTypeService.GetAllAssociatedDescendents( groupType.Guid ); if ( childGroupTypes.Any() ) { groupTypeIds.AddRange( childGroupTypes.Select( a => a.Id ) ); // get rid of any duplicates groupTypeIds = groupTypeIds.Distinct().ToList(); } } } var rockContext = serviceInstance.Context as RockContext; var attendanceQry = new AttendanceService( rockContext ).Queryable().Where( a => a.DidAttend.HasValue && a.DidAttend.Value ); if ( dateRange.Start.HasValue ) { var startDate = dateRange.Start.Value; attendanceQry = attendanceQry.Where( a => a.StartDateTime >= startDate ); } if ( dateRange.End.HasValue ) { var endDate = dateRange.End.Value; attendanceQry = attendanceQry.Where( a => a.StartDateTime < endDate ); } if ( groupTypeIds.Count == 1 ) { int groupTypeId = groupTypeIds[0]; attendanceQry = attendanceQry.Where( a => a.Group.GroupTypeId == groupTypeId ); } else if ( groupTypeIds.Count > 1 ) { attendanceQry = attendanceQry.Where( a => groupTypeIds.Contains( a.Group.GroupTypeId ) ); } else { // no group type selected, so return nothing return Expression.Constant( false ); } var qry = new PersonService( rockContext ).Queryable() .Where( p => attendanceQry.Where( xx => xx.PersonAlias.PersonId == p.Id ).Count() == attended ); BinaryExpression compareEqualExpression = FilterExpressionExtractor.Extract<Rock.Model.Person>( qry, parameterExpression, "p" ) as BinaryExpression; BinaryExpression result = FilterExpressionExtractor.AlterComparisonType( comparisonType, compareEqualExpression, null ); return result; }
/// <summary> /// Formats the selection. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override string FormatSelection( Type entityType, string selection ) { string result = "First Contribution Date"; string[] selectionValues = selection.Split( '|' ); if ( selectionValues.Length >= 3 ) { SlidingDateRangePicker fakeSlidingDateRangePicker = new SlidingDateRangePicker(); if ( selectionValues.Length >= 4 ) { // convert comma delimited to pipe fakeSlidingDateRangePicker.DelimitedValues = selectionValues[3].Replace( ',', '|' ); } else { // if converting from a previous version of the selection var lowerValue = selectionValues[0].AsDateTime(); var upperValue = selectionValues[1].AsDateTime(); fakeSlidingDateRangePicker.SlidingDateRangeMode = SlidingDateRangePicker.SlidingDateRangeType.DateRange; fakeSlidingDateRangePicker.SetDateRangeModeValue( new DateRange( lowerValue, upperValue ) ); } string accountNames = string.Empty; var accountGuids = selectionValues[2].Split( ',' ).Select( a => a.AsGuid() ).ToList(); accountNames = new FinancialAccountService( new RockContext() ).GetByGuids( accountGuids ).Select( a => a.Name ).ToList().AsDelimited( "," ); result = string.Format( "First contribution date{0}. Date Range: {1}", !string.IsNullOrWhiteSpace( accountNames ) ? " to accounts:" + accountNames : string.Empty, SlidingDateRangePicker.FormatDelimitedValues( fakeSlidingDateRangePicker.DelimitedValues ) ) ; } return result; }