| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- from datetime import timedelta
- from uuid import UUID
- from fastapi import APIRouter, Depends, HTTPException
- from sqlalchemy import delete, select
- from sqlalchemy.exc import IntegrityError
- from sqlalchemy.ext.asyncio import AsyncSession
- from app.api import deps
- from app.models import Project, Slot, Sms, User
- from app.schemas.requests import (
- ProjectImportGsheetRequest,
- ProjectRequest,
- ProjectSMSBatchRequest,
- )
- from app.schemas.responses import ProjectListResponse, ProjectResponse, SMSResponse
- router = APIRouter()
- @router.get("/projects", response_model=list[ProjectListResponse])
- async def list_project(
- current_user: User = Depends(deps.get_current_user),
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Get project_list"""
- results = await session.execute(select(Project))
- return results.scalars().all()
- @router.get("/public-projects", response_model=list[ProjectListResponse])
- async def list_public_project(
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Get the list of public projects"""
- results = await session.execute(select(Project).where(Project.is_public == True))
- return results.scalars().all()
- @router.post("/project", response_model=ProjectResponse)
- async def create_project(
- new_project: ProjectRequest,
- current_user: User = Depends(deps.get_current_user),
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Create a new project"""
- project = Project(**new_project.dict())
- session.add(project)
- try:
- await session.commit()
- except IntegrityError as e:
- raise HTTPException(422, "Project name already exist")
- await session.refresh(project)
- return ProjectResponse.from_orm(project)
- @router.get("/public-project/{id}", response_model=ProjectResponse)
- async def get_public_project(
- id: UUID,
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Get a project that is public"""
- result = await session.get(Project, id)
- if (result is None) or not result.is_public:
- return HTTPException(status_code=404, detail="Project not found")
- return result
- @router.get("/project/{id}", response_model=ProjectResponse)
- async def get_project(
- id: UUID,
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Get a project"""
- project = await session.get(Project, id)
- if project is None:
- return HTTPException(status_code=404, detail="Project not found")
- project.sms
- project.volunteers
- project.slots
- response = ProjectResponse.from_orm(project)
- return response
- @router.post("/project/{id}", response_model=ProjectListResponse)
- async def update_project(
- id: UUID,
- edit_project: ProjectRequest,
- current_user: User = Depends(deps.get_current_user),
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Edit project"""
- p = await session.get(Project, id)
- if p is None:
- raise HTTPException(status_code=404, detail="Project not found")
- p.name = edit_project.name
- p.is_public = edit_project.is_public
- await session.commit()
- return p
- @router.post("/project/{id}/import-gsheet", response_model=ProjectResponse)
- async def update_project_from_gsheet(
- id: UUID,
- gsheet: ProjectImportGsheetRequest,
- current_user: User = Depends(deps.get_current_user),
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Edit project name"""
- p = await session.get(Project, id)
- if p is None:
- raise HTTPException(status_code=404, detail="Project not found")
- url = gsheet.sheet_url
- # TODO implement feature to import
- return p
- @router.post("/project/{id}/create-all-sms", response_model=list[SMSResponse])
- async def create_sms_batch(
- id: UUID,
- sms_batch: ProjectSMSBatchRequest,
- current_user: User = Depends(deps.get_current_user),
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Create SMS based on a template and the list of slots and volunteer associated to the project
- The placeholder that can be used in the template are
- - {titre} slot.title
- - {description} slot.description
- - {debut} slot.starting_time
- - {fin} slot.ending_ting
- - {prenom} volunteer.name
- - {name} volunteer.surname
- """
- p = await session.get(Project, id)
- if p is None:
- raise HTTPException(status_code=404, detail="Project not found")
- # Get all slots
- slots = await session.execute(select(Slot).where(Slot.project_id == id))
- sms_list = []
- for slot in slots.scalars():
- # Replace the slot placeholder by their value
- slot_content = (
- sms_batch.template.replace("{titre}", slot.title)
- .replace("{description}", slot.description)
- .replace("{debut}", str(slot.starting_time))
- .replace("{fin}", str(slot.ending_time))
- )
- sending_time = slot.starting_time - timedelta(minutes=sms_batch.delta_t)
- for volunteer in slot.volunteers:
- # Create a new SMS customized for each user attache to the slot
- personalized_content = slot_content.replace(
- "{prenom}", volunteer.name
- ).replace("{nom}", volunteer.surname)
- sms = Sms(
- project_id=id,
- volunteer_id=volunteer.id,
- content=personalized_content,
- phone_number=volunteer.phone_number,
- sending_time=sending_time,
- )
- sms_list.append(sms)
- session.add_all(sms_list)
- await session.commit()
- return sms_list
- @router.delete("/project/{id}")
- async def delete_project(
- id: UUID,
- current_user: User = Depends(deps.get_current_user),
- session: AsyncSession = Depends(deps.get_session),
- ):
- """Delete project"""
- await session.execute(delete(Project).where(Project.id == id))
- await session.commit()
|