public async Task ResultProcessing(ExamLogResultDTO examResult)
        {
            var examLog = await ExamLogProcessing(examResult);

            if (examLog == null)
            {
                return;
            }

            // Cập nhật exam Logs
            await Repository.UpdateAsync(examLog);
        }
        private async Task <ExamLog> ExamLogProcessing(ExamLogResultDTO examResult)
        {
            var examLog = await Repository.IgnoreAutoIncludes().FirstOrDefaultAsync(x => x.Id == examResult.LogId);

            if (examLog.CompletionTime != null)
            {
                return(null);
            }

            // Tổng điểm của bài thi hiện tại
            var totalScore = 0F;

            // Phân giải thành bài thi đọc được
            var exam = JsonConvert.DeserializeObject <ExamForRenderDTO>(examLog.RawExamRendered);

            // Đánh dấu thời gian hoàn thành bài thi
            examLog.CompletionTime = DateTime.Now;

            // Thời gian thực hiện bài thi
            examLog.ExamTimeInMinutes = (float)(examLog.CompletionTime.Value - examLog.CreationTime).Seconds / 60;

            // Phân giải để thực hiện chấm bài thi
            for (int i = 0; i < exam.SkillCategories.Count; i++)
            {
                // Điểm tối đa của skill category
                var skcMaxScores = exam.SkillCategories[i].MaxScores;
                for (int j = 0; j < exam.SkillCategories[i].SkillParts.Count; j++)
                {
                    var skp = exam.SkillCategories[i].SkillParts[j];

                    // Điểm tối đa của skill part
                    var skpMaxScores = skp.MaxScores;

                    // Điểm cho phần thi thiện tại
                    var skpScores = 0F;

                    // Điểm khả dụng cho mỗi câu hỏi đúng
                    var skpScorePerQuestion = skp.MaxScores /
                                              skp.QuestionContainers.SelectMany(x => x.Questions).Count();

                    // Cờ kiểm tra có thể chấm tự động hay không
                    var isAutoCorrectable = skp.AnswerType == Common.AnswerTypes.TextAnswer ||
                                            skp.AnswerType == Common.AnswerTypes.ImageAnswer ||
                                            skp.AnswerType == Common.AnswerTypes.FillAnswer;


                    #region Bắt đầu phần chấm tự động

                    // Phân giải khung chứa ds câu hỏi
                    for (int k = 0;
                         k < exam
                         .SkillCategories[i]
                         .SkillParts[j]
                         .QuestionContainers
                         .Count;
                         k++)
                    {
                        // Phân giải danh sách câu hỏi
                        for (int l = 0;
                             l < exam
                             .SkillCategories[i]
                             .SkillParts[j]
                             .QuestionContainers[k]
                             .Questions.Count;
                             l++)
                        {
                            // Luu tam cau hoi hien tai
                            var question = exam.SkillCategories[i].SkillParts[j].QuestionContainers[k].Questions[l];

                            // Lay cau tra loi cua nguoi dung cho cau hoi hien tai
                            var userAnswer = examResult.Answers.Find(x => x.QuestionId == question.Id);

                            // Nếu phần này có thể chấm tự động được
                            if (isAutoCorrectable)
                            {
                                //// Nếu nội dung này đã được chấm trước đó thì bỏ qua, vì đây là nội dung chấm tự động
                                //if (skp.QuestionContainers.Any(x => x.Questions.Any(y => y.CorrectionContentTime != null)))
                                //    continue;

                                var isCorrect = false;

                                if (skp.AnswerType == Common.AnswerTypes.FillAnswer)
                                {
                                    // Xử ký KQ cho phần điền
                                    isCorrect = question.Answers.Any(
                                        x => x.AnswerContent.Equals(userAnswer?.Answer ?? "",
                                                                    StringComparison.OrdinalIgnoreCase) &&
                                        x.IsCorrect) && (!userAnswer?.Answer.IsNullOrEmpty() == true);
                                }
                                else
                                {
                                    // Xử lý theo kiểu trắc nghiệm
                                    isCorrect = question.Answers.Any(x => x.Id.ToString()
                                                                     .Equals(userAnswer?.Answer ?? "",
                                                                             StringComparison.OrdinalIgnoreCase) && x.IsCorrect);
                                }

                                // Luu ket qua dung sai
                                exam.SkillCategories[i]
                                .SkillParts[j]
                                .QuestionContainers[k]
                                .Questions[l].IsCorrect = isCorrect;

                                // Lưu giá trị điểm vào
                                exam.SkillCategories[i]
                                .SkillParts[j]
                                .QuestionContainers[k]
                                .Questions[l].Scores = skpScorePerQuestion;

                                // Lưu thời gian chấm
                                exam.SkillCategories[i]
                                .SkillParts[j]
                                .QuestionContainers[k]
                                .Questions[l].CorrectionContentTime = DateTime.Now;
                            }
                            else
                            {
                                if (exam.SkillCategories[i]
                                    .SkillParts[j]
                                    .QuestionContainers[k]
                                    .Questions[l].IsCorrect)
                                {
                                    exam.SkillCategories[i]
                                    .SkillParts[j]
                                    .QuestionContainers[k]
                                    .Questions[l].CorrectionContentTime = DateTime.Now;
                                }
                            }

                            // Tính điểm nếu câu trả lời này là đúng
                            if (exam.SkillCategories[i]
                                .SkillParts[j]
                                .QuestionContainers[k]
                                .Questions[l].IsCorrect)
                            {
                                totalScore += exam.SkillCategories[i]
                                              .SkillParts[j]
                                              .QuestionContainers[k]
                                              .Questions[l].Scores;
                                skpScores += exam.SkillCategories[i]
                                             .SkillParts[j]
                                             .QuestionContainers[k]
                                             .Questions[l].Scores;
                            }
                        }
                    }

                    #endregion

                    // Lưu điểm vào log điểm
                    if (isAutoCorrectable)
                    {
                        // Lưu kết quả chấm vào log Điểm
                        await SaveScoreLog(examLog.Id, skp.Id, skpScores, skpMaxScores);
                    }
                }
            }

            if (exam.SkillCategories
                .SelectMany(x => x.SkillParts.SelectMany(y => y.QuestionContainers.SelectMany(z => z.Questions)))
                .All(x => x.CorrectionContentTime != null))
            {
                // Đánh dấu rằng bài thi đã được chấm hoàn tất
                examLog.IsDoneScore = true;
            }

            examLog.ExamScores  = totalScore;
            examLog.UserAnswers = JsonConvert.SerializeObject(examResult.Answers);

            // Chuyển đổi lại thành Json
            examLog.RawExamRendered = JsonConvert.SerializeObject(exam);

            // Cho biết bài thi đã đạt hay chưa
            examLog.IsPassed = IsExamPassesed(examLog.ExamScores, examLog.CurrentMaxScore);

            return(examLog);
        }