/// <summary>
        /// Метод создает новое задание.
        /// </summary>
        /// <param name="task">Объект с данными задания.</param>
        /// <param name="userName">Login юзера.</param>
        /// <returns>Вернет данные созданного задания.</returns>
        public async Task <TaskEntity> CreateTask(TaskEntity oTask, string userName)
        {
            try
            {
                if (string.IsNullOrEmpty(oTask.TaskTitle) || string.IsNullOrEmpty(oTask.TaskDetail))
                {
                    throw new ArgumentException();
                }

                // Проверяет существование заказчика, который создает задание.
                bool bCustomer = await IdentityCustomer(userName);

                // Проверяет, есть ли такая категория в БД.
                bool bCategory = await IdentityCategory(oTask.CategoryCode);

                // Если все проверки прошли.
                if (bCustomer && bCategory)
                {
                    oTask.TaskBegda = DateTime.Now;

                    // Запишет код статуса "В аукционе".
                    oTask.StatusCode = await _postgre.TaskStatuses
                                       .Where(s => s.StatusName
                                              .Equals(StatusTask.AUCTION))
                                       .Select(s => s.StatusCode).FirstOrDefaultAsync();

                    // TODO: Доработать передачу с фронта для про или для всех.
                    oTask.TypeCode = "Для всех";

                    await _postgre.Tasks.AddAsync(oTask);

                    await _postgre.SaveChangesAsync();

                    return(oTask);
                }

                throw new ArgumentNullException();
            }

            catch (ArgumentNullException ex)
            {
                throw new ArgumentNullException($"Не все проверки пройдены {ex.Message}");
            }

            catch (ArgumentException ex)
            {
                throw new ArgumentException($"Не все обязательные поля заполнены {ex.Message}");
            }

            catch (Exception ex)
            {
                throw new Exception(ex.Message.ToString());
            }
        }
        /// <summary>
        /// Метод добавляет специализации исполнителя.
        /// </summary>
        /// <param name="specializations">Массив специализаций.</param>
        public async Task AddExecutorSpecializations(ExecutorSpecialization[] specializations, string executorName)
        {
            try
            {
                if (specializations.Length == 0)
                {
                    throw new ArgumentNullException();
                }

                UserEntity oExecutor = await _postgre.Users
                                       .Where(e => e.UserName
                                              .Equals(executorName))
                                       .FirstOrDefaultAsync();

                oExecutor.Specializations = CheckEmptySpec(oExecutor, specializations);
                await _postgre.SaveChangesAsync();
            }

            catch (ArgumentNullException ex)
            {
                throw new ArgumentNullException($"Передан пустой массив специализаций {ex.Message}");
            }

            catch (Exception ex)
            {
                Logger _logger = new Logger(_db, ex.GetType().FullName, ex.Message.ToString(), ex.StackTrace);
                _ = _logger.LogError();
                throw new Exception(ex.Message.ToString());
            }
        }
        /// <summary>
        /// Метод сохраняет личные данные юзера.
        /// </summary>
        /// <param name="needUserUpdate">Объект с данными юзера.</param>
        public async Task SaveProfileData(UserEntity needUserUpdate, string userName)
        {
            try
            {
                if (string.IsNullOrEmpty(userName))
                {
                    throw new ArgumentNullException();
                }

                // Изменяет объект юзера.
                await ChangeProfileData(needUserUpdate, userName);

                await _postgre.SaveChangesAsync();
            }

            catch (ArgumentNullException ex)
            {
                throw new ArgumentNullException($"Не передан UserId {ex.Message}");
            }

            catch (Exception ex)
            {
                Logger _logger = new Logger(_db, ex.GetType().FullName, ex.Message.ToString(), ex.StackTrace);
                _ = _logger.LogCritical();
                throw new Exception(ex.Message.ToString());
            }
        }
        /// <summary>
        /// Метод создает пользователя.
        /// </summary>
        /// <param name="user">Входная модель пользователя.</param>
        /// <returns>Список ошибок или статус успеха регистрации.</returns>
        private async Task <IActionResult> CreateUser(UserInput user)
        {
            try
            {
                IdentityResult errors = null;

                // Ищет такой email в БД.
                bool bErrorEmail = await IdentityUserEmail(user.Email);

                if (!bErrorEmail)
                {
                    try
                    {
                        // Генерит временный токен для пользователя.
                        string code = await _userManager.GenerateEmailConfirmationTokenAsync(user);

                        // Готовит ссылку, которая будет отображена в письме.
                        string callbackUrl = Url.Action("ConfirmAsync", "User", new { userId = user.Id, code = code },
                                                        protocol: HttpContext.Request.Scheme)
                                             .Replace("http://localhost:58822", "https://barbuuuda.ru")
                                             .Replace("https://barbuuuda.online", "https://barbuuuda.ru");

                        // Отправит уведомление на email.
                        EmailService emailService = new EmailService(_db);
                        await emailService.SendEmailAsync(user.Email, "Подтверждение регистрации",
                                                          $"Подтвердите регистрацию на сервисе Barbuuuda, перейдя по ссылке: <a href='{callbackUrl}'>подтвердить</a>");
                    }

                    // Если почта не существует.
                    catch (Exception ex)
                    {
                        Logger logger = new Logger(_db, ex.GetType().FullName, ex.Message.ToString(), ex.StackTrace);
                        _ = logger.LogCritical();

                        return(BadRequest(ErrorValidate.EMAIL_NOT_ENTITY));
                    }

                    // Проставит дату регистрации = текущая дата и время.
                    user.DateRegister = DateTime.UtcNow;

                    // Регистрирует пользователя.
                    IdentityResult oAddedUser = await _userManager.CreateAsync(user, user.UserPassword);

                    // Если регистрация успешна.
                    if (oAddedUser.Succeeded)
                    {
                        // Находит добавленного пользователя и берет его Id.
                        string userId = await _userService.GetLastUserAsync();

                        // Создаст счет пользователю (по дефолту в валюте RUB).
                        await _postgre.AddAsync(new InvoiceEntity()
                        {
                            UserId        = userId,
                            InvoiceAmount = 0,
                            Currency      = CurrencyType.CURRENCY_RUB,
                            ScoreNumber   = null,
                            ScoreEmail    = string.Empty
                        });

                        await _postgre.SaveChangesAsync();

                        return(Ok(oAddedUser));
                    }
                }

                // Что-то пошло не так, собирает ошибки запуская цепочку проверок валидации.
                else
                {
                    CustomValidatorExtension custom = new CustomValidatorExtension(_postgre);
                    errors = await custom.ValidateAsync(_userManager, user);
                }

                return(BadRequest(errors));
            }

            catch (Exception ex)
            {
                Logger logger = new Logger(_db, ex.GetType().FullName, ex.Message.ToString(), ex.StackTrace);
                await logger.LogCritical();

                throw new Exception(ex.Message);
            }
        }
 public async Task PostGreSaveChanges()
 {
     await _postGreDbContext.SaveChangesAsync();
 }
        /// <summary>
        /// Метод пишет сообщение.
        /// </summary>
        /// <param name="account">Логин пользователя.</param>
        /// <param name="message">Сообщение.</param>
        /// <param name="dialogId">Id диалога.</param>
        /// <returns>Список сообщений.</returns>
        public async Task <GetResultMessageOutput> SendAsync(string message, string account, long dialogId)
        {
            try
            {
                GetResultMessageOutput messagesList = new GetResultMessageOutput();

                // Если сообщения не передано, то ничего не делать.
                if (string.IsNullOrEmpty(message))
                {
                    return(null);
                }

                // Найдет Id пользователя.
                string userId = await _userService.GetUserIdByLogin(account);

                // Проверит существование диалога.
                bool isDialog = await _postgre.MainInfoDialogs
                                .Where(d => d.DialogId == dialogId)
                                .FirstOrDefaultAsync() != null;

                if (!isDialog)
                {
                    throw new NotFoundDialogIdException(dialogId);
                }

                // Запишет сообщение в диалог.
                await _postgre.DialogMessages.AddAsync(new DialogMessageEntity()
                {
                    Message     = message,
                    DialogId    = dialogId,
                    Created     = DateTime.Now,
                    UserId      = userId,
                    IsMyMessage = true
                });

                await _postgre.SaveChangesAsync();

                // Получит сообщения диалога.
                var messages = await(_postgre.DialogMessages
                                     .Where(d => d.DialogId == dialogId)
                                     .OrderBy(m => m.Created)
                                     .Select(res => new
                {
                    dialogId    = res.DialogId,
                    message     = res.Message,
                    created     = string.Format("{0:f}", res.Created),
                    userId      = res.UserId,
                    isMyMessage = res.IsMyMessage
                })
                                     .ToListAsync());

                // Приведет к типу MessageOutput.
                foreach (object messageText in messages)
                {
                    string        jsonString    = JsonSerializer.Serialize(messageText);
                    MessageOutput messageOutput = JsonSerializer.Deserialize <MessageOutput>(jsonString);

                    // Проставит флаг принадлежности сообщения.
                    messageOutput.IsMyMessage = messageOutput.UserId.Equals(userId);

                    // Затирает Id пользователя, чтобы фронт не видел.
                    messageOutput.UserId = null;

                    messagesList.Messages.Add(messageOutput);
                }
                messagesList.DialogState = DialogStateEnum.Open.ToString();

                return(messagesList);
            }

            catch (Exception ex)
            {
                Logger logger = new Logger(_db, ex.GetType().FullName, ex.Message, ex.StackTrace);
                await logger.LogCritical();

                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// Метод проверяет результаты ответов на тест исполнителем.
        /// </summary>
        /// <param name="answers">Массив с ответами на тест.</param>
        ///  /// <param name="userName">Логин юзера.</param>
        /// <returns>Статус прохождения теста true/false.</returns>
        public async Task <bool> CheckAnswersTestAsync(List <AnswerVariant> answers, string userName)
        {
            try
            {
                if (answers.Count == 0)
                {
                    throw new UserMessageException(TextException.ERROR_EMPTY_INPUT_ARRAY_ANSWERS);
                }

                List <bool> answersEqual = new List <bool>();

                // Считает кол-во правильных ответов.
                for (int i = 0; i < answers.Count; i++)
                {
                    // Уберет пробелы в начале и в конце.
                    answers[i].AnswerVariantText = CommonMethodsService.ReplaceSpacesString(answers[i].AnswerVariantText);

                    // Заменит флаг правильности с null на false.
                    if (answers[i].IsRight == null)
                    {
                        answers[i].IsRight = false;
                    }

                    // Находит такой ответ в БД.
                    AnswerVariantEntity answer = await _postgre.AnswerVariants
                                                 .Where(a => a.QuestionId
                                                        .Equals(answers[i].QuestionNumber))
                                                 .SingleOrDefaultAsync();

                    // Выбирает конкретный вариант для проверки правильности.
                    string rightVariant = answer.AnswerVariantText
                                          .Where(a => a.IsRight.Equals(true))
                                          .Select(a => a.AnswerVariantText)
                                          .FirstOrDefault();

                    answers[i].IsRight = answers[i].AnswerVariantText.Equals(rightVariant);
                    answersEqual.Add((bool)answers[i].IsRight);
                }

                // Если не все ответы были верными, то тест не пройден.
                bool isSuccessed = answersEqual.All(a => a.Equals(true));

                // Если исполнитель не прошел тест.
                if (!isSuccessed)
                {
                    return(false);
                }

                UserEntity user = await _user.GetUserByLogin(userName);

                user.IsSuccessedTest = true;
                await _postgre.SaveChangesAsync();

                return(true);
            }

            catch (Exception ex)
            {
                Logger _logger = new Logger(_db, ex.GetType().FullName, ex.Message.ToString(), ex.StackTrace);
                _ = _logger.LogError();
                throw new Exception(ex.Message.ToString());
            }
        }
        /// <summary>
        /// Метод пополнит счет пользователя на сервисе в переданной валюте, либо создаст новый счет в этой валюте.
        /// Также в этом методе происходит запись заказа в БД.
        /// Также этот метод производит вычитание суммы при оплате задания со счета заказчика.
        /// </summary>
        /// <param name="paymentSuccessInput">Входная модель.</param>
        /// <returns>Флаг успеха.</returns>
        public async Task <bool> RefillBalanceAsync(PaymentSuccessInput paymentSuccessInput)
        {
            try
            {
                OrderEntity     order;
                IFormatProvider formatter = new NumberFormatInfo {
                    NumberDecimalSeparator = "."
                };

                // Найдет Id пользователя по его логину.
                string userId = await _userService.GetUserIdByLogin(paymentSuccessInput.Account);

                if (string.IsNullOrEmpty(userId))
                {
                    throw new NotFoundUserException(paymentSuccessInput.Account);
                }

                if (paymentSuccessInput.LMI_PAYMENT_AMOUNT == null || string.IsNullOrEmpty(paymentSuccessInput.LMI_CURRENCY))
                {
                    throw new EmptyInvoiceParameterException();
                }

                // Если валюта не передана, значит выставить ее по дефолту в RUB.
                if (!string.IsNullOrEmpty(paymentSuccessInput.LMI_CURRENCY))
                {
                    paymentSuccessInput.LMI_CURRENCY = CurrencyType.CURRENCY_RUB;
                }

                // Если идет пополнение счета.
                if (paymentSuccessInput.Refill)
                {
                    // Ищет счет пользователя по UserId.
                    InvoiceEntity invoice = await _postgre.Invoices
                                            .Where(i => i.UserId
                                                   .Equals(userId) && i.Currency
                                                   .Equals(paymentSuccessInput.LMI_CURRENCY))
                                            .FirstOrDefaultAsync();

                    // Если счет пользователя в текущей валюте найден, то запишет средства на этот счет в этой валюте.
                    if (invoice != null)
                    {
                        invoice.InvoiceAmount += decimal.Parse(paymentSuccessInput.LMI_PAYMENT_AMOUNT, formatter);
                        await _postgre.SaveChangesAsync();
                    }

                    // Счета у пользователя в этой валюте не найдено, значит создаст счет в этой валюте.
                    else
                    {
                        await _postgre.Invoices.AddAsync(new InvoiceEntity
                        {
                            UserId        = userId,
                            InvoiceAmount = 0,
                            Currency      = paymentSuccessInput.LMI_CURRENCY,
                            ScoreNumber   = null,
                            ScoreEmail    = string.Empty
                        });

                        await _postgre.SaveChangesAsync();
                    }

                    order = new OrderEntity
                    {
                        Id         = userId,
                        Amount     = decimal.Parse(paymentSuccessInput.LMI_PAYMENT_AMOUNT, formatter),
                        Currency   = paymentSuccessInput.LMI_CURRENCY,
                        DateCreate = DateTime.Now
                    };
                }

                // Если идет оплата задания.
                else
                {
                    order = new OrderEntity
                    {
                        Id         = userId,
                        Amount     = decimal.Parse(paymentSuccessInput.LMI_PAYMENT_AMOUNT, formatter),
                        TaskId     = paymentSuccessInput.TaskId,
                        Currency   = paymentSuccessInput.LMI_CURRENCY,
                        DateCreate = DateTime.Now
                    };
                }

                // Запишет заказ пользователя в таблицу заказов.
                await _postgre.Orders.AddAsync(order);

                await _postgre.SaveChangesAsync();

                return(true);
            }

            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Logger logger = new Logger(_db, ex.GetType().FullName, ex.Message, ex.StackTrace);
                await logger.LogCritical();

                throw;
            }
        }