diff --git a/stregsystem/admin.py b/stregsystem/admin.py index 8b4620d7..ee5b936a 100644 --- a/stregsystem/admin.py +++ b/stregsystem/admin.py @@ -139,6 +139,8 @@ class ProductAdmin(admin.ModelAdmin): ) fields = ( "name", + "name_style", + "description", "price", ("active", "deactivate_date"), ("start_date", "quantity", "get_bought"), diff --git a/stregsystem/fixtures/testdata-themes.json b/stregsystem/fixtures/testdata-themes.json index fca5b0e5..1bd37cc0 100644 --- a/stregsystem/fixtures/testdata-themes.json +++ b/stregsystem/fixtures/testdata-themes.json @@ -1,94 +1,74 @@ [ - { - "model": "auth.user", - "pk": 1, - "fields": { - "password": "pbkdf2_sha256$30000$ivRA8qABWClG$pxi2R4uyotlGpwa66RQuDOXFaO9JElQutMFJqXmnOdI=", - "is_superuser": true, - "username": "tester", - "first_name": "test", - "last_name": "testsen", - "is_staff": true - } - }, - { - "model": "auth.user", - "pk": 2, - "fields": { - "password": "pbkdf2_sha256$30000$ivRA8qABWClG$pxi2R4uyotlGpwa66RQuDOXFaO9JElQutMFJqXmnOdI=", - "is_superuser": true, - "username": "q", - "first_name": "q", - "last_name": "q", - "is_staff": true - } - }, - { - "model": "auth.user", - "pk": 3, - "fields": { - "password": "pbkdf2_sha256$30000$ivRA8qABWClG$pxi2R4uyotlGpwa66RQuDOXFaO9JElQutMFJqXmnOdI=", - "username": "nodough", - "first_name": "no", - "last_name": "dough" - } - }, - { - "model": "auth.user", - "pk": 4, - "fields": { - "password": "pbkdf2_sha256$30000$ivRA8qABWClG$pxi2R4uyotlGpwa66RQuDOXFaO9JElQutMFJqXmnOdI=", - "username": "lowdough", - "first_name": "low", - "last_name": "dough" - } - }, { "model": "stregsystem.member", "pk": 1, "fields": { + "active": true, "username": "tester", + "year": "2025", "firstname": "Test", "lastname": "Testsen", + "gender": "", "email": "plznospam@fklub.dk", + "want_spam": true, "balance": 13366037, - "notes": "This is a test user." + "undo_count": 0, + "notes": "This is a test user.", + "signup_due_paid": true } }, { "model": "stregsystem.member", "pk": 2, "fields": { + "active": true, "username": "q", + "year": "2025", "firstname": "q", "lastname": "q", + "gender": "", "email": "plznospam@fklub.dk", + "want_spam": true, "balance": 13366037, - "notes": "This is a test user with a short name for maximum testing speed." + "undo_count": 0, + "notes": "This is a test user with a short name for maximum testing speed.", + "signup_due_paid": true } }, { "model": "stregsystem.member", "pk": 3, "fields": { + "active": true, "username": "nodough", + "year": "2025", "firstname": "No", "lastname": "Dough", + "gender": "", "email": "plznospam@fklub.dk", + "want_spam": true, "balance": 0, - "notes": "This is a test user with no stregdollars." + "undo_count": 0, + "notes": "This is a test user with no stregdollars.", + "signup_due_paid": true } }, { "model": "stregsystem.member", "pk": 4, "fields": { + "active": true, "username": "lowdough", + "year": "2025", "firstname": "Low", "lastname": "Dough", + "gender": "", "email": "plznospam@fklub.dk", + "want_spam": true, "balance": 1500, - "notes": "This is a test user with only 15 stregdollars." + "undo_count": 0, + "notes": "This is a test user with only 15 stregdollars.", + "signup_due_paid": true } }, { @@ -217,6 +197,24 @@ "name": "Te" } }, + { + "model": "stregsystem.room", + "pk": 1, + "fields": { + "name": "testrummet", + "description": "127.0.0.1", + "notes": "" + } + }, + { + "model": "stregsystem.room", + "pk": 2, + "fields": { + "name": "maymayrummet", + "description": "svedigt", + "notes": "" + } + }, { "model": "stregsystem.product", "pk": 11, @@ -224,11 +222,16 @@ "name": "Stregdollar", "price": 100, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 14 + ], + "rooms": [ + 1 ] } }, @@ -239,11 +242,16 @@ "name": "\u00d8l(Gr\u00f8n, Classic, Gulddamer) (excl. pant)", "price": 750, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 3 + ], + "rooms": [ + 1 ] } }, @@ -254,11 +262,16 @@ "name": "Cocio (Mellem)", "price": 1818, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 12 + ], + "rooms": [ + 1 ] } }, @@ -269,6 +282,12 @@ "name": "Pant B (plastflasker under 1 liter)", "price": 150, "active": true, + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, + "categories": [], "rooms": [ 1 ] @@ -281,12 +300,16 @@ "name": "Voksenvand (1 kop)", "price": 150, "active": true, + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, "caffeine_content_mg": 70, - "rooms": [ - 1 - ], "categories": [ 6 + ], + "rooms": [ + 1 ] } }, @@ -297,10 +320,15 @@ "name": "Limfjordsporter (excl. pant)", "price": 1000, "active": true, + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, + "categories": [], "rooms": [ 1 - ], - "categories": [] + ] } }, { @@ -310,11 +338,16 @@ "name": "S\u00f8m", "price": 300, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 13 + ], + "rooms": [ + 1 ] } }, @@ -322,14 +355,20 @@ "model": "stregsystem.product", "pk": 51, "fields": { - "name": "

Futtetyr

", + "name": "Futtetyr", + "name_style": "font-size: 2em;\nfont-weight: bold;\ncolor: red;\nmargin: .5em 0;", "price": 33300, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 14 + ], + "rooms": [ + 1 ] } }, @@ -340,11 +379,16 @@ "name": "Mambo No. 8", "price": 800, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 7 + ], + "rooms": [ + 1 ] } }, @@ -352,14 +396,20 @@ "model": "stregsystem.product", "pk": 1836, "fields": { - "name": "

FLAN billet

", + "name": "FLAN billet", + "name_style": "font-size: 2em;\nfont-weight: bold;\ncolor: red;\nmargin: .5em 0;", "price": 4269, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 5 + ], + "rooms": [ + 1 ] } }, @@ -370,11 +420,16 @@ "name": "Life potion (excl. pant)", "price": 1316, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 11 + ], + "rooms": [ + 1 ] } }, @@ -385,11 +440,16 @@ "name": "Kildev\u00e6ld uden pant (excl. brus)\"", "price": 706, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 2 + ], + "rooms": [ + 1 ] } }, @@ -400,6 +460,12 @@ "name": "Pant A (glasflasker og metald\u00e5ser under 1 liter)", "price": 100, "active": true, + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, + "categories": [], "rooms": [ 1 ] @@ -412,11 +478,16 @@ "name": "Grimbergen (excl. pant)", "price": 1900, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 3 + ], + "rooms": [ + 1 ] } }, @@ -427,11 +498,16 @@ "name": "Somersby (incl. pant)", "price": 1540, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 17 + ], + "rooms": [ + 1 ] } }, @@ -442,11 +518,16 @@ "name": "Apache attack helicopter", "price": 1280, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 10 + ], + "rooms": [ + 1 ] } }, @@ -457,11 +538,16 @@ "name": "Kakao (0,46 kop)", "price": 69, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 12 + ], + "rooms": [ + 1 ] } }, @@ -472,11 +558,16 @@ "name": "Sportycola (excl. pant)", "price": 600, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 2 + ], + "rooms": [ + 1 ] } }, @@ -487,10 +578,15 @@ "name": "Kinley (excl. pant)", "price": 680, "active": true, - "rooms": [ + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, + "categories": [ 1 ], - "categories": [ + "rooms": [ 1 ] } @@ -502,11 +598,16 @@ "name": "Bober \u00d8l (excl. pant x2)", "price": 650, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 3 + ], + "rooms": [ + 1 ] } }, @@ -514,14 +615,21 @@ "model": "stregsystem.product", "pk": 1903, "fields": { - "name": "

M\u00e5nedens \u00d8l


September: Bonk Beer", + "name": "M\u00e5nedens \u00d8l", + "name_style": "font-size: 1.15em;\nfont-weight: bold;\nmargin: 1em 0;", + "description": "September: Bonk Beer", "price": 1460, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 4 + ], + "rooms": [ + 1 ] } }, @@ -532,11 +640,16 @@ "name": "Tebrev (Partibestemt smag)", "price": 90, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 18 + ], + "rooms": [ + 1 ] } }, @@ -547,11 +660,16 @@ "name": "Raml\u00f8se/ vand med brus (excl. pant)", "price": 808, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 2 + ], + "rooms": [ + 1 ] } }, @@ -562,11 +680,16 @@ "name": "Juice (Solita, Rynkeby)", "price": 1131, "active": true, - "rooms": [ - 1 - ], + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, "categories": [ 16 + ], + "rooms": [ + 1 ] } }, @@ -577,14 +700,53 @@ "name": "Faxe Kondi Pro", "price": 1600, "active": true, - "rooms": [ + "start_date": null, + "quantity": 0, + "deactivate_date": null, + "alcohol_content_ml": 0, + "caffeine_content_mg": 0, + "categories": [ 1 ], - "categories": [ + "rooms": [ 1 ] } }, + { + "model": "stregsystem.productnote", + "pk": 1, + "fields": { + "text": "
\r\n", + "active": true, + "background_color": "yellow", + "text_color": "black", + "start_date": "2025-01-14", + "end_date": "2125-01-14", + "comment": "", + "products": [ + 1903 + ], + "rooms": [] + } + }, + { + "model": "stregsystem.productnote", + "pk": 2, + "fields": { + "text": "Udg\u00e5r!", + "active": true, + "background_color": "red", + "text_color": "black", + "start_date": "2025-01-14", + "end_date": "2125-01-14", + "comment": "", + "products": [ + 1879 + ], + "rooms": [] + } + }, { "model": "stregsystem.namedproduct", "pk": 111, @@ -897,22 +1059,6 @@ "product": 1912 } }, - { - "model": "stregsystem.room", - "pk": 1, - "fields": { - "name": "testrummet", - "description": "127.0.0.1" - } - }, - { - "model": "stregsystem.room", - "pk": 2, - "fields": { - "name": "maymayrummet", - "description": "svedigt" - } - }, { "model": "stregsystem.sale", "pk": 1, @@ -920,7 +1066,7 @@ "member": 1, "product": 11, "room": 1, - "timestamp": "2017-03-13T12:52:52.142+00:00", + "timestamp": "2017-03-13T12:52:52.142Z", "price": 100 } }, @@ -931,7 +1077,7 @@ "member": 1, "product": 32, "room": 1, - "timestamp": "2017-03-13T12:54:12.423+00:00", + "timestamp": "2017-03-13T12:54:12.423Z", "price": 200 } }, @@ -940,21 +1086,1231 @@ "pk": 3, "fields": { "member": 1, - "product": 14, + "product": 42, "room": 1, - "timestamp": "2017-03-13T13:38:10.573+00:00", + "timestamp": "2017-03-13T13:38:10.573Z", "price": 300 } }, { - "model": "stregsystem.sale", + "model": "admin.logentry", + "pk": 1, + "fields": { + "action_time": "2025-01-13T23:27:21.879Z", + "user": 1, + "content_type": 13, + "object_id": "1", + "object_repr": "
\r\n", "active": true, - "background_color": "Yellow", - "text_color": "", + "background_color": "yellow", + "text_color": "black", "start_date": "2025-01-14", "end_date": "2125-01-14", "comment": "", @@ -732,8 +736,8 @@ "fields": { "text": "Udgår!", "active": true, - "background_color": "", - "text_color": "", + "background_color": "red", + "text_color": "black", "start_date": "2025-01-14", "end_date": "2125-01-14", "comment": "", diff --git a/stregsystem/migrations/0023_product_description_product_name_style_and_more.py b/stregsystem/migrations/0023_product_description_product_name_style_and_more.py new file mode 100644 index 00000000..f884710a --- /dev/null +++ b/stregsystem/migrations/0023_product_description_product_name_style_and_more.py @@ -0,0 +1,41 @@ +# Generated by Django 4.1.13 on 2025-01-19 00:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("stregsystem", "0022_productnote"), + ] + + operations = [ + migrations.AddField( + model_name="product", + name="description", + field=models.CharField(blank=True, max_length=64), + ), + migrations.AddField( + model_name="product", + name="name_style", + field=models.TextField( + blank=True, + help_text="If product is very cool, usually something like: font-size: 2em; font-weight: bold; color: red; margin: 1em 0;", + max_length=64, + ), + ), + migrations.AlterField( + model_name="productnote", + name="background_color", + field=models.CharField( + default="yellow", help_text="Write a valid html color", max_length=20 + ), + ), + migrations.AlterField( + model_name="productnote", + name="text_color", + field=models.CharField( + default="black", help_text="Write a valid html color", max_length=20 + ), + ), + ] diff --git a/stregsystem/models.py b/stregsystem/models.py index 1cb7fed2..cb13e62f 100644 --- a/stregsystem/models.py +++ b/stregsystem/models.py @@ -577,6 +577,12 @@ def __str__(self): class Product(models.Model): # id automatisk... name = models.CharField(max_length=64) + name_style = models.TextField( + max_length=64, + blank=True, + help_text="If product is very cool, usually something like: font-size: 2em; font-weight: bold; color: red; margin: 1em 0;", + ) + description = models.CharField(max_length=64, blank=True) price = models.IntegerField() # penge, oere... active = models.BooleanField() start_date = models.DateField(blank=True, null=True) @@ -640,9 +646,9 @@ class ProductNote(models.Model): text = models.TextField() active = models.BooleanField(default=True) background_color = models.CharField( - max_length=20, help_text="Write a valid html color (default: red)", blank="red" + max_length=20, help_text="Write a valid html color", default="yellow" ) # If anyone wants to use LightGoldenRodYellow, they can - text_color = models.CharField(max_length=20, help_text="Write a valid html color (default: black)", blank="black") + text_color = models.CharField(max_length=20, help_text="Write a valid html color", default="black") start_date = models.DateField() end_date = models.DateField() comment = models.TextField(blank=True) diff --git a/stregsystem/static/stregsystem/stregsystem.css b/stregsystem/static/stregsystem/stregsystem.css index 4f484f34..23aba79d 100644 --- a/stregsystem/static/stregsystem/stregsystem.css +++ b/stregsystem/static/stregsystem/stregsystem.css @@ -79,10 +79,13 @@ button { font: inherit; text-decoration: underline; color: LinkText; - - &:active{ + &:active { color: ActiveText; } + + & * { + text-decoration: underline; + } } } @@ -138,6 +141,19 @@ table h2, table h3 { margin-bottom: 6px; } +#product-overview { + & button { + text-align: left; + } + & span { + display: inline-block; + } + & .note-box { + padding: 2px 4px 2px 4px; + border-radius: 8px; + } +} + .center-around { font-size: 0.8rem; line-height: 0.8rem; diff --git a/stregsystem/templates/stregsystem/index.html b/stregsystem/templates/stregsystem/index.html index 81b92ec4..eb7bf9b6 100644 --- a/stregsystem/templates/stregsystem/index.html +++ b/stregsystem/templates/stregsystem/index.html @@ -26,13 +26,6 @@ margin-top: 1.5em; margin-bottom: 1.5em; } - .note-box { - display: inline; - padding: 2px 4px 2px 4px; - border-radius: 8px; - color: black; - background-color: red; - } {% endblock %} @@ -66,7 +59,7 @@
{% block message %}{% endblock %}
-
+
{% block products %} {% if product_note_pair_list %} {% autoescape off %} @@ -83,9 +76,22 @@ {% for note in pair.note %} -
{{note.text}}
+ {{note.text}} {% endfor %} - {{pair.product.name}} + + {{pair.product.name}} + + {% if pair.product.description %} +
+ + {{pair.product.description}} + + {% endif %} {{pair.product.price|money}} kr @@ -103,9 +109,22 @@ {{pair.product.id|product_id_and_alias_string}} {% for note in pair.note %} -
{{note.text}}
+ {{note.text}} {% endfor %} - {{pair.product.name}} + + {{pair.product.name}} + + {% if pair.product.description %} +
+ + {{pair.product.description}} + + {% endif %} {{pair.product.price|money}} kr diff --git a/stregsystem/templates/stregsystem/menu.html b/stregsystem/templates/stregsystem/menu.html index 809f1986..08bb3921 100644 --- a/stregsystem/templates/stregsystem/menu.html +++ b/stregsystem/templates/stregsystem/menu.html @@ -83,33 +83,69 @@

Du {% csrf_token %} -
+
- {% for product in product_list|partition:"2"|first %} + {% for pair in product_note_pair_list|partition:"2"|first %} - + {% endfor %}
Produkt Pris
- + {{product.price|money}} kr{{pair.product.price|money}} kr
- {% if product_list|partition:"2"|last %} + {% if product_note_pair_list|partition:"2"|last %} - {% for product in product_list|partition:"2"|last %} + {% for pair in product_note_pair_list|partition:"2"|last %} - + {% endfor %}
Produkt Pris
- + {{product.price|money}} kr{{pair.product.price|money}} kr
diff --git a/stregsystem/tests.py b/stregsystem/tests.py index bf953762..f16b04dc 100644 --- a/stregsystem/tests.py +++ b/stregsystem/tests.py @@ -799,7 +799,7 @@ def test_chosen_color(self): text="COLORED-NOTE", start_date=datetime.date.today(), end_date=datetime.date.today(), - background_color="Yellow", + background_color="yellow", ) self.test_product_note.save() self.test_product_note.products.add(test_product) @@ -809,7 +809,7 @@ def test_chosen_color(self): self.assertContains( response, - "
COLORED-NOTE
", + "COLORED-NOTE", html=True, ) diff --git a/stregsystem/views.py b/stregsystem/views.py index dcc14c13..e8944581 100644 --- a/stregsystem/views.py +++ b/stregsystem/views.py @@ -96,6 +96,7 @@ def roomindex(request): def index(request, room_id): room = get_object_or_404(Room, pk=int(room_id)) + product_list = __get_productlist(room_id) ProductNotePair = namedtuple('ProductNotePair', 'product note') product_note_pair_list = [ ProductNotePair(product, __get_active_notes_for_product(product)) for product in __get_productlist(room_id) @@ -122,6 +123,10 @@ def sale(request, room_id): room = get_object_or_404(Room, pk=room_id) news = __get_news() product_list = __get_productlist(room_id) + ProductNotePair = namedtuple('ProductNotePair', 'product note') + product_note_pair_list = [ + ProductNotePair(product, __get_active_notes_for_product(product)) for product in __get_productlist(room_id) + ] buy_string = request.POST['quickbuy'].strip() # Handle empty line @@ -188,6 +193,10 @@ def _multibuy_hint(now, member): def quicksale(request, room, member: Member, bought_ids): news = __get_news() product_list = __get_productlist(room.id) + ProductNotePair = namedtuple('ProductNotePair', 'product note') + product_note_pair_list = [ + ProductNotePair(product, __get_active_notes_for_product(product)) for product in __get_productlist(room.id) + ] now = timezone.now() # Retrieve products and construct transaction @@ -228,6 +237,10 @@ def quicksale(request, room, member: Member, bought_ids): def usermenu(request, room, member, bought, from_sale=False): negative_balance = member.balance < 0 product_list = __get_productlist(room.id) + ProductNotePair = namedtuple('ProductNotePair', 'product note') + product_note_pair_list = [ + ProductNotePair(product, __get_active_notes_for_product(product)) for product in __get_productlist(room.id) + ] news = __get_news() promille = member.calculate_alcohol_promille() (