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())); } }
/// <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)); } } }