from typing import Optional from fastapi import APIRouter, HTTPException, Query, status from sqlalchemy.exc import IntegrityError from sqlmodel import Session, select from app.db import SessionDep from app.dependencies import CurrentUser, get_mail_template_in_organization, get_route_in_organization from app.models.mail_template import MailTemplate, MailTemplateCreate, MailTemplatePublic, MailTemplateUpdate from app.models.route import Route router = APIRouter(prefix="/mail-templates", tags=["mail-templates"]) def _commit_or_conflict(session: Session) -> None: try: session.commit() except IntegrityError as exc: session.rollback() if "uq_mail_template_route_event" in str(getattr(exc, "orig", exc)): raise HTTPException( status_code=status.HTTP_409_CONFLICT, detail="A mail template for this event type already exists on this route", ) from exc raise @router.post("", response_model=MailTemplatePublic, status_code=status.HTTP_201_CREATED) def create_mail_template(payload: MailTemplateCreate, session: SessionDep, current_user: CurrentUser) -> MailTemplate: get_route_in_organization(session, payload.route_id, current_user.organization_id) mail_template = MailTemplate.model_validate(payload) session.add(mail_template) _commit_or_conflict(session) session.refresh(mail_template) return mail_template @router.get("", response_model=list[MailTemplatePublic]) def list_mail_templates( session: SessionDep, current_user: CurrentUser, route_id: Optional[int] = None, ) -> list[MailTemplate]: statement = select(MailTemplate).join(Route).where(Route.organization_id == current_user.organization_id) if route_id is not None: statement = statement.where(MailTemplate.route_id == route_id) statement = statement.order_by(MailTemplate.id) return list(session.exec(statement).all()) @router.get("/{template_id}", response_model=MailTemplatePublic) def get_mail_template(template_id: int, session: SessionDep, current_user: CurrentUser) -> MailTemplate: return get_mail_template_in_organization(session, template_id, current_user.organization_id) @router.patch("/{template_id}", response_model=MailTemplatePublic) def update_mail_template( template_id: int, payload: MailTemplateUpdate, session: SessionDep, current_user: CurrentUser ) -> MailTemplate: mail_template = get_mail_template_in_organization(session, template_id, current_user.organization_id) for field, value in payload.model_dump(exclude_unset=True).items(): setattr(mail_template, field, value) session.add(mail_template) _commit_or_conflict(session) session.refresh(mail_template) return mail_template @router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT) def delete_mail_template(template_id: int, session: SessionDep, current_user: CurrentUser) -> None: mail_template = get_mail_template_in_organization(session, template_id, current_user.organization_id) session.delete(mail_template) session.commit()