@ -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 )
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 ) :
for prospect in queryset :
activity = Activity . objects . create (
@ -124,7 +128,7 @@ class ProspectAdmin(SyncedObjectAdmin):
change_list_template = " admin/biz/prospect/change_list.html "
ordering = [ ' -last_update ' ]
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 ' ]
def last_update_date ( self , obj ) :
@ -233,15 +237,17 @@ class ProspectAdmin(SyncedObjectAdmin):
try :
# Read the file content
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
updated_prospects = 0
created_entities = 0
created_events = 0
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
entity_name = row [ 0 ] . strip ( )
@ -251,9 +257,9 @@ class ProspectAdmin(SyncedObjectAdmin):
phone = row [ 4 ] . strip ( ) if row [ 4 ] . strip ( ) else None
if phone and not phone . startswith ( ' 0 ' ) :
phone = ' 0 ' + phone
attachment_text = row [ 5 ] . strip ( ) if row [ 5 ] . 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
# attachment_text = row[5].strip() if row[5].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
# Create or get Entity
entity = None
@ -266,13 +272,13 @@ class ProspectAdmin(SyncedObjectAdmin):
created_entities + = 1
# Get related user if provided
related_user = None
if related_user_name :
try :
related_user = User . objects . get ( username = related_user_name )
except User . DoesNotExist :
# 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 = None
# if related_user_name :
# try :
# related_user = User.objects.get(username=related_user_name )
# except User.DoesNotExist :
# # Try to find by first name if username doesn't exist
# related_user = User.objects.filter(first_name__icontains=related_user_name).first( )
# Create or update Prospect
prospect , prospect_created = Prospect . objects . get_or_create (
@ -282,69 +288,68 @@ class ProspectAdmin(SyncedObjectAdmin):
' last_name ' : last_name ,
' phone ' : phone ,
' name_unsure ' : False ,
' related_user ' : related_user ,
' source ' : source ,
}
)
if prospect_created :
created_prospects + = 1
else :
# Check if names are different and mark as name_unsure
if ( prospect . first_name != first_name or prospect . last_name != last_name ) :
prospect . name_unsure = True
# Update related_user if provided
if related_user :
prospect . related_user = related_user
prospect . save ( )
updated_prospects + = 1
# else :
# # Check if names are different and mark as name_unsure
# if (prospect.first_name != first_name or prospect.last_name != last_name) :
# prospect.name_unsure = True
# # Update related_user if provided
# if related_user :
# prospect.related_user = related_user
# prospect.save( )
# updated_prospects += 1
# Associate entity with prospect
if entity :
prospect . entities . add ( entity )
# Create Event if attachment_text or status is provided
if attachment_text or status_text :
# Map status text to Status enum
status_value = None
declination_reason = None
if status_text :
if ' CONTACTED ' in status_text :
status_value = Status . CONTACTED
elif ' RESPONDED ' in status_text :
status_value = Status . RESPONDED
elif ' SHOULD_TEST ' in status_text :
status_value = Status . SHOULD_TEST
elif ' CUSTOMER ' in status_text :
status_value = Status . CUSTOMER
elif ' TESTING ' in status_text :
status_value = Status . TESTING
elif ' LOST ' in status_text :
status_value = Status . LOST
elif ' DECLINED_TOO_EXPENSIVE ' in status_text :
status_value = Status . DECLINED
declination_reason = DeclinationReason . TOO_EXPENSIVE
elif ' USE_OTHER_PRODUCT ' in status_text :
status_value = Status . DECLINED
declination_reason = DeclinationReason . USE_OTHER_PRODUCT
elif ' USE_ANDROID ' in status_text :
status_value = Status . DECLINED
declination_reason = DeclinationReason . USE_ANDROID
elif ' NOK ' in status_text :
status_value = Status . DECLINED
declination_reason = DeclinationReason . UNKNOWN
elif ' DECLINED_UNRELATED ' in status_text :
status_value = Status . DECLINED_UNRELATED
activity = Activity . objects . create (
type = ActivityType . SMS ,
attachment_text = attachment_text ,
status = status_value ,
declination_reason = declination_reason ,
description = f " Imported from CSV - Status: { status_text } " if status_text else " Imported from CSV "
)
activity . prospects . add ( prospect )
created_events + = 1
# if attachment_text or status_text :
# # Map status text to Status enum
# status_value = None
# declination_reason = None
# if status_text :
# if 'CONTACTED' in status_text :
# status_value = Status. CONTACTED
# elif 'RESPONDED' in status_text :
# status_value = Status. RESPONDED
# elif 'SHOULD_TEST' in status_text :
# status_value = Status. SHOULD_TEST
# elif 'CUSTOMER' in status_text :
# status_value = Status. CUSTOMER
# elif 'TESTING' in status_text :
# status_value = Status. TESTING
# elif 'LOST' in status_text :
# status_value = Status. LOST
# elif 'DECLINED_TOO_EXPENSIVE' in status_text :
# status_value = Status. DECLINED
# declination_reason = DeclinationReason. TOO_EXPENSIVE
# elif 'USE_OTHER_PRODUCT' in status_text :
# status_value = Status. DECLINED
# declination_reason = DeclinationReason. USE_OTHER_PRODUCT
# elif 'USE_ANDROID' in status_text :
# status_value = Status. DECLINED
# declination_reason = DeclinationReason. USE_ANDROID
# elif 'NOK' in status_text :
# status_value = Status. DECLINED
# declination_reason = DeclinationReason. UNKNOWN
# elif 'DECLINED_UNRELATED' in status_text :
# status_value = Status. DECLINED_UNRELATED
# activity = Activity.objects.create (
# type=ActivityType.SMS ,
# attachment_text=attachment_text ,
# status=status_value ,
# declination_reason=declination_reason ,
# description=f"Imported from CSV - Status: {status_text}" if status_text else "Imported from CSV "
# )
# activity.prospects.add(prospect )
# created_events += 1
result = f " Successfully imported: { created_prospects } new prospects, { updated_prospects } updated prospects, { created_entities } new entities, { created_events } new events "
return result