diff --git a/gaehsnitz/management/commands/seed_drinks_2026.py b/gaehsnitz/management/commands/seed_drinks_2026.py index 0b4635d..63d1660 100644 --- a/gaehsnitz/management/commands/seed_drinks_2026.py +++ b/gaehsnitz/management/commands/seed_drinks_2026.py @@ -18,18 +18,18 @@ PAYMENTS = [ ] DRINKS = [ - # name, crates, btl/crate, size, price/crate, deposit/crate, sale/btl - ("Sterni", 12, 20, 0.5, 10.99, 3.10, 2.00), - ("Krosti", 5, 20, 0.5, 16.49, 3.10, 2.50), - ("Buddi", 5, 20, 0.5, 20.99, 3.10, 2.50), - ("Helles", 5, 20, 0.5, 15.99, 4.50, 2.50), - ("Radler", 2, 20, 0.5, 14.99, 3.10, 2.50), - ("Lübzer 0,0", 1, 20, 0.5, 17.99, 3.10, 2.50), - ("Freiberger 0,0", 4, 20, 0.5, 15.49, 3.10, 2.50), - ("Mate", 2, 20, 0.5, 17.49, 4.50, 2.50), - ("Vita Cola", 2, 12, 1.0, 10.99, 3.30, 2.50), - ("Spezi", 2, 20, 0.5, 17.99, 3.10, 2.50), - ("Wasser", 10, 12, 1.0, 5.99, 3.30, 1.50), + # name, category, crates, btl/crate, size, price/crate, deposit/crate, sale/btl + ("Sternburg Export", "beer", 12, 20, 0.5, 10.99, 3.10, 2.00), + ("Ur-Krostitzer", "beer", 5, 20, 0.5, 16.49, 3.10, 2.50), + ("Budweiser", "beer", 5, 20, 0.5, 20.99, 3.10, 2.50), + ("Altenburger Helles", "beer", 5, 20, 0.5, 15.99, 4.50, 2.50), + ("Feldschl. Radler", "radler", 2, 20, 0.5, 14.99, 3.10, 2.50), + ("Lübzer Grapef. 0,0", "alc_free_radler", 1, 20, 0.5, 17.99, 3.10, 2.50), + ("Freiberger 0,0", "alc_free_beer", 4, 20, 0.5, 15.49, 3.10, 2.50), + ("Club Mate", "soft", 2, 20, 0.5, 17.49, 4.50, 2.50), + ("Vita Cola", "soft", 2, 12, 1.0, 10.99, 3.30, 2.50), + ("Paulaner Spezi", "soft", 2, 20, 0.5, 17.99, 3.10, 2.50), + ("Wasser", "water", 10, 12, 1.0, 5.99, 3.30, 1.50), ] @@ -46,11 +46,12 @@ class Command(BaseCommand): ) self.stdout.write(f"{'created' if created else 'updated'}: {obj.purpose} ({obj.date})") - for name, crates, btl, size, price, deposit, sale in DRINKS: + for name, category, crates, btl, size, price, deposit, sale in DRINKS: obj, created = Drink.objects.update_or_create( name=name, year=2026, defaults={ + "category": category, "crates_ordered": crates, "crates_purchased": crates, "crates_returned": 0, diff --git a/gaehsnitz/migrations/0007_drink_category.py b/gaehsnitz/migrations/0007_drink_category.py new file mode 100644 index 0000000..0079559 --- /dev/null +++ b/gaehsnitz/migrations/0007_drink_category.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.5 on 2026-05-14 20:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gaehsnitz', '0006_user_payment'), + ] + + operations = [ + migrations.AddField( + model_name='drink', + name='category', + field=models.CharField(choices=[('beer', 'Bier'), ('radler', 'Radler'), ('alc_free_beer', 'Bier alkoholfrei'), ('soft', 'Softdrink'), ('water', 'Wasser')], default='beer', max_length=16, verbose_name='Kategorie'), + ), + ] diff --git a/gaehsnitz/migrations/0008_alter_drink_category.py b/gaehsnitz/migrations/0008_alter_drink_category.py new file mode 100644 index 0000000..95125c3 --- /dev/null +++ b/gaehsnitz/migrations/0008_alter_drink_category.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.5 on 2026-05-14 20:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gaehsnitz', '0007_drink_category'), + ] + + operations = [ + migrations.AlterField( + model_name='drink', + name='category', + field=models.CharField(choices=[('beer', 'Bier'), ('radler', 'Radler'), ('alc_free_beer', 'Bier alkoholfrei'), ('alc_free_radler', 'Radler alkoholfrei'), ('soft', 'Softdrink'), ('water', 'Wasser')], default='beer', max_length=16, verbose_name='Kategorie'), + ), + ] diff --git a/gaehsnitz/models.py b/gaehsnitz/models.py index 7429e20..adc230b 100644 --- a/gaehsnitz/models.py +++ b/gaehsnitz/models.py @@ -83,8 +83,22 @@ class Payment(models.Model): class Drink(models.Model): + class Category(models.TextChoices): + beer = "beer", "Bier" + radler = "radler", "Radler" + alc_free_beer = "alc_free_beer", "Bier alkoholfrei" + alc_free_radler = "alc_free_radler", "Radler alkoholfrei" + soft = "soft", "Softdrink" + water = "water", "Wasser" + name = models.CharField("Name", max_length=32) year = models.PositiveSmallIntegerField("Jahr", default=2024) + category = models.CharField( + "Kategorie", + max_length=16, + choices=Category.choices, + default=Category.beer, + ) crates_ordered = models.PositiveSmallIntegerField( "Kästen bestellt", help_text="nur zur Info, wie gut wir geplant haben — nicht die tatsächlich konsumierten/bezahlten Flaschen", diff --git a/gaehsnitz/static/suff/style.css b/gaehsnitz/static/suff/style.css index b3a9e95..c820d63 100644 --- a/gaehsnitz/static/suff/style.css +++ b/gaehsnitz/static/suff/style.css @@ -203,14 +203,58 @@ section { .drink-btn { width: 100%; - aspect-ratio: 4 / 3; + aspect-ratio: 3 / 2; display: flex; flex-direction: column; align-items: center; justify-content: center; - gap: 4px; - padding: 12px 8px; + gap: 2px; + padding: 8px; line-height: 1.2; + color: #161616; + text-shadow: none; +} + +.drink-btn-beer { + background: linear-gradient(180deg, #f0c878 0%, #b8731a 100%); +} +.drink-btn-beer:hover, .drink-btn-beer:focus { + background: linear-gradient(180deg, #f7d699 0%, #cc8520 100%); +} + +.drink-btn-radler { + background: linear-gradient(180deg, #f7e36b 0%, #d8a02a 100%); +} +.drink-btn-radler:hover, .drink-btn-radler:focus { + background: linear-gradient(180deg, #fff08c 0%, #e8b034 100%); +} + +.drink-btn-alc_free_beer { + background: linear-gradient(180deg, #f0c878 0%, #5e8bbf 100%); +} +.drink-btn-alc_free_beer:hover, .drink-btn-alc_free_beer:focus { + background: linear-gradient(180deg, #f7d699 0%, #7aa3d1 100%); +} + +.drink-btn-alc_free_radler { + background: linear-gradient(180deg, #f7e36b 0%, #5e8bbf 100%); +} +.drink-btn-alc_free_radler:hover, .drink-btn-alc_free_radler:focus { + background: linear-gradient(180deg, #fff08c 0%, #7aa3d1 100%); +} + +.drink-btn-soft { + background: linear-gradient(180deg, #f0a35e 0%, #a85a22 100%); +} +.drink-btn-soft:hover, .drink-btn-soft:focus { + background: linear-gradient(180deg, #f7b878 0%, #c06a2c 100%); +} + +.drink-btn-water { + background: linear-gradient(180deg, #d5e8f4 0%, #95c2dc 100%); +} +.drink-btn-water:hover, .drink-btn-water:focus { + background: linear-gradient(180deg, #e4f0f8 0%, #aad0e6 100%); } .drink-plus { @@ -228,7 +272,7 @@ section { .drink-price { font-size: 0.85rem; font-weight: normal; - opacity: 0.8; + opacity: 0.75; } .history { diff --git a/gaehsnitz/suff.py b/gaehsnitz/suff.py index 5659583..480586c 100644 --- a/gaehsnitz/suff.py +++ b/gaehsnitz/suff.py @@ -6,7 +6,7 @@ from django.contrib.admin.views.decorators import staff_member_required from django.contrib.auth import authenticate, login, logout from django.contrib.auth.decorators import login_required from django.contrib.auth import get_user_model -from django.db.models import F, Sum +from django.db.models import Case, F, IntegerField, Sum, Value, When from django.http import Http404, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse @@ -173,7 +173,24 @@ def pin_view(request): @require_http_methods(["GET"]) def me_view(request): phase = _require_open(request) - drinks = Drink.objects.filter(year=current_year()).order_by("name") if phase == "booking" else Drink.objects.none() + drinks = ( + Drink.objects.filter(year=current_year()) + .annotate( + category_order=Case( + When(category="beer", then=Value(0)), + When(category="alc_free_beer", then=Value(1)), + When(category="radler", then=Value(2)), + When(category="alc_free_radler", then=Value(3)), + When(category="soft", then=Value(4)), + When(category="water", then=Value(5)), + default=Value(99), + output_field=IntegerField(), + ) + ) + .order_by("category_order", "name") + if phase == "booking" + else Drink.objects.none() + ) booked_drink = None booked_id = request.GET.get("booked") if booked_id: diff --git a/gaehsnitz/templates/suff/me.html b/gaehsnitz/templates/suff/me.html index b306640..69765b8 100644 --- a/gaehsnitz/templates/suff/me.html +++ b/gaehsnitz/templates/suff/me.html @@ -42,7 +42,7 @@