37769-vm/core_views_log_visit.py
2026-02-08 21:35:24 +00:00

145 lines
5.7 KiB
Python

def log_door_visit(request):
"""
Mark all targeted voters at a specific address as visited, update their flags,
and create interaction records.
Can also render a standalone page for logging a visit.
"""
selected_tenant_id = request.session.get("tenant_id")
if not selected_tenant_id:
return redirect("index")
tenant = get_object_or_404(Tenant, id=selected_tenant_id)
campaign_settings, _ = CampaignSettings.objects.get_or_create(tenant=tenant)
# Capture query string for redirecting back with filters
next_qs = request.POST.get("next_query_string", request.GET.get("next_query_string", ""))
source = request.POST.get("source", request.GET.get("source", ""))
redirect_url = reverse("door_visits")
# Build redirect URL
redirect_params = []
if next_qs:
redirect_params.append(next_qs)
if source == "map":
redirect_params.append("open_map=1")
if redirect_params:
redirect_url += "?" + "&".join(redirect_params)
# Get address components from POST or GET
address_street = request.POST.get("address_street", request.GET.get("address_street"))
city = request.POST.get("city", request.GET.get("city"))
state = request.POST.get("state", request.GET.get("state"))
zip_code = request.POST.get("zip_code", request.GET.get("zip_code"))
if not address_street:
messages.warning(request, "No address provided.")
return redirect(redirect_url)
# Find targeted voters at this exact address
voters = Voter.objects.filter(
tenant=tenant,
address_street=address_street,
city=city,
state=state,
zip_code=zip_code,
is_targeted=True
)
if not voters.exists() and request.method == "POST":
messages.warning(request, f"No targeted voters found at {address_street}.")
return redirect(redirect_url)
voter_choices = [(v.id, f"{v.first_name} {v.last_name}") for v in voters]
# Get the volunteer linked to the current user
volunteer = Volunteer.objects.filter(user=request.user, tenant=tenant).first()
if request.method == "POST":
form = DoorVisitLogForm(request.POST, voter_choices=voter_choices)
if form.is_valid():
outcome = form.cleaned_data["outcome"]
notes = form.cleaned_data["notes"]
wants_yard_sign = form.cleaned_data["wants_yard_sign"]
candidate_support = form.cleaned_data["candidate_support"]
follow_up = form.cleaned_data["follow_up"]
follow_up_voter_id = form.cleaned_data.get("follow_up_voter")
call_notes = form.cleaned_data["call_notes"]
# Determine date/time in campaign timezone
campaign_tz_name = campaign_settings.timezone or "America/Chicago"
try:
tz = zoneinfo.ZoneInfo(campaign_tz_name)
except:
tz = zoneinfo.ZoneInfo("America/Chicago")
interaction_date = timezone.now().astimezone(tz)
# Get or create InteractionType
interaction_type, _ = InteractionType.objects.get_or_create(tenant=tenant, name="Door Visit")
# Get default caller for follow-ups
default_caller = None
if follow_up:
default_caller = Volunteer.objects.filter(tenant=tenant, is_default_caller=True).first()
for voter in voters:
# 1) Update voter flags
voter.door_visit = True
# 2) If "Wants a Yard Sign" checkbox is selected
if wants_yard_sign:
voter.yard_sign = "wants"
# 3) Update support status if Supporting or Not Supporting
if candidate_support in ["supporting", "not_supporting"]:
voter.candidate_support = candidate_support
voter.save()
# 4) Create interaction
Interaction.objects.create(
voter=voter,
volunteer=volunteer,
type=interaction_type,
date=interaction_date,
description=outcome,
notes=notes
)
# 5) Create ScheduledCall if follow_up is checked and this is the selected voter
if follow_up and follow_up_voter_id and str(voter.id) == follow_up_voter_id:
ScheduledCall.objects.create(
tenant=tenant,
voter=voter,
volunteer=default_caller,
comments=call_notes,
status="pending"
)
if follow_up:
messages.success(request, f"Door visit logged and follow-up call scheduled for {address_street}.")
else:
messages.success(request, f"Door visit logged for {address_street}.")
return redirect(redirect_url)
else:
messages.error(request, "There was an error in the visit log form.")
return redirect(redirect_url)
else:
# GET request: render standalone page
form = DoorVisitLogForm(voter_choices=voter_choices)
context = {
'selected_tenant': tenant,
'visit_form': form,
'address_street': address_street,
'city': city,
'state': state,
'zip_code': zip_code,
'voters': voters,
'next_query_string': next_qs,
'source': source,
'redirect_url': redirect_url,
}
return render(request, 'core/log_door_visit.html', context)