Source code for ferrosoft.apps.reporting.models

import pickle

from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _

from ferrosoft.apps.ferrobase.models import UUIDModel, StoredFile
from ferrosoft.importutils import import_object


[docs] class ReportStatus(models.IntegerChoices): NEW = 1, _("New") CREATED = 2, _("Created") FAILED = 3, _("Failed")
[docs] class ReportManager(models.Manager):
[docs] def get_queryset(self): return super().get_queryset().select_related("document__owner")
[docs] class Report(UUIDModel): class Meta: verbose_name = _("Report") verbose_name_plural = _("Reports") objects = ReportManager() creation_time = models.DateTimeField( verbose_name=_("Creation Time"), auto_now_add=True, ) status = models.IntegerField( verbose_name=_("Status"), choices=ReportStatus.choices, default=ReportStatus.NEW, ) document = models.ForeignKey( StoredFile, on_delete=models.CASCADE, related_name="+", verbose_name=_("File"), ) func_name = models.CharField( verbose_name=_("Function Name"), ) func_args = models.BinaryField( verbose_name=_("Function Arguments"), ) func_kwargs = models.BinaryField( verbose_name=_("Function Keyword Arguments"), ) return_url = models.URLField( verbose_name=_("Return URL"), null=True, )
[docs] def get_absolute_url(self): return reverse("reporting:generator", args=[self.pk])
[docs] def generate_document(self) -> bytes: func = import_object(self.func_name) args = pickle.loads(self.func_args) kwargs = pickle.loads(self.func_kwargs) if func is None: raise RuntimeError("Function not found: %s" % self.func_name) pdf_blob = func(*args, report=self, **kwargs) if not isinstance(pdf_blob, bytes): raise RuntimeError("Function must return PDF bytes object") return pdf_blob