volunteers.py 4.0 KB

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