Academatica.Api/Academatica.Api.Course/Controllers/CourseController.cs
/// <summary>
/// Endpoint used to finish the class with given ID (or practice of a class with given ID) for authenticated user.
/// </summary>
/// <param name="classId">Class ID.</param>
/// <param name="finishClassDto">Class finish params - amount of mistakes.</param>
/// <returns>Action result with received exp and achievements.</returns>
Endpoint used to finish the class with given ID (or practice of a class with given ID) for authenticated user.
Endpoint used to finish the class with given ID ( or practice of a class with given ID ) for authenticated user .
[HttpPost]
        [Route("classes/{classId}/finish")]
        public async Task<IActionResult> FinishClassForUser(string classId, [FromBody] FinishClassForUserRequestDto finishClassDto)
        {
            var userId = User.FindFirst("sub")?.Value;
            if (string.IsNullOrEmpty(userId))
            {
                return BadRequest("User ID was null.");
            }
            var user = _academaticaDbContext.Users.Where(x => x.Id.ToString() == userId).FirstOrDefault();
            if (user == null)
            {
                return NotFound("Invalid user ID.");
            }
            var finishedClass = _academaticaDbContext.Classes.Where(x => x.Id == classId).FirstOrDefault();
            if (finishedClass == null)
            {
                return NotFound("Invalid class ID.");
            }
            var userCompletedClasses = _academaticaDbContext.UserClasses.Where(x => x.UserId == user.Id).AsEnumerable();
            if (userCompletedClasses.Select(x => x.ClassId).Contains(finishedClass.Id))
            {
                var stats = _academaticaDbContext.UserStats.Where(x => x.UserId == user.Id).FirstOrDefault();
                if (stats != null)
                {
                    stats.UserExp += stats.UserExp + 50 <= 15000 ? (ulong)50 : 0;
                    stats.UserExpThisWeek += 50;
                    ExpChangePublishDto expChangePublishDto = new ExpChangePublishDto()
                    {
                        UserId = user.Id,
                        ExpThisWeek = stats.UserExpThisWeek,
                        Event = "EXP_CHANGE"
                    };
                    _messageBusClient.PublishExpChange(expChangePublishDto);
                }
                await _academaticaDbContext.SaveChangesAsync();
                return Ok(new FinishClassResponseDto()
                {
                    Exp = 50,
                    Achievements = new List<AchievementDto>()
                });
            }
            await _academaticaDbContext.UserClasses.AddAsync(new UserClass()
            {
                Class = finishedClass,
                ClassId = classId,
                CompletedAt = DateTime.UtcNow,
                User = user,
                UserId = user.Id
            });
            var finishedClassTopic = _academaticaDbContext.Topics.Where(x => x.Id == finishedClass.TopicId).FirstOrDefault();
            if (finishedClassTopic == null)
            {
                return NotFound("Invalid class topic.");
            }
            var userTopicMistakes = _academaticaDbContext.UserTopicMistakes.Where(x => x.TopicId == finishedClass.TopicId).FirstOrDefault();
            if (userTopicMistakes == null)
            {
                await _academaticaDbContext.UserTopicMistakes.AddAsync(new UserTopicMistake()
                {
                    User = user,
                    UserId = user.Id,
                    MistakeCount = (ulong)finishClassDto.MistakeCount,
                    Topic = finishedClassTopic,
                    TopicId = finishedClassTopic.Id
                });
            } else
            {
                userTopicMistakes.MistakeCount += (ulong)finishClassDto.MistakeCount;
            }
            var topicClassesIds = _academaticaDbContext.Classes.Where(x => x.TopicId == finishedClass.TopicId).Select(x => x.Id).ToList();
            var completedTopicClassesIds = _academaticaDbContext.UserClasses.Where(x => topicClassesIds.Contains(x.ClassId) && x.UserId.ToString() == userId).Select(x => x.ClassId).ToList();
            completedTopicClassesIds.Add(classId);
            if (Enumerable.SequenceEqual(topicClassesIds, completedTopicClassesIds))
            {
                await _academaticaDbContext.UserTopic.AddAsync(new UserTopic()
                {
                    User = user,
                    UserId = user.Id,
                    CompletedAt = DateTime.UtcNow,
                    Topic = finishedClassTopic,
                    TopicId = finishedClassTopic.Id
                });
                var tier = _academaticaDbContext.Tiers.Where(x => x.Id == finishedClassTopic.TierId).FirstOrDefault();
                if (tier != null)
                {
                    var tierTopicsIds = _academaticaDbContext.Topics.Where(x => x.TierId == finishedClassTopic.TierId).Select(x => x.Id).ToList();
                    var completedTierTopicsIds = _academaticaDbContext.UserTopic.Where(x => tierTopicsIds.Contains(x.TopicId)).Select(x => x.TopicId).ToList();
                    completedTierTopicsIds.Add(finishedClassTopic.Id);
                    if (Enumerable.SequenceEqual(tierTopicsIds, completedTierTopicsIds))
                    {
                        await _academaticaDbContext.UserTier.AddAsync(new UserTier()
                        {
                            User = user,
                            UserId = user.Id,
                            CompletedAt = DateTime.UtcNow,
                            Tier = tier,
                            TierId = tier.Id
                        });
                    }
                }
            }
            var statsEntry = _academaticaDbContext.UserStats.Where(x => x.UserId == user.Id).FirstOrDefault();
            if (statsEntry != null)
            {
                statsEntry.UserExp += statsEntry.UserExp + finishedClass.ExpReward <= 15000 ? finishedClass.ExpReward : 0;
                statsEntry.UserExpThisWeek += finishedClass.ExpReward;
                ExpChangePublishDto expChangePublishDto = new ExpChangePublishDto()
                {
                    UserId = user.Id,
                    ExpThisWeek = statsEntry.UserExpThisWeek,
                    Event = "EXP_CHANGE"
                };
                _messageBusClient.PublishExpChange(expChangePublishDto);
            }
            await _academaticaDbContext.SaveChangesAsync();
            var receivedAchievements = _practiceAchievementsDataClient.GetPracticeAchievements(user.Id, classId, finishClassDto.MistakeCount);
            return Ok(new FinishClassResponseDto()
            {
                Exp = (int)finishedClass.ExpReward,
                Achievements = receivedAchievements
            });
        }
[ HttpPost ] [ Route ( " " ) ] public async Task < IActionResult > FinishClassForUser ( string classId , [ FromBody ] FinishClassForUserRequestDto finishClassDto ) { var userId = User . FindFirst ( " " ) ? . Value ; if ( string . IsNullOrEmpty ( userId ) ) { return BadRequest ( " " ) ; } var user = _academaticaDbContext . Users . Where ( x => x . Id . ToString ( ) == userId ) . FirstOrDefault ( ) ; if ( user == null ) { return NotFound ( " " ) ; } var finishedClass = _academaticaDbContext . Classes . Where ( x => x . Id == classId ) . FirstOrDefault ( ) ; if ( finishedClass == null ) { return NotFound ( " " ) ; } var userCompletedClasses = _academaticaDbContext . UserClasses . Where ( x => x . UserId == user . Id ) . AsEnumerable ( ) ; if ( userCompletedClasses . Select ( x => x . ClassId ) . Contains ( finishedClass . Id ) ) { var stats = _academaticaDbContext . UserStats . Where ( x => x . UserId == user . Id ) . FirstOrDefault ( ) ; if ( stats != null ) { stats . UserExp += stats . UserExp + 50 <= 15000 ? ( ulong ) 50 : 0 ; stats . UserExpThisWeek += 50 ; ExpChangePublishDto expChangePublishDto = new ExpChangePublishDto ( ) { UserId = user . Id , ExpThisWeek = stats . UserExpThisWeek , Event = " " } ; _messageBusClient . PublishExpChange ( expChangePublishDto ) ; } await _academaticaDbContext . SaveChangesAsync ( ) ; return Ok ( new FinishClassResponseDto ( ) { Exp = 50 , Achievements = new List < AchievementDto > ( ) } ) ; } await _academaticaDbContext . UserClasses . AddAsync ( new UserClass ( ) { Class = finishedClass , ClassId = classId , CompletedAt = DateTime . UtcNow , User = user , UserId = user . Id } ) ; var finishedClassTopic = _academaticaDbContext . Topics . Where ( x => x . Id == finishedClass . TopicId ) . FirstOrDefault ( ) ; if ( finishedClassTopic == null ) { return NotFound ( " " ) ; } var userTopicMistakes = _academaticaDbContext . UserTopicMistakes . Where ( x => x . TopicId == finishedClass . TopicId ) . FirstOrDefault ( ) ; if ( userTopicMistakes == null ) { await _academaticaDbContext . UserTopicMistakes . AddAsync ( new UserTopicMistake ( ) { User = user , UserId = user . Id , MistakeCount = ( ulong ) finishClassDto . MistakeCount , Topic = finishedClassTopic , TopicId = finishedClassTopic . Id } ) ; } else { userTopicMistakes . MistakeCount += ( ulong ) finishClassDto . MistakeCount ; } var topicClassesIds = _academaticaDbContext . Classes . Where ( x => x . TopicId == finishedClass . TopicId ) . Select ( x => x . Id ) . ToList ( ) ; var completedTopicClassesIds = _academaticaDbContext . UserClasses . Where ( x => topicClassesIds . Contains ( x . ClassId ) && x . UserId . ToString ( ) == userId ) . Select ( x => x . ClassId ) . ToList ( ) ; completedTopicClassesIds . Add ( classId ) ; if ( Enumerable . SequenceEqual ( topicClassesIds , completedTopicClassesIds ) ) { await _academaticaDbContext . UserTopic . AddAsync ( new UserTopic ( ) { User = user , UserId = user . Id , CompletedAt = DateTime . UtcNow , Topic = finishedClassTopic , TopicId = finishedClassTopic . Id } ) ; var tier = _academaticaDbContext . Tiers . Where ( x => x . Id == finishedClassTopic . TierId ) . FirstOrDefault ( ) ; if ( tier != null ) { var tierTopicsIds = _academaticaDbContext . Topics . Where ( x => x . TierId == finishedClassTopic . TierId ) . Select ( x => x . Id ) . ToList ( ) ; var completedTierTopicsIds = _academaticaDbContext . UserTopic . Where ( x => tierTopicsIds . Contains ( x . TopicId ) ) . Select ( x => x . TopicId ) . ToList ( ) ; completedTierTopicsIds . Add ( finishedClassTopic . Id ) ; if ( Enumerable . SequenceEqual ( tierTopicsIds , completedTierTopicsIds ) ) { await _academaticaDbContext . UserTier . AddAsync ( new UserTier ( ) { User = user , UserId = user . Id , CompletedAt = DateTime . UtcNow , Tier = tier , TierId = tier . Id } ) ; } } } var statsEntry = _academaticaDbContext . UserStats . Where ( x => x . UserId == user . Id ) . FirstOrDefault ( ) ; if ( statsEntry != null ) { statsEntry . UserExp += statsEntry . UserExp + finishedClass . ExpReward <= 15000 ? finishedClass . ExpReward : 0 ; statsEntry . UserExpThisWeek += finishedClass . ExpReward ; ExpChangePublishDto expChangePublishDto = new ExpChangePublishDto ( ) { UserId = user . Id , ExpThisWeek = statsEntry . UserExpThisWeek , Event = " " } ; _messageBusClient . PublishExpChange ( expChangePublishDto ) ; } await _academaticaDbContext . SaveChangesAsync ( ) ; var receivedAchievements = _practiceAchievementsDataClient . GetPracticeAchievements ( user . Id , classId , finishClassDto . MistakeCount ) ; return Ok ( new FinishClassResponseDto ( ) { Exp = ( int ) finishedClass . ExpReward , Achievements = receivedAchievements } ) ; }
Endpoint used to finish the class with given ID (or practice of a class with given ID) for authenticated user.
Endpoint used to finish the class with given ID ( or practice of a class with given ID ) for authenticated user .
Action result with received exp and achievements.
Action result with received exp and achievements .
classId
string
None
FinishClassForUserRequestDto
[FromBody]
finishClassDto
Class finish params - amount of mistakes.
Class finish params - amount of mistakes .