public async Task <ActionResult> ScoreQuiz(int id, string nextUrl, string errorUrl = "") { metricSender.SendCount("quiz.manual_score"); if (string.IsNullOrEmpty(errorUrl)) { errorUrl = nextUrl; } using (var transaction = db.Database.BeginTransaction()) { var checking = slideCheckingsRepo.FindManualCheckingById <ManualQuizChecking>(id); if (checking.IsChecked) { return(Redirect(errorUrl + "Эта работа уже была проверена")); } if (!checking.IsLockedBy(User.Identity)) { return(Redirect(errorUrl + "Эта работа проверяется другим инструктором")); } var course = courseManager.GetCourse(checking.CourseId); var unit = course.FindUnitBySlideId(checking.SlideId); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}"); var answers = userQuizzesRepo.GetAnswersForUser(checking.CourseId, checking.SlideId, checking.UserId); QuizVersion quizVersion; /* If there is no user's answers for quiz, get the latest quiz version */ if (answers.Count == 0) { quizVersion = quizzesRepo.GetLastQuizVersion(checking.CourseId, checking.SlideId); } else { var firstAnswer = answers.FirstOrDefault().Value.FirstOrDefault(); quizVersion = firstAnswer != null ? firstAnswer.QuizVersion : quizzesRepo.GetFirstQuizVersion(checking.CourseId, checking.SlideId); } var totalScore = 0; var quiz = quizVersion.GetRestoredQuiz(course, unit); foreach (var question in quiz.Blocks.OfType <AbstractQuestionBlock>()) { var scoreFieldName = "quiz__score__" + question.Id; var scoreStr = Request.Form[scoreFieldName]; /* Invalid form: score isn't integer */ if (!int.TryParse(scoreStr, out var score)) { return(Redirect(errorUrl + $"Неверное количество баллов в задании «{question.QuestionIndex}. {question.Text.TruncateWithEllipsis(50)}»")); } /* Invalid form: score isn't from range 0..MAX_SCORE */ if (score < 0 || score > question.MaxScore) { return(Redirect(errorUrl + $"Неверное количество баллов в задании «{question.QuestionIndex}. {question.Text.TruncateWithEllipsis(50)}»: {score}")); } await userQuizzesRepo.SetScoreForQuizBlock(checking.CourseId, checking.UserId, checking.SlideId, question.Id, score); totalScore += score; } await slideCheckingsRepo.MarkManualCheckingAsChecked(checking, totalScore); await visitsRepo.UpdateScoreForVisit(checking.CourseId, checking.SlideId, checking.UserId); transaction.Commit(); metricSender.SendCount($"quiz.manual_score.score", totalScore); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.score", totalScore); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}.score", totalScore); if (totalScore == quiz.MaxScore) { metricSender.SendCount($"quiz.manual_score.full_scored"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.full_scored"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}.full_scored"); } await NotifyAboutManualQuizChecking(checking); } return(Redirect(nextUrl)); }