feat(subscription): Add comments for subscriptions

Close #3
This commit is contained in:
2026-02-25 10:26:29 +01:00
parent e3cf819fef
commit a45d8ea321
4 changed files with 67 additions and 29 deletions

View File

@@ -7,10 +7,11 @@ from typing import Annotated
from urllib.parse import quote_plus from urllib.parse import quote_plus
import starlette.status as status import starlette.status as status
from fastapi import Depends, FastAPI, HTTPException, Request, Response from fastapi import Depends, FastAPI, Form, HTTPException, Request, Response
from fastapi.responses import FileResponse, RedirectResponse from fastapi.responses import FileResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, BeforeValidator, validator
from sqlalchemy import create_engine, select from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
@@ -64,7 +65,7 @@ def get_user(request: Request, allow_none: bool = True) -> dict | None:
return { return {
"username": request.headers["ynh_user"], "username": request.headers["ynh_user"],
# TODO: This should obviously be replaced with a role based check # TODO: This should obviously be replaced with a role based check
"admin": request.headers["ynh_user"] in ["niklas.m", "martin.k"] "admin": request.headers["ynh_user"] in ["niklas.m", "martin.k"],
} }
if allow_none: if allow_none:
return None return None
@@ -156,35 +157,43 @@ async def subscribe(request: Request, session: SessionDep, user: UserDep):
) )
@app.post("/subscribe") def empty_string_to_zero(value):
async def add_subscribe(request: Request, session: SessionDep): if value == "":
form_data = await request.form() return 0
# TODO: Make this return a nicer error message else:
try: return value
num_adult_meals = int(form_data["numAdults"]) if form_data["numAdults"] else 0
num_children_meals = int(form_data["numKids"]) if form_data["numKids"] else 0
num_small_children_meals = (
int(form_data["numSmallKids"]) if form_data["numSmallKids"] else 0
)
except ValueError:
raise ValueError("All number fields must be integers")
class SubscriptionForm(BaseModel):
household: int
days: list[str]
comment: str
numAdults: Annotated[int, BeforeValidator(empty_string_to_zero)] = 0
numKids: Annotated[int, BeforeValidator(empty_string_to_zero)] = 0
numSmallKids: Annotated[int, BeforeValidator(empty_string_to_zero)] = 0
@app.post("/subscribe")
async def add_subscribe(
request: Request,
session: SessionDep,
form_data: Annotated[SubscriptionForm, Form()],
):
subscription = Subscription( subscription = Subscription(
household_id=form_data["household"], household_id=form_data.household,
num_adult_meals=num_adult_meals, num_adult_meals=form_data.numAdults,
num_children_meals=num_children_meals, num_children_meals=form_data.numKids,
num_small_children_meals=num_small_children_meals, num_small_children_meals=form_data.numSmallKids,
comment=form_data.comment,
) )
selected_days = form_data.getlist("days") subscription.monday = "1" in form_data.days
if selected_days: subscription.tuesday = "2" in form_data.days
subscription.monday = "1" in selected_days subscription.wednesday = "3" in form_data.days
subscription.tuesday = "2" in selected_days subscription.thursday = "4" in form_data.days
subscription.wednesday = "3" in selected_days subscription.friday = "5" in form_data.days
subscription.thursday = "4" in selected_days subscription.saturday = "6" in form_data.days
subscription.friday = "5" in selected_days subscription.sunday = "7" in form_data.days
subscription.saturday = "6" in selected_days
subscription.sunday = "7" in selected_days
session.add(subscription) session.add(subscription)
session.commit() session.commit()

View File

@@ -31,7 +31,9 @@ def run_nightly_tasks():
print("Done running nightly tasks.") print("Done running nightly tasks.")
def apply_subscriptions(session: Session, event: Event = None, dry_run: bool = False): def apply_subscriptions(
session: Session, event: Event | None = None, dry_run: bool = False
):
subscriptions = session.scalars(select(Subscription)).all() subscriptions = session.scalars(select(Subscription)).all()
@@ -76,13 +78,18 @@ def apply_subscriptions(session: Session, event: Event = None, dry_run: bool = F
f"There is already a registration for {subscription.household.name}. Skipping subscription." f"There is already a registration for {subscription.household.name}. Skipping subscription."
) )
continue continue
comment = "Dauerhafte Anmeldung"
if subscription.comment:
comment += f" mit Kommentar: {subscription.comment}"
reg = Registration( reg = Registration(
event_id=event.id, event_id=event.id,
household_id=subscription.household_id, household_id=subscription.household_id,
num_adult_meals=subscription.num_adult_meals, num_adult_meals=subscription.num_adult_meals,
num_children_meals=subscription.num_children_meals, num_children_meals=subscription.num_children_meals,
num_small_children_meals=subscription.num_small_children_meals, num_small_children_meals=subscription.num_small_children_meals,
comment="Dauerhafte Anmeldung", comment=comment,
) )
if dry_run: if dry_run:
print(f"DRY RUN: Would register {subscription.household.name}") print(f"DRY RUN: Would register {subscription.household.name}")

View File

@@ -89,6 +89,17 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div class="mb-3">
<label class="form-label">Kommentar</label>
<p class="text-muted small mb-2">
Dieser Kommentar wird bei jeder Anmeldung hinzugefügt.
</p>
<div class="d-flex flex-wrap gap-3">
<input name="comment" id="InputComment" class="form-control"
aria-label="Kommentar">
</div>
</div>
</div> </div>
<!-- Footer --> <!-- Footer -->
@@ -134,6 +145,14 @@
<div class="fw-bold small">{{ sub.day_string_de() }}</div> <div class="fw-bold small">{{ sub.day_string_de() }}</div>
</div> </div>
</div> </div>
{% if sub.comment %}
<div class="row g-2">
<div class="col-12">
<div class="text-muted" style="font-size: 0.7rem;">Kommentar</div>
<div class="fw-bold small">{{ sub.comment }}</div>
</div>
</div>
{% endif %}
</div> </div>
</div> </div>
{% endfor %} {% endfor %}

View File

@@ -39,6 +39,7 @@ def test_subscriptions(db_session):
num_adult_meals=2, num_adult_meals=2,
num_children_meals=1, num_children_meals=1,
num_small_children_meals=0, num_small_children_meals=0,
comment="test",
) )
) )
db_session.commit() db_session.commit()
@@ -54,3 +55,5 @@ def test_subscriptions(db_session):
assert not event1.subscriptions_applied assert not event1.subscriptions_applied
assert not ignore.subscriptions_applied assert not ignore.subscriptions_applied
assert event2.subscriptions_applied assert event2.subscriptions_applied
assert event2.registrations[0].comment is not None
assert "test" in event2.registrations[0].comment