"""Product video approval model.""" from datetime import datetime from typing import Any from sqlalchemy import ( Boolean, Column, DateTime, ForeignKey, Integer, String, Text, delete, func, select, ) from sqlalchemy.orm import Mapped, Session, mapped_column from video.connectors import mysql from video.constants import approval as approval_constants class Approval(mysql.ArModel): """Product Video.""" __tablename__ = "product_video_approval" primary_key = Column( Integer, name="id", nullable=False, primary_key=True, autoincrement=True, ) release_id = Column( Integer, ForeignKey("releases.release_id"), nullable=False, ) content_approved: Mapped[bool | None] = mapped_column(Boolean, default=False) content_approved_at: Mapped[datetime | None] = mapped_column(DateTime) content_approved_by: Mapped[str | None] = mapped_column(String) release_approved: Mapped[bool | None] = mapped_column(Boolean, default=False) release_approved_at: Mapped[datetime | None] = mapped_column(DateTime) release_approved_by: Mapped[str | None] = mapped_column(String) rejection_reason: Mapped[str | None] = mapped_column(Text) rejection_at: Mapped[datetime | None] = mapped_column(DateTime) rejection_by: Mapped[str | None] = mapped_column(String) final_approved_at: Mapped[datetime | None] = mapped_column(DateTime) final_approved_by: Mapped[str | None] = mapped_column(String) def to_dict(self) -> dict[str, Any]: """Get a dict representation.""" return { "id": self.primary_key, "release_id": self.release_id, "content_approved": self.content_approved, "content_approved_by": self.content_approved_by, "release_approved": self.release_approved, "release_approved_by": self.release_approved_by, "rejection_reason": self.rejection_reason, } def _get(release_id: int, session: Session) -> Approval | None: return session.execute( select(Approval).where(Approval.release_id == release_id) ).scalar_one_or_none() def get(release_id: int, session: Session | None = None) -> dict[str, Any]: """Get by release_id.""" if session is None: with mysql.ar_db_session() as s: return get(release_id, session=s) approval = _get(release_id, session) if not approval: return {} return approval.to_dict() def delete_approval(release_id: int, session: Session) -> None: """Delete.""" session.execute(delete(Approval).where(Approval.release_id == release_id)) def upsert( release_id: int, user_id: str | None, approval_type: str, value: bool | str | None, session: Session, ) -> dict[str, Any]: """Create or update.""" approval = _get(release_id, session) if approval: return update(approval, user_id, approval_type, value, session) return create(release_id, user_id, approval_type, value, session) def update( approval: Approval, user_id: str | None, approval_type: str, value: bool | str | None, session: Session, ) -> dict[str, Any]: """Update approval.""" if approval_type == approval_constants.CONTENT_TYPE: approval.content_approved = value # type: ignore[assignment] approval.content_approved_at = func.now() if value is True else None approval.content_approved_by = user_id if approval_type == approval_constants.RELEASE_TYPE: approval.release_approved = value # type: ignore[assignment] approval.release_approved_at = func.now() if value is True else None approval.release_approved_by = user_id if approval_type == approval_constants.FINAL_APPROVAL_TYPE: approval.final_approved_at = func.now() approval.final_approved_by = user_id if approval_type == approval_constants.REJECTION_TYPE: approval.rejection_reason = value # type: ignore[assignment] approval.rejection_at = func.now() if value else None approval.rejection_by = user_id session.add(approval) session.flush() return approval.to_dict() def create( release_id: int, user_id: str | None, approval_type: str, value: bool | str | None, session: Session, ) -> dict[str, Any]: """Create approval.""" data: dict[str, Any] = { "release_id": release_id, } if approval_type == approval_constants.CONTENT_TYPE: data["content_approved"] = value data["content_approved_at"] = func.now() if value is True else None data["content_approved_by"] = user_id if approval_type == approval_constants.RELEASE_TYPE: data["release_approved"] = value data["release_approved_at"] = func.now() if value is True else None data["release_approved_by"] = user_id if approval_type == approval_constants.FINAL_APPROVAL_TYPE: data["final_approved_at"] = func.now() data["final_approved_by"] = user_id if approval_type == approval_constants.REJECTION_TYPE: data["rejection_reason"] = value data["rejection_at"] = func.now() if value else None data["rejection_by"] = user_id approval = Approval(**data) session.add(approval) session.flush() return approval.to_dict()