예제 #1
0
def isUniqueBudgetName(budgetName, budgetID, userID):
    if budgetID == None:
        # Verify the net-new created budget name is not already existing in the users existing budgets
        results = db.execute(
            "SELECT name FROM budgets WHERE user_id = :usersID", {
                "usersID": userID
            }).fetchall()
        existingBudgets = convertSQLToDict(results)
    else:
        # Verify the updated budget name is not already existing in the users existing budgets
        results = db.execute(
            "SELECT name FROM budgets WHERE user_id = :usersID AND NOT id = :oldBudgetID",
            {
                "usersID": userID,
                "oldBudgetID": budgetID
            }).fetchall()
        existingBudgets = convertSQLToDict(results)

    # Loop through all budgets and compare names
    isUniqueName = True
    for budget in existingBudgets:
        if budgetName.lower() == budget["name"].lower():
            isUniqueName = False
            break

    if isUniqueName:
        return True
    else:
        return False
예제 #2
0
def generateBudgetsReport(userID, year=None):
    # Create data structure to hold users category spending data
    budgetsReport = []

    # Default to getting current years budgets
    if not year:
        year = datetime.now().year

    # Get every budgets spent/remaining for the user
    budgetsReport = tendie_dashboard.getBudgets(userID, year)

    # Loop through the budgets and add a new key/value pair to hold expense details per budget
    if budgetsReport:
        for record in budgetsReport:
            budgetID = tendie_budgets.getBudgetID(record["name"], userID)
            results = db.execute(
                "SELECT expenses.description, expenses.category, expenses.expenseDate, expenses.payer, expenses.amount 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()
            expenseDetails = convertSQLToDict(results)
            record["expenses"] = expenseDetails

    return budgetsReport
def getBudgetsFromSpendCategory(categoryID, userID):
    results = db.execute("SELECT budgets.id AS budgetid, budgets.name AS budgetname, categories.id AS categoryid, categories.name AS categoryname FROM budgetcategories INNER JOIN budgets on budgetcategories.budgets_id = budgets.id INNER JOIN categories on budgetcategories.category_id = categories.id WHERE budgets.user_id = :usersID AND budgetcategories.category_id = :categoryID ORDER BY budgets.name, categories.name", {
        "usersID": userID, "categoryID": categoryID}).fetchall()

    budgets = convertSQLToDict(results)

    return budgets
예제 #4
0
def generateMonthlyReport(userID, year=None):

    # Default to getting current years reports
    if not year:
        year = datetime.now().year

    # Create data structure to hold users monthly spending data for the chart (monthly summed data)
    spending_month_chart = tendie_dashboard.getMonthlySpending(userID, year)

    # Get the spending data from DB for the table (individual expenses per month)
    results = db.execute(
        "SELECT description, category, expensedate, amount, payer FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = :year ORDER BY id ASC",
        {
            "usersID": userID,
            "year": year
        }).fetchall()
    spending_month_table = convertSQLToDict(results)

    # Combine both data points (chart and table) into a single data structure
    monthlyReport = {
        "chart": spending_month_chart,
        "table": spending_month_table
    }

    return monthlyReport
예제 #5
0
def getWeeklySpending(weekNames, userID):
    weeklySpending = []
    week = {"startOfWeek": None, "endOfWeek": None, "amount": None}

    # Loop through each week and store the name/amount in a dict
    for name in weekNames:
        week["endOfWeek"] = name['endofweek'].strftime('%b %d')
        week["startOfWeek"] = name['startofweek'].strftime('%b %d')
        results = db.execute(
            "SELECT SUM(amount) AS amount FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = date_part('year', date(:weekName)) AND date_part('week', date(expensedate)) = date_part('week',date(:weekName))",
            {"usersID": userID, "weekName": str(name["endofweek"])}).fetchall()
        weekSpending = convertSQLToDict(results)

        # Set the amount to 0 if there are no expenses for a given week
        if weekSpending[0]["amount"] == None:
            week["amount"] = 0
        else:
            week["amount"] = weekSpending[0]["amount"]

        # Add the week to the list
        weeklySpending.append(week.copy())

    # Check to make sure at least 1 of the 4 weeks has expenses, otherwise set it to None so that the UI can be rendered with an appropriate message
    hasExpenses = False
    for record in weeklySpending:
        if record["amount"] != 0:
            hasExpenses = True
            break
    if hasExpenses is False:
        weeklySpending.clear()

    return weeklySpending
예제 #6
0
def getUpdatableBudget(budget, userID):

    # Get the users library of spend categories
    categories = tendie_categories.getSpendCategories(userID)

    # Get the budget's spend categories and % amount for each category
    results = db.execute("SELECT DISTINCT categories.name, budgetCategories.amount FROM budgetCategories INNER JOIN categories ON budgetCategories.category_id = categories.id INNER JOIN budgets ON budgetCategories.budgets_id = budgets.id WHERE budgets.id = :budgetsID",
                         {"budgetsID": budget["id"]}).fetchall()
    budgetCategories = convertSQLToDict(results)

    # Add 'categories' as a new key/value pair to the existing budget dict
    budget["categories"] = []

    # Populate the categories by looping through and adding all their categories
    for category in categories:
        for budgetCategory in budgetCategories:
            # Mark the category as checked/True if it exists in the budget that the user wants to update
            if category["name"] == budgetCategory["name"]:
                # Convert the percentage (decimal) into a whole integer to be consistent with UX
                amount = round(budgetCategory["amount"] * 100)
                budget["categories"].append(
                    {"name": category["name"], "amount": amount, "checked": True})
                break
        else:
            budget["categories"].append(
                {"name": category["name"], "amount": None, "checked": False})

    return budget
예제 #7
0
def getPayers(userID):
    results = db.execute(
        "SELECT name FROM payers WHERE user_id = :usersID ORDER BY name ASC", {"usersID": userID}).fetchall()

    payers = convertSQLToDict(results)

    return payers
예제 #8
0
def getSpendingTrends(userID, year=None):

    spending_trends = []
    categoryTrend = {"name": None, "proportionalAmount": None,
                     "totalSpent": None, "totalCount": None}

    # Default to getting current years spending
    if not year:
        year = datetime.now().year

    results = db.execute("SELECT category, COUNT(category) as count, SUM(amount) as amount FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = :year GROUP BY category ORDER BY COUNT(category) DESC",
                         {"usersID": userID, "year": year}).fetchall()
    categories = convertSQLToDict(results)

    # Calculate the total amount spent
    totalSpent = 0
    for categoryExpense in categories:
        totalSpent += categoryExpense["amount"]

    for category in categories:
        # Do not include category in chart if it's spending accounts for less than 1% of the overall spending
        proportionalAmount = round((category["amount"] / totalSpent) * 100)
        if (proportionalAmount < 1):
            continue
        else:
            categoryTrend["name"] = category["category"]
            categoryTrend["proportionalAmount"] = proportionalAmount
            categoryTrend["totalSpent"] = category["amount"]
            categoryTrend["totalCount"] = category["count"]
            spending_trends.append(categoryTrend.copy())

    return spending_trends
예제 #9
0
def getHistory(userID):
    results = db.execute("SELECT description, category, expenseDate AS date, payer, amount, submitTime FROM expenses WHERE user_id = :usersID ORDER BY submitTime ASC",
                         {"usersID": userID}).fetchall()

    history = convertSQLToDict(results)

    return history
예제 #10
0
def getBudgetByID(budgetID, userID):
    results = db.execute(
        "SELECT name, amount, year, id FROM budgets WHERE user_id = :usersID AND id = :budgetID", {"usersID": userID, "budgetID": budgetID}).fetchall()

    budget = convertSQLToDict(results)

    return budget[0]
예제 #11
0
def getLastFourWeekNames():
    # Query note: looks back 3 weeks from the current week and *thru* the current week to give a total of 4 weeks of start/end dates
    results = db.execute("SELECT date_trunc('week', CURRENT_DATE)::date AS startofweek, (date_trunc('week', CURRENT_DATE) + interval '6 day')::date AS endofweek UNION SELECT date_trunc('week', CURRENT_DATE - interval '1 week')::date AS startofweek, (date_trunc('week', CURRENT_DATE - interval '1 week') + interval '6 day')::date AS endofweek UNION SELECT date_trunc('week', CURRENT_DATE - interval '2 week')::date AS startofweek, (date_trunc('week', CURRENT_DATE - interval '2 week') + interval '6 day')::date AS endofweek UNION SELECT date_trunc('week', CURRENT_DATE - interval '3 week')::date AS startofweek, (date_trunc('week', CURRENT_DATE - interval '3 week') + interval '6 day')::date AS endofweek ORDER BY startofweek ASC").fetchall()

    weekNames = convertSQLToDict(results)

    return weekNames
예제 #12
0
def getTotalSpend_Month(userID):
    results = db.execute(
        "SELECT SUM(amount) AS expenses_month FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = date_part('year', CURRENT_DATE) AND date_part('month', date(expensedate)) = date_part('month', CURRENT_DATE)",
        {"usersID": userID}).fetchall()

    totalSpendMonth = convertSQLToDict(results)

    return totalSpendMonth[0]['expenses_month']
def getSpendCategories(userID):
    results = db.execute(
        "SELECT categories.name FROM usercategories INNER JOIN categories ON usercategories.category_id = categories.id WHERE usercategories.user_id = :usersID",
        {"usersID": userID}).fetchall()

    categories = convertSQLToDict(results)

    return categories
def getSpendCategories_Inactive(userID):
    results = db.execute(
        "SELECT category FROM expenses WHERE user_id = :usersID AND category NOT IN(SELECT categories.name FROM usercategories INNER JOIN categories ON categories.id = usercategories.category_id WHERE user_id = :usersID) GROUP BY category",
        {"usersID": userID}).fetchall()

    categories = convertSQLToDict(results)

    return categories
예제 #15
0
def getTotalSpend_Week(userID):
    # Query note: Day 0 of a week == Sunday. This query grabs expenses between the *current* weeks Monday and Sunday.
    results = db.execute(
        "SELECT SUM(amount) AS expenses_week FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = date_part('year', CURRENT_DATE) AND date_part('week', date(expensedate)) = date_part('week', CURRENT_DATE)",
        {"usersID": userID}).fetchall()

    totalSpendWeek = convertSQLToDict(results)

    return totalSpendWeek[0]['expenses_week']
예제 #16
0
def getLastFiveExpenses(userID):
    results = db.execute(
        "SELECT description, category, expenseDate, payer, amount FROM expenses WHERE user_id = :usersID ORDER BY id DESC LIMIT 5", {"usersID": userID}).fetchall()

    lastFiveExpenses = convertSQLToDict(results)

    if lastFiveExpenses:
        return lastFiveExpenses
    else:
        return None
예제 #17
0
def generatePayersReport(userID, year=None):

    # Default to getting current years reports
    if not year:
        year = datetime.now().year

    # First get all of the payers from expenses table (this may include payers that don't exist anymore for the user (i.e. deleted the payer and didn't update expense records))
    results_payers = db.execute(
        "SELECT payer AS name, SUM(amount) AS amount FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = :year GROUP BY payer ORDER BY amount DESC",
        {
            "usersID": userID,
            "year": year
        }).fetchall()
    payers = convertSQLToDict(results_payers)

    # Now get any payers the user has in their account but haven't expensed anything
    results_nonExpensePayers = db.execute(
        "SELECT name FROM payers WHERE user_id = :usersID AND name NOT IN (SELECT payer FROM expenses WHERE expenses.user_id = :usersID AND date_part('year', date(expensedate)) = :year)",
        {
            "usersID": userID,
            "year": year
        }).fetchall()
    nonExpensePayers = convertSQLToDict(results_nonExpensePayers)

    # Add the non-expense payers to the payers data structure and set their amounts to 0
    for payer in nonExpensePayers:
        newPayer = {"name": payer["name"], "amount": 0}
        payers.append(newPayer)

    # Calculate the total paid for all payers combined
    totalPaid = 0
    for payer in payers:
        totalPaid = totalPaid + payer["amount"]

    # Calculate the % paid per payer and add to the data structure
    if totalPaid != 0:
        for payer in payers:
            payer["percentAmount"] = round((payer["amount"] / totalPaid) * 100)

        return payers
    else:
        return None
예제 #18
0
def getBudgets(userID):
    results = db.execute(
        "SELECT id, name, amount FROM budgets WHERE user_id = :usersID ORDER BY name ASC",
        {
            "usersID": userID
        }).fetchall()

    budgets = convertSQLToDict(results)

    if budgets:
        return budgets
    else:
        return None
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
예제 #20
0
def getBudgets(userID):
    results = db.execute(
        "SELECT id, name, year, amount FROM budgets WHERE user_id = :usersID ORDER BY name ASC", {"usersID": userID}).fetchall()

    budgets_query = convertSQLToDict(results)

    if budgets_query:
        # Create a dict with budget year as key and empty list as value which will store all budgets for that year
        budgets = {budget['year']: [] for budget in budgets_query}

        # Update the dict by inserting budget info as values
        for budget in budgets_query:
            budgets[budget['year']].append(
                {'amount': budget['amount'], 'id': budget['id'], 'name': budget['name']})

        return budgets
    else:
        return None
예제 #21
0
def data_change():
    # For making sure that request was made by AJAX
    request_xhr_key = request.headers.get("X-Requested-With")
    if not request_xhr_key or request_xhr_key != "XMLHttpRequest":
        return
    # Responses for different AJAXs
    data = request.get_json()
    # Getting a user id
    user_id = session["user_id"]
    db = engine.connect()
    if data.get("data") == "add":
        adding_cash = data.get("value")
        db.execute(text(
            "UPDATE users SET cash = cash + :cash, all_cash = all_cash + :cash WHERE id = :user_id"
        ),
                   cash=adding_cash,
                   user_id=user_id)
        return jsonify({'action': 'add', 'cash': adding_cash})

    elif data.get("data") == "withdraw":
        withdraw_cash = data.get("value")
        db.execute(text(
            "UPDATE users SET cash = cash - :cash, all_cash = all_cash - :cash WHERE id = :user_id"
        ),
                   cash=withdraw_cash,
                   user_id=user_id)
        return jsonify({'action': 'withdraw', 'cash': withdraw_cash})

    else:
        old_password = data.get("old_password")
        new_password = data.get("new_password")
        user_data_result = db.execute(
            text("SELECT * FROM users WHERE id = :user_id"), user_id=user_id)
        row = convertSQLToDict(user_data_result)[0]
        # Ensure a password is correct
        if not check_password_hash(row["hashed"], old_password):
            return jsonify({"correct": False})
        else:
            db.execute(
                text("UPDATE users SET hashed = :hashed WHERE id = :user_id"),
                hashed=generate_password_hash(new_password),
                user_id=user_id)
            return jsonify({"correct": True})
예제 #22
0
def getMonthlySpending(userID):
    spending_month = []
    month = {"name": None, "amount": None}

    # Query note: pulls data for months of the *current* calendar year
    results = db.execute(
        "SELECT date_part('month', date(expensedate)) AS month, SUM(amount) AS amount FROM expenses WHERE user_id = :usersID AND date(expensedate) > date_trunc('month',(CURRENT_DATE - interval '11 months')) - interval '1 day' GROUP BY date_part('month', date(expensedate)) ORDER BY month",
        {
            "usersID": userID
        }).fetchall()
    spending_month_query = convertSQLToDict(results)

    for record in spending_month_query:
        month["name"] = calendar.month_abbr[int(record["month"])]
        month["amount"] = record["amount"]

        spending_month.append(month.copy())

    return spending_month
예제 #23
0
def generateMonthlyReport(userID):

    # Create data structure to hold users monthly spending data for the chart (monthly summed data)
    spending_month_chart = tendie_dashboard.getMonthlySpending(userID)

    # Get the spending data from DB for the table (individual expenses per month)
    results = db.execute(
        "SELECT description, category, expensedate, amount, payer FROM expenses WHERE user_id = :usersID AND date(expensedate) > date_trunc('month',(CURRENT_DATE - interval '11 months')) - interval '1 day' ORDER BY submitTime ASC",
        {
            "usersID": userID
        }).fetchall()
    spending_month_table = convertSQLToDict(results)

    # Combine both data points (chart and table) into a single data structure
    monthlyReport = {
        "chart": spending_month_chart,
        "table": spending_month_table
    }

    return monthlyReport
예제 #24
0
def getMonthlySpending(userID, year=None):
    spending_month = []
    month = {"name": None, "amount": None}

    # Default to getting current years spending
    if not year:
        year = datetime.now().year

    results = db.execute(
        "SELECT date_part('month', date(expensedate)) AS month, SUM(amount) AS amount FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = :year GROUP BY date_part('month', date(expensedate)) ORDER BY month",
        {"usersID": userID, "year": year}).fetchall()
    spending_month_query = convertSQLToDict(results)

    for record in spending_month_query:
        month["name"] = calendar.month_abbr[int(record["month"])]
        month["amount"] = record["amount"]

        spending_month.append(month.copy())

    return spending_month
예제 #25
0
def generateSpendingTrendsReport(userID, year=None):

    # Default to getting current years reports
    if not year:
        year = datetime.now().year

    # Get chart data for spending trends
    spending_trends_chart = tendie_dashboard.getSpendingTrends(userID, year)

    # Data structure for spending trends table
    categories = []
    category = {
        "name": None,
        "expenseMonth": 0,
        "expenseCount": 0,
        "amount": 0
    }
    spending_trends_table = {
        "January": [],
        "February": [],
        "March": [],
        "April": [],
        "May": [],
        "June": [],
        "July": [],
        "August": [],
        "September": [],
        "October": [],
        "November": [],
        "December": []
    }

    # Get all of the users categories first (doesn't include old categories the user deleted but are still tracked in Expenses)
    categories_active = tendie_categories.getSpendCategories(userID)

    # Get any categories that are in expenses but no longer exist as a selectable category for the user (because they deleted the category)
    categories_inactive = tendie_categories.getSpendCategories_Inactive(userID)

    # First fill using the users current categories, and then inactive categories from Expenses
    for activeCategory in categories_active:
        category["name"] = activeCategory["name"]
        categories.append(category.copy())

    for inactiveCategory in categories_inactive:
        category["name"] = inactiveCategory["category"]
        categories.append(category.copy())

    # Place a deep copy of the categories into each month (need deep copy here because every category may have unique spend data month to month. TODO: optimize this for memory/performance later)
    for month in spending_trends_table.keys():
        spending_trends_table[month] = copy.deepcopy(categories)

    # Get expense data for each category by month (retrieves the total amount of expenses per category by month, and the total count of expenses per category by month. Assumes there is at least 1 expense for the category)
    results = db.execute(
        "SELECT date_part('month', date(expensedate)) AS monthofcategoryexpense, category AS name, COUNT(category) AS count, SUM(amount) AS amount FROM expenses WHERE user_id = :usersID AND date_part('year', date(expensedate)) = :year GROUP BY date_part('month', date(expensedate)), category ORDER BY COUNT(category) DESC",
        {
            "usersID": userID,
            "year": year
        }).fetchall()

    spending_trends_table_query = convertSQLToDict(results)

    # Loop thru each monthly category expense from above DB query and update the data structure that holds all monthly category expenses
    for categoryExpense in spending_trends_table_query:
        # Get the key (month) for the data structure
        monthOfExpense = calendar.month_name[int(
            categoryExpense["monthofcategoryexpense"])]
        # Traverse the data structure: 1) go to the dict month based on the category expense date, 2) loop thru each dict category until a match in name occurs with the expense, 3) update the dict month/amount/count properties to match the DB record
        for category in spending_trends_table[monthOfExpense]:
            if category["name"] == categoryExpense["name"]:
                category["expenseMonth"] = categoryExpense[
                    "monthofcategoryexpense"]
                category["expenseCount"] = categoryExpense["count"]
                category["amount"] = categoryExpense["amount"]
                break
            else:
                continue

    # Calculates and stores the amount spent per category for the table (note: can't get this to work in jinja with the spending_trends_table dict because of how jinja scopes variables. TODO: rethink data-structure to combine these)
    numberOfCategories = len(categories)
    categoryTotal = 0
    # Loops through every month per category and sums up the monthly amounts
    for i in range(numberOfCategories):
        for month in spending_trends_table.keys():
            categoryTotal += spending_trends_table[month][i]["amount"]
        categories[i]["amount"] = categoryTotal
        categoryTotal = 0

    # Combine both data points (chart, table, categories) into a single data structure
    spendingTrendsReport = {
        "chart": spending_trends_chart,
        "table": spending_trends_table,
        "categories": categories
    }

    return spendingTrendsReport
예제 #26
0
def login():
    """Log user in"""

    # Forget any user_id
    session.clear()

    if request.method == "GET":
        return render_template("login.html")
    else:
        # This route with POST method is also used by AJAX to validate user data without loading
        # a new page after it

        # For making sure that request was made by AJAX
        request_xhr_key = request.headers.get("X-Requested-With")

        username = request.form.get("username")
        password = request.form.get("password")

        # In case if a bad guy disabled JS and submitted the form
        if not request_xhr_key or request_xhr_key != "XMLHttpRequest":
            # Ensure username is submitted and valid
            if not username or username.strip(
            ) == "" or len(username) > 127 or re.search(
                    EMOJI_PATTERN, username) or re.search(
                        space_regex, username):
                return apology("Please provide a valid username")
            # Ensure password was submitted and valid as well
            elif not password or password.strip() == "" or not re.search(
                    password_regex, password) or re.search(
                        EMOJI_PATTERN, password):
                return apology("Please provide a valid password")

        # Query database for username
        db = engine.connect()
        result = db.execute(
            text("SELECT * FROM users WHERE username = :username"),
            username=username)
        rows = convertSQLToDict(result)

        # Ensure username exists
        if len(rows) != 1:
            if request_xhr_key and request_xhr_key == "XMLHttpRequest":
                return jsonify({
                    "validated": False,
                    "username": "******"
                })
            else:
                return apology("Wrong username")
        # Ensure a password is correct
        elif not check_password_hash(rows[0]["hashed"], password):
            if request_xhr_key and request_xhr_key == "XMLHttpRequest":
                return jsonify({
                    "validated": False,
                    "password": "******"
                })
            else:
                return apology("Wrong password")

        # Remember which user has logged in
        session["user_id"] = rows[0]["id"]
        # Return a respective answer for AJAX or make redirection for disabled JS
        if request_xhr_key and request_xhr_key == "XMLHttpRequest":
            return jsonify({"validated": True})
        else:
            # Redirect user to home page
            return redirect("/")
예제 #27
0
def shop():
    # Query database for username
    db = engine.connect()
    result = db.execute(text("SELECT * FROM items ORDER BY id ASC"))
    rows = convertSQLToDict(result)
    return render_template("shop.html", rows=rows)
예제 #28
0
def profile():
    # Getting a user id
    user_id = session["user_id"]
    db = engine.connect()
    if request.method == "GET":
        # Query database for user data and items
        item_results = db.execute(text("SELECT * FROM items ORDER BY id ASC"))
        rows = convertSQLToDict(item_results)
        user_result = db.execute(text(
            "SELECT username, email, country, age, transport, gender, cash, all_cash FROM users WHERE id = :user_id"
        ),
                                 user_id=user_id)
        user_data = convertSQLToDict(user_result)[0]
        return render_template("profile.html", rows=rows, user_data=user_data)
    else:
        # For making sure that request was made by AJAX
        request_xhr_key = request.headers.get("X-Requested-With")
        if not request_xhr_key or request_xhr_key != "XMLHttpRequest":
            return
        # Responses for different AJAXs
        data = request.get_json()
        if data.get("account"):
            purchases_result = db.execute(text(
                "SELECT name, number FROM purchases JOIN items ON purchases.item_id = items.id WHERE purchases.user_id = :user_id"
            ),
                                          user_id=user_id)
            user_purchases = convertSQLToDict(purchases_result)
            return jsonify(user_purchases)
        elif data.get("history"):
            history_result = db.execute(text(
                "SELECT name, price, number, date FROM history LEFT JOIN items ON history.item_id = items.id WHERE history.user_id = :user_id"
            ),
                                        user_id=user_id)
            history = convertSQLToDict(history_result)
            return jsonify(history)
        else:
            total = data.get("total")
            picked_items = data.get("items")
            cancelled_items = []
            # Query database for items
            item_results = db.execute(
                text("SELECT * FROM items ORDER BY id ASC"))
            rows = convertSQLToDict(item_results)
            for item_id in picked_items:
                db_item_id = int(item_id) + 1
                left_items = rows[int(
                    item_id)]["current_number"] - picked_items[item_id]
                if left_items >= 0:
                    # Update a number of item left in the shop
                    db.execute(text(
                        "UPDATE items SET current_number = :number WHERE id = :item_id"
                    ),
                               number=left_items,
                               item_id=db_item_id)
                    # Check if a user has alredy bought such item before
                    bought_item = db.execute(text(
                        "SELECT * FROM purchases WHERE user_id = :user_id AND item_id = :item_id"
                    ),
                                             user_id=user_id,
                                             item_id=db_item_id).fetchall()
                    if not bought_item:
                        # If a user has not bought such item yet, then add it to his purchases
                        db.execute(text(
                            "INSERT INTO purchases (user_id, item_id, number) VALUES (:user_id, :item_id, :number)"
                        ),
                                   user_id=user_id,
                                   item_id=db_item_id,
                                   number=picked_items[item_id])
                    else:
                        # Else update the number of this item in purchases
                        db.execute(text(
                            "UPDATE purchases SET number = number + :number WHERE user_id = :user_id AND item_id = :item_id"
                        ),
                                   number=picked_items[item_id],
                                   user_id=user_id,
                                   item_id=db_item_id)
                    # Insert into history this purchase
                    db.execute(text(
                        "INSERT INTO history (user_id, item_id, number) VALUES (:user_id, :item_id, :number)"
                    ),
                               user_id=user_id,
                               item_id=db_item_id,
                               number=picked_items[item_id])
                else:
                    cancelled_items.append(int(item_id))
                    total -= rows[int(
                        item_id)]["price"] * picked_items[item_id]

            if total != 0:
                db.execute(text(
                    "UPDATE users SET cash = cash - :cash WHERE id = :user_id"
                ),
                           cash=total,
                           user_id=user_id)

            if cancelled_items:
                return jsonify({
                    "bought": False,
                    "total": total,
                    "cancelledItems": cancelled_items,
                    "rows": rows
                })
            else:
                return jsonify({"bought": True})
def getSpendCategoryLibrary():
    results = db.execute("SELECT id, name FROM categories").fetchall()

    convertSQLToDict(results)

    return categories