2026-01-26 10:30:49 -05:00

228 lines
6.0 KiB
Python

"""
Repository for Service model operations.
"""
from typing import List, Optional, Dict, Any
from datetime import date
from django.db.models import QuerySet
from django.utils import timezone
from backend.core.models import Service, Profile
from backend.core.repositories.base import BaseRepository
class ServiceRepository(BaseRepository[Service]):
"""
Repository for Service model operations.
"""
model = Service
@classmethod
def get_by_account(cls, account_id: str) -> QuerySet[Service]:
"""
Get services by account.
Args:
account_id: The account ID
Returns:
QuerySet of services for the account
"""
return Service.objects.filter(account_id=account_id)
@classmethod
def get_by_team_member(cls, profile_id: str) -> QuerySet[Service]:
"""
Get services by team member.
Args:
profile_id: The profile ID
Returns:
QuerySet of services assigned to the team member
"""
return Service.objects.filter(team_members__id=profile_id)
@classmethod
def get_by_status(cls, status: str) -> QuerySet[Service]:
"""
Get services by status.
Args:
status: The service status
Returns:
QuerySet of services with the specified status
"""
return Service.objects.filter(status=status)
@classmethod
def get_by_date_range(cls, start_date: date = None, end_date: date = None) -> QuerySet[Service]:
"""
Get services within a date range.
Args:
start_date: Start date (inclusive)
end_date: End date (inclusive)
Returns:
QuerySet of services within the date range
"""
return cls.filter_by_date_range(start_date, end_date)
@classmethod
def get_upcoming(cls) -> QuerySet[Service]:
"""
Get upcoming services.
Returns:
QuerySet of upcoming services
"""
return Service.objects.filter(date__gte=timezone.now().date())
@classmethod
def get_past_due(cls) -> QuerySet[Service]:
"""
Get past due services.
Returns:
QuerySet of past due services
"""
return Service.objects.filter(
date__lt=timezone.now().date(),
status__in=['scheduled', 'in_progress']
)
@classmethod
def get_for_today(cls) -> QuerySet[Service]:
"""
Get services scheduled for today.
Returns:
QuerySet of services scheduled for today
"""
return Service.objects.filter(date=timezone.now().date())
@classmethod
def search(cls, search_term: str, search_fields: List[str] = None) -> QuerySet[Service]:
"""
Search services by account or notes.
Args:
search_term: The search term
search_fields: Optional list of fields to search (ignored, using predefined fields)
Returns:
QuerySet of matching services
"""
return super().search(
search_term,
['account__name', 'notes']
)
@classmethod
def filter_services(
cls,
account_id: str = None,
status: str = None,
date_from: date = None,
date_to: date = None,
team_member_id: str = None
) -> QuerySet[Service]:
"""
Filter services by multiple criteria.
Args:
account_id: Filter by account ID
status: Filter by status
date_from: Filter by start date (inclusive)
date_to: Filter by end date (inclusive)
team_member_id: Filter by team member ID
Returns:
QuerySet of matching services
"""
queryset = Service.objects.all()
if account_id:
queryset = queryset.filter(account_id=account_id)
if status:
queryset = queryset.filter(status=status)
if date_from:
queryset = queryset.filter(date__gte=date_from)
if date_to:
queryset = queryset.filter(date__lte=date_to)
if team_member_id:
queryset = queryset.filter(team_members__id=team_member_id)
return queryset
@classmethod
def create_with_team_members(cls, data: Dict[str, Any], team_member_ids: List[str]) -> Service:
"""
Create a service with team members.
Args:
data: Service data
team_member_ids: List of team member IDs
Returns:
The created service
"""
# Create the service
service = cls.create(data)
# Add team members
if team_member_ids:
team_members = Profile.objects.filter(id__in=team_member_ids)
service.team_members.set(team_members)
return service
@classmethod
def update_status(cls, service_id: str, status: str) -> Optional[Service]:
"""
Update service status.
Args:
service_id: The service ID
status: The new status
Returns:
The updated service or None if not found
"""
service = cls.get_by_id(service_id)
if not service:
return None
service.status = status
# Set completed_at if status is 'completed'
if status == 'completed' and not service.completed_at:
service.completed_at = timezone.now()
service.save()
return service
@classmethod
def assign_team_members(cls, service_id: str, team_member_ids: List[str]) -> Optional[Service]:
"""
Assign team members to a service.
Args:
service_id: The service ID
team_member_ids: List of team member IDs
Returns:
The updated service or None if not found
"""
service = cls.get_by_id(service_id)
if not service:
return None
team_members = Profile.objects.filter(id__in=team_member_ids)
service.team_members.set(team_members)
return service