190 lines
5.9 KiB
Python
190 lines
5.9 KiB
Python
from django.db import models
|
|
from django.core.validators import EmailValidator
|
|
from django.utils import timezone
|
|
|
|
|
|
class ContactSubmission(models.Model):
|
|
"""
|
|
Model to store contact form submissions from the GNX website.
|
|
Based on the comprehensive contact form structure from ContactSection.tsx
|
|
"""
|
|
|
|
# Personal Information
|
|
first_name = models.CharField(max_length=100, verbose_name="First Name")
|
|
last_name = models.CharField(max_length=100, verbose_name="Last Name")
|
|
email = models.EmailField(validators=[EmailValidator()], verbose_name="Business Email")
|
|
phone = models.CharField(max_length=20, blank=True, null=True, verbose_name="Phone Number")
|
|
|
|
# Company Information
|
|
company = models.CharField(max_length=200, verbose_name="Company Name")
|
|
job_title = models.CharField(max_length=100, verbose_name="Job Title")
|
|
|
|
# Industry and Company Size
|
|
INDUSTRY_CHOICES = [
|
|
('technology', 'Technology'),
|
|
('finance', 'Finance'),
|
|
('healthcare', 'Healthcare'),
|
|
('manufacturing', 'Manufacturing'),
|
|
('retail', 'Retail'),
|
|
('education', 'Education'),
|
|
('government', 'Government'),
|
|
('other', 'Other'),
|
|
]
|
|
industry = models.CharField(
|
|
max_length=50,
|
|
choices=INDUSTRY_CHOICES,
|
|
blank=True,
|
|
null=True,
|
|
verbose_name="Industry"
|
|
)
|
|
|
|
COMPANY_SIZE_CHOICES = [
|
|
('1-10', '1-10 employees'),
|
|
('11-50', '11-50 employees'),
|
|
('51-200', '51-200 employees'),
|
|
('201-1000', '201-1000 employees'),
|
|
('1000+', '1000+ employees'),
|
|
]
|
|
company_size = models.CharField(
|
|
max_length=20,
|
|
choices=COMPANY_SIZE_CHOICES,
|
|
blank=True,
|
|
null=True,
|
|
verbose_name="Company Size"
|
|
)
|
|
|
|
# Project Details
|
|
PROJECT_TYPE_CHOICES = [
|
|
('software-development', 'Software Development'),
|
|
('cloud-migration', 'Cloud Migration'),
|
|
('digital-transformation', 'Digital Transformation'),
|
|
('data-analytics', 'Data Analytics'),
|
|
('security-compliance', 'Security & Compliance'),
|
|
('integration', 'System Integration'),
|
|
('consulting', 'Consulting Services'),
|
|
]
|
|
project_type = models.CharField(
|
|
max_length=50,
|
|
choices=PROJECT_TYPE_CHOICES,
|
|
blank=True,
|
|
null=True,
|
|
verbose_name="Project Type"
|
|
)
|
|
|
|
TIMELINE_CHOICES = [
|
|
('immediate', 'Immediate (0-3 months)'),
|
|
('short', 'Short-term (3-6 months)'),
|
|
('medium', 'Medium-term (6-12 months)'),
|
|
('long', 'Long-term (12+ months)'),
|
|
('planning', 'Still planning'),
|
|
]
|
|
timeline = models.CharField(
|
|
max_length=20,
|
|
choices=TIMELINE_CHOICES,
|
|
blank=True,
|
|
null=True,
|
|
verbose_name="Project Timeline"
|
|
)
|
|
|
|
BUDGET_CHOICES = [
|
|
('under-50k', 'Under €50,000'),
|
|
('50k-100k', '€50,000 - €100,000'),
|
|
('100k-250k', '€100,000 - €250,000'),
|
|
('250k-500k', '€250,000 - €500,000'),
|
|
('500k-1m', '€500,000 - €1,000,000'),
|
|
('over-1m', 'Over €1,000,000'),
|
|
('discuss', 'Prefer to discuss'),
|
|
]
|
|
budget = models.CharField(
|
|
max_length=20,
|
|
choices=BUDGET_CHOICES,
|
|
blank=True,
|
|
null=True,
|
|
verbose_name="Project Budget Range"
|
|
)
|
|
|
|
message = models.TextField(verbose_name="Project Description")
|
|
|
|
# Privacy & Communication
|
|
newsletter_subscription = models.BooleanField(
|
|
default=False,
|
|
verbose_name="Newsletter Subscription"
|
|
)
|
|
privacy_consent = models.BooleanField(
|
|
default=False,
|
|
verbose_name="Privacy Policy Consent"
|
|
)
|
|
|
|
# Metadata
|
|
STATUS_CHOICES = [
|
|
('new', 'New'),
|
|
('in_progress', 'In Progress'),
|
|
('contacted', 'Contacted'),
|
|
('qualified', 'Qualified'),
|
|
('closed', 'Closed'),
|
|
]
|
|
status = models.CharField(
|
|
max_length=20,
|
|
choices=STATUS_CHOICES,
|
|
default='new',
|
|
verbose_name="Status"
|
|
)
|
|
|
|
priority = models.CharField(
|
|
max_length=10,
|
|
choices=[
|
|
('low', 'Low'),
|
|
('medium', 'Medium'),
|
|
('high', 'High'),
|
|
('urgent', 'Urgent'),
|
|
],
|
|
default='medium',
|
|
verbose_name="Priority"
|
|
)
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created At")
|
|
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated At")
|
|
|
|
# Admin notes for internal use
|
|
admin_notes = models.TextField(blank=True, null=True, verbose_name="Admin Notes")
|
|
assigned_to = models.CharField(
|
|
max_length=100,
|
|
blank=True,
|
|
null=True,
|
|
verbose_name="Assigned To"
|
|
)
|
|
|
|
class Meta:
|
|
verbose_name = "Contact Submission"
|
|
verbose_name_plural = "Contact Submissions"
|
|
ordering = ['-created_at']
|
|
indexes = [
|
|
models.Index(fields=['email']),
|
|
models.Index(fields=['company']),
|
|
models.Index(fields=['status']),
|
|
models.Index(fields=['created_at']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.first_name} {self.last_name} - {self.company} ({self.created_at.strftime('%Y-%m-%d')})"
|
|
|
|
@property
|
|
def full_name(self):
|
|
return f"{self.first_name} {self.last_name}"
|
|
|
|
@property
|
|
def is_high_priority(self):
|
|
return self.priority in ['high', 'urgent']
|
|
|
|
@property
|
|
def is_enterprise_client(self):
|
|
return self.company_size in ['201-1000', '1000+']
|
|
|
|
def get_industry_display(self):
|
|
return dict(self.INDUSTRY_CHOICES).get(self.industry, self.industry)
|
|
|
|
def get_project_type_display(self):
|
|
return dict(self.PROJECT_TYPE_CHOICES).get(self.project_type, self.project_type)
|
|
|
|
def get_budget_display(self):
|
|
return dict(self.BUDGET_CHOICES).get(self.budget, self.budget) |