// 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);
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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);
        }
Beispiel #7
0
        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());
        }
Beispiel #10
0
        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);
        }
Beispiel #12
0
 public void BeforeEachTest()
 {
     _tableStorageServiceMock = new Mock <ITableStorageService>();
     _sut = new UserBalanceRepository(_tableStorageServiceMock.Object);
 }
Beispiel #13
0
        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));
        }