diff --git a/app.py b/app.py index 151f494..1d1e672 100644 --- a/app.py +++ b/app.py @@ -37,11 +37,22 @@ class Transaction(db.Model): category = db.relationship('Category', backref=db.backref('transactions', lazy=True)) +class Budget(db.Model): + id = db.Column(db.Integer, primary_key=True) + month = db.Column(db.Integer, nullable=False) + year = db.Column(db.Integer, nullable=False) + amount = db.Column(db.Float, nullable=False, default=0) + + __table_args__ = (db.UniqueConstraint('month', 'year', name='_month_year_uc'),) + + # Create database and tables if they don't exist with app.app_context(): + db.create_all() if not os.path.exists(DATABASE_PATH): - db.create_all() print("Database created successfully!") + else: + print("Database tables updated successfully!") # Home Page (Redirect to Summary) @@ -53,9 +64,31 @@ def index(): # Summary Page @app.route('/summary') def summary(): + now = datetime.now() + current_month = now.month + current_year = now.year + total_income = db.session.query(db.func.sum(Transaction.amount)).filter_by(type="income").scalar() or 0 total_expense = db.session.query(db.func.sum(Transaction.amount)).filter_by(type="expense").scalar() or 0 + monthly_expense = db.session.query(db.func.sum(Transaction.amount)).filter( + Transaction.type == "expense", + db.func.strftime('%m', Transaction.date) == f'{current_month:02d}', + db.func.strftime('%Y', Transaction.date) == str(current_year) + ).scalar() or 0 + + budget = Budget.query.filter_by(month=current_month, year=current_year).first() + budget_amount = budget.amount if budget else 0 + + budget_percentage = 0 + budget_status = 'normal' + if budget_amount > 0: + budget_percentage = (monthly_expense / budget_amount) * 100 + if budget_percentage >= 100: + budget_status = 'danger' + elif budget_percentage >= 80: + budget_status = 'warning' + income_summary = db.session.query(Category.name, db.func.sum(Transaction.amount), Category.chart_color) \ .join(Transaction).filter(Transaction.type == "income") \ .group_by(Category.name, Category.chart_color).all() @@ -72,9 +105,35 @@ def summary(): total_expense=total_expense, income_summary=income_summary, expense_summary=expense_summary, - categories=categories + categories=categories, + monthly_expense=monthly_expense, + budget_amount=budget_amount, + budget_percentage=min(budget_percentage, 100), + budget_status=budget_status, + current_month=calendar.month_name[current_month], + current_year=current_year ) + +# Set Budget +@app.route('/set_budget', methods=['POST']) +def set_budget(): + now = datetime.now() + current_month = now.month + current_year = now.year + amount = float(request.form.get('budget_amount', 0)) + + budget = Budget.query.filter_by(month=current_month, year=current_year).first() + if budget: + budget.amount = amount + else: + budget = Budget(month=current_month, year=current_year, amount=amount) + db.session.add(budget) + + db.session.commit() + flash("Budget updated successfully!", "success") + return redirect(url_for('summary')) + @app.route('/analytics-data') def analytics_data(): import calendar diff --git a/finance.db b/finance.db index 71871c7..27dbf51 100644 Binary files a/finance.db and b/finance.db differ diff --git a/templates/index.html b/templates/index.html index 603c361..5e969de 100644 --- a/templates/index.html +++ b/templates/index.html @@ -8,6 +8,61 @@

Summary

Remaining Balance: ${{ total_income - total_expense }}

+ +
+
+

{{ current_month }} {{ current_year }} Budget

+ +
+ + {% if budget_amount > 0 %} +
+
+ Spent: ${{ "%.2f"|format(monthly_expense) }} / ${{ "%.2f"|format(budget_amount) }} + {{ "%.1f"|format(budget_percentage) }}% +
+
+
+ {% if budget_percentage >= 10 %} + {{ "%.0f"|format(budget_percentage) }}% + {% endif %} +
+
+ {% if budget_status == 'danger' %} +

⚠️ Budget exceeded! You've spent over 100% of your budget.

+ {% elif budget_status == 'warning' %} +

⚠️ Warning: You've spent over 80% of your budget.

+ {% endif %} +
+ {% else %} +

No budget set for this month. Click "Set Budget" to create one.

+ {% endif %} +
+ + + +
@@ -106,6 +161,11 @@

Add Transaction

const form = document.getElementById("transaction-form"); form.classList.toggle("hidden"); } + + function toggleBudgetForm() { + const form = document.getElementById("budget-form"); + form.classList.toggle("hidden"); + } {% endblock %}