Beispiel #1
0
        public decimal FutureValue(DateTime futureDate, decimal?netPay)
        {
            try
            {
                Logger.Instance.Calculation($"FutureValue");
                var payperiods  = PayPeriodsTilDue(futureDate);
                var date        = DateTime.Today;
                var billManager = new BillManager();
                var billsFromDb = billManager.GetAllBills();

                var bills = new Dictionary <string, string>
                {
                    { "currentDate", DateTime.Today.ToShortDateString() },
                    { "endDate", DateTime.Today.Day <= 14
                        ? new DateTime(date.Year, date.Month, 15).ToShortDateString()
                        : new DateTime(date.Year, date.Month, LastDayOfMonth(date).Day).ToShortDateString() },
                    { "periodCosts", "0" },
                    { "totalCosts", "0" },
                    { "totalSavings", "0" }
                };

                foreach (var bill in billsFromDb)
                {
                    bills.Add(bill.Name, bill.DueDate.ToShortDateString());
                }

                for (var i = 0; i < payperiods; i++)
                {
                    bills = UpdateBillDueDates(bills);
                    bills = UpdateTotalCosts(bills);
                    SetCurrentAndEndDate(bills);
                    decimal?savings     = Convert.ToDecimal(bills["totalSavings"]);
                    var     periodCosts = Convert.ToDecimal(bills["periodCosts"]);

                    savings += netPay - periodCosts;
                    bills["totalSavings"] = savings.ToString();
                }
                //var cost = Convert.ToDecimal(bills["periodCosts"]);
                var save = Convert.ToDecimal(bills["totalSavings"]);
                Logger.Instance.Calculation($"FutureValue({futureDate:d}, {netPay}) returned {save}");

                return(save);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
Beispiel #2
0
        // GET: Bills
        public ActionResult Index()
        {
            try
            {
                Logger.Instance.DataFlow("Index");
                BillViewModel billVM = new BillViewModel();
                billVM.Bills   = _billManager.GetAllBills();
                billVM.Metrics = _billManager.GetBillMetrics();

                return(View(billVM));
            }
            catch (Exception e)
            {
                Logger.Instance.Error(e);
                return(View(new BillViewModel()));
            }
        }
Beispiel #3
0
        public decimal DiscretionarySpendingByDateRange(DateTime begin, DateTime end)
        {
            try
            {
                Logger.Instance.Calculation($"DiscretionarySpendingByDateRange");
                var transactionManager = new TransactionManager();
                var transactions       = transactionManager.GetTransactionsBetweenDates(begin, end);
                var billManager        = new BillManager();
                var bills  = billManager.GetAllBills();
                var isBill = false;
                var ret    = 0m;

                foreach (var transaction in transactions)
                {
                    foreach (var bill in bills)
                    {
                        // If the bill name matches the transaction payee, count the transaction as a bill (mandatory expense)
                        if (bill.Name.Equals(transaction.Payee))
                        {
                            isBill = true;
                            Logger.Instance.Calculation($"{transaction.Amount}: {transaction.Payee} transaction is a bill");
                        }
                        else
                        {
                            Logger.Instance.Calculation($"{transaction.Amount}: {transaction.Payee} transaction is not a bill");
                        }
                    }

                    // If transaction is not a bill, add to discretionary spending total
                    if (isBill)
                    {
                        continue;
                    }

                    ret += transaction.Amount;
                    Logger.Instance.Calculation($"{transaction.Amount} added to discretionary spending total");
                }
                Logger.Instance.Calculation($"{ret} total discretionary spending from {begin:d} to {end:d}");
                return(ret);
            }
            catch (Exception e)
            {
                Logger.Instance.Error(e);
                return(0.0m);
            }
        }
Beispiel #4
0
        private Dictionary <string, string> UpdateTotalCosts(Dictionary <string, string> billsDictionary)
        {
            try
            {
                Logger.Instance.Calculation($"UpdateTotalCosts");
                var billManager = new BillManager();
                var bills       = billManager.GetAllBills();
                var currentDate = Convert.ToDateTime(billsDictionary["currentDate"]);
                var endDate     = Convert.ToDateTime(billsDictionary["endDate"]);
                var expenses    = 0.0m;
                billsDictionary["periodCosts"] = "0";

                foreach (var bill in billsDictionary)
                {
                    if (bill.Key == "currentDate" || bill.Key == "endDate" || bill.Key == "periodCosts" ||
                        bill.Key == "totalSavings" || bill.Key == "totalCosts")
                    {
                        continue;
                    }

                    var dueDate = Convert.ToDateTime(bill.Value);
                    if (!(dueDate >= currentDate && dueDate <= endDate))
                    {
                        continue;
                    }

                    expenses += bills.Where(b => b.Name == bill.Key).Select(b => b.AmountDue).FirstOrDefault();
                    Logger.Instance.Calculation($"{expenses} added to {bill.Key}");
                }

                var billCosts = Convert.ToDecimal(billsDictionary["totalCosts"]);
                billsDictionary["totalCosts"] = (expenses + billCosts).ToString(CultureInfo.InvariantCulture);
                Logger.Instance.Calculation($"{expenses + billCosts} added to total costs (expenses: {expenses} + bill costs: {billCosts})");
                billsDictionary["periodCosts"] = expenses.ToString(CultureInfo.InvariantCulture);
                Logger.Instance.Calculation($"expenses: {expenses} added to period costs");

                return(billsDictionary);
            }
            catch (Exception e)
            {
                Logger.Instance.Error(e);
                return(null);
            }
        }
Beispiel #5
0
        public Dictionary <string, decimal> GetPaycheckContributionsDict()
        {
            try
            {
                var accountManager = new AccountManager();
                var accounts       = accountManager.GetAllAccounts();

                var billManager = new BillManager();
                var bills       = billManager.GetAllBills();

                var accountContribution = new Dictionary <string, decimal>();

                //Zeros out all accounts req paycheck contributions
                foreach (var account in accounts)
                {
                    account.PaycheckContribution = 0.0m;;
                }

                // update suggested paycheck contributions for bills
                foreach (var bill in bills)
                {
                    var billTotal = bill.AmountDue;
                    Logger.Instance.Calculation($"{billTotal} due on {bill.DueDate} for {bill.Name}");

                    // get the account assigned to the bill
                    bill.Account = accounts.FirstOrDefault(a => a.Id == bill.AccountId);
                    if (bill.Account != null && bill.Account.ExcludeFromSurplus)
                    {
                        continue;
                    }

                    //TODO: Needs to account for all pay frequencies
                    //TODO: Suggested contribution assumes payday twice a month.  need to update to include other options
                    if (bill.Account == null)
                    {
                        continue;
                    }
                    var contribution = 0.0m;
                    switch (bill.PaymentFrequency)
                    {
                    case FrequencyEnum.Annually:
                        contribution = billTotal / 24;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.SemiAnnually:
                        contribution = billTotal / 12;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.Quarterly:
                        contribution = billTotal / 6;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.SemiMonthly:     // every 2 months
                        contribution = billTotal / 4;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.Monthly:
                        contribution = billTotal / 2;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.Weekly:
                        contribution = billTotal * 2;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.BiWeekly:
                        contribution = billTotal;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;

                    case FrequencyEnum.Daily:
                        break;

                    default:
                        contribution = billTotal / 2;
                        if (accountContribution.ContainsKey(bill.Account.Name))
                        {
                            accountContribution[bill.Account.Name] += contribution;
                        }
                        else
                        {
                            accountContribution.Add(bill.Account.Name, contribution);
                        }
                        Logger.Instance.Calculation($"{Math.Round(contribution, 2)} added to {bill.Account.Name}.SuggestedContribution");
                        break;
                    }
                }

                return(accountContribution);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
Beispiel #6
0
        /// <summary>
        /// Updates database Bills.DueDate if the previous due date has passed
        /// </summary>
        public void UpdateBillDueDates()
        {
            try
            {
                Logger.Instance.Calculation($"UpdateBillDueDates");
                var billManager = new BillManager();
                var bills       = billManager.GetAllBills();
                var beginDate   = DateTime.Today;

                foreach (var bill in bills)
                {
                    if (bill.DueDate.Date > beginDate)
                    {
                        continue;
                    }

                    var frequency  = bill.PaymentFrequency;
                    var dueDate    = bill.DueDate;
                    var newDueDate = dueDate;

                    /* Updates bill due date to the current due date
                     * while loop handles due date updates, regardless of how out of date they are */
                    while (newDueDate < beginDate)
                    {
                        switch (frequency)
                        {
                        case FrequencyEnum.Daily:
                            newDueDate = newDueDate.AddDays(1);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Weekly:
                            newDueDate = newDueDate.AddDays(7);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.BiWeekly:
                            newDueDate = newDueDate.AddDays(14);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Monthly:
                            newDueDate = newDueDate.AddMonths(1);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.SemiMonthly:
                            newDueDate = newDueDate.AddDays(15);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Quarterly:
                            newDueDate = newDueDate.AddMonths(3);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.SemiAnnually:
                            newDueDate = newDueDate.AddMonths(6);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Annually:
                            newDueDate = newDueDate.AddYears(1);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                    bill.DueDate          = newDueDate;
                    _db.Entry(bill).State = EntityState.Modified;
                    Logger.Instance.Calculation($"{bill.Name} due date of {dueDate:d} updated to {newDueDate:d}");

                    if (!AddNewExpenseToDb(bill))
                    {
                        return;
                    }
                }


                _db.SaveChanges();
            }
            catch (Exception e)
            {
                Logger.Instance.Error(e);
            }
        }
Beispiel #7
0
        //TODO: Improve date range handling
        /// <summary>
        /// Returns summation of bills within the date range of the begin and end parameters
        /// </summary>
        /// <param name="begin">start date of the date range</param>
        /// <param name="end">end date of the date range</param>
        /// <param name="onlyMandatory">sumates only mandatory expenses</param>
        /// <returns></returns>
        public decimal ExpensesByDateRange(DateTime begin, DateTime end, bool onlyMandatory = false)
        {
            try
            {
                Logger.Instance.Calculation($"Expenses by DateRange");
                var billManager = new BillManager();
                var bills       = billManager.GetAllBills();
                var expenses    = 0m;

                foreach (var bill in bills)
                {
                    //if (bill.DueDate.Date < beginDate) continue;

                    var frequency  = bill.PaymentFrequency;
                    var dueDate    = bill.DueDate;
                    var newDueDate = dueDate;
                    Logger.Instance.Calculation($"{bill.Name} original due date is {dueDate:d}");
                    //TODO: Fix semi-monthly bills being added 3 times (31st, 16th, 1st)
                    while (newDueDate >= begin)
                    {
                        switch (frequency)
                        {
                        case FrequencyEnum.Daily:
                            newDueDate = newDueDate.AddDays(-1);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.Weekly:
                            newDueDate = newDueDate.AddDays(-7);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.BiWeekly:
                            newDueDate = newDueDate.AddDays(-14);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.Monthly:
                            newDueDate = newDueDate.AddMonths(-1);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.SemiMonthly:
                            newDueDate = newDueDate.AddDays(-15);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.Quarterly:
                            newDueDate = newDueDate.AddMonths(-3);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.SemiAnnually:
                            newDueDate = newDueDate.AddMonths(-6);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        case FrequencyEnum.Annually:
                            newDueDate = newDueDate.AddYears(-1);
                            Logger.Instance.Calculation($"{bill.Name} new due date is {newDueDate:d}");
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        // adds expense only if the bill due date falls within the date range
                        if (newDueDate < begin || newDueDate >= end)
                        {
                            continue;
                        }
                        expenses += bill.AmountDue;
                        Logger.Instance.Calculation($"Expenses: {expenses} added to {bill.Name}.AmountDue");
                    }
                }
                return(expenses);
            }
            catch (Exception e)
            {
                Logger.Instance.Error(e);
                return(0.0m);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Returns Dictionary with due dates for all bills for calculating all expenses within a timeframe.  Used for calculating future savings
        /// </summary>
        /// <param name="billsDictionary"></param>
        /// <returns></returns>
        private Dictionary <string, string> UpdateBillDueDates(Dictionary <string, string> billsDictionary)
        {
            try
            {
                Logger.Instance.Calculation($"UpdateBillDueDates");
                var billManager = new BillManager();
                var bills       = billManager.GetAllBills();
                var beginDate   = Convert.ToDateTime(billsDictionary["currentDate"]);

                foreach (var bill in bills)
                {
                    if (bill.DueDate.Date > beginDate)
                    {
                        continue;
                    }

                    var frequency  = bill.PaymentFrequency;
                    var dueDate    = bill.DueDate;
                    var newDueDate = dueDate;
                    Logger.Instance.Calculation($"{bill.Name} due date {dueDate:d}");
                    while (newDueDate < beginDate)
                    {
                        switch (frequency)
                        {
                        case FrequencyEnum.Daily:
                            newDueDate = newDueDate.AddDays(1);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Weekly:
                            newDueDate = newDueDate.AddDays(7);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.BiWeekly:
                            newDueDate = newDueDate.AddDays(14);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Monthly:
                            newDueDate = newDueDate.AddMonths(1);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.SemiMonthly:
                            newDueDate = newDueDate.AddDays(15);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Quarterly:
                            newDueDate = newDueDate.AddMonths(3);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.SemiAnnually:
                            newDueDate = newDueDate.AddMonths(6);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        case FrequencyEnum.Annually:
                            newDueDate = newDueDate.AddYears(1);
                            Logger.Instance.Calculation($"New due date {newDueDate:d}");
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        billsDictionary[bill.Name] = newDueDate.ToShortDateString();
                        Logger.Instance.Calculation($"Set due date {newDueDate:d}");
                    }
                }
                return(billsDictionary);
            }
            catch (Exception e)
            {
                Logger.Instance.Error(e);
                return(null);
            }
        }