leads-db/leads/views.py

182 lines
8.3 KiB
Python

from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Q
from django.contrib import messages
from django.db import transaction
from .models import Lead, IDSData, ImportLog
from .forms import LeadForm
import csv
import io
import json
import logging
from django.core.paginator import Paginator
logger = logging.getLogger(__name__)
def ids_data_detail(request, pk):
ids_data = get_object_or_404(IDSData, pk=pk)
return render(request, 'leads/ids_data_detail.html', {'ids_data': ids_data})
def lead_list(request):
query = request.GET.get('q')
if query:
leads = Lead.objects.filter(
Q(name__icontains=query) |
Q(email__icontains=query) |
Q(company__icontains=query)
).order_by('-score')
else:
leads = Lead.objects.all().order_by('-score')
return render(request, 'leads/lead_list.html', {'leads': leads})
def lead_detail(request, pk):
lead = get_object_or_404(Lead, pk=pk)
return render(request, 'leads/lead_detail.html', {'lead': lead})
def lead_create(request):
if request.method == 'POST':
form = LeadForm(request.POST)
if form.is_valid():
form.save()
return redirect('lead_list')
else:
form = LeadForm()
return render(request, 'leads/lead_form.html', {'form': form})
def lead_update(request, pk):
lead = get_object_or_404(Lead, pk=pk)
if request.method == 'POST':
form = LeadForm(request.POST, instance=lead)
if form.is_valid():
form.save()
return redirect('lead_list')
else:
form = LeadForm(instance=lead)
return render(request, 'leads/lead_form.html', {'form': form})
def lead_delete(request, pk):
lead = get_object_or_404(Lead, pk=pk)
if request.method == 'POST':
lead.delete()
return redirect('lead_list')
return render(request, 'leads/lead_confirm_delete.html', {'lead': lead})
def data_sources(request):
return render(request, 'leads/data_sources.html')
def ids_data(request):
ids_data_list = IDSData.objects.all().order_by('business_name')
paginator = Paginator(ids_data_list, 50) # Show 50 items per page
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'leads/ids_data.html', {'page_obj': page_obj})
def ids_data_import(request):
if request.method == 'POST':
csv_file = request.FILES.get('csv_file')
if csv_file:
try:
decoded_file = csv_file.read().decode('utf-8')
io_string = io.StringIO(decoded_file)
reader = csv.DictReader(io_string)
total_records = sum(1 for row in reader)
io_string.seek(0)
reader = csv.DictReader(io_string)
batch_size = 1000
batch = []
total_imported = 0
failed_records = []
with transaction.atomic():
for row in reader:
try:
ids_data = IDSData(
business_uuid=row['Business UUID'],
location_uuid=row['Location UUID'],
business_name=row['Business Name'],
yib=row['YiB'],
gbp_business_category=row['GBP Business Category'],
gbp_matching_service=row['GBP Matching Service'],
gbp_review_rating=float(row['GBP Review Rating']) if row['GBP Review Rating'] else None,
gbp_review_count=int(float(row['GBP Review Count'])) if row['GBP Review Count'] else None,
gbp_industry_avg_review_rating=float(row['GBP Industry Avg Review Rating']) if row['GBP Industry Avg Review Rating'] else None,
gbp_industry_avg_review_count=float(row['GBP Industry Avg Review Count']) if row['GBP Industry Avg Review Count'] else None,
gbp_review_rating_offset=float(row['GBP Review Rating Offset fr. Avg']) if row['GBP Review Rating Offset fr. Avg'] else None,
gbp_review_count_offset=float(row['GBP Review Count Offset fr. Avg']) if row['GBP Review Count Offset fr. Avg'] else None,
gbp_review_rating_health=row['GBP Review Rating Health'],
gbp_review_count_health=row['GBP Review Count Health'],
gbp_location_municipality=row['GBP Location Municipality'],
gbp_location_state=row['GBP Location State'],
location_from_gbp_business_name=row['Location from GBP Business Name'],
gbp_business_phone=row['GBP Business Phone'],
gbp_business_website=row['GBP Business Website'],
root_domain=row['Root Domain'],
md5_for_scrape=row['MD5 for Scrape'],
services_reputation_management=row['Services: Reputation Management'] == 'Yes',
services_gbp_optimization=row['Services: GBP Optimization'] == 'Yes',
services_needs_website=row['Services: Needs Website'] == 'Yes'
)
batch.append(ids_data)
if len(batch) >= batch_size:
IDSData.objects.bulk_create(batch, ignore_conflicts=True)
total_imported += len(batch)
batch = []
except Exception as e:
failed_records.append({
'row': dict(row),
'error': str(e)
})
if batch:
IDSData.objects.bulk_create(batch, ignore_conflicts=True)
total_imported += len(batch)
# Create import log
ImportLog.objects.create(
file_name=csv_file.name,
total_records=total_records,
imported_records=total_imported,
failed_records=len(failed_records),
error_log=json.dumps(failed_records)
)
messages.success(request, f'CSV file imported successfully. {total_imported} records imported or updated. Check import logs for details.')
logger.info(f'CSV import completed. {total_imported} records imported or updated.')
except Exception as e:
error_message = f'Error importing CSV file: {str(e)}'
messages.error(request, error_message)
logger.error(error_message)
logger.exception("Detailed import error:")
else:
messages.error(request, 'No CSV file provided.')
logger.warning('CSV import attempted without file')
return redirect('ids_data')
return render(request, 'leads/ids_data_import.html')
def ids_data_delete_all(request):
if request.method == 'POST':
IDSData.objects.all().delete()
messages.success(request, 'All IDS Data records have been deleted.')
return redirect('ids_data')
return render(request, 'leads/ids_data_delete_confirm.html')
def ids_data_delete(request, pk):
ids_data = get_object_or_404(IDSData, pk=pk)
if request.method == 'POST':
business_name = ids_data.business_name
ids_data.delete()
messages.success(request, f'IDS Data record "{business_name}" has been deleted.')
return redirect('ids_data')
return render(request, 'leads/ids_data_confirm_delete.html', {'ids_data': ids_data})
def import_logs(request):
logs = ImportLog.objects.all().order_by('-timestamp')
return render(request, 'leads/import_logs.html', {'logs': logs})
def import_log_detail(request, pk):
log = get_object_or_404(ImportLog, pk=pk)
failed_records = json.loads(log.error_log)
return render(request, 'leads/import_log_detail.html', {'log': log, 'failed_records': failed_records})