public static IEnumerable <PaymentDTO> CreatePayments(AccountDTO[] accounts, PaymentStatus status, IRnd <string> recipientRnd,
                                                       IRnd <int> countRnd, IRnd <float> amountRnd, IRnd <DateTime> startDateRnd, Func <DateTime> datetimeNow, IRnd <TimeSpan> intervalRnd, TitleRnd titleRnd)
 {
     foreach (var account in accounts)
     {
         var count = countRnd.Next();
         for (int i = 0; i < count; i++)
         {
             var interval           = intervalRnd.Next();
             var startTimestamp     = startDateRnd.Next();
             var repayDiff          = (int)((datetimeNow() - startTimestamp) / interval);
             var lastRepayTimestamp = startTimestamp + repayDiff * interval;
             yield return(new PaymentDTO
             {
                 Id = Guid.NewGuid().ToString(),
                 Name = titleRnd.Next(5),
                 AccountId = account.Id,
                 Amount = amountRnd.Next(),
                 StartTimestamp = startTimestamp,
                 LatestProcessingTimestamp = lastRepayTimestamp,
                 Interval = interval,
                 Status = (int)status,
                 Recipient = recipientRnd.Next(account.Id)
             });
         }
     }
 }
        public static string[] BusinessUserScenario(SetupAll setup, int clients, int actionsPerGroup, int minTransactions, int maxTransacitons, int requesters)
        {
            var users = setup.UsersSetup.Users.Where(u => u.Business)
                        .Select((u, i) => new { index = i, user = u })
                        .ToArray();
            var usersDict = users.ToDictionary(k => k.user.Id, v => v.user);
            var groups    = users.GroupBy(u => u.index % clients);
            var accounts  = setup.AccountsSetup.Accounts
                            .GroupBy(a => a.UserId)
                            .ToDictionary(k => k.Key, v => v.ToArray());

            var minAmount = 50;
            var amountRnd = new RndBuilder <float>(new CurrencyRnd()).Min(minAmount).Max(10000)
                            .DistributionValues(new float[] { 300, 500, 1500, 2500, 5000, 8000 })
                            .DistributionProbabilities(new[] { 2, 15, 20, 30, 25, 5, 3 })
                            .Build();
            var titelRnd             = new TitleRnd();
            var transactionsCountRnd = new RndBuilder <int>().Min(minTransactions).Max(maxTransacitons).Build();

            var allActions = new List <BusinessUserScenarioElement>();
            var no         = 0;

            foreach (var group in groups)
            {
                var groupCount    = group.Count();
                var groupAccounts = group.Where(g => accounts.ContainsKey(g.user.Id)).SelectMany(g => accounts[g.user.Id]).ToArray();
                var usersAccounts = groupAccounts.GroupBy(a => a.UserId).ToDictionary(k => k.Key, v => v.ToArray());

                for (int actions = 0; actions < actionsPerGroup; actions++)
                {
                    var user              = group.ElementAt(rand.Next(0, groupCount)).user;
                    var userAccounts      = usersAccounts[user.Id];
                    var transactionsCount = transactionsCountRnd.Next();
                    var userActions       = new List <BusinessUserTransaction>();

                    for (int i = 0; i < transactionsCount; i++)
                    {
                        if (userAccounts.All(a => a.Balance < minAmount))
                        {
                            continue;
                        }
                        var amount    = GetAmount(userAccounts, amountRnd);
                        var sender    = GetSender(amount, userAccounts);
                        var recipient = groupAccounts.ElementAt(rand.Next(0, groupAccounts.Length));

                        userActions.Add(new BusinessUserTransaction {
                            Amount = amount, AccountId = sender.Id, Recipient = recipient.Id, Title = titelRnd.Next()
                        });

                        sender.Balance    -= amount;
                        recipient.Balance += amount;
                    }

                    allActions.Add(new BusinessUserScenarioElement {
                        No = (no++).ToString(), Group = group.Key, UserId = user.Id, User = user.Login, Transactions = userActions.ToArray()
                    });
                }
            }

            return(allActions.GroupBy(a => a.Group % requesters).Select(g => JsonConvert.SerializeObject(g)).ToArray());
        }