Exemplo n.º 1
0
 public DashboardDTO()
 {
     Accounts               = new List <Account>();
     Transactions           = new List <Transaction>();
     CreditCards            = new List <CreditCard>();
     StaticFinancialMetrics = new StaticFinancialMetrics();
     TimePeriodMetrics      = new TimeValueOfMoneyMetrics();
 }
 public DashboardViewModel()
 {
     Accounts               = new List <Account>();
     Bills                  = new List <Bill>();
     Expenses               = new List <Expense>();
     Transactions           = new List <Transaction>();
     StaticFinancialMetrics = new StaticFinancialMetrics();
     TimePeriodMetrics      = new TimeValueOfMoneyMetrics();
 }
        public StaticFinancialMetrics RefreshStaticMetrics()
        {
            StaticFinancialMetrics metrics = new StaticFinancialMetrics();
            //TODO: create StaticFinancialMetrics manager class

            var income       = _calc.GetMonthlyIncome();
            var bills        = _db.Bills.ToList();
            var loans        = _db.Loans.ToList();
            var transactions = _db.Transactions.ToList();
            var accounts     = _db.Accounts.ToList();

            /* LOAN METRICS */
            var monthlyLoanInterest = 0.0m;
            var dailyLoanInterest   = 0.0m;

            foreach (var loan in loans)
            {
                monthlyLoanInterest += Calculations.MonthlyInterest(loan);
                dailyLoanInterest   += Calculations.DailyInterest(loan);
            }
            if (income > 0)
            {
                metrics.LoanInterestPercentOfIncome = monthlyLoanInterest / income;
            }
            metrics.MonthlyLoanInterest = monthlyLoanInterest;
            if (income > 0)
            {
                metrics.DailyLoanInterestPercentage = dailyLoanInterest / income;
            }
            metrics.DailyLoanInterest = dailyLoanInterest;

            /* CURRENT MONTH'S EXPENSES */
            //TODO: difference between totalDue and billsDue?
            //TODO: what counts as expenses, mandatory expenses, discretionary spending?
            //metrics.MandatoryExpenses = bills.Where(b => b.DueDate.Month == DateTime.Today.Month).Where(b => b.IsMandatory).Sum(b => b.AmountDue);
            //metrics.DiscretionaryExpenses = bills.Where(b => b.DueDate.Month == DateTime.Today.Month).Where(b => !b.IsMandatory).Sum(b => b.AmountDue);
            metrics.Expenses = bills.Where(b => b.DueDate.Month == DateTime.Today.Month && b.DueDate.Year == DateTime.Today.Year).Sum(b => b.AmountDue);

            /* PAST MONTHLY EXPENSES */
            var lastMonth         = DateTime.Today.AddMonths(-1);
            var lastMonthFirstDay = _calc.FirstDayOfMonth(lastMonth.Year, lastMonth.Month);
            var lastMonthLastDay  = _calc.LastDayOfMonth(lastMonth);

            metrics.LastMonthDiscretionarySpending = _calc.DiscretionarySpendingByDateRange(lastMonthFirstDay, lastMonthLastDay);
            metrics.LastMonthMandatoryExpenses     = _calc.ExpensesByDateRange(lastMonthFirstDay, lastMonthLastDay);

            /* RANKED EXPENSES */
            var costliestExpense = transactions.Where(t => t.Date.Month == lastMonth.Month).OrderByDescending(t => t.Amount).Select(t => t.Amount).Take(1).FirstOrDefault();

            metrics.CostliestExpenseAmount = costliestExpense;
            metrics.CostliestCategory      = transactions.Where(t => t.Date.Month == lastMonth.Month).OrderByDescending(t => t.Amount).Select(t => t.Category).Take(1).FirstOrDefault();
            if (income > 0)
            {
                metrics.CostliestExpensePercentage = costliestExpense / income;
            }

            /* AVERAGES */
            var transactionSumsByMonth = transactions.Select(t => new { t.Date.Year, t.Date.Month, t.Amount })
                                         .GroupBy(x => new { x.Year, x.Month }, (key, group) => new { year = key.Year, month = key.Month, expenses = group.Sum(k => k.Amount) }).ToList();

            //var discretionaryTransactions = transactions.Join(bills, t => t.CreditAccountId, b => b.AccountId, (t, b) => new { transactions = t, bills = b }).Where(x => x.bills.IsMandatory == false);

            //var discretionarySpendingSumsByMonth = discretionaryTransactions.Select(t => new { t.transactions.Date.Year, t.transactions.Date.Month, t.transactions.Amount })
            //    .GroupBy(x => new { x.Year, x.Month }, (key, group) => new { year = key.Year, month = key.Month, expenses = group.Sum(k => k.Amount) }).ToList();

            //var mandatoryTransactions = transactions.Join(bills, t => t.CreditAccountId, b => b.AccountId, (t, b) => new { transactions = t, bills = b }).Where(x => x.bills.IsMandatory);

            //var mandatoryExpensesByMonth = mandatoryTransactions.Select(t => new { t.transactions.Date.Year, t.transactions.Date.Month, t.transactions.Amount })
            //.GroupBy(x => new { x.Year, x.Month }, (key, group) => new { year = key.Year, month = key.Month, expenses = group.Sum(k => k.Amount) }).ToList();

            var last3MonthsTransactions         = transactionSumsByMonth.OrderByDescending(t => t.year).ThenByDescending(x => x.month).Take(3);
            var quarterlyTransactionAverageCost = last3MonthsTransactions.Average(t => t?.expenses);
            var lastMonthSpending            = transactionSumsByMonth.FirstOrDefault(t => t.year == lastMonth.Year && t.month == lastMonth.Month)?.expenses;
            var lastMonthSpendingVsMovingAvg = (lastMonthSpending - quarterlyTransactionAverageCost) / lastMonthSpending;

            metrics.AverageMonthlyExpenses3MMA = quarterlyTransactionAverageCost;
            metrics.PercentageChangeExpenses   = lastMonthSpendingVsMovingAvg;

            var expensesByMonth      = new Dictionary <DateTime, decimal>();
            var mandatoryByMonth     = new Dictionary <DateTime, decimal>();
            var discretionaryByMonth = new Dictionary <DateTime, decimal>();

            foreach (var transaction in transactionSumsByMonth)
            {
                var date   = new DateTime(transaction.year, transaction.month, 1);
                var amount = transaction.expenses;
                expensesByMonth.Add(date, amount);
            }

            //foreach (var transaction in discretionarySpendingSumsByMonth)
            //{
            //    var date = new DateTime(transaction.year, transaction.month, 1);
            //    var amount = transaction.expenses;
            //    discretionaryByMonth.Add(date, amount);
            //}

            //foreach (var transaction in mandatoryExpensesByMonth)
            //{
            //    var date = new DateTime(transaction.year, transaction.month, 1);
            //    var amount = transaction.expenses;
            //    mandatoryByMonth.Add(date, amount);
            //}

            foreach (KeyValuePair <DateTime, decimal> expense in expensesByMonth)
            {
                if (mandatoryByMonth.ContainsKey(expense.Key) == false)
                {
                    mandatoryByMonth.Add(expense.Key, 0m);
                }

                if (discretionaryByMonth.ContainsKey(expense.Key) == false)
                {
                    discretionaryByMonth.Add(expense.Key, 0m);
                }
            }

            foreach (KeyValuePair <DateTime, decimal> expense in mandatoryByMonth)
            {
                if (expensesByMonth.ContainsKey(expense.Key) == false)
                {
                    expensesByMonth.Add(expense.Key, 0m);
                }

                if (discretionaryByMonth.ContainsKey(expense.Key) == false)
                {
                    discretionaryByMonth.Add(expense.Key, 0m);
                }
            }

            foreach (KeyValuePair <DateTime, decimal> expense in discretionaryByMonth)
            {
                if (expensesByMonth.ContainsKey(expense.Key) == false)
                {
                    expensesByMonth.Add(expense.Key, 0m);
                }

                if (mandatoryByMonth.ContainsKey(expense.Key) == false)
                {
                    mandatoryByMonth.Add(expense.Key, 0m);
                }
            }

            var oneYearAgo = DateTime.Today.AddYears(-1);
            var index      = new DateTime(oneYearAgo.Year, oneYearAgo.Month, 1);

            for (DateTime i = index; i <= DateTime.Today; i = i.AddMonths(1))
            {
                if (expensesByMonth.ContainsKey(i))
                {
                    continue;
                }
                expensesByMonth.Add(i, 0m);
                mandatoryByMonth.Add(i, 0m);
                discretionaryByMonth.Add(i, 0m);
            }

            var last12           = expensesByMonth.Take(11);
            var orderedByYear    = last12.OrderBy(expense => expense.Key.Year);
            var thenOrderByMonth = orderedByYear.OrderBy(expense => expense.Key.Month);
            var toDict           = thenOrderByMonth.ToDictionary(expense => expense.Key, expense => expense.Value);

            metrics.ExpensesByMonth              = expensesByMonth.Take(12).OrderBy(expense => expense.Key.Year).ThenBy(expense => expense.Key.Month).ToDictionary(expense => $"{ConvertMonthIntToString(expense.Key.Month)}{expense.Key.Year}", expense => expense.Value);
            metrics.MandatoryExpensesByMonth     = mandatoryByMonth.Take(12).OrderBy(expense => expense.Key).ToDictionary(mandatory => $"{ConvertMonthIntToString(mandatory.Key.Month)}{mandatory.Key.Year}", mandatory => mandatory.Value);
            metrics.DiscretionarySpendingByMonth = discretionaryByMonth.Take(12).OrderBy(expense => expense.Key).ToDictionary(disc => $"{ConvertMonthIntToString(disc.Key.Month)}{disc.Key.Year}", disc => disc.Value);


            return(metrics);
        }
 public DashboardMetrics()
 {
     StaticMetrics = new StaticFinancialMetrics();
     TVMMetrics    = new TimeValueOfMoneyMetrics();
 }