// TODO: add functionality based on user settings // TODO: add multiple ways to distribute funds public static bool PeriodPay(User user) { var subscriptionInfo = UserSubscriptionInfoRepository.FindOrCreate(user); var paydayTime = subscriptionInfo.last_paid.AddMonths(1); if (DateTime.Now < paydayTime) { return(false); } var currency = subscriptionInfo.selected_currency; var balance = UserBalanceRepository.FindOrCreate(user, currency); decimal amount = 0; amount = balance.balance < subscriptionInfo.selected_amount ? balance.balance : subscriptionInfo.selected_amount; var randomProjectsToFund = 4; // TODO: get from user settings var amountToFundRandomProjects = amount / randomProjectsToFund; for (int i = 1; i <= randomProjectsToFund; i++) { var randomProject = ProjectRepository.FindRandom(); SubscriptionFundingUtils.FundEntity( user, randomProject.id, EntityType.Project, amountToFundRandomProjects, currency ); } return(true); }
public static Invoice ProcessConfirmedInvoice(Invoice invoice) { if (invoice.entity_type == EntityType.UserBalance) { UserBalanceRepository.FindOrCreate(invoice); } if ( !EntityUtils.IsEntityExists(invoice.entity_id, invoice.entity_type) || invoice.status != InvoiceStatus.Confirmed ) { throw new Exception("Entity entity not exists or has invalid status"); } switch (invoice.entity_type) { case EntityType.UserBalance: var user = invoice.User(); if (user == null) { throw new Exception("Invoice user not exists"); } UserBalanceUtils.Deposit(user, invoice); break; default: FundingBalanceUtils.FundEntity(invoice); break; } invoice.UpdateStatus(InvoiceStatus.Done); return(invoice.Refresh()); }
public static UserBalance Create( UserModel user = null, decimal amount = 0, CurrencyType currencyType = CurrencyType.BitCoin ) { user = user ?? UserFaker.Create(); var id = UserBalance.Create(user, currencyType, amount); return(UserBalanceRepository.Find(id)); }
public MyBalanceController() { Get("/api/v1/me/balances/get", _ => { var me = UserRepository.Find(CurrentRequest.UserId); var balances = UserBalanceRepository.GetPositive(me); return(HttpResponse.Item("balances", new UserBalanceTransformer().Many(balances))); }); }
public WithdrawalsCrudController() { Post("/api/v1/me/withdrawal/new", _ => { var errors = ValidationProcessor.Process(Request, new IValidatorRule[] { new ShouldHaveParameters(new[] { "amount", "currency_type", "address" }), new MinLength("address", 4), new ShouldBeCorrectEnumValue("currency_type", typeof(CurrencyType)), }, true); if (errors.Count > 0) { return(HttpResponse.Errors(errors)); } var me = UserRepository.Find(CurrentRequest.UserId); var currencyType = (CurrencyType)GetRequestEnum("currency_type", typeof(CurrencyType)); decimal amount = System.Convert.ToDecimal(GetRequestStr("amount")); if (amount < 0.01M) { return(HttpResponse.Error(HttpStatusCode.Forbidden, "Amount cannot be less than 0.01")); } var userBalance = UserBalanceRepository.Find(me, currencyType); if (userBalance == null || amount > userBalance.balance) { return(HttpResponse.Error(HttpStatusCode.Forbidden, "You cannot withdraw more that you currently have")); } var address = GetRequestStr("address"); var withdrawalRequest = WithdrawalRequestRepository.Create(me, currencyType, amount, address); return(HttpResponse.Item( "withdraw_request", new WithdrawalRequestTransformer().Transform(withdrawalRequest), HttpStatusCode.Created )); }); Get("/api/v1/me/withdrawals/get", _ => { var me = UserRepository.Find(CurrentRequest.UserId); var withdrawalRequests = WithdrawalRequestRepository.Get(me); return(HttpResponse.Item( "withdraw_requests", new WithdrawalRequestTransformer().Many(withdrawalRequests) )); }); }
public static Invoice Create( UserModel user, int entityId, EntityType entityType, decimal amount, CurrencyType currencyType, InvoiceStatus status, CurrencyWallet wallet ) { switch (entityType) { case EntityType.UserBalance: UserBalanceRepository.FindOrCreate(user, currencyType); break; } var invoice = Find(Invoice.Create(user, entityId, entityType, amount, currencyType, status, wallet)); DiscordWebhooks.SendEvent("system-events", $"New invoice #{invoice.id} was created for user: {invoice.user_id}"); return(invoice); }
public RegisterBonus() { Post("/api/v1/schedule/user/register_bonus/start", _ => { var task = Task.Run(() => { int tokenBonus = Convert.ToInt32( AppConfig.GetConfiguration("user:registration:token_bonus") ); if (tokenBonus <= 0) { return; } int pageIndex = 1; var users = DL.Model.User.User.Paginate(pageIndex, 100); while (users.Length > 0) { foreach (var user in users) { try { if ( !user.EmailConfirmed() || FundingTransactionRepository.Get(user).Length > 0 ) { continue; } var balance = UserBalanceRepository.FindOrCreate(user, CurrencyType.GitComToken); balance.UpdateBalance(balance.balance + tokenBonus); FundingTransactionRepository.Create( user, user.id, EntityType.UserBalance, 2M, CurrencyType.GitComToken, "Registration bonus" ); } catch (Exception e) { SentrySdk.CaptureException(e); } } ++pageIndex; users = DL.Model.User.User.Paginate(pageIndex, 100); } }); JobsPool.Get().Push(task); return(HttpResponse.Data(new JObject())); }); }
public void ProcessConfirmedInvoice_DataCorrect_InvoiceProcessed() { var user = UserFaker.Create(); var balance = UserBalanceRepository.FindOrCreate(user, CurrencyType.BitCoin); var invoice = InvoiceFaker.Create(user, balance.id, EntityType.UserBalance); invoice = invoice.UpdateStatus(InvoiceStatus.Confirmed).Refresh(); invoice = InvoiceUtils.ProcessConfirmedInvoice(invoice).Refresh(); balance = balance.Refresh(); Assert.NotNull(balance); Assert.AreEqual(InvoiceStatus.Done, invoice.status); Assert.AreEqual(invoice.amount, balance.balance); }
public static UserBalance Deposit(User user, Invoice invoice) { if (invoice.entity_type != EntityType.UserBalance) { throw new Exception("Deposit can be done only for UserBalance"); } var existingTx = FundingTransactionRepository.Find(user, invoice, user.id, EntityType.UserBalance); var balance = UserBalanceRepository.FindOrCreate(invoice); if (existingTx != null) { throw new Exception("Transaction for specified invoice already exists"); } FundingTransactionUtils.CreateTxFromInvoice(invoice); UserBalanceRepository.UpdateBalance(balance, balance.balance + invoice.amount); return(balance.Refresh()); }
public void RegisterBonus_Ok() { var user = UserFaker.Create(); var browser = new Browser(new DefaultNancyBootstrapper()); var result = browser .Post("/api/v1/schedule/user/register_bonus/start", with => { with.HttpRequest(); with.Query("schedule_token", AppConfig.GetConfiguration("auth:schedule:token")); }).Result; Assert.Zero(FundingTransactionRepository.Get(user).Length); JobsPool.Get().WaitAll(); Assert.True(FundingTransactionRepository.Get(user).Length == 1); var balance = UserBalanceRepository.Find(user, CurrencyType.GitComToken); var tokenBonus = System.Convert.ToInt32(AppConfig.GetConfiguration("user:registration:token_bonus")); Assert.AreEqual(tokenBonus, balance.balance); }
public void FundEntity_DataCorrect_EntityFunded() { var user = UserFaker.Create(); var amount = Rand.SmallDecimal(); var balance = UserBalanceRepository.FindOrCreate(user, CurrencyType.BitCoin); balance.UpdateBalance(amount); var info = UserSubscriptionInfoRepository.FindOrCreate(user); info.UpdateSelectedAmount(amount).Refresh(); ProjectFaker.Create(); SubscriptionUtils.PeriodPay(user); var txs = FundingTransactionRepository.Get(user); Assert.True(txs.Length > 0); Assert.True(txs[0].amount > 0); }
public void BeforeEachTest() { _tableStorageServiceMock = new Mock <ITableStorageService>(); _sut = new UserBalanceRepository(_tableStorageServiceMock.Object); }
public CliResult Execute() { Output("Approving invoice"); Output("Type invoice id:"); var id = Convert.ToInt32(Console.ReadLine()); var invoice = Invoice.Find(id); if (invoice == null) { Output($"Invoice with id {id} not found"); return(new CliResult(CliExitCode.NotFound, StrOutput)); } Output("Invoice:"); Output(JObject.FromObject(invoice).ToString()); Output("Transformed invoice:"); Output(new InvoiceTransformer().Transform(invoice).ToString()); Output("Invoice user:"******"Invoice has invalid status - allowed only: " + InvoiceStatus.RequiresConfirmation); return(new CliResult(CliExitCode.UnknownError, StrOutput)); } var isApproving = Ask("Approve that invoice?"); if (!isApproving) { Output("Aborted."); return(new CliResult(CliExitCode.Ok, StrOutput)); } Output("Approving invoice..."); invoice = InvoiceUtils.ConfirmInvoice(invoice); var isProcessing = Ask("Process confirmed invoice?"); if (!isProcessing) { return(new CliResult(CliExitCode.Ok, StrOutput)); } var balance = UserBalanceRepository.Find(invoice.User()); Output("Balance before:"); Output(new UserBalanceTransformer().Transform(balance).ToString()); Output("Processing invoice..."); invoice = InvoiceUtils.ProcessConfirmedInvoice(invoice); Output("Invoice processing finished..."); Output("Balance after:"); Output(new UserBalanceTransformer().Transform(balance.Refresh()).ToString()); Output("Transformed invoice:"); Output(new InvoiceTransformer().Transform(invoice).ToString()); return(new CliResult(CliExitCode.Ok, StrOutput)); }