from django.conf import settings from django.db import models from django.utils import timezone from core.models.base import BaseModel class ReportExportJob(BaseModel): class ExportType(models.TextChoices): EXCEL = "excel", "Excel" PDF = "pdf", "PDF" class Status(models.TextChoices): PENDING = "pending", "Pending" PROCESSING = "processing", "Processing" COMPLETED = "completed", "Completed" FAILED = "failed", "Failed" EXPIRED = "expired", "Expired" requesting_user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="report_export_jobs", ) workspace = models.ForeignKey( "workspaces.Workspace", on_delete=models.CASCADE, related_name="report_export_jobs", ) export_type = models.CharField(max_length=16, choices=ExportType.choices) status = models.CharField( max_length=16, choices=Status.choices, default=Status.PENDING, ) filters = models.JSONField(default=dict) file = models.FileField(upload_to="reports/exports/", blank=True, null=True) file_name = models.CharField(max_length=255, blank=True) error_message = models.TextField(blank=True) expires_at = models.DateTimeField(null=True, blank=True) completed_at = models.DateTimeField(null=True, blank=True) class Meta: db_table = "report_export_job" ordering = ("-created_at",) indexes = [ models.Index(fields=["requesting_user"], name="report_export_user_idx"), models.Index(fields=["workspace"], name="report_export_workspace_idx"), models.Index(fields=["status"], name="report_export_status_idx"), models.Index(fields=["expires_at"], name="report_export_expires_idx"), ] def mark_processing(self): self.status = self.Status.PROCESSING self.error_message = "" self.save(update_fields=["status", "error_message", "updated_at"]) def mark_completed(self, *, file_name: str): self.status = self.Status.COMPLETED self.file_name = file_name self.completed_at = timezone.now() self.expires_at = self.completed_at + timezone.timedelta(days=7) self.error_message = "" self.save( update_fields=[ "status", "file_name", "completed_at", "expires_at", "error_message", "updated_at", ] ) def mark_failed(self, message: str): self.status = self.Status.FAILED self.error_message = message[:2000] self.save(update_fields=["status", "error_message", "updated_at"]) def mark_expired(self): self.status = self.Status.EXPIRED self.save(update_fields=["status", "updated_at"])