220 lines
5.9 KiB
Python
220 lines
5.9 KiB
Python
"""
|
|
Repository for Account model operations.
|
|
"""
|
|
from typing import Optional
|
|
from django.db.models import Q, Prefetch
|
|
from django.utils import timezone
|
|
from backend.core.models import Account, Service
|
|
from backend.core.repositories.base import BaseRepository
|
|
|
|
|
|
class AccountRepository(BaseRepository[Account]):
|
|
"""
|
|
Repository for Account model operations.
|
|
"""
|
|
model = Account
|
|
|
|
@classmethod
|
|
def get_by_customer(cls, customer_id: str):
|
|
"""
|
|
Get accounts by customer.
|
|
|
|
Args:
|
|
customer_id: The customer ID
|
|
|
|
Returns:
|
|
QuerySet of accounts for the customer
|
|
"""
|
|
return Account.objects.filter(customer_id=customer_id)
|
|
|
|
@classmethod
|
|
def get_active(cls):
|
|
"""
|
|
Get all active accounts.
|
|
|
|
Returns:
|
|
QuerySet of active accounts
|
|
"""
|
|
return Account.objects.filter(
|
|
Q(end_date__isnull=True) | Q(end_date__gt=timezone.now().date())
|
|
)
|
|
|
|
@classmethod
|
|
def get_active_by_customer(cls, customer_id: str):
|
|
"""
|
|
Get active accounts by customer.
|
|
|
|
Args:
|
|
customer_id: The customer ID
|
|
|
|
Returns:
|
|
QuerySet of active accounts for the customer
|
|
"""
|
|
return Account.objects.filter(
|
|
customer_id=customer_id
|
|
).filter(
|
|
Q(end_date__isnull=True) | Q(end_date__gt=timezone.now().date())
|
|
)
|
|
|
|
@classmethod
|
|
def get_inactive(cls):
|
|
"""
|
|
Get all inactive accounts.
|
|
|
|
Returns:
|
|
QuerySet of inactive accounts
|
|
"""
|
|
return Account.objects.filter(
|
|
end_date__isnull=False,
|
|
end_date__lte=timezone.now().date()
|
|
)
|
|
|
|
@classmethod
|
|
def mark_inactive(cls, id: str) -> Optional[Account]:
|
|
"""
|
|
Mark an account as inactive.
|
|
|
|
Args:
|
|
id: The account ID
|
|
|
|
Returns:
|
|
The updated account or None if not found
|
|
"""
|
|
return cls.update(id, {'end_date': timezone.now().date()})
|
|
|
|
@classmethod
|
|
def search(cls, search_term: str, include_inactive: bool = False):
|
|
"""
|
|
Search accounts by name or contact info.
|
|
|
|
Args:
|
|
search_term: The search term
|
|
include_inactive: Whether to include inactive accounts
|
|
|
|
Returns:
|
|
QuerySet of matching accounts
|
|
"""
|
|
queryset = super().search(
|
|
search_term,
|
|
[
|
|
'name',
|
|
'primary_contact_first_name',
|
|
'primary_contact_last_name',
|
|
'primary_contact_email',
|
|
'secondary_contact_first_name',
|
|
'secondary_contact_last_name',
|
|
'secondary_contact_email',
|
|
'customer__name'
|
|
]
|
|
)
|
|
|
|
if not include_inactive:
|
|
queryset = queryset.filter(
|
|
Q(end_date__isnull=True) | Q(end_date__gt=timezone.now().date())
|
|
)
|
|
|
|
return queryset
|
|
|
|
@classmethod
|
|
def get_with_services(cls, id: str, upcoming_only: bool = False) -> Optional[Account]:
|
|
"""
|
|
Get an account with prefetched services.
|
|
|
|
Args:
|
|
id: The account ID
|
|
upcoming_only: Whether to include only upcoming services
|
|
|
|
Returns:
|
|
The account with services or None if not found
|
|
"""
|
|
services_queryset = Service.objects.all()
|
|
|
|
if upcoming_only:
|
|
services_queryset = services_queryset.filter(date__gte=timezone.now().date())
|
|
|
|
services_prefetch = Prefetch('services', queryset=services_queryset)
|
|
|
|
try:
|
|
return Account.objects.prefetch_related(services_prefetch).get(pk=id)
|
|
except Account.DoesNotExist:
|
|
return None
|
|
|
|
@classmethod
|
|
def get_with_revenues(cls, id: str) -> Optional[Account]:
|
|
"""
|
|
Get an account with prefetched revenues.
|
|
|
|
Args:
|
|
id: The account ID
|
|
|
|
Returns:
|
|
The account with revenues or None if not found
|
|
"""
|
|
try:
|
|
return Account.objects.prefetch_related('revenues').get(pk=id)
|
|
except Account.DoesNotExist:
|
|
return None
|
|
|
|
@classmethod
|
|
def get_with_labors(cls, id: str) -> Optional[Account]:
|
|
"""
|
|
Get an account with prefetched labors.
|
|
|
|
Args:
|
|
id: The account ID
|
|
|
|
Returns:
|
|
The account with labors or None if not found
|
|
"""
|
|
try:
|
|
return Account.objects.prefetch_related('labors').get(pk=id)
|
|
except Account.DoesNotExist:
|
|
return None
|
|
|
|
@classmethod
|
|
def get_with_schedules(cls, id: str) -> Optional[Account]:
|
|
"""
|
|
Get an account with prefetched schedules
|
|
|
|
Args:
|
|
id: The account ID
|
|
|
|
Returns:
|
|
The account with schedules or None if not found
|
|
"""
|
|
try:
|
|
return Account.objects.prefetch_related('schedules').get(pk=id)
|
|
except Account.DoesNotExist:
|
|
return None
|
|
|
|
@classmethod
|
|
def get_with_projects(cls, id: str) -> Optional[Account]:
|
|
"""
|
|
Get an account with prefetched projects.
|
|
Args:
|
|
id: The account ID
|
|
Returns:
|
|
The account with projects or None if not found
|
|
"""
|
|
try:
|
|
return Account.objects.prefetch_related('projects').get(pk=id)
|
|
except Account.DoesNotExist:
|
|
return None
|
|
|
|
@classmethod
|
|
def get_with_all_related(cls, id: str) -> Optional[Account]:
|
|
"""
|
|
Get an account with all related data prefetched.
|
|
|
|
Args:
|
|
id: The account ID
|
|
|
|
Returns:
|
|
The account with all related data or None if not found
|
|
"""
|
|
try:
|
|
return Account.objects.prefetch_related(
|
|
'services', 'revenues', 'labors', 'schedules.py', 'projects'
|
|
).select_related('customer').get(pk=id)
|
|
except Account.DoesNotExist:
|
|
return None |