/// <summary> /// Validates the group member does not already exist based on GroupId, GroupRoleId, and PersonId. /// Returns false if there is a duplicate member problem. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="groupType">Type of the group.</param> /// <param name="errorMessage">The error message.</param> /// <returns></returns> private bool ValidateGroupMemberDuplicateMember(RockContext rockContext, GroupTypeCache groupType, out string errorMessage) { if (GroupService.AllowsDuplicateMembers()) { errorMessage = string.Empty; return(true); } bool isNewOrChangedGroupMember = this.IsNewOrChangedGroupMember(rockContext); // if this isn't a new group member, then we can't really do anything about a duplicate record since it already existed before editing this record, so treat it as valid if (!isNewOrChangedGroupMember) { errorMessage = string.Empty; return(true); } errorMessage = string.Empty; var groupService = new GroupService(rockContext); // If the group member record is changing (new person, role, archive status, active status) check if there are any duplicates of this Person and Role for this group (besides the current record). var duplicateGroupMembers = new GroupMemberService(rockContext).GetByGroupIdAndPersonId(this.GroupId, this.PersonId).Where(a => a.GroupRoleId == this.GroupRoleId && this.Id != a.Id); if (duplicateGroupMembers.Any()) { var person = this.Person ?? new PersonService(rockContext).GetNoTracking(this.PersonId); var groupRole = groupType.Roles.Where(a => a.Id == this.GroupRoleId).FirstOrDefault(); errorMessage = $"{person} already belongs to the {groupRole.Name.ToLower()} role for this {groupType.GroupTerm.ToLower()}, and cannot be added again with the same role"; return(false); } return(true); }
/// <summary> /// Handles the SaveClick event of the modalAddPerson control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> void modalAddPerson_SaveClick( object sender, EventArgs e ) { if ( hfActiveTab.Value == "Existing" ) { if ( ppPerson.PersonId.HasValue && !FamilyMembers.Any( m => m.Id == ppPerson.PersonId.Value ) ) { var rockContext = new RockContext(); var person = new PersonService( rockContext ).Get( ppPerson.PersonId.Value ); if ( person != null ) { var familyMember = new FamilyMember(); familyMember.SetValuesFromPerson( person ); var familyRoleIds = familyRoles.Select( r => r.Id ).ToList(); var existingFamilyRoles = new GroupMemberService( rockContext ).Queryable( "GroupRole" ) .Where( m => m.PersonId == person.Id && familyRoleIds.Contains( m.GroupRoleId ) ) .OrderBy( m => m.GroupRole.Order ) .ToList(); var existingRole = existingFamilyRoles.Select( m => m.GroupRole ).FirstOrDefault(); if ( existingRole != null ) { familyMember.RoleGuid = existingRole.Guid; familyMember.RoleName = existingRole.Name; } familyMember.ExistingFamilyMember = existingFamilyRoles.Any( r => r.GroupId == _family.Id ); familyMember.RemoveFromOtherFamilies = cbRemoveOtherFamilies.Checked; FamilyMembers.Add( familyMember ); } } } else { var familyMember = new FamilyMember(); familyMember.FirstName = tbNewPersonFirstName.Text; familyMember.NickName = tbNewPersonFirstName.Text; familyMember.LastName = tbNewPersonLastName.Text; familyMember.Gender = ddlNewPersonGender.SelectedValueAsEnum<Gender>(); familyMember.BirthDate = dpNewPersonBirthDate.SelectedDate; var role = familyRoles.Where( r => r.Id == ( rblNewPersonRole.SelectedValueAsInt() ?? 0 ) ).FirstOrDefault(); if ( role != null ) { familyMember.RoleGuid = role.Guid; familyMember.RoleName = role.Name; } FamilyMembers.Add( familyMember ); } ppPerson.Required = false; tbNewPersonFirstName.Required = false; tbNewPersonLastName.Required = false; confirmExit.Enabled = true; hfActiveTab.Value = string.Empty; modalAddPerson.Hide(); BindMembers(); }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { var rockContext = new RockContext(); var transactionIdsQry = new FinancialTransactionService( rockContext ).Queryable(); var transactionDetailService = new FinancialTransactionDetailService( rockContext ); var qry = transactionDetailService.Queryable(); var targetPerson = this.ContextEntity<Person>(); if ( targetPerson != null ) { if ( targetPerson.GivingGroupId.HasValue ) { // gives as part of giving group var groupMemberQry = new GroupMemberService( rockContext ).GetByGroupId( targetPerson.GivingGroupId.Value ); qry = qry.Where( a => groupMemberQry.Any( b => b.PersonId == a.Transaction.AuthorizedPersonAlias.PersonId ) ); } else { // gives individually qry = qry.Where( a => a.Transaction.AuthorizedPersonAlias.PersonId == targetPerson.Id ); } } var qryTransactionsDetailsByYear = qry .Where( a => a.Transaction.TransactionDateTime.HasValue ) .GroupBy( a => SqlFunctions.DatePart( "year", a.Transaction.TransactionDateTime.Value ) ); var qryAccountSummariesByYear = qryTransactionsDetailsByYear.Select( a => new { Year = a.Key, Accounts = a.GroupBy( b => b.Account ).Select( c => new { Account = c.Key, TotalAmount = c.Sum( d => d.Amount ) } ).OrderBy( e => e.Account.Name ) } ).OrderByDescending( a => a.Year ); var summaryList = qryAccountSummariesByYear.ToList(); var mergeObjects = GlobalAttributesCache.GetMergeFields( this.CurrentPerson ); var yearsMergeObjects = new List<Dictionary<string, object>>(); foreach ( var item in summaryList ) { var accountsList = new List<object>(); foreach ( var a in item.Accounts ) { var accountDictionary = new Dictionary<string, object>(); accountDictionary.Add( "Account", a.Account ); accountDictionary.Add( "TotalAmount", a.TotalAmount ); accountsList.Add( accountDictionary ); } var yearDictionary = new Dictionary<string, object>(); yearDictionary.Add( "Year", item.Year ); yearDictionary.Add( "SummaryRows", accountsList ); yearsMergeObjects.Add( yearDictionary ); } mergeObjects.Add( "Rows", yearsMergeObjects ); lLavaOutput.Text = string.Empty; if ( GetAttributeValue( "EnableDebug" ).AsBooleanOrNull().GetValueOrDefault( false ) ) { lLavaOutput.Text = mergeObjects.lavaDebugInfo( rockContext ); } string template = GetAttributeValue( "LavaTemplate" ); lLavaOutput.Text += template.ResolveMergeFields( mergeObjects ).ResolveClientIds( upnlContent.ClientID ); }
/// <summary> /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set. /// </summary> /// <param name="entityType">The type of entity in the result set.</param> /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param> /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param> /// <param name="selection">A formatted string representing the filter settings.</param> /// <returns> /// A Linq Expression that can be used to filter an IQueryable. /// </returns> /// <exception cref="System.Exception">Filter issue(s): + errorMessages.AsDelimited( ; )</exception> public override Expression GetExpression( Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection ) { var settings = new FilterSettings( selection ); var context = (RockContext)serviceInstance.Context; // Get the Location Data View that defines the set of candidates from which proximate Locations can be selected. var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent( settings.DataViewGuid, context ); // Evaluate the Data View that defines the candidate Locations. var locationService = new LocationService( context ); var locationQuery = locationService.Queryable(); if ( dataView != null ) { locationQuery = DataComponentSettingsHelper.FilterByDataView( locationQuery, dataView, locationService ); } // Get all the Family Groups that have a Location matching one of the candidate Locations. int familyGroupTypeId = GroupTypeCache.Read( SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid() ).Id; var groupLocationsQuery = new GroupLocationService( context ).Queryable() .Where( gl => gl.Group.GroupTypeId == familyGroupTypeId && locationQuery.Any( l => l.Id == gl.LocationId ) ); // If a Location Type is specified, apply the filter condition. if (settings.LocationTypeGuid.HasValue) { int groupLocationTypeId = DefinedValueCache.Read( settings.LocationTypeGuid.Value ).Id; groupLocationsQuery = groupLocationsQuery.Where( x => x.GroupLocationTypeValue.Id == groupLocationTypeId ); } // Get all of the Group Members of the qualifying Families. var groupMemberServiceQry = new GroupMemberService( context ).Queryable() .Where( gm => groupLocationsQuery.Any( gl => gl.GroupId == gm.GroupId ) ); // Get all of the People corresponding to the qualifying Group Members. var qry = new PersonService( context ).Queryable() .Where( p => groupMemberServiceQry.Any( gm => gm.PersonId == p.Id ) ); // Retrieve the Filter Expression. var extractedFilterExpression = FilterExpressionExtractor.Extract<Model.Person>( qry, parameterExpression, "p" ); return extractedFilterExpression; }
/// <summary> /// Job that will run quick SQL queries on a schedule. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute( IJobExecutionContext context ) { JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? entryWorkflowType = dataMap.GetString( "EraEntryWorkflow" ).AsGuidOrNull(); Guid? exitWorkflowType = dataMap.GetString( "EraExitWorkflow" ).AsGuidOrNull(); bool updateVisitDates = dataMap.GetBooleanValue( "SetVisitDates" ); var groupTypeList = dataMap.GetString( "GroupTypes" ); // configuration // // giving int exitGivingCount = 1; // attendance int exitAttendanceCountShort = 1; int exitAttendanceCountLong = 8; // get era dataset from stored proc var resultContext = new RockContext(); var eraAttribute = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_CURRENTLY_AN_ERA.AsGuid() ); var eraStartAttribute = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_START_DATE.AsGuid() ); var eraEndAttribute = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_END_DATE.AsGuid() ); resultContext.Database.CommandTimeout = 3600; var results = resultContext.Database.SqlQuery<EraResult>( "spCrm_FamilyAnalyticsEraDataset" ).ToList(); int personEntityTypeId = EntityTypeCache.Read( "Rock.Model.Person" ).Id; int attributeEntityTypeId = EntityTypeCache.Read( "Rock.Model.Attribute" ).Id; int eraAttributeId = AttributeCache.Read( SystemGuid.Attribute.PERSON_ERA_CURRENTLY_AN_ERA.AsGuid() ).Id; int personAnalyticsCategoryId = CategoryCache.Read( SystemGuid.Category.HISTORY_PERSON_ANALYTICS.AsGuid() ).Id; foreach (var result in results ) { // create new rock context for each family (https://weblog.west-wind.com/posts/2014/Dec/21/Gotcha-Entity-Framework-gets-slow-in-long-Iteration-Loops) RockContext updateContext = new RockContext(); var attributeValueService = new AttributeValueService( updateContext ); var historyService = new HistoryService( updateContext ); // if era ensure it still meets requirements if ( result.IsEra ) { if (result.ExitGiftCountDuration < exitGivingCount && result.ExitAttendanceCountDurationShort < exitAttendanceCountShort && result.ExitAttendanceCountDurationLong < exitAttendanceCountLong ) { // exit era (delete attribute value from each person in family) var family = new GroupService( updateContext ).Queryable( "Members, Members.Person" ).AsNoTracking().Where( m => m.Id == result.FamilyId ).FirstOrDefault(); if ( family != null ) { foreach ( var person in family.Members.Select( m => m.Person ) ) { // remove the era flag var eraAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraAttribute.Id && v.EntityId == person.Id ).FirstOrDefault(); if ( eraAttributeValue != null ) { attributeValueService.Delete( eraAttributeValue ); } // set end date var eraEndAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraEndAttribute.Id && v.EntityId == person.Id ).FirstOrDefault(); if ( eraEndAttributeValue == null ) { eraEndAttributeValue = new AttributeValue(); eraEndAttributeValue.EntityId = person.Id; eraEndAttributeValue.AttributeId = eraEndAttribute.Id; attributeValueService.Add( eraEndAttributeValue ); } eraEndAttributeValue.Value = RockDateTime.Now.ToString(); // add a history record if ( personAnalyticsCategoryId != 0 && personEntityTypeId != 0 && attributeEntityTypeId != 0 && eraAttributeId != 0 ) { History historyRecord = new History(); historyService.Add( historyRecord ); historyRecord.EntityTypeId = personEntityTypeId; historyRecord.EntityId = person.Id; historyRecord.CreatedDateTime = RockDateTime.Now; historyRecord.CreatedByPersonAliasId = person.PrimaryAliasId; historyRecord.Caption = "eRA"; historyRecord.Summary = "Exited eRA Status"; historyRecord.Verb = "EXITED"; historyRecord.RelatedEntityTypeId = attributeEntityTypeId; historyRecord.RelatedEntityId = eraAttributeId; historyRecord.CategoryId = personAnalyticsCategoryId; } updateContext.SaveChanges(); } // launch exit workflow if ( exitWorkflowType.HasValue ) { LaunchWorkflow( exitWorkflowType.Value, family ); } } } } else { // entered era var family = new GroupService( updateContext ).Queryable( "Members" ).AsNoTracking().Where( m => m.Id == result.FamilyId ).FirstOrDefault(); if ( family != null ) { foreach ( var person in family.Members.Select( m => m.Person ) ) { // set era attribute to true var eraAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraAttribute.Id && v.EntityId == person.Id ).FirstOrDefault(); if ( eraAttributeValue == null ) { eraAttributeValue = new AttributeValue(); eraAttributeValue.EntityId = person.Id; eraAttributeValue.AttributeId = eraAttribute.Id; attributeValueService.Add( eraAttributeValue ); } eraAttributeValue.Value = bool.TrueString; // add start date var eraStartAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraStartAttribute.Id && v.EntityId == person.Id ).FirstOrDefault(); if (eraStartAttributeValue == null ) { eraStartAttributeValue = new AttributeValue(); eraStartAttributeValue.EntityId = person.Id; eraStartAttributeValue.AttributeId = eraStartAttribute.Id; attributeValueService.Add( eraStartAttributeValue ); } eraStartAttributeValue.Value = RockDateTime.Now.ToString(); // delete end date if it exists var eraEndAttributeValue = attributeValueService.Queryable().Where( v => v.AttributeId == eraEndAttribute.Id && v.EntityId == person.Id ).FirstOrDefault(); if ( eraEndAttributeValue != null ) { attributeValueService.Delete( eraEndAttributeValue ); } // add a history record if ( personAnalyticsCategoryId != 0 && personEntityTypeId != 0 && attributeEntityTypeId != 0 && eraAttributeId != 0 ) { History historyRecord = new History(); historyService.Add( historyRecord ); historyRecord.EntityTypeId = personEntityTypeId; historyRecord.EntityId = person.Id; historyRecord.CreatedDateTime = RockDateTime.Now; historyRecord.CreatedByPersonAliasId = person.PrimaryAliasId; historyRecord.Caption = "eRA"; historyRecord.Summary = "Entered eRA Status"; historyRecord.Verb = "ENTERED"; historyRecord.RelatedEntityTypeId = attributeEntityTypeId; historyRecord.RelatedEntityId = eraAttributeId; historyRecord.CategoryId = personAnalyticsCategoryId; } updateContext.SaveChanges(); } // launch entry workflow if ( entryWorkflowType.HasValue ) { LaunchWorkflow( entryWorkflowType.Value, family ); } } } // update stats } // load giving attributes resultContext.Database.ExecuteSqlCommand( "spCrm_FamilyAnalyticsGiving" ); // load attendance attributes resultContext.Database.ExecuteSqlCommand( "spCrm_FamilyAnalyticsAttendance" ); // process history for group types if (!string.IsNullOrWhiteSpace( groupTypeList ) ) { string[] groupTypeGuids = groupTypeList.Split( ',' ); var inactiveRecordValue = DefinedValueCache.Read( SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ); var groupTypeEntityTypeId = EntityTypeCache.Read( "Rock.Model.GroupType" ).Id; foreach ( var groupTypeGuid in groupTypeGuids ) { var groupType = GroupTypeCache.Read( groupTypeGuid.AsGuid() ); if ( groupType != null ) { // if the person is in a group of that type and the last history record for that group type isn't START write a start RockContext rockContext = new RockContext(); // get history for this group type var historyRecords = new HistoryService( rockContext ).Queryable() .Where( h => h.EntityTypeId == personEntityTypeId && h.RelatedEntityTypeId == groupTypeEntityTypeId && h.RelatedEntityId == groupType.Id ) .GroupBy( h => h.EntityId ) .Select( g => g.OrderByDescending( h => h.CreatedDateTime ).Select( h => new { h.EntityId, h.Verb } ).FirstOrDefault() ) .ToList(); // get group member information var groupMemberInfo = new GroupMemberService( rockContext ).Queryable() .Where( m => m.Group.GroupTypeId == groupType.Id && m.GroupMemberStatus == GroupMemberStatus.Active && m.Group.IsActive //&& m.Person.RecordStatusValueId != inactiveRecordValue.Id ) .GroupBy( m => m.PersonId ) .Select( g => g.OrderBy( m => m.CreatedDateTime ).Select( m => new { m.PersonId, m.CreatedDateTime, PersonAliasId = m.Person.Aliases.Select( p => p.Id ).FirstOrDefault() } ).FirstOrDefault() ) .ToList(); var needsStartDate = groupMemberInfo.Where( m => !historyRecords.Any( h => h.EntityId == m.PersonId && h.Verb == "STARTED" ) ); foreach ( var startItem in needsStartDate ) { using ( RockContext updateContext = new RockContext() ) { var historyService = new HistoryService( updateContext ); History history = new History(); historyService.Add( history ); history.EntityTypeId = personEntityTypeId; history.EntityId = startItem.PersonId; history.RelatedEntityTypeId = groupTypeEntityTypeId; history.RelatedEntityId = groupType.Id; history.Caption = groupType.Name; history.Summary = "Started Membership in Group Of Type"; history.Verb = "STARTED"; history.CreatedDateTime = startItem.CreatedDateTime; history.CreatedByPersonAliasId = startItem.PersonAliasId; history.CategoryId = personAnalyticsCategoryId; updateContext.SaveChanges(); } } var needsStoppedDate = historyRecords.Where( h => h.Verb == "STARTED" && !groupMemberInfo.Any( m => m.PersonId == h.EntityId ) ); foreach ( var stopItem in needsStoppedDate ) { using ( RockContext updateContext = new RockContext() ) { var person = new PersonService( updateContext ).Get( stopItem.EntityId ); if ( person != null ) { var historyService = new HistoryService( updateContext ); History history = new History(); historyService.Add( history ); history.EntityTypeId = personEntityTypeId; history.EntityId = person.Id; history.RelatedEntityTypeId = groupTypeEntityTypeId; history.RelatedEntityId = groupType.Id; history.Caption = groupType.Name; history.Summary = "Stopped Membership in Group Of Type"; history.Verb = "STOPPED"; history.CreatedDateTime = RockDateTime.Now; history.CreatedByPersonAliasId = person.PrimaryAliasId; history.CategoryId = personAnalyticsCategoryId; updateContext.SaveChanges(); } } } } } } // process visit dates if ( updateVisitDates ) { resultContext.Database.ExecuteSqlCommand( "spCrm_FamilyAnalyticsUpdateVisitDates" ); } }
/// <summary> /// Handles the SaveClick event of the modalAddPerson control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> void modalAddPerson_SaveClick( object sender, EventArgs e ) { if ( hfActiveTab.Value == "Existing" ) { if ( ppPerson.PersonId.HasValue ) { var existingfamilyMember = FamilyMembers.Where( m => m.Id == ppPerson.PersonId.Value ).FirstOrDefault(); if ( existingfamilyMember != null ) { existingfamilyMember.Removed = false; } else { var rockContext = new RockContext(); var person = new PersonService( rockContext ).Get( ppPerson.PersonId.Value ); if ( person != null ) { var familyMember = new FamilyMember(); familyMember.SetValuesFromPerson( person ); var familyRoleIds = familyRoles.Select( r => r.Id ).ToList(); var existingFamilyRoles = new GroupMemberService( rockContext ).Queryable( "GroupRole" ) .Where( m => m.PersonId == person.Id && familyRoleIds.Contains( m.GroupRoleId ) ) .OrderBy( m => m.GroupRole.Order ) .ToList(); var existingRole = existingFamilyRoles.Select( m => m.GroupRole ).FirstOrDefault(); if ( existingRole != null ) { familyMember.RoleGuid = existingRole.Guid; familyMember.RoleName = existingRole.Name; } familyMember.ExistingFamilyMember = existingFamilyRoles.Any( r => r.GroupId == _family.Id ); familyMember.RemoveFromOtherFamilies = cbRemoveOtherFamilies.Checked; FamilyMembers.Add( familyMember ); } } } } else { var familyMember = new FamilyMember(); familyMember.TitleValueId = ddlNewPersonTitle.SelectedValueAsId(); familyMember.FirstName = tbNewPersonFirstName.Text; familyMember.NickName = tbNewPersonFirstName.Text; familyMember.LastName = tbNewPersonLastName.Text; familyMember.SuffixValueId = ddlNewPersonSuffix.SelectedValueAsId(); familyMember.Gender = rblNewPersonGender.SelectedValueAsEnum<Gender>(); familyMember.MaritalStatusValueId = ddlNewPersonMaritalStatus.SelectedValueAsInt(); DateTime? birthdate = dpNewPersonBirthDate.SelectedDate; if ( birthdate.HasValue ) { // If setting a future birthdate, subtract a century until birthdate is not greater than today. var today = RockDateTime.Today; while ( birthdate.Value.CompareTo( today ) > 0 ) { birthdate = birthdate.Value.AddYears( -100 ); } } familyMember.BirthDate = birthdate; familyMember.GradeOffset = ddlGradePicker.SelectedValueAsInt(); familyMember.ConnectionStatusValueId = ddlNewPersonConnectionStatus.SelectedValueAsId(); var role = familyRoles.Where( r => r.Id == ( rblNewPersonRole.SelectedValueAsInt() ?? 0 ) ).FirstOrDefault(); if ( role != null ) { familyMember.RoleGuid = role.Guid; familyMember.RoleName = role.Name; } FamilyMembers.Add( familyMember ); } ppPerson.Required = false; tbNewPersonFirstName.Required = false; tbNewPersonLastName.Required = false; rblNewPersonRole.Required = false; rblNewPersonGender.Required = false; ddlNewPersonConnectionStatus.Required = false; confirmExit.Enabled = true; hfActiveTab.Value = string.Empty; modalAddPerson.Hide(); BindMembers(); }
/// <summary> /// Binds the default connectors. /// </summary> private void BindDefaultConnectors() { var defaultConnectors = new List<DefaultConnector>(); foreach (var campusId in cblSelectedItemsAsInt( cblCampus) ) { var connectorGroups = ConnectorGroupsState .Where( g => !g.CampusId.HasValue || g.CampusId.Value == campusId ) .ToList(); if ( connectorGroups.Any() ) { var groupIds = connectorGroups.Select( g => g.GroupId ); using ( var rockContext = new RockContext() ) { var people = new GroupMemberService( rockContext ) .Queryable().AsNoTracking() .Where( m => groupIds.Contains( m.GroupId ) && m.GroupMemberStatus == GroupMemberStatus.Active ) .Select( m => m.Person ) .ToList(); if ( people.Any() ) { var defaultConnector = new DefaultConnector(); var campus = CampusCache.Read( campusId ); defaultConnector.CampusId = campus.Id; defaultConnector.CampusName = campus.Name; defaultConnector.PersonAliasId = DefaultConnectors.ContainsKey( campusId ) ? DefaultConnectors[campusId] : (int?)null; defaultConnector.Options = new Dictionary<int, string>(); foreach( var person in people ) { int? personAliasId = person.PrimaryAliasId; if( personAliasId.HasValue ) { defaultConnector.Options.AddOrIgnore(personAliasId.Value, person.FullName); } } defaultConnectors.Add(defaultConnector); } } } } lvDefaultConnectors.DataSource = defaultConnectors; lvDefaultConnectors.DataBind(); }
/// <summary> /// Shows the view. /// </summary> private void ShowForm() { lReceipt.Visible = false; pnlAddPledge.Visible = true; if ( CurrentPerson != null ) { lName.Text = CurrentPerson.FullName; lName.Visible = true; tbFirstName.Visible = false; tbLastName.Visible = false; tbEmail.Visible = false; using ( var rockContext = new RockContext() ) { Guid? groupTypeGuid = GetAttributeValue( "SelectGroupType" ).AsGuidOrNull(); if ( groupTypeGuid.HasValue ) { var groups = new GroupMemberService( rockContext ) .Queryable().AsNoTracking() .Where( m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.PersonId == CurrentPerson.Id && m.GroupMemberStatus == GroupMemberStatus.Active && m.Group.IsActive ) .Select( m => new { m.GroupId, Name = m.Group.Name, GroupTypeName = m.Group.GroupType.Name } ) .ToList() .Distinct() .OrderBy( g => g.Name ) .ToList(); if ( groups.Any() ) { ddlGroup.Label = "For " + groups.First().GroupTypeName; ddlGroup.DataSource = groups; ddlGroup.DataBind(); ddlGroup.Visible = true; } else { ddlGroup.Visible = false; } } else { ddlGroup.Visible = false; } } } else { lName.Visible = false; ddlGroup.Visible = false; tbFirstName.Visible = true; tbLastName.Visible = true; tbEmail.Visible = true; tbFirstName.Text = string.Empty; tbLastName.Text = string.Empty; tbEmail.Text = string.Empty; } // Warn if Financial Account is not specified (must be set up by administrator) var financialAccount = new FinancialAccountService( new RockContext() ).Get( GetAttributeValue( "Account" ).AsGuid() ); if ( financialAccount == null ) { nbWarningMessage.Text = "Warning: No Account is specified for this pledge. Please contact the administrator."; nbWarningMessage.Visible = true; } else { nbWarningMessage.Visible = false; } drpDateRange.DelimitedValues = GetAttributeValue( "PledgeDateRange" ); // only show the date range picker if the block setting for date range isn't fully specified drpDateRange.Visible = drpDateRange.LowerValue == null || drpDateRange.UpperValue == null; ddlFrequency.Items.Clear(); var frequencies = DefinedTypeCache.Read( Rock.SystemGuid.DefinedType.FINANCIAL_FREQUENCY.AsGuid() ).DefinedValues.OrderBy( a => a.Order ).ThenBy( a => a.Value ); foreach ( var frequency in frequencies ) { ddlFrequency.Items.Add( new ListItem( frequency.Value, frequency.Id.ToString() ) ); } ddlFrequency.Visible = GetAttributeValue( "ShowPledgeFrequency" ).AsBooleanOrNull() ?? false; ddlFrequency.SelectedValue = null; // if Frequency is Visible, require it if RequirePledgeFrequency ddlFrequency.Required = ddlFrequency.Visible && ( GetAttributeValue( "RequirePledgeFrequency" ).AsBooleanOrNull() ?? false ); string saveButtonText = GetAttributeValue( "SaveButtonText" ); if ( !string.IsNullOrWhiteSpace( saveButtonText ) ) { btnSave.Text = saveButtonText; } else { btnSave.Text = "Save"; } lNote.Text = GetAttributeValue( "NoteMessage" ); }
/// <summary> /// Notifies the admins. /// </summary> /// <param name="subject">The subject.</param> /// <param name="message">The message.</param> /// <param name="appRoot">The application root.</param> /// <param name="themeRoot">The theme root.</param> /// <exception cref="System.Exception"> /// Error sending System Email: Could not read Email Medium Entity Type /// </exception> public static void NotifyAdmins( string subject, string message, string appRoot = "", string themeRoot = "" ) { try { List<string> recipients = null; Guid adminGroup = Rock.SystemGuid.Group.GROUP_ADMINISTRATORS.AsGuid(); using ( var rockContext = new RockContext() ) { recipients = new GroupMemberService( rockContext ).Queryable() .Where( m => m.Group.Guid.Equals( adminGroup ) && m.GroupMemberStatus == GroupMemberStatus.Active && m.Person.Email != null && m.Person.Email != "" ) .Select( m => m.Person.Email ) .ToList(); } if ( recipients != null && recipients.Any() ) { var mediumEntity = EntityTypeCache.Read( Rock.SystemGuid.EntityType.COMMUNICATION_MEDIUM_EMAIL.AsGuid() ); if ( mediumEntity != null ) { var medium = MediumContainer.GetComponent( mediumEntity.Name ); if ( medium != null && medium.IsActive ) { var transport = medium.Transport; if ( transport != null && transport.IsActive ) { try { transport.Send( recipients, null, subject, message, appRoot, themeRoot ); } catch ( Exception ex1 ) { throw new Exception( string.Format( "Error sending System Email ({0}).", subject ), ex1 ); } } else { throw new Exception( string.Format( "Error sending System Email: The '{0}' medium does not have a valid transport, or the transport is not active.", mediumEntity.FriendlyName ) ); } } else { throw new Exception( string.Format( "Error sending System Email: The '{0}' medium does not exist, or is not active (type: {1}).", mediumEntity.FriendlyName, mediumEntity.Name ) ); } } else { throw new Exception( "Error sending System Email: Could not read Email Medium Entity Type" ); } } } catch ( Exception ex ) { ExceptionLogService.LogException( ex, HttpContext.Current ); } }
/// <summary> /// Binds the group members grid. /// </summary> protected void BindGroupMembersGrid( bool isExporting = false ) { if ( _group != null ) { pnlGroupMembers.Visible = true; lHeading.Text = string.Format( "{0} {1}", _group.GroupType.GroupTerm, _group.GroupType.GroupMemberTerm.Pluralize() ); if ( _group.GroupType.Roles.Any() ) { nbRoleWarning.Visible = false; rFilter.Visible = true; gGroupMembers.Visible = true; var rockContext = new RockContext(); if ( _group != null && _group.RequiredSignatureDocumentTemplateId.HasValue ) { Signers = new SignatureDocumentService( rockContext ) .Queryable().AsNoTracking() .Where( d => d.SignatureDocumentTemplateId == _group.RequiredSignatureDocumentTemplateId.Value && d.Status == SignatureDocumentStatus.Signed && d.BinaryFileId.HasValue && d.AppliesToPersonAlias != null ) .OrderByDescending( d => d.LastStatusDate ) .Select( d => d.AppliesToPersonAlias.PersonId ) .ToList(); } GroupMemberService groupMemberService = new GroupMemberService( rockContext ); var qry = groupMemberService.Queryable( "Person,GroupRole", true ).AsNoTracking() .Where( m => m.GroupId == _group.Id ); // Filter by First Name string firstName = tbFirstName.Text; if ( !string.IsNullOrWhiteSpace( firstName ) ) { qry = qry.Where( m => m.Person.FirstName.StartsWith( firstName ) || m.Person.NickName.StartsWith( firstName ) ); } // Filter by Last Name string lastName = tbLastName.Text; if ( !string.IsNullOrWhiteSpace( lastName ) ) { qry = qry.Where( m => m.Person.LastName.StartsWith( lastName ) ); } // Filter by role var validGroupTypeRoles = _group.GroupType.Roles.Select( r => r.Id ).ToList(); var roles = new List<int>(); foreach ( var roleId in cblRole.SelectedValues.AsIntegerList() ) { if ( validGroupTypeRoles.Contains( roleId ) ) { roles.Add( roleId ); } } if ( roles.Any() ) { qry = qry.Where( m => roles.Contains( m.GroupRoleId ) ); } // Filter by Group Member Status var statuses = new List<GroupMemberStatus>(); foreach ( string status in cblGroupMemberStatus.SelectedValues ) { if ( !string.IsNullOrWhiteSpace( status ) ) { statuses.Add( status.ConvertToEnum<GroupMemberStatus>() ); } } if ( statuses.Any() ) { qry = qry.Where( m => statuses.Contains( m.GroupMemberStatus ) ); } var genders = new List<Gender>(); foreach ( var item in cblGenderFilter.SelectedValues ) { var gender = item.ConvertToEnum<Gender>(); genders.Add( gender ); } if ( genders.Any() ) { qry = qry.Where( m => genders.Contains( m.Person.Gender ) ); } // Filter by Campus if ( cpCampusFilter.SelectedCampusId.HasValue ) { Guid familyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); int campusId = cpCampusFilter.SelectedCampusId.Value; var qryFamilyMembersForCampus = new GroupMemberService( rockContext ).Queryable().Where( a => a.Group.GroupType.Guid == familyGuid && a.Group.CampusId == campusId ); qry = qry.Where( a => qryFamilyMembersForCampus.Any( f => f.PersonId == a.PersonId ) ); } // Filter by signed documents if ( Signers != null ) { if ( ddlSignedDocument.SelectedValue.AsBooleanOrNull() == true ) { qry = qry.Where( m => Signers.Contains( m.PersonId ) ); } else if ( ddlSignedDocument.SelectedValue.AsBooleanOrNull() == false ) { qry = qry.Where( m => !Signers.Contains( m.PersonId ) ); } } // Filter query by any configured attribute filters if ( AvailableAttributes != null && AvailableAttributes.Any() ) { var attributeValueService = new AttributeValueService( rockContext ); var parameterExpression = attributeValueService.ParameterExpression; foreach ( var attribute in AvailableAttributes ) { var filterControl = phAttributeFilters.FindControl( "filter_" + attribute.Id.ToString() ); if ( filterControl != null ) { var filterValues = attribute.FieldType.Field.GetFilterValues( filterControl, attribute.QualifierValues, Rock.Reporting.FilterMode.SimpleFilter ); var expression = attribute.FieldType.Field.AttributeFilterExpression( attribute.QualifierValues, filterValues, parameterExpression ); if ( expression != null ) { var attributeValues = attributeValueService .Queryable() .Where( v => v.Attribute.Id == attribute.Id ); attributeValues = attributeValues.Where( parameterExpression, expression, null ); qry = qry.Where( w => attributeValues.Select( v => v.EntityId ).Contains( w.Id ) ); } } } } _inactiveStatus = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ); SortProperty sortProperty = gGroupMembers.SortProperty; bool hasGroupRequirements = new GroupRequirementService( rockContext ).Queryable().Where( a => a.GroupId == _group.Id ).Any(); // If there are group requirements that that member doesn't meet, show an icon in the grid bool includeWarnings = false; var groupMemberIdsThatLackGroupRequirements = new GroupService( rockContext ).GroupMembersNotMeetingRequirements( _group.Id, includeWarnings ).Select( a => a.Key.Id ); List<GroupMember> groupMembersList = null; if ( sortProperty != null && sortProperty.Property != "FirstAttended" && sortProperty.Property != "LastAttended" ) { groupMembersList = qry.Sort( sortProperty ).ToList(); } else { groupMembersList = qry.OrderBy( a => a.GroupRole.Order ).ThenBy( a => a.Person.LastName ).ThenBy( a => a.Person.FirstName ).ToList(); } // If there is a required signed document that member has not signed, show an icon in the grid var personIdsThatHaventSigned = new List<int>(); if ( Signers != null ) { var memberPersonIds = groupMembersList.Select( m => m.PersonId ).ToList(); personIdsThatHaventSigned = memberPersonIds.Where( i => !Signers.Contains( i ) ).ToList(); } // Since we're not binding to actual group member list, but are using AttributeField columns, // we need to save the group members into the grid's object list gGroupMembers.ObjectList = new Dictionary<string, object>(); groupMembersList.ForEach( m => gGroupMembers.ObjectList.Add( m.Id.ToString(), m ) ); gGroupMembers.EntityTypeId = EntityTypeCache.Read( Rock.SystemGuid.EntityType.GROUP_MEMBER.AsGuid() ).Id; var homePhoneType = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME ); var cellPhoneType = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE ); // If exporting to Excel, the selectAll option will be true, and home location should be calculated var homeLocations = new Dictionary<int, Location>(); if ( isExporting ) { foreach ( var m in groupMembersList ) { homeLocations.Add( m.Id, m.Person.GetHomeLocation( rockContext ) ); } } var groupMemberIds = groupMembersList.Select( m => m.Id ).ToList(); // Get all the group members with any associated registrations _groupMembersWithRegistrations = new RegistrationRegistrantService( rockContext ) .Queryable().AsNoTracking() .Where( r => r.Registration != null && r.Registration.RegistrationInstance != null && r.GroupMemberId.HasValue && groupMemberIds.Contains( r.GroupMemberId.Value ) ) .ToList() .GroupBy( r => r.GroupMemberId.Value ) .Select( g => new { GroupMemberId = g.Key, Registrations = g.ToList() .Select( r => new { Id = r.Registration.Id, Name = r.Registration.RegistrationInstance.Name } ).Distinct() .ToDictionary( r => r.Id, r => r.Name ) } ) .ToDictionary( r => r.GroupMemberId, r => r.Registrations ); var registrationField = gGroupMembers.ColumnsOfType<RockTemplateFieldUnselected>().FirstOrDefault(); if ( registrationField != null ) { registrationField.Visible = _groupMembersWithRegistrations.Any(); } var connectionStatusField = gGroupMembers.ColumnsOfType<DefinedValueField>().FirstOrDefault( a => a.DataField == "ConnectionStatusValueId" ); if ( connectionStatusField != null ) { connectionStatusField.Visible = _group.GroupType.ShowConnectionStatus; } string photoFormat = "<div class=\"photo-icon photo-round photo-round-xs pull-left margin-r-sm js-person-popover\" personid=\"{0}\" data-original=\"{1}&w=50\" style=\"background-image: url( '{2}' ); background-size: cover; background-repeat: no-repeat;\"></div>"; var attendanceFirstLast = new Dictionary<int, DateRange>(); bool showAttendance = GetAttributeValue( "ShowAttendance" ).AsBoolean() && _group.GroupType.TakesAttendance; gGroupMembers.ColumnsOfType<DateField>().First( a => a.DataField == "FirstAttended" ).Visible = showAttendance; gGroupMembers.ColumnsOfType<DateField>().First( a => a.DataField == "LastAttended" ).Visible = showAttendance; if ( showAttendance ) { foreach ( var attendance in new AttendanceService( rockContext ) .Queryable().AsNoTracking() .Where( a => a.GroupId.HasValue && a.GroupId.Value == _group.Id && a.DidAttend.HasValue && a.DidAttend.Value ) .GroupBy( a => a.PersonAlias.PersonId ) .Select( g => new { PersonId = g.Key, FirstAttended = g.Min( a => a.StartDateTime ), LastAttended = g.Max( a => a.StartDateTime ) } ) .ToList() ) { attendanceFirstLast.Add( attendance.PersonId, new DateRange( attendance.FirstAttended, attendance.LastAttended ) ); } } var dataSource = groupMembersList.Select( m => new { m.Id, m.Guid, m.PersonId, m.Person.NickName, m.Person.LastName, Name = ( isExporting ? m.Person.LastName + ", " + m.Person.NickName : string.Format( photoFormat, m.PersonId, m.Person.PhotoUrl, ResolveUrl( "~/Assets/Images/person-no-photo-male.svg" ) ) + m.Person.NickName + " " + m.Person.LastName + ( ( hasGroupRequirements && groupMemberIdsThatLackGroupRequirements.Contains( m.Id ) ) ? " <i class='fa fa-exclamation-triangle text-warning'></i>" : string.Empty ) + ( !string.IsNullOrEmpty( m.Note ) ? " <i class='fa fa-file-text-o text-info'></i>" : string.Empty ) + ((personIdsThatHaventSigned.Contains( m.PersonId )) ? " <i class='fa fa-pencil-square-o text-danger'></i>" : string.Empty)), m.Person.BirthDate, m.Person.Age, m.Person.ConnectionStatusValueId, m.DateTimeAdded, FirstAttended = attendanceFirstLast.Where( a => a.Key == m.PersonId ).Select( a => a.Value.Start ).FirstOrDefault(), LastAttended = attendanceFirstLast.Where( a => a.Key == m.PersonId ).Select( a => a.Value.End ).FirstOrDefault(), Email = m.Person.Email, HomePhone = isExporting && homePhoneType != null ? m.Person.PhoneNumbers .Where( p => p.NumberTypeValueId.HasValue && p.NumberTypeValueId.Value == homePhoneType.Id ) .Select( p => p.NumberFormatted ) .FirstOrDefault() : string.Empty, CellPhone = isExporting && cellPhoneType != null ? m.Person.PhoneNumbers .Where( p => p.NumberTypeValueId.HasValue && p.NumberTypeValueId.Value == cellPhoneType.Id ) .Select( p => p.NumberFormatted ) .FirstOrDefault() : string.Empty, HomeAddress = homeLocations.ContainsKey( m.Id ) && homeLocations[m.Id] != null ? homeLocations[m.Id].FormattedAddress : string.Empty, Latitude = homeLocations.ContainsKey( m.Id ) && homeLocations[m.Id] != null ? homeLocations[m.Id].Latitude : (double?)null, Longitude = homeLocations.ContainsKey( m.Id ) && homeLocations[m.Id] != null ? homeLocations[m.Id].Longitude : (double?)null, GroupRole = m.GroupRole.Name, m.GroupMemberStatus, RecordStatusValueId = m.Person.RecordStatusValueId, IsDeceased = m.Person.IsDeceased } ).ToList(); if ( sortProperty != null ) { if ( sortProperty.Property == "FirstAttended" ) { if ( sortProperty.Direction == SortDirection.Descending ) { dataSource = dataSource.OrderByDescending( a => a.FirstAttended ?? DateTime.MinValue ).ToList(); } else { dataSource = dataSource.OrderBy( a => a.FirstAttended ?? DateTime.MinValue ).ToList(); } } if ( sortProperty.Property == "LastAttended" ) { if ( sortProperty.Direction == SortDirection.Descending ) { dataSource = dataSource.OrderByDescending( a => a.LastAttended ?? DateTime.MinValue ).ToList(); } else { dataSource = dataSource.OrderBy( a => a.LastAttended ?? DateTime.MinValue ).ToList(); } } } gGroupMembers.DataSource = dataSource; gGroupMembers.DataBind(); } else { nbRoleWarning.Text = string.Format( "{0} cannot be added to this {1} because the '{2}' group type does not have any roles defined.", _group.GroupType.GroupMemberTerm.Pluralize(), _group.GroupType.GroupTerm, _group.GroupType.Name ); nbRoleWarning.Visible = true; rFilter.Visible = false; gGroupMembers.Visible = false; } } else { pnlGroupMembers.Visible = false; } }
private void LoadGroups( int? currentGroupId ) { ddlGroup.Items.Clear(); int? personId = ppPerson.PersonId; Guid? groupTypeGuid = GetAttributeValue( "SelectGroupType" ).AsGuidOrNull(); if ( personId.HasValue && groupTypeGuid.HasValue ) { using ( var rockContext = new RockContext() ) { var groups = new GroupMemberService( rockContext ) .Queryable().AsNoTracking() .Where( m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.PersonId == personId.Value && m.GroupMemberStatus == GroupMemberStatus.Active && m.Group.IsActive ) .Select( m => new { m.GroupId, Name = m.Group.Name } ) .ToList() .Distinct() .OrderBy( g => g.Name ) .ToList(); if ( groups.Any() ) { ddlGroup.DataSource = groups; ddlGroup.DataBind(); ddlGroup.Items.Insert(0, new ListItem() ); ddlGroup.SetValue( currentGroupId ); } } } }
/// <summary> /// Gets the expression. /// </summary> /// <param name="context">The context.</param> /// <param name="entityIdProperty">The entity identifier property.</param> /// <param name="selection">The selection.</param> /// <returns></returns> public override Expression GetExpression( RockContext context, MemberExpression entityIdProperty, string selection ) { var settings = new GroupParticipationSelectSettings( selection ); // // Define Candidate Groups. // // Get the Group Data View that defines the set of candidates from which matching Groups can be selected. var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent( settings.DataViewGuid, context ); // Evaluate the Data View that defines the candidate Groups. var groupService = new GroupService( context ); var groupQuery = groupService.Queryable(); if (dataView != null) { groupQuery = DataComponentSettingsHelper.FilterByDataView( groupQuery, dataView, groupService ); } else { // Apply a default Group filter to only show Groups that would be visible in a Group List. groupQuery = groupQuery.Where( x => x.GroupType.ShowInGroupList ); } var groupKeys = groupQuery.Select( x => x.Id ); // // Construct the Query to return the list of Group Members matching the filter conditions. // var groupMemberQuery = new GroupMemberService( context ).Queryable(); // Filter By Group. groupMemberQuery = groupMemberQuery.Where( x => groupKeys.Contains( x.GroupId ) ); // Filter By Group Role Type. switch ( settings.RoleType ) { case RoleTypeSpecifier.Member: groupMemberQuery = groupMemberQuery.Where( x => !x.GroupRole.IsLeader ); break; case RoleTypeSpecifier.Leader: groupMemberQuery = groupMemberQuery.Where( x => x.GroupRole.IsLeader ); break; } // Filter by Group Member Status. if ( settings.MemberStatus.HasValue ) { groupMemberQuery = groupMemberQuery.Where( x => x.GroupMemberStatus == settings.MemberStatus.Value ); } // // Create a Select Expression to return the requested values. // // Set the Output Format of the field. Expression selectExpression; if (settings.ListFormat == ListFormatSpecifier.YesNo) { // Define a Query to return True/False text indicating if the Person participates in any of the filtered Groups. // Note that the text must be returned as an Enumerable to satisfy the expected output of this field. var personGroupsQuery = new PersonService( context ).Queryable() .Select( p => new List<string> { groupMemberQuery.Any( s => s.PersonId == p.Id ) ? "Yes" : "No" } ); selectExpression = SelectExpressionExtractor.Extract( personGroupsQuery, entityIdProperty, "p" ); } else { // Define a Query to return the collection of filtered Groups for each Person. Expression<Func<Rock.Model.GroupMember, string>> outputExpression; if (settings.ListFormat == ListFormatSpecifier.GroupOnly) { outputExpression = ( ( m => m.Group.Name ) ); } else { outputExpression = ( ( m => m.Group.Name + " [" + m.GroupRole.Name + "]" ) ); } // Define a Query to return the collection of filtered Groups for each Person. var personGroupsQuery = new PersonService( context ).Queryable() .Select( p => groupMemberQuery.Where( s => s.PersonId == p.Id ) .OrderBy( x => x.Group.Name ) .ThenBy( x => x.GroupRole.Name ) .Select( outputExpression ).AsEnumerable() ); selectExpression = SelectExpressionExtractor.Extract( personGroupsQuery, entityIdProperty, "p" ); } return selectExpression; }