def budgets(year=None): """Manage budgets""" # Make sure the year from route is valid if year: currentYear = datetime.now().year if not 2020 <= year <= currentYear: return apology( f"Please select a valid budget year: 2020 through {currentYear}" ) else: # Set year to current year if it was not in the route (this will set UX to display current years budgets) year = datetime.now().year # User reached route via GET if request.method == "GET": # Get the users income income = tendie_account.getIncome(session["user_id"]) # Get the users current budgets budgets = tendie_budgets.getBudgets(session["user_id"]) # Get the users total budgeted amount budgeted = tendie_budgets.getTotalBudgetedByYear( session["user_id"], year) return render_template("budgets.html", income=income, budgets=budgets, year=year, budgeted=budgeted, deletedBudgetName=None) # User reached route via POST else: # Get the name of the budget the user wants to delete budgetName = request.form.get("delete").strip() # Delete the budget deletedBudgetName = tendie_budgets.deleteBudget( budgetName, session["user_id"]) # Render the budgets page with a success message, otherwise throw an error/apology if deletedBudgetName: # Get the users income, current budgets, and sum their budgeted amount unless they don't have any budgets (same steps as a GET for this route) income = tendie_account.getIncome(session["user_id"]) budgets = tendie_budgets.getBudgets(session["user_id"]) budgeted = tendie_budgets.getTotalBudgetedByYear( session["user_id"], year) return render_template("budgets.html", income=income, budgets=budgets, year=year, budgeted=budgeted, deletedBudgetName=deletedBudgetName) else: return apology("Uh oh! Your budget could not be deleted.")
def budgets(): """Manage budgets""" # User reached route via GET if request.method == "GET": # Get the users income income = tendie_account.getIncome(session["user_id"]) # Get the users current budgets budgets = tendie_budgets.getBudgets(session["user_id"]) # Get the users total budgeted amount budgeted = tendie_budgets.getTotalBudgeted(session["user_id"]) return render_template("budgets.html", income=income, budgets=budgets, budgeted=budgeted, deletedBudgetName=None) # User reached route via POST else: # Get the name of the budget the user wants to delete budgetName = request.form.get("delete").strip() # Delete the budget deletedBudgetName = tendie_budgets.deleteBudget( budgetName, session["user_id"]) # Render the budgets page with a success message, otherwise throw an error/apology if deletedBudgetName: # Get the users income, current budgets, and sum their budgeted amount unless they don't have any budgets (same steps as a GET for this route) income = tendie_account.getIncome(session["user_id"]) budgets = tendie_budgets.getBudgets(session["user_id"]) budgeted = tendie_budgets.getTotalBudgeted(session["user_id"]) return render_template("budgets.html", income=income, budgets=budgets, budgeted=budgeted, deletedBudgetName=deletedBudgetName) else: return apology("Uh oh! Your budget could not be deleted.")
def createbudget(): """Create a budget""" # User reached route via POST if request.method == "POST": # Make sure user has no more than 20 budgets (note: 20 is an arbitrary value) if tendie_budgets.getBudgets(session["user_id"]) is not None: budgetCount = len(tendie_budgets.getBudgets(session["user_id"])) if budgetCount >= 20: return apology("You've reached the max amount of budgets'") # Get all of the budget info provided from the HTML form formData = list(request.form.items()) # Generate data structure to hold budget info from form budgetDict = tendie_budgets.generateBudgetFromForm(formData) # Render error message if budget name or categories contained invalid data if "apology" in budgetDict: return apology(budget["apology"]) else: # Add budget to DB for user budget = tendie_budgets.createBudget(budgetDict, session["user_id"]) # Render error message if budget name is a duplicate of another budget the user has if "apology" in budget: return apology(budget["apology"]) else: return render_template("budgetcreated.html", results=budget) else: # Get the users income income = tendie_account.getIncome(session["user_id"]) # Get the users total budgeted amount budgeted = tendie_budgets.getTotalBudgeted(session["user_id"]) # Get the users spend categories categories = tendie_categories.getSpendCategories(session["user_id"]) return render_template("createbudget.html", income=income, budgeted=budgeted, categories=categories)
def getBudgets(userID, year=None): budgets = [] budget = {"name": None, "amount": 0, "spent": 0, "remaining": 0} # Default to getting current years budgets if not year: year = datetime.now().year budgets_query = tendie_budgets.getBudgets(userID) # Build a budget dict to return if budgets_query and year in budgets_query: for record in budgets_query[year]: budgetID = record["id"] budget["name"] = record["name"] budget["amount"] = record["amount"] # Query the DB for the budgets total spent amount (calculated as the sum of expenses with categories that match the categories selected for the individual budget) results = db.execute( "SELECT SUM(amount) AS spent FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = :year AND category IN (SELECT categories.name FROM budgetcategories INNER JOIN categories on budgetcategories.category_id = categories.id WHERE budgetcategories.budgets_id = :budgetID)", { "usersID": userID, "year": year, "budgetID": budgetID }).fetchall() budget_TotalSpent = convertSQLToDict(results) if (budget_TotalSpent[0]["spent"] == None): budget["spent"] = 0 else: budget["spent"] = budget_TotalSpent[0]["spent"] # Set the remaining amount to 0 if the user has spent more than they budgeted for so that the charts don't look crazy if (budget["spent"] > budget["amount"]): budget["remaining"] = 0 else: budget["remaining"] = budget["amount"] - budget["spent"] # Add the budget to the list budgets.append(budget.copy()) return budgets # Return None if no budget was found else: return None