182 lines
8.3 KiB
Python
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})
|