Source code for ferrosoft.apps.ticketing.models

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

from ferrosoft.apps.ferrobase.models import LocalUser, CommonLimit, UUIDModel
from ferrosoft.apps.ticketing.api.service import generate_comment_hash


[docs] class TicketType(models.TextChoices): BUG = "B", _("Bug") SUPPORT = "S", _("Support") FEATURE_REQUEST = "F", _("Feature Request")
[docs] class TicketPriority(models.TextChoices): NORMAL = "N", _("Normal") High = "H", _("High")
[docs] class Settings(UUIDModel): name = models.CharField( max_length=100, default="Ticketing Settings", unique=True, editable=False, verbose_name=_("Settings Name"), )
[docs] @classmethod def get_instance(cls): instance = cls.objects.first() or cls.objects.create() return instance
[docs] def get_ticket_type_options(self, ticket_type: str) -> "TicketTypeProjectOption": return self.ticket_type_projects.filter(ticket_type=ticket_type).first()
def __str__(self): return self.name
[docs] class TaigaProject(UUIDModel): name = models.CharField( max_length=255, verbose_name=_("Project Name"), ) project_id = models.PositiveIntegerField( unique=True, verbose_name=_("Project ID"), ) types = models.JSONField( default=dict, verbose_name=_("Ticket Types"), ) priorities = models.JSONField( default=dict, verbose_name=_("Ticket Priorities"), )
[docs] def get_type_id(self, ticket_type_label: str) -> int: return self.types.get(ticket_type_label)
[docs] def get_priority_id(self, priority_label: str) -> int: return self.priorities.get(priority_label)
def __str__(self): return self.name
[docs] class TicketTypeProjectOption(UUIDModel): settings = models.ForeignKey( Settings, on_delete=models.CASCADE, related_name="ticket_type_projects", verbose_name=_("Settings"), ) ticket_type = models.CharField( max_length=1, choices=TicketType.choices, verbose_name=_("Ticket Type"), ) project = models.ForeignKey( TaigaProject, on_delete=models.CASCADE, related_name="ticket_type_options", verbose_name=_("Project"), ) class Meta: constraints = [ models.UniqueConstraint( fields=["settings", "ticket_type"], name="unique_settings_ticket_type", ) ]
[docs] @classmethod def create_association(cls, project_id: str, ticket_type: TicketType): cls.objects.get_or_create( settings=Settings.get_instance(), ticket_type=ticket_type, project=TaigaProject.objects.get(project_id=project_id), )
[docs] @classmethod def delete_association(cls, project_id: str, ticket_type: TicketType): try: cls.objects.get( settings=Settings.get_instance(), ticket_type=ticket_type, project__project_id=project_id, ).delete() except cls.DoesNotExist: return
[docs] class Ticket(UUIDModel):
[docs] def attachment_upload_path(instance, filename): return f"ticket/{instance.reference}/{filename}"
reference = models.CharField( max_length=int(CommonLimit.TINY_CHAR), verbose_name=_("Ticket ID"), ) created_by = models.ForeignKey( LocalUser, on_delete=models.CASCADE, related_name="created_by", verbose_name=_("Created by"), ) foreign_id = models.CharField( max_length=100, unique=True, null=True, default=None, verbose_name=_("Foreign ID"), ) title = models.CharField( max_length=int(CommonLimit.NORMAL_CHAR), verbose_name=_("Title"), ) description = models.TextField( verbose_name=_("Description"), ) created_at = models.DateTimeField( auto_now_add=True, verbose_name=_("Created at"), ) type = models.CharField( max_length=1, choices=TicketType.choices, verbose_name=_("Type"), default=TicketType.BUG, ) priority = models.CharField( max_length=1, choices=TicketPriority.choices, verbose_name=_("Priority"), default=TicketPriority.NORMAL, ) attachment = models.FileField( verbose_name=_("Attachment"), upload_to=attachment_upload_path, null=True, )
[docs] def get_absolute_url(self) -> str: return reverse("ticketing:ticket_detail", kwargs={"pk": str(self.pk)})
[docs] class Comment(UUIDModel): ticket = models.ForeignKey( Ticket, on_delete=models.CASCADE, related_name="comments", verbose_name=_("Ticket"), ) content = models.TextField( verbose_name=_("Comment"), ) created_at = models.DateTimeField( auto_now_add=True, verbose_name=_("Created at"), ) created_by = models.CharField( max_length=int(CommonLimit.TINY_CHAR), verbose_name=_("Created by"), ) class Meta: ordering = ["created_at"]
[docs] def save(self, *args, **kwargs): super().save(*args, **kwargs) cache.set( key=generate_comment_hash(self.content), value=self.id, timeout=None, )