Beispiel #1
0
        private Entities.Budget CloneBudget(Entities.Budget source, int workbookId,
                                            DateTime periodStartDate, DateTime periodEndDate)
        {
            // If there is no old budget (i.e. this is the first one we're creating),
            // then there's nothing to clone - create a new one.
            //
            if (source == null)
            {
                return(this.CreateNewBudget(workbookId, periodStartDate, periodEndDate));
            }

            source.BudgetItemList = this.budgetItemRepository
                                    .GetList(q => q.Where(x => x.Budget.Id == source.Id))
                                    .ToList();

            // Generate actual amounts for the old budget - because we'll use those to
            // populate the budgeted amounts for the new budget.
            //
            var actualAmountDictionary = this.financeTransactionRepository
                                         .GetFor <IDictionary <int, decimal> >(
                q => q
                .Where(x => x.Workbook.Id == source.Workbook.Id &&
                       x.TransactionDate >= source.PeriodStartDate &&
                       x.TransactionDate <= source.PeriodEndDate)
                .Select(x => new { x.BudgetHeading.Id, x.Amount })
                .ToList()
                .GroupBy(x => x.Id)
                .ToDictionary(x => x.Key, x => x.Select(y => y.Amount).Sum()));

            var budget = new Entities.Budget
            {
                Workbook        = source.Workbook,
                PeriodStartDate = periodStartDate,
                PeriodEndDate   = periodEndDate,
                BudgetItemList  = source.BudgetItemList
                                  .Select(x => new Entities.BudgetItem
                {
                    BudgetHeading = x.BudgetHeading,
                    Amount        =
                        actualAmountDictionary.ContainsKey(x.BudgetHeading.Id)
                                ? actualAmountDictionary[x.BudgetHeading.Id]
                                : 0
                })
                                  .ToList()
            };

            HandleAnnualizedAndSurplus(source, budget, actualAmountDictionary);

            return(budget);
        }
Beispiel #2
0
        private static void HandleAnnualizedAndSurplus(Entities.Budget oldBudget, Entities.Budget newBudget,
                                                       IDictionary <int, decimal> actualAmountDictionary)
        {
            // Annualized headings and surplus/deficit items need special care.
            // Surplus/deficit on annualized headings don't contribute to the overall surplus, they
            // are handled individually.

            var oldAnnualizedItems = oldBudget.BudgetItemList.Where(x => x.BudgetHeading.IsAnnualized);

            decimal overallSurplusToSubtract = 0;

            foreach (var oldAnnualizedItem in oldAnnualizedItems)
            {
                var actualAmount = actualAmountDictionary.ContainsKey(oldAnnualizedItem.BudgetHeading.Id)
                                       ? actualAmountDictionary[oldAnnualizedItem.BudgetHeading.Id]
                                       : 0;

                var surplus = oldAnnualizedItem.Amount - actualAmount;

                var newAnnualizedItem = newBudget.BudgetItemList.FirstOrDefault(
                    x => x.BudgetHeading.Id == oldAnnualizedItem.BudgetHeading.Id);

                if (newAnnualizedItem == null)
                {
                    continue;
                }

                newAnnualizedItem.Amount += surplus;
                overallSurplusToSubtract += surplus;
            }

            var oldEndingSurplus = oldBudget.BudgetItemList
                                   .Where(x => x.BudgetHeading.IsEndingSurplus)
                                   .Select(x => x.Amount)
                                   .Sum();

            oldEndingSurplus -= overallSurplusToSubtract;

            var newBeginningSurplusItem =
                newBudget.BudgetItemList.FirstOrDefault(x => x.BudgetHeading.IsBeginningSurplus);

            if (newBeginningSurplusItem != null)
            {
                newBeginningSurplusItem.Amount = oldEndingSurplus;
            }

            newBudget.BudgetItemList
            .Where(x => x.BudgetHeading.IsEndingSurplus)
            .ForEach(x => x.Amount = 0);
        }
Beispiel #3
0
        public Budget GetBudget(string userName, int id)
        {
            this.logger.Verbose(string.Format("Retrieving budget {0} for user {1}...", id, userName));

            Entities.Budget            budgetEntity           = null;
            IDictionary <int, decimal> actualAmountDictionary = null;

            try
            {
                this.Database.With(
                    this.budgetRepository,
                    this.budgetItemRepository,
                    this.financeTransactionRepository).Execute(
                    unit =>
                {
                    budgetEntity = this.budgetRepository.Get(id);
                    budgetEntity.BudgetItemList = this.budgetItemRepository
                                                  .GetList(q => q.Where(x => x.Budget.Id == id).ToList())
                                                  .ToList();

                    // Actual amounts are calculated on the fly from transactions within the
                    // same workbook that fall within the budget period. Each transaction has
                    // a budget heading.
                    //
                    actualAmountDictionary = this.financeTransactionRepository
                                             .GetFor <IDictionary <int, decimal> >(
                        q => q
                        .Where(x => x.Workbook.Id == budgetEntity.Workbook.Id &&
                               x.TransactionDate >= budgetEntity.PeriodStartDate &&
                               x.TransactionDate <= budgetEntity.PeriodEndDate)
                        .Select(x => new { x.BudgetHeading.Id, x.Amount })
                        .ToList()
                        .GroupBy(x => x.Id)
                        .ToDictionary(x => x.Key, x => x.Select(y => y.Amount).Sum()));
                });
            }
            catch (Exception ex)
            {
                ex.WrapLogAndThrow <ServiceException, ServiceErrorCodes>(ServiceErrorCodes.GetBudgetError);
            }

            Debug.Assert(budgetEntity != null);
            this.authorizationService.Authorize(userName, budgetEntity.Workbook.Id);

            return(budgetEntity.ToDc(actualAmountDictionary));
        }
        public static Budget ToDc(this Entities.Budget entity, IDictionary <int, decimal> actualAmountDictionary)
        {
            var budget = new Budget
            {
                WorkbookId     = entity.Workbook.Id,
                Id             = entity.Id,
                BudgetName     = entity.PeriodStartDate.ToString("MM/dd/yyyy") + " - " + entity.PeriodEndDate.ToString("MM/dd/yyyy"),
                BudgetItemList = entity.BudgetItemList
                                 .Select(x => new BudgetItem
                {
                    Id = x.Id,
                    IsMoneyComingIn   = x.BudgetHeading.BudgetHeadingType.IsMoneyComingIn,
                    BudgetHeading     = x.BudgetHeading.Name,
                    BudgetHeadingType = x.BudgetHeading.BudgetHeadingType.Name,
                    BudgetAmount      = x.Amount,
                    ActualAmount      =
                        actualAmountDictionary.ContainsKey(x.BudgetHeading.Id)
                                ? actualAmountDictionary[x.BudgetHeading.Id]
                                : 0
                })
                                 .OrderBy(x => x.IsMoneyComingIn ? 1 : 2)
                                 .ThenBy(x => x.BudgetHeadingType)
                                 .ThenBy(x => x.BudgetHeading)
                                 .ToList()
            };

            budget.BudgetHeadingList = budget.BudgetItemList
                                       .Select(x => x.BudgetHeading)
                                       .Distinct()
                                       .ToList();

            budget.BudgetHeadingTypeList = budget.BudgetItemList
                                           .Select(x => x.BudgetHeadingType)
                                           .Distinct()
                                           .ToList();

            return(budget);
        }