Skip to content

Commit

Permalink
Event report (#52)
Browse files Browse the repository at this point in the history
* Updated event model str types to more understandable one

* Added db index for event code

* Added event reports backend

* minor change after merge

* event id mistake cleared

* Allow collab clubs to also fetch the budget and other details for an event

* Allow collab clubs also to check bills status

* access to collab clubs added to view report

* instead of raising exception sending empty response

* Return relevant error/s if bill not found for an event

* added eventreport submissionstatus  in alleventbills query

---------

Co-authored-by: dileepadari <[email protected]>
  • Loading branch information
bhavberi and Dileepadari authored Jan 3, 2025
1 parent 819714b commit cbe41b4
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 31 deletions.
9 changes: 9 additions & 0 deletions db.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
db = client[MONGO_DATABASE]
eventsdb = db.events
holidaysdb = db.holidays
event_reportsdb = db.event_reports

try:
# check if the holidays index exists
Expand All @@ -25,5 +26,13 @@
holidaysdb.create_index(
[("date", 1)], unique=True, name="one_holiday_on_day"
)
if "unique_event_code" not in eventsdb.index_information():
eventsdb.create_index(
[("code", 1)], unique=True, name="unique_event_code"
)
if "unique_event_id" not in event_reportsdb.index_information():
event_reportsdb.create_index(
[("event_id", 1)], unique=True, name="unique_event_id"
)
except Exception:
pass
40 changes: 31 additions & 9 deletions models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
BaseModel,
ConfigDict,
Field,
HttpUrl,
ValidationInfo,
field_validator,
)
Expand All @@ -17,40 +18,59 @@
Event_Mode,
Event_Status,
HttpUrlString,
PrizesType,
PyObjectId,
event_desc_type,
event_name_type,
event_othr_type,
event_popu_type,
long_str_type,
medium_str_type,
short_str_type,
timezone,
very_short_str_type,
)


class EventReport(BaseModel):
eventid: str
summary: medium_str_type
attendance: event_popu_type
prizes: List[PrizesType] = []
prizes_breakdown: long_str_type
winners: long_str_type
photos_link: HttpUrlString
feedback_cc: medium_str_type
feedback_college: medium_str_type
submitted_by: str
submitted_time: datetime = Field(
default_factory=lambda: datetime.now(timezone), frozen=True
)


class Event(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
code: str | None = None
clubid: str
collabclubs: List[str] = []
studentBodyEvent: bool = False

name: event_name_type
name: very_short_str_type

description: event_desc_type | None = "No description available."
description: medium_str_type | None = "No description available."
datetimeperiod: Tuple[datetime, datetime]
poster: str | None = None
audience: List[Audience] = []
link: HttpUrlString | None = None

mode: Event_Mode = Event_Mode.hybrid
location: List[Event_Location] = []
equipment: event_othr_type | None = None
additional: event_othr_type | None = None
equipment: short_str_type | None = None
additional: short_str_type | None = None
population: event_popu_type | None = None
poc: str | None = None

status: Event_Status = Event_Status()
budget: List[BudgetType] = []
bills_status: Bills_Status = Bills_Status()
event_report_submitted: bool = False

@field_validator("datetimeperiod")
def check_end_year(cls, value, info: ValidationInfo):
Expand All @@ -61,14 +81,16 @@ def check_end_year(cls, value, info: ValidationInfo):
model_config = ConfigDict(
populate_by_name=True,
arbitrary_types_allowed=True,
extra="forbid",
str_strip_whitespace=True,
)


class Holiday(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
name: str
name: very_short_str_type
date: date
description: str | None = None
description: medium_str_type | None = None
created_time: datetime = Field(
default_factory=lambda: datetime.now(timezone), frozen=True
)
Expand Down
20 changes: 16 additions & 4 deletions mtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,14 @@ class Event_Location(StrEnum):
other = auto()


event_name_type = Annotated[
event_popu_type = Annotated[int, Field(ge=0)]

very_short_str_type = Annotated[
str, StringConstraints(min_length=1, max_length=200)
]
event_desc_type = Annotated[str, StringConstraints(max_length=5000)]
event_popu_type = Annotated[int, Field(ge=0)]
event_othr_type = Annotated[str, StringConstraints(max_length=1000)]
short_str_type = Annotated[str, StringConstraints(max_length=1000)]
medium_str_type = Annotated[str, StringConstraints(max_length=5000)]
long_str_type = Annotated[str, StringConstraints(max_length=10000)]


@strawberry.type
Expand All @@ -270,6 +272,16 @@ def positive_amount(cls, value):
return value


@strawberry.enum
class PrizesType(StrEnum):
win_certificates = auto()
participation_certificates = auto()
cash_prizes = auto()
vouchers = auto()
medals = auto()
others = auto()


# for handling mongo ObjectIds
class PyObjectId(ObjectId):
@classmethod
Expand Down
2 changes: 2 additions & 0 deletions mutations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from mutations.event_report import mutations as event_report_mutations
from mutations.events import mutations as events_mutations
from mutations.finances import mutations as finances_mutations
from mutations.holidays import mutations as holidays_mutations

mutations = [
*events_mutations,
*event_report_mutations,
*finances_mutations,
*holidays_mutations,
]
76 changes: 76 additions & 0 deletions mutations/event_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from datetime import datetime

import strawberry
from fastapi.encoders import jsonable_encoder

from db import event_reportsdb, eventsdb
from models import EventReport
from mtypes import Event_State_Status
from otypes import EventReportType, Info, InputEventReport
from utils import getMember


@strawberry.mutation
def addEventReport(details: InputEventReport, info: Info) -> EventReportType:
"""
Add an event report
returns the added event report
"""

user = info.context.user
if not user:
raise ValueError("User not authenticated")

user_role = user["role"]
if user_role not in ["club"]:
raise ValueError("User not authorized")

eventid = details.eventid
if not eventid:
raise ValueError("Event ID is required")
event = eventsdb.find_one(
{
"_id": eventid,
"datetimeperiod.1": {
"$lt": datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")
},
"status.state": Event_State_Status.approved.value,
}
)
if not event:
raise ValueError("Event not found")
if user_role == "club" and event["clubid"] != user["uid"]:
raise ValueError("User not authorized")

searchspace = {
"event_id": eventid,
}

event_report = event_reportsdb.find_one(searchspace)

if event_report:
raise ValueError("Event report already exists")

# Check if submitted_by is valid
cid = event["clubid"]
uid = details.submitted_by
if not getMember(cid, uid, info.context.cookies):
raise ValueError("Submitted by is not a valid member")

report_dict = jsonable_encoder(details.to_pydantic())
report_dict["event_id"] = details.eventid
event_report_id = event_reportsdb.insert_one(report_dict).inserted_id
event_report = event_reportsdb.find_one({"_id": event_report_id})

# Update event report submitted status to True
eventsdb.update_one(
{"_id": eventid},
{"$set": {"event_report_submitted": True}},
)

return EventReportType.from_pydantic(
EventReport.model_validate(event_report)
)


mutations = [addEventReport]
13 changes: 12 additions & 1 deletion otypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from strawberry.types import Info as _Info
from strawberry.types.info import RootValueType

from models import Event, Holiday
from models import Event, EventReport, Holiday
from mtypes import (
Audience,
Bills_State_Status,
Expand Down Expand Up @@ -48,6 +48,11 @@ def cookies(self) -> Dict | None:
)


@strawberry.experimental.pydantic.type(model=EventReport, all_fields=True)
class EventReportType:
pass


@strawberry.experimental.pydantic.type(model=Event, all_fields=True)
class EventType:
pass
Expand All @@ -68,6 +73,7 @@ class BillsStatusType:
eventname: str
clubid: str
bills_status: Bills_Status
eventReportSubmitted: str


@strawberry.input
Expand Down Expand Up @@ -129,6 +135,11 @@ class InputDataReportDetails:
status: str


@strawberry.experimental.pydantic.input(model=EventReport, all_fields=True)
class InputEventReport:
pass


@strawberry.type
class CSVResponse:
csvFile: str
Expand Down
4 changes: 3 additions & 1 deletion queries/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from queries.event_report import queries as event_report_queries
from queries.events import queries as events_queries
from queries.finances import queries as finances_queries
from queries.holidays import queries as holidays_queries

queries = [
*events_queries,
*event_report_queries,
*finances_queries,
*holidays_queries,
]
]
46 changes: 46 additions & 0 deletions queries/event_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import strawberry

from db import event_reportsdb, eventsdb
from models import EventReport
from otypes import EventReportType, Info


@strawberry.field
def eventReport(eventid: str, info: Info) -> EventReportType:
"""
Get the event report of an event
returns the event report
"""

user = info.context.user
if not user:
raise ValueError("User not authenticated")

user_role = user["role"]
if user_role not in ["cc", "slo", "club"]:
raise ValueError("User not authorized")

event = eventsdb.find_one({"_id": eventid, "event_report_submitted": True})
if not event:
raise ValueError("Event not found")
if user_role == "club" and event["clubid"] != user["uid"] and (
event["collabclubs"] is None
or user["uid"] not in event["collabclubs"]
):
raise ValueError("User not authorized")

event_report = event_reportsdb.find_one(
{
"event_id": eventid,
}
)

if not event_report:
raise ValueError("Event report not found")

return EventReportType.from_pydantic(
EventReport.model_validate(event_report)
)


queries = [eventReport]
9 changes: 8 additions & 1 deletion queries/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ def event(eventid: str, info: Info) -> EventType:
if (
user is None
or user["role"] not in ["club", "cc", "slc", "slo"]
or (user["role"] == "club" and user["uid"] != event["clubid"])
or (
user["role"] == "club"
and user["uid"] != event["clubid"]
and (
event["collabclubs"] is None
or user["uid"] not in event["collabclubs"]
)
)
):
trim_public_events(event)

Expand Down
Loading

0 comments on commit cbe41b4

Please sign in to comment.