mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 18:31:09 -05:00
- Update pghistory dependency from 0007 to 0006 in account migrations - Add docstrings and remove unused imports in htmx_forms.py - Add DJANGO_SETTINGS_MODULE bash commands to Claude settings - Add state transition definitions for ride statuses
124 lines
3.5 KiB
Python
124 lines
3.5 KiB
Python
"""
|
|
Celery tasks for rides app.
|
|
|
|
This module contains background tasks for ride management including:
|
|
- Automatic status transitions for closing rides
|
|
"""
|
|
|
|
import logging
|
|
|
|
from celery import shared_task
|
|
from django.contrib.auth import get_user_model
|
|
from django.db import transaction
|
|
from django.utils import timezone
|
|
|
|
logger = logging.getLogger(__name__)
|
|
User = get_user_model()
|
|
|
|
|
|
@shared_task(name="rides.check_overdue_closings")
|
|
def check_overdue_closings() -> dict:
|
|
"""
|
|
Check for rides in CLOSING status that have reached their closing_date
|
|
and automatically transition them to their post_closing_status.
|
|
|
|
This task should be run daily via Celery Beat.
|
|
|
|
Returns:
|
|
dict: Summary with counts of processed, succeeded, and failed rides
|
|
"""
|
|
from apps.rides.models import Ride
|
|
|
|
logger.info("Starting overdue closings check")
|
|
|
|
# Get or create system user for automated transitions
|
|
system_user = _get_system_user()
|
|
|
|
# Query rides that need transition
|
|
today = timezone.now().date()
|
|
overdue_rides = Ride.objects.filter(
|
|
status="CLOSING", closing_date__lte=today
|
|
).select_for_update()
|
|
|
|
processed = 0
|
|
succeeded = 0
|
|
failed = 0
|
|
failures = []
|
|
|
|
for ride in overdue_rides:
|
|
processed += 1
|
|
try:
|
|
with transaction.atomic():
|
|
ride.apply_post_closing_status(user=system_user)
|
|
succeeded += 1
|
|
logger.info(
|
|
"Successfully transitioned ride %s (%s) from CLOSING to %s",
|
|
ride.id,
|
|
ride.name,
|
|
ride.status,
|
|
)
|
|
except Exception as e:
|
|
failed += 1
|
|
error_msg = f"Ride {ride.id} ({ride.name}): {str(e)}"
|
|
failures.append(error_msg)
|
|
logger.error(
|
|
"Failed to transition ride %s (%s): %s",
|
|
ride.id,
|
|
ride.name,
|
|
str(e),
|
|
exc_info=True,
|
|
)
|
|
|
|
result = {
|
|
"processed": processed,
|
|
"succeeded": succeeded,
|
|
"failed": failed,
|
|
"failures": failures,
|
|
"date": today.isoformat(),
|
|
}
|
|
|
|
logger.info(
|
|
"Completed overdue closings check: %s processed, %s succeeded, %s failed",
|
|
processed,
|
|
succeeded,
|
|
failed,
|
|
)
|
|
|
|
return result
|
|
|
|
|
|
def _get_system_user():
|
|
"""
|
|
Get or create a system user for automated transitions.
|
|
|
|
Returns:
|
|
User: System user instance
|
|
"""
|
|
try:
|
|
# Try to get existing system user
|
|
system_user = User.objects.get(username="system")
|
|
except User.DoesNotExist:
|
|
# Create system user if it doesn't exist
|
|
try:
|
|
system_user = User.objects.create_user(
|
|
username="system",
|
|
email="system@thrillwiki.com",
|
|
is_active=False,
|
|
is_staff=False,
|
|
)
|
|
logger.info("Created system user for automated tasks")
|
|
except Exception as e:
|
|
# If creation fails, try to get moderator or admin user
|
|
logger.warning(
|
|
"Failed to create system user, falling back to moderator: %s", str(e)
|
|
)
|
|
try:
|
|
system_user = User.objects.filter(is_staff=True).first()
|
|
if not system_user:
|
|
# Last resort: use any user
|
|
system_user = User.objects.first()
|
|
except Exception:
|
|
system_user = None
|
|
|
|
return system_user
|