public void EditAccountOwnerModel(int accountId, int ownerId, int right, string action)
 {
     switch (action)
     {
         case "add":
             try
             {
                 using (var ctx = DatabaseContext.Instance.Make())
                 {
                     var newItem = new PLATFORM_USER_ACCOUNT
                     {
                         Account = accountId,
                         PlatformUser = ownerId,
                         RightsMask = right
                     };
                     ctx.PLATFORM_USER_ACCOUNT.Add(newItem);
                     ctx.SaveChanges();
                 }
             }
             catch (Exception ex)
             {
                 Logger.Error(String.Format("EditAccountOwnerModel() - ошибка при добавлении пользователя с ID {0} к управляющми счёта {1}", ownerId, accountId), ex);
             }
             break;
         case "del":
             try
             {
                 using (var ctx = DatabaseContext.Instance.Make())
                 {
                     var itemToDel = ctx.PLATFORM_USER_ACCOUNT.FirstOrDefault(x => x.Account == accountId && x.PlatformUser == ownerId);
                     if (itemToDel == null) return;
                     ctx.PLATFORM_USER_ACCOUNT.Remove(itemToDel);
                     ctx.SaveChanges();
                 }
             }
             catch (Exception ex)
             {
                 Logger.Error(String.Format("EditAccountOwnerModel() - ошибка при удалении пользователя с ID {0} из управляющих счётом {1}", ownerId, accountId), ex);
             }
             break;
     }
 }
        private string CreateAccount(out int accountId)
        {
            accountId = -1;
            if (string.IsNullOrEmpty(tbLogin.Text) ||
                string.IsNullOrEmpty(tbEmail.Text) ||
                string.IsNullOrEmpty(tbPassword.Text) ||
                cbAccountGroup.SelectedIndex < 0) return "Поля не заполнены";

            var login = tbLogin.Text;
            var password = tbPassword.Text;
            var email = tbEmail.Text;
            var group = cbAccountGroup.SelectedItem.ToString();
            var depo = tbStartDepo.Text.ToDecimalUniformSafe() ?? 0;
            var createTime = dpCreateTime.Value;

            using (var conn = DatabaseContext.Instance.Make())
            {
                if (conn.PLATFORM_USER.Any(u => u.Login == login))
                    return "Логин занят";
                if (conn.PLATFORM_USER.Any(u => u.Email == email))
                    return "Email занят";

                try
                {
                    var usr = new PLATFORM_USER
                    {
                        Login = login,
                        Password = password,
                        Email = email,
                        Name = tbName.Text,
                        Surname = tbSurname.Text,
                        RegistrationDate = createTime,
                        RoleMask = 0,
                        Patronym = "Н",
                        Title = "-"
                    };
                    conn.PLATFORM_USER.Add(usr);
                    var account = new ACCOUNT
                    {
                        Currency = "USD",
                        Balance = depo,
                        MaxLeverage = tbMaxLeverage.Text.ToDecimalUniformSafe() ?? 100,
                        AccountGroup = group,
                        TimeCreated = createTime,
                        Status = (int) Account.AccountStatus.Created
                    };
                    conn.ACCOUNT.Add(account);
                    conn.SaveChanges();
                    var pa = new PLATFORM_USER_ACCOUNT
                    {
                        PlatformUser = usr.ID,
                        Account = account.ID,
                        RightsMask = 0
                    };
                    conn.PLATFORM_USER_ACCOUNT.Add(pa);

                    var bc = new BALANCE_CHANGE
                    {
                        AccountID = account.ID,
                        Amount = depo,
                        ChangeType = (int) BalanceChangeType.Deposit,
                        Description = "Initial deposit",
                        ValueDate = createTime
                    };
                    conn.BALANCE_CHANGE.Add(bc);
                    conn.SaveChanges();
                    accountId = account.ID;
                    return string.Empty;
                }
                catch (Exception ex)
                {
                    return ex.GetType().Name + ": " + ex.Message;
                }
            }
        }
        public AccountRegistrationStatus RegisterAccount(PlatformUser user,
            string accountCurrency, int startBalance, decimal maxLeverage, string completedPassword, bool autoSignIn)
        {
            // проверить заполнение логина-почты-баланса-плеча
            if (user.Login.Length < PlatformUser.LoginLenMin ||
                user.Login.Length > PlatformUser.LoginLenMax) return AccountRegistrationStatus.IncorrectLogin;
            if (user.Email.Length < PlatformUser.EmailLenMin ||
                user.Email.Length > PlatformUser.EmailLenMax) return AccountRegistrationStatus.IncorrectEmail;
            if (!PlatformUser.CheckLoginSpelling(user.Login)) return AccountRegistrationStatus.IncorrectLogin;
            if (startBalance < Account.MinimumStartDepo || startBalance > Account.MaximumStartDepo)
                return AccountRegistrationStatus.IncorrectBalance;
            if (maxLeverage < 0) maxLeverage = 0;
            else if (maxLeverage > Account.MaximumDepoLeverage) maxLeverage = Account.MaximumDepoLeverage;
            long hash;
            if (!TradingContractDictionary.Instance.GetTickers(out hash).Any(c => c.ActiveBase == accountCurrency ||
                c.ActiveCounter == accountCurrency)) return AccountRegistrationStatus.WrongCurrency;

            // сгенерировать пароль
            if (string.IsNullOrEmpty(completedPassword))
            {
                string pwrd;
                while (true)
                {
                    pwrd = RandomWordGenerator.Password(new Random().Next(2) + 2);
                    if (pwrd.Length < PlatformUser.PasswordLenMin || pwrd.Length > PlatformUser.PasswordLenMax)
                        continue;
                    break;
                }
                user.Password = pwrd;
            }
            else
                user.Password = completedPassword;
            user.RegistrationDate = DateTime.Now;
            Logger.InfoFormat("RegisterAccount (email={0}, login={1}, pwrd={2}{3})",
                user.Email, user.Login, user.Password, string.IsNullOrEmpty(completedPassword) ? " (auto)" : "");
            if (string.IsNullOrEmpty(user.Title))
                user.Title = string.IsNullOrEmpty(user.Name) ? user.Login : user.Name;
            user.RoleMask = UserRole.Trader;

            // попытка создать пользователя и открыть счет
            using (var ctx = DatabaseContext.Instance.Make())
            {
                try
                {
                    // проверка дублирования
                    var existUser = ctx.PLATFORM_USER.FirstOrDefault(u => u.Email.Equals(user.Email, StringComparison.OrdinalIgnoreCase));
                    Logger.InfoFormat("Регистрация пользователя: email {0} занят", user.Email);
                    if (existUser != null) return AccountRegistrationStatus.DuplicateEmail;
                    existUser = ctx.PLATFORM_USER.FirstOrDefault(u => u.Login == user.Login);
                    if (existUser != null) return AccountRegistrationStatus.DuplicateLogin;
                }
                catch (Exception ex)
                {
                    Logger.Error("Ошибка в RegisterAccount(checks)", ex);
                    return AccountRegistrationStatus.ServerError;
                }

                // в рамках одной транзакции создать логин и счет
                //using (var transaction = ctx.Connection.BeginTransaction())
                {
                    DbTransaction transaction;
                    try
                    {
                        if (((IObjectContextAdapter)ctx).ObjectContext.Connection.State != ConnectionState.Open)
                            ((IObjectContextAdapter)ctx).ObjectContext.Connection.Open();
                        Logger.Info("Connection's opened");
                        transaction = ((IObjectContextAdapter)ctx).ObjectContext.Connection.BeginTransaction();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("RegisterAccount - ошибка в ctx.Connection.BeginTransaction", ex);
                        return AccountRegistrationStatus.ServerError;
                    }

                    try
                    {
                        // добавить пользователя
                        var userBase = LinqToEntity.UndecoratePlatformUser(user);
                        ctx.PLATFORM_USER.Add(userBase);

                        // добавить счет
                        var account = new ACCOUNT
                        {
                            AccountGroup = defaultDemoAccountGroupCode,
                            MaxLeverage = maxLeverage,
                            Balance = startBalance,
                            UsedMargin = 0,
                            Currency = accountCurrency,
                            Description = string.Format("demo account for {0}", user.Login),
                            Status = (int)Account.AccountStatus.Created,
                            TimeCreated = DateTime.Now,
                        };
                        try
                        {
                            ctx.ACCOUNT.Add(account);
                            // сохранить изменения (добавление пользователя и счета, нужны ID)
                            ctx.SaveChanges();
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("RegisterAccount - ACCOUNT adding error", ex);
                            return AccountRegistrationStatus.ServerError;
                        }

                        // добавить кошелек
                        try
                        {
                            var wallet = new WALLET
                            {
                                Balance = 0,
                                Currency = accountCurrency,
                                Password = user.Password,
                                User = userBase.ID
                            };
                            ctx.WALLET.Add(wallet);
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("RegisterAccount - WALLET adding error", ex);
                            return AccountRegistrationStatus.ServerError;
                        }

                        // пользователь-счет
                        var userAccount = new PLATFORM_USER_ACCOUNT
                        {
                            PlatformUser = userBase.ID,
                            Account = account.ID,
                            RightsMask = (int)AccountRights.Управление
                        };
                        ctx.PLATFORM_USER_ACCOUNT.Add(userAccount);

                        // перевод на счет
                        var trans = new BALANCE_CHANGE
                        {
                            ValueDate = DateTime.Now,
                            AccountID = account.ID,
                            Amount = startBalance,
                            ChangeType = (int)BalanceChangeType.Deposit,
                            Description = "initial deposit"
                        };
                        ctx.BALANCE_CHANGE.Add(trans);

                        // сделать сигнальщиком
                        if (makeNewlyAddedUsersSignallers)
                            MakeNewlyRegisteredAccountSignaller(ctx, userBase, account);

                        // сохранить все изменения
                        ctx.SaveChanges();
                        if (string.IsNullOrEmpty(completedPassword))
                            if (!SendEmailOnNewAccount(user, true))
                            {
                                transaction.Rollback();
                                return AccountRegistrationStatus.EmailDeliveryError;
                            }

                        transaction.Commit();
                        ((IObjectContextAdapter)ctx).ObjectContext.Connection.Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorFormat("Ошибка в RegisterAccount (login={0}, email={1}) : {2}",
                                           user.Login, user.Email, ex);
                        transaction.Rollback();
                        ((IObjectContextAdapter)ctx).ObjectContext.Connection.Close();
                        return AccountRegistrationStatus.ServerError;
                    }
                } // using (transaction ...
            }
            return AccountRegistrationStatus.OK;
        }