""" Repository for Schedule model operations. """ from datetime import datetime, date, timedelta from typing import Optional, List from django.db.models import QuerySet, Q from django.utils import timezone from backend.core.models import Schedule, Service from backend.core.repositories.base import BaseRepository class ScheduleRepository(BaseRepository[Schedule]): """ Repository for Schedule model operations. """ model = Schedule @classmethod def get_by_account(cls, account_id: str) -> QuerySet[Schedule]: """ Get schedules.py by account. Args: account_id: The account ID Returns: QuerySet of schedules.py for the account """ return Schedule.objects.filter(account_id=account_id) @classmethod def get_active(cls) -> QuerySet[Schedule]: """ Get active schedules.py. Returns: QuerySet of active schedules.py """ current_date = timezone.now().date() return Schedule.objects.filter( start_date__lte=current_date ).filter( Q(end_date__isnull=True) | Q(end_date__gte=current_date) # Use Q directly ) @classmethod def get_active_by_account(cls, account_id: str) -> Optional[Schedule]: """ Get active schedule for an account. Args: account_id: The account ID Returns: Active schedule for the account or None if not found """ current_date = timezone.now().date() return Schedule.objects.filter( account_id=account_id, start_date__lte=current_date ).filter( Q(end_date__isnull=True) | Q(end_date__gte=current_date) # Use Q directly ).first() @classmethod def search(cls, search_term: str, search_fields: List[str] = None) -> QuerySet[Schedule]: """ Search schedules Args: search_term: The search term search_fields: Optional list of fields to search (ignored, using predefined fields) Returns: QuerySet of matching schedules """ return super().search( search_term, [ 'account__name', 'account__customer__name' ] ) @classmethod def generate_services(cls, schedule_id: str, start_date: date, end_date: date) -> List[Service]: """ Generate services based on a schedule for a date range. Args: schedule_id: The schedule ID start_date: Start date (inclusive) end_date: End date (inclusive) Returns: List of generated services """ schedule = cls.get_by_id(schedule_id) if not schedule: return [] days_map = { 0: schedule.monday_service, # Monday is 0 1: schedule.tuesday_service, # Tuesday is 1 2: schedule.wednesday_service, # Wednesday is 2 3: schedule.thursday_service, # Thursday is 3 4: schedule.friday_service, # Friday is 4 5: schedule.saturday_service, # Saturday is 5 6: schedule.sunday_service # Sunday is 6 } services = [] current_date = start_date # Iterate through each day in the date range while current_date <= end_date: weekday = current_date.weekday() # Check if service is scheduled for this day if days_map[weekday] or (schedule.weekend_service and weekday >= 5): # Create a service service_data = { 'account': schedule.account, # Use the account object directly 'date': current_date, 'status': 'scheduled', 'deadline_start': datetime.combine( current_date, datetime.min.time() ).replace(hour=9), # Default to 9:00 AM 'deadline_end': datetime.combine( current_date, datetime.min.time() ).replace(hour=17) # Default to 5:00 PM } service = Service.objects.create(**service_data) services.append(service) current_date += timedelta(days=1) return services @classmethod def get_inactive(cls) -> QuerySet[Schedule]: """ Get inactive schedules. Returns: QuerySet of inactive schedules """ current_date = timezone.now().date() return Schedule.objects.filter(end_date__lt=current_date) @classmethod def get_by_date_range(cls, start_date: date = None, end_date: date = None) -> QuerySet[Schedule]: """ Get schedules within a date range. Args: start_date: Start date (inclusive) end_date: End date (inclusive) Returns: QuerySet of schedules within the date range """ queryset = Schedule.objects.all() if start_date: queryset = queryset.filter(start_date__gte=start_date) if end_date: queryset = queryset.filter(end_date__lte=end_date) return queryset