volunteers.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. from uuid import UUID
  2. from fastapi import APIRouter, Depends, HTTPException
  3. from sqlalchemy import delete, select
  4. from sqlalchemy.orm import Session
  5. from app.api import deps
  6. from app.api.utils import assert_project_exists, update_object_from_payload, verify_id_list
  7. from app.models import Slot, User, Volunteer, association_table_volunteer_slot
  8. from app.schemas.requests import VolunteerCreateRequest, VolunteerUpdateRequest
  9. from app.schemas.responses import VolunteerResponse
  10. router = APIRouter(prefix="/project/{project_id}", tags=["volunteers"])
  11. @router.get("/volunteers", response_model=list[VolunteerResponse])
  12. async def list_project_volunteers(
  13. project_id: UUID,
  14. current_user: User = Depends(deps.get_current_user),
  15. session: Session = Depends(deps.get_session),
  16. ):
  17. """List volunteers from project"""
  18. assert_project_exists(session, project_id)
  19. results = session.execute(select(Volunteer).where(Volunteer.project_id == project_id))
  20. return results.scalars().all()
  21. @router.post("/volunteer", response_model=VolunteerResponse)
  22. async def create_volunteer(
  23. project_id: UUID,
  24. new_volunteer: VolunteerCreateRequest,
  25. current_user: User = Depends(deps.get_current_user),
  26. session: Session = Depends(deps.get_session),
  27. ):
  28. """Create a new volunteer to the project"""
  29. assert_project_exists(session, project_id)
  30. input_dict = new_volunteer.model_dump()
  31. # Extract slots list from input dict
  32. slots: list[UUID] = []
  33. if input_dict["slots"] is not None:
  34. slots = input_dict["slots"]
  35. await verify_id_list(session, slots, project_id, Slot, "Invalid slot list")
  36. del input_dict["slots"]
  37. volunteer = Volunteer(project_id=project_id, **input_dict)
  38. session.add(volunteer)
  39. # commit to optain an id for the volunteer
  40. session.commit()
  41. if len(slots) > 0:
  42. session.execute(
  43. association_table_volunteer_slot.insert().values(
  44. [(volunteer.id, slot_id) for slot_id in slots]
  45. )
  46. )
  47. session.commit()
  48. return volunteer
  49. @router.post("/volunteer/{volunteer_id}", response_model=VolunteerResponse)
  50. async def update_volunteer(
  51. project_id: UUID,
  52. volunteer_id: UUID,
  53. new_volunteer: VolunteerUpdateRequest,
  54. current_user: User = Depends(deps.get_current_user),
  55. session: Session = Depends(deps.get_session),
  56. ):
  57. """Update a volunteer from the project"""
  58. volunteer = session.get(Volunteer, volunteer_id)
  59. if (volunteer is None) or (volunteer.project_id != str(project_id)):
  60. raise HTTPException(status_code=404, detail="Volunteer not found")
  61. input_dict = new_volunteer.model_dump(exclude_unset=True)
  62. # Extract slots list from input dict
  63. if "slots" in input_dict:
  64. slots: list[UUID] = input_dict["slots"]
  65. await verify_id_list(session, slots, project_id, Slot, "Invalid slot list")
  66. # Remove previous values
  67. session.execute(
  68. association_table_volunteer_slot.delete().where(
  69. association_table_volunteer_slot.c.volunteer_id == volunteer.id
  70. )
  71. )
  72. # Add the new slots
  73. if len(slots) > 0:
  74. session.execute(
  75. association_table_volunteer_slot.insert().values(
  76. [(volunteer.id, slot_id) for slot_id in slots]
  77. )
  78. )
  79. del input_dict["slots"]
  80. update_object_from_payload(volunteer, input_dict)
  81. session.commit()
  82. session.refresh(volunteer)
  83. return volunteer
  84. @router.delete("/volunteer/{volunteer_id}")
  85. async def delete_volunteer(
  86. project_id: UUID,
  87. volunteer_id: UUID,
  88. current_user: User = Depends(deps.get_current_user),
  89. session: Session = Depends(deps.get_session),
  90. ):
  91. """Delete a volunteer from the project"""
  92. session.execute(
  93. delete(Volunteer).where(
  94. (Volunteer.id == volunteer_id) & (Volunteer.project_id == project_id)
  95. )
  96. )
  97. session.commit()