HR-ATS-Portal/backend/org_settings/models.py

264 lines
9.0 KiB
Python

from typing import Any
import uuid
from datetime import datetime, timezone
from sqlalchemy import DateTime, JSON, func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import Field, SQLModel, select
def _now() -> datetime:
return datetime.now(timezone.utc)
class OrgSettings(SQLModel, table=True):
__tablename__ = "org_settings"
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
setting_key: str = Field(unique=True, index=True)
setting_value: Any = Field(sa_type=JSON)
category: str
updated_by: uuid.UUID | None = Field(default=None, foreign_key="users.id")
created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
@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 fetch_settings(cls, session: AsyncSession, *, category: str | None = None):
statement = select(cls)
if category:
statement = statement.where(cls.category == category)
statement = statement.order_by(cls.setting_key.asc())
result = await session.execute(statement)
rows = list(result.scalars().all())
return rows, len(rows)
@classmethod
async def get_by_key(cls, session: AsyncSession, setting_key: str):
result = await session.execute(select(cls).where(cls.setting_key == setting_key))
return result.scalars().first()
@classmethod
async def upsert_settings(cls, session: AsyncSession, items: list[dict], updated_by):
rows = []
now = _now()
for item in items:
key = item["setting_key"]
row = await cls.get_by_key(session, key)
if row is None:
row = cls(
setting_key=key,
setting_value=item.get("setting_value"),
category=item["category"],
updated_by=updated_by,
created_at=now,
updated_at=now,
)
else:
row.setting_value = item.get("setting_value")
row.category = item["category"]
row.updated_by = updated_by
row.updated_at = now
session.add(row)
rows.append(row)
await session.commit()
for row in rows:
await session.refresh(row)
return rows
class ExcludeUniversity(SQLModel, table=True):
__tablename__ = "exclude_university"
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
name: str = Field(index=True)
created_by: uuid.UUID | None = Field(default=None, foreign_key="users.id")
created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
is_deleted: bool = Field(default=False)
@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 get_by_id(cls, session: AsyncSession, record_id):
uid = cls._as_uuid(record_id)
if uid is None:
return None
result = await session.execute(
select(cls).where(cls.id == uid, cls.is_deleted == False) # noqa: E712
)
return result.scalars().first()
@classmethod
async def get_by_name(cls, session: AsyncSession, name: str, *, exclude_id=None):
cleaned = (name or "").strip()
if not cleaned:
return None
statement = select(cls).where(
func.lower(cls.name) == cleaned.lower(),
cls.is_deleted == False, # noqa: E712
)
if exclude_id is not None:
uid = cls._as_uuid(exclude_id)
if uid is not None:
statement = statement.where(cls.id != uid)
result = await session.execute(statement)
return result.scalars().first()
@classmethod
async def fetch_rows(cls, session: AsyncSession):
statement = select(cls).where(cls.is_deleted == False).order_by(cls.name.asc()) # noqa: E712
result = await session.execute(statement)
rows = list(result.scalars().all())
return rows, len(rows)
@classmethod
async def fetch_names(cls, session: AsyncSession) -> list[str]:
rows, _ = await cls.fetch_rows(session)
return [r.name for r in rows if r.name]
@classmethod
async def insert_row(cls, session: AsyncSession, fields: dict):
row = cls(**fields)
session.add(row)
await session.commit()
return await cls.get_by_id(session, row.id)
@classmethod
async def update_row(cls, session: AsyncSession, record_id, fields: dict):
row = await cls.get_by_id(session, record_id)
if not row:
return None
for key, value in fields.items():
setattr(row, key, value)
row.updated_at = _now()
session.add(row)
await session.commit()
await session.refresh(row)
return row
@classmethod
async def soft_delete_row(cls, session: AsyncSession, record_id):
row = await cls.get_by_id(session, record_id)
if not row:
return None
row.is_deleted = True
row.updated_at = _now()
session.add(row)
await session.commit()
return row
class ExcludeCompany(SQLModel, table=True):
__tablename__ = "exclude_company"
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
name: str = Field(index=True)
linkedin_url: str | None = Field(default=None)
created_by: uuid.UUID | None = Field(default=None, foreign_key="users.id")
created_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
updated_at: datetime = Field(default_factory=_now, sa_type=DateTime(timezone=True))
is_deleted: bool = Field(default=False)
@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 get_by_id(cls, session: AsyncSession, record_id):
uid = cls._as_uuid(record_id)
if uid is None:
return None
result = await session.execute(
select(cls).where(cls.id == uid, cls.is_deleted == False) # noqa: E712
)
return result.scalars().first()
@classmethod
async def get_by_name(cls, session: AsyncSession, name: str, *, exclude_id=None):
cleaned = (name or "").strip()
if not cleaned:
return None
statement = select(cls).where(
func.lower(cls.name) == cleaned.lower(),
cls.is_deleted == False, # noqa: E712
)
if exclude_id is not None:
uid = cls._as_uuid(exclude_id)
if uid is not None:
statement = statement.where(cls.id != uid)
result = await session.execute(statement)
return result.scalars().first()
@classmethod
async def fetch_rows(cls, session: AsyncSession):
statement = select(cls).where(cls.is_deleted == False).order_by(cls.name.asc()) # noqa: E712
result = await session.execute(statement)
rows = list(result.scalars().all())
return rows, len(rows)
@classmethod
async def fetch_names(cls, session: AsyncSession) -> list[str]:
rows, _ = await cls.fetch_rows(session)
return [r.name for r in rows if r.name]
@classmethod
async def fetch_linkedin_urls(cls, session: AsyncSession) -> list[str]:
rows, _ = await cls.fetch_rows(session)
return [r.linkedin_url for r in rows if r.linkedin_url]
@classmethod
async def insert_row(cls, session: AsyncSession, fields: dict):
row = cls(**fields)
session.add(row)
await session.commit()
return await cls.get_by_id(session, row.id)
@classmethod
async def update_row(cls, session: AsyncSession, record_id, fields: dict):
row = await cls.get_by_id(session, record_id)
if not row:
return None
for key, value in fields.items():
setattr(row, key, value)
row.updated_at = _now()
session.add(row)
await session.commit()
await session.refresh(row)
return row
@classmethod
async def soft_delete_row(cls, session: AsyncSession, record_id):
row = await cls.get_by_id(session, record_id)
if not row:
return None
row.is_deleted = True
row.updated_at = _now()
session.add(row)
await session.commit()
return row
import users.models as _users_models # noqa: E402, F401