Exemplo n.º 1
0
        public async Task <IActionResult> AddBooking(Booking Booking)
        {
            var RequiredField = uow.BookingDomainService.PostBooking(Booking);

            if (!RequiredField)
            {
                dc.Booking.Add(Booking);
                await dc.SaveChangesAsync();

                return(new ObjectResult(Booking));
            }
            return(null);
        }
        public async Task <IActionResult> AddPackageByActivity(PackageByActivity PackageByActivity)
        {
            var RequiredField = uow.PackageByActivityDomainService.PostPackageByActivity(PackageByActivity);

            if (!RequiredField)
            {
                dc.PackageByActivity.Add(PackageByActivity);
                await dc.SaveChangesAsync();

                return(new ObjectResult(PackageByActivity));
            }
            return(null);
        }
Exemplo n.º 3
0
        public async Task <IActionResult> AddCategory(Category Category)
        {
            var RequiredField = uow.CategoryDomainService.PostCategory(Category);

            if (!RequiredField)
            {
                dc.Category.Add(Category);
                await dc.SaveChangesAsync();

                return(new ObjectResult(Category));
            }
            return(null);
        }
Exemplo n.º 4
0
        public async Task <IActionResult> AddClient(Client Client)
        {
            var RequiredField = uow.ClientDomainService.PostClient(Client);

            if (!RequiredField)
            {
                dc.Client.Add(Client);
                await dc.SaveChangesAsync();

                return(new ObjectResult(Client));
            }
            return(null);
        }
Exemplo n.º 5
0
        public async Task <IActionResult> AddUser(User User)
        {
            var RequiredField = uow.UserDomainService.PostUser(User);

            if (!RequiredField)
            {
                dc.User.Add(User);
                await dc.SaveChangesAsync();

                return(new ObjectResult(User));
            }
            return(null);
        }
Exemplo n.º 6
0
        public async Task <IActionResult> AddActivity(ActivityDTO activity)
        {
            var RequiredField = uow.ActivityDomainService.PostActivity(activity);
            var CreateImage   = uow.ActivityDomainService.UploadImage(activity);

            if (!RequiredField && CreateImage != null)
            {
                var activityModel = mapper.Map <Activity>(activity);
                dc.Activity.Add(activityModel);
                await dc.SaveChangesAsync();

                return(new ObjectResult(activity));
            }
            return(null);
        }
Exemplo n.º 7
0
        public async Task <long> Handle(GetLastVisitedLessonQuery request, CancellationToken cancellationToken)
        {
            var lastVisited = await _context.LastVisitedLessons
                              .AsNoTracking()
                              .Where(x => x.CourseId == request.CourseId && x.UserId == _currentUser.UserId)
                              .FirstOrDefaultAsync(cancellationToken);

            if (lastVisited == null)
            {
                lastVisited = new LastVisitedLessonEntity
                {
                    CourseId = request.CourseId,
                    UserId   = _currentUser.UserId,
                    LessonId = (await _context.Courses
                                .Where(x => x.Id == request.CourseId)
                                .Include(x => x.Modules)
                                .ThenInclude(y => y.Lessons)
                                .FirstOrDefaultAsync(cancellationToken)).Modules.First().Lessons.First().Id
                };

                await _context.LastVisitedLessons.AddAsync(lastVisited, cancellationToken);

                await _context.SaveChangesAsync(cancellationToken);
            }

            return(lastVisited.LessonId);
        }
Exemplo n.º 8
0
        public async Task <CourseResponse> Handle(UpdateCourseInfoCommand request, CancellationToken cancellationToken)
        {
            var course = await _context.Courses
                         .Where(x => x.Id == request.Id)
                         .Include(x => x.Modules).ThenInclude(y => y.Lessons)
                         .Include(x => x.Authors).ThenInclude(y => y.Author)
                         .FirstOrDefaultAsync(cancellationToken);

            if (course == null)
            {
                throw new NotImplementedException();
            }

            if (course.Status == CourseStatus.AwaitingPublication || course.Status == CourseStatus.Published)
            {
                throw new NotImplementedException();
            }

            course.Title            = request.Title;
            course.Description      = request.Description;
            course.ShortDescription = request.ShortDescription;
            course.TargetAudience   = request.TargetAudience;
            course.Charge           = request.Charge;
            course.Avatar           = request.Avatar;

            _context.Courses.Update(course);
            await _context.SaveChangesAsync(cancellationToken);

            return(_mapper.Map <CourseEntity, CourseResponse>(course));
        }
        public async Task <List <ProgressResponse> > Handle(CreateProgressCommand request, CancellationToken cancellationToken)
        {
            var progresses = await _context.Progresses
                             .Where(x => x.CourseId == request.CourseId && x.UserId == _currentUser.UserId)
                             .Include(x => x.Lesson)
                             .ToListAsync(cancellationToken);

            if (progresses.All(x => x.LessonId != request.LessonId))
            {
                var progress = new ProgressEntity
                {
                    CourseId        = request.CourseId,
                    LessonId        = request.LessonId,
                    UserId          = _currentUser.UserId,
                    IsVisited       = true,
                    ManuallyChecked = !(progresses.FirstOrDefault(x => x.LessonId == request.LessonId).ManuallyChecked)
                };

                await _context.Progresses.AddAsync(progress, cancellationToken);

                await _context.SaveChangesAsync(cancellationToken);

                progresses.Add(progress);
            }



            return(_mapper.Map <List <ProgressEntity>, List <ProgressResponse> >(progresses));
        }
        public async Task <RefreshTokenResponse> Handle(RefreshGeneratedTokenCommand request, CancellationToken cancellationToken)
        {
            var validatedToken = GetPrincipalFromToken(request.Token);

            if (validatedToken == null)
            {
                throw new RefreshTokenException("Invalid token");
            }

            var expiryDateUnix = long.Parse(validatedToken.Claims.Single(x =>
                                                                         x.Type == JwtRegisteredClaimNames.Exp).Value);

            var expiryDateUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
                                .AddSeconds(expiryDateUnix);

            if (expiryDateUtc > DateTime.Now)
            {
                throw new System.NotImplementedException();
            }

            var jti = validatedToken.Claims.Single(x => x.Type == JwtRegisteredClaimNames.Jti).Value;

            var storedRefreshToken = _context.RefreshTokens
                                     .AsNoTracking()
                                     .SingleOrDefault(x => x.Token == request.RefreshToken);

            if (storedRefreshToken == null)
            {
                throw new RefreshTokenException("This refresh token does not exist");
            }
            if (storedRefreshToken.ExpiryDate < DateTime.UtcNow)
            {
                throw new RefreshTokenException("This refresh token has expired");
            }
            if (storedRefreshToken.Invalidated)
            {
                throw new RefreshTokenException("This refresh token has been invalidated");
            }
            if (storedRefreshToken.Used)
            {
                throw new RefreshTokenException("This refresh token has been used");
            }
            if (storedRefreshToken.JwtId != jti)
            {
                throw new RefreshTokenException("This refresh token does not match this JWT");
            }

            storedRefreshToken.Used = true;
            _context.RefreshTokens.Update(storedRefreshToken);
            await _context.SaveChangesAsync(cancellationToken);

            var user = await _manager.FindByIdAsync(validatedToken.Claims.Single(x =>
                                                                                 x.Type == JwtRegisteredClaimNames.Jti).Value);

            var tokenResult = await _mediator.Send(new GenerateTokenCommand { User = user }, cancellationToken);

            return(_mapper.Map <JsonWebTokenResult, RefreshTokenResponse>(tokenResult));
        }
Exemplo n.º 11
0
        public async Task <CourseResponse> Handle(UpdateCourseScheduleCommand request, CancellationToken cancellationToken)
        {
            var course = await _context.Courses
                         .Where(x => x.Id == request.Id)
                         .Include(x => x.Modules).ThenInclude(y => y.Lessons)
                         .Include(x => x.Authors).ThenInclude(y => y.Author)
                         .FirstOrDefaultAsync(cancellationToken);

            if (course == null)
            {
                throw new NotFoundException(nameof(CourseEntity), request.Id);
            }

            if (course.Status == CourseStatus.Published || course.Status == CourseStatus.AwaitingPublication)
            {
                throw new CourseStatusException(nameof(CourseEntity), request.Id);
            }

            var modules = _mapper.Map <ICollection <UpdateCourseScheduleCommand.UpdateModule>, ICollection <ModuleEntity> >(request.Modules);

            foreach (var module in course.Modules)
            {
                if (modules.All(x => x.Id != module.Id))
                {
                    _context.Modules.Remove(module);
                }

                foreach (var lesson in module.Lessons)
                {
                    if (!modules.Any(x => x.Lessons.Any(y => y.Id == lesson.Id)))
                    {
                        _context.Lessons.Remove(lesson);
                    }
                }
            }

            course.Modules = modules;

            var progresses = await _context.Progresses
                             .Where(x => x.CourseId == course.Id)
                             .ToListAsync(cancellationToken);

            foreach (var progress in progresses.Where(progress =>
                                                      !course.Modules.Any(x =>
                                                                          x.Lessons.Any(y =>
                                                                                        y.Id == progress.LessonId))))
            {
                _context.Progresses.Remove(progress);
            }


            _context.Courses.Update(course);

            await _context.SaveChangesAsync(cancellationToken);

            return(_mapper.Map <CourseEntity, CourseResponse>(course));
        }
Exemplo n.º 12
0
        public async Task <Unit> Handle(LogoutUserCommand request, CancellationToken cancellationToken)
        {
            var token = await _context.RefreshTokens
                        .AsNoTracking()
                        .Where(x => x.UserId == _currentUser.UserId && x.Token == request.RefreshToken)
                        .FirstOrDefaultAsync(cancellationToken);

            _context.RefreshTokens.Remove(token);
            await _context.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(UpdateCourseStatusCommand request, CancellationToken cancellationToken)
        {
            var course = await _context.Courses
                         .FirstOrDefaultAsync(x => x.Id == request.CourseId, cancellationToken);

            if (course == null)
            {
                throw new NotImplementedException();
            }

            course.Status = request.Status;
            _context.Courses.Update(course);
            await _context.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <long> Handle(CreateCommentCommand request, CancellationToken cancellationToken)
        {
            var comment = new CommentEntity
            {
                AuthorId  = _currentUser.UserId,
                LessonId  = request.LessonId,
                Text      = request.Text,
                WrittenAt = DateTime.Now
            };

            await _context.Comments.AddAsync(comment, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            return(comment.Id);
        }
        public async Task <Unit> Handle(DeleteSubscriptionCommand request, CancellationToken cancellationToken)
        {
            var subscription = await _context.Subscriptions
                               .AsNoTracking()
                               .FirstOrDefaultAsync(x => x.SubscriberId == _currentUser.UserId && x.CourseId == request.CourseId,
                                                    cancellationToken);

            if (subscription == null)
            {
                throw new SubscriptionException("Subscription for this user does not exist");
            }

            _context.Subscriptions.Remove(subscription);
            await _context.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <Unit> Handle(CreateSubscriptionCommand request, CancellationToken cancellationToken)
        {
            var subscription = await _context.Subscriptions
                               .AsNoTracking()
                               .FirstOrDefaultAsync(x => x.SubscriberId == _currentUser.UserId && x.CourseId == request.CourseId, cancellationToken);

            if (subscription != null)
            {
                throw new SubscriptionException("Already subscribed");
            }

            await _context.Subscriptions.AddAsync(new UserCourseEntity
            {
                SubscriberId = _currentUser.UserId,
                CourseId     = request.CourseId
            }, cancellationToken);

            if (_context.Progresses
                .AsNoTracking()
                .Count(x => x.CourseId == request.CourseId && x.UserId == _currentUser.UserId) == 0)
            {
                var modules = await _context.Modules
                              .AsNoTracking()
                              .Where(x => x.CourseId == request.CourseId)
                              .Include(x => x.Lessons)
                              .ToListAsync(cancellationToken);

                foreach (var progress in from module in modules from lesson in module.Lessons select new ProgressEntity
                {
                    CourseId = request.CourseId,
                    LessonId = lesson.Id,
                    UserId = _currentUser.UserId,
                    IsVisited = false,
                    ManuallyChecked = !lesson.ManualChecking,
                    Score = 0
                })
                {
                    await _context.Progresses.AddAsync(progress, cancellationToken);
                }
            }


            await _context.SaveChangesAsync(cancellationToken);

            return(Unit.Value);
        }
        public async Task <JsonWebTokenResult> Handle(GenerateTokenCommand request, CancellationToken cancellationToken)
        {
            var tokenHandler = new JwtSecurityTokenHandler();
            var key          = Encoding.ASCII.GetBytes(_jsonWebToken.Secret);

            var tokenExpiration = DateTime.UtcNow.AddSeconds(_jsonWebToken.TokenLifetime);

            var claims = new List <Claim>
            {
                new Claim(JwtRegisteredClaimNames.Sub, request.User.Email),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                new Claim(JwtRegisteredClaimNames.Email, request.User.Email),
                new Claim("Id", request.User.Id)
            };

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject            = new ClaimsIdentity(claims),
                Expires            = tokenExpiration,
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
                                                            SecurityAlgorithms.HmacSha256Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescriptor);

            var refreshToken = new RefreshTokenEntity
            {
                Token        = Guid.NewGuid().ToString(),
                JwtId        = token.Id,
                UserId       = request.User.Id,
                CreationDate = DateTime.UtcNow,
                ExpiryDate   = DateTime.UtcNow.AddMonths(6)
            };

            await _context.RefreshTokens.AddAsync(refreshToken, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            return(new JsonWebTokenResult()
            {
                Token = tokenHandler.WriteToken(token),
                TokenExpirationTime = ((DateTimeOffset)tokenExpiration).ToUnixTimeSeconds().ToString(),
                RefreshToken = refreshToken.Token
            });
        }
        public async Task <int> Handle(LikeLessonCommand request, CancellationToken cancellationToken)
        {
            var likedLesson = await _context.LessonsLikes.FindAsync(request.LessonId, _currentUser.UserId);

            if (likedLesson == null)
            {
                likedLesson = new UserLessonLikesEntity
                {
                    LessonId = request.LessonId,
                    UserId   = _currentUser.UserId
                };

                await _context.LessonsLikes.AddAsync(likedLesson, cancellationToken);
            }
            else
            {
                _context.LessonsLikes.Remove(likedLesson);
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(_context.LessonsLikes.AsNoTracking().Count(x => x.LessonId == request.LessonId));
        }
        public async Task <long> Handle(CreateCourseCommand request, CancellationToken cancellationToken)
        {
            var course = new CourseEntity
            {
                Title  = request.Title,
                Status = CourseStatus.InDeveloping
            };

            course.Authors = new List <AuthorCourseEntity>
            {
                new AuthorCourseEntity
                {
                    CourseId = course.Id,
                    AuthorId = _currentUser.UserId
                }
            };

            await _context.Courses.AddAsync(course, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            return(course.Id);
        }
Exemplo n.º 20
0
        public async Task <int> Handle(LikeCourseCommand request, CancellationToken cancellationToken)
        {
            var likedCourse = await _context.CoursesLikes.FindAsync(request.CourseId, _currentUser.UserId);

            if (likedCourse == null)
            {
                likedCourse = new UserCourseLikesEntity
                {
                    CourseId = request.CourseId,
                    UserId   = _currentUser.UserId
                };

                await _context.CoursesLikes.AddAsync(likedCourse, cancellationToken);
            }
            else
            {
                _context.CoursesLikes.Remove(likedCourse);
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(_context.CoursesLikes.AsNoTracking().Count(x => x.CourseId == request.CourseId));
        }
        public async Task <long> Handle(CreateCommentReplyCommand request, CancellationToken cancellationToken)
        {
            var rootComment = await _context.Comments.AnyAsync(x => x.Id == request.RootCommentId, cancellationToken);

            if (!rootComment)
            {
                throw new NotImplementedException();
            }

            var reply = new CommentEntity
            {
                AuthorId      = _currentUser.UserId,
                LessonId      = request.LessonId,
                Text          = request.Text,
                WrittenAt     = DateTime.Now,
                RootCommentId = request.RootCommentId
            };

            await _context.Comments.AddAsync(reply, cancellationToken);

            await _context.SaveChangesAsync(cancellationToken);

            return(reply.Id);
        }
Exemplo n.º 22
0
        public async Task <LessonWithoutAnswersResponse> Handle(GetLessonWithoutAnswersQuery request, CancellationToken cancellationToken)
        {
            var courseId = (await _context.Lessons
                            .AsNoTracking()
                            .Where(x => x.Id == request.LessonId)
                            .Include(x => x.Module)
                            .FirstOrDefaultAsync(cancellationToken)).Module.CourseId;

            var subscribed =
                await _context.Subscriptions.AnyAsync(
                    x => x.SubscriberId == _currentUser.UserId && x.CourseId == courseId, cancellationToken);

            if (!subscribed)
            {
                throw new NotImplementedException();
            }

            var lesson = await _context.Lessons
                         .AsNoTracking()
                         .Where(x => x.Id == request.LessonId)
                         .Include(x => x.Sections).ThenInclude(z => z.Quiz).ThenInclude(y => y.Questions).ThenInclude(c => c.Answers)
                         .Include(x => x.Sections).ThenInclude(z => z.Quiz).ThenInclude(y => y.Attempts)
                         .Include(x => x.Comments).ThenInclude(z => z.Author)
                         .Include(x => x.Comments).ThenInclude(z => z.UsersLikes)
                         .Include(x => x.Comments).ThenInclude(z => z.Replies).ThenInclude(y => y.Author)
                         .Include(x => x.Comments).ThenInclude(z => z.Replies).ThenInclude(y => y.UsersLikes)
                         .FirstOrDefaultAsync(cancellationToken);

            if (lesson == null)
            {
                throw new NotImplementedException();
            }

            var progress = await _context.Progresses
                           .AsNoTracking()
                           .Where(x => x.LessonId == request.LessonId && x.UserId == _currentUser.UserId)
                           .FirstOrDefaultAsync(cancellationToken);

            if (progress == null)
            {
                throw new NotImplementedException();
            }

            progress.IsVisited = true;
            _context.Progresses.Update(progress);

            var lastVisited = await _context.LastVisitedLessons
                              .AsNoTracking()
                              .Where(x => x.CourseId == courseId && x.UserId == _currentUser.UserId)
                              .FirstOrDefaultAsync(cancellationToken);

            if (lastVisited == null)
            {
                lastVisited = new LastVisitedLessonEntity
                {
                    CourseId = courseId,
                    UserId   = _currentUser.UserId,
                    LessonId = lesson.Id
                };

                await _context.LastVisitedLessons.AddAsync(lastVisited, cancellationToken);
            }
            else
            {
                lastVisited.LessonId = lesson.Id;
                _context.LastVisitedLessons.Update(lastVisited);
            }

            var sections = lesson.Sections.Where(x => x.Type == LessonSectionType.Quiz).ToList();

            foreach (var section in sections)
            {
                section.Quiz.MaxAttempts -= section.Quiz.Attempts.Count;
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(_mapper.Map <LessonEntity, LessonWithoutAnswersResponse>(lesson));
        }
        public async Task <QuizValidationResponse> Handle(ValidateQuizCommand request, CancellationToken cancellationToken)
        {
            var lessonId = (await _context.Quizzes
                            .AsNoTracking()
                            .Where(x => x.Id == request.Id)
                            .Include(x => x.Section)
                            .FirstOrDefaultAsync(cancellationToken)).Section.LessonId;

            var quiz = await _context.Quizzes
                       .AsNoTracking()
                       .Where(x => x.Id == request.Id)
                       .Include(x => x.Questions)
                       .ThenInclude(y => y.Answers)
                       .FirstOrDefaultAsync(cancellationToken);

            if (quiz == null)
            {
                throw new System.NotImplementedException();
            }

            var response = new QuizValidationResponse();

            foreach (var question in quiz.Questions)
            {
                response.MaxAttempts = quiz.MaxAttempts;
                response.Questions ??= new List <QuizValidationResponse.QuestionValidationResponse>();

                var responseAnswers =
                    question.Answers.Select(answer =>
                                            new QuizValidationResponse.AnswerValidationResponse()
                {
                    Id    = answer.Id,
                    Value = answer.Value,
                    Wrong = request.Questions.Any(x
                                                  => x.Answers.Any(y
                                                                   => y.Id == answer.Id && y.IsSelected != answer.IsCorrect)),
                    IsSelected = request.Questions.Any(x
                                                       => x.Answers.Any(y
                                                                        => y.Id == answer.Id && y.IsSelected))
                }).ToList();

                response.Questions.Add(new QuizValidationResponse.QuestionValidationResponse()
                {
                    Id      = question.Id,
                    Type    = question.Type,
                    Value   = question.Value,
                    Score   = question.Score,
                    Answers = new List <QuizValidationResponse.AnswerValidationResponse>(responseAnswers),
                });
            }

            var progress = await _context.Progresses
                           .AsNoTracking()
                           .Where(x => x.LessonId == lessonId && x.UserId == _currentUser.UserId)
                           .FirstOrDefaultAsync(cancellationToken);

            if (response.Questions.All(x => x.Answers.All(y => y.Wrong == false)))
            {
                progress.Score = response.Questions.Sum(x => x.Score);
                _context.Progresses.Update(progress);
            }

            var attempt = await _context.UserQuizAttempts
                          .AsNoTracking()
                          .Where(x => x.UserId == _currentUser.UserId && x.QuizId == quiz.Id && x.ProgressId == progress.Id)
                          .FirstOrDefaultAsync(cancellationToken);

            if (attempt == null)
            {
                attempt = new QuizAttempts
                {
                    AttemptId  = 1,
                    ProgressId = progress.Id,
                    QuizId     = quiz.Id,
                    UserId     = _currentUser.UserId,
                    Result     = JsonConvert.SerializeObject(response) // TODO: JSON STRINGIFY
                };
                response.MaxAttempts--;
                await _context.UserQuizAttempts.AddAsync(attempt, cancellationToken);
            }
            else
            {
                var count = _context.UserQuizAttempts.Count(x =>
                                                            x.UserId == _currentUser.UserId && x.QuizId == quiz.Id && x.ProgressId == progress.Id);

                if (count == quiz.MaxAttempts)
                {
                    throw new NotImplementedException();
                }

                if (count < quiz.MaxAttempts)
                {
                    attempt = new QuizAttempts
                    {
                        AttemptId  = count + 1,
                        ProgressId = progress.Id,
                        QuizId     = quiz.Id,
                        UserId     = _currentUser.UserId,
                        Result     = JsonConvert.SerializeObject(response) // TODO: JSON STRINGIFY
                    };
                    await _context.UserQuizAttempts.AddAsync(attempt, cancellationToken);

                    response.MaxAttempts -= count + 1;
                }
                else
                {
                    response.MaxAttempts = 0;
                }
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(response);
        }
        public async Task AddUser(User User)
        {
            await dc.User.AddAsync(User);

            await dc.SaveChangesAsync();
        }
Exemplo n.º 25
0
        public async Task <LessonResponse> Handle(UpdateLessonCommand request, CancellationToken cancellationToken)
        {
            var lesson = await _context.Lessons
                         .Where(x => x.Id == request.Id)
                         .Include(x => x.Module).ThenInclude(y => y.Course)
                         .Include(x => x.Sections)
                         .ThenInclude(z => z.Quiz)
                         .ThenInclude(y => y.Questions)
                         .ThenInclude(c => c.Answers)
                         .FirstOrDefaultAsync(cancellationToken);

            if (lesson == null)
            {
                throw new NotFoundException(nameof(LessonEntity), request.Id);
            }

            if (lesson.Module.Course.Status == CourseStatus.Published || lesson.Module.Course.Status == CourseStatus.AwaitingPublication)
            {
                throw new CourseStatusException(nameof(CourseEntity), request.Id);
            }

            var updated = _mapper.Map <UpdateLessonCommand, LessonEntity>(request);

            foreach (var section in lesson.Sections)
            {
                if (section.Type == LessonSectionType.Quiz)
                {
                    foreach (var question in section.Quiz.Questions)
                    {
                        foreach (var answer in question.Answers)
                        {
                            if (!request.Sections.Any(x =>
                                                      x.Quiz != null && x.Quiz.Questions.Any(y =>
                                                                                             y.Answers.Any(c =>
                                                                                                           c.Id == answer.Id))))
                            {
                                _context.Answers.Remove(answer);
                            }
                        }

                        if (!request.Sections.Any(x =>
                                                  x.Quiz != null && x.Quiz.Questions.Any(y =>
                                                                                         y.Id == question.Id)))
                        {
                            _context.Questions.Remove(question);
                        }
                    }
                }

                if (request.Sections.All(x => x.Id != section.Id))
                {
                    _context.Sections.Remove(section);
                }
            }

            lesson.Title    = updated.Title;
            lesson.Sections = updated.Sections;
            lesson.MaxScore = lesson.Sections
                              .Where(section => section.Type == LessonSectionType.Quiz)
                              .Sum(section => section.Quiz.Questions.Sum(question => question.Score));

            _context.Lessons.Update(lesson);

            await _context.SaveChangesAsync(cancellationToken);

            return(_mapper.Map <LessonEntity, LessonResponse>(lesson));
        }