This commit is contained in:
Iliyan Angelov
2025-11-24 03:52:08 +02:00
parent dfcaebaf8c
commit 366f28677a
18241 changed files with 865352 additions and 567 deletions

262
backEnd/contact/views.py Normal file
View File

@@ -0,0 +1,262 @@
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from django.db.models import Q
from .models import ContactSubmission
from .serializers import (
ContactSubmissionSerializer,
ContactSubmissionCreateSerializer,
ContactSubmissionListSerializer,
ContactSubmissionUpdateSerializer
)
from .email_service import (
send_contact_submission_notification,
send_contact_submission_confirmation,
check_email_health,
send_test_email
)
class ContactSubmissionViewSet(viewsets.ModelViewSet):
"""
ViewSet for managing contact form submissions.
Provides endpoints for:
- Creating new contact submissions (public)
- Listing submissions (admin only)
- Retrieving individual submissions (admin only)
- Updating submission status (admin only)
"""
queryset = ContactSubmission.objects.all()
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['status', 'priority', 'industry', 'company_size', 'project_type']
search_fields = ['first_name', 'last_name', 'email', 'company', 'job_title']
ordering_fields = ['created_at', 'updated_at', 'priority']
ordering = ['-created_at']
def get_serializer_class(self):
"""
Return appropriate serializer class based on action.
"""
if self.action == 'create':
return ContactSubmissionCreateSerializer
elif self.action == 'list':
return ContactSubmissionListSerializer
elif self.action in ['update', 'partial_update']:
return ContactSubmissionUpdateSerializer
return ContactSubmissionSerializer
def get_permissions(self):
"""
Set permissions based on action.
"""
if self.action == 'create':
# Allow anyone to create contact submissions
permission_classes = [AllowAny]
else:
# Require authentication for all other actions
permission_classes = [IsAuthenticated]
return [permission() for permission in permission_classes]
def create(self, request, *args, **kwargs):
"""
Create a new contact submission.
Public endpoint for form submissions.
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# Set initial priority based on company size and budget
instance = serializer.save()
self._set_initial_priority(instance)
# Send email notifications
try:
# Send notification to company email
send_contact_submission_notification(instance)
# Send confirmation email to customer
send_contact_submission_confirmation(instance)
except Exception as e:
# Log the error but don't fail the submission
import logging
logger = logging.getLogger(__name__)
logger.error(f"Failed to send email notifications for submission #{instance.id}: {str(e)}")
# Return success response
return Response({
'message': 'Thank you for your submission! We\'ll contact you within 24 hours.',
'submission_id': instance.id,
'status': 'success'
}, status=status.HTTP_201_CREATED)
def _set_initial_priority(self, instance):
"""
Set initial priority based on submission data.
"""
priority = 'medium' # default
# High priority for enterprise clients with large budgets
if (instance.company_size in ['201-1000', '1000+'] and
instance.budget in ['250k-500k', '500k-1m', 'over-1m']):
priority = 'high'
# Urgent for immediate timeline with high budget
elif (instance.timeline == 'immediate' and
instance.budget in ['100k-250k', '250k-500k', '500k-1m', 'over-1m']):
priority = 'urgent'
# Low priority for small companies with small budgets
elif (instance.company_size in ['1-10', '11-50'] and
instance.budget in ['under-50k', '50k-100k']):
priority = 'low'
instance.priority = priority
instance.save(update_fields=['priority'])
@action(detail=True, methods=['post'])
def mark_contacted(self, request, pk=None):
"""
Mark a submission as contacted.
"""
submission = self.get_object()
submission.status = 'contacted'
submission.save(update_fields=['status'])
return Response({
'message': 'Submission marked as contacted',
'status': submission.status
})
@action(detail=True, methods=['post'])
def mark_qualified(self, request, pk=None):
"""
Mark a submission as qualified.
"""
submission = self.get_object()
submission.status = 'qualified'
submission.save(update_fields=['status'])
return Response({
'message': 'Submission marked as qualified',
'status': submission.status
})
@action(detail=True, methods=['post'])
def close_submission(self, request, pk=None):
"""
Close a submission.
"""
submission = self.get_object()
submission.status = 'closed'
submission.save(update_fields=['status'])
return Response({
'message': 'Submission closed',
'status': submission.status
})
@action(detail=False, methods=['get'])
def stats(self, request):
"""
Get statistics about contact submissions.
"""
total = self.get_queryset().count()
new = self.get_queryset().filter(status='new').count()
in_progress = self.get_queryset().filter(status='in_progress').count()
contacted = self.get_queryset().filter(status='contacted').count()
qualified = self.get_queryset().filter(status='qualified').count()
closed = self.get_queryset().filter(status='closed').count()
# Priority breakdown
urgent = self.get_queryset().filter(priority='urgent').count()
high = self.get_queryset().filter(priority='high').count()
medium = self.get_queryset().filter(priority='medium').count()
low = self.get_queryset().filter(priority='low').count()
# Enterprise clients
enterprise = self.get_queryset().filter(
company_size__in=['201-1000', '1000+']
).count()
return Response({
'total_submissions': total,
'status_breakdown': {
'new': new,
'in_progress': in_progress,
'contacted': contacted,
'qualified': qualified,
'closed': closed,
},
'priority_breakdown': {
'urgent': urgent,
'high': high,
'medium': medium,
'low': low,
},
'enterprise_clients': enterprise,
})
@action(detail=False, methods=['get'])
def recent(self, request):
"""
Get recent submissions (last 7 days).
"""
from datetime import datetime, timedelta
recent_date = datetime.now() - timedelta(days=7)
recent_submissions = self.get_queryset().filter(
created_at__gte=recent_date
).order_by('-created_at')[:10]
serializer = ContactSubmissionListSerializer(recent_submissions, many=True)
return Response(serializer.data)
@action(detail=False, methods=['get'])
def high_priority(self, request):
"""
Get high priority submissions.
"""
high_priority_submissions = self.get_queryset().filter(
priority__in=['urgent', 'high']
).order_by('-created_at')
serializer = ContactSubmissionListSerializer(high_priority_submissions, many=True)
return Response(serializer.data)
@action(detail=False, methods=['get'])
def email_health(self, request):
"""
Check email service health for production monitoring.
"""
health_status = check_email_health()
return Response(health_status)
@action(detail=False, methods=['post'])
def send_test_email(self, request):
"""
Send a test email to verify email configuration.
"""
email = request.data.get('email')
if not email:
return Response({
'error': 'Email address is required'
}, status=status.HTTP_400_BAD_REQUEST)
success = send_test_email(email)
if success:
return Response({
'message': f'Test email sent successfully to {email}',
'status': 'success'
})
else:
return Response({
'error': 'Failed to send test email',
'status': 'error'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)