podlgad w kategoriach

This commit is contained in:
Mateusz Gruszczyński
2025-08-13 22:52:51 +02:00
parent 960715f5d7
commit 1befc2f87d
2 changed files with 37 additions and 27 deletions

55
app.py
View File

@@ -48,6 +48,7 @@ from sqlalchemy import func, extract, inspect, or_, case, text
from sqlalchemy.orm import joinedload
from collections import defaultdict, deque
from functools import wraps
# from flask_talisman import Talisman # import niżej pod warunkiem
from flask_session import Session
from types import SimpleNamespace
@@ -93,16 +94,18 @@ if referrer_policy:
# jak naglowki wylaczone, nie ładuj talisman z pominięciem referrer_policy
effective_headers = {
k: v for k, v in talisman_kwargs.items()
k: v
for k, v in talisman_kwargs.items()
if k != "referrer_policy" and v not in (None, False)
}
if effective_headers:
from flask_talisman import Talisman
talisman = Talisman(
app,
session_cookie_secure=app.config.get("SESSION_COOKIE_SECURE", True),
**talisman_kwargs
**talisman_kwargs,
)
print("[TALISMAN] Włączony z nagłówkami:", list(effective_headers.keys()))
else:
@@ -941,19 +944,16 @@ def save_pdf_as_webp(file, path):
def get_active_months_query(visible_lists_query=None):
if db.engine.name == "sqlite":
month_col = func.strftime('%Y-%m', ShoppingList.created_at)
month_col = func.strftime("%Y-%m", ShoppingList.created_at)
else:
month_col = func.to_char(ShoppingList.created_at, 'YYYY-MM')
month_col = func.to_char(ShoppingList.created_at, "YYYY-MM")
query = db.session.query(month_col.label("month"))
if visible_lists_query is not None:
query = query.select_from(visible_lists_query.subquery())
active_months = (
query.filter(ShoppingList.created_at != None)
.distinct()
.order_by("month")
.all()
query.filter(ShoppingList.created_at != None).distinct().order_by("month").all()
)
return [row.month for row in active_months]
@@ -1201,6 +1201,7 @@ def file_mtime_filter(path):
# return datetime.utcnow()
return datetime.now(timezone.utc)
@app.template_filter("todatetime")
def to_datetime_filter(s):
return datetime.strptime(s, "%Y-%m-%d")
@@ -1294,8 +1295,7 @@ def main_page():
def date_filter(query):
if start and end:
query = query.filter(
ShoppingList.created_at >= start,
ShoppingList.created_at < end
ShoppingList.created_at >= start, ShoppingList.created_at < end
)
return query
@@ -1362,14 +1362,11 @@ def main_page():
if current_user.is_authenticated:
visible_lists_query = ShoppingList.query.filter(
or_(
ShoppingList.owner_id == current_user.id,
ShoppingList.is_public == True
ShoppingList.owner_id == current_user.id, ShoppingList.is_public == True
)
)
else:
visible_lists_query = ShoppingList.query.filter(
ShoppingList.is_public == True
)
visible_lists_query = ShoppingList.query.filter(ShoppingList.is_public == True)
# Teraz możemy bezpiecznie pobrać miesiące
month_options = get_active_months_query(visible_lists_query)
@@ -1382,8 +1379,12 @@ def main_page():
db.session.query(
Item.list_id,
func.count(Item.id).label("total_count"),
func.sum(case((Item.purchased == True, 1), else_=0)).label("purchased_count"),
func.sum(case((Item.not_purchased == True, 1), else_=0)).label("not_purchased_count"),
func.sum(case((Item.purchased == True, 1), else_=0)).label(
"purchased_count"
),
func.sum(case((Item.not_purchased == True, 1), else_=0)).label(
"not_purchased_count"
),
)
.filter(Item.list_id.in_(all_ids))
.group_by(Item.list_id)
@@ -1394,7 +1395,7 @@ def main_page():
s.list_id: (
s.total_count or 0,
s.purchased_count or 0,
s.not_purchased_count or 0
s.not_purchased_count or 0,
)
for s in stats
}
@@ -1409,7 +1410,9 @@ def main_page():
)
for l in all_lists:
total_count, purchased_count, not_purchased_count = stats_map.get(l.id, (0, 0, 0))
total_count, purchased_count, not_purchased_count = stats_map.get(
l.id, (0, 0, 0)
)
l.total_count = total_count
l.purchased_count = purchased_count
l.not_purchased_count = not_purchased_count
@@ -1435,11 +1438,10 @@ def main_page():
now=now,
timedelta=timedelta,
month_options=month_options,
selected_month=month_str
selected_month=month_str,
)
@app.route("/system-auth", methods=["GET", "POST"])
def system_auth():
if (
@@ -2191,7 +2193,7 @@ def admin_panel():
month_str = request.args.get("m")
if not month_str:
month_str = datetime.now(timezone.utc).strftime("%Y-%m")
show_all = (month_str == "all")
show_all = month_str == "all"
if not show_all:
try:
@@ -2224,10 +2226,12 @@ def admin_panel():
)
if not show_all and start and end:
base_query = base_query.filter(ShoppingList.created_at >= start, ShoppingList.created_at < end)
base_query = base_query.filter(
ShoppingList.created_at >= start, ShoppingList.created_at < end
)
all_lists = base_query.all()
# tylko listy z danych miesięcy
month_options = get_active_months_query()
@@ -2303,7 +2307,7 @@ def admin_panel():
)
purchased_items_count = Item.query.filter_by(purchased=True).count()
expense_summary = get_admin_expense_summary()
process = psutil.Process(os.getpid())
app_mem = process.memory_info().rss // (1024 * 1024)
@@ -2971,6 +2975,7 @@ def admin_mass_edit_categories():
"admin/mass_edit_categories.html", lists=lists, categories=categories
)
@app.route("/admin/list_items/<int:list_id>")
@login_required
@admin_required

View File

@@ -8,6 +8,11 @@
<a href="{{ url_for('admin_panel') }}" class="btn btn-outline-secondary">← Powrót do panelu</a>
</div>
</div>
<div class="alert alert-warning border-warning text-dark" role="alert">
<strong>Uwaga!</strong> Przypisanie więcej niż jednej kategorii do listy może zaburzyć
poprawne zliczanie wydatków, ponieważ wydatki tej listy będą jednocześnie
klasyfikowane do kilku kategorii.
</div>
<form method="post">
<div class="card bg-dark text-white mb-5">
@@ -20,7 +25,7 @@
<th scope="col">Nazwa listy</th>
<th scope="col">Właściciel</th>
<th scope="col">Data utworzenia</th>
<th scope="col">Podgląd</th>
<th scope="col">Podgląd produktów</th>
<th scope="col">Kategorie</th>
</tr>
</thead>
@@ -34,7 +39,7 @@
<td>
<button type="button" class="btn btn-sm btn-outline-info preview-btn"
data-list-id="{{ lst.id }}">
🔍 Podgląd
🔍 Zobacz
</button>
</td>
<td style="min-width: 220px;">