internal async Task <bool> SaveClonedProjectScheduleVersion(ProjectScheduleVersion model) { using (ApplicationDbContext db = new ApplicationDbContext()) { // remove oldest backup ProjectScheduleVersion // foreach loop is used to allow for changes to ProjectScheduleVersionBackupCount, i.e. multiple records might be returned from query var backupVersionsToDelete = await db.ProjectScheduleVersions.Where(v => v.ProjectID == model.ProjectID && v.VersionNum >= ProjectScheduleVersionBackupCount).ToListAsync(); foreach (ProjectScheduleVersion v in backupVersionsToDelete) { db.ProjectScheduleVersions.Remove(v); } await db.SaveChangesAsync(); // increment VersionNum of exsting ProjectScheduleVersions var existingVersionsToIncrement = await db.ProjectScheduleVersions.Where(v => v.ProjectID == model.ProjectID).OrderBy(v => v.VersionNum).ToListAsync(); existingVersionsToIncrement.First().SavedAt = DateTime.Now; existingVersionsToIncrement.First().Comments = model.Comments; foreach (ProjectScheduleVersion v in existingVersionsToIncrement) { v.VersionNum++; db.Entry(v).State = EntityState.Modified; } await db.SaveChangesAsync(); return(true); } }
internal async Task <int> CreateNewProject(CreateUserProjectViewModel viewModel) { using (ApplicationDbContext db = new ApplicationDbContext()) { // creat new UserProject record UserProject userProject = new UserProject(); userProject.InjectFrom(viewModel); userProject.CreatedAt = DateTime.Now; userProject.ModifiedAt = DateTime.Now; db.UserProjects.Add(userProject); await db.SaveChangesAsync(); // initialize blank ProjectScheduleVersion ProjectScheduleVersion schedule = new ProjectScheduleVersion(); schedule.ProjectID = userProject.ID; schedule.VersionNum = 1; schedule.CreatedAt = userProject.CreatedAt; schedule.SavedAt = userProject.CreatedAt; schedule.Comments = "[initialize project schedule]"; db.ProjectScheduleVersions.Add(schedule); await db.SaveChangesAsync(); // initialize 'project' GanttTask based on user-specified ProjectStartDate GanttTask initProject = new GanttTask() { ProjectID = userProject.ID, ProjectScheduleVersionID = schedule.ID, Text = viewModel.Name, StartDate = viewModel.ProjectStartDate, Duration = 1, Progress = 0m, SortOrder = 0, Type = "project", Open = true }; db.GanttTasks.Add(initProject); await db.SaveChangesAsync(); // initialize 'task' GanttTask for proper rendering of start/end dates in grid GanttTask initTask = new GanttTask() { ProjectID = userProject.ID, ProjectScheduleVersionID = schedule.ID, Text = "New Task", StartDate = viewModel.ProjectStartDate, Duration = 1, Progress = 0m, SortOrder = 1, Type = "task", ParentId = initProject.GanttTaskId }; db.GanttTasks.Add(initTask); await db.SaveChangesAsync(); return(userProject.ID); } }
internal async Task <Tuple <ProjectScheduleVersion, bool> > CloneProjectScheduleVersionForEdit(int projectId) { using (ApplicationDbContext db = new ApplicationDbContext()) { // check db for existing 'cloned' records that have been abandoned var abandonedSchedule = await db.ProjectScheduleVersions.Where(s => s.ProjectID == projectId && s.VersionNum == 0).FirstOrDefaultAsync(); if (abandonedSchedule != null) { return(Tuple.Create(abandonedSchedule, true)); // set AbandonedSchedule flag to true } // create new ProjectScheduleVersion for use during editing // user will have the option to discard edits, which will delete the new records ProjectScheduleVersion newSchedule = new ProjectScheduleVersion() { ProjectID = projectId, VersionNum = 0, // VersionNum = 0 denotes temporary 'clone' for editing CreatedAt = DateTime.Now, SavedAt = DateTime.Now }; db.ProjectScheduleVersions.Add(newSchedule); await db.SaveChangesAsync(); // initialize dictionary, used to crosswalk ParentId, SourceGanttTask, and TargetGanttTask values after cloning Dictionary <int, int> taskIdDictionary = new Dictionary <int, int>(); // identify current ProjectScheduleVersion (VersionNum = 1), then clone GanttLinks and GanttTasks int currentScheduleId = await GetProjectScheduleVersionId(projectId, 1); var existingGanttTasks = await db.GanttTasks.Where(t => t.ProjectScheduleVersionID == currentScheduleId).ToListAsync(); foreach (GanttTask t in existingGanttTasks) { int oldId = t.GanttTaskId; GanttTask newTask = new GanttTask(); newTask.InjectFrom(t); db.GanttTasks.Add(newTask); newTask.ProjectScheduleVersionID = newSchedule.ID; await db.SaveChangesAsync(); // must save record to generate new ID taskIdDictionary.Add(oldId, newTask.GanttTaskId); // log ID's in dictionary for crosswalk } var ganttLinks = await db.GanttLinks.Where(l => l.ProjectScheduleVersionID == currentScheduleId).ToListAsync(); foreach (GanttLink l in ganttLinks) { GanttLink newLink = new GanttLink(); newLink.InjectFrom(l); db.GanttLinks.Add(newLink); newLink.ProjectScheduleVersionID = newSchedule.ID; } await db.SaveChangesAsync(); // crosswalk ParentID values for GanttTasks var newGanttTasks = await db.GanttTasks.Where(t => t.ProjectScheduleVersionID == newSchedule.ID).ToListAsync(); foreach (GanttTask t in newGanttTasks) { if (t.ParentId != null) { int newId = taskIdDictionary[t.ParentId.Value]; t.ParentId = newId; db.Entry(t).State = EntityState.Modified; } } // crosswalk SourceTaskId and TargetTaskId values for GanttLinks var newGanttLinks = await db.GanttLinks.Where(l => l.ProjectScheduleVersionID == newSchedule.ID).ToListAsync(); foreach (GanttLink l in newGanttLinks) { int newSourceId = taskIdDictionary[l.SourceTaskId]; l.SourceTaskId = newSourceId; int newTargetId = taskIdDictionary[l.TargetTaskId]; l.TargetTaskId = newTargetId; db.Entry(l).State = EntityState.Modified; } await db.SaveChangesAsync(); return(Tuple.Create(newSchedule, false)); // set AbandonedSchedule flag to false } }