Esempio n. 1
0
        public ActionResult Quiz(QuizSlide slide, string courseId, string userId, bool isGuest, bool isLti = false, ManualQuizChecking manualQuizCheckQueueItem = null, int?send = null, bool attempt = false)
        {
            metricSender.SendCount("quiz.show");
            if (isLti)
            {
                metricSender.SendCount("quiz.show.lti");
            }
            metricSender.SendCount($"quiz.show.{courseId}");
            metricSender.SendCount($"quiz.show.{courseId}.{slide.Id}");

            var course = courseManager.FindCourse(courseId);

            if (course == null)
            {
                return(HttpNotFound());
            }

            if (isGuest)
            {
                metricSender.SendCount("quiz.show.to.guest");
                return(PartialView(GuestQuiz(course, slide)));
            }

            var slideId          = slide.Id;
            var maxAttemptsCount = GetMaxAttemptsCount(courseId, slide);
            var userScores       = GetUserScoresForBlocks(courseId, userId, slideId, manualQuizCheckQueueItem?.Submission);

            var score = userScores?.AsEnumerable().Sum(res => res.Value) ?? 0;

            var state = GetQuizState(courseId, userId, slideId, score, slide.MaxScore, manualQuizCheckQueueItem?.Submission);

            log.Info($"Показываю тест для пользователя {userId} в слайде {courseId}:{slide.Id}, isLti = {isLti}");

            /* If it's manual checking, change quiz state to IsChecking for correct rendering */
            if (manualQuizCheckQueueItem != null)
            {
                state.Status = QuizStatus.IsCheckingByInstructor;
            }

            /* For manually checked quizzes show last attempt's answers until ?attempt=true is defined in query string */
            if (slide.ManualChecking && manualQuizCheckQueueItem == null && state.Status == QuizStatus.ReadyToSend && state.UsedAttemptsCount > 0 && !attempt)
            {
                state.Status = QuizStatus.Sent;
            }

            /* We also want to show user's answer if user sent answers just now */
            if (state.Status == QuizStatus.ReadyToSend && send.HasValue)
            {
                state.Status = QuizStatus.Sent;
            }

            var userAnswers     = userQuizzesRepo.GetAnswersForShowingOnSlide(courseId, slide, userId, manualQuizCheckQueueItem?.Submission);
            var canUserFillQuiz = CanUserFillQuiz(state.Status);

            var questionAnswersFrequency = new DefaultDictionary <string, DefaultDictionary <string, int> >();

            if (User.HasAccessFor(courseId, CourseRole.CourseAdmin))
            {
                questionAnswersFrequency = slide.Blocks.OfType <ChoiceBlock>().ToDictionary(
                    block => block.Id,
                    block => userQuizzesRepo.GetAnswersFrequencyForChoiceBlock(courseId, slide.Id, block.Id).ToDefaultDictionary()
                    ).ToDefaultDictionary();
            }

            var model = new QuizModel
            {
                Course              = course,
                Slide               = slide,
                QuizState           = state,
                MaxAttemptsCount    = maxAttemptsCount,
                UserScores          = userScores,
                AnswersToQuizzes    = userAnswers,
                IsLti               = isLti,
                Checking            = manualQuizCheckQueueItem,
                ManualCheckingsLeft = manualQuizCheckQueueItem != null?GetManualCheckingsCountInQueue(course, slide) : 0,
                                          CanUserFillQuiz          = canUserFillQuiz,
                                          GroupsIds                = Request.GetMultipleValuesFromQueryString("group"),
                                          QuestionAnswersFrequency = questionAnswersFrequency,
            };

            return(PartialView(model));
        }