"""CRUD service for CustomFieldDefinition.""" from __future__ import annotations import uuid from typing import Any from sqlalchemy import select, delete from sqlalchemy.ext.asyncio import AsyncSession from app.models.custom_field_definition import CustomFieldDefinition async def list_definitions( db: AsyncSession, tenant_id: uuid.UUID, entity: str | None = None, ) -> list[CustomFieldDefinition]: """List custom field definitions for a tenant, optionally filtered by entity.""" stmt = select(CustomFieldDefinition).where( CustomFieldDefinition.tenant_id == tenant_id, CustomFieldDefinition.is_active == True, # noqa: E712 ) if entity: stmt = stmt.where(CustomFieldDefinition.entity == entity) stmt = stmt.order_by(CustomFieldDefinition.sort_order, CustomFieldDefinition.name) result = await db.execute(stmt) return list(result.scalars().all()) async def get_definition( db: AsyncSession, tenant_id: uuid.UUID, definition_id: uuid.UUID, ) -> CustomFieldDefinition | None: """Get a single custom field definition by ID.""" stmt = select(CustomFieldDefinition).where( CustomFieldDefinition.id == definition_id, CustomFieldDefinition.tenant_id == tenant_id, ) result = await db.execute(stmt) return result.scalar_one_or_none() async def create_definition( db: AsyncSession, tenant_id: uuid.UUID, user_id: uuid.UUID, data: dict[str, Any], ) -> CustomFieldDefinition: """Create a new custom field definition.""" definition = CustomFieldDefinition( tenant_id=tenant_id, entity=data["entity"], name=data["name"], label=data["label"], field_type=data["field_type"], options=data.get("options"), default_value=data.get("default_value"), required=data.get("required", False), is_active=data.get("is_active", True), sort_order=data.get("sort_order", 0), created_by=user_id, updated_by=user_id, ) db.add(definition) await db.flush() await db.refresh(definition) return definition async def update_definition( db: AsyncSession, tenant_id: uuid.UUID, definition_id: uuid.UUID, data: dict[str, Any], user_id: uuid.UUID | None = None, ) -> CustomFieldDefinition | None: """Update an existing custom field definition.""" definition = await get_definition(db, tenant_id, definition_id) if definition is None: return None update_fields = ["label", "field_type", "options", "default_value", "required", "is_active", "sort_order"] for field in update_fields: if field in data: setattr(definition, field, data[field]) if user_id is not None: definition.updated_by = user_id await db.flush() await db.refresh(definition) return definition async def delete_definition( db: AsyncSession, tenant_id: uuid.UUID, definition_id: uuid.UUID, ) -> bool: """Delete a custom field definition.""" stmt = select(CustomFieldDefinition).where( CustomFieldDefinition.id == definition_id, CustomFieldDefinition.tenant_id == tenant_id, ) result = await db.execute(stmt) definition = result.scalar_one_or_none() if definition is None: return False await db.delete(definition) await db.flush() return True