62 lines
2.1 KiB
Python
62 lines
2.1 KiB
Python
"""Business logic for vacation days.
|
|
|
|
The service owns rules; the repository only persists. Routers call services, not
|
|
repositories directly. This is the REFERENCE service — keep services thin and
|
|
free of HTTP/DB details.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from uuid import UUID, uuid4
|
|
|
|
from app.entities.vacation_days import VacationDays
|
|
from app.repositories.vacation_days_repository import VacationDaysRepository
|
|
from app.utils.errors import NotFoundError, ValidationError
|
|
|
|
|
|
class VacationDaysService:
|
|
def __init__(self, repo: VacationDaysRepository) -> None:
|
|
self._repo = repo
|
|
|
|
async def upsert(
|
|
self,
|
|
personal_data_uuid: UUID,
|
|
workspace_id: UUID,
|
|
year: int,
|
|
total_days: int,
|
|
saved_days_in: int = 0,
|
|
) -> VacationDays:
|
|
"""Create or update the (parent, year) vacation entry.
|
|
|
|
Raises ValidationError on negative inputs (schema also guards this, but a
|
|
service should not trust its caller).
|
|
"""
|
|
if total_days < 0 or saved_days_in < 0:
|
|
raise ValidationError("Vacation day counts cannot be negative")
|
|
|
|
existing = await self._repo.get_by_parent_year(personal_data_uuid, year)
|
|
if existing is not None:
|
|
existing.total_days = total_days
|
|
existing.saved_days_in = saved_days_in
|
|
return await self._repo.update(existing.id, existing)
|
|
|
|
entity = VacationDays(
|
|
id=uuid4(),
|
|
personal_data_uuid=personal_data_uuid,
|
|
workspace_id=workspace_id,
|
|
year=year,
|
|
total_days=total_days,
|
|
saved_days_in=saved_days_in,
|
|
created_at=datetime.now(),
|
|
updated_at=datetime.now(),
|
|
)
|
|
return await self._repo.create(entity)
|
|
|
|
async def get(self, vacation_days_id: UUID) -> VacationDays:
|
|
entity = await self._repo.get_by_id(vacation_days_id)
|
|
if entity is None:
|
|
raise NotFoundError(f"VacationDays {vacation_days_id} not found")
|
|
return entity
|
|
|
|
async def list_for_workspace(self, workspace_id: UUID) -> list[VacationDays]:
|
|
return await self._repo.list(workspace_id=workspace_id)
|