Remove a period's days along with the period
Deleting a period left every day it had funded behind. The link from a day back to its period was set to null the instant the period was deleted, so the days became untraceable before anything could clean them up, and the next recalculation had no way to know they no longer belonged to anything. Undo had the same fault for the same reason: the period went, the days stayed, and a reload showed them still there. The days are now removed with the period, before the link can be broken. A day pinned by hand goes too — pinning keeps the planner from quietly retyping a day, not from being deleted when you delete the period it belongs to, which is already how an unplanned band behaves.
This commit is contained in:
@@ -10,6 +10,7 @@ from uuid import UUID, uuid4
|
||||
|
||||
from app.entities.leave_wish import LeaveWish
|
||||
from app.repositories.leave_wish_repository import LeaveWishRepository
|
||||
from app.repositories.planned_leave_repository import PlannedLeaveRepository
|
||||
from app.utils.errors import NotFoundError, ValidationError
|
||||
|
||||
_VALID_RECURRENCE = {"yearly", "once"}
|
||||
@@ -21,8 +22,13 @@ _LEAP_REFERENCE_YEAR = 2028
|
||||
|
||||
|
||||
class LeaveWishService:
|
||||
def __init__(self, repo: LeaveWishRepository) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
repo: LeaveWishRepository,
|
||||
planned_leave_repo: PlannedLeaveRepository,
|
||||
) -> None:
|
||||
self._repo = repo
|
||||
self._planned_leave_repo = planned_leave_repo
|
||||
|
||||
async def create(
|
||||
self,
|
||||
@@ -197,7 +203,29 @@ class LeaveWishService:
|
||||
return await self._repo.update(leave_wish_id, entity)
|
||||
|
||||
async def delete(self, leave_wish_id: UUID) -> None:
|
||||
"""Delete a wish and every `planned_leave_day` row it produced.
|
||||
|
||||
Under the calendar-direct-manipulation UX a period *is* its wish: the
|
||||
band the user drew, the days the allocator filled it with, and any
|
||||
of those days the user later hand-edited are all one thing. Deleting
|
||||
the period must remove all of it — including pinned days.
|
||||
`wish_id` is nullable and `ON DELETE SET NULL` at the schema level
|
||||
(so a row can still exist detached/ad-hoc), but that "orphan, don't
|
||||
delete" behavior is wrong for this call path: the rows are deleted
|
||||
explicitly, *before* the wish row goes, so the FK's SET NULL never
|
||||
gets a row left to act on. See `PlannedLeaveRepository.delete_by_wish`.
|
||||
|
||||
A pinned day is deleted too rather than surviving as ad-hoc. Pinning
|
||||
only protects a day from being silently retyped/reassigned by a
|
||||
later `sync_plan` re-plan (see that method's docstring) — it is not
|
||||
a signal that the day should outlive the period a user explicitly
|
||||
chose to delete. This also matches the ad-hoc-period delete path
|
||||
(`Calendar.handleDeletePeriod`'s no-`wishId` branch), which already
|
||||
deletes every day in the band regardless of `is_pinned` with no
|
||||
special-casing.
|
||||
"""
|
||||
await self.get(leave_wish_id) # raises NotFoundError if missing
|
||||
await self._planned_leave_repo.delete_by_wish(leave_wish_id)
|
||||
await self._repo.delete(leave_wish_id)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user