| 
1 | 1 | import logging  | 
2 | 2 | from datetime import UTC, datetime  | 
 | 3 | +from io import BytesIO  | 
3 | 4 | from uuid import UUID, uuid4  | 
4 | 5 | 
 
  | 
5 |  | -from fastapi import Body, Depends, File, HTTPException, UploadFile  | 
 | 6 | +from fastapi import Body, Depends, File, HTTPException, Query, Response, UploadFile  | 
6 | 7 | from fastapi.responses import FileResponse  | 
7 | 8 | from sqlalchemy.ext.asyncio import AsyncSession  | 
8 | 9 | 
 
  | 
 | 
23 | 24 | )  | 
24 | 25 | from app.modules.sport_competition.types_sport_competition import (  | 
25 | 26 |     CompetitionGroupType,  | 
 | 27 | +    ExcelExportParams,  | 
26 | 28 |     ProductSchoolType,  | 
27 | 29 | )  | 
28 |  | -from app.modules.sport_competition.utils_sport_competition import (  | 
 | 30 | +from app.modules.sport_competition.utils.data_exporter import (  | 
 | 31 | +    construct_users_excel_with_parameters,  | 
 | 32 | +)  | 
 | 33 | +from app.modules.sport_competition.utils.validation_checker import (  | 
29 | 34 |     check_validation_consistency,  | 
 | 35 | +)  | 
 | 36 | +from app.modules.sport_competition.utils_sport_competition import (  | 
30 | 37 |     checksport_category_compatibility,  | 
31 | 38 |     get_public_type_from_user,  | 
32 | 39 |     validate_payment,  | 
@@ -344,6 +351,77 @@ async def get_current_user_competition(  | 
344 | 351 |     return competition_user  | 
345 | 352 | 
 
  | 
346 | 353 | 
 
  | 
 | 354 | +@module.router.get(  | 
 | 355 | +    "/competition/users/data-export",  | 
 | 356 | +    response_class=FileResponse,  | 
 | 357 | +    status_code=200,  | 
 | 358 | +)  | 
 | 359 | +async def export_competition_users_data(  | 
 | 360 | +    included_fields: list[ExcelExportParams] = Query(default=[]),  | 
 | 361 | +    exclude_non_validated: bool = False,  | 
 | 362 | +    db: AsyncSession = Depends(get_db),  | 
 | 363 | +    user: schemas_sport_competition.CompetitionUser = Depends(  | 
 | 364 | +        is_user_in(group_id=GroupType.competition_admin),  | 
 | 365 | +    ),  | 
 | 366 | +    edition: schemas_sport_competition.CompetitionEdition = Depends(  | 
 | 367 | +        get_current_edition,  | 
 | 368 | +    ),  | 
 | 369 | +):  | 
 | 370 | +    """  | 
 | 371 | +    Export competition users data for the current edition as a CSV file.  | 
 | 372 | +    """  | 
 | 373 | +    users = await cruds_sport_competition.load_all_competition_users(  | 
 | 374 | +        edition.id,  | 
 | 375 | +        db,  | 
 | 376 | +        exclude_non_validated=exclude_non_validated,  | 
 | 377 | +    )  | 
 | 378 | +    products = await cruds_sport_competition.load_products(  | 
 | 379 | +        edition.id,  | 
 | 380 | +        db,  | 
 | 381 | +    )  | 
 | 382 | +    sports = await cruds_sport_competition.load_all_sports(db)  | 
 | 383 | +    schools = await cruds_sport_competition.load_all_schools(edition.id, db)  | 
 | 384 | + | 
 | 385 | +    participants = None  | 
 | 386 | +    if ExcelExportParams.participants in included_fields:  | 
 | 387 | +        all_participants = await cruds_sport_competition.load_all_participants(  | 
 | 388 | +            edition.id,  | 
 | 389 | +            db,  | 
 | 390 | +        )  | 
 | 391 | +        participants = {p.user_id: p for p in all_participants}  | 
 | 392 | +    payments = None  | 
 | 393 | +    if ExcelExportParams.payments in included_fields:  | 
 | 394 | +        payments = await cruds_sport_competition.load_all_payments(edition.id, db)  | 
 | 395 | +    purchases = await cruds_sport_competition.load_all_purchases(edition.id, db)  | 
 | 396 | + | 
 | 397 | +    excel_io = BytesIO()  | 
 | 398 | + | 
 | 399 | +    construct_users_excel_with_parameters(  | 
 | 400 | +        parameters=included_fields,  | 
 | 401 | +        sports=sports,  | 
 | 402 | +        schools=schools,  | 
 | 403 | +        users=users,  | 
 | 404 | +        products=products,  | 
 | 405 | +        users_participant=participants,  | 
 | 406 | +        users_payments=payments,  | 
 | 407 | +        users_purchases=purchases,  | 
 | 408 | +        export_io=excel_io,  | 
 | 409 | +    )  | 
 | 410 | + | 
 | 411 | +    res = excel_io.getvalue()  | 
 | 412 | + | 
 | 413 | +    excel_io.close()  | 
 | 414 | + | 
 | 415 | +    headers = {  | 
 | 416 | +        "Content-Disposition": f'attachment; filename="competition_users_{edition.name}.xlsx"',  | 
 | 417 | +    }  | 
 | 418 | +    return Response(  | 
 | 419 | +        res,  | 
 | 420 | +        headers=headers,  | 
 | 421 | +        media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",  | 
 | 422 | +    )  | 
 | 423 | + | 
 | 424 | + | 
347 | 425 | @module.router.get(  | 
348 | 426 |     "/competition/users/{user_id}",  | 
349 | 427 |     response_model=schemas_sport_competition.CompetitionUser,  | 
 | 
0 commit comments