from django.db import models from django.core.exceptions import ValidationError from django.utils.text import slugify from django_prose_editor.fields import ProseEditorField def validate_image_size(value): filesize = value.size if filesize > 1 * 1024 * 1024: # 1MB raise ValidationError("Maximum file size is 1MB") class Currency(models.TextChoices): CHF = "CHF", "Swiss Franc" EUR = "EUR", "Euro" USD = "USD", "US Dollar" class Term(models.TextChoices): MTH = "MTH", "per Month (30d)" DAY = "DAY", "per Day" HR = "HR", "per Hour" MIN = "MIN", "per Minute" class Unit(models.TextChoices): GIB = "GIB", "GiB" MIB = "MIB", "MiB" CPU = "CPU", "vCPU" # This should be a relation, but for now this is good enough :TM: class ManagedServiceProvider(models.TextChoices): VS = "VS", "VSHN" class ReusableText(models.Model): name = models.CharField(max_length=100) textsnippet = models.ForeignKey( "self", on_delete=models.SET_NULL, null=True, blank=True, related_name="children", ) text = ProseEditorField() class Meta: ordering = ["name"] def __str__(self): return self.name def get_full_text(self): """Returns the text with all nested textsnippet content recursively included in reverse order""" text_parts = [] # Recursively collect all text parts def collect_text(snippet): if snippet is None: return collect_text(snippet.textsnippet) # Collect deepest snippets first text_parts.append(snippet.text) # Start collection with the deepest snippets collect_text(self.textsnippet) # Add the main text at the end text_parts.append(self.text) # Join all text parts return "".join(text_parts) class Category(models.Model): name = models.CharField(max_length=100) slug = models.SlugField(unique=True) parent = models.ForeignKey( "self", on_delete=models.CASCADE, null=True, blank=True, related_name="children" ) description = models.TextField(blank=True) order = models.IntegerField(default=0) class Meta: verbose_name = "Service Category" verbose_name_plural = "Service Categories" ordering = ["order", "name"] def __str__(self): if self.parent: return f"{self.parent} > {self.name}" return self.name def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) super().save(*args, **kwargs) @property def full_path(self): path = [self.name] parent = self.parent while parent: path.append(parent.name) parent = parent.parent return " > ".join(reversed(path))