private void BtnMakeSignalServiceClick(object sender, EventArgs e) { // проверить введенные данные var listError = new List<string>(); var feeDay = tbFeeSignalDay.Text.ToDecimalUniformSafe(); if (!feeDay.HasValue) listError.Add(Localizer.GetString("MessageCannotRecognizeSignalComissionString") + ": 0 0.25 5 12.50"); if (listError.Count > 0) { MessageBox.Show(string.Join(Environment.NewLine, listError), Localizer.GetString("TitleError"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // проверить наличие реального счета, если их несколько - дать выбор var accountSelected = UserServiceRegistrator.SelectTerminalUserAccount(RequireRealAccountForTradeSignals); if (accountSelected == null) return; var service = new PaidService { FixedPrice = feeDay.Value, Comment = nameTextBox.Text, ServiceType = PaidServiceType.Signals, AccountId = accountSelected.ID }; if (UserServiceRegistrator.RegisterOrUpdateService(service)) DialogResult = DialogResult.OK; }
public ServiceDetailForm(int serviceId) : this() { try { service = TradeSharpWalletManager.Instance.proxy.GetPaidServiceDetail(serviceId, out user); } catch (Exception ex) { Logger.Error("ServiceDetailForm - GetPaidServiceDetail(" + serviceId + ")", ex); } }
public ACCOUNT_SHARE_HISTORY CalculateAccountShare(TradeSharpConnection ctx, ACCOUNT_SHARE share, ACCOUNT_SHARE ownerShare, ref decimal ownersMoney, decimal equity, PaidService serviceWithFeeScale, out bool feeWasTaken) { feeWasTaken = false; var shareMoney = equity*share.Share/100M; var hist = new ACCOUNT_SHARE_HISTORY { Account = share.Account, Date = DateTime.Now, OldShare = share.Share, OldHWM = share.HWM, NewShare = share.Share, NewHWM = Math.Max(share.HWM ?? 0, shareMoney), ShareOwner = share.ShareOwner, ShareAmount = shareMoney }; share.HWM = hist.NewHWM; if ((hist.OldHWM ?? 0) == 0) return hist; if (shareMoney <= hist.OldHWM) return hist; if (serviceWithFeeScale == null) return hist; // был установлен новый HWM? var aboveHwm = shareMoney - hist.OldHWM.Value; // посчитать сумму комиссии var fee = serviceWithFeeScale.CalculateFee(shareMoney, aboveHwm); if (fee < 0.01M) return hist; feeWasTaken = true; // этот самый кусочек приписать владельцу и списать его с пайщика ownersMoney += fee; shareMoney -= fee; ownerShare.Share = ownersMoney*100M/equity; share.Share = shareMoney*100M/equity; var newHwm = shareMoney; if (newHwm > share.HWM) { share.HWM = newHwm; hist.NewHWM = newHwm; } return hist; }
public static bool RegisterOrUpdateService(PaidService service) { // получить кошелек пользователя Wallet wallet; try { wallet = TradeSharpWalletManager.Instance.proxy.GetUserWallet( CurrentProtectedContext.Instance.MakeProtectedContext(), AccountStatus.Instance.Login); if (wallet == null) throw new Exception("Кошелек не заведен"); } catch (Exception ex) { Logger.ErrorFormat("GetUserWallet({0}) error: {1}", AccountStatus.Instance.Login, ex); dialogBoxProvider.ShowMessageBox("Не удалось получить данные о кошельке", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } // отправить на сервер запрос service.User = wallet.User; WalletError error; try { TradeSharpWalletManager.Instance.proxy.RegisterOrUpdateService( CurrentProtectedContext.Instance.MakeProtectedContext(), service, out error); } catch (Exception ex) { Logger.ErrorFormat("TradeSharpWalletManager.RegisterOrUpdateService({0}) error: {1}", AccountStatus.Instance.Login, ex); error = WalletError.CommonError; } if (error == WalletError.OK) { dialogBoxProvider.ShowMessageBox("Сервис зарегистрирован в системе", "Подтверждение", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return true; } dialogBoxProvider.ShowMessageBox(EnumFriendlyName<WalletError>.GetString(error), "Ошибка регистрации сервера", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }
public void TestCalculateAccountShare() { var mgr = PAMMFeeManager.Instance; var investorsShare = conn.ACCOUNT_SHARE.First(s => s.Account == testAccount.ID && s.ShareOwner != shareOwner.ID); var ownersShare = conn.ACCOUNT_SHARE.First(s => s.Account == testAccount.ID && s.ShareOwner == shareOwner.ID); var testService = new PaidService { Currency = testAccount.Currency, serviceRates = new List<PaidServiceRate> { new PaidServiceRate { Amount = 20, RateType = PaidServiceRate.ServiceRateType.Percent, UserBalance = 0 } } }; decimal ownersMoney = 0; bool feeWasTaken; var record = mgr.CalculateAccountShare(conn, investorsShare, ownersShare, ref ownersMoney, 10000, testService, out feeWasTaken); Assert.IsFalse(feeWasTaken, "CalculateAccountShare(==HWM) - комиссия не взымается"); Assert.IsNotNull(record, "CalculateAccountShare(==HWM) - запись д.б. создана"); Assert.IsNotNull(record.NewHWM, "CalculateAccountShare(==HWM) - запись д.б. создана c HWM != null"); Assert.IsNotNull(investorsShare.HWM, "CalculateAccountShare(==HWM) - HWM д.б. модифицирована"); // "добавить" денег - HWM должен обновиться const int aboveEquity = 500; record = mgr.CalculateAccountShare(conn, investorsShare, ownersShare, ref ownersMoney, 10000 + aboveEquity, testService, out feeWasTaken); Assert.IsTrue(feeWasTaken, "CalculateAccountShare(>HWM) - комиссия таки взымается"); Assert.IsNotNull(record.OldHWM, "CalculateAccountShare(==HWM) - запись д.б. создана c OldHWM != null"); }
public void TestRegisterOrUpdateService() { var service = new PaidService { AccountId = 51, Comment = "TornSphincter", ServiceType = PaidServiceType.PAMM, serviceRates = new List<PaidServiceRate> { new PaidServiceRate { Amount = 20, RateType = PaidServiceRate.ServiceRateType.Percent } } }; var isRegistred = UserServiceRegistrator.RegisterOrUpdateService(service); Assert.IsTrue(isRegistred, "UserServiceRegistrator - сервис должен быть зарегистрирован"); }
private void SetupGrids() { var blank = new PaidService(); // торговые сигналы gridServiceSignal.Columns.Add(new FastColumn(blank.Property(s => s.AccountId), Localizer.GetString("TitleAccount")) { formatter = value => Localizer.GetString("TitleAccountNumber") + value.ToString(), SortOrder = FastColumnSort.Ascending }); gridServiceSignal.Columns.Add(new FastColumn(blank.Property(s => s.FixedPrice), Localizer.GetString("TitlePerDay")) { rowFormatter = valueObject => { var srv = (PaidService) valueObject; return srv.FixedPrice.ToStringUniformMoneyFormat() + " " + srv.Currency; } }); gridServiceSignal.Columns.Add(new FastColumn(blank.Property(s => s.FixedPriceMonth), Localizer.GetString("TitleInMonth")) { rowFormatter = valueObject => { var srv = (PaidService) valueObject; return srv.FixedPriceMonth.ToStringUniformMoneyFormat() + " " + srv.Currency; } }); gridServiceSignal.CalcSetTableMinWidth(); // ПАММ gridServicePAMM.Columns.Add(new FastColumn(blank.Property(s => s.AccountId), Localizer.GetString("TitleAccount")) { formatter = value => Localizer.GetString("TitleAccountNumber") + value.ToString(), SortOrder = FastColumnSort.Ascending }); gridServicePAMM.Columns.Add(new FastColumn(blank.Property(s => s.FixedPrice), Localizer.GetString("TitleReward")) { rowFormatter = valueObject => { var srv = (PaidService)valueObject; if (srv.serviceRates.Count == 0) return "-"; return string.Join(", ", srv.serviceRates.Select(s => string.Format("{0}{1}%", s.UserBalance == 0 ? "" : (Localizer.GetString("TitleFromSmall") + " " + s.UserBalance.ToStringUniformMoneyFormat() + " - "), s.Amount))); } }); gridServicePAMM.CalcSetTableMinWidth(); }
/// <summary> /// отключить услугу /// </summary> private void DeregisterTradeSignals(PaidService service) { if (service == null) return; // отписаться от услуги WalletError error; try { TradeSharpWalletManager.Instance.proxy.DisableService( CurrentProtectedContext.Instance.MakeProtectedContext(), service.Id, out error); } catch (Exception ex) { Logger.ErrorFormat("TradeSharpWalletManager.DisableService({0}) error: {1}", service.Id, ex); error = WalletError.CommonError; } if (error == WalletError.OK) { MessageBox.Show(Localizer.GetString("MessageServiceIsTurnedOff"), Localizer.GetString("TitleConfirmation"), MessageBoxButtons.OK, MessageBoxIcon.Asterisk); ShowSignallerOptions(editedUser); } else MessageBox.Show(EnumFriendlyName<WalletError>.GetString(error), Localizer.GetString("TitleError"), MessageBoxButtons.OK, MessageBoxIcon.Error); }
private void BtnMakePAMMClick(object sender, EventArgs e) { // включить ПАММ if (gridServicePAMM.rows.Count == 0) { // выбрать реальный счет пользователя var accountSelected = UserServiceRegistrator.SelectTerminalUserAccount(true); if (accountSelected == null) return; var dlg = new OpenPAMMForm(accountSelected.Currency); if (dlg.ShowDialog() == DialogResult.Cancel) return; if (!dlg.EnablePAMM) return; var service = new PaidService { AccountId = accountSelected.ID, Currency = accountSelected.Currency, ServiceType = PaidServiceType.PAMM, serviceRates = dlg.ServiceRates, Comment = Localizer.GetString("TitlePAMMAccount") + " #" + accountSelected.ID }; if (!UserServiceRegistrator.RegisterOrUpdateService(service)) return; ShowSignallerOptions(editedUser); return; } // отключить ПАММ-сервис var servicePAMM = (PaidService) gridServicePAMM.rows[0].ValueObject; DeregisterTradeSignals(servicePAMM); }
private bool CreateOrUpdateServiceFeeRecords(PaidService service, TradeSharpConnection ctx, bool existedService) { if (service.serviceRates == null) service.serviceRates = new List<PaidServiceRate>(); try { if ((service.serviceRates == null || service.serviceRates.Count == 0) && !existedService) return true; // сервис уже был зарегистрирован? if (existedService) { var rates = ctx.SERVICE_RATE.Where(r => r.Service == service.Id).ToList(); if (rates.Count == 0 && service.serviceRates.Count == 0) return true; // рейты не изменились? if (rates.Count == service.serviceRates.Count) if (rates.All(r => service.serviceRates.Any(sr => sr.Amount == r.Amount && sr.UserBalance == r.UserBalance && (int)sr.RateType == r.RateType))) return true; // удалить имеющиеся рейты foreach (var rate in rates) ctx.SERVICE_RATE.Remove(rate); } // добавить рейты foreach (var rate in service.serviceRates) ctx.SERVICE_RATE.Add(new SERVICE_RATE { Amount = rate.Amount, Service = service.Id, UserBalance = rate.UserBalance, RateType = (int)rate.RateType }); ctx.SaveChanges(); return true; } catch (Exception ex) { Logger.Error("CreateOrUpdateServiceFeeRecords() error", ex); return false; } }
public bool RegisterOrUpdateService(ProtectedOperationContext secCtx, PaidService service, out WalletError error) { if (!UserSessionStorage.Instance.PermitUserOperation(secCtx, false, false)) { error = WalletError.InsufficientRights; return false; } // проверить сервис - 1 000 000 USD в день, к примеру, перебор // одному пользователю недозволительно высталять 10 сервисов // счет должен быть реальным if (service.ServiceType == PaidServiceType.PAMM || service.ServiceType == PaidServiceType.Signals) { // проверить - реальный счет? if (!service.AccountId.HasValue) { error = WalletError.InvalidData; return false; } if (service.FixedPrice < 0) { error = WalletError.InvalidData; return false; } try { using (var ctx = DatabaseContext.Instance.Make()) { var account = ctx.ACCOUNT.FirstOrDefault(a => a.ID == service.AccountId.Value); if (account == null) { error = WalletError.InvalidData; return false; } service.Currency = account.Currency; // перевести сумму в USD - если она велика - вернуть false // перевести стоимость сервиса в USD var fixedPrice = service.FixedPrice; if (account.Currency != MaxFixedPriceCheckCurrency) { string errorStr; var fixedPriceTarget = DalSpot.Instance.ConvertSourceCurrencyToTargetCurrency(MaxFixedPriceCheckCurrency, account.Currency, (double)service.FixedPrice, QuoteStorage.Instance.ReceiveAllData(), out errorStr); if (!fixedPriceTarget.HasValue) { error = WalletError.InvalidData; return false; } fixedPrice = fixedPriceTarget.Value; } if (fixedPrice > MaxFixedPricePerDayUSD) { error = WalletError.InvalidData; return false; } // проверить, солько сервисов зарегистрировал пользователь? // заодно проверить - нет ли сервиса того же типа с указанием того же счета var user = ctx.PLATFORM_USER.FirstOrDefault(u => u.ID == service.User); if (user == null) { error = WalletError.InvalidData; return false; } var existService = ctx.SERVICE.FirstOrDefault(s => s.User == user.ID && s.ServiceType == (int)service.ServiceType); // обновить сервис if (existService != null) { service.Id = existService.ID; existService.AccountId = service.AccountId; existService.Comment = service.Comment; existService.FixedPrice = service.FixedPrice; existService.Currency = service.Currency; // прогрессивная шкала оплаты if (!CreateOrUpdateServiceFeeRecords(service, ctx, true)) { error = WalletError.ServerError; return false; } ctx.SaveChanges(); error = WalletError.OK; return true; } // создать новый сервис var srvNew = ctx.SERVICE.Add(new SERVICE { User = service.User, AccountId = service.AccountId, Comment = service.Comment, FixedPrice = service.FixedPrice, Currency = service.Currency, ServiceType = (short)service.ServiceType }); Logger.InfoFormat("New service added: user={0}, account={1}, type={2}, price={3} {4}", service.User, service.AccountId, service.ServiceType, service.FixedPrice.ToStringUniformMoneyFormat(), service.Currency); ctx.SaveChanges(); service.Id = srvNew.ID; // прогрессивная шкала оплаты if (!CreateOrUpdateServiceFeeRecords(service, ctx, false)) { error = WalletError.ServerError; return false; } error = WalletError.OK; return true; } } catch (Exception ex) { Logger.Error("RegisterOrUpdateService error", ex); } } // не ПАММ и не сигналы... error = WalletError.CommonError; return false; }
public bool RegisterOrUpdateService(ProtectedOperationContext ctx, PaidService service, out WalletError error) { error = WalletError.OK; if (Channel == null) throw new Exception("WalletManagerProxy: связь не установлена"); try { return Channel.RegisterOrUpdateService(ctx, service, out error); } catch { RenewFactory(); try { return Channel.RegisterOrUpdateService(ctx, service, out error); } catch (Exception ex2) { Logger.Error("RegisterOrUpdateService() error: ", ex2); return false; } } }