Skip to content

Commit b4f2531

Browse files
fix: Raid issues (#596)
- Fix team number --------- Co-authored-by: Armand Didierjean <[email protected]>
1 parent e012d33 commit b4f2531

File tree

5 files changed

+389
-81
lines changed

5 files changed

+389
-81
lines changed

app/modules/raid/cruds_raid.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from collections.abc import Sequence
22
from datetime import UTC, datetime
33

4-
from sqlalchemy import delete, func, or_, select, update
4+
from sqlalchemy import delete, or_, select, update
55
from sqlalchemy.ext.asyncio import AsyncSession
66
from sqlalchemy.orm import selectinload
77

@@ -105,7 +105,7 @@ async def get_all_teams(
105105

106106
async def get_all_validated_teams(
107107
db: AsyncSession,
108-
) -> list[models_raid.Team]:
108+
) -> Sequence[models_raid.Team]:
109109
teams = await db.execute(
110110
select(models_raid.Team).options(
111111
# Since there is nested classes in the Team model, we need to load all the related data
@@ -542,9 +542,21 @@ async def get_number_of_team_by_difficulty(
542542
db: AsyncSession,
543543
) -> int:
544544
result = await db.execute(
545-
select(func.count()).where(models_raid.Team.difficulty == difficulty),
545+
select(models_raid.Team).where(models_raid.Team.difficulty == difficulty),
546546
)
547-
return result.scalar() or 0
547+
teams_found = result.scalars().all()
548+
# We can not use a where clause because the validation_progress is a Python property
549+
# and is not usable in a SQL query
550+
team_numbers = [
551+
team.number if team.number is not None and team.number >= 0 else 0
552+
for team in filter(
553+
lambda team: team.validation_progress == 100
554+
and team.number is not None
555+
and team.number >= 0,
556+
teams_found,
557+
)
558+
]
559+
return max(team_numbers) if team_numbers else 0
548560

549561

550562
async def create_participant_checkout(

app/modules/raid/endpoints_raid.py

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from app.modules.raid.raid_type import DocumentType, DocumentValidation, Size
2525
from app.modules.raid.utils.drive.drive_file_manager import DriveFileManager
2626
from app.modules.raid.utils.utils_raid import (
27+
generate_teams_pdf_util,
2728
get_participant,
2829
post_update_actions,
2930
save_security_file,
@@ -215,12 +216,13 @@ async def update_participant(
215216

216217
await cruds_raid.update_participant(participant_id, participant, is_minor, db)
217218
team = await cruds_raid.get_team_by_participant_id(participant_id, db)
218-
await post_update_actions(
219-
team,
220-
db,
221-
drive_file_manager,
222-
settings=settings,
223-
)
219+
if team:
220+
await post_update_actions(
221+
team,
222+
db,
223+
drive_file_manager,
224+
settings=settings,
225+
)
224226

225227

226228
@module.router.post(
@@ -257,18 +259,19 @@ async def create_team(
257259
await cruds_raid.create_team(db_team, db)
258260
# We need to get the team from the db to have access to relationships
259261
created_team = await cruds_raid.get_team_by_id(team_id=db_team.id, db=db)
260-
await post_update_actions(
261-
created_team,
262-
db,
263-
drive_file_manager,
264-
settings=settings,
265-
)
262+
if created_team:
263+
await post_update_actions(
264+
created_team,
265+
db,
266+
drive_file_manager,
267+
settings=settings,
268+
)
266269
return created_team
267270

268271

269272
@module.router.post(
270273
"/raid/teams/generate-pdf",
271-
status_code=204,
274+
status_code=200,
272275
)
273276
async def generate_teams_pdf(
274277
user: models_users.CoreUser = Depends(is_user_in(GroupType.raid_admin)),
@@ -280,15 +283,13 @@ async def generate_teams_pdf(
280283
PDF are automatically generated when a team is created or updated.
281284
This endpoint is used to regenerate all the PDFs.
282285
"""
283-
teams = await cruds_raid.get_all_teams(db)
286+
await generate_teams_pdf_util(
287+
db=db,
288+
drive_file_manager=drive_file_manager,
289+
settings=settings,
290+
)
284291

285-
for team in teams:
286-
await post_update_actions(
287-
team,
288-
db,
289-
drive_file_manager,
290-
settings=settings,
291-
)
292+
return "PDF generation started"
292293

293294

294295
@module.router.get(
@@ -371,12 +372,13 @@ async def update_team(
371372
raise HTTPException(status_code=403, detail="You can only edit your own team.")
372373
await cruds_raid.update_team(team_id, team, db)
373374
updated_team = await cruds_raid.get_team_by_id(team_id, db)
374-
await post_update_actions(
375-
updated_team,
376-
db,
377-
drive_file_manager,
378-
settings=settings,
379-
)
375+
if updated_team:
376+
await post_update_actions(
377+
updated_team,
378+
db,
379+
drive_file_manager,
380+
settings=settings,
381+
)
380382

381383

382384
@module.router.delete(
@@ -578,12 +580,13 @@ async def validate_document(
578580
"""
579581
await cruds_raid.update_document_validation(document_id, validation, db)
580582
team = await cruds_raid.get_team_by_participant_id(user.id, db)
581-
await post_update_actions(
582-
team,
583-
db,
584-
drive_file_manager,
585-
settings=settings,
586-
)
583+
if team:
584+
await post_update_actions(
585+
team,
586+
db,
587+
drive_file_manager,
588+
settings=settings,
589+
)
587590

588591

589592
@module.router.post(
@@ -680,12 +683,13 @@ async def confirm_payment(
680683
participant_id,
681684
db,
682685
)
683-
await post_update_actions(
684-
team,
685-
db,
686-
drive_file_manager,
687-
settings=settings,
688-
)
686+
if team:
687+
await post_update_actions(
688+
team,
689+
db,
690+
drive_file_manager,
691+
settings=settings,
692+
)
689693

690694

691695
@module.router.post(
@@ -711,12 +715,13 @@ async def confirm_t_shirt_payment(
711715
raise HTTPException(status_code=400, detail="T shirt size not set.")
712716
await cruds_raid.confirm_t_shirt_payment(participant_id, db)
713717
team = await cruds_raid.get_team_by_participant_id(participant_id, db)
714-
await post_update_actions(
715-
team,
716-
db,
717-
drive_file_manager,
718-
settings=settings,
719-
)
718+
if team:
719+
await post_update_actions(
720+
team,
721+
db,
722+
drive_file_manager,
723+
settings=settings,
724+
)
720725

721726

722727
@module.router.post(
@@ -737,12 +742,13 @@ async def validate_attestation_on_honour(
737742
raise HTTPException(status_code=403, detail="You are not the participant")
738743
await cruds_raid.validate_attestation_on_honour(participant_id, db)
739744
team = await cruds_raid.get_team_by_participant_id(participant_id, db)
740-
await post_update_actions(
741-
team,
742-
db,
743-
drive_file_manager,
744-
settings=settings,
745-
)
745+
if team:
746+
await post_update_actions(
747+
team,
748+
db,
749+
drive_file_manager,
750+
settings=settings,
751+
)
746752

747753

748754
@module.router.post(

app/modules/raid/utils/pdf/pdf_writer.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,11 @@ def write_participant_document(self, participant: Participant):
150150
participant.parent_authorization,
151151
]:
152152
if document:
153-
pdf = get_file_path_from_data("raid", document.id, "documents")
153+
pdf = get_file_path_from_data(
154+
"raid",
155+
document.id,
156+
"assets/pdf/default_PDF.pdf",
157+
)
154158
extension = pdf.absolute().suffix[1:]
155159
if extension in ["jpg", "jpeg", "png"]:
156160
self.write_document(document, participant)

app/modules/raid/utils/utils_raid.py

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
from app.core.payment import schemas_payment
1212
from app.core.utils.config import Settings
1313
from app.modules.raid import coredata_raid, cruds_raid, models_raid, schemas_raid
14+
from app.modules.raid.raid_type import Difficulty
1415
from app.modules.raid.schemas_raid import (
1516
ParticipantBase,
1617
ParticipantUpdate,
1718
)
1819
from app.modules.raid.utils.drive.drive_file_manager import DriveFileManager
1920
from app.modules.raid.utils.pdf.pdf_writer import HTMLPDFWriter, PDFWriter
20-
from app.utils.tools import (
21-
get_core_data,
22-
)
21+
from app.utils.tools import get_core_data
2322

2423
hyperion_error_logger = logging.getLogger("hyperion.error")
2524

@@ -135,10 +134,20 @@ async def write_teams_csv(
135134
async def set_team_number(team: models_raid.Team, db: AsyncSession) -> None:
136135
if team.difficulty is None:
137136
return
138-
new_team_number = await cruds_raid.get_number_of_team_by_difficulty(
137+
number_of_team = await cruds_raid.get_number_of_team_by_difficulty(
139138
team.difficulty,
140139
db,
141140
)
141+
difficulty_separator = {
142+
Difficulty.discovery: 0,
143+
Difficulty.sports: 100,
144+
Difficulty.expert: 200,
145+
}
146+
new_team_number = (
147+
difficulty_separator[team.difficulty] + 1
148+
if number_of_team == 0
149+
else number_of_team + 1
150+
)
142151
updated_team: schemas_raid.TeamUpdate = schemas_raid.TeamUpdate(
143152
number=new_team_number,
144153
)
@@ -184,31 +193,36 @@ async def save_team_info(
184193

185194

186195
async def post_update_actions(
187-
team: models_raid.Team | None,
196+
team: models_raid.Team,
188197
db: AsyncSession,
189198
drive_file_manager: DriveFileManager,
190199
settings: Settings,
200+
should_generate_all_teams_csv: bool = True,
191201
) -> None:
192202
try:
193-
if team:
194-
if team.validation_progress == 100:
195-
await set_team_number(team, db)
203+
if team.validation_progress == 100 and (
204+
team.number is None or team.number == -1
205+
):
206+
await set_team_number(team, db)
207+
208+
# Usually we want to update the csv file each team a team is updated
209+
# but when we batch update teams we only want to update the csv file once, at the end
210+
if should_generate_all_teams_csv:
196211
all_teams = await cruds_raid.get_all_validated_teams(db)
197-
if all_teams:
198-
await write_teams_csv(
199-
all_teams,
200-
db,
201-
drive_file_manager,
202-
settings=settings,
203-
)
204-
await save_team_info(
205-
team,
206-
db,
207-
drive_file_manager,
208-
settings=settings,
209-
)
212+
await write_teams_csv(
213+
all_teams,
214+
db,
215+
drive_file_manager,
216+
settings=settings,
217+
)
218+
await save_team_info(
219+
team,
220+
db,
221+
drive_file_manager,
222+
settings=settings,
223+
)
210224
except Exception:
211-
hyperion_error_logger.exception("Error while creating pdf")
225+
hyperion_error_logger.exception(f"Error while creating pdf for team {team.id}")
212226
return
213227

214228

@@ -269,3 +283,38 @@ async def get_participant(
269283
if not participant:
270284
raise HTTPException(status_code=404, detail="Participant not found.")
271285
return participant
286+
287+
288+
async def generate_teams_pdf_util(
289+
db: AsyncSession,
290+
drive_file_manager: DriveFileManager,
291+
settings: Settings,
292+
):
293+
teams = await cruds_raid.get_all_teams(db)
294+
295+
hyperion_error_logger.warning(f"RAID: Generating PDF for {len(teams)} teams")
296+
297+
for index, team in enumerate(teams):
298+
hyperion_error_logger.info(f"RAID: team {index}/{len(teams)}")
299+
300+
# We reset the team number to -1 to force the update of the team number
301+
await cruds_raid.update_team(team.id, schemas_raid.TeamUpdate(number=-1), db)
302+
await post_update_actions(
303+
team,
304+
db,
305+
drive_file_manager,
306+
settings=settings,
307+
should_generate_all_teams_csv=False,
308+
)
309+
310+
all_teams = await cruds_raid.get_all_validated_teams(db)
311+
await write_teams_csv(
312+
all_teams,
313+
db,
314+
drive_file_manager,
315+
settings=settings,
316+
)
317+
318+
hyperion_error_logger.warning(
319+
f"RAID: Successfully generated PDF for {len(teams)} teams",
320+
)

0 commit comments

Comments
 (0)