예제 #1
0
        public async Task <IActionResult> AddAssignedQuestion(EditChallengeViewModel inputModel)
        {
            if (ModelState.IsValid)
            {
                // Translate the view model to our backend model
                var assignedQuestion = new ACMQ.AssignedQuestion
                {
                    Answers = inputModel.QuestionToAdd.Answers
                              .Select(p => new ACMQ.AssignedQuestion.AnswerList
                    {
                        AnswerParameters = p.AnswerParameters?.Select(a => new ACMQ.AssignedQuestion.AnswerParameterItem()
                        {
                            ErrorMessage = a.ErrorMessage, Key = a.Key, Value = a.Value ?? (inputModel.QuestionToAdd.QuestionType == "MultiChoice" ? "false" : "")
                        }).ToList(),
                        AssociatedQuestionId = p.AssociatedQuestionId,
                        ResponseType         = p.ResponseType
                    }
                                      ).ToList(),
                    QuestionType         = inputModel.QuestionToAdd.QuestionType,
                    AssociatedQuestionId = inputModel.QuestionToAdd.AssociatedQuestionId,
                    Description          = inputModel.QuestionToAdd.Description,
                    Difficulty           = inputModel.QuestionToAdd.Difficulty,
                    Name                  = inputModel.QuestionToAdd.Name,
                    QuestionId            = string.IsNullOrWhiteSpace(inputModel.QuestionToAdd.Id) ? Guid.NewGuid().ToString() : inputModel.QuestionToAdd.Id,
                    TargettedAzureService = inputModel.QuestionToAdd.TargettedAzureService,
                    Text                  = inputModel.QuestionToAdd.Text,
                    TextParameters        = inputModel.QuestionToAdd.TextParameters?.ToDictionary(p => p.Key, p => p.Value) ?? new Dictionary <string, string>(),
                    ChallengeId           = inputModel.QuestionToAdd.ChallengeId,
                    Uris                  = inputModel.QuestionToAdd.Uris?
                                            .Select(p => new ACMQ.AssignedQuestion.UriList
                    {
                        CallType                  = p.CallType,
                        Id                        = p.Id,
                        Uri                       = p.Uri,
                        UriParameters             = p.UriParameters?.ToDictionary(q => q.Key, q => q.Value) ?? new Dictionary <string, string>(),
                        RequiresContributorAccess = p.RequiresContributorAccess
                    }
                                                    ).ToList(),
                    Justification = inputModel.QuestionToAdd.Justification,
                    UsefulLinks   = inputModel.QuestionToAdd.UsefulLinks ?? new List <string>()
                };

                List <ACMQ.QuestionLite> challengeQuestions = null;
                if (inputModel.ChallengeQuestions != null)
                {
                    challengeQuestions = inputModel.ChallengeQuestions
                                         .Select(p => new ACMQ.QuestionLite
                    {
                        Description          = p.Description,
                        Difficulty           = p.Difficulty,
                        Id                   = p.Id,
                        Index                = p.Index,
                        Name                 = p.Name,
                        AssociatedQuestionId = p.AssociatedQuestionId,
                        NextQuestionId       = p.NextQuestionId
                    }).ToList();
                }
                else
                {
                    challengeQuestions = new List <ACMQ.QuestionLite>();
                }

                // Get the existing challenge details
                var challenge = new ACMT.ChallengeDetails()
                {
                    Description          = inputModel.Description,
                    Id                   = inputModel.Id,
                    Name                 = inputModel.Name,
                    Questions            = challengeQuestions,
                    AzureServiceCategory = inputModel.AzureServiceCategory,
                    WelcomeMessage       = inputModel.WelcomeMessage,
                    Duration             = inputModel.Duration,
                    PrereqLinks          = inputModel.PrereqLinks
                };

                // Check if this is an update to an existing challenge question
                if (challenge.Questions.Exists(p => p.Id == assignedQuestion.QuestionId))
                {
                    // We only need to update the assigned question, not the challenge
                    var updateQuestionResult = await assignedQuestionProvider.AddItemAsync(assignedQuestion);

                    if (!updateQuestionResult.Success)
                    {
                        return(StatusCode(500));
                    }
                }
                else
                {
                    // Create a new Challenge Question
                    var newChallengeQuestion = new ACMQ.QuestionLite
                    {
                        Name                 = assignedQuestion.Name,
                        Description          = assignedQuestion.Description,
                        Difficulty           = assignedQuestion.Difficulty,
                        Id                   = assignedQuestion.QuestionId,
                        AssociatedQuestionId = assignedQuestion.AssociatedQuestionId,
                        Index                = challenge.Questions.Count()
                    };
                    // Assign the next question value of the last question in the challenge to this one
                    if (challenge.Questions.Count > 0)
                    {
                        challenge.Questions[challenge.Questions.Count - 1].NextQuestionId = assignedQuestion.QuestionId;
                    }
                    challenge.Questions.Add(newChallengeQuestion);

                    // Get the global parameters for the challenge
                    var globalParamsResponse = await challengeParameterProvider.GetItemAsync(assignedQuestion.ChallengeId);

                    var globalParams = globalParamsResponse.Item2;

                    // Check if the parameter is global and it exists in the global parameters list
                    // If yes, increment the count. If no, add it
                    foreach (var parameter in assignedQuestion.TextParameters.ToList())
                    {
                        if (parameter.Key.StartsWith("Global."))
                        {
                            var globalParameter = globalParams?.Parameters?.Where(p => p.Key == parameter.Key.Replace("Global.", "")).FirstOrDefault();

                            if (globalParameter == null)
                            {
                                if (globalParams == null)
                                {
                                    globalParams = new ACMP.GlobalChallengeParameters()
                                    {
                                        ChallengeId = assignedQuestion.ChallengeId, Parameters = new List <ACMP.GlobalChallengeParameters.ParameterDefinition>()
                                    };
                                }
                                else if (globalParams.Parameters == null)
                                {
                                    globalParams.Parameters = new List <ACMP.GlobalChallengeParameters.ParameterDefinition>();
                                }

                                globalParams.Parameters.Add(new ACMP.GlobalChallengeParameters.ParameterDefinition
                                {
                                    Key   = parameter.Key.Replace("Global.", ""),
                                    Value = parameter.Value,
                                    AssignedToQuestion = 1
                                });
                            }
                            else
                            {
                                globalParameter.AssignedToQuestion += 1;
                            }
                        }
                    }

                    await challengeParameterProvider.AddItemAsync(globalParams);

                    var addQuestionResult = await assignedQuestionProvider.AddItemAsync(assignedQuestion);

                    if (addQuestionResult.Success)
                    {
                        var updateChallengeResult = await challengeProvider.AddItemAsync(challenge);

                        if (!updateChallengeResult.Success)
                        {
                            await assignedQuestionProvider.DeleteItemAsync(assignedQuestion.QuestionId);

                            return(StatusCode(500));
                        }
                    }
                }
            }

            return(RedirectToAction("Edit", new
            {
                challengeId = inputModel.QuestionToAdd.ChallengeId
            }));
        }
        public async Task <IActionResult> StartChallenge(string challengeId, string questionId)
        {
            var user = await _userManager.GetUserAsync(User);

            var userChallengeResponse = await userChallengesProvider.GetItemAsync(user.Id);

            var challengeResponse = await challengesProvider.GetItemAsync(challengeId);

            var aggregateReponse = await aggregateProvider.GetItemAsync(challengeId);

            if (!userChallengeResponse.Item1.IsError)
            {
                // If the challenge is not locked, lock it since the first user has started it
                if (!challengeResponse.Item2.IsLocked)
                {
                    challengeResponse.Item2.IsLocked = true;
                    await challengesProvider.AddItemAsync(challengeResponse.Item2);
                }

                // If this is a new challenge, we first need to show the introduction
                var showIntroduction = false;

                // New tournament
                if (!userChallengeResponse.Item1.Success)
                {
                    var userChallenge = new UserChallenges {
                        Id = user.Id, Challenges = new List <UserChallengeItem>()
                    };
                    userChallenge.Challenges
                    .Add(new UserChallengeItem()
                    {
                        AccumulatedXP   = 0,
                        ChallengeId     = challengeId,
                        Completed       = false,
                        CurrentQuestion = questionId,
                        StartTimeUTC    = DateTime.Now.ToUniversalTime(),
                        CurrentIndex    = 0,
                        NumOfQuestions  = challengeResponse.Item2.Questions.Count()
                    });

                    await userChallengesProvider.AddItemAsync(userChallenge);

                    if (aggregateReponse.Item1.Success)
                    {
                        var agg =
                            aggregateReponse.Item2 ??
                            new ACMA.Aggregate()
                        {
                            Id             = challengeId,
                            ChallengeUsers = new ACMA.ChallengeAggregateUsers()
                            {
                                Finished = 0, Started = 0
                            }
                        };

                        agg.ChallengeUsers.Started += 1;
                        await aggregateProvider.AddItemAsync(agg);
                    }
                    else
                    {
                        // Doesn't exist
                        var agg = new ACMA.Aggregate()
                        {
                            Id             = challengeId,
                            ChallengeUsers = new ACMA.ChallengeAggregateUsers()
                            {
                                Finished = 0, Started = 0
                            }
                        };

                        agg.ChallengeUsers.Started += 1;
                        await aggregateProvider.AddItemAsync(agg);
                    }

                    showIntroduction = true;
                }
                else
                {
                    // The user already has done some challenges
                    // If this is new, then add the userChallenge and update the Aggregate
                    if (!userChallengeResponse.Item2.Challenges.Any(p => p.ChallengeId == challengeId))
                    {
                        userChallengeResponse.Item2.Challenges
                        .Add(new UserChallengeItem()
                        {
                            AccumulatedXP   = 0,
                            ChallengeId     = challengeId,
                            Completed       = false,
                            CurrentQuestion = questionId,
                            StartTimeUTC    = DateTime.Now.ToUniversalTime(),
                            CurrentIndex    = 0,
                            NumOfQuestions  = challengeResponse.Item2.Questions.Count()
                        });
                        await userChallengesProvider.AddItemAsync(userChallengeResponse.Item2);

                        if (aggregateReponse.Item1.Success)
                        {
                            var agg =
                                aggregateReponse.Item2 ??
                                new ACMA.Aggregate()
                            {
                                Id             = challengeId,
                                ChallengeUsers = new ACMA.ChallengeAggregateUsers()
                                {
                                    Finished = 0, Started = 0
                                }
                            };

                            agg.ChallengeUsers.Started += 1;
                            await aggregateProvider.AddItemAsync(agg);
                        }
                        else
                        {
                            // Doesn't exist
                            var agg = new ACMA.Aggregate()
                            {
                                Id             = challengeId,
                                ChallengeUsers = new ACMA.ChallengeAggregateUsers()
                                {
                                    Finished = 0, Started = 0
                                }
                            };

                            agg.ChallengeUsers.Started += 1;
                            await aggregateProvider.AddItemAsync(agg);
                        }

                        showIntroduction = true;
                    }
                    else if (userChallengeResponse.Item2.Challenges.Where(p => p.ChallengeId == challengeId).FirstOrDefault()?.CurrentIndex == 0)
                    {
                        // If the user already registered for the challenge but never started it
                        showIntroduction = true;
                    }
                }

                if (showIntroduction)
                {
                    return(RedirectToAction("Introduction", new { challengeId = challengeId, questionId = questionId }));
                }
                else
                {
                    return(RedirectToAction("ShowQuestion", new { challengeId = challengeId, questionId = questionId }));
                }
            }


            return(StatusCode(500));
        }