Files
F-r-ldraledigplannerare/backend/app/services/planning_service.py
T
2026-06-01 16:48:21 +02:00

94 lines
3.2 KiB
Python

"""Business logic for planned leave days (calendar planning)."""
from datetime import date, datetime
from uuid import UUID, uuid4
from app.entities.planned_leave import PlannedLeaveDay
from app.repositories.planned_leave_repository import PlannedLeaveRepository
from app.services.analytics_service import AnalyticsService
from app.utils.errors import NotFoundError, ValidationError
class PlanningService:
def __init__(
self,
repo: PlannedLeaveRepository,
analytics_service: AnalyticsService,
) -> None:
self._repo = repo
self._analytics = analytics_service
async def add_planned_day(
self,
workspace_id: UUID,
child_id: UUID,
parent_personal_data_uuid: UUID,
date: date,
day_type: str,
is_dubbeldag: bool = False,
) -> PlannedLeaveDay:
"""Add a planned leave day.
Validates that the day is available (dubbeldagar rules, no double-booking).
"""
# Validation 1: Check dubbeldagar quota if this is a dubbeldag
if is_dubbeldag:
await self._analytics.validate_dubbeldagar(child_id, date)
# Validation 2: Check no double-booking on the same date
existing = await self._repo.list_by_workspace_child(
workspace_id=workspace_id,
child_id=child_id,
from_date=date,
to_date=date,
)
if existing:
raise ValidationError(f"A planned day already exists on {date}")
now = datetime.now()
entity = PlannedLeaveDay(
id=uuid4(),
workspace_id=workspace_id,
child_id=child_id,
parent_personal_data_uuid=parent_personal_data_uuid,
date=date,
day_type=day_type,
is_dubbeldag=is_dubbeldag,
created_at=now,
updated_at=now,
)
return await self._repo.create(entity)
async def remove_planned_day(self, planned_leave_day_id: UUID) -> None:
"""Remove a planned leave day."""
entity = await self._repo.get_by_id(planned_leave_day_id)
if entity is None:
raise NotFoundError(f"PlannedLeaveDay {planned_leave_day_id} not found")
await self._repo.delete(planned_leave_day_id)
async def list_by_workspace(self, workspace_id: UUID) -> list[PlannedLeaveDay]:
"""Get all planned days for a workspace."""
return await self._repo.list(workspace_id=workspace_id)
async def list_by_date_range(
self,
workspace_id: UUID,
child_id: UUID,
start_date: date,
end_date: date,
) -> list[PlannedLeaveDay]:
"""Get planned days within a date range for a child."""
return await self._repo.list_by_workspace_child(
workspace_id=workspace_id,
child_id=child_id,
from_date=start_date,
to_date=end_date,
)
async def get(self, planned_leave_day_id: UUID) -> PlannedLeaveDay:
"""Get a planned day by ID."""
entity = await self._repo.get_by_id(planned_leave_day_id)
if entity is None:
raise NotFoundError(f"PlannedLeaveDay {planned_leave_day_id} not found")
return entity