slots.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from uuid import UUID
  2. from fastapi import APIRouter, Depends, HTTPException
  3. from sqlalchemy import delete, select
  4. from sqlalchemy.ext.asyncio import AsyncSession
  5. from app.api import deps
  6. from app.api.utils import update_object_from_payload, verify_id_list
  7. from app.models import (
  8. Project,
  9. Slot,
  10. User,
  11. Volunteer,
  12. association_table_volunteer_slot,
  13. )
  14. from app.schemas.requests import (
  15. SlotCreateRequest,
  16. SlotUpdateRequest,
  17. )
  18. from app.schemas.responses import SlotResponse
  19. router = APIRouter()
  20. @router.get("/project/{id}/slots", response_model=list[SlotResponse])
  21. async def list_project_slots(
  22. id: UUID,
  23. current_user: User = Depends(deps.get_current_user),
  24. session: AsyncSession = Depends(deps.get_session),
  25. ):
  26. """List slots from project"""
  27. p = await session.get(Project, id)
  28. if p is None:
  29. raise HTTPException(status_code=404, detail="Project not found")
  30. results = await session.execute(select(Slot).where(Slot.project_id == id))
  31. return results.scalars()
  32. @router.post("/project/{id}/slot", response_model=SlotResponse)
  33. async def create_slot(
  34. id: UUID,
  35. new_slot: SlotCreateRequest,
  36. current_user: User = Depends(deps.get_current_user),
  37. session: AsyncSession = Depends(deps.get_session),
  38. ):
  39. """Create a new slot to the project"""
  40. p = await session.get(Project, id)
  41. if p is None:
  42. raise HTTPException(status_code=404, detail="Project not found")
  43. input_dict = new_slot.dict()
  44. # Extract volunteer list from input dict
  45. volunteers: list[UUID] = []
  46. if input_dict["volunteers"] is not None:
  47. volunteers = input_dict["volunteers"]
  48. await verify_id_list(
  49. session, volunteers, id, Volunteer, "Invalid volunteer list"
  50. )
  51. del input_dict["volunteers"]
  52. slot = Slot(project_id=id, **input_dict)
  53. session.add(slot)
  54. await session.commit()
  55. # Add the slot to the list of volunteer
  56. await session.execute(
  57. association_table_volunteer_slot.insert().values(
  58. [(volunteer_id, slot.id) for volunteer_id in volunteers]
  59. )
  60. )
  61. await session.commit()
  62. return slot
  63. @router.post("/project/{id}/slot/{slot_id}", response_model=SlotResponse)
  64. async def update_slot(
  65. id: UUID,
  66. slot_id: UUID,
  67. new_slot: SlotUpdateRequest,
  68. current_user: User = Depends(deps.get_current_user),
  69. session: AsyncSession = Depends(deps.get_session),
  70. ):
  71. """Update a slot from the project"""
  72. slot = await session.get(Slot, slot_id)
  73. if (slot is None) or slot.project_id != id:
  74. raise HTTPException(status_code=404, detail="Slot not found")
  75. input_dict = new_slot.dict()
  76. if input_dict["volunteers"] is not None:
  77. volunteers: list[UUID] = input_dict["volunteers"]
  78. await verify_id_list(
  79. session, volunteers, id, Volunteer, "Invalid volunteer list"
  80. )
  81. await session.execute(
  82. association_table_volunteer_slot.delete().where(
  83. association_table_volunteer_slot.c.slot_id == slot.id
  84. )
  85. )
  86. await session.execute(
  87. association_table_volunteer_slot.insert().values(
  88. [(volunteer_id, slot.id) for volunteer_id in volunteers]
  89. )
  90. )
  91. del input_dict["volunteers"]
  92. update_object_from_payload(slot, input_dict)
  93. await session.commit()
  94. await session.refresh(slot)
  95. return slot
  96. @router.delete("/project/{id}/slot/{slot_id}")
  97. async def delete_slot(
  98. id: UUID,
  99. slot_id: UUID,
  100. current_user: User = Depends(deps.get_current_user),
  101. session: AsyncSession = Depends(deps.get_session),
  102. ):
  103. """Delete a slot from the project"""
  104. await session.execute(
  105. delete(Slot).where((Slot.id == slot_id) & (Slot.project_id == id))
  106. )
  107. await session.commit()