Files
finance_app/app.py

116 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime, date
from dotenv import load_dotenv
load_dotenv() # Загрузка переменных окружения из .env
app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY', 'secret-key')
# Конфигурация PostgreSQL
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'postgresql://user:password@localhost/finance_db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Модель данных
class Transaction(db.Model):
id = db.Column(db.Integer, primary_key=True)
type = db.Column(db.String(10), nullable=False) # 'income' или 'expense'
amount = db.Column(db.Float, nullable=False)
category = db.Column(db.String(50), nullable=False)
date = db.Column(db.Date, nullable=False, default=date.today())
description = db.Column(db.Text)
def __repr__(self):
return f'<Transaction {self.id}: {self.type} {self.amount}>'
# Роуты
@app.route('/')
def index():
# Получаем все транзакции, отсортированные по дате
transactions = Transaction.query.order_by(Transaction.date.desc()).all()
# Рассчитываем общие суммы
total_income = sum(t.amount for t in transactions if t.type == 'income')
total_expense = sum(t.amount for t in transactions if t.type == 'expense')
balance = total_income - total_expense
# Группируем по категориям
categories = {}
for t in transactions:
if t.category not in categories:
categories[t.category] = {'income': 0, 'expense': 0}
categories[t.category][t.type] += t.amount
return render_template('index.html',
transactions=transactions,
total_income=total_income,
total_expense=total_expense,
balance=balance,
categories=categories,
current_date=date.today())
@app.route('/add', methods=['GET', 'POST'])
def add_transaction():
if request.method == 'POST':
# Получаем данные из формы
transaction_type = request.form['type']
amount = float(request.form['amount'])
category = request.form['category']
transaction_date = datetime.strptime(request.form['date'], '%Y-%m-%d').date()
description = request.form['description']
# Создаем новую транзакцию
new_transaction = Transaction(
type=transaction_type,
amount=amount,
category=category,
date=transaction_date,
description=description
)
# Сохраняем в БД
db.session.add(new_transaction)
db.session.commit()
flash('Транзакция успешно добавлена!', 'success')
return redirect(url_for('index'))
# Для GET-запроса показываем форму
return render_template('add.html', current_date=date.today())
@app.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit_transaction(id):
transaction = Transaction.query.get_or_404(id)
if request.method == 'POST':
# Обновляем данные
transaction.type = request.form['type']
transaction.amount = float(request.form['amount'])
transaction.category = request.form['category']
transaction.date = datetime.strptime(request.form['date'], '%Y-%m-%d').date()
transaction.description = request.form['description']
# Сохраняем изменения
db.session.commit()
flash('Транзакция успешно обновлена!', 'success')
return redirect(url_for('index'))
# Для GET-запроса показываем форму с текущими данными
return render_template('edit.html', transaction=transaction)
@app.route('/delete/<int:id>')
def delete_transaction(id):
transaction = Transaction.query.get_or_404(id)
db.session.delete(transaction)
db.session.commit()
flash('Транзакция успешно удалена!', 'success')
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)