Example #1
0
        /// <summary>
        /// Resumes a <see cref="Altask.Data.Model.Occurrence"/>.
        /// </summary>
        /// <param name="occurrenceId"></param>
        /// <param name="userId"></param>
        /// <returns>Returns a <see cref="Altask.Data.EntityResult"/> indicating success or failure.</returns>
        public virtual async Task <ActionResult> Resume(long occurrenceId, int userId)
        {
            ThrowIfDisposed();

            var userEntity = await Context.Users.FindAsync(userId);

            if (userEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExist("User")));
            }

            var occurrenceEntity = await Context.Occurrences.FindAsync(occurrenceId);

            if (occurrenceEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExist("Occurrence")));
            }

            if (!occurrenceEntity.Started.GetValueOrDefault(false))
            {
                return(BadRequest(ErrorDescriber.DefaultError("Occurrence has not been started.")));
            }

            if (occurrenceEntity.Completed.GetValueOrDefault(false))
            {
                return(BadRequest(ErrorDescriber.DefaultError("Occurrence has already been completed.")));
            }

            if (!occurrenceEntity.StoppedOn.HasValue)
            {
                return(BadRequest(ErrorDescriber.DefaultError("Occurrence cannot be resumed. The occurrence was not stopped.")));
            }

            occurrenceEntity.ResumedBy = userEntity.UserName;
            occurrenceEntity.ResumedOn = DateTime.Now;
            occurrenceEntity.Logs.Add(new Data.Model.OccurrenceLog()
            {
                Type = "Resumed"
            });
            Context.Entry(occurrenceEntity).State = EntityState.Modified;
            var result = await Context.SaveChangesAsync();

            if (result.Succeeded)
            {
                await AfterUpdateAsync(occurrenceEntity);

                var taskEntity = await Context.Tasks.FindAsync(occurrenceEntity.TaskId);

                var scheduleEntity = await Context.Schedules.FindAsync(occurrenceEntity.ScheduleId);

                var instance = TaskInstance.FromSchedule(taskEntity, occurrenceEntity.Date, scheduleEntity).MergeOccurrence(occurrenceEntity);
                SignalRHub.NotifyOccurrenceCreate(null, instance, occurrenceEntity.ToDto());
                return(Ok(new { instance = instance }));
            }
            else
            {
                return(BadRequest(result));
            }
        }
Example #2
0
        private async Task <EntityResult <TaskInstance> > AddSingleOccurrence(Data.Model.Task task, Data.Model.Schedule scheduleEntity, int?assetId, int?userId, DateTime date)
        {
            date = date.LessSeconds();
            Context.Entry(task).Reference(t => t.Form).Load();

            var newOccurrence = new Altask.Data.Model.Occurrence()
            {
                AsEarlyAsDate = date,
                Date          = date,
                FormModel     = task.Form.PublishedModel,
                TaskId        = task.Id,
                TimeSpent     = 0,
                ScheduleId    = scheduleEntity.Id,
            };

            var assetEntity = await Context.Assets.FindAsync(assetId);

            if (assetEntity != null)
            {
                newOccurrence.AssetId = assetEntity.Id;
            }

            var userEntity = await Context.Users.FindAsync(userId);

            if (userEntity != null)
            {
                newOccurrence.UserId = userEntity.Id;
            }

            if (assetEntity == null && userEntity == null)
            {
                return(EntityResult <TaskInstance> .Failed(ErrorDescriber.DefaultError("An occurrence must have either and asset or user associated to it.")));
            }

            newOccurrence.Logs.Add(new Data.Model.OccurrenceLog()
            {
                Type = "Created"
            });
            Context.Occurrences.Add(newOccurrence);
            BeforeCreate(newOccurrence, newOccurrence.ToDto());
            var result = await Context.SaveChangesAsync();

            if (result.Succeeded)
            {
                await AfterCreateAsync(newOccurrence, true);

                var instance = TaskInstance.FromSchedule(task, newOccurrence.Date, scheduleEntity).MergeOccurrence(newOccurrence);
                SignalRHub.NotifyOccurrenceCreate(null, instance, newOccurrence.ToDto());
                return(EntityResult <TaskInstance> .Succeded(instance));
            }
            else
            {
                return(EntityResult <TaskInstance> .Failed(result.Errors.ToArray()));
            }
        }
Example #3
0
        internal override async Task <EntityResult> AfterUpdateAsync(Data.Model.Occurrence entity, bool notifyAll = false)
        {
            await Context.Entry(entity).Reference(e => e.Asset).LoadAsync();

            await Context.Entry(entity).Reference(e => e.User).LoadAsync();

            await Context.Entry(entity).Reference(e => e.Task).LoadAsync();

            await Context.Entry(entity).Reference(e => e.Schedule).LoadAsync();

            var instance = TaskInstance.FromSchedule(entity.Task, entity.Date, entity.Schedule).MergeOccurrence(entity);

            SignalRHub.NotifyOccurrenceUpdate(ClientId, instance, entity.ToDto());
            return(EntityResult.Succeded(0));
        }
Example #4
0
        /// <summary>
        /// Completes a <see cref="Altask.Data.Model.Occurrence"/>.
        /// </summary>
        /// <param name="occurrenceId"></param>
        /// <param name="userId"></param>
        /// <param name="formModel"></param>
        /// <returns>Returns a <see cref="Altask.Data.EntityResult"/> indicating success or failure.</returns>
        public virtual async Task <ActionResult> Complete(long occurrenceId, int userId, string formModel)
        {
            ThrowIfDisposed();

            if (formModel == null)
            {
                return(BadRequest(ErrorDescriber.DefaultError("A valid FormModel representing the occurrences results must be specified.")));
            }

            var userEntity = await Context.Users.FindAsync(userId);

            if (userEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExist("User")));
            }

            var occurrenceEntity = await Context.Occurrences.FindAsync(occurrenceId);

            if (occurrenceEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExist("Occurrence")));
            }

            if (!occurrenceEntity.Started.GetValueOrDefault(false))
            {
                return(BadRequest(ErrorDescriber.DefaultError("Occurrence cannot be completed. The occurrence has not been started.")));
            }

            if (occurrenceEntity.Completed.GetValueOrDefault(false))
            {
                return(BadRequest(ErrorDescriber.DefaultError("Occurrence already completed")));
            }

            if (occurrenceEntity.StoppedOn.HasValue && !occurrenceEntity.ResumedOn.HasValue)
            {
                return(BadRequest(ErrorDescriber.DefaultError("Occurrence cannot be completed. The occurrence was stopped and has not yet been resumed.")));
            }

            occurrenceEntity.Completed   = true;
            occurrenceEntity.CompletedBy = userEntity.UserName;
            occurrenceEntity.CompletedOn = DateTime.Now;
            occurrenceEntity.FormModel   = formModel;
            occurrenceEntity.TimeSpent  += (int)DateTime.Now.Subtract(occurrenceEntity.ResumedOn.GetValueOrDefault(occurrenceEntity.StartedOn.Value)).TotalSeconds;
            occurrenceEntity.StoppedBy   = null;
            occurrenceEntity.StoppedOn   = null;
            occurrenceEntity.ResumedBy   = null;
            occurrenceEntity.ResumedOn   = null;
            occurrenceEntity.Logs.Add(new Data.Model.OccurrenceLog()
            {
                Type = "Completed"
            });
            Context.Entry(occurrenceEntity).State = EntityState.Modified;
            var result = await Context.SaveChangesAsync();

            if (result.Succeeded)
            {
                await AfterUpdateAsync(occurrenceEntity);

                var taskEntity = await Context.Tasks.FindAsync(occurrenceEntity.TaskId);

                var scheduleEntity = await Context.Schedules.FindAsync(occurrenceEntity.ScheduleId);

                var instance = TaskInstance.FromSchedule(taskEntity, occurrenceEntity.Date, scheduleEntity).MergeOccurrence(occurrenceEntity);
                SignalRHub.NotifyOccurrenceCreate(null, instance, occurrenceEntity.ToDto());
                return(Ok(new { instance = instance }));
            }
            else
            {
                return(BadRequest(result));
            }
        }
Example #5
0
        /// <summary>
        /// Adds an <see cref="Altask.Data.Model.Occurrence"/> based on the <see cref="Altask.Data.Model.Schedule"/>.
        /// </summary>
        /// <param name="schedule"></param>
        /// <returns>Returns a <see cref="Altask.Data.EntityResult"/> indicating success or failure.</returns>
        public virtual async Task <ActionResult> AddAndStart(long scheduleId, int?assetId, int?userId, DateTime date, int startedByUserId)
        {
            date = date.LessSeconds();
            ThrowIfDisposed();

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var scheduleEntity = await Context.Schedules.FindAsync(scheduleId);

            if (scheduleEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExist("Schedule")));
            }

            if (scheduleEntity.EndsOn.HasValue && scheduleEntity.EndsOn.Value < DateTime.Now)
            {
                return(BadRequest(ErrorDescriber.DefaultError("No more occurrences can be created for the associated Schedule.  The Schedule has ended.")));
            }

            if (scheduleEntity.EndsAfter.HasValue)
            {
                var pastOccurrences = await Context.Occurrences.Where(o => o.ScheduleId == scheduleEntity.Id && o.Date != date).ToListAsync();

                if (pastOccurrences.Count == scheduleEntity.EndsAfter.Value)
                {
                    return(BadRequest(ErrorDescriber.DefaultError("Not more occurrences can be created for the associated Schedule.  The maximum number of occurrences have been created.")));
                }
            }

            var taskEntity = await Context.Tasks.FindAsync(scheduleEntity.TaskId);

            await Context.Entry(taskEntity).Reference(t => t.Form).LoadAsync();

            if (taskEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExistFor("Task", "Schedule")));
            }

            var startedByEntity = await Context.Users.FindAsync(startedByUserId);

            if (startedByEntity == null)
            {
                return(BadRequest(ErrorDescriber.DoesNotExist("User")));
            }

            date = date.Date.Add(scheduleEntity.StartsOn.TimeOfDay).LessSeconds();
            var occurrenceEntity = await Context.Occurrences.FirstOrDefaultAsync(o => o.ScheduleId == scheduleEntity.Id && o.Date == date &&
                                                                                 (assetId.HasValue ? (userId.HasValue ? o.AssetId == assetId && o.UserId == userId : o.AssetId == assetId && o.UserId == null) :
                                                                                  (userId.HasValue ? o.UserId == userId && o.AssetId == null : o.AssetId == null && o.UserId == null)));

            if (occurrenceEntity != null)
            {
                if (!occurrenceEntity.Started.GetValueOrDefault(false))
                {
                    occurrenceEntity.Started   = true;
                    occurrenceEntity.StartedBy = startedByEntity.UserName;
                    occurrenceEntity.StartedOn = DateTime.Now;
                    occurrenceEntity.TimeSpent = 0;
                    occurrenceEntity.Logs.Add(new Data.Model.OccurrenceLog()
                    {
                        Type = "Started"
                    });
                    Context.Entry(occurrenceEntity).State = EntityState.Modified;
                    var result = await Context.SaveChangesAsync();

                    if (result.Succeeded)
                    {
                        await AfterUpdateAsync(occurrenceEntity);

                        var instance = TaskInstance.FromSchedule(taskEntity, occurrenceEntity.Date, scheduleEntity).MergeOccurrence(occurrenceEntity);
                        SignalRHub.NotifyOccurrenceCreate(null, instance, occurrenceEntity.ToDto());
                        return(Ok(new { instance = instance }));
                    }
                    else
                    {
                        return(BadRequest(result));
                    }
                }

                var existing = TaskInstance.FromSchedule(taskEntity, occurrenceEntity.Date, scheduleEntity).MergeOccurrence(occurrenceEntity);
                SignalRHub.NotifyOccurrenceCreate(null, existing, occurrenceEntity.ToDto());
                return(Ok(new { instance = existing }));
            }
            else
            {
                var newOccurrence = new Altask.Data.Model.Occurrence()
                {
                    Date       = date,
                    FormModel  = taskEntity.Form.PublishedModel,
                    Started    = true,
                    StartedBy  = startedByEntity.UserName,
                    StartedOn  = DateTime.Now,
                    TaskId     = taskEntity.Id,
                    TimeSpent  = 0,
                    ScheduleId = scheduleEntity.Id
                };

                var assetEntity = await Context.Assets.FindAsync(assetId);

                if (assetEntity != null)
                {
                    newOccurrence.AssetId = assetEntity.Id;
                }

                var userEntity = await Context.Users.FindAsync(userId);

                if (userEntity != null)
                {
                    newOccurrence.UserId = userEntity.Id;
                }

                if (assetEntity == null && userEntity == null)
                {
                    return(BadRequest(ErrorDescriber.DefaultError("An occurrence must have either and asset or user associated to it.")));
                }

                newOccurrence.Logs.Add(new Data.Model.OccurrenceLog()
                {
                    Type = "Created"
                });
                newOccurrence.Logs.Add(new Data.Model.OccurrenceLog()
                {
                    Type = "Started"
                });
                Context.Occurrences.Add(newOccurrence);
                BeforeCreate(newOccurrence, newOccurrence.ToDto());
                var result = await Context.SaveChangesAsync();

                if (result.Succeeded)
                {
                    await AfterCreateAsync(newOccurrence);

                    var instance = TaskInstance.FromSchedule(taskEntity, newOccurrence.Date, scheduleEntity).MergeOccurrence(newOccurrence);
                    SignalRHub.NotifyOccurrenceCreate(null, instance, newOccurrence.ToDto());
                    return(Ok(new { instance = instance }));
                }
                else
                {
                    return(BadRequest(result));
                }
            }
        }
Example #6
0
        public void Run()
        {
            while (!Terminated)
            {
                _lastRun = DateTime.Now;

                if (!Settings.TaskAlertServiceActive)
                {
                    Thread.Sleep(5000);
                    continue;
                }

                try {
                    using (_context = new ApplicationDbContext("TaskAlertService")) {
                        var settings = _context.Settings.Where(s => s.Area == "System" && s.Classification == "Email").ToList();
                        _emailService = new EmailService(settings.Single(s => s.Name == "SmtpAddress").Value,
                                                         int.Parse(settings.Single(s => s.Name == "SmtpPort").Value),
                                                         settings.Single(s => s.Name == "UserName").Value,
                                                         settings.Single(s => s.Name == "Password").Value);

                        var count = 0;

                        using (var command = new SqlCommand("[dbo].[GetTaskAlertCount]", _context.Database.Connection as SqlConnection)) {
                            bool closeConnection = false;

                            if (command.Connection.State != ConnectionState.Open)
                            {
                                command.Connection.Open();
                                closeConnection = true;
                            }

                            command.CommandTimeout = 300;
                            command.CommandType    = System.Data.CommandType.StoredProcedure;
                            command.Parameters.Add(new SqlParameter("@LastDate", _lastDate));
                            command.Parameters.Add(new SqlParameter("@OffsetPast", Settings.TaskAlertServiceOffsetPast));
                            command.Parameters.Add(new SqlParameter("@OffsetFuture", Settings.TaskAlertServiceOffsetFuture));
                            count = Convert.ToInt32(command.ExecuteScalar());

                            if (closeConnection)
                            {
                                command.Connection.Close();
                            }
                        }

                        if (count != _lastCount)
                        {
                            _lastCount = count;
                            _lastDate  = DateTime.Now;
                            _instances.Clear();
                            _tasks = _context.Tasks.AsNoTracking().Where(t => t.Alerts.Any(ta => ta.Active))
                                     .Include(e => e.Alerts)
                                     .Include(e => e.Schedules)
                                     .ToList();
                            _assets = _context.Assets.AsNoTracking().ToList();
                            _users  = _context.Users.AsNoTracking().ToList();

                            foreach (var task in _tasks)
                            {
                                foreach (var schedule in task.Schedules)
                                {
                                    var dtoSchedule = schedule.ToDto();
                                    var dates       = dtoSchedule.GetRunDates(DateTime.Now.AddDays(Settings.TaskAlertServiceOffsetPast), DateTime.Now.AddDays(Settings.TaskAlertServiceOffsetFuture));

                                    foreach (var date in dates)
                                    {
                                        if (dtoSchedule.Assets.Count > 0)
                                        {
                                            foreach (var asset in dtoSchedule.Assets)
                                            {
                                                if (dtoSchedule.Users.Count > 0)
                                                {
                                                    foreach (var user in dtoSchedule.Users)
                                                    {
                                                        var instance   = TaskInstance.FromSchedule(task, date, schedule);
                                                        var occurrence = _context.Occurrences.AsNoTracking().SingleOrDefault(o => o.ScheduleId == schedule.Id && o.AssetId == asset.AssetId && o.UserId == user.Id && o.Date == date);

                                                        if (occurrence != null)
                                                        {
                                                            instance.MergeOccurrence(occurrence);
                                                        }
                                                        else
                                                        {
                                                            instance.AssetId = asset.AssetId;
                                                            instance.Asset   = asset.Asset;
                                                            instance.UserId  = user.UserId;
                                                            instance.User    = user.User;
                                                        }

                                                        _instances.Add(instance);
                                                    }
                                                }
                                                else
                                                {
                                                    var instance   = TaskInstance.FromSchedule(task, date, schedule);
                                                    var occurrence = _context.Occurrences.AsNoTracking().SingleOrDefault(o => o.ScheduleId == schedule.Id && o.AssetId == asset.AssetId && o.Date == date);

                                                    if (occurrence != null)
                                                    {
                                                        instance.MergeOccurrence(occurrence);
                                                    }
                                                    else
                                                    {
                                                        instance.AssetId = asset.AssetId;
                                                        instance.Asset   = asset.Asset;
                                                    }

                                                    _instances.Add(instance);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            foreach (var user in dtoSchedule.Users)
                                            {
                                                var instance   = TaskInstance.FromSchedule(task, date, schedule);
                                                var occurrence = _context.Occurrences.AsNoTracking().SingleOrDefault(o => o.ScheduleId == schedule.Id && o.UserId == user.UserId && o.Date == date);

                                                if (occurrence != null)
                                                {
                                                    instance.MergeOccurrence(occurrence);
                                                }
                                                else
                                                {
                                                    instance.UserId = user.UserId;
                                                    instance.User   = user.User;
                                                }

                                                _instances.Add(instance);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (var instance in _instances)
                        {
                            var task = _tasks.FirstOrDefault(t => t.Id == instance.TaskId);
                            SendAlerts(instance, task.Alerts.ToArray());
                        }
                    }

                    if (Settings.TaskAlertServiceThrottle > 0)
                    {
                        Thread.Sleep(1000 * Settings.TaskAlertServiceThrottle);
                    }
                }
                catch (ThreadAbortException)
                {
                    Run();
                }
                catch (Exception ex) {
                    EventLog.WriteEntry(Settings.EventLogSource, string.Format("The Task Alert Service encountered the following error: {0}\n\n{1}", ex.Message, ex.StackTrace), EventLogEntryType.Error);
                    _errorCount++;

                    if (_errorCount == 100)
                    {
                        EventLog.WriteEntry(Settings.EventLogSource, "The Task Alert Service has encountered too many errors in succession.  It will be automatically shut down.", EventLogEntryType.Warning);
                        Terminated  = true;
                        _errorCount = 0;
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Returns a collection of <see cref="Altask.Data.Model.Task"/> objects matching the specified filter.
        /// </summary>
        /// <param name="filter">A <see cref="Altask.www.Models.TaskListOptions"/> object on which to filter.</param>
        /// <returns>Returns a <see cref="Altask.Data.EntityResult"/> indicating success or failure.</returns>
        public virtual async Task <ActionResult> ProjectTo(ProjectToOptions filter)
        {
            ThrowIfDisposed();

            if (filter == null)
            {
                filter = new ProjectToOptions();
            }

            var fromDate  = filter.FromDate;
            var toDate    = filter.ToDate;
            var instances = new List <TaskInstance>();

            if (fromDate <= DateTime.Now)
            {
                filter.ToDate = DateTime.Now;

                var pastOccurrences = await Context.Occurrences.AsNoTracking().Where(filter.GetOccurrencePredicate())
                                      .Include(e => e.Task)
                                      .Include(e => e.Schedule)
                                      .ToListAsync();

                foreach (var occurrence in pastOccurrences)
                {
                    var instance = TaskInstance.FromSchedule(occurrence.Task, occurrence.Date, occurrence.Schedule);
                    instance.MergeOccurrence(occurrence);
                    instances.Add(instance);
                }

                filter.FromDate = DateTime.Now;
            }


            filter.ToDate = toDate;

            var tasks = await Context.Tasks.AsNoTracking().Where(filter.GetTaskPredicate())
                        .Include(e => e.Form)
                        .Include(e => e.Schedules)
                        .ToListAsync();

            var occurrences = await Context.Occurrences.AsNoTracking().Where(filter.GetOccurrencePredicate()).ToListAsync();

            var userIds  = filter.GetUserIds();
            var assetIds = filter.GetAssetIds();

            foreach (var task in tasks)
            {
                foreach (var schedule in task.Schedules)
                {
                    var dtoSchedule = schedule.ToDto();
                    var dates       = dtoSchedule.GetRunDates(filter.FromDate, filter.ToDate);

                    foreach (var date in dates)
                    {
                        if (dtoSchedule.Assets.Count > 0)
                        {
                            foreach (var asset in dtoSchedule.Assets)
                            {
                                if (assetIds.Count > 0 && !assetIds.Contains(asset.AssetId))
                                {
                                    continue;
                                }

                                if (dtoSchedule.Users.Count > 0)
                                {
                                    foreach (var user in dtoSchedule.Users)
                                    {
                                        if (userIds.Count > 0 && !userIds.Contains(user.UserId))
                                        {
                                            continue;
                                        }

                                        var instance   = TaskInstance.FromSchedule(task, date, schedule);
                                        var occurrence = occurrences.SingleOrDefault(o => o.ScheduleId == schedule.Id && o.AssetId == asset.AssetId && o.UserId == user.Id && o.Date == date);

                                        if (occurrence != null)
                                        {
                                            instance.MergeOccurrence(occurrence);
                                        }
                                        else
                                        {
                                            instance.AssetId = asset.AssetId;
                                            instance.Asset   = asset.Asset;
                                            instance.UserId  = user.UserId;
                                            instance.User    = user.User;
                                        }

                                        instances.Add(instance);
                                    }
                                }
                                else
                                {
                                    var instance   = TaskInstance.FromSchedule(task, date, schedule);
                                    var occurrence = occurrences.SingleOrDefault(o => o.ScheduleId == schedule.Id && o.AssetId == asset.AssetId && o.Date == date);

                                    if (occurrence != null)
                                    {
                                        instance.MergeOccurrence(occurrence);
                                    }
                                    else
                                    {
                                        instance.AssetId = asset.AssetId;
                                        instance.Asset   = asset.Asset;
                                    }

                                    instances.Add(instance);
                                }
                            }
                        }
                        else
                        {
                            foreach (var user in dtoSchedule.Users)
                            {
                                if (userIds.Count > 0 && !userIds.Contains(user.UserId))
                                {
                                    continue;
                                }

                                var instance   = TaskInstance.FromSchedule(task, date, schedule);
                                var occurrence = occurrences.SingleOrDefault(o => o.ScheduleId == schedule.Id && o.UserId == user.UserId && o.Date == date);

                                if (occurrence != null)
                                {
                                    instance.MergeOccurrence(occurrence);
                                }
                                else
                                {
                                    instance.UserId = user.UserId;
                                    instance.User   = user.User;
                                }

                                instances.Add(instance);
                            }
                        }
                    }
                }
            }

            return(Ok(new { tasks = instances }, JsonRequestBehavior.AllowGet));
        }
Example #8
0
        public void Run()
        {
            while (!Terminated)
            {
                _lastRun = DateTime.Now;

                if (!Settings.OccurrenceServiceActive)
                {
                    Thread.Sleep(5000);
                    continue;
                }

                try {
                    var instances = new List <TaskInstance>();

                    using (_context = new ApplicationDbContext("OccurrenceService")) {
                        // Joe - Removing "count" check since it's not a very accurate way to determine
                        // if work needs to be done.
                        //using (var command = new SqlCommand("[dbo].[GetTaskOccurrenceCount]", _context.Database.Connection as SqlConnection)) {
                        //    bool closeConnection = false;

                        //    if (command.Connection.State != ConnectionState.Open) {
                        //        command.Connection.Open();
                        //        closeConnection = true;
                        //    }

                        //    command.CommandTimeout = 300;
                        //    command.CommandType = System.Data.CommandType.StoredProcedure;
                        //    command.Parameters.Add(new SqlParameter("@LastDate", _lastDate));
                        //    var count = Convert.ToInt32(command.ExecuteScalar());

                        //    if (closeConnection) {
                        //        command.Connection.Close();
                        //    }
                        //}

                        // Removing _tasks cache since it held a reference to (and mght have used) a dbcontext which was disposed.
                        var tasks = _context.Tasks.AsNoTracking().Where(t => t.Schedules.Any(s => s.Active))
                                    .Include(e => e.Alerts)
                                    .Include(e => e.Schedules)
                                    .ToList();

                        foreach (var task in tasks)
                        {
                            if (task.Id == 20097)
                            {
                                var s = "";
                                Debug.Print(s);
                            }

                            if (!task.Active)
                            {
                                continue;
                            }

                            foreach (var schedule in task.Schedules)
                            {
                                if (!schedule.Active)
                                {
                                    continue;
                                }

                                var dtoSchedule = schedule.ToDto();
                                var dates       = dtoSchedule.GetRunDates(DateTime.Now.AddDays(Settings.OccurrenceServiceOffset), DateTime.Now);

                                foreach (var date in dates)
                                {
                                    if (dtoSchedule.Assets.Count > 0)
                                    {
                                        foreach (var asset in dtoSchedule.Assets)
                                        {
                                            if (dtoSchedule.Users.Count > 0)
                                            {
                                                foreach (var user in dtoSchedule.Users)
                                                {
                                                    var instance = TaskInstance.FromSchedule(task, date, schedule);

                                                    if (!DoesOccurrenceExist(schedule.Id, asset.AssetId, user.UserId, date))
                                                    {
                                                        instance.AssetId = asset.AssetId;
                                                        instance.Asset   = asset.Asset;
                                                        instance.UserId  = user.UserId;
                                                        instance.User    = user.User;
                                                        instances.Add(instance);
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                var instance = TaskInstance.FromSchedule(task, date, schedule);

                                                if (!DoesOccurrenceExist(schedule.Id, asset.AssetId, null, date))
                                                {
                                                    instance.AssetId = asset.AssetId;
                                                    instance.Asset   = asset.Asset;
                                                    instances.Add(instance);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        foreach (var user in dtoSchedule.Users)
                                        {
                                            var instance = TaskInstance.FromSchedule(task, date, schedule);

                                            if (!DoesOccurrenceExist(schedule.Id, null, user.UserId, date))
                                            {
                                                instance.UserId = user.UserId;
                                                instance.User   = user.User;
                                                instances.Add(instance);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (var instance in instances)
                        {
                            CreateOccurrence(instance);
                        }

                        _errorCount = 0;

                        if (Settings.OccurrenceServiceThrottle > 0)
                        {
                            Thread.Sleep(1000 * Settings.OccurrenceServiceThrottle);
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    Run();
                }
                catch (ObjectDisposedException) {
                    _errorCount++;

                    if (_errorCount == 100)
                    {
                        throw;
                    }
                    else
                    {
                        Run();
                    }
                }
                catch (Exception ex) {
                    EventLog.WriteEntry(Settings.EventLogSource, string.Format("The Occurrence Service encountered the following error: {0}\n\n{1}", ex.Message, ex.StackTrace), EventLogEntryType.Error);
                    _errorCount++;

                    if (_errorCount == 100)
                    {
                        EventLog.WriteEntry(Settings.EventLogSource, "The Occurrence Service has encountered too many errors in succession.  It will be automatically shut down.", EventLogEntryType.Warning);
                        Terminated  = true;
                        _errorCount = 0;
                    }
                }
            }
        }