Exemple #1
0
        /// <summary>
        /// Get a query for people that have met prerequisites
        /// </summary>
        /// <param name="rockContext"></param>
        /// <param name="stepTypeView"></param>
        /// <returns></returns>
        private IQueryable <int> GetPersonIdsThatHaveMetPrerequisitesQuery(RockContext rockContext, StepTypeView stepTypeView)
        {
            var stepService = new StepService(rockContext);

            // We are querying for people that have met all the prerequisites for this step type
            // This method should not be called for stepTypes that do not have prerequisites
            // because that would be a query for everyone in the database
            var firstStepTypeId   = stepTypeView.PrerequisiteStepTypeIds.First();
            var prerequisiteCount = stepTypeView.PrerequisiteStepTypeIds.Count();

            // Aliases that have completed the first prerequisite
            var query = stepService.Queryable().AsNoTracking()
                        .Where(s =>
                               s.StepStatus.IsCompleteStatus &&
                               s.StepTypeId == firstStepTypeId)
                        .Select(s => s.PersonAlias.PersonId);

            for (var i = 1; i < prerequisiteCount; i++)
            {
                var stepTypeId = stepTypeView.PrerequisiteStepTypeIds.ElementAt(i);

                // Aliases that have completed this subsequent prerequisite
                var subquery = stepService.Queryable().AsNoTracking()
                               .Where(s =>
                                      s.StepStatus.IsCompleteStatus &&
                                      s.StepTypeId == stepTypeId)
                               .Select(s => s.PersonAlias.PersonId);

                // Find the intersection (people in the main query who have also met this prerequisite)
                query = query.Intersect(subquery);
            }

            return(query);
        }
Exemple #2
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType"></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)
        {
            if (string.IsNullOrWhiteSpace(selection))
            {
                return(null);
            }

            var values = JsonConvert.DeserializeObject <List <string> >(selection);

            if (values.Count < 3)
            {
                return(null);
            }

            var stepProgramGuid  = values[0].AsGuid();
            var stepTypeGuid     = values[1].AsGuid();
            var selectedProperty = values[2];

            var stepProgram = GetStepProgram(stepProgramGuid);

            if (stepProgram == null)
            {
                return(null);
            }

            var stepType = GetStepType(stepTypeGuid);

            if (stepType == null)
            {
                return(null);
            }

            var rockContext = ( RockContext )serviceInstance.Context;

            var entityFields = GetStepAttributes(stepType.Id);
            var entityField  = entityFields.FindFromFilterSelection(selectedProperty);

            if (entityField == null)
            {
                return(null);
            }

            // Find matchings Steps.
            var stepService              = new StepService(rockContext);
            var stepParameterExpression  = stepService.ParameterExpression;
            var attributeFilterValues    = values.Skip(3).ToList();
            var attributeWhereExpression = GetAttributeExpression(stepService, stepParameterExpression, entityField, attributeFilterValues);
            var stepQuery = stepService.Queryable()
                            .Where(stepParameterExpression, attributeWhereExpression);

            // Get Person records associated with the Steps.
            var personService = new PersonService(rockContext);
            var personQuery   = personService.Queryable()
                                .Where(p => stepQuery.Any(x => x.PersonAlias.PersonId == p.Id));

            // Extract the expression.
            var dataFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.Person>(personQuery, parameterExpression, "p");

            return(dataFilterExpression);
        }
Exemple #3
0
        /// <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)
        {
            var settings = new FilterSettings(selection);

            var context = ( RockContext )serviceInstance.Context;

            // Get the Data View that defines the set of related records from which entities can be selected.
            var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent(settings.DataViewGuid, context);

            // Evaluate the Data View that defines the related records.
            var relatedEntityService = new StepService(context);

            var relatedEntityQuery = relatedEntityService.Queryable();

            if (dataView != null)
            {
                relatedEntityQuery = DataComponentSettingsHelper.FilterByDataView(relatedEntityQuery, dataView, relatedEntityService);
            }

            // Get all of the People corresponding to the qualifying related records.
            var personService = new PersonService(( RockContext )serviceInstance.Context);

            var qry = personService.Queryable()
                      .Where(p => relatedEntityQuery.Any(xx => xx.PersonAlias.PersonId == p.Id));

            // Retrieve the Filter Expression.
            var extractedFilterExpression = FilterExpressionExtractor.Extract <Model.Person>(qry, parameterExpression, "p");

            return(extractedFilterExpression);
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            var dataContext = new RockContext();

            var stepProgramsQry = new StepProgramService(dataContext)
                                  .Queryable();

            // Filter by: Category
            if (_categoryGuids.Any())
            {
                stepProgramsQry = stepProgramsQry.Where(a => a.Category != null && _categoryGuids.Contains(a.Category.Guid));
            }
            else
            {
                var categoryId = rFilter.GetUserPreference("Category").AsIntegerOrNull();

                if (categoryId.HasValue && categoryId > 0)
                {
                    stepProgramsQry = stepProgramsQry.Where(a => a.CategoryId == categoryId.Value);
                }
            }

            // Filter by: Active
            var activeFilter = rFilter.GetUserPreference("Active").ToLower();

            switch (activeFilter)
            {
            case "active":
                stepProgramsQry = stepProgramsQry.Where(a => a.IsActive);
                break;

            case "inactive":
                stepProgramsQry = stepProgramsQry.Where(a => !a.IsActive);
                break;
            }

            // Sort by: Order
            stepProgramsQry = stepProgramsQry.OrderBy(b => b.Order);

            // Retrieve the Step Program data models and create corresponding view models to display in the grid.
            var stepService = new StepService(dataContext);

            var completedStepsQry = stepService.Queryable().Where(x => x.StepStatus != null && x.StepStatus.IsCompleteStatus);

            var stepPrograms = stepProgramsQry.Select(x =>
                                                      new StepProgramListItemViewModel
            {
                Id                 = x.Id,
                Name               = x.Name,
                IconCssClass       = x.IconCssClass,
                Category           = x.Category.Name,
                StepTypeCount      = x.StepTypes.Count,
                StepCompletedCount = completedStepsQry.Count(y => y.StepType.StepProgramId == x.Id)
            })
                               .ToList();

            gStepProgram.DataSource = stepPrograms;

            gStepProgram.DataBind();
        }
Exemple #5
0
        /// <summary>
        /// Delete the test data
        /// </summary>
        private static void DeleteTestData()
        {
            using (var rockContext = new RockContext())
            {
                var stepService = new StepService(rockContext);
                var stepQuery   = stepService.Queryable().Where(s => s.ForeignKey == ForeignKey);
                stepService.DeleteRange(stepQuery);
                rockContext.SaveChanges();
            }

            using (var rockContext = new RockContext())
            {
                var stepProgramService = new StepProgramService(rockContext);
                var stepProgramQuery   = stepProgramService.Queryable().Where(sp => sp.ForeignKey == ForeignKey);
                stepProgramService.DeleteRange(stepProgramQuery);
                rockContext.SaveChanges();
            }

            using (var rockContext = new RockContext())
            {
                var personSearchKeyService = new PersonSearchKeyService(rockContext);
                var personSearchKeyQuery   = personSearchKeyService.Queryable()
                                             .Where(psk =>
                                                    psk.PersonAlias.Person.ForeignKey == ForeignKey ||
                                                    PersonGuids.Contains(psk.PersonAlias.Person.Guid));
                personSearchKeyService.DeleteRange(personSearchKeyQuery);
                rockContext.SaveChanges();
            }

            using (var rockContext = new RockContext())
            {
                var personAliasService = new PersonAliasService(rockContext);
                var personAliasQuery   = personAliasService.Queryable()
                                         .Where(pa =>
                                                pa.Person.ForeignKey == ForeignKey ||
                                                PersonGuids.Contains(pa.Person.Guid));
                personAliasService.DeleteRange(personAliasQuery);
                rockContext.SaveChanges();
            }

            using (var rockContext = new RockContext())
            {
                var personService = new PersonService(rockContext);
                var personQuery   = personService.Queryable()
                                    .Where(p =>
                                           p.ForeignKey == ForeignKey ||
                                           PersonGuids.Contains(p.Guid));
                personService.DeleteRange(personQuery);
                rockContext.SaveChanges();
            }
        }
Exemple #6
0
        /// <summary>
        /// Gets the source entities query. This is the set of source entities that should be passed to the process method
        /// when processing this achievement type.
        /// </summary>
        /// <param name="achievementTypeCache">The achievement type cache.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public override IQueryable <IEntity> GetSourceEntitiesQuery(AchievementTypeCache achievementTypeCache, RockContext rockContext)
        {
            var stepProgram = GetStepProgramCache(achievementTypeCache);
            var stepTypes   = stepProgram.StepTypes;
            var service     = new StepService(rockContext);
            var query       = service.Queryable();

            if (stepTypes?.Any() == true)
            {
                var stepTypeIds = stepTypes.Select(st => st.Id);
                return(query.Where(s => stepTypeIds.Contains(s.StepTypeId)));
            }

            return(query);
        }
Exemple #7
0
        /// <summary>
        /// These are people that cannot have new step because they already
        /// have one and are within the minimum date range.
        /// </summary>
        /// <param name="stepTypeView">The step type view.</param>
        /// <param name="rockContext"></param>
        /// <param name="minDaysBetweenSteps"></param>
        /// <returns></returns>
        private IQueryable <int> GetPeopleThatCannotGetStepQuery(RockContext rockContext, StepTypeView stepTypeView, int minDaysBetweenSteps)
        {
            var stepService = new StepService(rockContext);
            var minStepDate = DateTime.MinValue;

            // We are querying for people that will ultimately be excluded from getting a new
            // step created from this job.
            // If duplicates are not allowed, then we want to find anyone with a step ever
            // If duplicates are allowed and a day range is set, then it is within that timeframe.
            if (stepTypeView.AllowMultiple && minDaysBetweenSteps >= 1)
            {
                minStepDate = RockDateTime.Now.AddDays(0 - minDaysBetweenSteps);
            }

            var query = stepService.Queryable().AsNoTracking()
                        .Where(s =>
                               s.StepTypeId == stepTypeView.StepTypeId &&
                               (!s.CompletedDateTime.HasValue || s.CompletedDateTime.Value >= minStepDate))
                        .Select(s => s.PersonAlias.PersonId);

            return(query);
        }
Exemple #8
0
        /// <summary>
        /// These are people that cannot have new step because they already
        /// have one and are within the minimum date range.
        /// </summary>
        /// <param name="stepTypeView">The step type view.</param>
        /// <param name="rockContext"></param>
        /// <param name="minDaysBetweenSteps"></param>
        /// <returns></returns>
        private IQueryable <int> GetPersonIdsThatCannotGetStepQuery(RockContext rockContext, StepTypeView stepTypeView, int minDaysBetweenSteps)
        {
            // We are querying for people that will ultimately be excluded from getting a new
            // step created from this job.
            var stepService = new StepService(rockContext);
            var query       = stepService.Queryable().AsNoTracking().Where(s => s.StepTypeId == stepTypeView.StepTypeId);

            if (stepTypeView.AllowMultiple)
            {
                // If allow multiple and completed date is within the minDaysBetweenSteps timeframe
                var minStepDate = minDaysBetweenSteps >= 1 ?
                                  RockDateTime.Now.AddDays(0 - minDaysBetweenSteps) :
                                  DateTime.MinValue;

                query = query.Where(s => s.CompletedDateTime.HasValue && s.CompletedDateTime >= minStepDate);
            }
            else
            {
                // If not allow multiple and has a completed date at all
                query = query.Where(s => s.CompletedDateTime.HasValue);
            }

            return(query.Select(s => s.PersonAlias.PersonId));
        }
Exemple #9
0
        /// <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)
        {
            var settings = new FilterSettings(selection);

            if (!settings.IsValid)
            {
                return(null);
            }

            var dataContext = ( RockContext )serviceInstance.Context;

            int stepProgramId = 0;

            var stepProgram = GetStepProgram(dataContext, settings.StepProgramGuid);

            if (stepProgram != null)
            {
                stepProgramId = stepProgram.Id;
            }

            var stepService = new StepService(dataContext);

            // Filter by Step Program
            var stepQuery = stepService.Queryable().Where(x => x.StepType.StepProgramId == stepProgramId);

            // Filter by Step Types
            if (settings.StepTypeGuids.Count() > 0)
            {
                var stepTypeService = new StepTypeService(dataContext);

                var stepTypeIds = stepTypeService.Queryable()
                                  .Where(a => settings.StepTypeGuids.Contains(a.Guid))
                                  .Select(a => a.Id).ToList();

                stepQuery = stepQuery.Where(x => stepTypeIds.Contains(x.StepTypeId));
            }

            // Filter by Step Status
            if (settings.StepStatusGuids.Count() > 0)
            {
                var stepStatusService = new StepStatusService(dataContext);

                var stepStatusIds = stepStatusService.Queryable()
                                    .Where(a => settings.StepStatusGuids.Contains(a.Guid))
                                    .Select(a => a.Id).ToList();

                stepQuery = stepQuery.Where(x => x.StepStatusId.HasValue && stepStatusIds.Contains(x.StepStatusId.Value));
            }

            // Filter by Date Started
            if (settings.StartedInPeriod != null)
            {
                var startDateRange = settings.StartedInPeriod.GetDateRange(TimePeriodDateRangeBoundarySpecifier.Exclusive);

                if (startDateRange.Start != null)
                {
                    stepQuery = stepQuery.Where(x => x.StartDateTime > startDateRange.Start.Value);
                }
                if (startDateRange.End != null)
                {
                    stepQuery = stepQuery.Where(x => x.StartDateTime < startDateRange.End.Value);
                }
            }

            // Filter by Date Completed
            if (settings.CompletedInPeriod != null)
            {
                var completedDateRange = settings.CompletedInPeriod.GetDateRange(TimePeriodDateRangeBoundarySpecifier.Exclusive);

                if (completedDateRange.Start != null)
                {
                    stepQuery = stepQuery.Where(x => x.CompletedDateTime > completedDateRange.Start.Value);
                }
                if (completedDateRange.End != null)
                {
                    stepQuery = stepQuery.Where(x => x.CompletedDateTime < completedDateRange.End.Value);
                }
            }

            // Filter by Step Campus
            if (settings.StepCampusGuids.Count() > 0)
            {
                var campusService = new CampusService(dataContext);

                var stepCampusIds = campusService.Queryable()
                                    .Where(a => settings.StepCampusGuids.Contains(a.Guid))
                                    .Select(a => a.Id).ToList();

                stepQuery = stepQuery.Where(x => x.CampusId.HasValue && stepCampusIds.Contains(x.CampusId.Value));
            }

            // Create Person Query.
            var personService = new PersonService(( RockContext )serviceInstance.Context);

            var qry = personService.Queryable()
                      .Where(p => stepQuery.Any(x => x.PersonAlias.PersonId == p.Id));

            var extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.Person>(qry, parameterExpression, "p");

            return(extractedFilterExpression);
        }
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <exception cref="System.NotImplementedException"></exception>

        public void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            // get the configured timeout, or default to 60 minutes if it is blank
            var commandTimeout       = dataMap.GetString(AttributeKey.CommandTimeout).AsIntegerOrNull() ?? AttributeDefaults.CommandTimeout;
            var isProcessingComplete = false;
            var batchSize            = 2;
            var totalBatchSize       = 0;
            var currentBatch         = 1;

            totalBatchSize = new StepService(new RockContext())
                             .Queryable()
                             .Where(a => a.CompletedDateTime.HasValue && !a.StepProgramCompletionId.HasValue)
                             .Select(a => a.PersonAlias.PersonId)
                             .Distinct()
                             .Count();
            var runtime = System.Diagnostics.Stopwatch.StartNew();
            var lastProcessedPersonId = 0;

            while (!isProcessingComplete)
            {
                using (var rockContext = new RockContext())
                {
                    var stepTypeService = new StepTypeService(rockContext);
                    var stepService     = new StepService(rockContext);
                    var personQry       = stepService
                                          .Queryable()
                                          .Where(a => a.CompletedDateTime.HasValue && !a.StepProgramCompletionId.HasValue && a.PersonAlias.PersonId > lastProcessedPersonId)
                                          .Select(a => a.PersonAlias.PersonId)
                                          .Distinct()
                                          .OrderBy(a => a)
                                          .Take(batchSize);

                    var stepProgramStepTypeMappings = stepTypeService
                                                      .Queryable()
                                                      .Where(a => a.IsActive)
                                                      .GroupBy(a => a.StepProgramId)
                                                      .ToDictionary(a => a.Key, b => b.Select(c => c.Id).ToList());

                    var steps = new StepService(rockContext)
                                .Queryable("PersonAlias")
                                .AsNoTracking()
                                .Where(a => personQry.Contains(a.PersonAlias.PersonId) && !a.StepProgramCompletionId.HasValue && a.CompletedDateTime.HasValue)
                                .ToList();

                    isProcessingComplete = personQry.Count() < batchSize;
                    var batchPersonIds = personQry.ToList();

                    foreach (var personId in batchPersonIds)
                    {
                        var personSteps = steps.Where(a => a.PersonAlias.PersonId == personId);
                        if (!personSteps.Any())
                        {
                            continue;
                        }

                        foreach (var stepProgramId in stepProgramStepTypeMappings.Keys)
                        {
                            var stepTypeIds    = stepProgramStepTypeMappings[stepProgramId];
                            var stepsByProgram = personSteps.Where(a => stepTypeIds.Contains(a.StepTypeId)).OrderBy(a => a.CompletedDateTime).ToList();

                            if (!stepsByProgram.Any())
                            {
                                continue;
                            }

                            while (stepsByProgram.Any() && stepTypeIds.All(a => stepsByProgram.Any(b => b.StepTypeId == a)))
                            {
                                var stepSet = new List <Step>();
                                foreach (var stepTypeId in stepTypeIds)
                                {
                                    var step = stepsByProgram.Where(a => a.StepTypeId == stepTypeId).FirstOrDefault();
                                    if (step == null)
                                    {
                                        continue;
                                    }

                                    stepSet.Add(step);
                                    stepsByProgram.RemoveAll(a => a.Id == step.Id);
                                }

                                var personAliasId = stepSet.Select(a => a.PersonAliasId).FirstOrDefault();
                                StepService.UpdateStepProgramCompletion(stepSet, personAliasId, stepProgramId);
                            }
                        }
                        lastProcessedPersonId = personId;
                    }

                    var processTime           = runtime.ElapsedMilliseconds;
                    var recordsProcessed      = ( double )(batchSize * currentBatch) + batchPersonIds.Count;
                    var recordsPerMillisecond = recordsProcessed / processTime;
                    var recordsRemaining      = totalBatchSize - recordsProcessed;
                    var minutesRemaining      = recordsRemaining / recordsPerMillisecond / 1000 / 60;
                    context.UpdateLastStatusMessage($"Processing {recordsProcessed} of {totalBatchSize} records. Approximately {minutesRemaining:N0} minutes remaining.");
                    currentBatch++;
                }
            }

            ServiceJobService.DeleteJob(context.GetJobId());
        }
Exemple #11
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            if (!_blockContextIsValid)
            {
                return;
            }

            if (_program == null)
            {
                return;
            }

            var dataContext = this.GetDataContext();

            var stepTypesQry = new StepTypeService(dataContext)
                               .Queryable();

            // Filter by: Step Programs
            stepTypesQry = stepTypesQry.Where(x => x.StepProgramId == _program.Id);

            // Filter by: Name
            var name = rFilter.GetUserPreference(FilterSettingName.Name).ToStringSafe();

            if (!string.IsNullOrWhiteSpace(name))
            {
                stepTypesQry = stepTypesQry.Where(a => a.Name.Contains(name));
            }

            // Filter by: Allow Multiple
            var allowMultiple = rFilter.GetUserPreference(FilterSettingName.AllowMultiple).AsBooleanOrNull();

            if (allowMultiple.HasValue)
            {
                stepTypesQry = stepTypesQry.Where(a => a.AllowMultiple == allowMultiple.Value);
            }

            // Filter by: Has Duration
            var hasDuration = rFilter.GetUserPreference(FilterSettingName.SpansTime).AsBooleanOrNull();

            if (hasDuration.HasValue)
            {
                stepTypesQry = stepTypesQry.Where(a => a.HasEndDate == hasDuration.Value);
            }

            // Filter by: Active
            var activeFilter = rFilter.GetUserPreference(FilterSettingName.ActiveStatus).ToUpperInvariant();

            switch (activeFilter)
            {
            case "ACTIVE":
                stepTypesQry = stepTypesQry.Where(a => a.IsActive);
                break;

            case "INACTIVE":
                stepTypesQry = stepTypesQry.Where(a => !a.IsActive);
                break;
            }

            // Sort by: Order, Id.
            stepTypesQry = stepTypesQry.OrderBy(b => b.Order).ThenBy(b => b.Id);

            // Retrieve the Step Type data models and create corresponding view models to display in the grid.
            var stepService = new StepService(dataContext);

            var startedStepsQry   = stepService.Queryable();
            var completedStepsQry = stepService.Queryable().Where(x => x.StepStatus != null && x.StepStatus.IsCompleteStatus);

            var stepTypes = stepTypesQry.Select(x =>
                                                new StepTypeListItemViewModel
            {
                Id                     = x.Id,
                Name                   = x.Name,
                IconCssClass           = x.IconCssClass,
                AllowMultipleInstances = x.AllowMultiple,
                HasDuration            = x.HasEndDate,
                StartedCount           = startedStepsQry.Count(y => y.StepTypeId == x.Id),
                CompletedCount         = completedStepsQry.Count(y => y.StepTypeId == x.Id)
            })
                            .ToList();

            gStepType.DataSource = stepTypes;

            gStepType.DataBind();
        }
Exemple #12
0
        /// <summary>
        /// Processes the step type. Add steps for everyone in the dataview
        /// </summary>
        /// <param name="jobContext">The job context.</param>
        /// <param name="stepTypeView">The step type view.</param>
        /// <param name="minDaysBetweenSteps">The minimum days between steps.</param>
        /// <param name="addedResults">The added results.</param>
        /// <param name="updatedResults">The updated results.</param>
        /// <param name="errorMessages">The error message.</param>
        private void ProcessStepType(
            IJobExecutionContext jobContext,
            StepTypeView stepTypeView,
            int minDaysBetweenSteps,
            ConcurrentBag <int> addedResults,
            ConcurrentBag <int> updatedResults,
            out List <string> errorMessages)
        {
            errorMessages = new List <string>();
            var rockContextGetList = new RockContext();

            rockContextGetList.Database.CommandTimeout = SqlCommandTimeoutSeconds;

            // Steps are created with a status of "complete", so if we need to know the status id
            var stepStatusId = stepTypeView.CompletedStepStatusIds.FirstOrDefault();

            if (stepStatusId == default)
            {
                errorMessages.Add($"The Step Type with id {stepTypeView.StepTypeId} does not have a valid Complete Status to use");
                return;
            }

            // Get the dataview configured for the step type
            var dataViewService = new DataViewService(rockContextGetList);
            var dataview        = dataViewService.Get(stepTypeView.AutoCompleteDataViewId);

            if (dataview == null)
            {
                errorMessages.Add($"The dataview {stepTypeView.AutoCompleteDataViewId} for step type {stepTypeView.StepTypeId} did not resolve");
                return;
            }

            // We can use the dataview to get the person alias id query
            var dataViewGetQueryArgs = new DataViewGetQueryArgs
            {
                DbContext = rockContextGetList,
                DatabaseTimeoutSeconds = SqlCommandTimeoutSeconds
            };

            IQueryable <IEntity> dataviewQuery;

            try
            {
                dataviewQuery = dataview.GetQuery(dataViewGetQueryArgs);
            }
            catch (Exception ex)
            {
                errorMessages.Add(ex.Message);
                ExceptionLogService.LogException(ex);
                return;
            }

            if (dataviewQuery == null)
            {
                errorMessages.Add($"Generating a query for dataview {stepTypeView.AutoCompleteDataViewId} for step type {stepTypeView.StepTypeId} was not successful");
                return;
            }

            // This query contains person ids in the dataview
            var personIdQuery = dataviewQuery.AsNoTracking().Select(e => e.Id);

            // Get the query for people that cannot get a new step
            var personIdsThatCannotGetStepQuery = GetPersonIdsThatCannotGetStepQuery(rockContextGetList, stepTypeView, minDaysBetweenSteps);

            // Subtract the people that cannot get a new step
            personIdQuery = personIdQuery.Except(personIdsThatCannotGetStepQuery);

            // If there are prerequisites, then subtract the people that cannot get the step because of unmet prerequisites
            if (stepTypeView.PrerequisiteStepTypeIds.Any())
            {
                var personIdsThatHaveMetPrerequisitesQuery = GetPersonIdsThatHaveMetPrerequisitesQuery(rockContextGetList, stepTypeView);
                personIdQuery = personIdQuery.Intersect(personIdsThatHaveMetPrerequisitesQuery);
            }

            // Convert to person aliases ids
            var personAliasService = new PersonAliasService(rockContextGetList);
            var personInfoList     = personAliasService.GetPrimaryAliasQuery()
                                     .Where(a => personIdQuery.Contains(a.PersonId))
                                     .Select(a => new
            {
                PersonId       = a.PersonId,
                PrimaryAliasId = a.Id
            })
                                     .ToList();

            // Add or update steps for each of the remaining aliases that have met all the conditions
            var stepServiceGetList = new StepService(rockContextGetList);
            var now          = RockDateTime.Now;
            var addedCount   = 0;
            var updatedCount = 0;

            // Query for existing incomplete steps for the people
            var existingIncompleteStepIdsByPersonId = stepServiceGetList.Queryable()
                                                      .Where(s =>
                                                             s.StepTypeId == stepTypeView.StepTypeId &&
                                                             personIdQuery.Contains(s.PersonAlias.PersonId) &&
                                                             !s.CompletedDateTime.HasValue)
                                                      .Select(a => new
            {
                a.PersonAlias.PersonId,
                StepId = a.Id
            })
                                                      .ToList()
                                                      .GroupBy(a => a.PersonId)
                                                      .ToDictionary(
                k => k.Key,
                // just in case the Person is has more than one incomplete step for this step type, just use the latest one
                // it should clean it self up on subsequent runs since the other steps for this person wouldn't have been marked complete yet
                v => v.Max(s => s.StepId)
                );


            long totalCount    = personInfoList.Count;
            long progressCount = 0;

            foreach (var personIdInfo in personInfoList)
            {
                var personId             = personIdInfo.PersonId;
                var personPrimaryAliasId = personIdInfo.PrimaryAliasId;

                var existingStepId = existingIncompleteStepIdsByPersonId.GetValueOrNull(personId);

                using (var rockContextLoop = new RockContext())
                {
                    var  stepServiceLoop = new StepService(rockContextLoop);
                    Step step;
                    if (existingStepId.HasValue)
                    {
                        step = stepServiceLoop.Get(existingStepId.Value);
                    }
                    else
                    {
                        step = new Step
                        {
                            StepTypeId    = stepTypeView.StepTypeId,
                            Caption       = stepTypeView.Name,
                            StartDateTime = now,
                            PersonAliasId = personPrimaryAliasId
                        };
                    }

                    step.CompletedDateTime = now;
                    step.StepStatusId      = stepStatusId;

                    if (!existingStepId.HasValue)
                    {
                        stepServiceLoop.AddWithoutValidation(step);
                        addedCount++;
                    }
                    else
                    {
                        updatedCount++;
                    }

                    rockContextLoop.SaveChanges();
                }

                progressCount++;

                // Update the progress every 5 seconds
                if ((RockDateTime.Now - _lastProgressUpdate).TotalSeconds >= 5)
                {
                    try
                    {
                        jobContext.UpdateLastStatusMessage($"Processing {stepTypeView.Name } steps : {progressCount}/{totalCount}");
                    }
                    catch (Exception ex)
                    {
                        // ignore, but write to debug output
                        System.Diagnostics.Debug.WriteLine($"Error updating LastStatusMessage for ProcessStepType loop: {ex}");
                    }
                    finally
                    {
                        _lastProgressUpdate = RockDateTime.Now;
                    }
                }
            }

            addedResults.Add(addedCount);
            updatedResults.Add(updatedCount);
        }
Exemple #13
0
        /// <summary>
        /// Render the grid view's grid
        /// </summary>
        private void RenderStepGrid()
        {
            if (!ValidateRequiredModels())
            {
                return;
            }

            // Get the initial query
            var stepTypes = GetStepTypes();

            // Get filter values
            var stepTypeNameFilter   = gfGridFilter.GetUserPreference(FilterKey.StepTypeName);
            var stepStatusNameFilter = gfGridFilter.GetUserPreference(FilterKey.StepStatusName);

            // Apply step type filters
            if (!string.IsNullOrEmpty(stepTypeNameFilter))
            {
                stepTypes = stepTypes.Where(st => st.Name.Contains(stepTypeNameFilter)).ToList();
            }

            // Get the step type Ids
            var stepTypeIds = stepTypes.Select(st => st.Id).ToList();

            // Query for the steps
            var rockContext = GetRockContext();
            var stepService = new StepService(rockContext);
            var person      = GetPerson();

            var stepsQuery = stepService.Queryable()
                             .AsNoTracking()
                             .Include(s => s.StepType)
                             .Include(s => s.StepStatus)
                             .Where(s =>
                                    s.PersonAlias.PersonId == person.Id &&
                                    stepTypeIds.Contains(s.StepTypeId));

            // Apply step filters
            if (!string.IsNullOrEmpty(stepStatusNameFilter))
            {
                stepsQuery = stepsQuery.Where(s => s.StepStatus != null && s.StepStatus.Name.Contains(stepStatusNameFilter));
            }

            // Create a view model for each step
            var viewModels = stepsQuery.Select(s => new StepGridRowViewModel
            {
                Id                   = s.Id,
                StepTypeName         = s.StepType.Name,
                CompletedDateTime    = s.CompletedDateTime,
                StepStatusColor      = s.StepStatus == null ? string.Empty : s.StepStatus.StatusColor,
                StepStatusName       = s.StepStatus == null ? string.Empty : s.StepStatus.Name,
                StepTypeIconCssClass = s.StepType.IconCssClass,
                StepTypeOrder        = s.StepType.Order,
                Summary              = string.Empty // TODO
            });

            // Sort the view models
            if (gStepList.SortProperty != null)
            {
                viewModels = viewModels.Sort(gStepList.SortProperty);
            }
            else
            {
                viewModels = viewModels.OrderBy(vm => vm.StepTypeOrder).ThenBy(vm => vm.StepTypeName);
            }

            // Bind the grid for the steps
            gStepList.SetLinqDataSource(viewModels);
            gStepList.DataBind();
        }
        /// <summary>
        /// Migrates a baptism record from a Attribute Matrix Item to a Step
        /// </summary>
        /// <param name="itemId">Matrix Item Id</param>
        /// <param name="personId">The Person Id of the person who was baptized.</param>
        /// <returns></returns>
        private bool MigrateBaptismItem(int itemId, int personId)
        {
            using (var context = new RockContext())
            {
                var matrixItem = new AttributeMatrixItemService(context).Get(itemId);

                var person = new PersonService(context).Get(personId);

                if (matrixItem == null)
                {
                    results["Fail"] += String.Format("Failed Migration {0} - {1}, baptism matrix item not found.",
                                                     itemId,
                                                     person != null ? person.FullName : "Unknown") + Environment.NewLine;
                    return(false);
                }



                matrixItem.LoadAttributes(context);
                var campusGuid      = matrixItem.GetAttributeValue("BaptismLocation").AsGuidOrNull();
                var baptismDate     = matrixItem.GetAttributeValue("BaptismDate").AsDateTime();
                var baptizedBy      = matrixItem.GetAttributeValue("BaptizedBy");
                var baptismTypeGuid = matrixItem.GetAttributeValue("BaptismType").AsGuidOrNull();


                var stepService = new StepService(context);



                var step = stepService.Queryable()
                           .Where(s => s.ForeignId == itemId)
                           .Where(s => s.PersonAlias.PersonId == personId)
                           .SingleOrDefault();

                if (step == null)
                {
                    step = new Step()
                    {
                        StepTypeId    = BaptismStepType.Id,
                        PersonAliasId = person.PrimaryAliasId.Value,
                        ForeignId     = matrixItem.Id
                    };

                    stepService.Add(step);
                }

                if (baptismDate >= new DateTime(1753, 1, 1))     //datetime minimum date
                {
                    step.StartDateTime     = baptismDate;
                    step.CompletedDateTime = baptismDate;
                }

                step.StepStatusId = StepStatus.Id;

                if (campusGuid.HasValue)
                {
                    step.CampusId = CampusCache.Get(campusGuid.Value).Id;
                }

                context.SaveChanges();
                step.LoadAttributes(context);

                step.SetAttributeValue("BaptismType", baptismTypeGuid);

                if (baptizedBy.IsNotNullOrWhiteSpace())
                {
                    step.SetAttributeValue("BaptizedBy", baptizedBy);
                }
                else
                {
                    step.SetAttributeValue("BaptizedBy", null);
                }

                step.SaveAttributeValues(context);

                results["Success"] += String.Format("Successfully migrated baptism item {0}-{1} for {2}.",
                                                    matrixItem.Id,
                                                    baptismTypeGuid.HasValue ? DefinedValueCache.Get(baptismTypeGuid.Value).Value : "Unknown Type",
                                                    person != null ? person.FullName : "Unknown") + Environment.NewLine;

                return(true);
            }
        }
Exemple #15
0
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        protected void BindParticipantsGrid(bool isExporting = false, bool isCommunication = false)
        {
            if (_stepType == null)
            {
                pnlSteps.Visible = false;
                return;
            }

            pnlSteps.Visible = true;
            rFilter.Visible  = true;
            gSteps.Visible   = true;

            var campusCount = CampusCache.All(false).Count;

            if (campusCount <= 1)
            {
                var campusColumn = gSteps.ColumnsOfType <RockBoundField>().Where(a => a.DataField == "CampusName").FirstOrDefault();
                if (campusColumn != null)
                {
                    campusColumn.Visible = false;
                }
            }

            lHeading.Text = string.Format("{0} Steps", _stepType.Name);

            _fullNameField     = gSteps.ColumnsOfType <RockLiteralField>().Where(a => a.ID == "lExportFullName").FirstOrDefault();
            _nameWithHtmlField = gSteps.ColumnsOfType <RockLiteralField>().Where(a => a.ID == "lNameWithHtml").FirstOrDefault();

            var dataContext = GetDataContext();

            var stepService = new StepService(dataContext);

            var qry = stepService.Queryable()
                      .Include(x => x.StepStatus)
                      .Include(x => x.PersonAlias.Person)
                      .AsNoTracking()
                      .Where(x => x.StepTypeId == _stepType.Id);

            // Filter by First Name
            string firstName = tbFirstName.Text;

            if (!string.IsNullOrWhiteSpace(firstName))
            {
                qry = qry.Where(m =>
                                m.PersonAlias.Person.FirstName.StartsWith(firstName) ||
                                m.PersonAlias.Person.NickName.StartsWith(firstName));
            }

            // Filter by Last Name
            string lastName = tbLastName.Text;

            if (!string.IsNullOrWhiteSpace(lastName))
            {
                qry = qry.Where(m => m.PersonAlias.Person.LastName.StartsWith(lastName));
            }

            // Filter by Step Status
            var validStatusIds = _stepType.StepProgram.StepStatuses.Select(r => r.Id).ToList();

            var statusIds = new List <int>();

            foreach (var statusId in cblStepStatus.SelectedValues.AsIntegerList())
            {
                if (validStatusIds.Contains(statusId))
                {
                    statusIds.Add(statusId);
                }
            }

            if (statusIds.Any())
            {
                qry = qry.Where(m => statusIds.Contains(m.StepStatusId ?? 0));
            }

            // Filter By Start Date
            var startDateRange = DateRangePicker.CalculateDateRangeFromDelimitedValues(drpDateStarted.DelimitedValues);

            if (startDateRange.Start.HasValue)
            {
                qry = qry.Where(m =>
                                m.StartDateTime.HasValue &&
                                m.StartDateTime.Value >= startDateRange.Start.Value);
            }

            if (startDateRange.End.HasValue)
            {
                var exclusiveEndDate = startDateRange.End.Value.Date.AddDays(1);
                qry = qry.Where(m =>
                                m.StartDateTime.HasValue &&
                                m.StartDateTime.Value < exclusiveEndDate);
            }

            // Filter by Date Completed
            var completedDateRange = DateRangePicker.CalculateDateRangeFromDelimitedValues(drpDateCompleted.DelimitedValues);

            if (completedDateRange.Start.HasValue)
            {
                qry = qry.Where(m =>
                                m.CompletedDateTime.HasValue &&
                                m.CompletedDateTime.Value >= completedDateRange.Start.Value);
            }

            if (completedDateRange.End.HasValue)
            {
                var exclusiveEndDate = completedDateRange.End.Value.Date.AddDays(1);
                qry = qry.Where(m =>
                                m.CompletedDateTime.HasValue &&
                                m.CompletedDateTime.Value < exclusiveEndDate);
            }

            // Filter by Note
            string note = tbNote.Text;

            if (!string.IsNullOrWhiteSpace(note))
            {
                qry = qry.Where(m => m.Note.Contains(note));
            }

            var campusId = cpCampusFilter.SelectedCampusId;

            if (campusId != null)
            {
                qry = qry.Where(m => m.CampusId == campusId);
            }

            // Filter query by any configured attribute filters
            if (AvailableAttributes != null && AvailableAttributes.Any())
            {
                foreach (var attribute in AvailableAttributes)
                {
                    var filterControl = phAttributeFilters.FindControl("filter_" + attribute.Id.ToString());
                    qry = attribute.FieldType.Field.ApplyAttributeQueryFilter(qry, filterControl, attribute, stepService, Rock.Reporting.FilterMode.SimpleFilter);
                }
            }

            // Apply Grid Sort
            var sortProperty = gSteps.SortProperty;

            if (sortProperty != null)
            {
                qry = qry.Sort(sortProperty);
            }
            else
            {
                qry = qry.OrderBy(a => a.PersonAlias.Person.LastName).ThenBy(a => a.PersonAlias.Person.FirstName);
            }

            var stepIdQuery = qry.Select(m => m.Id);

            _inactiveStatus = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE);

            gSteps.EntityTypeId = new Step().TypeId;

            _stepStatusField = gSteps.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == lStepStatusHtml.ID);

            _stepDateStartedField = gSteps.ColumnsOfType <RockBoundField>().FirstOrDefault(a => a.HeaderText == "Date Started");

            if (_stepDateStartedField != null)
            {
                _stepDateStartedField.Visible = _stepType.HasEndDate;
            }

            _showNoteColumn = GetAttributeValue(AttributeKey.ShowNoteColumn).AsBoolean();

            gSteps.ColumnsOfType <RockBoundField>().First(a => a.DataField == "Note").Visible = _showNoteColumn;

            var hasDuration = _stepType.HasEndDate;

            var qrySteps = qry.Select(x => new StepParticipantListViewModel
            {
                Id                = x.Id,
                PersonId          = x.PersonAlias.PersonId,
                LastName          = x.PersonAlias.Person.LastName,
                NickName          = x.PersonAlias.Person.NickName,
                StartedDateTime   = x.StartDateTime,
                CompletedDateTime = x.CompletedDateTime,
                StepStatusName    = (x.StepStatus == null ? "" : x.StepStatus.Name),
                IsCompleted       = (x.StepStatus == null ? false : x.StepStatus.IsCompleteStatus),
                Note              = x.Note,
                CampusName        = x.Campus == null ? string.Empty : x.Campus.Name,
                Person            = x.PersonAlias.Person
            });

            // Add the Step data models to the grid object list to allow custom attribute values to be read.
            if (this.AvailableAttributes != null &&
                this.AvailableAttributes.Any())
            {
                gSteps.ObjectList = qry.ToDictionary(k => k.Id.ToString(), v => ( object )v);
            }

            gSteps.SetLinqDataSource(qrySteps);

            gSteps.DataBind();
        }
Exemple #16
0
        public void StepDateKeyJoinsCorrectly()
        {
            var expectedRecordCount = 15;
            var startYear           = 2015;
            var completedYear       = 2016;
            var endYear             = 2017;

            using (var rockContext = new RockContext())
            {
                var stepService = new StepService(rockContext);

                var minStartDateValue = TestDataHelper.GetAnalyticsSourceMinDateForYear(rockContext, startYear);
                var maxStartDateValue = TestDataHelper.GetAnalyticsSourceMaxDateForYear(rockContext, startYear);

                var minCompletedDateValue = TestDataHelper.GetAnalyticsSourceMinDateForYear(rockContext, completedYear);
                var maxCompletedDateValue = TestDataHelper.GetAnalyticsSourceMaxDateForYear(rockContext, completedYear);

                var minEndDateValue = TestDataHelper.GetAnalyticsSourceMinDateForYear(rockContext, endYear);
                var maxEndDateValue = TestDataHelper.GetAnalyticsSourceMaxDateForYear(rockContext, endYear);

                for (var i = 0; i < 15; i++)
                {
                    var startDate     = TestDataHelper.GetRandomDateInRange(minStartDateValue, maxStartDateValue);
                    var endDate       = TestDataHelper.GetRandomDateInRange(minEndDateValue, maxEndDateValue);
                    var completedDate = TestDataHelper.GetRandomDateInRange(minCompletedDateValue, maxCompletedDateValue);

                    while (endDate < startDate)
                    {
                        endDate = TestDataHelper.GetRandomDateInRange(minEndDateValue, maxEndDateValue);
                    }

                    while (completedDate < startDate)
                    {
                        completedDate = TestDataHelper.GetRandomDateInRange(minCompletedDateValue, maxCompletedDateValue);
                    }

                    var step = BuildStep(rockContext, completedDate, startDate, endDate);

                    stepService.Add(step);
                }

                rockContext.SaveChanges();
            }

            using (var rockContext = new RockContext())
            {
                var stepService = new StepService(rockContext);

                var steps = stepService.
                            Queryable().
                            Where(i => i.ForeignKey == stepForiegnKey).
                            Where(i => i.CompletedSourceDate.CalendarYear == completedYear);

                Assert.AreEqual(expectedRecordCount, steps.Count());
                Assert.IsNotNull(steps.First().CompletedSourceDate);

                steps = stepService.
                        Queryable().
                        Where(i => i.ForeignKey == stepForiegnKey).
                        Where(i => i.StartSourceDate.CalendarYear == startYear);

                Assert.AreEqual(expectedRecordCount, steps.Count());
                Assert.IsNotNull(steps.First().StartSourceDate);

                steps = stepService.
                        Queryable().
                        Where(i => i.ForeignKey == stepForiegnKey).
                        Where(i => i.EndSourceDate.CalendarYear == endYear);

                Assert.AreEqual(expectedRecordCount, steps.Count());
                Assert.IsNotNull(steps.First().EndSourceDate);
            }
        }