Skip to content

Commit

Permalink
#103 - CRUD de matches
Browse files Browse the repository at this point in the history
  • Loading branch information
Reginaldo-Neto committed Jun 7, 2023
1 parent 2e06f41 commit 7ddb0b4
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 28 deletions.
6 changes: 2 additions & 4 deletions backend/api/models/championships.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
from sqlalchemy.orm import relationship
from api.database.config import Base
import enum
from datetime import datetime
from typing import Optional
from pydantic import BaseModel


class EnumFormat(enum.Enum):
Expand Down Expand Up @@ -32,4 +29,5 @@ class Championship(Base):
created_at = Column(DateTime)
admin_id = Column(Integer, ForeignKey("users.id"))
game_id = Column(Integer, ForeignKey("games.id"))
teams = relationship("Team", secondary="championship_has_teams", backref="teams")
matches = Column(Integer, ForeignKey("matches.id"))
teams = relationship("Team", secondary="championship_has_teams", backref="teams")
16 changes: 16 additions & 0 deletions backend/api/models/matches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sqlalchemy import Column, Integer, String, ForeignKey
from api.database.config import Base


class Match(Base):
__tablename__ = "matches"

id = Column(Integer, primary_key=True, autoincrement=True)
championship_id = Column(Integer, ForeignKey("championships.id"))
team_1_id = Column(Integer, ForeignKey("teams.id"))
team_2_id = Column(Integer, ForeignKey("teams.id"))
winner_team_id = Column(Integer, ForeignKey("teams.id"))
bracket = Column(Integer)
round = Column(Integer)
result = Column(String)

4 changes: 2 additions & 2 deletions backend/api/routers/championships_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ async def update(id: int, update_request: ChampionshipUpdateRequest, token: Anno
if championship_exists:
raise HTTPException(status_code=400, detail="Championship with this name already exists")

if update_request.max_teams and update_request.min_teams == None:
if update_request.max_teams and update_request.min_teams is not None:
if championship.min_teams > update_request.max_teams:
raise HTTPException(status_code=400, detail="Max Teams cannot be less than Min Teams")

if update_request.min_teams and update_request.max_teams == None:
if update_request.min_teams and update_request.max_teams is not None:
if championship.max_teams < update_request.min_teams:
raise HTTPException(status_code=400, detail="Min Teams cannot be greater than Max Teams")

Expand Down
206 changes: 206 additions & 0 deletions backend/api/routers/matches_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
from api.database.config import Session, engine

from api.schemas.matches import (
Response,
MatchInput,
MatchSchema,
MatchUpdateRequest
)
from api.models.matches import Match
from api.models.championships import Championship
from api.models.teams import Team
from api.utils.auth_services import get_password_hash, oauth2_scheme, get_current_user
from fastapi import APIRouter, HTTPException, Depends
from typing import Annotated
from fastapi.encoders import jsonable_encoder
from sqlalchemy import Enum, func
from sqlalchemy.orm import joinedload


router = APIRouter(
prefix="/matches",
tags=["matches"],
# dependencies=[Depends(get_token_header)],
responses={404: {"description": "Matches Not Found"}},
)

session = Session(bind=engine)


@router.get(
"/",
response_model=list[MatchSchema],
response_description="Sucesso de resposta da aplicação.",
)
async def getAll(

id: int = None,
championship_id: int = None,
team_1_id: int = None,
team_2_id: int = None,
winner_team_id: int = None,
bracket: int = None,
round: int = None,
result: str = None,
skip: int = 0,
limit: int = 100,
):
query = session.query(Match)

if id is not None:
query = query.filter(Match.id == id)
if championship_id is not None:
query = query.filter(Match.championship_id == championship_id)
if team_1_id is not None:
query = query.filter(Match.team_1_id == team_1_id)
if team_2_id is not None:
query = query.filter(Match.team_2_id == team_2_id)
if winner_team_id is not None:
query = query.filter(Match.winner_team_id == winner_team_id)
if result is not None:
query = query.filter(func.lower(Match.result).like(f"%{result.lower()}%"))
if round is not None:
query = query.filter(Match.round == round)
if bracket is not None:
query = query.filter(Match.bracket == bracket)

Matches = query.offset(skip).limit(limit).all()

return jsonable_encoder(Matches)


@router.get(
"/{id}",
response_model=MatchSchema,
response_description="Sucesso de resposta da aplicação.",
)
async def getById(id: int):
match = (
session.query(Match).options(joinedload(Match.team_1_id), joinedload(Match.team_2_id)).
filter(Match.id == id).
first()
)
if match == None:
raise HTTPException(status_code=404, detail="Match not found")
return jsonable_encoder(match)

@router.get(
"/championship/{championship_id}",
response_model=MatchSchema,
response_description="Sucesso de resposta da aplicação.",
)

async def getByChampionshipId(championship_id: int, skip: int = 0, limit: int = 100,):
camp = session.query(Championship).filter(Championship.id == championship_id).first()

if camp == None:
raise HTTPException(status_code=404, detail="Championship not found")
matches = (session.query
.options(joinedload(Championship.matches))
.filter(Match.championship_id == championship_id)
.offset(skip)
.limit(limit)
.all()
)
if matches == None:
raise HTTPException(status_code=404, detail="Match not found")
return jsonable_encoder(matches)


@router.post(
"/create",
status_code=201,
response_model=MatchSchema,
response_description="Sucesso de resposta da aplicação.",
)
async def create(data: MatchInput, token: Annotated[str, Depends(oauth2_scheme)]):
part = session.query(Match).filter(Match.id == data.id).first()
if part != None:
raise HTTPException(status_code=400, detail="Match with this ID already exists")
user = await get_current_user(token)
time1 = session.query(Team).filter(Team.id == data.team_1_id).first()
if time1 == None:
raise HTTPException(status_code=404, detail="Team 1 not found")
time2 = session.query(Team).filter(Team.id == data.team_2_id).first()
if time2 == None:
raise HTTPException(status_code=404, detail="Team 2 not found")
championship = session.query(Championship).filter(Championship.id == data.championship_id).first()
if championship == None:
raise HTTPException(status_code=404, detail="Championship not found")

match_input = Match(
id=data.id,
championship_id=data.championship_id,
team_1_id=data.team_1_id,
team_2_id=data.team_2_id,
winner_team_id=data.winner_team_id,
bracket=data.bracket,
round=data.round,
result=data.result
)
session.add(match_input)
session.commit()
session.refresh(match_input)
response = {
"id": match_input.id,
"championship_id": match_input.championship_id,
"team_1_id": match_input.team_1_id,
"team_2_id": match_input.team_2_id,
"winner_team_id": match_input.winner_team_id,
"bracket": match_input.bracket,
"round": match_input.round,
"result": match_input.result
}
return jsonable_encoder(response)

#Vou deixar o delete comentado pq o Rafa disse que nao ia precisar, mas se no futuro precisar ja ta pronto
#@router.delete(
# "/delete/{id}",
# status_code=200,
# response_model=MatchSchema,
# response_description="Sucesso de resposta da aplicação.",
#)
#async def delete(id: int):
# match = session.query(Match).filter(Match.id == id).first()
# if match == None:
# raise HTTPException(status_code=404, detail="Match not found")

# session.delete(match)
# session.commit()

# return jsonable_encoder(match)


@router.put(
"/update/{id}",
status_code=200,
response_model=MatchSchema,
response_description="Sucesso de resposta da aplicação.",
)
async def update(id: int, update_request: MatchUpdateRequest, token: Annotated[str, Depends(oauth2_scheme)]):
user = await get_current_user(token)
match = session.query(Match).filter(Match.id == id).first()

if match is None:
raise HTTPException(
status_code=404, detail="Match not found"
)
#winner round result
venc = session.query(Team).filter(Match.team_1_id == update_request.winner_team_id and Match.team_2_id == update_request.winner_team_id).first()
if venc is None:
raise HTTPException(
status_code=404, detail="Team not found"
)

if update_request.result == None:
raise HTTPException(status_code=400, detail="Result cannot be None")

update_data = update_request.dict(exclude_unset=True)
for key, value in update_data.items():
if getattr(match, key) != value:
setattr(match, key, value)

session.commit()
session.refresh(match)

return jsonable_encoder(match)
3 changes: 2 additions & 1 deletion backend/api/routers/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
from .auth_routes import router as auth_routes
from .championships_routes import router as championships_routes
from .games_routes import router as games_routes
routes = [users_router, teams_router, auth_routes, championships_routes, games_routes]
from .matches_routes import router as matches_routes
routes = [users_router, teams_router, auth_routes, championships_routes, games_routes, matches_routes]
2 changes: 1 addition & 1 deletion backend/api/schemas/championships.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def min_teams_greater_than_zero(cls, v):

@validator("max_teams")
def max_teams_greater_than_min_teams(cls, v, values):
print(values)
#print(values)
if values["min_teams"] != None and v < values["min_teams"]:
raise ValueError("The maximum number of teams must be greater than or equal to the minimum number of teams")
return v
Expand Down
33 changes: 13 additions & 20 deletions backend/api/schemas/matches.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,13 @@ class Config:
orm_mode = True

class MatchInput(MatchSchema):
id: int
championship_id: int
game_id: int
team_1_id: int
team_2_id: int
winner_team_id: int
bracket: int
round: int
resul: str #ver se é possivel criar partida sem resultado inicial

@validator("resul")
def check_empty_fields(cls, v):
assert v != "", "Empty strings are not allowed."
return v

@validator("resul")
def check_spaced_fields(cls, v):
assert v.strip(), "Empty strings are not allowed."
return v

@validator("id", "championship_id", "team_1_id", "team_2_id", "winner_team_id", "game_id", "bracket", "round")
@validator("championship_id", "team_1_id", "team_2_id", "bracket", "round")
def check_positive_numbers(cls, v):
assert v >= 0, "Negative numbers are not allowed."
return v
Expand All @@ -47,18 +33,25 @@ class Config:
orm_mode = True

class MatchUpdateRequest(BaseModel):
winner_team_id: Optional[int] = Field(default=None, foreign_key="teams.id") #ver se fica a chave estrangeira
winner_team_id: Optional[int] = Field(default=None, foreign_key="teams.id")
result: Optional[str] = None

@validator("*")
@validator("result")
def check_empty_fields(cls, v):
assert v != "", "Empty strings are not allowed."
return v

@validator("*")
@validator("result")
def check_spaced_fields(cls, v):
assert v.strip(), "Empty strings are not allowed."
return v



class Config:
extra = "forbid"
orm_mode = True

class Response(GenericModel, Generic[T]):
code: str
status: str
message: str
result: Optional[T]

0 comments on commit 7ddb0b4

Please sign in to comment.