This commit is contained in:
Mateusz Gruszczyński
2025-07-24 23:30:51 +02:00
parent 04bc3773e1
commit 34205f0e65
6 changed files with 377 additions and 149 deletions

77
app.py
View File

@@ -45,7 +45,8 @@ from config import Config
from PIL import Image, ExifTags, ImageFilter, ImageOps
from werkzeug.utils import secure_filename
from werkzeug.middleware.proxy_fix import ProxyFix
from sqlalchemy import func, extract, inspect
from sqlalchemy import func, extract, inspect, or_
from sqlalchemy.orm import joinedload
from collections import defaultdict, deque
from functools import wraps
@@ -114,7 +115,10 @@ class ShoppingList(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(150), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
owner_id = db.Column(db.Integer, db.ForeignKey("user.id"))
owner = db.relationship("User", backref="lists", foreign_keys=[owner_id])
is_temporary = db.Column(db.Boolean, default=False)
share_token = db.Column(db.String(64), unique=True, nullable=True)
# expires_at = db.Column(db.DateTime, nullable=True)
@@ -131,6 +135,8 @@ class Item(db.Model):
# added_at = db.Column(db.DateTime, default=datetime.utcnow)
added_at = db.Column(db.DateTime, default=utcnow)
added_by = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True)
added_by_user = db.relationship("User", backref="added_items", lazy=True, foreign_keys=[added_by])
purchased = db.Column(db.Boolean, default=False)
purchased_at = db.Column(db.DateTime, nullable=True)
quantity = db.Column(db.Integer, default=1)
@@ -958,8 +964,7 @@ def view_list(list_id):
@app.route("/user_expenses")
@login_required
def user_expenses():
from sqlalchemy.orm import joinedload
# Lista wydatków użytkownika
expenses = (
Expense.query.join(ShoppingList, Expense.list_id == ShoppingList.id)
.options(joinedload(Expense.list))
@@ -968,7 +973,7 @@ def user_expenses():
.all()
)
rows = [
expense_table = [
{
"title": e.list.title if e.list else "Nieznana",
"amount": e.amount,
@@ -977,7 +982,35 @@ def user_expenses():
for e in expenses
]
return render_template("user_expenses.html", expense_table=rows)
lists = (
ShoppingList.query
.filter(
or_(
ShoppingList.owner_id == current_user.id,
ShoppingList.is_public == True
)
)
.order_by(ShoppingList.created_at.desc())
.all()
)
lists_data = [
{
"id": l.id,
"title": l.title,
"created_at": l.created_at,
"total_expense": sum(e.amount for e in l.expenses),
"owner_username": l.owner.username if l.owner else "?"
}
for l in lists
]
return render_template(
"user_expenses.html",
expense_table=expense_table,
lists_data=lists_data
)
@app.route("/user/expenses_data")
@@ -2213,6 +2246,10 @@ def handle_add_item(data):
name = data["name"].strip()
quantity = data.get("quantity", 1)
list_obj = db.session.get(ShoppingList, list_id)
if not list_obj:
return
try:
quantity = int(quantity)
if quantity < 1:
@@ -2248,12 +2285,15 @@ def handle_add_item(data):
if max_position is None:
max_position = 0
user_id = current_user.id if current_user.is_authenticated else None
user_name = current_user.username if current_user.is_authenticated else "Gość"
new_item = Item(
list_id=list_id,
name=name,
quantity=quantity,
position=max_position + 1,
added_by=current_user.id if current_user.is_authenticated else None,
added_by=user_id,
)
db.session.add(new_item)
@@ -2271,9 +2311,9 @@ def handle_add_item(data):
"id": new_item.id,
"name": new_item.name,
"quantity": new_item.quantity,
"added_by": (
current_user.username if current_user.is_authenticated else "Gość"
),
"added_by": user_name,
"added_by_id": user_id,
"owner_id": list_obj.owner_id,
},
to=str(list_id),
include_self=True,
@@ -2292,6 +2332,7 @@ def handle_add_item(data):
)
@socketio.on("check_item")
def handle_check_item(data):
# item = Item.query.get(data["item_id"])
@@ -2345,7 +2386,19 @@ def handle_uncheck_item(data):
@socketio.on("request_full_list")
def handle_request_full_list(data):
list_id = data["list_id"]
items = Item.query.filter_by(list_id=list_id).order_by(Item.position.asc()).all()
shopping_list = db.session.get(ShoppingList, list_id)
if not shopping_list:
return
owner_id = shopping_list.owner_id
items = (
Item.query.options(joinedload(Item.added_by_user))
.filter_by(list_id=list_id)
.order_by(Item.position.asc())
.all()
)
items_data = []
for item in items:
@@ -2358,12 +2411,16 @@ def handle_request_full_list(data):
"not_purchased": item.not_purchased,
"not_purchased_reason": item.not_purchased_reason,
"note": item.note or "",
"added_by": item.added_by_user.username if item.added_by_user else None,
"added_by_id": item.added_by_user.id if item.added_by_user else None,
"owner_id": owner_id,
}
)
emit("full_list", {"items": items_data}, to=request.sid)
@socketio.on("update_note")
def handle_update_note(data):
item_id = data["item_id"]