/// <summary> /// Gets the group placement registrants. /// </summary> /// <param name="options">The options.</param> /// <param name="currentPerson">The current person.</param> /// <returns></returns> public List <GroupPlacementRegistrant> GetGroupPlacementRegistrants(GetGroupPlacementRegistrantsParameters options, Person currentPerson) { var rockContext = this.Context as RockContext; var registrationRegistrantService = new RegistrationRegistrantService(rockContext); var registrationRegistrantQuery = registrationRegistrantService.Queryable(); registrationRegistrantQuery = registrationRegistrantQuery .Where(a => a.Registration.RegistrationInstance.RegistrationTemplateId == options.RegistrationTemplateId); if (options.RegistrationInstanceId.HasValue) { registrationRegistrantQuery = registrationRegistrantQuery.Where(a => a.Registration.RegistrationInstanceId == options.RegistrationInstanceId.Value); } else if (options.RegistrationTemplateInstanceIds?.Any() == true) { registrationRegistrantQuery = registrationRegistrantQuery.Where(a => options.RegistrationTemplateInstanceIds.Contains(a.Registration.RegistrationInstanceId)); } if (options.RegistrantPersonDataViewFilterId.HasValue) { var dataFilter = new DataViewFilterService(rockContext).Get(options.RegistrantPersonDataViewFilterId.Value); List <string> errorMessages = new List <string>(); var personService = new PersonService(rockContext); var paramExpression = personService.ParameterExpression; var personWhereExpression = dataFilter?.GetExpression(typeof(Person), personService, paramExpression, errorMessages); if (personWhereExpression != null) { var personIdQry = personService.Queryable().Where(paramExpression, personWhereExpression, null).Select(x => x.Id); registrationRegistrantQuery = registrationRegistrantQuery.Where(a => personIdQry.Contains(a.PersonAlias.PersonId)); } } if (options.RegistrantId.HasValue) { registrationRegistrantQuery = registrationRegistrantQuery.Where(a => a.Id == options.RegistrantId.Value); } Block registrationInstanceGroupPlacementBlock = new BlockService(rockContext).Get(options.BlockId); if (registrationInstanceGroupPlacementBlock != null && currentPerson != null) { const string RegistrantAttributeFilter_RegistrationInstanceId = "RegistrantAttributeFilter_RegistrationInstanceId_{0}"; const string RegistrantAttributeFilter_RegistrationTemplateId = "RegistrantAttributeFilter_RegistrationTemplateId_{0}"; string userPreferenceKey; if (options.RegistrationInstanceId.HasValue) { userPreferenceKey = PersonService.GetBlockUserPreferenceKeyPrefix(options.BlockId) + string.Format(RegistrantAttributeFilter_RegistrationInstanceId, options.RegistrationInstanceId); } else { userPreferenceKey = PersonService.GetBlockUserPreferenceKeyPrefix(options.BlockId) + string.Format(RegistrantAttributeFilter_RegistrationTemplateId, options.RegistrationTemplateId); } var attributeFilters = PersonService.GetUserPreference(currentPerson, userPreferenceKey).FromJsonOrNull <Dictionary <int, string> >() ?? new Dictionary <int, string>(); var parameterExpression = registrationRegistrantService.ParameterExpression; Expression registrantWhereExpression = null; foreach (var attributeFilter in attributeFilters) { var attribute = AttributeCache.Get(attributeFilter.Key); var attributeFilterValues = attributeFilter.Value.FromJsonOrNull <List <string> >(); var entityField = EntityHelper.GetEntityFieldForAttribute(attribute); if (entityField != null && attributeFilterValues != null) { var attributeWhereExpression = ExpressionHelper.GetAttributeExpression(registrationRegistrantService, parameterExpression, entityField, attributeFilterValues); if (registrantWhereExpression == null) { registrantWhereExpression = attributeWhereExpression; } else { registrantWhereExpression = Expression.AndAlso(registrantWhereExpression, attributeWhereExpression); } } } if (registrantWhereExpression != null) { registrationRegistrantQuery = registrationRegistrantQuery.Where(parameterExpression, registrantWhereExpression); } } var registrationTemplatePlacement = new RegistrationTemplatePlacementService(rockContext).Get(options.RegistrationTemplatePlacementId); if (options.FilterFeeId.HasValue) { registrationRegistrantQuery = registrationRegistrantQuery.Where(a => a.Fees.Any(f => f.RegistrationTemplateFeeId == options.FilterFeeId.Value)); } if (options.FilterFeeOptionIds?.Any() == true) { registrationRegistrantQuery = registrationRegistrantQuery.Where(a => a.Fees.Any(f => f.RegistrationTemplateFeeItemId.HasValue && options.FilterFeeOptionIds.Contains(f.RegistrationTemplateFeeItemId.Value))); } // don't include registrants that are on the waiting list registrationRegistrantQuery = registrationRegistrantQuery.Where(a => a.OnWaitList == false); registrationRegistrantQuery = registrationRegistrantQuery.OrderBy(a => a.PersonAlias.Person.LastName).ThenBy(a => a.PersonAlias.Person.NickName); var registrationTemplatePlacementService = new RegistrationTemplatePlacementService(rockContext); var registrationInstanceService = new RegistrationInstanceService(rockContext); // get a queryable of PersonIds for the registration template shared groups so we can determine if the registrant has been placed var registrationTemplatePlacementGroupsPersonIdQuery = registrationTemplatePlacementService.GetRegistrationTemplatePlacementPlacementGroups(registrationTemplatePlacement).SelectMany(a => a.Members).Select(a => a.PersonId); // and also get a queryable of PersonIds for the registration instance placement groups so we can determine if the registrant has been placed IQueryable <InstancePlacementGroupPersonId> allInstancesPlacementGroupInfoQuery = null; if (!options.RegistrationInstanceId.HasValue && (options.RegistrationTemplateInstanceIds == null || !options.RegistrationTemplateInstanceIds.Any())) { // if neither RegistrationInstanceId or RegistrationTemplateInstanceIds was specified, use all of the RegistrationTemplates instances options.RegistrationTemplateInstanceIds = new RegistrationTemplateService(rockContext).GetSelect(options.RegistrationTemplateId, s => s.Instances.Select(i => i.Id)).ToArray(); } if (options.RegistrationInstanceId.HasValue) { allInstancesPlacementGroupInfoQuery = registrationInstanceService.GetRegistrationInstancePlacementGroups(registrationInstanceService.Get(options.RegistrationInstanceId.Value)) .Where(a => a.GroupTypeId == registrationTemplatePlacement.GroupTypeId) .SelectMany(a => a.Members).Select(a => a.PersonId) .Select(s => new InstancePlacementGroupPersonId { PersonId = s, RegistrationInstanceId = options.RegistrationInstanceId.Value }); } else if (options.RegistrationTemplateInstanceIds?.Any() == true) { foreach (var registrationInstanceId in options.RegistrationTemplateInstanceIds) { var instancePlacementGroupInfoQuery = registrationInstanceService.GetRegistrationInstancePlacementGroups(registrationInstanceService.Get(registrationInstanceId)) .Where(a => a.GroupTypeId == registrationTemplatePlacement.GroupTypeId) .SelectMany(a => a.Members).Select(a => a.PersonId) .Select(s => new InstancePlacementGroupPersonId { PersonId = s, RegistrationInstanceId = registrationInstanceId }); if (allInstancesPlacementGroupInfoQuery == null) { allInstancesPlacementGroupInfoQuery = instancePlacementGroupInfoQuery; } else { allInstancesPlacementGroupInfoQuery = allInstancesPlacementGroupInfoQuery.Union(instancePlacementGroupInfoQuery); } } } if (allInstancesPlacementGroupInfoQuery == null) { throw new ArgumentNullException("Registration Instance(s) must be specified"); } // select in a way to avoid lazy loading var registrationRegistrantPlacementQuery = registrationRegistrantQuery.Select(r => new { Registrant = r, r.PersonAlias.Person, r.Registration.RegistrationInstance, // marked as AlreadyPlacedInGroup if the Registrant is a member of any of the registrant template placement group or the registration instance placement groups AlreadyPlacedInGroup = registrationTemplatePlacementGroupsPersonIdQuery.Contains(r.PersonAlias.PersonId) || allInstancesPlacementGroupInfoQuery.Any(x => x.RegistrationInstanceId == r.Registration.RegistrationInstanceId && x.PersonId == r.PersonAlias.PersonId) }); var registrationRegistrantPlacementList = registrationRegistrantPlacementQuery.AsNoTracking().ToList(); var groupPlacementRegistrantList = registrationRegistrantPlacementList .Select(x => new GroupPlacementRegistrant(x.Registrant, x.Person, x.AlreadyPlacedInGroup, x.RegistrationInstance, options)) .ToList(); return(groupPlacementRegistrantList.ToList()); }