public async Task <IActionResult> GetChapterDetails(int courseId, int chapterNumber) { if (courseId < 1 || chapterNumber < 1) { return(BadRequest()); } try { var chapter = await _chapterService.LoadChapterAsync(courseId, chapterNumber); List <User> chapterUsers = new List <User>(); if (IsLector()) { chapterUsers.AddRange(await _chapterRepository.GetUsersOfChapterAsync(chapter.Id)); } if (!chapterUsers.Any()) //add the own user { chapterUsers.Add(await _userManager.GetUserAsync(User)); } var model = _chapterConverter.ToChapterDetailModel(chapter, chapterUsers); return(Ok(model)); } catch (DataNotFoundException) { return(NotFound()); } }
public async Task <IActionResult> DownloadCourseExerciseScores(int courseId, [FromBody] ScoreOptions input) { //TODO: clean up this quick an dirty (non-performant) implementation. if (!IsLector()) { return(Forbid()); } //Get (and sort) all users var allUsers = new List <User>(); foreach (var chapterScoreOptions in input.ChapterScoreOptions) { var chapter = await _chapterService.LoadChapterAsync(courseId, chapterScoreOptions.ChapterNumber); allUsers = allUsers.Union(await _chapterRepository.GetUsersOfChapterAsync(chapter.Id), new DomainOjbectEqualityComparer <User>()).ToList(); } allUsers = allUsers.OrderBy(u => u.LastName).ThenBy(u => u.FirstName).ToList(); //preload the chapters var chapterDictionary = new Dictionary <int, Chapter>(); foreach (var chapterScoreOptions in input.ChapterScoreOptions) { chapterDictionary[chapterScoreOptions.ChapterNumber] = await _chapterService.LoadChapterWithTestsAsync(courseId, chapterScoreOptions.ChapterNumber); } var results = new List <dynamic>(); foreach (var user in allUsers) { var result = new ExpandoObject(); result.TryAdd("LastName", user.LastName); result.TryAdd("FirstName", user.FirstName); double total = 0.0; double totalMaximum = 0.0; foreach (var chapterScoreOptions in input.ChapterScoreOptions) { var chapter = chapterDictionary[chapterScoreOptions.ChapterNumber]; foreach (var exerciseScoreOptions in chapterScoreOptions.ExerciseScoreOptions) { var exercise = chapter.Exercises.FirstOrDefault(e => e.Code == exerciseScoreOptions.ExerciseCode); if (exercise == null) { continue; } var numberOfTests = exercise.Tests.Count; var resultDto = await _assignmentService.GetResultsForUserAsync(exercise.Id, user.Id, chapterScoreOptions.Date); var numberOfPassedTests = resultDto?.TestResults?.Count(r => r.Passed) ?? 0; double scorePerTest = exerciseScoreOptions.MaximumScore / (numberOfTests - exerciseScoreOptions.MinimumNumberOfGreenTestsThreshold); double score = Math.Max(numberOfPassedTests - exerciseScoreOptions.MinimumNumberOfGreenTestsThreshold, 0) * scorePerTest; total += score; totalMaximum += exerciseScoreOptions.MaximumScore; result.TryAdd($"{chapter.Number}.{exerciseScoreOptions.ExerciseCode}_NbrPassed({numberOfTests})", numberOfPassedTests); result.TryAdd($"{chapter.Number}.{exerciseScoreOptions.ExerciseCode}_Score({exerciseScoreOptions.MaximumScore})", score); } } result.TryAdd($"Total({totalMaximum})", total); results.Add(result); } var memoryStream = new MemoryStream(); var streamWriter = new StreamWriter(memoryStream); var config = new Configuration { QuoteAllFields = true, CultureInfo = new CultureInfo("nl-BE"), }; var csv = new CsvWriter(streamWriter, config); csv.WriteRecords(results); streamWriter.Flush(); memoryStream.Position = 0; return(File(memoryStream, "text/csv", "ExerciseScores.csv")); }