from django.db import models from django.contrib.auth import get_user_model from django.core.validators import EmailValidator import uuid User = get_user_model() class ContactGroup(models.Model): """Contact groups for organizing contacts.""" user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contact_groups') name = models.CharField(max_length=100) description = models.TextField(blank=True) color = models.CharField(max_length=7, default='#007bff') # Hex color created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'contact_groups' unique_together = ['user', 'name'] ordering = ['name'] def __str__(self): return f"{self.user.email} - {self.name}" class Contact(models.Model): """Contact model for storing contact information.""" user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contacts') group = models.ForeignKey(ContactGroup, on_delete=models.SET_NULL, null=True, blank=True, related_name='contacts') # Basic information first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) email = models.EmailField() phone = models.CharField(max_length=20, blank=True) company = models.CharField(max_length=100, blank=True) job_title = models.CharField(max_length=100, blank=True) # Additional information avatar = models.ImageField(upload_to='contact_avatars/', null=True, blank=True) notes = models.TextField(blank=True) website = models.URLField(blank=True) birthday = models.DateField(null=True, blank=True) # Address information address_line1 = models.CharField(max_length=100, blank=True) address_line2 = models.CharField(max_length=100, blank=True) city = models.CharField(max_length=50, blank=True) state = models.CharField(max_length=50, blank=True) postal_code = models.CharField(max_length=20, blank=True) country = models.CharField(max_length=50, blank=True) # Social media linkedin = models.URLField(blank=True) twitter = models.URLField(blank=True) facebook = models.URLField(blank=True) # Metadata is_favorite = models.BooleanField(default=False) is_blocked = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = 'contacts' unique_together = ['user', 'email'] ordering = ['first_name', 'last_name'] indexes = [ models.Index(fields=['user', 'email']), models.Index(fields=['user', 'is_favorite']), models.Index(fields=['user', 'is_blocked']), ] def __str__(self): return f"{self.first_name} {self.last_name} ({self.email})" def get_full_name(self): return f"{self.first_name} {self.last_name}".strip() def get_address(self): """Get formatted address.""" address_parts = [ self.address_line1, self.address_line2, self.city, self.state, self.postal_code, self.country ] return ', '.join([part for part in address_parts if part]) class ContactInteraction(models.Model): """Track interactions with contacts.""" INTERACTION_TYPES = [ ('email_sent', 'Email Sent'), ('email_received', 'Email Received'), ('phone_call', 'Phone Call'), ('meeting', 'Meeting'), ('note', 'Note'), ] contact = models.ForeignKey(Contact, on_delete=models.CASCADE, related_name='interactions') interaction_type = models.CharField(max_length=20, choices=INTERACTION_TYPES) subject = models.CharField(max_length=200, blank=True) description = models.TextField(blank=True) date = models.DateTimeField(auto_now_add=True) created_by = models.ForeignKey(User, on_delete=models.CASCADE) class Meta: db_table = 'contact_interactions' ordering = ['-date'] def __str__(self): return f"{self.contact.get_full_name()} - {self.get_interaction_type_display()}" class ContactImport(models.Model): """Track contact imports.""" STATUS_CHOICES = [ ('pending', 'Pending'), ('processing', 'Processing'), ('completed', 'Completed'), ('failed', 'Failed'), ] user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='contact_imports') filename = models.CharField(max_length=255) file = models.FileField(upload_to='contact_imports/') status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') total_contacts = models.IntegerField(default=0) imported_contacts = models.IntegerField(default=0) failed_contacts = models.IntegerField(default=0) error_log = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) completed_at = models.DateTimeField(null=True, blank=True) class Meta: db_table = 'contact_imports' ordering = ['-created_at'] def __str__(self): return f"{self.user.email} - {self.filename}"