Example #1
0
        /// <summary>
        /// Gets the step type.
        /// </summary>
        /// <param name="rockContext"></param>
        /// <param name="action">The action.</param>
        /// <param name="errorMessage">The error message.</param>
        /// <returns></returns>
        private StepType GetStepType(RockContext rockContext, WorkflowAction action, out string errorMessage)
        {
            errorMessage = string.Empty;
            var      stepTypeIncludes = "StepProgram.StepStatuses";
            var      stepTypeService  = new StepTypeService(rockContext);
            StepType stepType         = null;
            var      stepTypeValue    = GetLavaAttributeValue(action, AttributeKey.StepProgramStepType);

            // Check if the value is a guid. This method works for stepProgram|stepType or simply just step type guids
            StepProgramStepTypeFieldType.ParseDelimitedGuids(stepTypeValue, out var unused1, out var stepTypeGuid);

            if (stepTypeGuid.HasValue)
            {
                stepType = stepTypeService.Queryable(stepTypeIncludes).AsNoTracking().FirstOrDefault(st => st.Guid == stepTypeGuid.Value);

                if (stepType == null)
                {
                    errorMessage = $"The step type with the guid '{stepTypeGuid.Value}' was not found";
                    return(null);
                }
            }

            // Try to get a step type with a step type id
            if (stepType == null)
            {
                var stepTypeId = stepTypeValue.AsIntegerOrNull();

                if (!stepTypeId.HasValue)
                {
                    errorMessage = "The step type identifier is required but was missing";
                    return(null);
                }

                stepType = stepTypeService.Queryable(stepTypeIncludes).AsNoTracking().FirstOrDefault(st => st.Id == stepTypeId.Value);

                if (stepType == null)
                {
                    errorMessage = $"The step type with the id '{stepTypeId.Value}' was not found";
                    return(null);
                }
            }

            if (stepType.StepProgram == null)
            {
                errorMessage = $"The step type '{stepType.Name}' program is missing";
                return(null);
            }

            if (stepType.StepProgram.StepStatuses == null || !stepType.StepProgram.StepStatuses.Any())
            {
                errorMessage = $"The step program '{stepType.StepProgram.Name}' does not have any statuses";
                return(null);
            }

            return(stepType);
        }
Example #2
0
        /// <summary>
        /// Get the step type model
        /// </summary>
        /// <returns></returns>
        private StepType GetStepType()
        {
            if (_stepType == null)
            {
                var step = GetStep();

                if (step != null)
                {
                    _stepType = step.StepType;
                }
                else
                {
                    var stepTypeId = GetAttributeValue(AttributeKey.StepType).AsIntegerOrNull() ??
                                     PageParameter(ParameterKey.StepTypeId).AsIntegerOrNull();

                    if (stepTypeId.HasValue)
                    {
                        var rockContext = GetRockContext();
                        var service     = new StepTypeService(rockContext);

                        _stepType = service.Queryable()
                                    .AsNoTracking()
                                    .FirstOrDefault(st => st.Id == stepTypeId.Value && st.IsActive);
                    }
                }
            }

            return(_stepType);
        }
Example #3
0
        /// <summary>
        /// Loads the drop down items.
        /// </summary>
        /// <param name="picker">The picker.</param>
        /// <param name="includeEmptyOption">if set to <c>true</c> [include empty option].</param>
        internal static void LoadDropDownItems(IStepTypePicker picker, bool includeEmptyOption)
        {
            var selectedItems = picker.Items.Cast <ListItem>()
                                .Where(i => i.Selected)
                                .Select(i => i.Value).AsIntegerList();

            picker.Items.Clear();

            if (!picker.StepProgramId.HasValue)
            {
                return;
            }

            if (includeEmptyOption)
            {
                // add Empty option first
                picker.Items.Add(new ListItem());
            }

            var stepTypeService = new StepTypeService(new RockContext());
            var stepTypes       = stepTypeService.Queryable().AsNoTracking()
                                  .Where(st =>
                                         st.StepProgramId == picker.StepProgramId.Value &&
                                         st.IsActive)
                                  .OrderBy(st => st.Order)
                                  .ThenBy(st => st.Name)
                                  .ToList();

            foreach (var stepType in stepTypes)
            {
                var li = new ListItem(stepType.Name, stepType.Id.ToString());
                li.Selected = selectedItems.Contains(stepType.Id);
                picker.Items.Add(li);
            }
        }
Example #4
0
        /// <summary>
        /// Gets the step type view query. All active step types that have a person based
        /// dataview configured
        /// </summary>
        /// <returns></returns>
        private List <StepTypeView> GetStepTypeViews()
        {
            var personEntityTypeId = EntityTypeCache.Get <Person>().Id;
            var rockContext        = new RockContext();
            var stepTypeService    = new StepTypeService(rockContext);

            var views = stepTypeService.Queryable().AsNoTracking()
                        .Where(st =>
                               st.StepProgram.IsActive &&
                               st.IsActive &&
                               st.AutoCompleteDataViewId.HasValue &&
                               st.AutoCompleteDataView.EntityTypeId == personEntityTypeId)
                        .Select(st => new StepTypeView
            {
                StepTypeId              = st.Id,
                StepProgramId           = st.StepProgramId,
                AllowMultiple           = st.AllowMultiple,
                AutoCompleteDataViewId  = st.AutoCompleteDataViewId.Value,
                PrerequisiteStepTypeIds = st.StepTypePrerequisites.Select(stp => stp.PrerequisiteStepTypeId),

                // Get a list of the step statuses, but only take 1 so that it doesn't cause a second database call
                CompletedStepStatusIds = st.StepProgram.StepStatuses
                                         .OrderBy(ss => ss.Order)
                                         .Where(ss =>
                                                ss.IsCompleteStatus &&
                                                ss.IsActive)
                                         .Select(ss => ss.Id)
                                         .Take(1)
            })
                        .ToList();

            return(views);
        }
Example #5
0
        /// <summary>
        /// Populates the selection lists for Step Type and Step Status.
        /// </summary>
        /// <param name="filterField">The filter field.</param>
        private void PopulateStepProgramRelatedSelectionLists(FilterField filterField)
        {
            var dataContext = new RockContext();

            var programService = new StepProgramService(dataContext);

            SingleEntityPicker <StepProgram> stepProgramSingleEntityPicker = filterField.ControlsOfTypeRecursive <SingleEntityPicker <StepProgram> >().FirstOrDefault(c => c.HasCssClass("js-step-program-picker"));
            RockCheckBoxList cblStepType    = filterField.ControlsOfTypeRecursive <RockCheckBoxList>().FirstOrDefault(c => c.HasCssClass("js-step-type"));
            RockCheckBoxList _cblStepStatus = filterField.ControlsOfTypeRecursive <RockCheckBoxList>().FirstOrDefault(c => c.HasCssClass("js-step-status"));

            int?stepProgramId = stepProgramSingleEntityPicker.SelectedId;

            StepProgram stepProgram = null;

            if (stepProgramId != null)
            {
                stepProgram = programService.Get(stepProgramId.Value);
            }

            if (stepProgram != null)
            {
                // Step Type list
                cblStepType.Items.Clear();

                var stepTypeService = new StepTypeService(dataContext);

                var stepTypes = stepTypeService.Queryable().Where(x => x.StepProgramId == stepProgramId);

                foreach (var item in stepTypes)
                {
                    cblStepType.Items.Add(new ListItem(item.Name, item.Guid.ToString()));
                }

                cblStepType.Visible = cblStepType.Items.Count > 0;

                // Step Status list
                _cblStepStatus.Items.Clear();

                var stepStatusService = new StepStatusService(dataContext);

                var stepStatuses = stepStatusService.Queryable().Where(x => x.StepProgramId == stepProgramId);

                foreach (var item in stepStatuses)
                {
                    _cblStepStatus.Items.Add(new ListItem(item.Name, item.Guid.ToString()));
                }

                _cblStepStatus.Visible = _cblStepStatus.Items.Count > 0;
            }
            else
            {
                cblStepType.Visible    = false;
                _cblStepStatus.Visible = false;
            }
        }
        /// <summary>
        /// Get a list of triggers that may be fired by a state change in the entity being processed.
        /// </summary>
        /// <param name="dataContext"></param>
        /// <param name="entityGuid"></param>
        /// <returns></returns>
        protected override List <StepWorkflowTrigger> GetEntityChangeTriggers(RockContext dataContext, Guid entityGuid)
        {
            // Get the triggers associated with the Step Type to which this Step is related.
            var triggers = new List <StepWorkflowTrigger>();

            var stepTypeService = new StepTypeService(dataContext);

            var stepType = stepTypeService.Queryable()
                           .AsNoTracking()
                           .Include(x => x.StepWorkflowTriggers)
                           .FirstOrDefault(x => x.Id == this.StepTypeId);

            if (stepType == null)
            {
                ExceptionLogService.LogException($"StepChangeTransaction failed. Step Type does not exist [StepTypeId={ StepTypeId }].");
                return(null);
            }

            var stepTypeTriggers = stepType.StepWorkflowTriggers
                                   .Where(w => w.TriggerType != StepWorkflowTrigger.WorkflowTriggerCondition.Manual)
                                   .ToList();

            triggers.AddRange(stepTypeTriggers);

            var stepProgramId = stepType.StepProgramId;

            // Get the triggers associated with the Step Program to which this Step is related, but are not associated with a specific Step Type.
            var stepProgramService = new StepProgramService(dataContext);

            var stepProgram = stepProgramService.Queryable()
                              .AsNoTracking()
                              .Include(x => x.StepWorkflowTriggers)
                              .FirstOrDefault(x => x.Id == stepProgramId);

            if (stepProgram == null)
            {
                ExceptionLogService.LogException($"StepChangeTransaction failed. Step Program does not exist [StepProgramId={ stepProgramId }].");
                return(null);
            }

            var stepProgramTriggers = stepProgram.StepWorkflowTriggers
                                      .Where(w => w.StepTypeId == null &&
                                             w.TriggerType != StepWorkflowTrigger.WorkflowTriggerCondition.Manual)
                                      .ToList();

            triggers.AddRange(stepProgramTriggers);

            return(triggers);
        }
Example #7
0
        /// <summary>
        /// Populates the selection lists for Step Type and Step Status.
        /// </summary>
        /// <param name="stepProgramId">The Step Program identifier.</param>
        private void PopulateStepProgramRelatedSelectionLists(int?stepProgramId)
        {
            var dataContext = new RockContext();

            var programService = new StepProgramService(dataContext);

            StepProgram stepProgram = null;

            if (stepProgramId != null)
            {
                stepProgram = programService.Get(stepProgramId.Value);
            }

            if (stepProgram != null)
            {
                // Step Type list
                _cblStepType.Items.Clear();

                var stepTypeService = new StepTypeService(dataContext);

                var stepTypes = stepTypeService.Queryable().Where(x => x.StepProgramId == stepProgramId);

                foreach (var item in stepTypes)
                {
                    _cblStepType.Items.Add(new ListItem(item.Name, item.Guid.ToString()));
                }

                _cblStepType.Visible = _cblStepType.Items.Count > 0;

                // Step Status list
                _cblStepStatus.Items.Clear();

                var stepStatusService = new StepStatusService(dataContext);

                var stepStatuses = stepStatusService.Queryable().Where(x => x.StepProgramId == stepProgramId);

                foreach (var item in stepStatuses)
                {
                    _cblStepStatus.Items.Add(new ListItem(item.Name, item.Guid.ToString()));
                }

                _cblStepStatus.Visible = _cblStepStatus.Items.Count > 0;
            }
            else
            {
                _cblStepType.Visible   = false;
                _cblStepStatus.Visible = false;
            }
        }
Example #8
0
        private void CreateWellKnownGuidToIdMap()
        {
            _GuidToIdMap = new Dictionary <Guid, int>();

            Dictionary <Guid, int> guidDictionary;

            var dataContext = new RockContext();

            // Add Step Types
            var stepTypeService = new StepTypeService(dataContext);

            guidDictionary = stepTypeService.Queryable().ToDictionary(k => k.Guid, v => v.Id);

            _GuidToIdMap = _GuidToIdMap.Union(guidDictionary).ToDictionary(k => k.Key, v => v.Value);

            // Add Step Statuses
            var stepStatusService = new StepStatusService(dataContext);

            guidDictionary = stepStatusService.Queryable().ToDictionary(k => k.Guid, v => v.Id);

            _GuidToIdMap = _GuidToIdMap.Union(guidDictionary).ToDictionary(k => k.Key, v => v.Value);

            // Add Person Aliases - Map Person Guid to PersonAlias.Id
            var personAliasService = new PersonAliasService(dataContext);

            var personService = new PersonService(dataContext);

            var personKnownGuids = new List <Guid>();

            personKnownGuids.Add(Constants.AlishaMarblePersonGuid);
            personKnownGuids.Add(Constants.BenJonesPersonGuid);
            personKnownGuids.Add(Constants.BillMarblePersonGuid);
            personKnownGuids.Add(Constants.BrianJonesPersonGuid);
            personKnownGuids.Add(Constants.SarahSimmonsPersonGuid);
            personKnownGuids.Add(Constants.TedDeckerPersonGuid);

            var knownPeople = personService.Queryable().Where(x => personKnownGuids.Contains(x.Guid));

            foreach (var knownPerson in knownPeople)
            {
                _GuidToIdMap.Add(knownPerson.Guid, knownPerson.PrimaryAliasId ?? 0);
            }
        }
Example #9
0
        /// <summary>
        /// Set the ordinal position of an item in the list.
        /// </summary>
        /// <param name="oldIndex"></param>
        /// <param name="newIndex"></param>
        private void ReorderStepType(int oldIndex, int newIndex)
        {
            if (_program == null)
            {
                return;
            }

            var rockContext = this.GetDataContext();

            var service = new StepTypeService(rockContext);

            var stepTypes = service.Queryable()
                            .Where(x => x.StepProgramId == _program.Id)
                            .OrderBy(b => b.Order)
                            .ToList();

            service.Reorder(stepTypes, oldIndex, newIndex);

            rockContext.SaveChanges();

            this.BindGrid();
        }
Example #10
0
        /// <summary>
        /// Gets the models from the delimited values.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="stepProgram">The step program</param>
        /// <param name="stepType">The step type</param>
        private void GetModelsFromAttributeValue(string value, out StepProgram stepProgram, out StepType stepType)
        {
            stepProgram = null;
            stepType    = null;

            ParseDelimitedGuids(value, out var stepProgramGuid, out var stepTypeGuid);

            if (stepProgramGuid.HasValue || stepTypeGuid.HasValue)
            {
                var rockContext = new RockContext();

                if (stepProgramGuid.HasValue)
                {
                    var stepProgramService = new StepProgramService(rockContext);
                    stepProgram = stepProgramService.Queryable().AsNoTracking().FirstOrDefault(sp => sp.Guid == stepProgramGuid.Value);
                }

                if (stepTypeGuid.HasValue)
                {
                    var stepTypeService = new StepTypeService(rockContext);
                    stepType = stepTypeService.Queryable().AsNoTracking().FirstOrDefault(sp => sp.Guid == stepTypeGuid.Value);
                }
            }
        }
Example #11
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);
        }
Example #12
0
        /// <summary>
        /// Formats the selection.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override string FormatSelection(Type entityType, string selection)
        {
            string result = "Steps taken";

            var settings = new FilterSettings(selection);

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

            var dataContext = new RockContext();

            // Step Program
            var stepProgram = this.GetStepProgram(dataContext, settings.StepProgramGuid);

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

            // Step Types
            List <StepType> stepTypes;

            if (settings.StepTypeGuids != null)
            {
                var stepTypeService = new StepTypeService(dataContext);

                stepTypes = stepTypeService.Queryable().Where(a => settings.StepTypeGuids.Contains(a.Guid)).ToList();
            }
            else
            {
                stepTypes = new List <StepType>();
            }

            // Step Statuses
            List <StepStatus> stepStatuses;

            if (settings.StepStatusGuids != null)
            {
                var stepStatusService = new StepStatusService(dataContext);

                stepStatuses = stepStatusService.Queryable().Where(a => settings.StepStatusGuids.Contains(a.Guid)).ToList();
            }
            else
            {
                stepStatuses = new List <StepStatus>();
            }

            // Step Campuses
            List <CampusCache> stepCampuses;

            if (settings.StepCampusGuids != null)
            {
                stepCampuses = CampusCache.All().Where(a => settings.StepCampusGuids.Contains(a.Guid)).ToList();
            }
            else
            {
                stepCampuses = new List <CampusCache>();
            }

            result += string.Format(" in Program: {0}", stepProgram.Name);

            if (stepTypes.Any())
            {
                result += string.Format(", in Step: {0}", stepTypes.Select(a => a.Name).ToList().AsDelimited(","));
            }

            if (stepStatuses.Any())
            {
                result += string.Format(", with Status: {0}", stepStatuses.Select(a => a.Name).ToList().AsDelimited(","));
            }

            // Start Date
            if (settings.StartedInPeriod != null &&
                settings.StartedInPeriod.Range != TimePeriodRangeSpecifier.All)
            {
                result += string.Format(", with Date Started: {0}", settings.StartedInPeriod.GetDescription());
            }

            // Completion Date
            if (settings.CompletedInPeriod != null &&
                settings.CompletedInPeriod.Range != TimePeriodRangeSpecifier.All)
            {
                result += string.Format(", with Date Completed: {0}", settings.CompletedInPeriod.GetDescription());
            }

            if (stepCampuses.Any())
            {
                result += string.Format(", at Campus: {0}", stepCampuses.Select(a => a.Name).ToList().AsDelimited(","));
            }

            return(result);
        }
        /// <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());
        }
Example #14
0
        public void AddStepsRandomParticipationEntries()
        {
            // Get a complete set of active Step Types ordered by Program and structure order.
            var dataContext = new RockContext();

            var programService = new StepProgramService(dataContext);

            var programIdList = programService.Queryable().Where(x => x.StepTypes.Any()).OrderBy(x => x.Order).Select(x => x.Id).ToList();

            var statusService = new StepStatusService(dataContext);

            var statuses = statusService.Queryable().ToList();

            // Get a random selection of people that are not system users or specific users for which test data already exists.
            var personService = new PersonService(dataContext);

            int tedPersonAliasId = 0;

            var testPeopleIdList = new List <int> {
                tedPersonAliasId
            };

            var personQuery = personService.Queryable().Where(x => !x.IsSystem && x.LastName != "Anonymous" && !testPeopleIdList.Contains(x.Id)).Select(x => x.Id);

            var personAliasService = new PersonAliasService(dataContext);

            var personAliasIdList = personAliasService.Queryable().Where(x => personQuery.Contains(x.PersonId)).Select(x => x.Id).ToList();

            var personAliasIdQueue = new Queue <int>(personAliasIdList.GetRandomizedList(_MaxPersonCount));

            int      stepCounter   = 0;
            int      personAliasId = 0;
            int      stepProgramId = 0;
            DateTime startDateTime = RockDateTime.Now;
            DateTime newStepDateTime;
            int      campusId;
            int      maxStepTypeCount;
            int      stepsToAddCount;
            int      offsetDays;
            int      personCounter = 0;
            bool     isCompleted;

            // Loop through the set of people, adding at least 1 program and 1 step for each person.
            var rng = new Random();

            var typeService = new StepTypeService(dataContext);

            var stepTypesAll = typeService.Queryable().ToList();

            var campusList = CampusCache.All();

            StepService stepService = null;

            while (personAliasIdQueue.Any())
            {
                personAliasId = personAliasIdQueue.Dequeue();

                personCounter += 1;

                // Randomly select the Programs that this person will participate in.
                var addProgramCount = rng.Next(1, programIdList.Count + 1);

                var programsToAdd = new Queue <int>(programIdList.GetRandomizedList(addProgramCount));

                while (programsToAdd.Any())
                {
                    stepProgramId = programsToAdd.Dequeue();

                    newStepDateTime = startDateTime;

                    // Get a random campus at which the step was completed.
                    campusId = campusList.GetRandomElement().Id;

                    var stepStatuses = statusService.Queryable().Where(x => x.StepProgramId == stepProgramId).ToList();

                    maxStepTypeCount = stepTypesAll.Count(x => x.StepProgramId == stepProgramId);

                    // Randomly select a number of Steps that this person will achieve in the Program, in Step order.
                    // This creates a distribution weighted toward achievement of earlier Steps, which is the likely scenario for most Programs.
                    // Steps are added from last to first in reverse chronological order, with the last step being achieved in the current year.
                    stepsToAddCount = rng.Next(1, maxStepTypeCount);

                    Debug.Print($"Adding Steps: PersonAliasId: {personAliasId}, ProgramId={stepProgramId}, Steps={stepsToAddCount}");

                    var stepTypesToAdd = new Queue <StepType>(stepTypesAll.Take(stepsToAddCount).Reverse());

                    while (stepTypesToAdd.Any())
                    {
                        var stepTypeToAdd = stepTypesToAdd.Dequeue();

                        // If this is not the last step to be added for this person, make sure the status represents a completion.
                        if (stepTypesToAdd.Any())
                        {
                            isCompleted = true;
                        }
                        else
                        {
                            isCompleted = rng.Next(1, 100) <= _PercentChanceOfLastStepCompletion;
                        }

                        var eligibleStatuses = stepStatuses.Where(x => x.IsCompleteStatus == isCompleted).ToList();

                        // If there is no status that represents completion, allow any status.
                        if (eligibleStatuses.Count == 0)
                        {
                            eligibleStatuses = stepStatuses;
                        }

                        var newStatus = eligibleStatuses.GetRandomElement();

                        // Subtract a random number of days from the current step date to get a suitable date for the preceding step in the program.
                        offsetDays = rng.Next(1, _MaxDaysBetweenSteps);

                        newStepDateTime = newStepDateTime.AddDays(-1 * offsetDays);

                        var newStep = new Step();

                        newStep.StepTypeId = stepTypeToAdd.Id;

                        if (newStatus != null)
                        {
                            newStep.StepStatusId = newStatus.Id;
                        }

                        newStep.PersonAliasId = personAliasId;
                        newStep.CampusId      = campusId;
                        newStep.StartDateTime = newStepDateTime;

                        if (isCompleted)
                        {
                            newStep.CompletedDateTime = newStepDateTime;
                        }

                        newStep.ForeignKey = _SampleDataForeignKey;

                        if (stepService == null)
                        {
                            var stepDataContext = new RockContext();

                            stepService = new StepService(stepDataContext);
                        }

                        stepService.Add(newStep);

                        // Save a batch of records and recycle the context to speed up processing.
                        if (stepCounter % 100 == 0)
                        {
                            stepService.Context.SaveChanges();

                            stepService = null;
                        }

                        stepCounter++;
                    }
                }
            }

            Debug.Print($"--> Created {stepCounter} steps for {personCounter} people.");
        }