feat(leads): link consumer account to lead on submission

- user_account FK on Lead model (SET_NULL, related_name='submitted_leads')
- Migration 0004_lead_user_account
- ScheduleCallView auto-matches consumer account by email on create
- _serialize_lead now returns userAccount: {id, name, email, phone, eventifyId, profilePicture}
This commit is contained in:
2026-04-07 11:52:41 +05:30
parent 9142b8fedb
commit d04891c064
4 changed files with 64 additions and 3 deletions

View File

@@ -0,0 +1,28 @@
# Generated by Django 4.2.21 on 2026-04-07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('admin_api', '0003_lead'),
]
operations = [
migrations.AddField(
model_name='lead',
name='user_account',
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name='submitted_leads',
to=settings.AUTH_USER_MODEL,
help_text='Consumer platform account that submitted this lead (auto-matched by email)',
),
),
]

View File

@@ -222,9 +222,13 @@ class Lead(models.Model):
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='new')
source = models.CharField(max_length=20, choices=SOURCE_CHOICES, default='schedule_call')
priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='medium')
assigned_to = models.ForeignKey(
assigned_to = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, blank=True, related_name='assigned_leads'
)
user_account = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, blank=True, related_name='submitted_leads',
help_text='Consumer platform account that submitted this lead (auto-matched by email)'
)
notes = models.TextField(blank=True, default='')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

View File

@@ -2357,6 +2357,25 @@ def _serialize_lead(lead):
if lead.assigned_to:
assigned_name = lead.assigned_to.get_full_name() or lead.assigned_to.username
assigned_id = lead.assigned_to.pk
user_account = None
if lead.user_account:
u = lead.user_account
profile_pic = None
try:
if u.profile_picture:
profile_pic = u.profile_picture.url
except Exception:
pass
user_account = {
'id': u.pk,
'name': u.get_full_name() or u.username,
'email': u.email,
'phone': getattr(u, 'phone_number', None) or '',
'eventifyId': getattr(u, 'eventify_id', None),
'profilePicture': profile_pic,
}
return {
'id': lead.pk,
'name': lead.name,
@@ -2372,6 +2391,7 @@ def _serialize_lead(lead):
'notes': lead.notes,
'createdAt': lead.created_at.isoformat(),
'updatedAt': lead.updated_at.isoformat(),
'userAccount': user_account,
}
@@ -2399,7 +2419,7 @@ class LeadListView(APIView):
def get(self, request):
from admin_api.models import Lead
from django.db.models import Q
qs = Lead.objects.select_related('assigned_to').order_by('-created_at')
qs = Lead.objects.select_related('assigned_to', 'user_account').order_by('-created_at')
# Filters
status_f = request.query_params.get('status', '').strip()
@@ -2448,7 +2468,7 @@ class LeadDetailView(APIView):
def get(self, request, pk):
from admin_api.models import Lead
from django.shortcuts import get_object_or_404
lead = get_object_or_404(Lead.objects.select_related('assigned_to'), pk=pk)
lead = get_object_or_404(Lead.objects.select_related('assigned_to', 'user_account'), pk=pk)
return Response(_serialize_lead(lead))

View File

@@ -491,6 +491,14 @@ class ScheduleCallView(View):
if errors:
return JsonResponse({'errors': errors}, status=400)
# Auto-link to a consumer account if one exists with this email
from django.contrib.auth import get_user_model
_User = get_user_model()
try:
consumer_account = _User.objects.get(email=email)
except _User.DoesNotExist:
consumer_account = None
lead = Lead.objects.create(
name=name,
email=email,
@@ -500,6 +508,7 @@ class ScheduleCallView(View):
status='new',
source='schedule_call',
priority='medium',
user_account=consumer_account,
)
log("info", f"New schedule-call lead #{lead.pk} from {email}", request=request)
return JsonResponse({