from django.db import models from django.urls import reverse class Voter(models.Model): CANDIDATE_SUPPORT_CHOICES = [ ('unknown', 'Unknown'), ('supporting', 'Supporting'), ('not_supporting', 'Not Supporting'), ] YARD_SIGN_CHOICES = [ ('none', 'None'), ('wants', 'Wants a Yard Sign'), ('has', 'Has a Yard Sign'), ] LIKELIHOOD_CHOICES = [(i, str(i)) for i in range(1, 6)] voter_id = models.CharField(max_length=50, unique=True) first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) address = models.TextField() phone = models.CharField(max_length=20, blank=True, null=True) email = models.EmailField(blank=True, null=True) # Demographics district = models.CharField(max_length=100, blank=True, null=True) precinct = models.CharField(max_length=100, blank=True, null=True) registration_date = models.DateField(blank=True, null=True) # Engagement likelihood_to_vote = models.IntegerField(choices=LIKELIHOOD_CHOICES, default=3) candidate_support = models.CharField(max_length=20, choices=CANDIDATE_SUPPORT_CHOICES, default='unknown') yard_sign_status = models.CharField(max_length=20, choices=YARD_SIGN_CHOICES, default='none') # Geocode (Optional for map integration later) latitude = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True) longitude = models.DecimalField(max_digits=9, decimal_places=6, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['last_name', 'first_name'] def __str__(self): return f"{self.first_name} {self.last_name} ({self.voter_id})" def get_absolute_url(self): return reverse('voter_detail', kwargs={'pk': self.pk}) class VotingRecord(models.Model): voter = models.ForeignKey(Voter, on_delete=models.CASCADE, related_name='voting_records') election_date = models.DateField() description = models.CharField(max_length=255) primary_party = models.CharField(max_length=50, blank=True, null=True) def __str__(self): return f"{self.voter.last_name} - {self.election_date}" class Donation(models.Model): METHOD_CHOICES = [ ('Cash', 'Cash'), ('Check', 'Check'), ('Credit/Debit', 'Credit/Debit'), ] voter = models.ForeignKey(Voter, on_delete=models.CASCADE, related_name='donations') donation_date = models.DateField() amount = models.DecimalField(max_digits=10, decimal_places=2) method = models.CharField(max_length=20, choices=METHOD_CHOICES, default='Check') def __str__(self): return f"{self.voter.last_name} - ${self.amount} ({self.method})" class VoterContact(models.Model): CONTACT_TYPE_CHOICES = [ ('Phone', 'Phone'), ('Door Visit', 'Door Visit'), ('Mail', 'Mail'), ] voter = models.ForeignKey(Voter, on_delete=models.CASCADE, related_name='contacts') contact_type = models.CharField(max_length=20, choices=CONTACT_TYPE_CHOICES) contact_date = models.DateTimeField() description = models.CharField(max_length=255) notes = models.TextField(blank=True, null=True) def __str__(self): return f"{self.voter.last_name} - {self.contact_type} on {self.contact_date.date()}" class EventParticipation(models.Model): voter = models.ForeignKey(Voter, on_delete=models.CASCADE, related_name='event_participations') event_date = models.DateField() event_type = models.CharField(max_length=100) description = models.TextField(blank=True, null=True) def __str__(self): return f"{self.voter.last_name} - {self.event_type} on {self.event_date}"