production-taskbar / backend / helpdesk / models.py
models.py
Raw
from colorfield.fields import ColorField
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
from simple_history.models import HistoricalRecords


class Problem(models.Model):
    name = models.CharField(
        max_length=40,
        unique=True,
        verbose_name=_('name'),
    )
    label = models.CharField(
        max_length=40,
        blank=True,
        verbose_name=_('label'),
    )
    label.help_text = _('If not empty used as name in frontend')
    require_scan = models.BooleanField(
        default=True,
        verbose_name=_('require scan'),
    )
    require_scan.help_text = _('User must scan badge to send ticket')
    add_mao_boards = models.BooleanField(
        default=False,
        verbose_name=_('add mao boards'),
    )
    add_mao_boards.help_text = _('Add information from MAO about boards')
    add_winkhmman_path = models.BooleanField(
        default=False,
        verbose_name=_('add winkhmman path'),
    )
    add_winkhmman_path.help_text = _('Add WinKHMMan.exe path')
    attach_screenshot = models.BooleanField(
        default=False,
        verbose_name=_('Attach screenshot'),
    )
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        verbose_name = _('problem')
        verbose_name_plural = _('problems')

    def __str__(self) -> str:
        return f"{self.name}"


class Category(models.Model):
    name = models.CharField(
        max_length=20,
        verbose_name=_('name'),
    )
    label = models.CharField(
        max_length=20,
        blank=True,
        verbose_name=_('label'),
    )
    label.help_text = _('If not empty used as name in frontend')
    problems = models.ManyToManyField(
        Problem,
        blank=True,
        verbose_name=_('problem'),
    )
    configuration = models.JSONField(
        default=dict,
        blank=True,
        null=True,
        verbose_name=_('configuration'),
    )
    configuration.help_text = _('Configuration information for reciever')
    location = models.ForeignKey(
        "taskbar.Location",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        verbose_name=_('location'),
        help_text=_('For convenience with different configurations'))
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        verbose_name = _('category')
        verbose_name_plural = _('categories')
        unique_together = ('name', 'location')

    def __str__(self) -> str:
        return f'{self.name} ({self.location_id})' if self.location_id else f'{self.name}'    #type: ignore


class CategoriesSet(models.Model):
    name = models.CharField(
        max_length=20,
        unique=True,
        verbose_name=_('name'),
    )
    categories = models.ManyToManyField(
        Category,
        blank=True,
        verbose_name=_('category'),
    )
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        verbose_name = _('category set')
        verbose_name_plural = _('categories set')

    def __str__(self) -> str:
        return f"{self.name}"


class Reciever(models.Model):
    name = models.CharField(max_length=20, unique=True, verbose_name=_('name'))
    configuration = models.JSONField(
        default=dict,
        blank=True,
        null=True,
        verbose_name=_('configuration'),
    )
    configuration.help_text = _('Frontend client configuration')
    backend_configuration = models.JSONField(
        default=dict,
        blank=True,
        null=True,
        verbose_name=_('backend configuration'),
    )
    backend_configuration.help_text = _('Сonfiguration for backend')
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        verbose_name = _('reciever')
        verbose_name_plural = _('recievers')
        unique_together = ('name', )

    def __str__(self) -> str:
        return f"{self.name}"


class Department(models.Model):
    name = models.CharField(max_length=20, verbose_name=_('name'))
    location = models.ForeignKey(
        "taskbar.Location",
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        verbose_name=_('location'),
    )
    categories_set = models.ForeignKey(
        CategoriesSet,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        verbose_name=_('category'),
    )
    contacts = models.TextField(
        max_length=255,
        blank=True,
        verbose_name=_('contacts'),
    )
    reciever = models.ForeignKey(
        Reciever,
        on_delete=models.CASCADE,
        blank=False,
        null=True,
        verbose_name=_('reciever'),
    )
    configuration = models.JSONField(
        default=dict,
        blank=True,
        null=True,
        verbose_name=_('configuration'),
    )
    configuration.help_text = _('Configuration information for reciever')
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        verbose_name = _('department')
        verbose_name_plural = _('departments')
        unique_together = ('name', 'location')

    def __str__(self) -> str:
        return f"{self.location_id}: {self.name}"    #type: ignore


class Status(models.Model):
    name = models.CharField(max_length=20, verbose_name=_('name'))
    label = models.CharField(
        max_length=40,
        blank=True,
        verbose_name=_('label'),
    )
    description = models.TextField(
        max_length=60,
        blank=True,
        verbose_name=_('description'),
    )
    color = ColorField(
        format='hexa',
        verbose_name=_('color'),
    )
    sysaid_code = models.IntegerField(
        blank=True,
        null=True,
        verbose_name=_('sysaid code'),
    )
    sysaid_code.help_text = _('Code for sysaid')
    redmine_code = models.IntegerField(
        blank=True,
        null=True,
        verbose_name=_('redmine code'),
    )
    redmine_code.help_text = _('Code for redmine')
    close_timeout = models.IntegerField(
        blank=True,
        null=True,
        validators=[MaxValueValidator(60),
                    MinValueValidator(2)],
        verbose_name=_('close timeout'),
    )
    close_timeout.help_text = _(
        'Timeout before stop tracking and close overlay')
    history = HistoricalRecords(cascade_delete_history=True)

    class Meta:
        verbose_name = _('status')
        verbose_name_plural = _('statuses')

    def __str__(self) -> str:
        return f"{self.name}"


class Issue(models.Model):
    department = models.ForeignKey(
        Department,
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        verbose_name=_('department'),
    )
    issue_id = models.IntegerField(verbose_name=_('issue id'))
    status = models.ForeignKey(
        Status,
        on_delete=models.CASCADE,
        blank=False,
        null=True,
        verbose_name=_('status'),
    )
    title = models.CharField(max_length=40, verbose_name=_('title'))
    description = models.TextField(verbose_name=_('description'))
    phone = models.CharField(
        blank=True,
        null=True,
        max_length=13,
        verbose_name=_('phone'),
    )
    hostname = models.CharField(max_length=20, verbose_name=_('hostname'))
    user_id = models.IntegerField(verbose_name=_('user id'))
    responsibility = models.CharField(
        max_length=40,
        blank=True,
        null=True,
        verbose_name=_('responsibility'),
    )
    comments = models.TextField(blank=True, verbose_name=_('comments'))
    create_datetime = models.DateTimeField(
        auto_now_add=True,
        verbose_name=_('create datetime'),
    )
    update_datetime = models.DateTimeField(
        null=True,
        verbose_name=_('update datetime'),
    )
    close_datetime = models.DateTimeField(
        null=True,
        verbose_name=_('close datetime'),
    )

    class Meta:
        verbose_name = _('issue')
        verbose_name_plural = _('issues')
        unique_together = ('department', 'issue_id')
        ordering = ["-id"]

    def __str__(self) -> str:
        return f"{self.title} ({self.department_id}-{self.issue_id})"    #type: ignore