Example #1
0
        public ActionResult ExportCourseStatistics(CourseStatisticsParams param)
        {
            var model = GetCourseStatisticsModel(param, 3000);

            var package = new ExcelPackage();

            FillCourseStatisticsExcelWorksheet(
                package.Workbook.Worksheets.Add(model.Course.Title),
                model
                );
            FillCourseStatisticsExcelWorksheet(
                package.Workbook.Worksheets.Add("Только полные баллы"),
                model,
                onlyFullScores: true
                );

            var filename = model.Course.Id + ".xlsx";

            Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
            Response.Charset = "";
            Response.Cache.SetCacheability(HttpCacheability.NoCache);
            Response.ContentType = "application/vnd.ms-excel";
            package.SaveAs(Response.OutputStream);
            Response.End();
            return(new EmptyResult());
        }
Example #2
0
        public ActionResult CourseStatistics(CourseStatisticsParams param, int max = 200)
        {
            if (param.CourseId == null)
            {
                return(HttpNotFound());
            }

            var usersLimit = max;

            if (usersLimit > 300)
            {
                usersLimit = 300;
            }
            if (usersLimit < 0)
            {
                usersLimit = 200;
            }

            var model = GetCourseStatisticsModel(param, usersLimit);

            if (model == null)
            {
                return(HttpNotFound());
            }
            return(View(model));
        }
Example #3
0
        public ActionResult ExportCourseStatisticsAsXml(CourseStatisticsParams param)
        {
            var model = GetCourseStatisticsModel(param, 3000);

            var filename = model.Course.Id + ".xml";

            Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);

            return(Content(new CourseStatisticsModel(model).XmlSerialize(), "text/xml"));
        }
Example #4
0
        public ActionResult ExportCourseStatisticsAsJson(CourseStatisticsParams param)
        {
            var model = GetCourseStatisticsModel(param, 3000);

            var filename = model.Course.Id + ".json";

            Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);

            return(Json(new CourseStatisticsModel(model), JsonRequestBehavior.AllowGet));
        }
Example #5
0
        /*TODO: extract copy-paste */
        private CourseStatisticPageModel GetCourseStatisticsModel(CourseStatisticsParams param, int usersLimit)
        {
            var courseId     = param.CourseId;
            var periodStart  = param.PeriodStartDate;
            var periodFinish = param.PeriodFinishDate;
            var groupsIds    = Request.GetMultipleValues("group");
            var isInstructor = User.HasAccessFor(courseId, CourseRole.Instructor);
            var isStudent    = !isInstructor;

            var currentUserId = User.Identity.GetUserId();

            if (isStudent && !CanStudentViewGroupsStatistics(currentUserId, groupsIds))
            {
                return(null);
            }

            var realPeriodFinish = periodFinish.Add(TimeSpan.FromDays(1));

            var course    = courseManager.GetCourse(courseId);
            var slidesIds = course.Slides.Select(s => s.Id).ToList();

            var filterOptions = ControllerUtils.GetFilterOptionsByGroup <VisitsFilterOptions>(groupsRepo, User, courseId, groupsIds, allowSeeGroupForAnyMember: true);

            filterOptions.SlidesIds    = slidesIds;
            filterOptions.PeriodStart  = periodStart;
            filterOptions.PeriodFinish = realPeriodFinish;

            var usersIds = visitsRepo.GetVisitsInPeriod(filterOptions).DistinctBy(v => v.UserId).Select(v => v.UserId);

            /* If we filtered out users from one or several groups show them all */
            if (filterOptions.UsersIds != null && !filterOptions.IsUserIdsSupplement)
            {
                usersIds = filterOptions.UsersIds;
            }

            var visitedUsers = usersIds
                               .Join(db.Users, v => v, u => u.Id, (v, u) => new UnitStatisticUserInfo {
                UserId = u.Id, UserName = u.UserName, UserVisibleName = (u.LastName + u.FirstName != "" ? u.LastName + " " + u.FirstName : u.UserName).Trim()
            })
                               .ToList();
            var isMore = visitedUsers.Count > usersLimit;

            var unitBySlide   = course.Units.SelectMany(u => u.Slides.Select(s => Tuple.Create(u.Id, s.Id))).ToDictionary(p => p.Item2, p => p.Item1);
            var scoringGroups = course.Settings.Scoring.Groups;

            var visitedSlidesCountByUserAllTime = visitsRepo.GetVisitsInPeriod(filterOptions.WithPeriodStart(DateTime.MinValue).WithPeriodFinish(DateTime.MaxValue))
                                                  .GroupBy(v => v.UserId)
                                                  .ToDictionary(g => g.Key, g => g.Count());

            /* Get `usersLimit` best by slides count */
            visitedUsers = visitedUsers
                           .OrderByDescending(u => visitedSlidesCountByUserAllTime.GetOrDefault(u.UserId, 0))
                           .Take(usersLimit)
                           .ToList();
            var visitedUsersIds = visitedUsers.Select(v => v.UserId).ToList();

            var visitedUsersGroups = groupsRepo.GetUsersGroupsIds(new List <string> {
                courseId
            }, visitedUsersIds, User, 10).ToDefaultDictionary();

            /* From now fetch only filtered users' statistics */
            filterOptions.UsersIds            = visitedUsersIds;
            filterOptions.IsUserIdsSupplement = false;
            var scoreByUserUnitScoringGroup = ((IEnumerable <Visit>)visitsRepo.GetVisitsInPeriod(filterOptions))
                                              .GroupBy(v => Tuple.Create(v.UserId, unitBySlide[v.SlideId], course.FindSlideById(v.SlideId)?.ScoringGroup))
                                              .ToDictionary(g => g.Key, g => g.Sum(v => v.Score))
                                              .ToDefaultDictionary();

            var shouldBeSolvedSlides    = course.Slides.Where(s => s.ShouldBeSolved).ToList();
            var shouldBeSolvedSlidesIds = shouldBeSolvedSlides.Select(s => s.Id).ToList();
            var shouldBeSolvedSlidesByUnitScoringGroup = shouldBeSolvedSlides
                                                         .GroupBy(s => Tuple.Create(unitBySlide[s.Id], s.ScoringGroup))
                                                         .ToDictionary(g => g.Key, g => g.ToList())
                                                         .ToDefaultDictionary();
            var scoreByUserAndSlide = ((IEnumerable <Visit>)visitsRepo.GetVisitsInPeriod(filterOptions.WithSlidesIds(shouldBeSolvedSlidesIds)))
                                      .GroupBy(v => Tuple.Create(v.UserId, v.SlideId))
                                      .ToDictionary(g => g.Key, g => g.Sum(v => v.Score))
                                      .ToDefaultDictionary();

            var additionalScores = additionalScoresRepo
                                   .GetAdditionalScoresForUsers(courseId, visitedUsersIds)
                                   .ToDictionary(kv => kv.Key, kv => kv.Value.Score)
                                   .ToDefaultDictionary();
            var usersGroupsIds = groupsRepo.GetUsersGroupsIds(courseId, visitedUsersIds);
            var enabledAdditionalScoringGroupsForGroups = groupsRepo.GetEnabledAdditionalScoringGroups(courseId)
                                                          .GroupBy(e => e.GroupId)
                                                          .ToDictionary(g => g.Key, g => g.Select(e => e.ScoringGroupId).ToList());

            /* Filter out only scoring groups which are affected in selected groups */
            var additionalScoringGroupsForFilteredGroups = ControllerUtils.GetEnabledAdditionalScoringGroupsForGroups(groupsRepo, course, groupsIds, User);

            scoringGroups = scoringGroups
                            .Where(kv => kv.Value.MaxNotAdditionalScore > 0 || additionalScoringGroupsForFilteredGroups.Contains(kv.Key))
                            .ToDictionary(kv => kv.Key, kv => kv.Value)
                            .ToSortedDictionary();

            var groups = groupsRepo.GetAvailableForUserGroups(courseId, User);

            if (!isInstructor)
            {
                groups = groupsRepo.GetUserGroups(courseId, currentUserId);
            }
            var model = new CourseStatisticPageModel
            {
                IsInstructor       = isInstructor,
                Course             = course,
                SelectedGroupsIds  = groupsIds,
                Groups             = groups,
                PeriodStart        = periodStart,
                PeriodFinish       = periodFinish,
                VisitedUsers       = visitedUsers,
                VisitedUsersIsMore = isMore,
                VisitedUsersGroups = visitedUsersGroups,
                ShouldBeSolvedSlidesByUnitScoringGroup = shouldBeSolvedSlidesByUnitScoringGroup,
                ScoringGroups = scoringGroups,
                ScoreByUserUnitScoringGroup = scoreByUserUnitScoringGroup,
                ScoreByUserAndSlide         = scoreByUserAndSlide,
                AdditionalScores            = additionalScores,
                UsersGroupsIds = usersGroupsIds,
                EnabledAdditionalScoringGroupsForGroups = enabledAdditionalScoringGroupsForGroups,
            };

            return(model);
        }