Skip to content
Open
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
14d6a4a
made achivements.html file
CHSten Apr 3, 2025
34b4b73
fremskridt
CHSten Apr 7, 2025
e18aafd
AchievementAdmin models + testdata
CHSten Apr 13, 2025
c7d317d
Add achievement-border-glow.webp via upload
CHSten Apr 13, 2025
b4d7578
Added achievements to menu_userinfo.html
CHSten Apr 15, 2025
80ae100
Updated achievements.py & achievement models
CHSten Apr 18, 2025
f62f6c0
Added AchievementConstraint model
CHSten Apr 25, 2025
8ed2a8a
it works now!
CHSten Apr 25, 2025
cb9b65b
Fixed underscores of private functions
CHSten Apr 29, 2025
4823a2f
added Sales History
CHSten Apr 30, 2025
840a041
Achievements readme
henneboy Apr 30, 2025
d951d41
Merge pull request #1 from CHSten/add-achievements-md
CHSten Apr 30, 2025
5e46a67
Changed how achievements are stored
CHSten Apr 30, 2025
6e0d6d1
Merge branch 'next' of https://github.com/CHSten/stregsystemet into next
CHSten Apr 30, 2025
cf6bffc
Changed the models + backend
CHSten May 1, 2025
b640439
Added Types & Comments
CHSten May 7, 2025
d9a7fb6
Added Alcohol and Caffeine Content
CHSten May 7, 2025
c9595b0
alcohol content fix
CHSten May 7, 2025
11df34d
fixed alcohol content and caffeine content fix
CHSten May 7, 2025
07f9fca
Made top percentage round to 2 decimals
CHSten May 7, 2025
f67bb76
Updated admin.py
CHSten May 7, 2025
4503e83
Added Clean() + achievements.md
CHSten May 9, 2025
54dd42e
Ran Black Code Formatter on modified files
CHSten May 9, 2025
5feb30c
Reduced migrations & Added some tests
CHSten May 13, 2025
35cce16
Added tests
CHSten May 14, 2025
185a694
ran Black Code Formatter
CHSten May 14, 2025
4d9ba00
Tweaked __str__ function to AchievementConstraint
CHSten May 14, 2025
2a06f2c
Fixed everything
CHSten May 23, 2025
f3ea7b4
Did black formatting again
CHSten May 23, 2025
52a358a
Fixed failing tests
CHSten May 23, 2025
ff02d79
Merge branch 'next' into next
CHSten Sep 8, 2025
5b0c222
Minor changes to get_user_leaderboard_position()
CHSten Sep 8, 2025
cccf05e
Fixed test issues
CHSten Sep 8, 2025
321074e
Forgot to push file
CHSten Sep 9, 2025
ce9fd37
Delete .vscode/settings.json
CHSten Sep 9, 2025
77824dd
Delete .python-version
CHSten Sep 9, 2025
e6fc720
Merge branch 'next' into next
CHSten Oct 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,7 @@ Using the debugging tool [MailHog](https://github.com/mailhog/MailHog) (Follow t
Themes
-------
[Read more about themes here.](./themes.md)

Achievements
-------
[Read more about achievements here.](./achievements.md)
49 changes: 49 additions & 0 deletions achievements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Achievements

An achievement is a milestone which is stored in the database for the individual member.

# Achievements database structure

`Achievement` defines an achievement with a title, description, icon, and optional timing rules.
Only one of begin_at or duration can be set.

`AchievementConstraint` is an optional time-based restrictions (e.g., date, time, weekday) tied to an achievement.
Useful for limiting when an achievement can be completed.

`AchievementTask` defines what a user must do to earn an achievement. Linked to a product, category, alcohol_content, or caffeine_content — only one of these may be set.
Supports different task types like spending/remaining funds.

`AchievementComplete` tracks when a member completes an achievement. Each member can only complete an achievement once.

## How to Add an Achievement

### What Achievements Can Track

- Product or category purchase amounts
- Used or remaining funds
- Alcohol or caffeine content

### Optional Constraints

- Specific months, days, times, or weekdays for completion

### Steps to Add and Achievement

1. Log in to the Admin panel:

- Admin panel: <http://127.0.0.1:8000/admin/>
- Login: `tester:treotreo`

2. Create a new Achievement
3. Add one or more AchievementTask entries linked to that achievement
4. (*Optional*) Add AchievementConstraint entries if you want time-based restrictions

### Adding Custom Logic

For achievements with unique behavior, add a new task_type in AchievementTask and implement the logic in achievements.py.

## Achievement Ideas
* Quite the bartender: Pomster = Limfjordsporter + Monster
* Keeper of secrets: buy a fytteturs billet.
* Ægte Datalog: buy a limfjordsporter
* Exam Week Warrior – Buy 3 energy drinks or coffees during exam month
38 changes: 28 additions & 10 deletions kiosk/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-04-21 14:26
from __future__ import unicode_literals
# Generated by Django 4.1.13 on 2025-05-14 07:58

from django.db import migrations, models
import kiosk.models
import kiosk.validators


class Migration(migrations.Migration):

initial = True

dependencies = [
]
dependencies = []

operations = [
migrations.CreateModel(
name='KioskItem',
name="KioskItem",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(blank=True, max_length=100, null=True)),
('active', models.BooleanField(default=True)),
('image', models.ImageField(upload_to='kiosk')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(blank=True, max_length=100, null=True)),
("notes", models.CharField(blank=True, max_length=2000, null=True)),
("uploaded_date", models.DateField(auto_now_add=True)),
("active", models.BooleanField(default=True)),
(
"media",
models.FileField(
upload_to="kiosk",
validators=[kiosk.validators.validate_file_extension],
),
),
("ordering", models.IntegerField(default=kiosk.models.random_ordering)),
("start_datetime", models.DateTimeField(blank=True, null=True)),
("end_datetime", models.DateTimeField(blank=True, null=True)),
],
),
]
27 changes: 0 additions & 27 deletions kiosk/migrations/0002_auto_20170913_1632.py

This file was deleted.

21 changes: 0 additions & 21 deletions kiosk/migrations/0003_kioskitem_ordering.py

This file was deleted.

19 changes: 0 additions & 19 deletions kiosk/migrations/0004_kioskitem_media.py

This file was deleted.

27 changes: 0 additions & 27 deletions kiosk/migrations/0005_migrate_image_to_media_20201112_1713.py

This file was deleted.

23 changes: 0 additions & 23 deletions kiosk/migrations/0006_remove_image_20201112_1715.py

This file was deleted.

23 changes: 0 additions & 23 deletions kiosk/migrations/0007_auto_20230823_1138.py

This file was deleted.

11 changes: 3 additions & 8 deletions razzia/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.1.13 on 2024-09-14 13:35
# Generated by Django 4.1.13 on 2025-05-14 07:58

import datetime
from django.db import migrations, models
Expand All @@ -10,10 +10,7 @@ class Migration(migrations.Migration):
initial = True

dependencies = [
(
"stregsystem",
"0018_member_signup_due_paid_alter_mobilepayment_status_and_more",
),
("stregsystem", "0001_initial"),
]

operations = [
Expand All @@ -35,9 +32,7 @@ class Migration(migrations.Migration):
("start_date", models.DateTimeField(auto_now_add=True)),
],
options={
"permissions": (
("host_razzia", "Can host a foobar, fnugfald or bread razzia"),
),
"permissions": (("browse_razzia", "Can browse razzias"),),
},
),
migrations.CreateModel(
Expand Down
17 changes: 0 additions & 17 deletions razzia/migrations/0002_alter_razzia_options.py

This file was deleted.

73 changes: 67 additions & 6 deletions stregreport/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,84 @@
# Generated by Django 2.0.2 on 2018-09-27 13:12
# Generated by Django 4.1.13 on 2025-05-14 07:58

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('stregsystem', '0008_add_sale_products_id_timestamp_index'),
("stregsystem", "0001_initial"),
]

operations = [
migrations.CreateModel(
name='BreadRazzia',
name="BreadRazzia",
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('start_date', models.DateTimeField(auto_now_add=True)),
('members', models.ManyToManyField(to='stregsystem.Member')),
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("start_date", models.DateTimeField(auto_now_add=True)),
(
"razzia_type",
models.CharField(
choices=[
("BR", "Brødrazzia"),
("FB", "Foobar razzia"),
("FF", "Fnugfald razzia"),
],
default="BR",
max_length=2,
),
),
],
options={
"permissions": (
("host_razzia", "Can host a foobar, fnugfald or bread razzia"),
),
},
),
migrations.CreateModel(
name="RazziaEntryOld",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("time", models.DateTimeField(auto_now_add=True, null=True)),
(
"member",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="stregsystem.member",
),
),
(
"razzia",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="stregreport.breadrazzia",
),
),
],
),
migrations.AddField(
model_name="breadrazzia",
name="members",
field=models.ManyToManyField(
through="stregreport.RazziaEntryOld", to="stregsystem.member"
),
),
]
Loading