public static BudgetPlanDetails CreateBudgetPlanEditModel(List <ExpenseTypeList> expenditureTypes)
        {
            var model = new BudgetPlanDetails()
            {
                ExpenseTypes = new List <BudgetPlanExpenseType>()
            };

            foreach (var expenditureType in expenditureTypes)
            {
                model.ExpenseTypes.Add(new BudgetPlanExpenseType()
                {
                    ExpenseType   = expenditureType,
                    ExpectedValue = 100
                });
            }

            return(model);
        }
Exemple #2
0
        /// <summary>
        /// Create a budget plan.
        /// </summary>
        /// <param name="budgetPlanDetails"></param>
        /// <param name="accountId"></param>
        public void CreateBudgetPlan(BudgetPlanDetails budgetPlanDetails, int accountId)
        {
            var budgetPlan = Mapper.Map <BudgetPlan>(budgetPlanDetails);

            _budgetPlanRepository.Create(budgetPlan);

            foreach (var ExpenseType in budgetPlanDetails.ExpenseTypes)
            {
                var plannedExpense = new BudgetByExpenseType
                {
                    Budget        = ExpenseType.ExpectedValue,
                    ExpenseTypeId = ExpenseType.ExpenseType.Id,
                    BudgetPlanId  = budgetPlan.Id,
                    AccountId     = accountId
                };

                // Account ID is defined at BudgetByExpenseType time because at first, I wanted to plan budget through several accounts.
                // It might evolve later so for now, I keep it here, independently from BudgetByExpenseType.

                _budgetByExpenseTypeRepository.Create(plannedExpense);
            }
        }
Exemple #3
0
        /// <summary>
        /// Edit a budget plan.
        /// </summary>
        /// <param name="budgetPlanDetails"></param>
        /// <param name="accountId"></param>
        public void EditBudgetPlan(BudgetPlanDetails budgetPlanDetails, int accountId)
        {
            var budgetPlan = _budgetPlanRepository.GetById(budgetPlanDetails.Id);

            budgetPlan.Name            = budgetPlanDetails.Name;
            budgetPlan.ExpectedIncomes = budgetPlanDetails.ExpectedIncomes;
            budgetPlan.ExpectedSavings = budgetPlanDetails.ExpectedSavings;
            _budgetPlanRepository.Update(budgetPlan);

            var existingBudgetPlanExpenses = _budgetByExpenseTypeRepository.GetList2(x => x.ExpenseType)
                                             .Where(x => x.BudgetPlanId == budgetPlanDetails.Id);

            foreach (var budgetExpenseType in budgetPlanDetails.ExpenseTypes)
            {
                var existingBudgetExpenseType = existingBudgetPlanExpenses.SingleOrDefault(x => x.ExpenseType.Id == budgetExpenseType.ExpenseType.Id);

                if (existingBudgetExpenseType == null)
                {
                    // Add
                    var plannedExpense = new BudgetByExpenseType()
                    {
                        Budget        = budgetExpenseType.ExpectedValue,
                        ExpenseTypeId = budgetExpenseType.ExpenseType.Id,
                        BudgetPlanId  = budgetPlanDetails.Id,
                        AccountId     = accountId
                    };
                    _budgetByExpenseTypeRepository.Create(plannedExpense);
                }
                else
                {
                    // Update
                    existingBudgetExpenseType.Budget = budgetExpenseType.ExpectedValue;
                    _budgetByExpenseTypeRepository.Update(existingBudgetExpenseType);
                }
            }
        }
        public ExpenseSummary GetExpenseSummary(int accountId, BudgetPlanDetails budgetPlan)
        {
            var account = _bankAccountRepository.GetById(accountId, x => x.Bank, x => x.Currency);

            if (account == null)
            {
                throw new ArgumentException("Account can't be null.");
            }

            var today = DateTime.Now;
            var over12MonthsInterval = new Interval(today, DateTimeUnitEnums.Years, 1);
            var over6MonthsInterval  = new Interval(today, DateTimeUnitEnums.Months, 6);
            var currentMonthInterval = new Interval(today, today);
            var previousInterval     = new Interval(today, DateTimeUnitEnums.Months, 1);

            var categories = _ExpenseTypeRepository.GetList2().GroupBy(x => x.Id).ToDictionary(x => x.Key, y => y.Single());

            var over12MonthsNames = over12MonthsInterval.GetIntervalsByMonth();
            var currentMonthName  = currentMonthInterval.GetSingleMonthName();

            // Retrieve both current month expenses and over 12 months expenses
            var expenses = GetExpenses(new PFM.Services.DTOs.SearchParameters.ExpenseGetListSearchParameters
            {
                AccountId = accountId,
                StartDate = over12MonthsInterval.StartDate,
                EndDate   = currentMonthInterval.EndDate
            });

            // Reset the start date to the first movement (First day of the same month)
            over12MonthsInterval.StartDate = DateTimeFormatHelper.GetFirstDayOfMonth(
                expenses.Any() ?
                expenses.OrderBy(x => x.DateExpense).First().DateExpense :
                today);

            // Count the number of months in the interval
            var nbMonthInterval = over12MonthsInterval.Count(DateTimeUnitEnums.Months);

            if (nbMonthInterval == 0)
            {
                nbMonthInterval = 1; // No expenses -> no division by zero
            }
            // Get current budget plan if it exists
            var budgetPlanByCategory =
                budgetPlan?.ExpenseTypes.GroupBy(x => x.ExpenseType.Id).ToDictionary(x => x.Key, y => y.Single().ExpectedValue)
                ?? categories.ToDictionary(x => x.Key, y => (decimal)0.00);

            var expensesByCategories = expenses.Any()
                ? expenses.GroupBy(x => x.ExpenseTypeId).ToDictionary(x => x.Key, y => y.ToList())
                : categories.ToDictionary(x => x.Key, y => new List <ExpenseList>());

            var expensesByCategory = new List <ExpenseSummaryByCategory>();

            foreach (var exp in expensesByCategories)
            {
                var category              = categories[exp.Key];
                var expensesCurrentMonth  = exp.Value.Where(x => currentMonthInterval.IsBetween(x.DateExpense)).ToList();
                var expensesPreviousMonth = exp.Value.Where(x => previousInterval.IsBetween(x.DateExpense)).ToList();
                var expensesOver12Months  = exp.Value.Where(x => over12MonthsInterval.IsBetween(x.DateExpense)).ToList();

                // ReSharper disable once UseObjectOrCollectionInitializer
                var expenseSummary = new ExpenseSummaryByCategory();
                expenseSummary.CurrencySymbol          = account.Currency.Symbol;
                expenseSummary.CategoryId              = category.Id;
                expenseSummary.CategoryName            = category.Name;
                expenseSummary.CategoryColor           = category.GraphColor;
                expenseSummary.CostCurrentMonth        = expensesCurrentMonth.Sum(x => x.Cost);
                expenseSummary.CostPreviousMonth       = expensesPreviousMonth.Sum(x => x.Cost);
                expenseSummary.CostPlannedMonthly      = budgetPlanByCategory.ContainsKey(exp.Key) ? budgetPlanByCategory[exp.Key] : 0;
                expenseSummary.CostOver12Month         = expensesOver12Months.Sum(x => x.Cost);
                expenseSummary.AverageCostOver12Months = expenseSummary.CostOver12Month / nbMonthInterval;

                // Retrieve the expenses per months (details and summary)
                foreach (var month in over12MonthsNames)
                {
                    var interval   = month.Value;
                    var expByMonth = exp.Value.Where(x => interval.IsBetween(x.DateExpense)).ToList();

                    expenseSummary.Expenses.Add(month.Key, expByMonth);
                    expenseSummary.ExpensesByMonth.Add(month.Key, new ExpenseSummaryByCategoryAndByMonth(expByMonth.Sum(x => x.Cost)));
                }
                expenseSummary.Expenses.Add(currentMonthName, expensesCurrentMonth);
                expenseSummary.ExpensesByMonth.Add(currentMonthName, new ExpenseSummaryByCategoryAndByMonth(expensesCurrentMonth.Sum(x => x.Cost)));

                expensesByCategory.Add(expenseSummary);
            }

            var totalExpensesOver12Months = expenses.Where(x => over12MonthsInterval.IsBetween(x.DateExpense)).Sum(x => x.Cost);

            // Get actual/expected expenses by month for last 12 Months
            var budgetPlanExpenses           = budgetPlanByCategory.Values.Sum(x => x);
            var detailedExpensesOver12Months = new Dictionary <string, ExpenseSummaryByMonth>();

            foreach (var month in over12MonthsNames)
            {
                var interval   = month.Value;
                var expByMonth = expenses.Where(x => interval.IsBetween(x.DateExpense)).Sum(x => x.Cost);
                detailedExpensesOver12Months.Add(month.Key, new ExpenseSummaryByMonth()
                {
                    ExpenseValue         = expByMonth,
                    ExpenseExpectedValue = budgetPlanExpenses
                });
            }
            detailedExpensesOver12Months.Add(currentMonthName, new ExpenseSummaryByMonth()
            {
                ExpenseValue         = expenses.Where(x => currentMonthInterval.IsBetween(x.DateExpense)).Sum(x => x.Cost),
                ExpenseExpectedValue = budgetPlanExpenses
            });

            var incomes = _incomeRepository.GetList2().Where(x => x.AccountId == accountId && x.DateIncome >= over12MonthsInterval.StartDate && x.DateIncome < currentMonthInterval.EndDate).ToList();
            var savings = _savingRepository.GetList2().Where(x => x.AccountId == accountId && x.DateSaving >= over12MonthsInterval.StartDate && x.DateSaving < currentMonthInterval.EndDate).ToList();

            // Get the incomes/expenses/savings by month for last 6 months
            var over6MonthsNames             = over6MonthsInterval.GetIntervalsByMonth();
            var detailedMovementsOver6Months = new Dictionary <string, ExpenseSummaryByMonth>();

            foreach (var month in over6MonthsNames)
            {
                var interval      = month.Value;
                var incomeByMonth = incomes.Where(x => interval.IsBetween(x.DateIncome)).Sum(x => x.Cost);
                var savingByMonth = savings.Where(x => interval.IsBetween(x.DateSaving)).Sum(x => x.Amount);
                detailedMovementsOver6Months.Add(month.Key, new ExpenseSummaryByMonth()
                {
                    ExpenseValue = detailedExpensesOver12Months[month.Key].ExpenseValue,
                    IncomeValue  = incomeByMonth,
                    SavingValue  = savingByMonth
                });
            }
            detailedMovementsOver6Months.Add(currentMonthName, new ExpenseSummaryByMonth()
            {
                ExpenseValue = detailedExpensesOver12Months[currentMonthName].ExpenseValue,
                IncomeValue  = incomes.Where(x => currentMonthInterval.IsBetween(x.DateIncome)).Sum(x => x.Cost),
                SavingValue  = savings.Where(x => currentMonthInterval.IsBetween(x.DateSaving)).Sum(x => x.Amount)
            });

            var ExpenseSummary = new ExpenseSummary()
            {
                Account                      = Mapper.Map <AccountDetails>(account),
                ExpensesByCategory           = expensesByCategory.OrderByDescending(x => x.CostCurrentMonth).ToList(),
                LabelCurrentMonth            = DateTimeFormatHelper.GetMonthNameAndYear(today),
                LabelPreviousMonth           = DateTimeFormatHelper.GetMonthNameAndYear(today.AddMonths(-1)),
                BudgetPlanName               = budgetPlan != null ? budgetPlan.Name : string.Empty,
                AccountName                  = account.Name,
                DisplayDashboard             = true,
                CurrencySymbol               = account.Currency.Symbol,
                HasCurrentBudgetPlan         = budgetPlan != null,
                HasExpenses                  = expenses.Any(),
                HasCategories                = categories.Any(),
                TotalExpensesOver12Months    = totalExpensesOver12Months,
                DetailedExpensesOver12Months = detailedExpensesOver12Months,
                DetailedMovementsOver6Months = detailedMovementsOver6Months,
                CurrentMonthTotalExpense     = expenses.Where(x => currentMonthInterval.IsBetween(x.DateExpense)).Sum(x => x.Cost),
                AverageExpenses              = expenses.Where(x => over12MonthsInterval.IsBetween(x.DateExpense)).Sum(x => x.Cost) / nbMonthInterval,
                AverageIncomes               = incomes.Where(x => over12MonthsInterval.IsBetween(x.DateIncome)).Sum(x => x.Cost) / nbMonthInterval,
                AverageSavings               = savings.Where(x => over12MonthsInterval.IsBetween(x.DateSaving)).Sum(x => x.Amount) / nbMonthInterval
            };

            return(ExpenseSummary);
        }
Exemple #5
0
        public BudgetPlanDetails BuildBudgetPlan(int accountId, int?budgetPlanId = null)
        {
            var currencySymbol = _bankAccountRepository.GetById(accountId, x => x.Currency).Currency.Symbol;

            var today = DateTime.Now;
            var over12MonthsInterval = new Interval(today, DateTimeUnitEnums.Years, 1);
            var previousInterval     = new Interval(today, DateTimeUnitEnums.Months, 1);
            var firstOfNextMonth     = DateTimeFormatHelper.GetFirstDayOfMonth(today.AddMonths(1));

            // Retrieve the categories
            var categories = _ExpenseTypeRepository.GetList2().GroupBy(x => x.Id).ToDictionary(x => x.Key, y => y.Single());

            // Retrieve the expenses over the last 12 months (excluding current month)
            var expensesOver12Months = _ExpenseRepository.GetByParameters(new ExpenseGetListSearchParameters()
            {
                AccountId = accountId,
                StartDate = over12MonthsInterval.StartDate,
                EndDate   = over12MonthsInterval.EndDate
            });

            // Group by category the expenses over the last 12 months
            var expensesOver12MonthsByCategory = expensesOver12Months.GroupBy(x => x.ExpenseTypeId).ToDictionary(x => x.Key, y => y.ToList());

            over12MonthsInterval.StartDate = DateTimeFormatHelper.GetFirstDayOfMonth(
                expensesOver12Months.Any() ?
                expensesOver12Months.OrderBy(x => x.DateExpense).First().DateExpense :
                today);

            var nbMonthInterval = over12MonthsInterval.Count(DateTimeUnitEnums.Months);

            if (nbMonthInterval == 0)
            {
                nbMonthInterval = 1; // No expenses -> no division by zero
            }
            // Retrieve the expenses last months and group by category
            var lastMonthExpenses           = expensesOver12Months.Where(x => previousInterval.IsBetween(x.DateExpense)).ToList();
            var lastMonthExpensesByCategory = lastMonthExpenses.GroupBy(x => x.ExpenseTypeId).ToDictionary(x => x.Key, y => y.ToList());

            // Get the current Budget Plan for the account. If none, returns a default of cost of 0.00
            var currentBudgetPlan           = GetCurrent(accountId);
            var currentBudgetPlanByCategory = currentBudgetPlan?.ExpenseTypes
                                              .GroupBy(x => x.ExpenseType.Id)
                                              .ToDictionary(x => x.Key, y => y.Single().ExpectedValue);

            // Get the existing Budget Plan for the provided ID. If none, returns a default of cost of 0.00
            var existingBudgetPlan           = budgetPlanId.HasValue ? GetById(budgetPlanId.Value) : null;
            var existingBudgetPlanByCategory = existingBudgetPlan?.ExpenseTypes.GroupBy(x => x.ExpenseType.Id).ToDictionary(x => x.Key, y => y.Single().ExpectedValue);

            BudgetPlanDetails budgetPlan = null;

            if (existingBudgetPlan != null)
            {
                budgetPlan = new BudgetPlanDetails()
                {
                    Id                   = existingBudgetPlan.Id,
                    Name                 = existingBudgetPlan.Name,
                    ExpenseTypes         = new List <BudgetPlanExpenseType>(),
                    CurrencySymbol       = currencySymbol,
                    StartDate            = existingBudgetPlan.StartDate,
                    EndDate              = existingBudgetPlan.EndDate,
                    PlannedStartDate     = firstOfNextMonth,
                    HasCurrentBudgetPlan = currentBudgetPlan != null,
                    BudgetPlanName       = currentBudgetPlan?.Name
                };
            }
            else
            {
                budgetPlan = new BudgetPlanDetails()
                {
                    ExpenseTypes         = new List <BudgetPlanExpenseType>(),
                    CurrencySymbol       = currencySymbol,
                    HasCurrentBudgetPlan = currentBudgetPlan != null,
                    BudgetPlanName       = currentBudgetPlan?.Name
                };
            }

            foreach (var category in categories)
            {
                var expectedValue = 0.00M; var currentBudgetPlanValue = 0.00M;

                if (currentBudgetPlan != null)
                {
                    currentBudgetPlanValue = currentBudgetPlanByCategory.ContainsKey(category.Key)
                                                ? currentBudgetPlanByCategory[category.Key]
                                                : 0.00M;
                }

                if (existingBudgetPlan != null)
                {
                    expectedValue = existingBudgetPlanByCategory.ContainsKey(category.Key)
                                        ? existingBudgetPlanByCategory[category.Key]
                                        : 0.00M;
                }
                else if (currentBudgetPlan != null)
                {
                    expectedValue = currentBudgetPlanValue;
                }

                var previousMonthValue = lastMonthExpensesByCategory.ContainsKey(category.Key)
                                            ? lastMonthExpensesByCategory[category.Key].Sum(x => x.Cost)
                                            : 0.00M;

                var averageMonthValue = expensesOver12MonthsByCategory.ContainsKey(category.Key)
                                            ? expensesOver12MonthsByCategory[category.Key].Sum(x => x.Cost)
                                            : 0.00M;

                var mappedCategory = Mapper.Map <ExpenseTypeList>(category.Value);

                var budgetPlanByCategory = new BudgetPlanExpenseType
                {
                    CurrencySymbol         = budgetPlan.CurrencySymbol,
                    ExpenseType            = mappedCategory,
                    ExpectedValue          = expectedValue,
                    PreviousMonthValue     = previousMonthValue,
                    CurrentBudgetPlanValue = currentBudgetPlanValue,
                    AverageMonthValue      = averageMonthValue / nbMonthInterval
                };

                budgetPlan.ExpenseTypes.Add(budgetPlanByCategory);
            }

            budgetPlan.ExpensePreviousMonthValue     = lastMonthExpenses.Sum(x => x.Cost);
            budgetPlan.ExpenseAverageMonthValue      = expensesOver12Months.Sum(x => x.Cost) / nbMonthInterval;
            budgetPlan.ExpenseCurrentBudgetPlanValue = currentBudgetPlan?.ExpenseTypes.Sum(x => x.ExpectedValue);

            var incomes = _incomeRepository.GetList2().Where(x => x.AccountId == accountId).ToList();

            budgetPlan.IncomeCurrentBudgetPlanValue = currentBudgetPlan?.ExpectedIncomes;
            budgetPlan.IncomePreviousMonthValue     = incomes.Where(x => previousInterval.IsBetween(x.DateIncome)).Sum(x => x.Cost);
            budgetPlan.IncomeAverageMonthValue      = incomes.Where(x => over12MonthsInterval.IsBetween(x.DateIncome)).Sum(x => x.Cost) / nbMonthInterval;

            budgetPlan.ExpectedIncomes = existingBudgetPlan?.ExpectedIncomes ?? budgetPlan.IncomePreviousMonthValue;

            var savings = _savingRepository.GetList2().Where(x => x.AccountId == accountId).ToList();

            budgetPlan.SavingCurrentBudgetPlanValue = currentBudgetPlan?.ExpectedSavings;
            budgetPlan.SavingPreviousMonthValue     = savings.Where(x => previousInterval.IsBetween(x.DateSaving)).Sum(x => x.Amount);
            budgetPlan.SavingAverageMonthValue      = savings.Where(x => over12MonthsInterval.IsBetween(x.DateSaving)).Sum(x => x.Amount) / nbMonthInterval;

            budgetPlan.ExpectedSavings = existingBudgetPlan?.ExpectedSavings ?? budgetPlan.SavingPreviousMonthValue;

            return(budgetPlan);
        }
Exemple #6
0
 public ExpenseSummary GetExpenseSummary(int accountId, [FromBody] BudgetPlanDetails budgetPlan)
 {
     return(_ExpenseService.GetExpenseSummary(accountId, budgetPlan));
 }
 public void Edit(int accountId, [FromBody] BudgetPlanDetails budgetPlanDetails)
 {
     _BudgetPlanService.EditBudgetPlan(budgetPlanDetails, accountId);
 }
 public void Create(int accountId, [FromBody] BudgetPlanDetails budgetPlanDetails)
 {
     _BudgetPlanService.CreateBudgetPlan(budgetPlanDetails, accountId);
 }