from typing import Self from django.db import models from django.contrib.auth import get_user_model from django.db.models.signals import m2m_changed from django.dispatch import receiver from django.utils import timezone from sync.models import BaseModel User = get_user_model() class Status(models.TextChoices): NONE = 'NONE', 'None' CONTACTED = 'CONTACTED', 'Contacted' RESPONDED = 'RESPONDED', 'Responded' SHOULD_TEST = 'SHOULD_TEST', 'Should test' TESTING = 'TESTING', 'Testing' CUSTOMER = 'CUSTOMER', 'Customer' LOST = 'LOST', 'Lost customer' DECLINED_TOO_EXPENSIVE = 'DECLINED_TOO_EXPENSIVE', 'Too expensive' DECLINED_USE_SOMETHING_ELSE = 'DECLINED_USE_SOMETHING_ELSE', 'Use something else' DECLINED_OTHER = 'DECLINED_OTHER', 'Declined other reason' DECLINED_UNRELATED = 'DECLINED_UNRELATED', 'Declined without significance' class ActivityType(models.TextChoices): MAIL = 'MAIL', 'Mailing List' SMS = 'SMS', 'SMS Campaign' CALL = 'CALL', 'Call' PRESS = 'PRESS', 'Press Release' class Entity(BaseModel): name = models.CharField(max_length=200, null=True, blank=True) address = models.CharField(max_length=200, null=True, blank=True) zip_code = models.CharField(max_length=20, null=True, blank=True) city = models.CharField(max_length=500, null=True, blank=True) official_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) # status = models.IntegerField(default=Status.NONE, choices=Status.choices) def delete_dependencies(self): pass class Meta: verbose_name_plural = "Entities" def __str__(self): return self.name class Prospect(BaseModel): first_name = models.CharField(max_length=200, null=True, blank=True) last_name = models.CharField(max_length=200, null=True, blank=True) email = models.EmailField(unique=True) phone = models.CharField(max_length=25, null=True, blank=True) name_unsure = models.BooleanField(default=False) official_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) entities = models.ManyToManyField(Entity, blank=True, related_name='prospects') source = models.CharField(max_length=100, null=True, blank=True) def delete_dependencies(self): pass class Meta: permissions = [ ("manage_prospects", "Can manage prospects"), ("view_prospects", "Can view prospects"), ] def current_status(self): last_activity = self.activities.exclude(status=None).order_by('-creation_date').first() if last_activity: return last_activity.status return None def entity_names(self): entity_names = [entity.name for entity in self.entities.all()] return " - ".join(entity_names) def full_name(self): return f'{self.first_name} {self.last_name}' def __str__(self): return self.full_name() class Activity(BaseModel): status = models.CharField(max_length=50, default=Status.NONE, choices=Status.choices, null=True, blank=True) type = models.CharField(max_length=20, choices=ActivityType.choices, null=True, blank=True) description = models.TextField(null=True, blank=True) attachment_text = models.TextField(null=True, blank=True) prospects = models.ManyToManyField(Prospect, related_name='activities') def __str__(self): if self.status: return self.status elif self.type: return self.type else: return f'desc = {self.description}, attachment_text = {self.attachment_text}' def delete_dependencies(self): pass class Meta: verbose_name_plural = "Activities" ordering = ['-creation_date'] permissions = [ ("manage_events", "Can manage events"), ("view_events", "Can view events"), ] def __str__(self): return f"{self.get_type_display()} - {self.creation_date.date()}" def html_desc(self): fields = [field for field in [self.creation_date.strftime("%d/%m/%Y %H:%M"), self.type, self.status, self.attachment_text, self.description] if field is not None] html = '
| {field} | ' html += '