adds prospect option

mailing
Laurent 1 month ago
parent 5754a655bc
commit c8ea7699c5
  1. 135
      biz/admin.py

@ -79,6 +79,10 @@ def mark_as_have_account(modeladmin, request, queryset):
create_default_activity_for_prospect(modeladmin, request, queryset, None, Status.HAVE_CREATED_ACCOUNT, None) create_default_activity_for_prospect(modeladmin, request, queryset, None, Status.HAVE_CREATED_ACCOUNT, None)
mark_as_have_account.short_description = "Mark as having an account" mark_as_have_account.short_description = "Mark as having an account"
def mark_as_not_concerned(modeladmin, request, queryset):
create_default_activity_for_prospect(modeladmin, request, queryset, None, Status.NOT_CONCERNED, None)
mark_as_not_concerned.short_description = "Mark as not concerned"
def create_default_activity_for_prospect(modeladmin, request, queryset, type, status, reason): def create_default_activity_for_prospect(modeladmin, request, queryset, type, status, reason):
for prospect in queryset: for prospect in queryset:
activity = Activity.objects.create( activity = Activity.objects.create(
@ -124,7 +128,7 @@ class ProspectAdmin(SyncedObjectAdmin):
change_list_template = "admin/biz/prospect/change_list.html" change_list_template = "admin/biz/prospect/change_list.html"
ordering = ['-last_update'] ordering = ['-last_update']
filter_horizontal = ['entities'] filter_horizontal = ['entities']
actions = ['send_email', create_activity_for_prospect, mark_as_inbound, contacted_by_sms, mark_as_should_test, mark_as_testing, mark_as_customer, mark_as_have_account, declined_too_expensive, declined_use_something_else, declined_android_user] actions = ['send_email', create_activity_for_prospect, mark_as_inbound, contacted_by_sms, mark_as_should_test, mark_as_testing, mark_as_customer, mark_as_have_account, declined_too_expensive, declined_use_something_else, declined_android_user, mark_as_not_concerned]
raw_id_fields = ['official_user', 'related_user'] raw_id_fields = ['official_user', 'related_user']
def last_update_date(self, obj): def last_update_date(self, obj):
@ -233,15 +237,17 @@ class ProspectAdmin(SyncedObjectAdmin):
try: try:
# Read the file content # Read the file content
file_content = file.read().decode('utf-8') file_content = file.read().decode('utf-8')
csv_reader = csv.reader(io.StringIO(file_content)) csv_reader = csv.reader(io.StringIO(file_content), delimiter=';')
created_prospects = 0 created_prospects = 0
updated_prospects = 0 updated_prospects = 0
created_entities = 0 created_entities = 0
created_events = 0 created_events = 0
for row in csv_reader: for row in csv_reader:
if len(row) < 8: print(f'>>> row size is {len(row)}')
if len(row) < 5:
print(f'>>> WARNING: row size is {len(row)}: {row}')
continue # Skip rows that don't have enough columns continue # Skip rows that don't have enough columns
entity_name = row[0].strip() entity_name = row[0].strip()
@ -251,9 +257,9 @@ class ProspectAdmin(SyncedObjectAdmin):
phone = row[4].strip() if row[4].strip() else None phone = row[4].strip() if row[4].strip() else None
if phone and not phone.startswith('0'): if phone and not phone.startswith('0'):
phone = '0' + phone phone = '0' + phone
attachment_text = row[5].strip() if row[5].strip() else None # attachment_text = row[5].strip() if row[5].strip() else None
status_text = row[6].strip() if row[6].strip() else None # status_text = row[6].strip() if row[6].strip() else None
related_user_name = row[7].strip() if row[7].strip() else None # related_user_name = row[7].strip() if row[7].strip() else None
# Create or get Entity # Create or get Entity
entity = None entity = None
@ -266,13 +272,13 @@ class ProspectAdmin(SyncedObjectAdmin):
created_entities += 1 created_entities += 1
# Get related user if provided # Get related user if provided
related_user = None # related_user = None
if related_user_name: # if related_user_name:
try: # try:
related_user = User.objects.get(username=related_user_name) # related_user = User.objects.get(username=related_user_name)
except User.DoesNotExist: # except User.DoesNotExist:
# Try to find by first name if username doesn't exist # # Try to find by first name if username doesn't exist
related_user = User.objects.filter(first_name__icontains=related_user_name).first() # related_user = User.objects.filter(first_name__icontains=related_user_name).first()
# Create or update Prospect # Create or update Prospect
prospect, prospect_created = Prospect.objects.get_or_create( prospect, prospect_created = Prospect.objects.get_or_create(
@ -282,69 +288,68 @@ class ProspectAdmin(SyncedObjectAdmin):
'last_name': last_name, 'last_name': last_name,
'phone': phone, 'phone': phone,
'name_unsure': False, 'name_unsure': False,
'related_user': related_user,
'source': source, 'source': source,
} }
) )
if prospect_created: if prospect_created:
created_prospects += 1 created_prospects += 1
else: # else:
# Check if names are different and mark as name_unsure # # Check if names are different and mark as name_unsure
if (prospect.first_name != first_name or prospect.last_name != last_name): # if (prospect.first_name != first_name or prospect.last_name != last_name):
prospect.name_unsure = True # prospect.name_unsure = True
# Update related_user if provided # # Update related_user if provided
if related_user: # if related_user:
prospect.related_user = related_user # prospect.related_user = related_user
prospect.save() # prospect.save()
updated_prospects += 1 # updated_prospects += 1
# Associate entity with prospect # Associate entity with prospect
if entity: if entity:
prospect.entities.add(entity) prospect.entities.add(entity)
# Create Event if attachment_text or status is provided # Create Event if attachment_text or status is provided
if attachment_text or status_text: # if attachment_text or status_text:
# Map status text to Status enum # # Map status text to Status enum
status_value = None # status_value = None
declination_reason = None # declination_reason = None
if status_text: # if status_text:
if 'CONTACTED' in status_text: # if 'CONTACTED' in status_text:
status_value = Status.CONTACTED # status_value = Status.CONTACTED
elif 'RESPONDED' in status_text: # elif 'RESPONDED' in status_text:
status_value = Status.RESPONDED # status_value = Status.RESPONDED
elif 'SHOULD_TEST' in status_text: # elif 'SHOULD_TEST' in status_text:
status_value = Status.SHOULD_TEST # status_value = Status.SHOULD_TEST
elif 'CUSTOMER' in status_text: # elif 'CUSTOMER' in status_text:
status_value = Status.CUSTOMER # status_value = Status.CUSTOMER
elif 'TESTING' in status_text: # elif 'TESTING' in status_text:
status_value = Status.TESTING # status_value = Status.TESTING
elif 'LOST' in status_text: # elif 'LOST' in status_text:
status_value = Status.LOST # status_value = Status.LOST
elif 'DECLINED_TOO_EXPENSIVE' in status_text: # elif 'DECLINED_TOO_EXPENSIVE' in status_text:
status_value = Status.DECLINED # status_value = Status.DECLINED
declination_reason = DeclinationReason.TOO_EXPENSIVE # declination_reason = DeclinationReason.TOO_EXPENSIVE
elif 'USE_OTHER_PRODUCT' in status_text: # elif 'USE_OTHER_PRODUCT' in status_text:
status_value = Status.DECLINED # status_value = Status.DECLINED
declination_reason = DeclinationReason.USE_OTHER_PRODUCT # declination_reason = DeclinationReason.USE_OTHER_PRODUCT
elif 'USE_ANDROID' in status_text: # elif 'USE_ANDROID' in status_text:
status_value = Status.DECLINED # status_value = Status.DECLINED
declination_reason = DeclinationReason.USE_ANDROID # declination_reason = DeclinationReason.USE_ANDROID
elif 'NOK' in status_text: # elif 'NOK' in status_text:
status_value = Status.DECLINED # status_value = Status.DECLINED
declination_reason = DeclinationReason.UNKNOWN # declination_reason = DeclinationReason.UNKNOWN
elif 'DECLINED_UNRELATED' in status_text: # elif 'DECLINED_UNRELATED' in status_text:
status_value = Status.DECLINED_UNRELATED # status_value = Status.DECLINED_UNRELATED
activity = Activity.objects.create( # activity = Activity.objects.create(
type=ActivityType.SMS, # type=ActivityType.SMS,
attachment_text=attachment_text, # attachment_text=attachment_text,
status=status_value, # status=status_value,
declination_reason=declination_reason, # declination_reason=declination_reason,
description=f"Imported from CSV - Status: {status_text}" if status_text else "Imported from CSV" # description=f"Imported from CSV - Status: {status_text}" if status_text else "Imported from CSV"
) # )
activity.prospects.add(prospect) # activity.prospects.add(prospect)
created_events += 1 # created_events += 1
result = f"Successfully imported: {created_prospects} new prospects, {updated_prospects} updated prospects, {created_entities} new entities, {created_events} new events" result = f"Successfully imported: {created_prospects} new prospects, {updated_prospects} updated prospects, {created_entities} new entities, {created_events} new events"
return result return result

Loading…
Cancel
Save