"""Business logic for PersonalData (parent profile) settings. Routers call services, not repositories directly (see child_service.py, the reference service). This currently only covers the settings-update path (`salary_type`, `employment_status`, `min_vacation_days_per_year`) — creation lives in AuthService/WorkspaceService, which construct PersonalData directly as part of registration/invite flows. """ from uuid import UUID from app.entities.personal_data import PersonalData from app.repositories.personal_data_repository import PersonalDataRepository from app.utils.errors import NotFoundError, ValidationError _MIN_VACATION_DAYS_FLOOR = 0 _MIN_VACATION_DAYS_CEILING = 60 # generous upper bound; real cap is entitlement-dependent class PersonalDataService: def __init__(self, repo: PersonalDataRepository) -> None: self._repo = repo async def get(self, personal_data_uuid: UUID) -> PersonalData: entity = await self._repo.get_by_id(personal_data_uuid) if entity is None: raise NotFoundError(f"PersonalData {personal_data_uuid} not found") return entity async def update( self, personal_data_uuid: UUID, salary_type: str | None = None, employment_status: str | None = None, min_vacation_days_per_year: int | None = None, ) -> PersonalData: """Partial update. Raises ValidationError/NotFoundError.""" entity = await self.get(personal_data_uuid) if salary_type is not None: entity.salary_type = salary_type if employment_status is not None: entity.employment_status = employment_status if min_vacation_days_per_year is not None: _validate_min_vacation_days(min_vacation_days_per_year) entity.min_vacation_days_per_year = min_vacation_days_per_year return await self._repo.update(personal_data_uuid, entity) def _validate_min_vacation_days(value: int) -> None: if not _MIN_VACATION_DAYS_FLOOR <= value <= _MIN_VACATION_DAYS_CEILING: raise ValidationError( f"min_vacation_days_per_year must be between {_MIN_VACATION_DAYS_FLOOR} " f"and {_MIN_VACATION_DAYS_CEILING}" )