public override async Task <AggregateOverallResponse> AggregateOverall(AggregateOverallRequest request, ServerCallContext context)
        {
            var cardsIds             = cardsRepository.GetCardsIds();
            var transactionsResponse = await transactionsReadClient.FilterAsync(new FilterTransactionsRequest { Cards = { cardsIds }, TimestampTo = request.TimestampTo, TimestampFrom = request.TimestampFrom }, context.RequestHeaders.SelectCustom());

            var aggregations = Aggregations.CreateOverallCsvReport(new OverallReportData {
                Aggregations = request.Aggregations.ToArray(), Granularity = request.Granularity, Transactions = transactionsResponse.Transactions.ToArray()
            });

            return(new AggregateOverallResponse {
                Portions = { aggregations }
            });
        }
        public override async Task <AggregateUserActivityResponse> AggregateUserActivity(AggregateUserActivityRequest request, ServerCallContext context)
        {
            var accounts = accountsRepository.GetByUser(request.UserId);

            if (!accounts.Any())
            {
                return(new AggregateUserActivityResponse());
            }

            var accountsIds          = accounts.Select(a => a.Id);
            var transactionsResponse = await transactionsClient.FilterAsync(new FilterTransactionsRequest
            {
                Senders       = { accountsIds },
                Recipients    = { accountsIds },
                TimestampFrom = request.TimestampFrom,
                TimestampTo   = request.TimestampTo
            }, context.RequestHeaders.SelectCustom());

            var transactions = transactionsResponse.Transactions.ToArray();
            var aggregated   = accounts.SelectMany(a => AggregateUserTransactions(a, transactions, request.Granularity));

            return(new AggregateUserActivityResponse {
                Portions = { aggregated }
            });
        }
        public async Task <Panel> Panel(string userId)
        {
            var headers = HttpContext.CreateHeadersWithFlowId();

            RepeatedField <Loan>        loans        = new RepeatedField <Loan>();
            RepeatedField <Payment>     payments     = new RepeatedField <Payment>();
            RepeatedField <Account>     accounts     = new RepeatedField <Account>();
            RepeatedField <Card>        cards        = new RepeatedField <Card>();
            RepeatedField <Transaction> transactions = new RepeatedField <Transaction>();

            var accountsResponse = await accountsReadClient.GetUserAccountsAsync(new GetUserAccountsRequest { UserId = userId }, headers);

            var accountsIds = accountsResponse.Accounts.Select(a => a.Id).ToArray();

            accounts = accountsResponse.Accounts;

            if (accounts.Any())
            {
                var parallelTasks = new List <Task>();
                parallelTasks.Add(Task.Run(async() =>
                {
                    var transactionsResponse = await transactionsReadClient.FilterAsync(new FilterTransactionsRequest {
                        Senders = { accountsIds }, Top = PanelTransactionsCount
                    }, headers);
                    transactions = transactionsResponse.Transactions;
                }));

                parallelTasks.Add(Task.Run(async() =>
                {
                    var paymentsResponse = await paymentsReadClient.GetByAccountsAsync(new GetPaymentsRequest {
                        Ids = { accountsIds }
                    }, headers);
                    payments = paymentsResponse.Payments;
                }));

                parallelTasks.Add(Task.Run(async() =>
                {
                    var loansResponse = await loansReadClient.GetByAccountsAsync(new GetLoansRequest {
                        Ids = { accountsIds }
                    }, headers);
                    loans = loansResponse.Loans;
                }));

                parallelTasks.Add(Task.Run(async() =>
                {
                    var cardsResponse = await cardsReadClient.GetByAccountsAsync(new GetCardsRequest {
                        Ids = { accountsIds }
                    }, headers);
                    cards = cardsResponse.Cards;
                }));


                await Task.WhenAll(parallelTasks);
            }

            return(new Panel
            {
                Accounts = mapper.Map <AccountDTO[]>(accounts),
                Loans = mapper.Map <LoanDTO[]>(loans),
                Payments = mapper.Map <PaymentDTO[]>(payments),
                Transactions = mapper.Map <TransactionDTO[]>(transactions),
                Cards = mapper.Map <CardDTO[]>(cards),
            });
        }