/// <summary> /// Redirects to Problem action after successful deletion of the test /// </summary> /// <param name="id">Id for test to be deleted</param> /// <returns>Redirects to /Administration/Tests/Problem/{id} after succesful deletion otherwise to /Administration/Test/ with proper error message</returns> public ActionResult ConfirmDelete(int?id) { if (id == null) { this.TempData.AddDangerMessage(Resource.Invalid_test); return(this.RedirectToAction <TestsController>(x => x.Index())); } var test = this.Data.Tests.All().FirstOrDefault(t => t.Id == id); if (test == null) { this.TempData.AddDangerMessage(Resource.Invalid_test); return(this.RedirectToAction <TestsController>(x => x.Index())); } if (!this.CheckIfUserHasProblemPermissions(test.ProblemId)) { this.TempData[GlobalConstants.DangerMessage] = "Нямате привилегиите за това действие"; return(this.RedirectToAction("Index", "Contests", new { area = "Administration" })); } using (var scope = new TransactionScope()) { // delete all test runs for the test this.Data.TestRuns.Delete(tr => tr.TestId == id.Value); this.Data.SaveChanges(); // delete the test this.Data.Tests.Delete(test); this.Data.SaveChanges(); // recalculate submissions point var problemSubmissions = this.Data.Submissions .All() .Include(s => s.TestRuns) .Include(s => s.TestRuns.Select(tr => tr.Test)) .Where(s => s.ProblemId == test.ProblemId) .ToList(); var submissionResults = problemSubmissions .Select(s => new { s.Id, s.ParticipantId, CorrectTestRuns = s.TestRuns.Count(t => t.ResultType == TestRunResultType.CorrectAnswer && !t.Test.IsTrialTest), AllTestRuns = s.TestRuns.Count(t => !t.Test.IsTrialTest), MaxPoints = s.Problem.MaximumPoints }) .ToList(); var problemSubmissionsById = problemSubmissions.ToDictionary(s => s.Id); var topResults = new Dictionary <int, ParticipantScoreModel>(); foreach (var submissionResult in submissionResults) { var submission = problemSubmissionsById[submissionResult.Id]; int points = 0; if (submissionResult.AllTestRuns != 0) { points = (submissionResult.CorrectTestRuns * submissionResult.MaxPoints) / submissionResult.AllTestRuns; } submission.Points = points; submission.CacheTestRuns(); if (submissionResult.ParticipantId.HasValue) { var participantId = submissionResult.ParticipantId.Value; if (!topResults.ContainsKey(participantId) || topResults[participantId].Points < points) { // score does not exists or have less points than current submission topResults[participantId] = new ParticipantScoreModel { Points = points, SubmissionId = submission.Id }; } else if (topResults[participantId].Points == points) { // save score with latest submission if (topResults[participantId].SubmissionId < submission.Id) { topResults[participantId].SubmissionId = submission.Id; } } } } this.Data.SaveChanges(); var participants = topResults.Keys.ToList(); // find all participant scores for the test's problem var existingScores = this.participantScoresData .GetAll() .Where(x => x.ProblemId == test.ProblemId && participants.Contains(x.ParticipantId)) .ToList(); // replace the scores with updated values foreach (var existingScore in existingScores) { var topScore = topResults[existingScore.ParticipantId]; existingScore.Points = topScore.Points; existingScore.SubmissionId = topScore.SubmissionId; } this.Data.SaveChanges(); scope.Complete(); } this.TempData.AddInfoMessage(Resource.Test_deleted_successfully); return(this.RedirectToAction("Problem", new { id = test.ProblemId })); }
public void RecalculatePointsByProblem(int problemId) { using (var scope = TransactionsHelper.CreateTransactionScope()) { var problemSubmissions = this.submissionsData .GetAllByProblem(problemId) .Include(s => s.TestRuns) .Include(s => s.TestRuns.Select(tr => tr.Test)) .ToList(); var submissionResults = problemSubmissions .Select(s => new { s.Id, s.ParticipantId, CorrectTestRuns = s.TestRuns.Count(t => t.ResultType == TestRunResultType.CorrectAnswer && !t.Test.IsTrialTest), AllTestRuns = s.TestRuns.Count(t => !t.Test.IsTrialTest), MaxPoints = s.Problem.MaximumPoints }) .ToList(); var problemSubmissionsById = problemSubmissions.ToDictionary(s => s.Id); var topResults = new Dictionary <int, ParticipantScoreModel>(); foreach (var submissionResult in submissionResults) { var submission = problemSubmissionsById[submissionResult.Id]; var points = 0; if (submissionResult.AllTestRuns != 0) { points = (submissionResult.CorrectTestRuns * submissionResult.MaxPoints) / submissionResult.AllTestRuns; } submission.Points = points; submission.CacheTestRuns(); if (!submissionResult.ParticipantId.HasValue) { continue; } var participantId = submissionResult.ParticipantId.Value; if (!topResults.ContainsKey(participantId) || topResults[participantId].Points < points) { topResults[participantId] = new ParticipantScoreModel { Points = points, SubmissionId = submission.Id }; } else if (topResults[participantId].Points == points) { if (topResults[participantId].SubmissionId < submission.Id) { topResults[participantId].SubmissionId = submission.Id; } } } this.submissions.SaveChanges(); var participants = topResults.Keys.ToList(); var existingScores = this.participantScoresData .GetAllByProblem(problemId) .Where(p => participants.Contains(p.ParticipantId)) .ToList(); foreach (var existingScore in existingScores) { var topScore = topResults[existingScore.ParticipantId]; existingScore.Points = topScore.Points; existingScore.SubmissionId = topScore.SubmissionId; } this.submissions.SaveChanges(); scope.Complete(); } }