wylaczenie sposob platnosci i porpawki ux

This commit is contained in:
Mateusz Gruszczyński
2025-10-10 13:30:13 +02:00
parent 1c69295b9b
commit f9406a46cf
7 changed files with 332 additions and 260 deletions

155
app.py
View File

@@ -82,8 +82,8 @@ class Zbiorka(db.Model):
id = db.Column(db.Integer, primary_key=True)
nazwa = db.Column(db.String(100), nullable=False)
opis = db.Column(db.Text, nullable=False)
numer_konta = db.Column(db.String(50), nullable=False)
numer_telefonu_blik = db.Column(db.String(50), nullable=False)
numer_konta = db.Column(db.String(50), nullable=True)
numer_telefonu_blik = db.Column(db.String(50), nullable=True)
cel = db.Column(Numeric(12, 2), nullable=False, default=0)
stan = db.Column(Numeric(12, 2), default=0)
ukryta = db.Column(db.Boolean, default=False)
@@ -92,6 +92,8 @@ class Zbiorka(db.Model):
pokaz_postep_finanse = db.Column(db.Boolean, default=True, nullable=False)
pokaz_postep_pozycje = db.Column(db.Boolean, default=True, nullable=False)
pokaz_postep_kwotowo = db.Column(db.Boolean, default=True, nullable=False)
uzyj_konta = db.Column(db.Boolean, default=True, nullable=False)
uzyj_blik = db.Column(db.Boolean, default=True, nullable=False)
wplaty = db.relationship(
"Wplata",
@@ -386,88 +388,69 @@ def formularz_zbiorek(zbiorka_id=None):
return redirect(url_for("index"))
is_edit = zbiorka_id is not None
zb = None
if is_edit:
zb = db.session.get(Zbiorka, zbiorka_id)
if zb is None:
abort(404)
zb = db.session.get(Zbiorka, zbiorka_id) if is_edit else None
if is_edit and zb is None:
abort(404)
global_settings = UstawieniaGlobalne.query.first()
def _temp_obj():
t = zb or Zbiorka()
t.nazwa = (request.form.get("nazwa", "") or "").strip()
t.opis = (request.form.get("opis", "") or "").strip()
t.numer_konta = (request.form.get("numer_konta", "") or "").strip()
t.numer_telefonu_blik = (request.form.get("numer_telefonu_blik", "") or "").strip()
t.ukryj_kwote = "ukryj_kwote" in request.form
t.pokaz_postep_finanse = "pokaz_postep_finanse" in request.form
t.pokaz_postep_pozycje = "pokaz_postep_pozycje" in request.form
t.pokaz_postep_kwotowo = "pokaz_postep_kwotowo" in request.form
t.uzyj_konta = "uzyj_konta" in request.form
t.uzyj_blik = "uzyj_blik" in request.form
return t
if request.method == "POST":
# Pola wspólne
# Pola
nazwa = (request.form.get("nazwa", "") or "").strip()
opis = (request.form.get("opis", "") or "").strip()
numer_konta = (request.form.get("numer_konta", "") or "").strip()
numer_telefonu_blik = (request.form.get("numer_telefonu_blik", "") or "").strip()
# Widoczność kwot i poszczególnych pasków postępu
# Przełączniki płatności
uzyj_konta = "uzyj_konta" in request.form
uzyj_blik = "uzyj_blik" in request.form
# Widoczność/metryki
ukryj_kwote = "ukryj_kwote" in request.form
pokaz_postep_finanse = "pokaz_postep_finanse" in request.form
pokaz_postep_pozycje = "pokaz_postep_pozycje" in request.form
pokaz_postep_kwotowo = "pokaz_postep_kwotowo" in request.form
# Walidacja wymaganych pól tekstowych (zanim uderzymy w bazę)
# Walidacje
if not nazwa:
flash("Nazwa jest wymagana", "danger")
temp_zb = zb or Zbiorka()
temp_zb.nazwa = nazwa
temp_zb.opis = opis
temp_zb.numer_konta = numer_konta
temp_zb.numer_telefonu_blik = numer_telefonu_blik
temp_zb.ukryj_kwote = ukryj_kwote
temp_zb.pokaz_postep_finanse = pokaz_postep_finanse
temp_zb.pokaz_postep_pozycje = pokaz_postep_pozycje
temp_zb.pokaz_postep_kwotowo = pokaz_postep_kwotowo
return render_template("admin/formularz_zbiorek.html", zbiorka=temp_zb, global_settings=global_settings)
return render_template("admin/formularz_zbiorek.html", zbiorka=_temp_obj(), global_settings=global_settings)
if not opis:
flash("Opis jest wymagany", "danger")
temp_zb = zb or Zbiorka()
temp_zb.nazwa = nazwa
temp_zb.opis = opis
temp_zb.numer_konta = numer_konta
temp_zb.numer_telefonu_blik = numer_telefonu_blik
temp_zb.ukryj_kwote = ukryj_kwote
temp_zb.pokaz_postep_finanse = pokaz_postep_finanse
temp_zb.pokaz_postep_pozycje = pokaz_postep_pozycje
temp_zb.pokaz_postep_kwotowo = pokaz_postep_kwotowo
return render_template("admin/formularz_zbiorek.html", zbiorka=temp_zb, global_settings=global_settings)
return render_template("admin/formularz_zbiorek.html", zbiorka=_temp_obj(), global_settings=global_settings)
if not numer_konta:
flash("Numer konta jest wymagany", "danger")
temp_zb = zb or Zbiorka()
temp_zb.nazwa = nazwa
temp_zb.opis = opis
temp_zb.numer_konta = numer_konta
temp_zb.numer_telefonu_blik = numer_telefonu_blik
temp_zb.ukryj_kwote = ukryj_kwote
temp_zb.pokaz_postep_finanse = pokaz_postep_finanse
temp_zb.pokaz_postep_pozycje = pokaz_postep_pozycje
temp_zb.pokaz_postep_kwotowo = pokaz_postep_kwotowo
return render_template("admin/formularz_zbiorek.html", zbiorka=temp_zb, global_settings=global_settings)
# Co najmniej jeden kanał
if not (uzyj_konta or uzyj_blik):
flash("Włącz co najmniej jeden kanał wpłat (konto lub BLIK).", "danger")
return render_template("admin/formularz_zbiorek.html", zbiorka=_temp_obj(), global_settings=global_settings)
if not numer_telefonu_blik:
flash("Numer telefonu BLIK jest wymagany", "danger")
temp_zb = zb or Zbiorka()
temp_zb.nazwa = nazwa
temp_zb.opis = opis
temp_zb.numer_konta = numer_konta
temp_zb.numer_telefonu_blik = numer_telefonu_blik
temp_zb.ukryj_kwote = ukryj_kwote
temp_zb.pokaz_postep_finanse = pokaz_postep_finanse
temp_zb.pokaz_postep_pozycje = pokaz_postep_pozycje
temp_zb.pokaz_postep_kwotowo = pokaz_postep_kwotowo
return render_template("admin/formularz_zbiorek.html", zbiorka=temp_zb, global_settings=global_settings)
# Warunkowe wartości
if uzyj_konta and not numer_konta:
flash("Numer konta jest wymagany (kanał przelewu włączony).", "danger")
return render_template("admin/formularz_zbiorek.html", zbiorka=_temp_obj(), global_settings=global_settings)
# Cel — Decimal, > 0; akceptuj przecinek i usuń spacje/nbsp
if uzyj_blik and not numer_telefonu_blik:
flash("Numer telefonu BLIK jest wymagany (kanał BLIK włączony).", "danger")
return render_template("admin/formularz_zbiorek.html", zbiorka=_temp_obj(), global_settings=global_settings)
# Cel > 0
cel_raw = (request.form.get("cel", "") or "")
cel_norm = (
cel_raw.replace(" ", "")
.replace("\u00A0", "")
.replace(",", ".")
.strip()
)
cel_norm = cel_raw.replace(" ", "").replace("\u00A0", "").replace(",", ".").strip()
try:
if not cel_norm:
raise InvalidOperation
@@ -476,51 +459,41 @@ def formularz_zbiorek(zbiorka_id=None):
raise InvalidOperation
except (InvalidOperation, ValueError):
flash("Podano nieprawidłową wartość dla celu zbiórki", "danger")
# Odtwórz stan formularza, ale nie używaj zbiorka.id w szablonie
temp_zb = zb or Zbiorka()
temp_zb.nazwa = nazwa
temp_zb.opis = opis
temp_zb.numer_konta = numer_konta
temp_zb.numer_telefonu_blik = numer_telefonu_blik
# cel pozostaw niewypełniony przy błędzie, aby input pokazał to co wpisał użytkownik
temp_zb.ukryj_kwote = ukryj_kwote
temp_zb.pokaz_postep_finanse = pokaz_postep_finanse
temp_zb.pokaz_postep_pozycje = pokaz_postep_pozycje
temp_zb.pokaz_postep_kwotowo = pokaz_postep_kwotowo
return render_template("admin/formularz_zbiorek.html", zbiorka=temp_zb, global_settings=global_settings)
return render_template("admin/formularz_zbiorek.html", zbiorka=_temp_obj(), global_settings=global_settings)
# Lista produktów
# Produkty
names = request.form.getlist("item_nazwa[]")
links = request.form.getlist("item_link[]")
prices = request.form.getlist("item_cena[]")
def _read_price(val):
"""Zwraca Decimal(>=0) albo None; akceptuje przecinek jako separator dziesiętny."""
def _read_price(val: str):
if not val or not val.strip():
return None
try:
d = Decimal(val.replace(",", "."))
if d < 0:
return None
return d
return d if d >= 0 else None
except Exception:
return None
# --- ZAPIS ZBIÓRKI + PRODUKTÓW ---
# Zapis
if is_edit:
# Aktualizacja istniejącej zbiórki
zb.nazwa = nazwa
zb.opis = opis
zb.numer_konta = numer_konta
zb.numer_telefonu_blik = numer_telefonu_blik
# NOT NULL-safe: puste stringi gdy wyłączone
zb.uzyj_konta = uzyj_konta
zb.uzyj_blik = uzyj_blik
zb.numer_konta = numer_konta if uzyj_konta else ""
zb.numer_telefonu_blik = numer_telefonu_blik if uzyj_blik else ""
zb.cel = cel
zb.ukryj_kwote = ukryj_kwote
zb.pokaz_postep_finanse = pokaz_postep_finanse
zb.pokaz_postep_pozycje = pokaz_postep_pozycje
zb.pokaz_postep_kwotowo = pokaz_postep_kwotowo
db.session.commit() # zapisz bazowe pola
db.session.commit()
# Nadpisz listę produktów
# Nadpisz pozycje
zb.przedmioty.clear()
for i, raw_name in enumerate(names):
name = (raw_name or "").strip()
@@ -529,7 +502,6 @@ def formularz_zbiorek(zbiorka_id=None):
link = (links[i] if i < len(links) else "").strip() or None
cena_val = _read_price(prices[i] if i < len(prices) else "")
kupione_val = request.form.get(f"item_kupione_val_{i}") == "1"
db.session.add(Przedmiot(
zbiorka_id=zb.id,
nazwa=name,
@@ -537,17 +509,17 @@ def formularz_zbiorek(zbiorka_id=None):
cena=cena_val,
kupione=kupione_val
))
db.session.commit()
flash("Zbiórka została zaktualizowana", "success")
else:
# Utworzenie nowej zbiórki
nowa = Zbiorka(
nazwa=nazwa,
opis=opis,
numer_konta=numer_konta,
numer_telefonu_blik=numer_telefonu_blik,
uzyj_konta=uzyj_konta,
uzyj_blik=uzyj_blik,
numer_konta=(numer_konta if uzyj_konta else ""),
numer_telefonu_blik=(numer_telefonu_blik if uzyj_blik else ""),
cel=cel,
ukryj_kwote=ukryj_kwote,
pokaz_postep_finanse=pokaz_postep_finanse,
@@ -557,7 +529,6 @@ def formularz_zbiorek(zbiorka_id=None):
db.session.add(nowa)
db.session.commit() # potrzebne ID
# Dodaj produkty do nowej zbiórki
for i, raw_name in enumerate(names):
name = (raw_name or "").strip()
if not name:
@@ -565,7 +536,6 @@ def formularz_zbiorek(zbiorka_id=None):
link = (links[i] if i < len(links) else "").strip() or None
cena_val = _read_price(prices[i] if i < len(prices) else "")
kupione_val = request.form.get(f"item_kupione_val_{i}") == "1"
db.session.add(Przedmiot(
zbiorka_id=nowa.id,
nazwa=name,
@@ -573,7 +543,6 @@ def formularz_zbiorek(zbiorka_id=None):
cena=cena_val,
kupione=kupione_val
))
db.session.commit()
flash("Zbiórka została dodana", "success")