Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
05bc812
added dress code as a field in event
Trobbi May 14, 2025
fd00ffd
also added event price
Trobbi May 14, 2025
c6b5a92
changed to int, should be better
Trobbi May 14, 2025
75e1ddc
removed cash field and added less than 0 price check :trollface:
Trobbi May 19, 2025
2d27e33
Merge branch 'main' into add-dresscode-to-event
Trobbi May 19, 2025
53245b1
added check to see if me is signed up 👻
Trobbi May 19, 2025
e16909a
fixed alcohol event type :beers:
Trobbi May 26, 2025
2168f39
fix i mission groups osv, added so missions are either accepted or not
Trobbi May 26, 2025
b096657
fixed remove route
Trobbi May 26, 2025
470b364
added so event has a field for the confirmed users and a route for ad…
Trobbi May 27, 2025
eda8470
Merge branch 'alkohol_types' into app-route-work
Trobbi Jun 15, 2025
f1aa2c7
Merge branch 'accept-mission' into app-route-work
Trobbi Jun 15, 2025
300fd65
Merge branch 'users-that-got-in-event' into app-route-work
Trobbi Jun 15, 2025
0c16d74
the other solution was poop, this is better
Trobbi Jun 15, 2025
5837b24
changed how event prices work, for free, put 0
Trobbi Jun 15, 2025
eb02817
Merge branch 'add-dresscode-to-event' into app-route-work
Trobbi Jun 15, 2025
21c2d93
fixed some errors
Trobbi Jun 15, 2025
296d7b2
added so event has a field for how many are signed up, idk if this is…
Trobbi Jun 15, 2025
57cebaa
changed the signoff route
Trobbi Jun 25, 2025
a6fda6f
added some checks in signup and removed signup_not_opened_yet
Trobbi Jun 25, 2025
c78ac5f
added field in schema
Trobbi Jun 25, 2025
0f6f22b
bruh
Trobbi Jun 25, 2025
b313db9
skjut mig
Trobbi Jun 25, 2025
cf9a37a
frogor
Trobbi Jun 25, 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
28 changes: 17 additions & 11 deletions api_schemas/event_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from api_schemas.event_signup_schemas import EventSignupRead
from db_models.priority_model import Priority_DB
from helpers.constants import MAX_EVENT_DESC, MAX_EVENT_TITLE
from helpers.types import MEMBER_ROLES, datetime_utc
from helpers.types import ALCOHOL_EVENT_TYPES, EVENT_DOT_TYPES, MEMBER_ROLES, datetime_utc
from pydantic import StringConstraints

if TYPE_CHECKING:
Expand All @@ -26,15 +26,18 @@ class EventRead(BaseSchema):
max_event_users: int
priorities: list[Priority_DB]
all_day: bool
signup_not_opened_yet: bool
recurring: bool
drink: bool
food: bool
cash: bool
closed: bool
can_signup: bool
drink_package: bool
is_nollning_event: bool
alcohol_event_type: str
dress_code: str
price: int
signup_count: int
dot: str
lottery: bool


# we dont need to be as strict about out data as in data.
Expand All @@ -55,15 +58,17 @@ class EventCreate(BaseSchema):
max_event_users: int
priorities: list[MEMBER_ROLES]
all_day: bool
signup_not_opened_yet: bool
recurring: bool
drink: bool
food: bool
cash: bool
closed: bool
can_signup: bool
drink_package: bool
is_nollning_event: bool
alcohol_event_type: ALCOHOL_EVENT_TYPES
dress_code: str
price: int
dot: EVENT_DOT_TYPES
lottery: bool


class EventUpdate(BaseSchema):
Expand All @@ -76,18 +81,19 @@ class EventUpdate(BaseSchema):
title_en: Annotated[str, StringConstraints(max_length=MAX_EVENT_TITLE)] | None = None
description_sv: Annotated[str, StringConstraints(max_length=MAX_EVENT_DESC)] | None = None
description_en: Annotated[str, StringConstraints(max_length=MAX_EVENT_DESC)] | None = None
location: str
location: str | None = None
max_event_users: int | None = None
all_day: bool | None = None
signup_not_opened_yet: bool | None = None
recurring: bool | None = None
drink: bool | None = None
food: bool | None = None
cash: bool | None = None
closed: bool | None = None
can_signup: bool | None = None
drink_package: bool | None = None
is_nollning_event: bool | None = None
alcohol_event_type: ALCOHOL_EVENT_TYPES | None = None
dresscode: str | None = None
price: int | None = None
dot: EVENT_DOT_TYPES | None = None


class AddEventTag(BaseSchema):
Expand Down
5 changes: 3 additions & 2 deletions api_schemas/event_signup_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class EventSignupRead(BaseSchema):
priority: str
group_name: str
drinkPackage: DRINK_PACKAGES
confirmed_status: bool


class EventSignupUpdate(BaseSchema):
Expand All @@ -27,5 +28,5 @@ class EventSignupUpdate(BaseSchema):
drinkPackage: DRINK_PACKAGES | None = None


class EventSignupDelete(BaseSchema):
user_id: int | None = None
# class EventSignupDelete(BaseSchema):
# user_id: int
6 changes: 4 additions & 2 deletions api_schemas/group_mission_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ class GroupMissionCreate(BaseSchema):


class GroupMissionEdit(BaseSchema):
points: int
adventure_mission_id: int
points: int | None = None
adventure_mission_id: int | None = None
is_accepted: bool | None = None


class GroupMissionRead(BaseSchema):
points: int
adventure_mission: AdventureMissionRead
nollning_group: NollningGroupRead
is_accepted: bool
19 changes: 14 additions & 5 deletions db_models/event_model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from helpers.types import datetime_utc
from helpers.types import ALCOHOL_EVENT_TYPES, EVENT_DOT_TYPES, datetime_utc
from typing import TYPE_CHECKING
from sqlalchemy import ForeignKey, String
from sqlalchemy import ForeignKey, String, Enum
from sqlalchemy.orm import mapped_column, Mapped, relationship
from helpers.constants import MAX_EVENT_DESC, MAX_EVENT_LOCATION, MAX_EVENT_TITLE
from .base_model import BaseModel_DB
Expand Down Expand Up @@ -35,6 +35,14 @@ class Event_DB(BaseModel_DB):

location: Mapped[str] = mapped_column(String(MAX_EVENT_LOCATION))

dress_code: Mapped[str] = mapped_column(String(MAX_EVENT_TITLE))

price: Mapped[int] = mapped_column()

signup_count: Mapped[int] = mapped_column(init=False, default=0)

alcohol_event_type: Mapped[ALCOHOL_EVENT_TYPES] = mapped_column()

max_event_users: Mapped[int] = mapped_column(default=0)

event_users: Mapped[list["EventUser_DB"]] = relationship(
Expand All @@ -50,11 +58,8 @@ class Event_DB(BaseModel_DB):
)

all_day: Mapped[bool] = mapped_column(default=False)
signup_not_opened_yet: Mapped[bool] = mapped_column(default=True)
recurring: Mapped[bool] = mapped_column(default=False)
drink: Mapped[bool] = mapped_column(default=False)
food: Mapped[bool] = mapped_column(default=False)
cash: Mapped[bool] = mapped_column(default=False)
closed: Mapped[bool] = mapped_column(default=False)
can_signup: Mapped[bool] = mapped_column(default=False)
drink_package: Mapped[bool] = mapped_column(default=False)
Expand All @@ -64,3 +69,7 @@ class Event_DB(BaseModel_DB):
)

is_nollning_event: Mapped[bool] = mapped_column(default=False)

dot: Mapped[EVENT_DOT_TYPES] = mapped_column(default="None")

lottery: Mapped[bool] = mapped_column(default=False)
6 changes: 5 additions & 1 deletion db_models/event_user_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import TYPE_CHECKING, Optional
from sqlalchemy import Column, DateTime, ForeignKey
from sqlalchemy import Column, DateTime, Enum, ForeignKey

# from helpers.types import MEMBER_TYPE
from .base_model import BaseModel_DB
Expand All @@ -22,6 +22,10 @@ class EventUser_DB(BaseModel_DB):
event: Mapped["Event_DB"] = relationship(back_populates="event_users")
event_id: Mapped[int] = mapped_column(ForeignKey("event_table.id"), primary_key=True)

confirmed_status: Mapped[str] = mapped_column(
Enum("confirmed", "unconfirmed", name="confirmed_enum"), default="unconfirmed"
)

group_name: Mapped[Optional[str]] = mapped_column(default=None)
priority: Mapped[str] = mapped_column(default="Övrigt")
drinkPackage: Mapped[str] = mapped_column(default="None")
Expand Down
2 changes: 2 additions & 0 deletions db_models/group_mission_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ class GroupMission_DB(BaseModel_DB):

nollning_group: Mapped["NollningGroup_DB"] = relationship(back_populates="group_missions")
nollning_group_id: Mapped[int] = mapped_column(ForeignKey("nollning_group_table.id"), primary_key=True)

is_accepted: Mapped[bool] = mapped_column(default=False, init=False)
4 changes: 4 additions & 0 deletions helpers/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,7 @@ def force_utc(date: datetime):
FOOD_PREFERENCES = Literal["Vegetarian", "Vegan", "Pescetarian", "Mjölkallergi", "Gluten"]

DRINK_PACKAGES = Literal["None", "AlcoholFree", "Alcohol"]

ALCOHOL_EVENT_TYPES = Literal["Alcohol", "Alcohol-Served", "None"]

EVENT_DOT_TYPES = Literal["None", "Single", "Double"]
26 changes: 26 additions & 0 deletions routes/event_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ def get_random_event_signup(event_id: int, db: DB_dependency):
return users


@event_router.patch(
"/event-confirm-event-users/{event_id}",
dependencies=[Permission.require("manage", "Event")],
response_model=EventRead,
)
def confirm_event_users(db: DB_dependency, event_id: int, confirmed_users: list[UserRead]):
event = db.query(Event_DB).filter_by(id=event_id).one_or_none()

if not event:
raise HTTPException(404, detail="Event not found")

if len(confirmed_users) > event.max_event_users:
raise HTTPException(400, detail="Too many users for chosen event")

confirmed_user_ids = [user.id for user in confirmed_users]

for event_user in event.event_users:
if event_user.user_id in confirmed_user_ids:
event_user.confirmed_status = "confirmed"

db.commit()
db.refresh(event)

return event


@event_router.post("/add-tag", dependencies=[Permission.require("manage", "Event")], response_model=AddEventTag)
def add_tag_to_event(data: AddEventTag, db: DB_dependency):

Expand Down
19 changes: 14 additions & 5 deletions routes/event_signup_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from db_models.event_model import Event_DB
from db_models.event_user_model import EventUser_DB
from db_models.user_model import User_DB
from services.event_signup_service import signup_to_event, signoff_from_event, update_event_signup
from services.event_signup_service import signup_to_event, signoff_from_event, update_event_signup, check_me_signup
from user.permission import Permission
from api_schemas.event_signup_schemas import EventSignupCreate, EventSignupRead, EventSignupUpdate, EventSignupDelete
from api_schemas.event_signup_schemas import EventSignupCreate, EventSignupRead, EventSignupUpdate
from pydantic_extra_types.phone_numbers import PhoneNumber
from api_schemas.event_schemas import EventRead

Expand Down Expand Up @@ -43,7 +43,7 @@ def event_signup_route(
@event_signup_router.delete("/{event_id}", response_model=EventSignupRead)
def event_signoff_route(
event_id: int,
data: EventSignupDelete,
user_id: int,
me: Annotated[User_DB, Permission.member()],
manage_permission: Annotated[bool, Permission.check("manage", "Event")],
db: DB_dependency,
Expand All @@ -52,13 +52,13 @@ def event_signoff_route(
if event is None:
raise HTTPException(status.HTTP_404_NOT_FOUND)

if data.user_id is None or data.user_id == me.id:
if user_id == me.id:
return signoff_from_event(event, me.id, manage_permission, db)

if manage_permission == False:
raise HTTPException(status.HTTP_400_BAD_REQUEST, "Check your permissions mate")

return signoff_from_event(event, data.user_id, manage_permission, db)
return signoff_from_event(event, user_id, manage_permission, db)


@event_signup_router.patch("/{event_id}", response_model=EventSignupRead)
Expand All @@ -82,6 +82,15 @@ def update_event_signup_route(
return update_event_signup(event, data, data.user_id, manage_permission, db)


@event_signup_router.get("/me-signup/{event_id}", response_model=EventSignupRead)
def get_me_event_signup(event_id: int, me: Annotated[User_DB, Permission.member()], db: DB_dependency):
event = db.query(Event_DB).filter_by(id=event_id).one_or_none()
if event is None:
raise HTTPException(404, detail="Event not found")

return check_me_signup(event_id, me, db)


# @event_signup_router.get("/{event_id}", response_model=list[EventSignupRead])
# def get_all_signups(event_id: int, db: DB_dependency):
# signups = db.query(EventUser_DB).filter(EventUser_DB.event_id == event_id).all()
Expand Down
29 changes: 27 additions & 2 deletions routes/nollning_router.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from fastapi import APIRouter
from sqlalchemy import desc
from fastapi import APIRouter, HTTPException
from sqlalchemy import and_, desc
from api_schemas.group_schema import GroupRead
from api_schemas.nollning_schema import (
NollningCreate,
NollningRead,
Expand All @@ -9,6 +10,8 @@
)
from database import DB_dependency
from db_models.nollning_model import Nollning_DB
from db_models.nollning_group_model import NollningGroup_DB
from db_models.group_mission_model import GroupMission_DB
from services.nollning_service import (
add_g_to_nollning,
create_nollning,
Expand Down Expand Up @@ -70,3 +73,25 @@ def get_all_nollning_groups(db: DB_dependency, id: int):
)
def delete_group_mission(db: DB_dependency, id: int, data: NollningDeleteMission):
return delete_group_m(db, id, data)


@nollning_router.delete(
"/remove_group/{nollning_group_id}",
dependencies=[Permission.require("manage", "Nollning")],
response_model=NollningGroupRead,
)
def remove_group_from_nollning(db: DB_dependency, nollning_group_id: int):
nollning_group = db.query(NollningGroup_DB).filter_by(id=nollning_group_id).one_or_none()

if not nollning_group:
raise HTTPException(404, detail="Group not in nollning")

completed_missions = db.query(GroupMission_DB).filter_by(nollning_group_id=nollning_group.id).all()

if completed_missions:
raise HTTPException(409, detail="Group has missions in nollning and therefore cannot be unlinked")

db.delete(nollning_group)
db.commit()

return nollning_group
5 changes: 5 additions & 0 deletions seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ def seed_events(db: Session, one_council: Council_DB):
signup_start=signup_start,
signup_end=signup_end,
location="Mattehuset",
dress_code="vad du vill",
price=123,
alcohol_event_type="Alcohol",
dot="Double",
lottery=False,
)
db.add(event)
db.commit()
Expand Down
4 changes: 2 additions & 2 deletions services/adventure_mission_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def create_adventure_mission(db: Session, data: AdventureMissionCreate):
if data.max_points < 1:
raise HTTPException(400, detail="Max points has to be atleast 1")

if data.min_points < 1:
raise HTTPException(400, detail="Min points has to be atleast 1")
if data.min_points < 0:
raise HTTPException(400, detail="Min points has to be atleast 0")

new_adventure_mission = AdventureMission_DB(
nollning_id=data.nollning_id,
Expand Down
19 changes: 15 additions & 4 deletions services/event_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ def create_new_event(data: EventCreate, db: Session):
if start < datetime.now(UTC):
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail="Event start cannot be in the past, silly.")

if data.price < 0:
raise HTTPException(400, detail="price cannot be lower than 0")

# Check if council exists. It's just some extra validation
council = db.query(Council_DB).filter_by(id=data.council_id).one_or_none()
if council is None:
raise HTTPException(status.HTTP_404_NOT_FOUND, "That council does not exist")

if data.price < 0:
raise HTTPException(400, detail="Price cannot be lower than 0")

event = Event_DB(
starts_at=start,
ends_at=end,
Expand All @@ -37,16 +43,18 @@ def create_new_event(data: EventCreate, db: Session):
signup_end=signup_end,
max_event_users=data.max_event_users,
all_day=data.all_day,
signup_not_opened_yet=data.signup_not_opened_yet,
recurring=data.recurring,
drink=data.drink,
food=data.food,
cash=data.cash,
closed=data.closed,
can_signup=data.can_signup,
drink_package=data.drink_package,
location=data.location,
is_nollning_event=data.is_nollning_event,
dress_code=data.dress_code,
price=data.price,
alcohol_event_type=data.alcohol_event_type,
dot=data.dot,
lottery=data.lottery,
)
db.add(event) # This adds the event itself to the session
db.flush() # This is optional but can be helpful to ensure 'event.id' is set if used immediately after
Expand Down Expand Up @@ -79,7 +87,10 @@ def update_event(event_id: int, data: EventUpdate, db: Session):
event = db.query(Event_DB).filter_by(id=event_id).one_or_none()

if not event:
raise HTTPException(status.HTTP_404_NOT_FOUND)
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="Event not found")

if data.price is not None and data.price < 0:
raise HTTPException(400, detail="Price cannot be lower than 0")

for var, value in vars(data).items():
setattr(event, var, value) if value is not None else None
Expand Down
Loading