97 lines
4.4 KiB
Python
97 lines
4.4 KiB
Python
import datetime
|
|
from django.core.exceptions import ValidationError
|
|
from django.db import models
|
|
from django.db.models import Q
|
|
from core.models.base import BaseModel
|
|
from core.models.account import AccountAddress
|
|
|
|
|
|
class Schedule(BaseModel):
|
|
"""
|
|
Service schedules for accounts.
|
|
"""
|
|
name = models.CharField(max_length=255, blank=True, null=True, verbose_name="Name")
|
|
account_address = models.ForeignKey(AccountAddress, on_delete=models.PROTECT, related_name='schedules',
|
|
verbose_name="Account Service Address", null=True)
|
|
monday_service = models.BooleanField(default=False, verbose_name="Monday Service")
|
|
tuesday_service = models.BooleanField(default=False, verbose_name="Tuesday Service")
|
|
wednesday_service = models.BooleanField(default=False, verbose_name="Wednesday Service")
|
|
thursday_service = models.BooleanField(default=False, verbose_name="Thursday Service")
|
|
friday_service = models.BooleanField(default=False, verbose_name="Friday Service")
|
|
saturday_service = models.BooleanField(default=False, verbose_name="Saturday Service")
|
|
sunday_service = models.BooleanField(default=False, verbose_name="Sunday Service")
|
|
weekend_service = models.BooleanField(default=False, verbose_name="Weekend Service",
|
|
help_text=(
|
|
"When enabled, represents a single service visit on Friday that can be performed "
|
|
"any time between Friday-Sunday and verified by Monday morning. "
|
|
"Individual Fri/Sat/Sun service flags must be disabled when this is enabled."))
|
|
schedule_exception = models.TextField(blank=True, null=True, verbose_name="Schedule Exceptions",
|
|
help_text=(
|
|
"Notes about any exceptions or special requirements for this schedule"))
|
|
start_date = models.DateField(verbose_name="Start Date", help_text="Date when this schedule becomes active")
|
|
end_date = models.DateField(blank=True, null=True, verbose_name="End Date",
|
|
help_text="Optional date when this schedule expires")
|
|
|
|
class Meta:
|
|
ordering = ['-start_date']
|
|
verbose_name = "Schedule"
|
|
verbose_name_plural = "Schedules"
|
|
indexes = [
|
|
models.Index(fields=['account_address', 'start_date']),
|
|
models.Index(fields=['weekend_service']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"Schedule for {self.account_address.account.name} - {self.account_address.name if self.account_address.name else 'Primary Service Address'}"
|
|
|
|
def clean(self):
|
|
"""Validate schedule configuration"""
|
|
super().clean()
|
|
|
|
if self.end_date and self.start_date > self.end_date:
|
|
raise ValidationError({
|
|
'end_date': "End date must be after start date"
|
|
})
|
|
|
|
start = self.start_date
|
|
end = self.end_date or datetime.date.max
|
|
|
|
qs = Schedule.objects.filter(account_address=self.account_address)
|
|
if self.pk:
|
|
qs = qs.exclude(pk=self.pk)
|
|
|
|
overlaps = qs.filter(
|
|
Q(end_date__isnull=True, start_date__lte=end) |
|
|
Q(end_date__isnull=False, start_date__lte=end, end_date__gte=start)
|
|
)
|
|
|
|
if overlaps.exists():
|
|
raise ValidationError("Schedule dates overlap with an existing schedule for this address.")
|
|
|
|
# Validate weekend service configuration
|
|
if self.weekend_service:
|
|
weekend_days = [
|
|
self.friday_service,
|
|
self.saturday_service,
|
|
self.sunday_service
|
|
]
|
|
if any(weekend_days):
|
|
raise ValidationError({
|
|
'weekend_service': "When weekend service is enabled, Friday, Saturday, "
|
|
"and Sunday service flags must be disabled"
|
|
})
|
|
|
|
has_regular_service = any([
|
|
self.monday_service,
|
|
self.tuesday_service,
|
|
self.wednesday_service,
|
|
self.thursday_service,
|
|
self.friday_service,
|
|
self.saturday_service,
|
|
self.sunday_service
|
|
])
|
|
if not has_regular_service and not self.weekend_service:
|
|
raise ValidationError(
|
|
"At least one service day or weekend service must be selected"
|
|
)
|