@@ -2674,14 +2674,13 @@ def extract_info(row, field_name_list, default_response=""):
2674
2674
pass
2675
2675
return default_response
2676
2676
2677
- def columns_exist_in_csv ( csv_reader , columns ):
2677
+ def columns_exist ( field_names , columns ):
2678
2678
"""returns True if any value in the list `columns` exists in the file"""
2679
- first_row = next (csv_reader )
2680
- result = extract_info (first_row , columns , None )
2681
- if result is None :
2682
- return False
2683
- else :
2684
- return True
2679
+ case_insensitive_row = {k .lower () for k in field_names }
2680
+ for column in columns :
2681
+ if column in case_insensitive_row :
2682
+ return True
2683
+ return False
2685
2684
2686
2685
csv_file .seek (0 )
2687
2686
csv_reader = csv .DictReader (TextIOWrapper (csv_file .file ))
@@ -2697,73 +2696,81 @@ def columns_exist_in_csv(csv_reader, columns):
2697
2696
# order matters here - the most important columns should be validated last,
2698
2697
# so the error refers to the most important missing column
2699
2698
try :
2700
- if not columns_exist_in_csv (csv_reader , phone_field_names ):
2699
+ if not columns_exist (csv_reader . fieldnames , phone_field_names ):
2701
2700
error = "Warning: This file does not contain a phone column"
2702
2701
else :
2703
2702
some_columns_exist = True
2704
- if not columns_exist_in_csv (csv_reader , address_field_names ):
2703
+ if not columns_exist (csv_reader . fieldnames , address_field_names ):
2705
2704
error = "Warning: This file does not contain an address column"
2706
2705
else :
2707
2706
some_columns_exist = True
2708
- if not columns_exist_in_csv (csv_reader , name_field_names ):
2707
+ if not columns_exist (csv_reader . fieldnames , name_field_names ):
2709
2708
error = "Warning: This file does not contain a name column"
2710
2709
else :
2711
2710
some_columns_exist = True
2712
- if not columns_exist_in_csv (csv_reader , email_field_names ):
2711
+ if not columns_exist (csv_reader . fieldnames , email_field_names ):
2713
2712
error = "Warning: This file does not contain an email column"
2714
2713
else :
2715
2714
some_columns_exist = True
2716
2715
if not some_columns_exist :
2717
2716
error = (
2718
2717
"Unable to read information from this CSV file. Make sure it contains an email and a name column"
2719
2718
)
2720
- except UnicodeDecodeError as e :
2719
+
2720
+ total_tos = 0
2721
+ total_skipped = 0
2722
+ for row in csv_reader :
2723
+ bidder_number = extract_info (row , bidder_number_fields )
2724
+ email = extract_info (row , email_field_names )
2725
+ name = extract_info (row , name_field_names )
2726
+ phone = extract_info (row , phone_field_names )
2727
+ address = extract_info (row , address_field_names )
2728
+ is_club_member = extract_info (row , is_club_member_fields )
2729
+ if is_club_member .lower () in ["yes" , "true" , "member" , "club member" ]:
2730
+ is_club_member = True
2731
+ else :
2732
+ is_club_member = False
2733
+ if email or name or phone or address :
2734
+ if self .tos_is_in_auction (self .auction , name , email ):
2735
+ logger .debug ("CSV import skipping %s" , name )
2736
+ total_skipped += 1
2737
+ else :
2738
+ logger .debug ("CSV import adding %s" , name )
2739
+ if bidder_number :
2740
+ if AuctionTOS .objects .filter (auction = self .auction , bidder_number = bidder_number ).first ():
2741
+ bidder_number = ""
2742
+ AuctionTOS .objects .create (
2743
+ auction = self .auction ,
2744
+ pickup_location = self .auction .location_qs .first (),
2745
+ manually_added = True ,
2746
+ bidder_number = bidder_number ,
2747
+ name = name ,
2748
+ phone_number = phone ,
2749
+ email = email ,
2750
+ address = address ,
2751
+ is_club_member = is_club_member ,
2752
+ )
2753
+ total_tos += 1
2754
+ if error :
2755
+ messages .error (self .request , error )
2756
+ msg = f"{ total_tos } users added"
2757
+ if total_skipped :
2758
+ msg += (
2759
+ f", { total_skipped } users are already in this auction (matched by email, or name if email not set)"
2760
+ )
2761
+ messages .info (self .request , msg )
2762
+ url = reverse ("auction_tos_list" , kwargs = {"slug" : self .auction .slug })
2763
+ response = HttpResponse (status = 200 )
2764
+ response ["HX-Redirect" ] = url
2765
+ return response
2766
+ except (UnicodeDecodeError , ValueError ) as e :
2721
2767
messages .error (
2722
2768
self .request , f"Unable to read file. Make sure this is a valid UTF-8 CSV file. Error was: { e } "
2723
2769
)
2724
2770
url = reverse ("bulk_add_users" , kwargs = {"slug" : self .auction .slug })
2725
2771
response = HttpResponse (status = 200 )
2726
2772
response ["HX-Redirect" ] = url
2727
2773
return response
2728
- total_tos = 0
2729
- total_skipped = 0
2730
- for row in csv_reader :
2731
- bidder_number = extract_info (row , bidder_number_fields )
2732
- email = extract_info (row , email_field_names )
2733
- name = extract_info (row , name_field_names )
2734
- phone = extract_info (row , phone_field_names )
2735
- address = extract_info (row , address_field_names )
2736
- is_club_member = extract_info (row , is_club_member_fields )
2737
- if is_club_member .lower () in ["yes" , "true" , "member" , "club member" ]:
2738
- is_club_member = True
2739
- else :
2740
- is_club_member = False
2741
- if email or name or phone or address :
2742
- if self .tos_is_in_auction (self .auction , name , email ):
2743
- total_skipped += 1
2744
- else :
2745
- AuctionTOS .objects .create (
2746
- auction = self .auction ,
2747
- pickup_location = self .auction .location_qs .first (),
2748
- manually_added = True ,
2749
- bidder_number = bidder_number ,
2750
- name = name ,
2751
- phone_number = phone ,
2752
- email = email ,
2753
- address = address ,
2754
- is_club_member = is_club_member ,
2755
- )
2756
- total_tos += 1
2757
- if error :
2758
- messages .error (self .request , error )
2759
- msg = f"{ total_tos } users added"
2760
- if total_skipped :
2761
- msg += f", { total_skipped } users are already in this auction (matched by email, or name if email not set)"
2762
- messages .info (self .request , msg )
2763
- url = reverse ("auction_tos_list" , kwargs = {"slug" : self .auction .slug })
2764
- response = HttpResponse (status = 200 )
2765
- response ["HX-Redirect" ] = url
2766
- return response
2767
2774
2768
2775
# The code below would populate the formset with the info from the CSV.
2769
2776
# This process is simply not working, and it fails silently with no log.
0 commit comments