예제 #1
0
        public async Task <IActionResult> SubmitPost(Submission sub, Guid id, string stage, IEnumerable <IFormFile> uploadFiles)
        {
            if (ModelState.IsValid)
            {
                var asg = await _context.Assignments
                          .Include(a => a.Stages)
                          .Include(a => a.Course)
                          .Include(a => a.Groups)
                          .ThenInclude(g => g.Members)
                          .ThenInclude(gjt => gjt.ApplicationUser)
                          .SingleOrDefaultAsync(a => a.ID == id);

                var astage = asg.Stages.SingleOrDefault(stg => stg.Id == stage);

                var user = await _userManager.GetUserAsync(User);

                var group = asg.GroupFor(user);

                if (group != null)
                {
                    _context.Entry(group).Collection(g => g.Members).Load();
                }

                var presub = await _context.Submissions
                             .Include(s => s.AssignmentStage)
                             .Include(s => s.Submitter)
                             .Include(s => s.ForGroup)
                             .SingleOrDefaultAsync(s =>
                                                   s.AssignmentStage == astage &&
                                                   (s.Submitter.Id == user.Id || (group != null && s.ForGroup.ID == group.ID)));

                if (astage == null || presub != null)
                {
                    return(NotFound());
                }

                var filerefs = new List <FileRef>();

                foreach (IFormFile f in uploadFiles)
                {
                    var fileref = new FileRef
                    {
                        ID          = Guid.NewGuid(),
                        Owner       = user,
                        Name        = f.FileName,
                        ContentType = f.ContentType,
                    };

                    using (var stream = fileref.Open(_config["Storage:BasePath"], FileMode.Create))
                    {
                        await f.CopyToAsync(stream);
                    }

                    await _context.FileRefs.AddAsync(fileref);

                    filerefs.Add(fileref);
                }

                sub.Submitter = user;
                sub.ForGroup  = group;
                // TODO: change to allow students to modify their submissions
                sub.Confirmed       = true;
                sub.AssignmentStage = astage;
                sub.ID        = Guid.NewGuid();
                sub.Files     = filerefs;
                sub.TimeStamp = DateTime.Now;

                if (group == null)
                {
                    var _stageHolder = await _context.StageHolders
                                       .SingleOrDefaultAsync(sh =>
                                                             sh.AssignmentID == asg.ID &&
                                                             sh.UserID == user.Id);

                    if (_stageHolder != null)
                    {
                        _stageHolder.CurrentStage += 1;
                        _context.Update(_stageHolder);
                    }
                    else
                    {
                        var newSH = new StageHolder
                        {
                            AssignmentID = asg.ID,
                            UserID       = user.Id,
                            CurrentStage = Assignment.START_STAGE + 1,
                        };
                        _context.Add(newSH);
                    }
                }
                else
                {
                    group.CurrentStage += 1;
                    _context.Update(group);
                }

                await _context.AddAsync(sub);

                // Feels wrong to await this. It should be a continuation of some kind that
                // doesn't need to be performed on this thread. Possibly Save Changes and
                // start an assignment pass
                if (astage.IsPeerReviewed)
                {
                    await ReviewPass(sub, astage.ReviewsPerStudent);
                }

                await _context.SaveChangesAsync();

                return(RedirectToAction(nameof(StudentDetails), new { id = asg.ID }));
            }
            else
            {
                ViewData["Error"]        = string.Join("; ", ModelState.Values.Select(v => v.Errors));
                ViewData["AssignmentID"] = id;
                ViewData["StageID"]      = stage;
                return(View(sub));
            }
        }