Пример #1
0
        public AssessmentEligibilityStatus GetEligibilityStatus(string username, int courseId)
        {
            bool       hasActiveSubscription = _subscriptions.All().FirstOrDefault(x => x.User.Username == username && x.CourseId == courseId)?.Status == SubscriptionStatus.Active;
            List <int> unvisitedLectures;

            if (hasActiveSubscription && _lecturesService.HasVisitedAllLectures(username, courseId, out unvisitedLectures))
            {
                AssessmentSubmission latestSubmission = _assessmentSubmissions.All()
                                                        .Where(x =>
                                                               x.AssessmentRequest.User.Username == username &&
                                                               x.CourseId == courseId).OrderByDescending(x => x.CreatedOn).FirstOrDefault();

                if (latestSubmission != null)
                {
                    if (latestSubmission.IsSuccessful)
                    {
                        return(AssessmentEligibilityStatus.AlreadyCompleted);
                    }
                    if (NextAvailableAssessmentAttempt(latestSubmission.CreatedOn) > DateTime.UtcNow)
                    {
                        return(AssessmentEligibilityStatus.Lockout);
                    }
                }

                return(AssessmentEligibilityStatus.Eligible);
            }

            return(AssessmentEligibilityStatus.NotEligible);
        }
Пример #2
0
        public void CreateAssessmentSubmission(AssessmentSubmission submission, out Certificate certificate)
        {
            if (submission == null)
            {
                throw new ArgumentNullException(nameof(submission));
            }

            certificate = null;

            //TODO validation
            AssessmentRequest request = submission.AssessmentRequest ?? _assessmentRequests.GetById(submission.AssessmentRequestId);

            request.IsCompleted = true;
            _assessmentRequests.Update(request);
            _assessmentRequests.SaveChanges();

            submission.UserId = request.UserId;
            _assessmentSubmissions.Add(submission);
            _assessmentSubmissions.SaveChanges();

            Course submissionCourse = _courses.GetById(submission.CourseId);

            if (submission.IsSuccessful)
            {
                certificate = _certificatesService.GenerateCertificate(request.User.Username, submissionCourse.Id, submission);
                string certificateUrl        = _routeProvider.GetCertificateRoute(certificate);
                string certificatePictureUrl = _routeProvider.GetCertificatePictureRoute(certificate);
                _messageService.SendExamSuccessfulMessage(request.User, submissionCourse, certificateUrl, certificatePictureUrl);
            }
            else
            {
                string assessmentUrl = _routeProvider.GetAssessmentRoute(submissionCourse.Id);
                _taskRunner.Schedule <IMessageService>(x => x.SendExamAvailableMessage(request.User, submissionCourse, assessmentUrl), NextAvailableAssessmentAttempt(submission.CreatedOn));//TODO add config setting
            }
        }
Пример #3
0
        public DateTime?GetNextAssessmentAttemptDate(string username, int courseId)
        {
            AssessmentSubmission latestSubmission =
                _assessmentSubmissions.All()
                .Where(x => x.User.Username == username && x.CourseId == courseId)
                .OrderByDescending(x => x.CreatedOn)
                .FirstOrDefault();

            if (latestSubmission == null)
            {
                return(null);
            }

            return(NextAvailableAssessmentAttempt(latestSubmission.CreatedOn));
        }
Пример #4
0
        public Certificate GenerateCertificate(string username, int courseId, AssessmentSubmission assessmentSubmission)
        {
            User   user   = _users.GetByUsername(username);
            Course course = _courses.GetById(courseId);

            Certificate certificate = new Certificate
            {
                UserId = user.Id,
                AssesmentSubmissionId = assessmentSubmission.Id,
                CourseId = course.Id,
                Code     = _random.GenerateRandomCode(10)
            };

            CertificateGenerationInfo certificateGenerationInfo = _generationInfoProvider.GetByCourseId(courseId);

            string certificateRelativePath = string.Format(CertificateFilePathFormat, certificate.Code);
            string filePath = Path.Combine(certificateGenerationInfo.BaseFilePath, certificateRelativePath);

            certificate.FilePath = certificateRelativePath;
            _certificates.Add(certificate);
            _certificates.SaveChanges();


            Bitmap        bitmap  = (Bitmap)Image.FromFile(Path.GetFullPath(certificateGenerationInfo.TemplateFilePath));//load the image file
            QRCodeEncoder encoder = new QRCodeEncoder();
            Bitmap        certificateUrlQrCode = encoder.Encode(string.Format(CertificateUrlFormat, certificate.Code));

            using (Graphics certificateTemplate = Graphics.FromImage(bitmap))
            {
                using (Font arialFont = new Font("Arial", 16, FontStyle.Bold))
                {
                    using (Font arialFontLarge = new Font("Arial", 20, FontStyle.Bold))
                    {
                        PlaceholderInfo studentData     = certificateGenerationInfo.StudentName;
                        PlaceholderInfo courseData      = certificateGenerationInfo.CourseName;
                        PlaceholderInfo datePlaceholder = certificateGenerationInfo.IssueDate;
                        PlaceholderInfo qrPlaceholder   = certificateGenerationInfo.QrCode;
                        PlaceholderInfo certificateNumberPlaceholder = certificateGenerationInfo.CertificateNumber;
                        PlaceholderInfo moduleNamesPlaceholder       = certificateGenerationInfo.ModuleNames;
                        PlaceholderInfo numberOfHoursPlaceholder     = certificateGenerationInfo.NumberOfHours;
                        certificateTemplate.DrawString($"{user.FirstName} {user.MiddleName} {user.LastName}", arialFontLarge, new SolidBrush(ColorTranslator.FromHtml(studentData.Color)), new Rectangle(studentData.TopLeftX, studentData.TopLeftY, studentData.Width, studentData.Height));
                        certificateTemplate.DrawString(course.Title, arialFontLarge, new SolidBrush(ColorTranslator.FromHtml(courseData.Color)), new Rectangle(courseData.TopLeftX, courseData.TopLeftY, courseData.Width, courseData.Height));
                        certificateTemplate.DrawString(DateTime.Today.ToString("dd.MM.yyy") + "г.", arialFont, new SolidBrush(ColorTranslator.FromHtml(datePlaceholder.Color)), new Rectangle(datePlaceholder.TopLeftX, datePlaceholder.TopLeftY, datePlaceholder.Width, datePlaceholder.Height));
                        certificateTemplate.DrawImage(certificateUrlQrCode, new Rectangle(qrPlaceholder.TopLeftX, qrPlaceholder.TopLeftY, qrPlaceholder.Width, qrPlaceholder.Height));
                        certificateTemplate.DrawString($"Рег. № {certificate.Id}", arialFontLarge, new SolidBrush(ColorTranslator.FromHtml(certificateNumberPlaceholder.Color)), new Rectangle(certificateNumberPlaceholder.TopLeftX, certificateNumberPlaceholder.TopLeftY, certificateNumberPlaceholder.Width, certificateNumberPlaceholder.Height));
                        certificateTemplate.DrawString(course.ModuleNames, arialFont, new SolidBrush(ColorTranslator.FromHtml(moduleNamesPlaceholder.Color)), new Rectangle(moduleNamesPlaceholder.TopLeftX, moduleNamesPlaceholder.TopLeftY, moduleNamesPlaceholder.Width, moduleNamesPlaceholder.Height));
                        certificateTemplate.DrawString($"{course.NumberOfHours} учебни часа", arialFont, new SolidBrush(ColorTranslator.FromHtml(numberOfHoursPlaceholder.Color)), new Rectangle(numberOfHoursPlaceholder.TopLeftX, numberOfHoursPlaceholder.TopLeftY, numberOfHoursPlaceholder.Width, numberOfHoursPlaceholder.Height));


                        string directoryPath = Path.GetDirectoryName(filePath);
                        Debug.Assert(!string.IsNullOrEmpty(directoryPath));
                        if (!Directory.Exists(directoryPath))
                        {
                            Directory.CreateDirectory(directoryPath);
                        }

                        bitmap.Save(filePath);
                    }
                }
            }
            return(certificate);
        }
        public ActionResult Assessment(AssessmentViewModel assessment)
        {
            int    courseId = _coursesContentService.GetCourseId(Umbraco.AssignedContentItem);
            string username = User.Identity.Name;

            if (!_feedbackService.UserHasSentFeedback(username, courseId))
            {
                return(RedirectToRoute("Feedback", new { courseNiceUrl = Umbraco.AssignedContentItem.UrlName }));
            }

            if (_assessments.GetEligibilityStatus(username, courseId) != AssessmentEligibilityStatus.Eligible)
            {
                return(Redirect(Umbraco.AssignedContentItem.Url));
            }

            if (assessment.AssessmentRequestId == default(int))
            {
                throw new ArgumentException("Assessment Id is missing from Assessment Submission. Cannot evaluate assessment");
            }

            var assessmentRequest = _assessments.GetAssessmentRequest(assessment.AssessmentRequestId);

            IEnumerable <IPublishedContent> questions = Umbraco.TypedContent(assessmentRequest.QuestionIds.Split(',').ToList());
            IPublishedContent assessmentContnet       = Umbraco.TypedContent(assessmentRequest.AssessmentExternalId);
            var requiredCorrectAnswers =
                assessmentContnet.GetPropertyValue <int>(
                    nameof(Models.Umbraco.DocumentTypes.Assessment.RequiredCorrectAnswers));

            if (requiredCorrectAnswers == default(int))
            {
                throw new ArgumentException($"Number of required correct answers is not set for assessment with ID: {assessmentRequest.AssessmentExternalId}");
            }

            AssessmentViewModel      assessmentViewModel = new AssessmentViewModel();
            List <QuestionViewModel> questionViewModel   = new List <QuestionViewModel>();


            _mapper.AddCustomMapping(typeof(IEnumerable <QuestionAnswer>).FullName, UmbracoMapperMappings.MapQuestionAnswer)
            .MapCollection(questions, questionViewModel)
            .Map(assessmentContnet, assessmentViewModel);

            assessmentViewModel.Questions = questionViewModel;
            int correctAnswers = 0;

            foreach (QuestionViewModel questionInDb in assessmentViewModel.Questions)
            {
                QuestionViewModel questionAnswered = assessment.Questions.Single(x => x.Id == questionInDb.Id);
                questionAnswered.QuestionText = questionInDb.QuestionText;
                bool isCorrectlyAnswered = true;
                foreach (QuestionAnswer answerInDb in questionInDb.Answers)
                {
                    QuestionAnswer answer = questionAnswered.Answers.Single(x => x.Index == answerInDb.Index);
                    answer.Text = answerInDb.Text;
                    if (answer.IsCorrect != answerInDb.IsCorrect)
                    {
                        isCorrectlyAnswered = false;
                        break;
                    }
                }

                if (isCorrectlyAnswered)
                {
                    correctAnswers++;
                }
            }

            var submission = new AssessmentSubmission
            {
                CourseId          = courseId,
                AssessmentRequest = assessmentRequest,
                Submission        = JsonConvert.SerializeObject(assessment.Questions)
            };

            if (correctAnswers >= requiredCorrectAnswers)
            {
                submission.IsSuccessful = true;
            }

            Certificate certificate;

            _assessments.CreateAssessmentSubmission(submission, out certificate);

            if (submission.IsSuccessful)
            {
                TempData["SuccessfulSubmission"] = true;
                TempData["CorrectAnswers"]       = correctAnswers;
                TempData["RequiredAnswers"]      = requiredCorrectAnswers;
                return(RedirectToRoute("Certificate", new { certificateCode = certificate.Code }));
            }

            return(View("AssessmentFailure", new AssessmentFailureViewModel
            {
                CorrectAnswers = correctAnswers,
                RequiredAnswers = requiredCorrectAnswers,
                NumberOfQuestions = questions.Count(),
                CourseTitle = Umbraco.AssignedContentItem.Name,
                CourseUrl = Umbraco.AssignedContentItem.Url,
                // ReSharper disable once PossibleInvalidOperationException - This should never be null as we've just done a submission
                NextAttempt = _assessments.GetNextAssessmentAttemptDate(username, courseId).Value
            }));
        }