Exemple #1
0
        public async Task <ResponseModel <List <CreateSessionModel> > > Handle(CreateSessionCommand request, CancellationToken cancellationToken)
        {
            var redisKey        = $"SessionsByTenantId{request.TenantId}";
            var newSessions     = new List <Session>();
            var createdSessions = new List <CreateSessionModel>();

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    foreach (var createSessionModel in request.CreateSessionModels)
                    {
                        var newSession = new Session
                        {
                            CreatedBy   = request.CreatedBy,
                            GameId      = createSessionModel.GameId,
                            Name        = createSessionModel.Name,
                            ClassroomId = createSessionModel.ClassroomId
                        };
                        newSessions.Add(newSession);
                    }

                    if (newSessions.Count > 20)
                    {
                        _context.BulkInsert(newSessions);
                    }
                    else
                    {
                        await _context.Sessions.AddRangeAsync(newSessions, cancellationToken);

                        await _context.SaveChangesAsync(cancellationToken);
                    }

                    transaction.Commit();
                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.Sessions
                                                              .AsNoTracking()
                                                              .ToListAsync(cancellationToken),
                                                              cancellationToken);

                    newSessions.ForEach(x =>
                                        createdSessions.Add(new CreateSessionModel(x.Id, x.GameId, x.ClassroomId, x.Name, x.CreatedBy, x.CreatedAt)));
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(Session), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            return(new ResponseModel <List <CreateSessionModel> >(createdSessions));
        }
        public async Task <ResponseModel <CreateProfessionModel> > Handle(CreateProfessionCommand request,
                                                                          CancellationToken cancellationToken)
        {
            var newProfessions = new List <Profession>();

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                var redisKey = $"ProfessionsByTenantId{request.TenantId}";
                try
                {
                    var professionsByTenantId = await _context.Professions
                                                .Where(x => x.TenantId == request.TenantId)
                                                .ToListAsync(cancellationToken);

                    foreach (var requestProfession in request.Professions)
                    {
                        var profession = new Profession
                        {
                            CreatedBy = request.AdminUserId,
                            Name      = requestProfession,
                            TenantId  = request.TenantId
                        };
                        newProfessions.Add(profession);
                    }

                    await _context.Professions.AddRangeAsync(newProfessions, cancellationToken);

                    await _context.SaveChangesAsync(cancellationToken);

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => professionsByTenantId,
                                                              cancellationToken);

                    transaction.Commit();
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(Profession), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var professions = new CreateProfessionModel(newProfessions);

            return(new ResponseModel <CreateProfessionModel>(professions));
        }
Exemple #3
0
        public async Task <ResponseModel <UpdateWorkingStatusModel> > Handle(UpdateWorkingStatusCommand request, CancellationToken cancellationToken)
        {
            var redisKey  = $"WorkingStatusByTenantId{request.TenantId}";
            var updatedAt = DateTimeOffset.Now;

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var workingStatuses = await _context.WorkingStatuses
                                          .Where(x => x.TenantId == request.TenantId)
                                          .ToListAsync(cancellationToken);

                    var currentWorkingStatus = workingStatuses.FirstOrDefault(x => x.Id == request.Id);

                    if (currentWorkingStatus is null)
                    {
                        throw new NotFoundException(nameof(WorkingStatus), request.Id);
                    }

                    currentWorkingStatus.Name      = request.Name;
                    currentWorkingStatus.UpdatedBy = request.UpdatedBy;
                    currentWorkingStatus.UpdatedAt = updatedAt;

                    _context.Update(currentWorkingStatus);
                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => workingStatuses
                                                              , cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(WorkingStatus), request.Name);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var workingStatusModel = new UpdateWorkingStatusModel(request.Id,
                                                                  request.Name,
                                                                  request.UpdatedBy,
                                                                  updatedAt);

            return(new ResponseModel <UpdateWorkingStatusModel>(workingStatusModel));
        }
        public async Task <AdminUserAuthenticateModel> Handle(AuthenticateAdminUserCommand request, CancellationToken cancellationToken)
        {
            var adminUser = await _context.AdminUsers
                            .SingleOrDefaultAsync(u =>
                                                  u.Email.Equals(request.Email, StringComparison.InvariantCultureIgnoreCase),
                                                  cancellationToken);

            if (adminUser is null)
            {
                throw new NotFoundException(nameof(request.Email), request.Email);
            }

            var salt              = adminUser.PasswordSalt;
            var passwordHash      = request.Password?.GetSHA512(salt);
            var today             = DateTimeOffset.Now;
            var isPasswordExpired = today.Subtract(adminUser.LastPasswordChangeDateTime).Days > 90;

            if (!passwordHash.SequenceEqual(adminUser.Password))
            {
                adminUser.NumberOfInvalidPasswordAttemps = Math.Min(adminUser.NumberOfInvalidPasswordAttemps + 1, int.MaxValue);
                try
                {
                    await _context.SaveChangesAsync(cancellationToken);
                }
                catch (DbUpdateConcurrencyException)
                {
                    //TODO https://docs.microsoft.com/en-us/ef/core/saving/concurrency
                }
                catch (Exception)
                {
                    //TODO
                    throw;
                }
                //TODO:  Auth exception
                throw new Exception();
            }

            Guid tenantId;

            try
            {
                tenantId = _context.TenantAdminUsers
                           .Include(x => x.Tenant)
                           .First(x => x.AdminUserId == adminUser.Id && x.Tenant.HostName == request.HostName).TenantId;
            }
            catch (Exception)
            {
                throw new UnauthorizedAccessException();
            }


            return(new AdminUserAuthenticateModel(id: adminUser.Id,
                                                  email: adminUser.Email,
                                                  name: adminUser.Name,
                                                  isPasswordExpired: isPasswordExpired,
                                                  tenantId: tenantId,
                                                  hostName: request.HostName));
        }
Exemple #5
0
        public async Task <ResponseModel <UpdateTenantModel> > Handle(UpdateTenantCommand request, CancellationToken cancellationToken)
        {
            var updatedAt = DateTimeOffset.Now;

            using (IDbContextTransaction transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var tenant = await _context.Tenants.SingleOrDefaultAsync(x =>
                                                                             x.Id == request.Id &&
                                                                             x.TenantAdminUsers.Any(y =>
                                                                                                    y.AdminUserId == request.UpdatedBy),
                                                                             cancellationToken);

                    if (tenant is null)
                    {
                        throw new NotFoundException(nameof(Tenant), request.HostName);
                    }

                    tenant.Name        = request.Name;
                    tenant.HostName    = request.HostName;
                    tenant.Description = request.Description;
                    tenant.Logo        = request.Logo;
                    tenant.UpdatedBy   = request.UpdatedBy;
                    tenant.UpdatedAt   = updatedAt;

                    _context.Tenants.Update(tenant);
                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Tenant), request.HostName);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var model = new UpdateTenantModel(id: request.Id,
                                              updatedAt: updatedAt,
                                              name: request.Name,
                                              description: request.Description,
                                              hostName: request.HostName,
                                              logo: request.Logo);

            return(new ResponseModel <UpdateTenantModel>(model));
        }
        public async Task <ResponseModel <CreateTenantModel> > Handle(CreateTenantCommand request, CancellationToken cancellationToken)
        {
            var newTenant = new Tenant
            {
                Name        = request.Name,
                Description = request.Description,
                HostName    = request.HostName,
                Logo        = request.Logo,
                CreatedBy   = request.CreatedBy
            };

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    await _context.Tenants.AddAsync(newTenant, cancellationToken);

                    await _context.TenantAdminUsers.AddAsync(new TenantAdminUser
                    {
                        TenantId    = newTenant.Id,
                        AdminUserId = request.CreatedBy,
                        CreatedBy   = request.CreatedBy
                    }, cancellationToken);

                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Tenant), request.HostName);
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var createTenantModel = new CreateTenantModel(id: newTenant.Id,
                                                          createdAt: newTenant.CreatedAt,
                                                          name: newTenant.Name,
                                                          description: newTenant.Description,
                                                          hostName: newTenant.HostName,
                                                          logo: newTenant.Logo);

            return(new ResponseModel <CreateTenantModel>(createTenantModel));
        }
Exemple #7
0
        public async Task <ResponseModel <CreateWorkingStatusModel> > Handle(CreateWorkingStatusCommand request, CancellationToken cancellationToken)
        {
            var redisKey      = $"WorkingStatusesByTenantId{request.TenantId}";
            var workingStatus = new WorkingStatus
            {
                Name      = request.Name,
                CreatedBy = request.CreatedBy,
                TenantId  = request.TenantId
            };

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    await _context.WorkingStatuses.AddAsync(workingStatus, cancellationToken);

                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.WorkingStatuses
                                                              .Where(x => x.TenantId == request.TenantId)
                                                              .ToList()
                                                              , cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(WorkingStatus), request.Name);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }
            var workingStatusModel = new CreateWorkingStatusModel(workingStatus.Id,
                                                                  workingStatus.Name,
                                                                  workingStatus.CreatedBy,
                                                                  workingStatus.CreatedAt);

            return(new ResponseModel <CreateWorkingStatusModel>(workingStatusModel));
        }
        public async Task <ResponseModel <RegisterAdminUserModel> > Handle(RegisterAdminUserCommand request, CancellationToken cancellationToken)
        {
            var salt = ByteArrayExtensions.GetRandomSalt();
            var item = new AdminUser
            {
                Email                      = request.Email,
                Name                       = request.Name,
                Surname                    = request.Surname,
                TimeZone                   = request.TimeZone,
                CreatedDateTime            = DateTimeOffset.Now,
                LastPasswordChangeDateTime = DateTimeOffset.Now,
                PasswordSalt               = salt,
                Password                   = request.Password.GetSHA512(salt),
            };

            using (IDbContextTransaction transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    _context.Add(item);
                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(AdminUser), nameof(AdminUser.Email));
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var model = new RegisterAdminUserModel(id: item.Id,
                                                   email: item.Email,
                                                   username: item.UserName,
                                                   name: item.Name,
                                                   surname: item.Surname,
                                                   phoneNumber: item.PhoneNumber,
                                                   timeZone: item.TimeZone,
                                                   createDateTime: item.CreatedDateTime);

            return(new ResponseModel <RegisterAdminUserModel>(model));
        }
Exemple #9
0
        public async Task <ResponseModel <UpdateAdminUserModel> > Handle(UpdateAdminUserCommand request, CancellationToken cancellationToken)
        {
            var item = await _context.AdminUsers.SingleOrDefaultAsync(au => au.Id == request.Id, cancellationToken);

            using (IDbContextTransaction transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    _context.Add(item);
                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(AdminUser), nameof(AdminUser.Email));
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var model = new UpdateAdminUserModel(id: item.Id,
                                                 email: item.Email,
                                                 username: item.UserName,
                                                 name: item.Name,
                                                 surname: item.Surname,
                                                 phoneNumber: item.PhoneNumber,
                                                 timeZone: item.TimeZone,
                                                 createDateTime: item.CreatedDateTime);

            return(new ResponseModel <UpdateAdminUserModel>(model));
        }
        public async Task <ResponseModel <List <CreateOptionModel> > > Handle(CreateOptionCommand request, CancellationToken cancellationToken)
        {
            var redisKey       = $"OptionsWithQuestionByTenantId{request.TenantId}";
            var newOptions     = new List <Option>();
            var createdOptions = new List <CreateOptionModel>();

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var currentQuestions = _context.Questions.Where(x => x.TenantId == request.TenantId);

                    foreach (var createOptionModel in request.CreateOptionModels)
                    {
                        var questionIsExist = await currentQuestions
                                              .AnyAsync(x =>
                                                        x.Id == createOptionModel.QuestionId,
                                                        cancellationToken);

                        if (!questionIsExist)
                        {
                            throw new NotFoundException(nameof(Question), createOptionModel.QuestionId);
                        }
                        var newOption = new Option
                        {
                            CreatedBy       = request.CreatedBy,
                            VisibilityOrder = createOptionModel.VisibilityOrder,
                            QuestionId      = createOptionModel.QuestionId,
                            Text            = createOptionModel.Text,
                            IsCorrect       = createOptionModel.IsCorrect
                        };
                        newOptions.Add(newOption);
                    }

                    if (newOptions.Count > 20)
                    {
                        _context.BulkInsert(newOptions);
                    }
                    else
                    {
                        await _context.Options.AddRangeAsync(newOptions, cancellationToken);

                        await _context.SaveChangesAsync(cancellationToken);
                    }

                    transaction.Commit();
                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.Options
                                                              .AsNoTracking()
                                                              .Include(x => x.Question)
                                                              .ToListAsync(cancellationToken),
                                                              cancellationToken);

                    newOptions.ForEach(x => createdOptions.Add(new CreateOptionModel(x.Id,
                                                                                     x.Text,
                                                                                     x.VisibilityOrder,
                                                                                     x.QuestionId,
                                                                                     x.CreatedBy,
                                                                                     x.CreatedAt,
                                                                                     x.IsCorrect)));
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(Option), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            return(new ResponseModel <List <CreateOptionModel> >(createdOptions));
        }
        public async Task <ResponseModel <CreateQuestionModel> > Handle(CreateQuestionCommand request, CancellationToken cancellationToken)
        {
            var redisKey = $"QuestionsByTenantId{request.TenantId}";

            var newQuestion = new Question
            {
                TenantId             = request.TenantId,
                CreatedBy            = request.CreatedBy,
                Text                 = request.Text,
                Duration             = request.Duration,
                QuestionCategoryId   = request.CategoryId,
                QuestionDifficultyId = request.DifficultyId,
                QuestionTypeId       = request.TypeId,
                ContentFileId        = request.ContentFileId
            };

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    if (request.TagsIdList != null)
                    {
                        foreach (var tagId in request.TagsIdList)
                        {
                            var questionTag = new QuestionTag
                            {
                                QuestionId = newQuestion.Id,
                                TagId      = tagId
                            };
                            newQuestion.QuestionTags.Add(questionTag);
                        }
                    }
                    await _context.Questions.AddAsync(newQuestion, cancellationToken);

                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.Questions
                                                              .AsNoTracking()
                                                              .Where(x => x.TenantId == request.TenantId)
                                                              .Include(x => x.QuestionTags)
                                                              .ThenInclude(y => y.Tag)
                                                              .ToList()
                                                              , cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Question), request.Text);
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var createQuestionModel = new CreateQuestionModel(newQuestion.Id,
                                                              newQuestion.Text,
                                                              newQuestion.Duration,
                                                              newQuestion.QuestionDifficultyId,
                                                              newQuestion.QuestionCategoryId,
                                                              newQuestion.QuestionTypeId,
                                                              newQuestion.ContentFileId,
                                                              newQuestion.CreatedBy,
                                                              newQuestion.CreatedAt);

            return(new ResponseModel <CreateQuestionModel>(createQuestionModel));
        }
Exemple #12
0
        public async Task <ResponseModel <UpdateQuestionModel> > Handle(UpdateQuestionCommand request, CancellationToken cancellationToken)
        {
            var redisKey  = $"QuestionsByTenantId{request.TenantId}";
            var updatedAt = DateTimeOffset.Now;

            var questionListByTenantId = _context.Questions
                                         .Where(x => x.TenantId == request.TenantId)
                                         .Include(x => x.QuestionTags)
                                         .ThenInclude(y => y.Tag);

            var updateQuestion = questionListByTenantId.FirstOrDefault(x => x.Id == request.Id);

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    if (updateQuestion == null)
                    {
                        throw new NotFoundException(nameof(Question), request.Id);
                    }

                    updateQuestion.Duration             = request.Duration;
                    updateQuestion.Text                 = request.Text;
                    updateQuestion.QuestionCategoryId   = request.CategoryId;
                    updateQuestion.QuestionDifficultyId = request.DifficultyId;
                    updateQuestion.QuestionTypeId       = request.TypeId;
                    updateQuestion.ContentFileId        = request.ContentFileId;
                    updateQuestion.UpdatedAt            = updatedAt;
                    updateQuestion.UpdatedBy            = request.UpdatedBy;


                    if (request.TagsIdList != null)
                    {
                        _context.QuestionTags.RemoveRange(updateQuestion.QuestionTags);
                        foreach (var TagId in request.TagsIdList)
                        {
                            updateQuestion.QuestionTags.Add(new QuestionTag
                            {
                                QuestionId = updateQuestion.Id,
                                TagId      = TagId
                            });
                        }
                    }


                    _context.Questions.Update(updateQuestion);
                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => questionListByTenantId.ToList()
                                                              , cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Question), request.Text);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var updateQuestionModel = new UpdateQuestionModel(updateQuestion.Id,
                                                              updateQuestion.Text,
                                                              updateQuestion.Duration,
                                                              updateQuestion.QuestionDifficultyId,
                                                              updateQuestion.QuestionCategoryId,
                                                              updateQuestion.QuestionTypeId,
                                                              updateQuestion.QuestionTags.Select(x => TagDetailModel.Create(x.Tag)).ToList(),
                                                              updateQuestion.ContentFileId,
                                                              request.UpdatedBy,
                                                              updatedAt);

            return(new ResponseModel <UpdateQuestionModel>(updateQuestionModel));
        }
        public async Task <ResponseModel <List <CreateClassroomModel> > > Handle(CreateClassroomCommand request, CancellationToken cancellationToken)
        {
            var redisKey                 = $"ClassroomsByTenantId{request.TenantId}";
            var newClassrooms            = new List <Classroom>();
            var newClassroomTraineeUsers = new List <ClassroomTraineeUser>();
            var createdClassrooms        = new List <CreateClassroomModel>();
            var random = new Random();

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    foreach (var createClassroomModel in request.CreateClassroomModels)
                    {
                        foreach (var traineeUserId in createClassroomModel.TraineeUsersIdList)
                        {
                            var isExist = await _context.TraineeUsers
                                          .Include(x => x.Department)
                                          .AnyAsync(x => x.Id == traineeUserId &&
                                                    x.Department.TenantId == request.TenantId, cancellationToken);

                            if (!isExist)
                            {
                                throw new NotFoundException(nameof(TraineeUser), traineeUserId);
                            }
                        }
                        var newClassroom = new Classroom
                        {
                            CreatedBy     = request.CreatedBy,
                            TrainerUserId = createClassroomModel.TrainerUserId,
                            Name          = createClassroomModel.Name,
                            TrainingId    = createClassroomModel.TrainingId,
                            BeginDatetime = createClassroomModel.BeginDatetime,
                            EndDatetime   = createClassroomModel.EndDatetime,
                            Location      = createClassroomModel.Location,
                            Code          = random.Next(0, 100000).ToString()
                        };

                        newClassrooms.Add(newClassroom);
                    }

                    if (newClassrooms.Count > 20)
                    {
                        await _context.BulkInsertAsync(newClassrooms, cancellationToken : cancellationToken);


                        foreach (var newClassroom in newClassrooms)
                        {
                            foreach (var createClassroomModel in request.CreateClassroomModels)
                            {
                                foreach (var i in createClassroomModel.TraineeUsersIdList)
                                {
                                    newClassroomTraineeUsers.Add(new ClassroomTraineeUser
                                    {
                                        ClassroomId   = newClassroom.Id,
                                        TraineeUserId = i
                                    });
                                }
                            }
                        }

                        await _context.BulkInsertAsync(newClassroomTraineeUsers, cancellationToken : cancellationToken);
                    }
                    else
                    {
                        for (int i = 0; i < newClassrooms.Count; i++)
                        {
                            await _context.Classrooms.AddAsync(newClassrooms[i], cancellationToken);

                            foreach (var traineeUserId in request.CreateClassroomModels[i].TraineeUsersIdList)
                            {
                                newClassrooms[i].ClassroomTraineeUsers.Add(new ClassroomTraineeUser
                                {
                                    TraineeUserId = traineeUserId
                                });
                            }
                        }

                        await _context.SaveChangesAsync(cancellationToken);
                    }

                    transaction.Commit();
                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.Classrooms
                                                              .AsNoTracking()
                                                              .ToListAsync(cancellationToken),
                                                              cancellationToken);

                    newClassrooms.ForEach(x =>
                                          createdClassrooms.Add(new CreateClassroomModel(x.Id,
                                                                                         x.TrainerUserId,
                                                                                         x.TrainingId,
                                                                                         x.Name,
                                                                                         x.ClassroomTraineeUsers
                                                                                         .Select(s => s.TraineeUserId)
                                                                                         .ToList(),
                                                                                         x.BeginDatetime,
                                                                                         x.EndDatetime,
                                                                                         x.Location,
                                                                                         x.CreatedBy,
                                                                                         x.CreatedAt,
                                                                                         x.Code)));
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(Department), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            return(new ResponseModel <List <CreateClassroomModel> >(createdClassrooms));
        }
Exemple #14
0
        public async Task <ResponseModel <UpdateOptionModel> > Handle(UpdateOptionCommand request, CancellationToken cancellationToken)
        {
            var redisKey  = $"OptionsWithQuestionByTenantId{request.TenantId}";
            var updatedAt = DateTimeOffset.Now;

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var optionsByTenantId = await _context.Options
                                            .Include(x => x.Question)
                                            .Where(x => x.Question.TenantId == request.TenantId)
                                            .ToListAsync(cancellationToken);


                    var updateOption = optionsByTenantId.FirstOrDefault(x => x.Id == request.Id);
                    if (updateOption is null)
                    {
                        throw new NotFoundException(nameof(Option), request.Id);
                    }

                    updateOption.VisibilityOrder = request.VisibilityOrder;
                    updateOption.Text            = request.Text;
                    updateOption.UpdatedAt       = updatedAt;
                    updateOption.UpdatedBy       = request.UpdatedBy;
                    updateOption.IsCorrect       = request.IsCorrect;

                    _context.Options.Update(updateOption);
                    await _context.SaveChangesAsync(cancellationToken);

                    optionsByTenantId = optionsByTenantId.Select(x => new Option
                    {
                        Id              = x.Id,
                        CreatedBy       = x.CreatedBy,
                        UpdatedBy       = x.UpdatedBy,
                        VisibilityOrder = x.VisibilityOrder,
                        Text            = x.Text,
                        UpdatedAt       = x.UpdatedAt,
                        IsCorrect       = x.IsCorrect
                    }).ToList();

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => optionsByTenantId,
                                                              cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Option), request.Id);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }
            var updateOptionModel = new UpdateOptionModel(request.Id,
                                                          request.Text,
                                                          request.VisibilityOrder,
                                                          request.QuestionId,
                                                          request.UpdatedBy,
                                                          request.IsCorrect,
                                                          updatedAt);

            return(new ResponseModel <UpdateOptionModel>(updateOptionModel));
        }
Exemple #15
0
        public async Task <ResponseModel <UpdateTrainingModel> > Handle(UpdateTrainingCommand request, CancellationToken cancellationToken)
        {
            var redisKey  = $"TrainingsByTenantId{request.TenantId}";
            var updatedAt = DateTimeOffset.Now;

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var trainingsByTenantId = await _context.Trainings
                                              .Include(x => x.TrainingSeries)
                                              .Where(x => x.TrainingSeries.TenantId == request.TenantId)
                                              .ToListAsync(cancellationToken);


                    var updateTraining = trainingsByTenantId.FirstOrDefault(x => x.Id == request.Id);
                    if (updateTraining is null)
                    {
                        throw new NotFoundException(nameof(Training), request.Id);
                    }

                    updateTraining.Name               = request.Name;
                    updateTraining.BeginDateTime      = request.BeginDateTime;
                    updateTraining.EndDateTime        = request.EndDateTime;
                    updateTraining.Description        = request.Description;
                    updateTraining.TrainingSeriesId   = request.TrainingSeriesId;
                    updateTraining.TrainingCategoryId = request.TrainingCategoryId;
                    updateTraining.UpdatedAt          = updatedAt;
                    updateTraining.UpdatedBy          = request.UpdatedBy;

                    _context.Trainings.Update(updateTraining);
                    await _context.SaveChangesAsync(cancellationToken);

                    trainingsByTenantId = trainingsByTenantId.Select(x => new Training
                    {
                        Id                 = x.Id,
                        CreatedBy          = x.CreatedBy,
                        UpdatedBy          = x.UpdatedBy,
                        Name               = x.Name,
                        UpdatedAt          = x.UpdatedAt,
                        TrainingCategoryId = x.TrainingCategoryId,
                        BeginDateTime      = x.BeginDateTime,
                        EndDateTime        = x.EndDateTime,
                    }).ToList();

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => trainingsByTenantId,
                                                              cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Training), request.Id);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }
            var updateTrainingModel = new UpdateTrainingModel(request.Id,
                                                              request.TrainingSeriesId,
                                                              request.TrainingCategoryId,
                                                              request.Name,
                                                              request.Description,
                                                              request.UpdatedBy,
                                                              updatedAt,
                                                              request.BeginDateTime,
                                                              request.EndDateTime);

            return(new ResponseModel <UpdateTrainingModel>(updateTrainingModel));
        }
Exemple #16
0
        public async Task <ResponseModel <UpdateContentFileModel> > Handle(UpdateContentFileCommand request, CancellationToken cancellationToken)
        {
            var redisKey  = $"ContentFilesByTenantId{request.TenantId}";
            var updatedAt = DateTimeOffset.Now;

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var contentFilesByTenantId = await _context.ContentFiles
                                                 .Where(x => x.TenantId == request.TenantId)
                                                 .ToListAsync(cancellationToken);

                    var updateContentFile = contentFilesByTenantId.FirstOrDefault(x => x.Id == request.Id);
                    if (updateContentFile is null)
                    {
                        throw new NotFoundException(nameof(ContentFile), request.Id);
                    }

                    updateContentFile.Name        = request.Name;
                    updateContentFile.ContentType = request.ContentType;
                    updateContentFile.UpdatedAt   = updatedAt;
                    updateContentFile.UpdatedBy   = request.UpdatedBy;
                    updateContentFile.Data        = request.Data;

                    _context.ContentFiles.Update(updateContentFile);
                    await _context.SaveChangesAsync(cancellationToken);

                    contentFilesByTenantId = contentFilesByTenantId.Select(x => new ContentFile
                    {
                        Id          = x.Id,
                        CreatedBy   = x.CreatedBy,
                        UpdatedBy   = x.UpdatedBy,
                        Name        = x.Name,
                        ContentType = x.ContentType,
                        UpdatedAt   = x.UpdatedAt,
                        Data        = x.Data
                    }).ToList();

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => contentFilesByTenantId,
                                                              cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(ContentFile), request.Id);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }
            var updateContentFileModel = new UpdateContentFileModel(request.Id,
                                                                    request.Name,
                                                                    request.ContentType,
                                                                    request.Data,
                                                                    request.UpdatedBy,
                                                                    updatedAt);

            return(new ResponseModel <UpdateContentFileModel>(updateContentFileModel));
        }
Exemple #17
0
        public async Task <ResponseModel <CreateTraineeUserModel> > Handle(CreateTraineeUserCommand request, CancellationToken cancellationToken)
        {
            var redisKey    = $"TraineeUsersWithDepartmentsByTenantId{request.TenantId}";
            var salt        = ByteArrayExtensions.GetRandomSalt();
            var traineeUser = new TraineeUser
            {
                Name                       = request.Name,
                DepartmentId               = request.DepartmentId,
                Gender                     = request.Gender,
                NationalIdentityNumber     = request.NationalIdentityNumber,
                PhoneNumber                = request.PhoneNumber,
                Surname                    = request.Surname,
                WorkingStatusId            = request.WorkingStatusId,
                CreatedBy                  = request.CreatedBy,
                Email                      = request.Email,
                LastPasswordChangeDateTime = DateTimeOffset.Now,
                PasswordSalt               = salt,
                Password                   = request.Password.GetSHA512(salt),
                AvatarId                   = request.AvatarId
            };

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var isExistAnyDepartment = await _context.Departments.AnyAsync(x =>
                                                                                   x.TenantId == request.TenantId &&
                                                                                   x.Id == request.DepartmentId,
                                                                                   cancellationToken);

                    if (!isExistAnyDepartment)
                    {
                        throw new NotFoundException(nameof(Department), request.DepartmentId);
                    }

                    await _context.TraineeUsers.AddAsync(traineeUser, cancellationToken);

                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.TraineeUsers
                                                              .Include(x => x.Department)
                                                              .Where(x => x.Department.TenantId == request.TenantId)
                                                              .ToList()
                                                              , cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(TraineeUser), request.Name);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var traineeUserModel = new CreateTraineeUserModel(traineeUser.Id,
                                                              traineeUser.CreatedAt,
                                                              traineeUser.Name,
                                                              traineeUser.Email,
                                                              traineeUser.Surname,
                                                              traineeUser.NationalIdentityNumber,
                                                              traineeUser.PhoneNumber,
                                                              traineeUser.Gender,
                                                              traineeUser.AvatarId);

            return(new ResponseModel <CreateTraineeUserModel>(traineeUserModel));
        }
Exemple #18
0
        public async Task <ResponseModel <UpdateClassroomModel> > Handle(UpdateClassroomCommand request, CancellationToken cancellationToken)
        {
            var redisKey  = $"ClassroomsByTenantId{request.TenantId}";
            var updatedAt = DateTimeOffset.Now;

            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var classroomsByTenantId = await _context.Classrooms
                                               .Include(x => x.Training)
                                               .Include(x => x.Training.TrainingSeries)
                                               .Where(x => x.Training.TrainingSeries.TenantId == request.TenantId)
                                               .Include(x => x.ClassroomTraineeUsers)
                                               .ToListAsync(cancellationToken);

                    var updateClassroom = classroomsByTenantId.FirstOrDefault(x => x.Id == request.Id);

                    if (updateClassroom is null)
                    {
                        throw new NotFoundException(nameof(Classroom), request.Id);
                    }

                    updateClassroom.Name          = request.Name;
                    updateClassroom.UpdatedAt     = updatedAt;
                    updateClassroom.UpdatedBy     = request.UpdatedBy;
                    updateClassroom.BeginDatetime = request.BeginDatetime;
                    updateClassroom.EndDatetime   = request.EndDatetime;
                    updateClassroom.Location      = request.Location;

                    if (request.TraineeUsersIdList != null)
                    {
                        _context.ClassroomTraineeUsers.RemoveRange(updateClassroom.ClassroomTraineeUsers);
                        foreach (var TraineeUserId in request.TraineeUsersIdList)
                        {
                            updateClassroom.ClassroomTraineeUsers.Add(new ClassroomTraineeUser
                            {
                                ClassroomId   = updateClassroom.Id,
                                TraineeUserId = TraineeUserId
                            });
                        }
                    }

                    _context.Classrooms.Update(updateClassroom);
                    await _context.SaveChangesAsync(cancellationToken);

                    classroomsByTenantId = classroomsByTenantId.Select(x => new Classroom
                    {
                        Id            = x.Id,
                        CreatedBy     = x.CreatedBy,
                        UpdatedBy     = x.UpdatedBy,
                        Name          = x.Name,
                        UpdatedAt     = x.UpdatedAt,
                        TrainingId    = x.TrainingId,
                        TrainerUserId = x.TrainerUserId,
                        BeginDatetime = x.BeginDatetime,
                        EndDatetime   = x.EndDatetime,
                        Location      = x.Location,
                        Code          = x.Code
                    }).ToList();

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => classroomsByTenantId,
                                                              cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException &&
                                                   (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException &&
                                                   sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(Classroom), request.Id);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var updateClassroomModel = new UpdateClassroomModel(request.Id,
                                                                request.TrainerUserId,
                                                                request.TrainingId,
                                                                request.Name,
                                                                request.UpdatedBy,
                                                                updatedAt,
                                                                request.TraineeUsersIdList,
                                                                request.BeginDatetime,
                                                                request.EndDatetime,
                                                                request.Location);

            return(new ResponseModel <UpdateClassroomModel>(updateClassroomModel));
        }
Exemple #19
0
        public async Task <ResponseModel <UpdateTraineeUserModel> > Handle(UpdateTraineeUserCommand request, CancellationToken cancellationToken)
        {
            var redisKey = $"TraineeUsersWithDepartmentsByTenantId{request.TenantId}";
            var salt     = ByteArrayExtensions.GetRandomSalt();
            var updateAt = DateTimeOffset.Now;

            using (IDbContextTransaction transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    var traineeUsers = await _context.TraineeUsers
                                       .Include(x => x.Department)
                                       .Where(x => x.Department.TenantId == request.TenantId)
                                       .ToListAsync(cancellationToken);

                    var traineeUser = traineeUsers.FirstOrDefault(x => x.Id == request.Id);

                    if (traineeUser is null)
                    {
                        throw new NotFoundException(nameof(TraineeUser), request.Id);
                    }

                    traineeUser.Name                       = request.Name;
                    traineeUser.DepartmentId               = request.DepartmentId;
                    traineeUser.AvatarId                   = request.AvatarId;
                    traineeUser.Gender                     = request.Gender;
                    traineeUser.NationalIdentityNumber     = request.NationalIdentityNumber;
                    traineeUser.PhoneNumber                = request.PhoneNumber;
                    traineeUser.Surname                    = request.Surname;
                    traineeUser.WorkingStatusId            = request.WorkingStatusId;
                    traineeUser.UpdatedBy                  = request.UpdatedBy;
                    traineeUser.UpdatedAt                  = updateAt;
                    traineeUser.PasswordSalt               = salt;
                    traineeUser.Password                   = request.Password.GetSHA512(salt);
                    traineeUser.Email                      = request.Email;
                    traineeUser.LastPasswordChangeDateTime = updateAt;

                    _context.Update(traineeUser);
                    await _context.SaveChangesAsync(cancellationToken);

                    transaction.Commit();

                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => traineeUsers
                                                              , cancellationToken);
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();
                    throw new ObjectAlreadyExistsException(nameof(TraineeUser), request.Name);
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            var traineeUserModel = new UpdateTraineeUserModel(request.Id,
                                                              request.Name,
                                                              request.Email,
                                                              request.Surname,
                                                              request.NationalIdentityNumber,
                                                              request.PhoneNumber,
                                                              request.Gender,
                                                              request.AvatarId,
                                                              updateAt);

            return(new ResponseModel <UpdateTraineeUserModel>(traineeUserModel));
        }
Exemple #20
0
        public async Task <ResponseModel <List <UpdateTraineeGroupModel> > > Handle(UpdateTraineeGroupCommand request, CancellationToken cancellationToken)
        {
            var redisKey             = $"TraineeGroupsByTenantId{request.TenantId}";
            var updateTraineeGroups  = new List <TraineeGroup>();
            var updatedTraineeGroups = new List <UpdateTraineeGroupModel>();

            var redisTraineeGroups = await _cacheService.RedisCacheAsync(redisKey,
                                                                         _ => _context.TraineeGroups
                                                                         .AsNoTracking()
                                                                         .Where(x => x.TenantId == request.TenantId)
                                                                         .ToList()
                                                                         , cancellationToken);


            using (var transaction = await _context.Database.BeginTransactionAsync(cancellationToken))
            {
                try
                {
                    foreach (var updateTraineeGroupModel in request.UpdateTraineeGroupCommandModels)
                    {
                        var traineeGroup = redisTraineeGroups.FirstOrDefault(x => x.Id == updateTraineeGroupModel.Id);
                        if (traineeGroup != null)
                        {
                            throw new TransactionException();
                        }

                        var updateTraineeGroup = new TraineeGroup
                        {
                            TenantId  = request.TenantId,
                            UpdatedBy = request.UpdatedBy,
                            Name      = updateTraineeGroupModel.Name
                        };
                        updateTraineeGroups.Add(updateTraineeGroup);
                    }

                    if (updateTraineeGroups.Count > 20)
                    {
                        _context.BulkUpdate(updateTraineeGroups);
                    }
                    else
                    {
                        await _context.TraineeGroups.AddRangeAsync(updateTraineeGroups, cancellationToken);

                        await _context.SaveChangesAsync(cancellationToken);
                    }

                    transaction.Commit();
                    await _cacheService.RedisCacheUpdateAsync(redisKey,
                                                              _ => _context.TraineeGroups
                                                              .AsNoTracking()
                                                              .ToListAsync(cancellationToken),
                                                              cancellationToken);

                    updateTraineeGroups.ForEach(x => updatedTraineeGroups.Add(new UpdateTraineeGroupModel(x.Id,
                                                                                                          x.Name,
                                                                                                          x.UpdatedBy,
                                                                                                          x.UpdatedAt
                                                                                                          )));
                }
                catch (DbUpdateException ex) when((ex.InnerException is SqlException sqlException && (sqlException.Number == 2627 || sqlException.Number == 2601)) ||
                                                  (ex.InnerException is SqliteException sqliteException && sqliteException.SqliteErrorCode == 19))
                {
                    transaction.Rollback();

                    throw new ObjectAlreadyExistsException(nameof(TraineeGroup), ExceptionExtensions.GetExceptionMessage(ex));
                }
                catch (NotFoundException)
                {
                    transaction.Rollback();
                    throw;
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw new TransactionException();
                }
            }

            return(new ResponseModel <List <UpdateTraineeGroupModel> >(updatedTraineeGroups));
        }