from django.db import models from django.db.models import Max, Value from django.db.models.functions import Coalesce from django.utils.translation import gettext_lazy as _ import uuid from encrypted_model_fields.fields import EncryptedCharField # Create your models here. class Questionnaire(models.Model): class Meta: verbose_name = _('Questionnaire') verbose_name_plural = _('Questionnaires') ordering = ['name'] id = models.UUIDField(_('ID'), default=uuid.uuid4, editable=False, unique=True, primary_key=True) name = models.CharField(_('Name'), max_length=200, help_text=_('Name of the questionnaire.')) description = models.TextField(_('Description'), blank=True, null=True, help_text=_('Enter a short description for this questionnaire.')) created_at = models.DateTimeField(_('Date created'), auto_now_add=True, help_text=_('The date and time this questionnaire has been created')) updated_at = models.DateTimeField(_('Date updated'), auto_now=True, help_text=_('The date and time this questionnaire has been updated')) @property def allQuestions(self): return QuestionnaireQuestion.objects.filter(topic__questionnaire=self.id) def __str__(self): """str: Returns a readable string.""" return f'{self.name}' class QuestionnaireTopic(models.Model): class Meta: verbose_name = _('Questionnaire topic') verbose_name_plural = _('Questionnaire topics') ordering = ['name'] id = models.UUIDField(_('ID'), default=uuid.uuid4, editable=False, unique=True, primary_key=True) name = models.CharField(_('Name'), max_length=200, help_text=_('Name of the questionnaire topic.')) questionnaire = models.ForeignKey(Questionnaire, verbose_name=Questionnaire._meta.verbose_name, on_delete=models.CASCADE, help_text=_('The questionnaire topic for this questionnaire.'), related_name='topics') description = models.TextField(_('Description'), blank=True, null=True, help_text=_('Enter a short description for this questionnaire topic.')) order = models.PositiveIntegerField(_('Order'), blank=True) created_at = models.DateTimeField(_('Date created'), auto_now_add=True, help_text=_('The date and time this questionnaire topic has been created')) updated_at = models.DateTimeField(_('Date updated'), auto_now=True, help_text=_('The date and time this questionnaire topic has been updated')) def save(self, *args, **kwargs): if self.order is None: self.order = QuestionnaireTopic.objects.filter(questionnaire=self.questionnaire).aggregate(neworder=Coalesce(Max('order'), Value(0)))['neworder'] + 1 super().save(*args, **kwargs) def __str__(self): """str: Returns a readable string.""" return f'{self.name}' class QuestionnaireQuestionTypes(models.TextChoices): DATE = ('DATE', _('Date field')) NUMBER = ('NUMBER', _('Number field')) MULTIPLE = ('MULTIPLE', _('Multi options field')) SINGLE = ('SINGLE', _('Single option field')) TEXT = ('TEXT', _('Single text line')) class QuestionnaireQuestion(models.Model): class Meta: verbose_name = _('Questionnaire question') verbose_name_plural = _('Questionnaire questions') ordering = ['name'] id = models.UUIDField(_('ID'), default=uuid.uuid4, editable=False, unique=True, primary_key=True) name = models.CharField(_('Name'), max_length=200, help_text=_('Name of the questionnaire topic.')) type = models.CharField(_('Type'), max_length=15, choices=QuestionnaireQuestionTypes.choices, default=QuestionnaireQuestionTypes.SINGLE, help_text=_('Question type')) description = models.TextField(_('Description'), blank=True, null=True, help_text=_('Enter a short description for this questionnaire topic.')) order = models.PositiveIntegerField(_('Order'), blank=True,) choices = models.TextField(_('Choices'), blank=True, null=True, help_text=_('Enter the choices 1 per line.
Use a format like \'= [Text]\' for an \'anders\' option.
Use format \'[Text]=[Value]\' for different value for each choice ')) topic = models.ForeignKey(QuestionnaireTopic, verbose_name=QuestionnaireTopic._meta.verbose_name, on_delete=models.CASCADE, help_text=_('The questionnaire topic for this questionnaire.'), related_name='questions') created_at = models.DateTimeField(_('Date created'), auto_now_add=True, help_text=_('The date and time this questionnaire topic has been created')) updated_at = models.DateTimeField(_('Date updated'), auto_now=True, help_text=_('The date and time this questionnaire topic has been updated')) def save(self, *args, **kwargs): if self.order is None: self.order = QuestionnaireQuestion.objects.filter(topic__questionnaire=self.topic.questionnaire).aggregate(neworder=Coalesce(Max('order'), Value(0)))['neworder'] + 1 super().save(*args, **kwargs) def choices_list(self): return [choice.strip() for choice in self.choices.strip("\n").split('\n')] def __str__(self): """str: Returns a readable string.""" return f'{self.name}' class QuestionnaireResponse(models.Model): class Meta: verbose_name = _('Questionnaire response') verbose_name_plural = _('Questionnaire responses') ordering = ['-created_at'] id = models.UUIDField(_('ID'), default=uuid.uuid4, editable=False, unique=True, primary_key=True) questionnaire = models.ForeignKey(Questionnaire, verbose_name=Questionnaire._meta.verbose_name, on_delete=models.CASCADE, help_text=_('The questionnaire for this response.')) response = models.TextField(_('Response'), help_text=_('Questionaire response in CSV')) created_at = models.DateTimeField(_('Date created'), auto_now_add=True, help_text=_('The date and time this questionnaire response has been created')) updated_at = models.DateTimeField(_('Date updated'), auto_now=True, help_text=_('The date and time this questionnaire response has been updated')) class QuestionnaireStorageTypes(models.TextChoices): WEBDAV = ('WEBDAV', _('WebDAV')) class QuestionnaireStorage(models.Model): class Meta: verbose_name = _('Questionnaire storage') verbose_name_plural = _('Questionnaire storages') ordering = ['name'] id = models.UUIDField(_('ID'), default=uuid.uuid4, editable=False, unique=True, primary_key=True) name = models.CharField(_('Name'), max_length=200, help_text=_('Name of the questionnaire storage')) type = models.CharField(_('Type'), max_length=15, choices=QuestionnaireStorageTypes.choices, default=QuestionnaireStorageTypes.WEBDAV, help_text=_('Storage type')) server = models.CharField(_('Server'), max_length=200, help_text=_('Server url')) username = EncryptedCharField(_('Username'), max_length=200, help_text=_('Username')) password = EncryptedCharField(_('Password'), max_length=200, help_text=_('Password')) path = models.CharField(_('Path'), max_length=200, help_text=_('Location on disk')) created_at = models.DateTimeField(_('Date created'), auto_now_add=True, help_text=_('The date and time this questionnaire storage has been created')) updated_at = models.DateTimeField(_('Date updated'), auto_now=True, help_text=_('The date and time this questionnaire storage has been updated'))