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 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_plural = "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)) class CloudProvider(models.Model): name = models.CharField(max_length=100) slug = models.SlugField(unique=True) description = ProseEditorField(blank=True) logo = models.ImageField( upload_to="cloud_provider_logos/", validators=[validate_image_size], null=True, blank=True, ) def __str__(self): return self.name def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) super().save(*args, **kwargs) def get_absolute_url(self): return reverse("services:provider_detail", kwargs={"slug": self.slug}) class Country(models.Model): name = models.CharField(max_length=100) code = models.CharField(max_length=2) class Meta: verbose_name_plural = "Countries" def __str__(self): return self.name class ServiceLevel(models.Model): name = models.CharField(max_length=100) description = models.TextField() response_time = models.CharField(max_length=50) def __str__(self): return self.name class Service(models.Model): name = models.CharField(max_length=200) description = ProseEditorField() cloud_provider = models.ForeignKey(CloudProvider, on_delete=models.CASCADE) service_level = models.ForeignKey(ServiceLevel, on_delete=models.CASCADE) categories = models.ManyToManyField(Category, related_name="services") countries = models.ManyToManyField(Country) price = models.DecimalField(max_digits=10, decimal_places=2) features = ProseEditorField() logo = models.ImageField( upload_to="service_logos/", validators=[validate_image_size], null=True, blank=True, ) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Lead(models.Model): service = models.ForeignKey(Service, on_delete=models.CASCADE) name = models.CharField(max_length=200) company = models.CharField(max_length=200) email = models.EmailField() phone = models.CharField(max_length=50) created_at = models.DateTimeField(auto_now_add=True) odoo_lead_id = models.IntegerField(null=True, blank=True) def __str__(self): return f"{self.name} - {self.company} ({self.service})"