From 14c53aa85693e0984bdf0765da1ea78c0c6ebc37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Sat, 13 Sep 2025 22:45:20 +0200 Subject: [PATCH] commit2 permissions --- app.py | 47 +++++++++++++++++++++++++++++------------ static/js/functions.js | 2 +- templates/expenses.html | 2 +- templates/list.html | 3 +-- templates/main.html | 7 +++--- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/app.py b/app.py index dba782b..57c949d 100644 --- a/app.py +++ b/app.py @@ -1056,6 +1056,31 @@ def get_total_expenses_grouped_by_list_created_at( expenses = [round(grouped[l], 2) for l in labels] return {"labels": labels, "expenses": expenses} +def resolve_range(range_type: str): + now = datetime.now(timezone.utc) + sd = ed = None + bucket = "monthly" + + rt = (range_type or "").lower() + if rt in ("last7days", "last_7_days"): + sd = (now - timedelta(days=7)).date().strftime("%Y-%m-%d") + ed = now.date().strftime("%Y-%m-%d") + bucket = "daily" + elif rt in ("last30days", "last_30_days"): + sd = (now - timedelta(days=30)).date().strftime("%Y-%m-%d") + ed = now.date().strftime("%Y-%m-%d") + bucket = "monthly" elif rt in ("last90days", "last_90_days"): + sd = (now - timedelta(days=90)).date().strftime("%Y-%m-%d") + ed = now.date().strftime("%Y-%m-%d") + bucket = "monthly" + elif rt in ("thismonth", "this_month"): + first = datetime(now.year, now.month, 1, tzinfo=timezone.utc) + sd = first.date().strftime("%Y-%m-%d") + ed = now.date().strftime("%Y-%m-%d") + bucket = "monthly" + + return sd, ed, bucket + def save_pdf_as_webp(file, path): try: @@ -1960,24 +1985,19 @@ def view_list(list_id): @app.route("/expenses") @login_required def expenses(): - from sqlalchemy.orm import joinedload - from types import SimpleNamespace - start_date_str = request.args.get("start_date") end_date_str = request.args.get("end_date") - category_id = request.args.get("category_id", type=str) # może być "none" + category_id = request.args.get("category_id", type=str) show_all = request.args.get("show_all", "true").lower() == "true" now = datetime.now(timezone.utc) - # --- 1) Widoczne listy (właściciel/publiczne/udzielone), aktywne (niearch./niewygasłe) --- visible_clause = visible_lists_clause_for_expenses( user_id=current_user.id, include_shared=show_all, now_dt=now ) lists_q = ShoppingList.query.filter(*visible_clause) - # Filtr zakresu po CREATED_AT LISTY (nie po Expense) if start_date_str and end_date_str: try: start = datetime.strptime(start_date_str, "%Y-%m-%d") @@ -1989,7 +2009,6 @@ def expenses(): except ValueError: flash("Błędny zakres dat", "danger") - # Filtr kategorii na LISTACH (bez joinów, żeby nie ucinać „none”) if category_id: if category_id == "none": lists_q = lists_q.filter(~ShoppingList.categories.any()) @@ -2003,7 +2022,6 @@ def expenses(): except (TypeError, ValueError): pass - # Materializacja list (to jest pełna, finalna lista do wyświetlenia) lists_filtered = ( lists_q .options(joinedload(ShoppingList.owner), joinedload(ShoppingList.categories)) @@ -2012,7 +2030,6 @@ def expenses(): ) list_ids = [l.id for l in lists_filtered] or [-1] - # --- 2) Wydatki: po wybranych listach (bez dodatkowego filtra dat, bo zakres dotyczy list) --- expenses = ( Expense.query .options( @@ -2024,7 +2041,6 @@ def expenses(): .all() ) - # --- 3) Sumy per lista (LEFT OUTER JOIN + COALESCE; nie utnie list bez wydatków) --- totals_rows = ( db.session.query( ShoppingList.id.label("lid"), @@ -2038,7 +2054,6 @@ def expenses(): ) totals_map = {row.lid: float(row.total_expense or 0) for row in totals_rows} - # --- 4) Kategorie do filtra (z samych widocznych list po filtrach) --- categories = ( Category.query .join(shopping_list_category, shopping_list_category.c.category_id == Category.id) @@ -2050,7 +2065,6 @@ def expenses(): ) categories.append(SimpleNamespace(id="none", name="Bez kategorii")) - # --- 5) Dane do widoku (format bez zmian) --- expense_table = [ { "title": (e.shopping_list.title if e.shopping_list else "Nieznana"), @@ -2065,7 +2079,7 @@ def expenses(): "id": l.id, "title": l.title, "created_at": l.created_at, - "total_expense": totals_map.get(l.id, 0.0), # 0.0 gdy brak wydatków + "total_expense": totals_map.get(l.id, 0.0), "owner_username": l.owner.username if l.owner else "?", "categories": [c.id for c in l.categories], } @@ -2092,6 +2106,13 @@ def expenses_data(): category_id = request.args.get("category_id") by_category = request.args.get("by_category", "false").lower() == "true" + if not start_date or not end_date: + sd, ed, bucket = resolve_range(range_type) + if sd and ed: + start_date = sd + end_date = ed + range_type = bucket + if by_category: result = get_total_expenses_grouped_by_category( show_all=show_all, diff --git a/static/js/functions.js b/static/js/functions.js index ab379c7..ef89d4b 100644 --- a/static/js/functions.js +++ b/static/js/functions.js @@ -234,7 +234,7 @@ function toggleVisibility(listId) { toggleBtn.innerHTML = '🙈 Ukryj listę'; } else { shareHeader.textContent = '🔗 Udostępnij link (widoczna tylko przez link / uprawnienia)'; - toggleBtn.innerHTML = '👁️ Uczyń publiczną'; + toggleBtn.innerHTML = '🐵 Uczyń publiczną'; } }); } diff --git a/templates/expenses.html b/templates/expenses.html index 1de5e43..c5e5cd1 100644 --- a/templates/expenses.html +++ b/templates/expenses.html @@ -13,7 +13,7 @@
diff --git a/templates/list.html b/templates/list.html index aa2b58c..ed8f157 100644 --- a/templates/list.html +++ b/templates/list.html @@ -55,10 +55,9 @@ {% if list.is_public %} 🙈 Ustaw niepubliczną {% else %} - 👁️ Uczyń publiczną + 🐵 Uczyń publiczną {% endif %} - ➕ Nadaj dostęp diff --git a/templates/main.html b/templates/main.html index d2473c8..1c7b1e2 100644 --- a/templates/main.html +++ b/templates/main.html @@ -63,7 +63,7 @@ Twoje listy {% if user_lists %} @@ -87,15 +87,14 @@
📄 Otwórz + class="btn btn-sm btn-outline-light d-flex align-items-center text-nowrap">📂 Otwórz ✏️ Odznaczaj 📋 Kopiuj - - {% if l.is_public %}🙈 Niepubliczna{% else %}👁️ Publiczna{% endif %} + {% if l.is_public %}🙈 Ukryj{% else %}🐵 Odkryj{% endif %} ⚙️ Ustawienia