Implement basic hike functions
This commit is contained in:
@@ -138,6 +138,8 @@ class ApiTags(DocumentedStrEnum):
|
||||
DIVISIONS = "Divisions"
|
||||
MEMBERS = "Members"
|
||||
|
||||
HIKES = "Hikes"
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
181
backend/app/models/hike.py
Normal file
181
backend/app/models/hike.py
Normal file
@@ -0,0 +1,181 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from sqlmodel import (
|
||||
Session,
|
||||
Relationship,
|
||||
Field,
|
||||
)
|
||||
|
||||
from . import mixin
|
||||
from .base import (
|
||||
BaseSQLModel,
|
||||
DocumentedStrEnum,
|
||||
DocumentedIntFlag,
|
||||
DocumentedStrFlagType,
|
||||
auto_enum,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .event import Event
|
||||
|
||||
# region # Hike ################################################################
|
||||
|
||||
class HikeTeamPage(DocumentedIntFlag):
|
||||
ROUTE = auto_enum() # Route steps info
|
||||
QUESTIONS = auto_enum() # Visible questions
|
||||
|
||||
VISITED_PLACES = auto_enum() # Places the team has been
|
||||
CURRENT_PLACE = auto_enum() # Place where the team currently is
|
||||
UNVISITED_PLACES = auto_enum() # Places the team still neat to visit
|
||||
|
||||
PLACES = VISITED_PLACES | CURRENT_PLACE | UNVISITED_PLACES # All the places
|
||||
|
||||
TRAVEL_TIME = auto_enum() # Total travel time
|
||||
TRAVEL_FREE_TIME = auto_enum() # Total travel time
|
||||
PLACE_TIME = auto_enum() # Total place time
|
||||
CALCULATE_TIME = auto_enum() # Total time calculated based on hike settings
|
||||
# TODO: Think about time between oter teams
|
||||
|
||||
PLACE_POINTS = auto_enum() # Points scored on a place
|
||||
TOTAL_PLACE_POINTS = auto_enum() # All points got on all places
|
||||
ASSIST_POINTS = auto_enum() # Minus points for assistants
|
||||
# TODO: Think about place in classement
|
||||
|
||||
ASSIST_LOG = auto_enum() # Assisted items
|
||||
ASSIST_LATTER = auto_enum() # ???
|
||||
|
||||
|
||||
# ##############################################################################
|
||||
|
||||
|
||||
class HikeTimeCalculation(DocumentedIntFlag):
|
||||
TRAVEL_TIME = auto_enum() # Time traveling
|
||||
|
||||
# TODO: Think about time groups (in this model we have 2, free and non free)
|
||||
TRAVEL_FREE_TIME = auto_enum() # Time that is excluded from traveling but not at a place
|
||||
PLACE_TIME = auto_enum() # Time checked in at a place
|
||||
|
||||
TOTAL_TIME = TRAVEL_TIME | TRAVEL_FREE_TIME | PLACE_TIME
|
||||
|
||||
|
||||
# ##############################################################################
|
||||
|
||||
|
||||
class HikeBase(
|
||||
mixin.Name,
|
||||
mixin.Contact,
|
||||
BaseSQLModel,
|
||||
):
|
||||
tracker_interval: int | None = Field(
|
||||
default=None,
|
||||
nullable=True,
|
||||
description="Is GPS button available, value will be the interval",
|
||||
)
|
||||
|
||||
is_multi_day: bool = Field(
|
||||
default=False,
|
||||
nullable=False,
|
||||
description="Show datetime in stead of time only",
|
||||
)
|
||||
|
||||
team_page: HikeTeamPage = Field(
|
||||
default=HikeTeamPage.PLACES | HikeTeamPage.ROUTE | HikeTeamPage.QUESTIONS,
|
||||
nullable=False,
|
||||
description="Show all the places of the route inside the teams page",
|
||||
sa_type=DocumentedStrFlagType(HikeTeamPage),
|
||||
)
|
||||
|
||||
time_calculation: HikeTimeCalculation = Field(
|
||||
default=HikeTimeCalculation.TRAVEL_TIME,
|
||||
nullable=False,
|
||||
description="Wath should we calculate inside the total time",
|
||||
sa_type=DocumentedStrFlagType(HikeTimeCalculation),
|
||||
)
|
||||
|
||||
min_time_points: int | None = Field(
|
||||
default=0,
|
||||
ge=0,
|
||||
# TODO: le: max_time_points
|
||||
description="Min points for time",
|
||||
)
|
||||
|
||||
max_time_points: int | None = Field(
|
||||
default=100,
|
||||
ge=0, # TODO: ge > min_time_points
|
||||
description="Max points for time",
|
||||
)
|
||||
|
||||
max_question_points: int | None = Field(
|
||||
default=None,
|
||||
description="None: Calculate from answers (no max), Positive: Set as max for dynamic range",
|
||||
)
|
||||
|
||||
|
||||
# Properties to receive via API on creation
|
||||
class HikeCreate(HikeBase):
|
||||
pass
|
||||
|
||||
|
||||
# Properties to receive via API on update, all are optional
|
||||
class HikeUpdate(HikeBase):
|
||||
is_multi_day: bool | None = Field(default=None) # type: ignore
|
||||
team_page: HikeTeamPage | None = Field(default=None) # type: ignore
|
||||
time_calculation: HikeTimeCalculation | None = Field(default=None) # type: ignore
|
||||
|
||||
|
||||
class Hike(mixin.RowId, HikeBase, table=True):
|
||||
# --- database only items --------------------------------------------------
|
||||
|
||||
# --- read only items ------------------------------------------------------
|
||||
|
||||
# --- back_populates links -------------------------------------------------
|
||||
|
||||
# --- CRUD actions ---------------------------------------------------------
|
||||
@classmethod
|
||||
def create(cls, *, session: Session, create_obj: HikeCreate) -> "Hike":
|
||||
data_obj = create_obj.model_dump(exclude_unset=True)
|
||||
|
||||
db_obj = cls.model_validate(data_obj)
|
||||
session.add(db_obj)
|
||||
session.commit()
|
||||
session.refresh(db_obj)
|
||||
return db_obj
|
||||
|
||||
@classmethod
|
||||
def update(
|
||||
cls, *, session: Session, db_obj: "Hike", in_obj: HikeUpdate
|
||||
) -> "Hike":
|
||||
data_obj = in_obj.model_dump(exclude_unset=True)
|
||||
db_obj.sqlmodel_update(data_obj)
|
||||
session.add(db_obj)
|
||||
session.commit()
|
||||
session.refresh(db_obj)
|
||||
return db_obj
|
||||
|
||||
|
||||
# Properties to return via API, id is always required
|
||||
class HikePublic(mixin.RowIdPublic, HikeBase):
|
||||
pass
|
||||
|
||||
|
||||
class HikesPublic(BaseSQLModel):
|
||||
data: list[HikePublic]
|
||||
count: int
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
# region # Hike / Route ########################################################
|
||||
|
||||
|
||||
class RouteType(DocumentedStrEnum):
|
||||
START_FINISH = auto_enum() # Start at the start and end at the finish
|
||||
CIRCULAR = auto_enum() # Start some ware, finish at the last new place
|
||||
CIRCULAR_BACK_TO_START = auto_enum() # Start and finish on the same random place (CIRCULAR + next to start)
|
||||
|
||||
|
||||
# ##############################################################################
|
||||
|
||||
|
||||
# endregion
|
||||
@@ -32,6 +32,8 @@ class PermissionModule(DocumentedStrEnum):
|
||||
DIVISION = auto_enum()
|
||||
MEMBER = auto_enum()
|
||||
|
||||
HIKE = auto_enum()
|
||||
|
||||
|
||||
class PermissionPart(DocumentedStrEnum):
|
||||
ADMIN = auto_enum()
|
||||
|
||||
Reference in New Issue
Block a user