ukrywanie akcji
This commit is contained in:
15
alters.txt
15
alters.txt
@@ -1,2 +1,17 @@
|
||||
ALTER TABLE zbiorka ALTER COLUMN numer_konta DROP NOT NULL;
|
||||
ALTER TABLE zbiorka ALTER COLUMN numer_telefonu_blik DROP NOT NULL;
|
||||
|
||||
_______________________________
|
||||
|
||||
PGSQL
|
||||
ALTER TABLE wplata ADD COLUMN ukryta boolean NOT NULL DEFAULT false;
|
||||
ALTER TABLE wydatek ADD COLUMN ukryta boolean NOT NULL DEFAULT false;
|
||||
|
||||
-- po migracji można zdjąć DEFAULT (opcjonalnie)
|
||||
ALTER TABLE wplata ALTER COLUMN ukryta DROP DEFAULT;
|
||||
ALTER TABLE wydatek ALTER COLUMN ukryta DROP DEFAULT;
|
||||
|
||||
|
||||
SQLite
|
||||
ALTER TABLE wplata ADD COLUMN ukryta INTEGER NOT NULL DEFAULT 0;
|
||||
ALTER TABLE wydatek ADD COLUMN ukryta INTEGER NOT NULL DEFAULT 0;
|
97
app.py
97
app.py
@@ -145,6 +145,7 @@ class Wplata(db.Model):
|
||||
data = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
opis = db.Column(db.Text, nullable=True)
|
||||
zbiorka = db.relationship("Zbiorka", back_populates="wplaty")
|
||||
ukryta = db.Column(db.Boolean, nullable=False, default=False)
|
||||
|
||||
class Wydatek(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
@@ -156,7 +157,7 @@ class Wydatek(db.Model):
|
||||
kwota = db.Column(Numeric(12, 2), nullable=False)
|
||||
data = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
opis = db.Column(db.Text, nullable=True)
|
||||
|
||||
ukryta = db.Column(db.Boolean, nullable=False, default=False)
|
||||
|
||||
class UstawieniaGlobalne(db.Model):
|
||||
__tablename__ = "ustawienia_globalne"
|
||||
@@ -296,17 +297,25 @@ def zbiorka(zbiorka_id):
|
||||
if zb.ukryta and (not current_user.is_authenticated or not current_user.czy_admin):
|
||||
abort(404)
|
||||
|
||||
# scalona oś czasu: wpłaty + wydatki
|
||||
aktywnosci = [
|
||||
{"typ": "wpłata", "kwota": w.kwota, "opis": w.opis, "data": w.data}
|
||||
is_admin = current_user.is_authenticated and current_user.czy_admin
|
||||
show_hidden = is_admin and (request.args.get("show_hidden") in ("1", "true", "yes"))
|
||||
|
||||
# wpłaty / wydatki z filtrem ukrycia
|
||||
wplaty = [
|
||||
{"typ": "wpłata", "kwota": w.kwota, "opis": w.opis, "data": w.data, "ukryta": getattr(w, "ukryta", False)}
|
||||
for w in zb.wplaty
|
||||
] + [
|
||||
{"typ": "wydatek", "kwota": x.kwota, "opis": x.opis, "data": x.data}
|
||||
for x in zb.wydatki
|
||||
if show_hidden or not getattr(w, "ukryta", False)
|
||||
]
|
||||
wydatki = [
|
||||
{"typ": "wydatek", "kwota": x.kwota, "opis": x.opis, "data": x.data, "ukryta": getattr(x, "ukryta", False)}
|
||||
for x in zb.wydatki
|
||||
if show_hidden or not getattr(x, "ukryta", False)
|
||||
]
|
||||
|
||||
aktywnosci = wplaty + wydatki
|
||||
aktywnosci.sort(key=lambda a: a["data"], reverse=True)
|
||||
|
||||
return render_template("zbiorka.html", zbiorka=zb, aktywnosci=aktywnosci)
|
||||
return render_template("zbiorka.html", zbiorka=zb, aktywnosci=aktywnosci, show_hidden=show_hidden)
|
||||
|
||||
|
||||
# TRASY LOGOWANIA I REJESTRACJI
|
||||
@@ -838,17 +847,41 @@ def robots():
|
||||
def transakcje_zbiorki(zbiorka_id):
|
||||
if not current_user.czy_admin:
|
||||
flash("Brak uprawnień", "danger"); return redirect(url_for("index"))
|
||||
|
||||
zb = db.session.get(Zbiorka, zbiorka_id)
|
||||
if zb is None:
|
||||
abort(404)
|
||||
|
||||
aktywnosci = (
|
||||
[{"typ": "wpłata", "id": w.id, "kwota": w.kwota, "opis": w.opis, "data": w.data} for w in zb.wplaty] +
|
||||
[{"typ": "wydatek","id": x.id, "kwota": x.kwota,"opis": x.opis,"data": x.data} for x in zb.wydatki]
|
||||
[
|
||||
{
|
||||
"typ": "wpłata",
|
||||
"id": w.id,
|
||||
"kwota": w.kwota,
|
||||
"opis": w.opis,
|
||||
"data": w.data,
|
||||
"ukryta": bool(w.ukryta),
|
||||
}
|
||||
for w in zb.wplaty
|
||||
]
|
||||
+
|
||||
[
|
||||
{
|
||||
"typ": "wydatek",
|
||||
"id": x.id,
|
||||
"kwota": x.kwota,
|
||||
"opis": x.opis,
|
||||
"data": x.data,
|
||||
"ukryta": bool(x.ukryta),
|
||||
}
|
||||
for x in zb.wydatki
|
||||
]
|
||||
)
|
||||
aktywnosci.sort(key=lambda a: a["data"], reverse=True)
|
||||
return render_template("admin/transakcje.html", zbiorka=zb, aktywnosci=aktywnosci)
|
||||
|
||||
|
||||
|
||||
@app.route("/admin/wplata/<int:wplata_id>/zapisz", methods=["POST"])
|
||||
@login_required
|
||||
def zapisz_wplate(wplata_id):
|
||||
@@ -874,6 +907,50 @@ def zapisz_wplate(wplata_id):
|
||||
flash("Wpłata zaktualizowana", "success")
|
||||
return redirect(url_for("transakcje_zbiorki", zbiorka_id=zb.id))
|
||||
|
||||
@app.post("/wplata/<int:wplata_id>/ukryj")
|
||||
@login_required
|
||||
def ukryj_wplate(wplata_id):
|
||||
if not current_user.czy_admin: abort(403)
|
||||
w = db.session.get(Wplata, wplata_id)
|
||||
if not w: abort(404)
|
||||
w.ukryta = True
|
||||
db.session.commit()
|
||||
flash("Wpłata ukryta.", "success")
|
||||
return redirect(request.referrer or url_for("admin_dashboard"))
|
||||
|
||||
@app.post("/wplata/<int:wplata_id>/odkryj")
|
||||
@login_required
|
||||
def odkryj_wplate(wplata_id):
|
||||
if not current_user.czy_admin: abort(403)
|
||||
w = db.session.get(Wplata, wplata_id)
|
||||
if not w: abort(404)
|
||||
w.ukryta = False
|
||||
db.session.commit()
|
||||
flash("Wpłata odkryta.", "success")
|
||||
return redirect(request.referrer or url_for("admin_dashboard"))
|
||||
|
||||
@app.post("/wydatek/<int:wydatek_id>/ukryj")
|
||||
@login_required
|
||||
def ukryj_wydatek(wydatek_id):
|
||||
if not current_user.czy_admin: abort(403)
|
||||
w = db.session.get(Wydatek, wydatek_id)
|
||||
if not w: abort(404)
|
||||
w.ukryta = True
|
||||
db.session.commit()
|
||||
flash("Wydatek ukryty.", "success")
|
||||
return redirect(request.referrer or url_for("admin_dashboard"))
|
||||
|
||||
@app.post("/wydatek/<int:wydatek_id>/odkryj")
|
||||
@login_required
|
||||
def odkryj_wydatek(wydatek_id):
|
||||
if not current_user.czy_admin: abort(403)
|
||||
w = db.session.get(Wydatek, wydatek_id)
|
||||
if not w: abort(404)
|
||||
w.ukryta = False
|
||||
db.session.commit()
|
||||
flash("Wydatek odkryty.", "success")
|
||||
return redirect(request.referrer or url_for("admin_dashboard"))
|
||||
|
||||
|
||||
@app.route("/admin/wplata/<int:wplata_id>/usun", methods=["POST"])
|
||||
@login_required
|
||||
|
@@ -23,4 +23,5 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
modalX.show();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@@ -6,24 +6,21 @@
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 class="mb-0">Transakcje: {{ zbiorka.nazwa }}</h3>
|
||||
|
||||
<div class="btn-group" role="group" aria-label="Akcje zbiórki">
|
||||
<a class="btn btn-sm btn-outline-light" href="{{ url_for('dodaj_wplate', zbiorka_id=zbiorka.id) }}">
|
||||
<i class="fas fa-plus-circle"></i> Dodaj wpłatę
|
||||
</a>
|
||||
|
||||
<a class="btn btn-sm btn-outline-light" href="{{ url_for('dodaj_wydatek', zbiorka_id=zbiorka.id) }}">
|
||||
Dodaj wydatek
|
||||
</a>
|
||||
|
||||
<a class="btn btn-sm btn-outline-light" href="{{ url_for('edytuj_stan', zbiorka_id=zbiorka.id) }}">
|
||||
Edytuj stan
|
||||
</a>
|
||||
|
||||
<a class="btn btn-sm btn-outline-light" href="{{ url_for('zbiorka', zbiorka_id=zbiorka.id) }}">
|
||||
Otwórz ↗
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm">
|
||||
@@ -41,15 +38,22 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for a in aktywnosci %}
|
||||
<tr>
|
||||
<tr data-tx-id="{{ a.id }}" data-tx-typ="{{ a.typ }}">
|
||||
<td>{{ a.data|dt("%d.%m.%Y %H:%M") }}</td>
|
||||
<td>
|
||||
<span class="badge {{ 'bg-success' if a.typ=='wpłata' else 'bg-danger' }}">{{ a.typ
|
||||
}}</span>
|
||||
|
||||
</td>
|
||||
<td class="text-end">{{ '%.2f'|format(a.kwota) }} PLN</td>
|
||||
<td class="text-muted">{{ a.opis or '—' }}</td>
|
||||
<td class="text-end">
|
||||
|
||||
{% if a.ukryta %}<span class="badge bg-secondary ms-1">[ akcja ukryta ]</span>{% endif
|
||||
%}
|
||||
|
||||
|
||||
<div class="d-inline-flex flex-nowrap align-items-center gap-2">
|
||||
{% if a.typ == 'wpłata' %}
|
||||
<button class="btn btn-sm btn-outline-light btn-edit-wplata" data-id="{{ a.id }}"
|
||||
data-kwota="{{ '%.2f'|format(a.kwota) }}" data-opis="{{ a.opis|e if a.opis }}"
|
||||
@@ -61,10 +65,22 @@
|
||||
onsubmit="return confirm('Usunąć wpłatę? Cofnie to wpływ na stan.');">
|
||||
<button class="btn btn-sm btn-outline-danger">Usuń</button>
|
||||
</form>
|
||||
|
||||
{% if a.ukryta %}
|
||||
<form class="d-inline" method="post"
|
||||
action="{{ url_for('odkryj_wplate', wplata_id=a.id) }}">
|
||||
<button class="btn btn-sm btn-outline-secondary">Odkryj</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-outline-light btn-edit-wydatek"
|
||||
data-id="{{ a.id }}" data-kwota="{{ '%.2f'|format(a.kwota) }}"
|
||||
data-opis="{{ a.opis|e if a.opis }}"
|
||||
<form class="d-inline" method="post"
|
||||
action="{{ url_for('ukryj_wplate', wplata_id=a.id) }}">
|
||||
<button class="btn btn-sm btn-outline-secondary">Ukryj</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
<button class="btn btn-sm btn-outline-light btn-edit-wydatek" data-id="{{ a.id }}"
|
||||
data-kwota="{{ '%.2f'|format(a.kwota) }}" data-opis="{{ a.opis|e if a.opis }}"
|
||||
data-action="{{ url_for('zapisz_wydatek', wydatek_id=a.id) }}">
|
||||
Edytuj
|
||||
</button>
|
||||
@@ -73,7 +89,22 @@
|
||||
onsubmit="return confirm('Usunąć wydatek? Cofnie to wpływ na stan.');">
|
||||
<button class="btn btn-sm btn-outline-danger">Usuń</button>
|
||||
</form>
|
||||
|
||||
{% if a.ukryta %}
|
||||
<span class="badge bg-secondary">Ukryta</span>
|
||||
<form class="d-inline" method="post"
|
||||
action="{{ url_for('odkryj_wydatek', wydatek_id=a.id) }}">
|
||||
<button class="btn btn-sm btn-outline-secondary">Odkryj</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form class="d-inline" method="post"
|
||||
action="{{ url_for('ukryj_wydatek', wydatek_id=a.id) }}">
|
||||
<button class="btn btn-sm btn-outline-secondary">Ukryj</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
|
Reference in New Issue
Block a user