nexus-5/core/models/labor.py
2026-01-26 11:09:40 -05:00

57 lines
1.9 KiB
Python

from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Q
import datetime
from core.models.base import BaseModel
from core.models.account import AccountAddress
class Labor(BaseModel):
"""Labor records for accounts"""
account_address = models.ForeignKey(
AccountAddress,
on_delete=models.PROTECT,
related_name='labors',
verbose_name="Account Service Address",
null=True
)
amount = models.DecimalField(max_digits=10, decimal_places=2)
start_date = models.DateField()
end_date = models.DateField(blank=True, null=True)
class Meta:
ordering = ['-start_date']
indexes = [
models.Index(fields=['account_address', 'start_date']),
]
verbose_name = "Labor"
verbose_name_plural = "Labors"
def __str__(self):
return f"{self.account_address.account.name} - {self.account_address.name} - ${self.amount}"
def clean(self):
super().clean()
# Basic date validity
if self.end_date and self.start_date > self.end_date:
raise ValidationError({'end_date': "End date must be after start date"})
# Optional: amount validation
if self.amount is None or self.amount < 0:
raise ValidationError({'amount': "Amount must be a non-negative value"})
# Overlap prevention within the same account_address
start = self.start_date
end = self.end_date or datetime.date.max
qs = Labor.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("Labor rate dates overlap with an existing labor rate for this address.")