private ActionResult WithCategoryAndBudgetItem(int budgetId,
                                                       CategoryToBudgetItemViewModel viewModel,
                                                       Func <Budget, BudgetItem, Category, ActionResult> work)
        {
            var budget = GetBudget(budgetId);

            if (TryValidateModel(viewModel))
            {
                var item = budget.Items.SingleOrDefault(x => x.Id == viewModel.ItemId);
                if (item == null)
                {
                    ModelState.AddModelError("ItemId", $"Budget item '{viewModel.ItemId}' does not belong to this budget");
                }
                var category = Db.Categories.SingleOrDefault(x => x.Id == viewModel.CategoryId);
                if (category == null)
                {
                    ModelState.AddModelError("CategoryId", $"Unknown category '{viewModel.CategoryId}'.");
                }
                if (ModelState.IsValid)
                {
                    return(work(budget, item, category));
                }
            }
            return(ValidationErrorsAsJson());
        }
 public ActionResult RemoveCategory(int id, CategoryToBudgetItemViewModel viewModel)
 {
     return(WithCategoryAndBudgetItem(id, viewModel, (budget, item, category) =>
     {
         item.Categories.Remove(category);
         Db.SaveChanges();
         return Json("OK");
     }));
 }
 public ActionResult AddCategory(int id, CategoryToBudgetItemViewModel viewModel)
 {
     return(WithCategoryAndBudgetItem(id, viewModel, (budget, item, category) =>
     {
         foreach (var cat in category.Children)
         {
             item.Categories.Add(cat);
         }
         Db.SaveChanges();
         return Json("OK");
     }));
 }