Department_Module
ahmed.mujtaba 2026-09-14 14:55:01 +05:00
parent ff1f91973d
commit addbc77d2b
5 changed files with 167 additions and 0 deletions

54
backend/department/app.py Normal file
View File

@ -0,0 +1,54 @@
from fastapi import APIRouter,Depends,Query,Response
from fastapi.responses import FileResponse,JSONResponse
from fastapi import HTTPException,Request
from db_setup import get_session
from department.models import Department
from department.views import DepartmentCreate,DepartmentGet
from users.permissions import PermissionTag, require_permission
from sqlalchemy.ext.asyncio import AsyncSession
import uuid
import json
from dotenv import load_dotenv
import logging
from typing import Optional,Annotated
from users.permissions import get_current_user
from pydantic import BaseModel
from uuid import UUID
from typing import Literal, Optional
import os
import uuid
load_dotenv()
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/create")
async def create_department(
request: Request,
session: Annotated[AsyncSession, Depends(get_session)],
current_user: Annotated[dict, Depends(get_current_user)]):
try:
data=await request.json()
department_data=DepartmentCreate(data,session)
department=await department_data.create_department()
return JSONResponse(status_code=201, content={"message": "Department created successfully", "department": department.model_dump()})
except Exception as e:
logger.error(f"Error creating department: {e}")
raise HTTPException(status_code=500, detail=str(e))
@router.get("/get/{department_id}")
async def get_department_by_id(
session: Annotated[AsyncSession, Depends(get_session)],
department_id:Optional[UUID] = None,
current_user: Annotated[dict, Depends(get_current_user)]):
try:
if not department_id:
# send back the list of all departments
department_data=DepartmentGet(department_id,session)
department=await department_data.get_department_by_id()
return JSONResponse(status_code=200, content={"message": "Department fetched successfully", "department": department.model_dump()})
except Exception as e:
logger.error(f"Error fetching department: {e}")
raise HTTPException(status_code=500, detail=str(e))

View File

@ -0,0 +1,74 @@
import uuid
from datetime import datetime, timezone
from typing import Optional,List
from sqlalchemy import DateTime, func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import Field, SQLModel, select
from fastapi import HTTPException
from users.models import Users
def _now() -> datetime:
return datetime.now(timezone.utc)
class Department(SQLModel, table=True):
__tablename__ = "departments"
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
name: str = Field(index=True,unique=True)
description: Optional[str] = Field(default="")
short_code: Optional[str] = Field(default="",max_length=10)
is_active: bool = Field(default=True)
parent_department_id: Optional[uuid.UUID] = Field(foreign_key="departments.id")
department_head_id: Optional[uuid.UUID] = Field(foreign_key="users.id")
location:Optional[List[str]] = Field(default_factory=list)
subtitle:Optional[str] = Field(default="")
created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
created_by: Optional[uuid.UUID] = Field(foreign_key="users.id")
updated_by: Optional[uuid.UUID] = Field(foreign_key="users.id")
@staticmethod
def _as_uuid(record_id) -> uuid.UUID | None:
if record_id in (None, ""):
return None
try:
return uuid.UUID(str(record_id))
except ValueError:
return None
@classmethod
async def create_department(cls,session:AsyncSession,data:dict):
try:
uid=cls._as_uuid(data.get("parent_department_id"))
if data.get("department_head_id"):
user=await Users.get_by_id(session,data.get("department_head_id"))
if not user:
raise HTTPException(status_code=404, detail="User not found")
department_head_id=user.id
else:
raise HTTPException(status_code=400, detail="Department head ID is required")
department=cls(
name=data.get("name"),
description=data.get("description"),
short_code=data.get("short_code"),
parent_department_id=uid if data.get("parent_department_id") else None,
department_head_id=department_head_id,
location=data.get("location"),
subtitle=data.get("subtitle"),
created_by=data.get("created_by"),
updated_by=data.get("updated_by"),
)
session.add(department)
await session.commit()
return department
except Exception as e:
session.rollback()
raise HTTPException(status_code=500, detail=str(e))
@classmethod
async def get_department_by_id(cls,session:AsyncSession,department_id:uuid.UUID):
uid=cls._as_uuid(department_id)
if uid is None:
raise ValueError("Invalid department ID")
result=await session.execute(select(cls).where(cls.id == uid))
return result.scalars().first()

View File

View File

@ -0,0 +1,28 @@
from sqlalchemy.ext.asyncio import AsyncSession
from department.models import Department
from fastapi import HTTPException
class DepartmentCreate:
def __init__(self,data,db=AsyncSession) -> None:
self.data=data
self.db=db
async def create_department(self):
try:
department=Department.create_department(self.db,self.data)
return department
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
class DepartmentGet(DepartmentCreate):
def __init__(self,department_id,db=AsyncSession) -> None:
self.department_id=department_id
super().__init__(None,self.db)
async def get_department_by_id(self):
try:
department=Department.get_department_by_id(self.db,self.department_id)
return department
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

View File

@ -30,6 +30,7 @@ class PermissionModule(str, Enum):
JOBS = "jobs"
CANDIDATES = "candidates"
PIPELINE = "pipeline"
DEPARTMENT = "department"
INTERVIEWS = "interviews"
ASSESSMENTS = "assessments"
OFFERS = "offers"
@ -71,6 +72,16 @@ class PermissionTag(str, Enum):
DASHBOARD_EXPORT = "dashboard.export"
DASHBOARD_MANAGE = "dashboard.manage"
DASHBOARD_CONFIGURE = "dashboard.configure"
DEPARTMENT_VIEW = "department.view"
DEPARTMENT_CREATE = "department.create"
DEPARTMENT_EDIT = "department.edit"
DEPARTMENT_DELETE = "department.delete"
DEPARTMENT_APPROVE = "department.approve"
DEPARTMENT_EXPORT = "department.export"
DEPARTMENT_MANAGE = "department.manage"
DEPARTMENT_CONFIGURE = "department.configure"
INBOX_VIEW = "inbox.view"
INBOX_CREATE = "inbox.create"
INBOX_EDIT = "inbox.edit"