slots.py 4.3 KB

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