From c8ea7699c5e01bae97c34edb662b2e1532031979 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 26 Sep 2025 10:36:49 +0200 Subject: [PATCH] adds prospect option --- biz/admin.py | 135 ++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/biz/admin.py b/biz/admin.py index d018112..1f4c230 100644 --- a/biz/admin.py +++ b/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) 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