/// <summary>
        /// Gets an IQueryable with all transactions, filtered by report period and being related to walletId specified in GetTransactionsDto
        /// </summary>
        private IQueryable <TransactionBase> GetFilteredTransactions(GetTransactionsDto dto)
        {
            DateTime fromDate, toDate;

            try
            {
                (fromDate, toDate) = GetReportPeriodLimits(dto);
            }
            catch (ArgumentException e)
            {
                throw new ValidationException(new() { { nameof(dto.ReportPeriod), e.Message } });
            }

            var transactionsInPeriod = _dbContext.Transactions
                                       .Where(t => t.TimeStamp >= fromDate && t.TimeStamp < toDate);

            var inWalletTransactions = transactionsInPeriod
                                       .Where(t => t.WalletId == dto.WalletId);

            var otherWalletTransactions = transactionsInPeriod
                                          .Where(t =>
                                                 t is WalletTransaction &&
                                                 (t as WalletTransaction).OtherWalletId == dto.WalletId);

            return(inWalletTransactions.Union(otherWalletTransactions));
        }
        public async Task <ShortTransactionSummaryDomain> GetShortSummaryAsync(GetTransactionsDto dto)
        {
            var transactions = GetFilteredTransactions(dto);

            if (dto.ReportPeriod != ReportPeriods.Custom)
            {
                await _walletService.SetWalletReportPeriodAsync(dto.WalletId, dto.ReportPeriod);
            }

            var categoryAmounts = transactions
                                  .Where(t => t is CategoryTransaction)
                                  .Select(t => t.Amount);

            var walletAmounts = transactions
                                .Where(t => t is WalletTransaction)
                                .Select(t => new
            {
                walletId = t.WalletId == dto.WalletId ?
                           (t as WalletTransaction).OtherWalletId :
                           t.WalletId,
                amount = t.WalletId == dto.WalletId ?
                         t.Amount :
                         t.Amount * -1
            })
                                .GroupBy(x => x.walletId)
                                .Select(g => g.Sum(x => x.amount));

            var allAmounts = categoryAmounts.Concat(walletAmounts);

            return(new ShortTransactionSummaryDomain
            {
                Income = await allAmounts.Where(a => a > 0).SumAsync(),
                Expense = await allAmounts.Where(a => a < 0).SumAsync()
            });
        }
Example #3
0
        public async Task <IActionResult> GetTransactions([FromQuery] GetTransactionsDto data)
        {
            var query  = Mapper.Map <GetTransactionsQuery>(data);
            var result = await Mediator.Send(query);

            return(FromResult(result));
        }
Example #4
0
        public async Task <IActionResult> GetTransactions([FromBody] GetTransactionsDto dto)
        {
            _logger.LogInformation("ViewTransactionsController GetTransactions action account service");

            var transactions = await _proxy.GetTransactionsAsync(dto);

            return(Ok(transactions));
        }
        public async Task <RecievedTransactionsDto> GetTransactionsAsync(GetTransactionsDto model)
        {
            Logger.LogInformation("CaseflowApiProxy GetTransactionsAsync action account service");

            var uri    = $"v1/accounts/{Uri.EscapeDataString(model.AccountReference)}/transactions?limit=0";
            var result = await GetResultAsync <RecievedTransactionsDto>(uri);

            return(result);
        }
        private (DateTime from, DateTime to) GetReportPeriodLimits(GetTransactionsDto dto)
        {
            if (dto.ReportPeriod == ReportPeriods.Custom)
            {
                return(dto.CustomFromDate.Value, dto.CustomToDate.Value);
            }

            DateTime currDate = DateTime.Today;

            DateTime fromDate, toDate;

            switch (dto.ReportPeriod)
            {
            case ReportPeriods.CurrentDay:
                fromDate = currDate;
                toDate   = fromDate.AddHours(24);
                break;

            case ReportPeriods.CurrentWeek:
                var weekStart = DayOfWeek.Monday;

                fromDate = currDate.AddDays(-(int)currDate.DayOfWeek + (int)weekStart);
                toDate   = fromDate.AddDays(7);
                break;

            case ReportPeriods.CurrentMonth:
                fromDate = currDate.AddDays(-currDate.Day + 1);
                toDate   = fromDate.AddMonths(1);
                break;

            case ReportPeriods.CurrentYear:
                fromDate = new DateTime(currDate.Year, 1, 1);
                toDate   = fromDate.AddYears(1);
                break;

            case ReportPeriods.AllTime:
                fromDate = new DateTime(0);
                toDate   = DateTime.Now;
                break;

            case ReportPeriods.Custom: throw new ArgumentException("A custom report period can't be automatically determined.");

            default: throw new ArgumentException($"reportPeriod value should be one of: {string.Join(", ", ReportPeriods.GetValues())}.");
            }

            return(fromDate, toDate);
        }
        public async Task <TransactionSummaryDomain> GetSummaryAsync(GetTransactionsDto dto)
        {
            var transactions = GetFilteredTransactions(dto);

            if (dto.ReportPeriod != ReportPeriods.Custom)
            {
                await _walletService.SetWalletReportPeriodAsync(dto.WalletId, dto.ReportPeriod);
            }

            var categoryInfos = transactions
                                .Where(t => t is CategoryTransaction)
                                .Select(t => t as CategoryTransaction)
                                .Select(t => new
            {
                t.CategoryId,
                t.Category.Name,
                t.Amount
            })
                                .GroupBy(x => new { x.CategoryId, x.Name })
                                .Select(g => new
            {
                WalletId   = null as int?,
                CategoryId = g.Key.CategoryId as int?,
                g.Key.Name,
                Amount = g.Sum(x => x.Amount)
            });

            var nativeWalletInfos = transactions
                                    .Where(t => t is WalletTransaction && t.WalletId == dto.WalletId)
                                    .Select(t => new
            {
                WalletId       = (t as WalletTransaction).OtherWalletId,
                Name           = (t as WalletTransaction).OtherWallet.Name,
                Amount         = t.Amount,
                IsWalletShared =
                    (t as WalletTransaction).OtherWallet.UserId == dto.UserId ||
                    (t as WalletTransaction).OtherWallet.WalletAllowedUsers.Any(wu => wu.UserId == dto.UserId)
            });

            var relatedWalletInfos = transactions
                                     .Where(t => t.WalletId != dto.WalletId)
                                     .Select(t => new
            {
                WalletId       = t.WalletId,
                Name           = t.Wallet.Name,
                Amount         = t.Amount * -1,
                IsWalletShared =
                    t.Wallet.UserId == dto.UserId ||
                    t.Wallet.WalletAllowedUsers.Any(wu => wu.UserId == dto.UserId)
            });

            var walletInfosWithUnshared = nativeWalletInfos.Concat(relatedWalletInfos)
                                          .GroupBy(x => new { x.WalletId, x.Name, x.IsWalletShared })
                                          .Select(g => new
            {
                g.Key.WalletId,
                g.Key.Name,
                Amount = g.Sum(x => x.Amount),
                g.Key.IsWalletShared
            })
                                          .Where(x => x.Amount != 0)
                                          .Select(x => new
            {
                x.WalletId,
                x.Name,
                x.Amount,
                IsIncome = x.Amount > 0,
                x.IsWalletShared
            });

            var walletInfosOnlyShared = walletInfosWithUnshared
                                        .Where(x => x.IsWalletShared)
                                        .Select(x => new
            {
                WalletId   = x.WalletId as int?,
                CategoryId = null as int?,
                Name       = x.Name,
                Amount     = x.Amount
            });

            var walletInfosOnlyUnshared = walletInfosWithUnshared
                                          .Where(x => x.IsWalletShared == false)
                                          .GroupBy(x => new { x.IsWalletShared, x.IsIncome })
                                          .Select(g => new
            {
                WalletId   = null as int?,
                CategoryId = null as int?,
                Name       = "Private wallet(s)",
                Amount     = g.Sum(x => x.Amount)
            });

            var walletInfos = walletInfosOnlyShared.Union(walletInfosOnlyUnshared);

            var allInfos = await categoryInfos
                           .Union(walletInfos)
                           .ToListAsync();

            var categoryIncomes = allInfos
                                  .Where(i => i.CategoryId != null && i.Amount > 0)
                                  .Select(i => new CategorySummaryDomain
            {
                Id     = i.CategoryId.Value,
                Name   = i.Name,
                Amount = i.Amount
            });

            var categoryExpenses = allInfos
                                   .Where(i => i.CategoryId != null && i.Amount < 0)
                                   .Select(i => new CategorySummaryDomain
            {
                Id     = i.CategoryId.Value,
                Name   = i.Name,
                Amount = i.Amount
            });

            var walletIncomes = allInfos
                                .Where(i => i.CategoryId == null && i.Amount > 0)
                                .Select(i => new WalletSummaryDomain
            {
                Id     = i.WalletId,
                Name   = i.Name,
                Amount = i.Amount
            });

            var walletExpenses = allInfos
                                 .Where(i => i.CategoryId == null && i.Amount < 0)
                                 .Select(i => new WalletSummaryDomain
            {
                Id     = i.WalletId,
                Name   = i.Name,
                Amount = i.Amount
            });

            return(new TransactionSummaryDomain
            {
                TotalIncome = allInfos
                              .Where(i => i.Amount > 0)
                              .Sum(i => i.Amount),
                TotalExpense = allInfos
                               .Where(i => i.Amount < 0)
                               .Sum(i => i.Amount),
                IncomeDetails = new OneWaySummaryDomain
                {
                    Categories = categoryIncomes,
                    Wallets = walletIncomes
                },
                ExpenseDetails = new OneWaySummaryDomain
                {
                    Categories = categoryExpenses,
                    Wallets = walletExpenses
                }
            });
        }
        public async Task <List <TransactionDomain> > GetTransactionsAsync(GetTransactionsDto dto)
        {
            var transactions = GetFilteredTransactions(dto);

            if (dto.ReportPeriod != ReportPeriods.Custom)
            {
                await _walletService.SetWalletReportPeriodAsync(dto.WalletId, dto.ReportPeriod);
            }

            IQueryable <TransactionDomain> categoryTransactions = transactions
                                                                  .Where(t => t is CategoryTransaction)
                                                                  .Select(t => new TransactionDomain
            {
                Id            = t.Id,
                Amount        = t.Amount,
                CategoryId    = (t as CategoryTransaction).CategoryId,
                OtherWalletId = null,
                TargetLabel   = (t as CategoryTransaction).Category.Name,
                Timestamp     = t.TimeStamp
            });

            var nativeWalletInfos = transactions
                                    .Where(t => t is WalletTransaction && t.WalletId == dto.WalletId)
                                    .Select(t => new
            {
                t.Id,
                t.Amount,
                OtherWalletId = (t as WalletTransaction).OtherWalletId,
                TargetLabel   = (t as WalletTransaction).OtherWallet.Name,
                t.TimeStamp,
                IsWalletShared =
                    (t as WalletTransaction).OtherWallet.UserId == dto.UserId ||
                    (t as WalletTransaction).OtherWallet.WalletAllowedUsers.Any(wu => wu.UserId == dto.UserId)
            });

            var relatedWalletInfos = transactions
                                     .Where(t => t is WalletTransaction && t.WalletId != dto.WalletId)
                                     .Select(t => new
            {
                t.Id,
                Amount        = t.Amount * -1,
                OtherWalletId = t.WalletId,
                TargetLabel   = t.Wallet.Name,
                t.TimeStamp,
                IsWalletShared =
                    (t as WalletTransaction).Wallet.UserId == dto.UserId ||
                    (t as WalletTransaction).Wallet.WalletAllowedUsers.Any(wu => wu.UserId == dto.UserId)
            });

            IQueryable <TransactionDomain> walletTransactions = nativeWalletInfos
                                                                .Union(relatedWalletInfos)
                                                                .Select(x => new TransactionDomain
            {
                Id            = x.Id,
                Amount        = x.Amount,
                CategoryId    = null,
                OtherWalletId = x.IsWalletShared ? x.OtherWalletId : null,
                TargetLabel   = x.IsWalletShared ? x.TargetLabel : "Private wallet",
                Timestamp     = x.TimeStamp
            });

            List <TransactionDomain> res = await categoryTransactions
                                           .Union(walletTransactions)
                                           .OrderByDescending(t => t.Timestamp)
                                           .ToListAsync();

            return(res);
        }