feat(backend): add ability to schedule member in cli
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional, Tuple, List
|
||||
from typing import Optional, Tuple, List, Iterable
|
||||
|
||||
from backend.repositories import (
|
||||
ClassificationRepository,
|
||||
@@ -48,7 +48,7 @@ class SchedulingService:
|
||||
service_id: int,
|
||||
*,
|
||||
only_active: bool = True,
|
||||
boost_seconds: int = 5 * 24 * 60 * 60,
|
||||
boost_seconds: int = 2 * 24 * 60 * 60,
|
||||
exclude_member_ids: Iterable[int] | None = None,
|
||||
) -> Optional[Tuple[int, str, str, int]]:
|
||||
"""
|
||||
@@ -224,4 +224,78 @@ class SchedulingService:
|
||||
status=ScheduleStatus.DECLINED,
|
||||
reason=reason,
|
||||
)
|
||||
return ("created", new_sched.ScheduleId)
|
||||
return ("created", new_sched.ScheduleId)
|
||||
|
||||
def preview_next_member(
|
||||
self,
|
||||
classification_ids: Iterable[int],
|
||||
service_id: int,
|
||||
*,
|
||||
only_active: bool = True,
|
||||
boost_seconds: int = 2 * 24 * 60 * 60,
|
||||
exclude_member_ids: Iterable[int] | None = None,
|
||||
) -> Optional[Tuple[int, str, str]]:
|
||||
"""
|
||||
Preview who would be scheduled next for a service without actually creating the schedule.
|
||||
|
||||
Same logic as schedule_next_member, but doesn't create any records.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Tuple[member_id, first_name, last_name] | None
|
||||
The member who would be scheduled next, or None if no eligible member found.
|
||||
"""
|
||||
# Same logic as schedule_next_member but without creating records
|
||||
svc = self.service_repo.get_by_id(service_id)
|
||||
if svc is None:
|
||||
return None
|
||||
|
||||
service_type_id = svc.ServiceTypeId
|
||||
target_date = svc.ServiceDate
|
||||
|
||||
excluded = set(exclude_member_ids or [])
|
||||
candidates: List = self.member_repo.candidate_queue(
|
||||
classification_ids=list(classification_ids),
|
||||
only_active=only_active,
|
||||
boost_seconds=boost_seconds,
|
||||
)
|
||||
|
||||
for member in candidates:
|
||||
member_id = member.MemberId
|
||||
|
||||
if member_id in excluded:
|
||||
continue
|
||||
|
||||
if not self.availability_repo.get(member_id, service_type_id):
|
||||
continue
|
||||
|
||||
if self.schedule_repo.has_schedule_on_date(member_id, target_date):
|
||||
continue
|
||||
|
||||
if self.schedule_repo.has_any(
|
||||
member_id,
|
||||
service_id,
|
||||
statuses=[ScheduleStatus.ACCEPTED],
|
||||
):
|
||||
continue
|
||||
if self.schedule_repo.has_any(
|
||||
member_id,
|
||||
service_id,
|
||||
statuses=[ScheduleStatus.PENDING],
|
||||
):
|
||||
continue
|
||||
if self.schedule_repo.has_any(
|
||||
member_id,
|
||||
service_id,
|
||||
statuses=[ScheduleStatus.DECLINED],
|
||||
):
|
||||
continue
|
||||
|
||||
# Found eligible member - return without creating schedule
|
||||
return (
|
||||
member_id,
|
||||
member.FirstName,
|
||||
member.LastName,
|
||||
)
|
||||
|
||||
return None
|
||||
Reference in New Issue
Block a user