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 import uuid from sync.models import BaseModel User = get_user_model() class Status(models.TextChoices): NONE = 'NONE', 'None' INBOUND = 'INBOUND', 'Inbound' CONTACTED = 'CONTACTED', 'Contacted' RESPONDED = 'RESPONDED', 'Responded' SHOULD_TEST = 'SHOULD_TEST', 'Should test' TESTING = 'TESTING', 'Testing' CUSTOMER = 'CUSTOMER', 'Customer' LOST = 'LOST', 'Lost customer' DECLINED = 'DECLINED', 'Declined' # DECLINED_UNRELATED = 'DECLINED_UNRELATED', 'Declined without significance' NOT_CONCERNED = 'NOT_CONCERNED', 'Not concerned' SHOULD_BUY = 'SHOULD_BUY', 'Should buy' HAVE_CREATED_ACCOUNT = 'HAVE_CREATED_ACCOUNT', 'Have created account' class DeclinationReason(models.TextChoices): TOO_EXPENSIVE = 'TOO_EXPENSIVE', 'Too expensive' USE_OTHER_PRODUCT = 'USE_OTHER_PRODUCT', 'Use other product' USE_ANDROID = 'USE_ANDROID', 'Use Android' TOO_FEW_TOURNAMENTS = 'TOO_FEW_TOURNAMENTS', 'Too few tournaments' NOT_INTERESTED = 'NOT_INTERESTED', 'Not interested' UNKNOWN = 'UNKNOWN', 'Unknown' class ActivityType(models.TextChoices): MAIL = 'MAIL', 'Mail' SMS = 'SMS', 'SMS' CALL = 'CALL', 'Call' PRESS = 'PRESS', 'Press Release' WORD_OF_MOUTH = 'WORD_OF_MOUTH', 'Word of mouth' WHATS_APP = 'WHATS_APP', 'WhatsApp' class Entity(BaseModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) 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): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) 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, null=True, blank=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) contact_again = models.DateTimeField(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 Status.NONE def current_activity_type(self): last_activity = self.activities.exclude(type=None).order_by('-creation_date').first() if last_activity: return last_activity.type return None def current_text(self): last_activity = self.activities.exclude(status=None).order_by('-creation_date').first() if last_activity: return last_activity.attachment_text return '' def current_declination_reason(self): last_activity = self.activities.exclude(status=None).order_by('-creation_date').first() if last_activity: return last_activity.declination_reason return None def entity_names(self): entity_names = [entity.name for entity in self.entities.all()] return " - ".join(entity_names) def full_name(self): if self.first_name and self.last_name: return f'{self.first_name} {self.last_name}' elif self.first_name: return self.first_name elif self.last_name: return self.last_name else: return 'no name' def __str__(self): return self.full_name() class Activity(BaseModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) status = models.CharField(max_length=50, choices=Status.choices, null=True, blank=True) declination_reason = models.CharField(max_length=50, choices=DeclinationReason.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'] # 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.status, self.declination_reason, self.attachment_text, self.description, self.type] if field is not None] html = '' for field in fields: html += f'' html += '
{field}
' return html def prospect_names(self): prospect_names = [prospect.full_name() for prospect in self.prospects.all()] return ", ".join(prospect_names) @receiver(m2m_changed, sender=Activity.prospects.through) def update_prospect_last_update(sender, instance, action, pk_set, **kwargs): instance.prospects.update(last_update=timezone.now(),contact_again=None) class EmailTemplate(BaseModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) name = models.CharField(max_length=100) subject = models.CharField(max_length=200) body = models.TextField(null=True, blank=True) activities = models.ManyToManyField(Activity, blank=True, related_name='email_templates') def __str__(self): return self.name def delete_dependencies(self): pass class ProspectGroup(BaseModel): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) name = models.CharField(max_length=200, null=True, blank=True) prospects = models.ManyToManyField(Prospect, blank=True, related_name='prospect_groups') def user_count(self): return self.prospects.count() def __str__(self): return self.name def delete_dependencies(self): pass # class EmailCampaign(models.Model): # event = models.OneToOneField(Event, on_delete=models.CASCADE) # subject = models.CharField(max_length=200) # content = models.TextField() # sent_at = models.DateTimeField(null=True, blank=True) # class EmailTracker(models.Model): # campaign = models.ForeignKey(EmailCampaign, on_delete=models.CASCADE) # prospect = models.ForeignKey(Prospect, on_delete=models.CASCADE) # tracking_id = models.UUIDField(default=uuid.uuid4, editable=False) # sent = models.BooleanField(default=False) # sent_at = models.DateTimeField(null=True, blank=True) # opened = models.BooleanField(default=False) # opened_at = models.DateTimeField(null=True, blank=True) # clicked = models.BooleanField(default=False) # clicked_at = models.DateTimeField(null=True, blank=True) # error_message = models.TextField(blank=True) # class Meta: # unique_together = ['campaign', 'prospect']