Beispiel #1
0
            public static async Task <Result <QuestionInfo> > GetNextQuestion(UserSubjectProgress progress, CancellationToken cancellationToken, IDbContext db)
            {
                UserQuestion nextQuestion            = null;
                var          applicableQuestionLevel = progress.Level == 3 ? 2 : progress.Level;
                var          questions = progress.Questions.Where(x => x.Level == applicableQuestionLevel).ToList().Shuffle();

                //Pega a primeira pergunta não respondida
                foreach (var userQuestion in questions)
                {
                    if (userQuestion.Answered)
                    {
                        continue;
                    }

                    nextQuestion = userQuestion;
                    break;
                }

                if (nextQuestion == null)
                {
                    //if (progress.Questions.All(x => x.Level != applicableQuestionLevel))
                    //    return Result.Fail<QuestionInfo>("Não foi possível obter nenhuma questão para o nível atual");

                    //Se não encontrou nenhuma é pq acabou o BDQ e tem que resetar as perguntas que ele respondeu errado
                    foreach (var userQuestion in progress.Questions.Where(x => x.Level == applicableQuestionLevel).ToList())
                    {
                        if (!userQuestion.Answered || userQuestion.HasAnsweredCorrectly)
                        {
                            continue;
                        }
                        //if (!userQuestion.Answered || userQuestion.HasAnsweredCorrectly || userQuestion.AnsweredCount > 99) continue;

                        userQuestion.Answered = false;
                        if (nextQuestion == null)
                        {
                            nextQuestion = userQuestion;
                        }
                    }

                    //Atualiza no banco de dados
                    if (nextQuestion != null)
                    {
                        await db.UserSubjectProgressCollection.ReplaceOneAsync(t => t.Id == progress.Id, progress,
                                                                               cancellationToken : cancellationToken);
                    }
                }

                if (nextQuestion == null)
                {
                    return(Result.Fail <QuestionInfo>("Não foi possível obter nenhuma questão para o nível atual"));
                }

                var question = await db.QuestionCollection
                               .AsQueryable()
                               .Where(x => x.Id == nextQuestion.QuestionId)
                               .FirstOrDefaultAsync(cancellationToken: cancellationToken);

                //validando se a configuração das perguntas mudou
                var dbcorrectAnswer = question.Answers.FirstOrDefault(x => x.Points == 2);

                if (dbcorrectAnswer == null)
                {
                    return(Result.Fail <QuestionInfo>("Pergunta com configuração errada. Por favor contate o suporte"));
                }
                if (nextQuestion.CorrectAnswerId != dbcorrectAnswer.Id)
                {
                    nextQuestion.CorrectAnswerId = dbcorrectAnswer.Id;
                    //Atualiza no banco de dados
                    await db.UserSubjectProgressCollection.ReplaceOneAsync(t => t.Id == progress.Id, progress,
                                                                           cancellationToken : cancellationToken);
                }
                var rand     = new Random(DateTime.Now.Millisecond + DateTime.Now.Second);
                var response = new QuestionInfo()
                {
                    Text      = question.Text,
                    Id        = question.Id,
                    ModuleId  = question.ModuleId,
                    SubjectId = question.SubjectId,
                    Answers   = question.Answers.Select(a => new AnswerInfo()
                    {
                        Id          = a.Id,
                        Description = a.Description,
                        Concepts    = a.Concepts
                    }).ToList().Shuffle(),
                    Concepts = question.Concepts.Select(c => c.Name).ToList()
                };

                return(Result.Ok(response));
            }
Beispiel #2
0
            public async Task <Result <QuestionInfo> > Handle(Contract request, CancellationToken cancellationToken)
            {
                try
                {
                    var moduleId  = ObjectId.Parse(request.ModuleId);
                    var subjectId = ObjectId.Parse(request.SubjectId);
                    var userId    = ObjectId.Parse(request.UserId);
                    var progress  = await _db
                                    .UserSubjectProgressCollection
                                    .AsQueryable()
                                    .FirstOrDefaultAsync(x => x.ModuleId == moduleId &&
                                                         x.UserId == userId &&
                                                         x.SubjectId == subjectId, cancellationToken: cancellationToken);

                    if (progress != null)
                    {
                        //Já está no nivel máximo
                        if (progress.Level == 4)
                        {
                            return(Result.Fail <QuestionInfo>("Você já alcançou o nível máximo"));
                        }

                        //Não tem mais perguntas disponiveis
                        //var applicableQuestionLevel = progress.Level == 3 ? 2 : progress.Level;
                        //var currentQuestions = progress.Questions.Where(x => x.Level == applicableQuestionLevel).ToList();
                        //if (currentQuestions.All(x => x.HasAnsweredCorrectly || x.AnsweredCount > 1))
                        //    return Result.Fail<QuestionInfo>("Não há a possibilidade de progredir no nivel atual. Você já alcançou o máximo de erros possíveis.");

                        //Buscado a nova lista de respostas
                        //var newQuestionList = await this.GetUserQuestionList(moduleId, subjectId, cancellationToken, progress);
                        var newQuestionList = await this.GetUserQuestionList(moduleId, subjectId, cancellationToken);

                        newQuestionList = newQuestionList.Shuffle();

                        // Retirando as perguntas não respondidas que não existem mais
                        var questionCount   = progress.Questions.Count;
                        var newQuestionsIds = newQuestionList.Select(x => x.QuestionId);
                        progress.Questions = progress.Questions
                                             .Where(x => x.HasAnsweredCorrectly || newQuestionsIds.Contains(x.QuestionId))
                                             .OrderBy(x => x.Order).ToList();

                        if (questionCount != progress.Questions.Count || questionCount < newQuestionList.Count)
                        {
                            //Tirando as respostas existentes da nova lista
                            var questionIdList = progress.Questions.Select(x => x.QuestionId).ToList();

                            progress.Questions.AddRange(newQuestionList
                                                        .Where(x => !questionIdList.Contains(x.QuestionId)).OrderBy(x => x.Order));
                            //Ordenando depois de tudo pronto
                            for (var i = 0; i < progress.Questions.Count; i++)
                            {
                                progress.Questions[i].Order = i;
                            }

                            //Atualiza no banco de dados
                            await _db.UserSubjectProgressCollection.ReplaceOneAsync(t => t.Id == progress.Id, progress,
                                                                                    cancellationToken : cancellationToken);
                        }
                    }
                    else
                    {
                        progress = UserSubjectProgress.Create(moduleId, subjectId, userId);
                        //progress.Questions = await this.GetUserQuestionList(moduleId, subjectId, cancellationToken, null);
                        progress.Questions = await this.GetUserQuestionList(moduleId, subjectId, cancellationToken);

                        //Atualiza no banco de dados
                        await _db.UserSubjectProgressCollection.InsertOneAsync(progress,
                                                                               cancellationToken : cancellationToken);
                    }

                    var nextQuestion = await GetNextQuestion(progress, cancellationToken, _db);

                    return(nextQuestion);
                }
                catch (Exception err)
                {
                    Console.WriteLine(err.Message);
                    throw;
                }
            }
Beispiel #3
0
            private async Task SetModuleProgress(List <Module> modules, List <Track> tracks, List <UserProgress> userTracks, ObjectId userId, UserInfoDB userInfo, CancellationToken token)
            {
                var moduleId      = ObjectId.Parse(userInfo.IdModuloEvento);
                var currentModule = modules.FirstOrDefault(t => t.Id == moduleId);

                if (currentModule != null)
                {
                    await _db.ModuleGradeCollection.InsertOneAsync(
                        ModuleGrade.Create(
                            ObjectId.Parse(userInfo.IdModuloEvento), userId,
                            CellIsEmpty(userInfo.Pontuacao) ? 0 : decimal.Parse(userInfo.Pontuacao.Replace(".", ",")),
                            CellIsEmpty(userInfo.Presenca) ? 0 : decimal.Parse(userInfo.Presenca.Replace(".", ","))
                            ).Data, cancellationToken : token
                        );

                    int currentLevel    = GetLevelByGrade(userInfo.Pontuacao);
                    var progressesToAdd = new List <UserSubjectProgress>();

                    if (currentModule.Subjects != null && currentModule.Subjects.Count > 0)
                    {
                        foreach (var subject  in currentModule.Subjects)
                        {
                            var progress = UserSubjectProgress.Create(moduleId, subject.Id, userId);
                            progress.Level  = currentLevel;
                            progress.Points = 100 * currentLevel;
                            progressesToAdd.Add(progress);
                        }

                        await _db.UserSubjectProgressCollection.InsertManyAsync(
                            progressesToAdd, cancellationToken : token
                            );
                    }

                    var moduleProgress = UserModuleProgress.Create(moduleId, userId);
                    moduleProgress.Level  = currentLevel;
                    moduleProgress.Points = progressesToAdd.Sum(p => p.Points);

                    await _db.UserModuleProgressCollection.InsertOneAsync(
                        moduleProgress, cancellationToken : token
                        );

                    var track = tracks.FirstOrDefault(t =>
                                                      userTracks.Any(ut => ut.Id == t.Id) &&
                                                      t.ModulesConfiguration.Any(m => m.ModuleId == moduleId)
                                                      );

                    if (track != null)
                    {
                        var trackProgress = await _db.UserTrackProgressCollection
                                            .AsQueryable()
                                            .Where(t => t.TrackId == track.Id && t.UserId == userId)
                                            .FirstOrDefaultAsync();

                        if (trackProgress != null)
                        {
                            int modulesCompleted = 0;

                            var trackConfig = track.ModulesConfiguration.FirstOrDefault(m => m.ModuleId == moduleId);

                            if (trackConfig != null && currentLevel > trackConfig.Level)
                            {
                                modulesCompleted++;
                                trackProgress.ModulesCompleted.Add(moduleId);
                                trackProgress.Progress = (decimal)modulesCompleted / (decimal)track.ModulesConfiguration.Count;

                                await _db.UserTrackProgressCollection.ReplaceOneAsync(
                                    t => t.Id == trackProgress.Id, trackProgress,
                                    cancellationToken : token
                                    );
                            }
                        }
                    }
                }
            }