Coverage for apps/kwai-api/src/kwai_api/v1/training_schedules/endpoints.py: 83%

84 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2024-01-01 00:00 +0000

1"""Module for endpoints for training schedules.""" 

2 

3from fastapi import APIRouter, Depends, HTTPException, status 

4from kwai_bc_club.repositories.coach_repository import CoachNotFoundException 

5from kwai_bc_identity.users.user import UserEntity 

6from kwai_bc_training.coaches.coach_db_repository import CoachDbRepository 

7from kwai_bc_training.create_training_schedule import ( 

8 CreateTrainingSchedule, 

9 CreateTrainingScheduleCommand, 

10) 

11from kwai_bc_training.delete_training_schedule import ( 

12 DeleteTrainingSchedule, 

13 DeleteTrainingScheduleCommand, 

14) 

15from kwai_bc_training.get_training_schedule import ( 

16 GetTrainingSchedule, 

17 GetTrainingScheduleCommand, 

18) 

19from kwai_bc_training.get_training_schedules import ( 

20 GetTrainingSchedules, 

21 GetTrainingSchedulesCommand, 

22) 

23from kwai_bc_training.get_trainings import GetTrainings, GetTrainingsCommand 

24from kwai_bc_training.teams.team_db_repository import TeamDbRepository 

25from kwai_bc_training.trainings.training_db_repository import TrainingDbRepository 

26from kwai_bc_training.trainings.training_schedule_db_repository import ( 

27 TrainingScheduleDbRepository, 

28) 

29from kwai_bc_training.trainings.training_schedule_repository import ( 

30 TrainingScheduleNotFoundException, 

31) 

32from kwai_bc_training.update_training_schedule import ( 

33 UpdateTrainingSchedule, 

34 UpdateTrainingScheduleCommand, 

35) 

36from kwai_core.db.uow import UnitOfWork 

37from kwai_core.domain.value_objects.owner import Owner 

38from kwai_core.json_api import PaginationModel 

39 

40from kwai_api.dependencies import create_database, get_current_user 

41from kwai_api.v1.training_schedules.presenters import ( 

42 JsonApiTrainingSchedulePresenter, 

43 JsonApiTrainingSchedulesPresenter, 

44) 

45from kwai_api.v1.training_schedules.schemas import ( 

46 TrainingScheduleDocument, 

47 TrainingSchedulesDocument, 

48) 

49from kwai_api.v1.trainings.endpoints import TrainingsFilterModel 

50from kwai_api.v1.trainings.presenters import JsonApiTrainingsDocumentPresenter 

51from kwai_api.v1.trainings.schemas import TrainingsDocument 

52 

53 

54router = APIRouter() 

55 

56 

57@router.get("/training_schedules") 

58async def get_training_schedules( 

59 pagination: PaginationModel = Depends(PaginationModel), 

60 db=Depends(create_database), 

61) -> TrainingSchedulesDocument: 

62 """Get all training schedules.""" 

63 command = GetTrainingSchedulesCommand( 

64 offset=pagination.offset or 0, limit=pagination.limit 

65 ) 

66 presenter = JsonApiTrainingSchedulesPresenter() 

67 await GetTrainingSchedules(TrainingScheduleDbRepository(db), presenter).execute( 

68 command 

69 ) 

70 

71 return presenter.get_document() 

72 

73 

74@router.get( 

75 "/training_schedules/{training_schedule_id}", 

76 responses={ 

77 status.HTTP_404_NOT_FOUND: {"description": "Training schedule was not found."} 

78 }, 

79) 

80async def get_training_schedule( 

81 training_schedule_id: int, 

82 db=Depends(create_database), 

83) -> TrainingScheduleDocument: 

84 """Get training schedule with the given id.""" 

85 command = GetTrainingScheduleCommand(id=training_schedule_id) 

86 presenter = JsonApiTrainingSchedulePresenter() 

87 try: 

88 await GetTrainingSchedule(TrainingScheduleDbRepository(db), presenter).execute( 

89 command 

90 ) 

91 except TrainingScheduleNotFoundException as ex: 

92 raise HTTPException( 

93 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

94 ) from ex 

95 

96 return presenter.get_document() 

97 

98 

99@router.post( 

100 "/training_schedules", 

101 status_code=status.HTTP_201_CREATED, 

102) 

103async def create_training_schedule( 

104 resource: TrainingScheduleDocument, 

105 db=Depends(create_database), 

106 user: UserEntity = Depends(get_current_user), 

107) -> TrainingScheduleDocument: 

108 """Create a new training schedule.""" 

109 if ( 

110 resource.data.relationships is not None 

111 and resource.data.relationships.team is not None 

112 and resource.data.relationships.team.data is not None 

113 and resource.data.relationships.team.data.id is not None 

114 ): 

115 team_id = int(resource.data.relationships.team.data.id) 

116 else: 

117 team_id = None 

118 

119 coaches = [int(coach.id) for coach in resource.data.relationships.coaches.data] 

120 

121 command = CreateTrainingScheduleCommand( 

122 name=resource.data.attributes.name, 

123 description=resource.data.attributes.description, 

124 weekday=resource.data.attributes.weekday, 

125 start_time=resource.data.attributes.start_time, 

126 end_time=resource.data.attributes.end_time, 

127 timezone=resource.data.attributes.timezone, 

128 active=resource.data.attributes.active, 

129 location=resource.data.attributes.location or "", 

130 remark=resource.data.attributes.remark or "", 

131 team_id=team_id, 

132 coaches=coaches, 

133 ) 

134 presenter = JsonApiTrainingSchedulePresenter() 

135 async with UnitOfWork(db): 

136 try: 

137 await CreateTrainingSchedule( 

138 TrainingScheduleDbRepository(db), 

139 TeamDbRepository(db), 

140 CoachDbRepository(db), 

141 Owner(id=user.id, uuid=user.uuid, name=user.name), 

142 presenter, 

143 ).execute(command) 

144 except ValueError as ve: 

145 raise HTTPException( 

146 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ve) 

147 ) from ve 

148 

149 return presenter.get_document() 

150 

151 

152@router.patch( 

153 "/training_schedules/{training_schedule_id}", 

154 responses={ 

155 status.HTTP_404_NOT_FOUND: {"description": "Training schedule was not found."} 

156 }, 

157) 

158async def update_training_schedule( 

159 training_schedule_id: int, 

160 resource: TrainingScheduleDocument, 

161 db=Depends(create_database), 

162 user: UserEntity = Depends(get_current_user), 

163) -> TrainingScheduleDocument: 

164 """Update a training schedule.""" 

165 if ( 

166 resource.data.relationships is not None 

167 and resource.data.relationships.team is not None 

168 and resource.data.relationships.team.data is not None 

169 and resource.data.relationships.team.data.id is not None 

170 ): 

171 team_id = int(resource.data.relationships.team.data.id) 

172 else: 

173 team_id = None 

174 

175 coaches = [int(coach.id) for coach in resource.data.relationships.coaches.data] 

176 

177 command = UpdateTrainingScheduleCommand( 

178 id=training_schedule_id, 

179 name=resource.data.attributes.name, 

180 description=resource.data.attributes.description, 

181 weekday=resource.data.attributes.weekday, 

182 start_time=resource.data.attributes.start_time, 

183 end_time=resource.data.attributes.end_time, 

184 timezone=resource.data.attributes.timezone, 

185 active=resource.data.attributes.active, 

186 location=resource.data.attributes.location or "", 

187 remark=resource.data.attributes.remark or "", 

188 team_id=team_id, 

189 coaches=coaches, 

190 ) 

191 presenter = JsonApiTrainingSchedulePresenter() 

192 async with UnitOfWork(db): 

193 try: 

194 await UpdateTrainingSchedule( 

195 TrainingScheduleDbRepository(db), 

196 TeamDbRepository(db), 

197 CoachDbRepository(db), 

198 Owner(id=user.id, uuid=user.uuid, name=user.name), 

199 presenter, 

200 ).execute(command) 

201 except TrainingScheduleNotFoundException as ex: 

202 raise HTTPException( 

203 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

204 ) from ex 

205 except ValueError as ve: 

206 raise HTTPException( 

207 status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(ve) 

208 ) from ve 

209 

210 return presenter.get_document() 

211 

212 

213@router.delete( 

214 "/training_schedules/{training_schedule_id}", 

215 responses={ 

216 status.HTTP_404_NOT_FOUND: {"description": "Training schedule was not found."} 

217 }, 

218) 

219async def delete_training_schedule( 

220 training_schedule_id: int, 

221 db=Depends(create_database), 

222 user: UserEntity = Depends(get_current_user), 

223) -> None: 

224 """Delete a training schedule.""" 

225 command = DeleteTrainingScheduleCommand( 

226 id=training_schedule_id, delete_trainings=False 

227 ) 

228 await DeleteTrainingSchedule( 

229 TrainingScheduleDbRepository(db), TrainingDbRepository(db) 

230 ).execute(command) 

231 

232 

233@router.get( 

234 "/training_schedules/{training_schedule_id}/trainings", 

235 responses={ 

236 status.HTTP_404_NOT_FOUND: { 

237 "description": "Training schedule or coach was not found." 

238 } 

239 }, 

240) 

241async def get_trainings( 

242 training_schedule_id: int, 

243 pagination: PaginationModel = Depends(PaginationModel), 

244 trainings_filter: TrainingsFilterModel = Depends(TrainingsFilterModel), 

245 db=Depends(create_database), 

246) -> TrainingsDocument: 

247 """Get trainings of the given training schedule.""" 

248 command = GetTrainingsCommand( 

249 offset=pagination.offset or 0, 

250 limit=pagination.limit, 

251 year=trainings_filter.year, 

252 month=trainings_filter.month, 

253 start=trainings_filter.start, 

254 end=trainings_filter.end, 

255 active=trainings_filter.active, 

256 coach=trainings_filter.coach, 

257 schedule=training_schedule_id, 

258 ) 

259 presenter = JsonApiTrainingsDocumentPresenter() 

260 

261 try: 

262 await GetTrainings( 

263 TrainingDbRepository(db), 

264 CoachDbRepository(db), 

265 TrainingScheduleDbRepository(db), 

266 presenter, 

267 ).execute(command) 

268 except TrainingScheduleNotFoundException as ex: 

269 raise HTTPException( 

270 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

271 ) from ex 

272 except CoachNotFoundException as ex: 

273 raise HTTPException( 

274 status_code=status.HTTP_404_NOT_FOUND, detail=str(ex) 

275 ) from ex 

276 

277 return presenter.get_document()