Skip to content

Commit a62b066

Browse files
catInOrbitnorbusan
andauthored
8972 export attendee csv error (#8952)
* Rewrite celery export and its helper task with Dictwriter, better validation * Added new parameter for test case * Test case logic change due to new return type * Test case logic change due to new return type * Recorrect test case --------- Co-authored-by: Norbert Preining <[email protected]>
1 parent fe643dc commit a62b066

File tree

3 files changed

+74
-55
lines changed

3 files changed

+74
-55
lines changed

app/api/helpers/csv_jobs_util.py

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -57,72 +57,65 @@ def export_orders_csv(orders):
5757
return rows
5858

5959

60-
def export_attendees_csv(attendees, custom_forms):
60+
def export_attendees_csv(attendees, custom_forms, attendee_form_dict):
61+
return_dict_list = []
6162

62-
headers = [
63-
'Order#',
64-
'Order Date',
65-
'Status',
66-
'Payment Type',
67-
'Payment Mode',
68-
'Ticket Name',
69-
'Ticket Price',
70-
'Ticket Type',
71-
'Tax ID',
72-
'Address',
73-
'Company',
74-
'Country',
75-
'State',
76-
'City',
77-
'Zipcode',
78-
]
79-
80-
for fields in custom_forms:
81-
headers.append(fields.name)
82-
83-
rows = [headers]
8463
for attendee in attendees:
85-
column = [
86-
str(attendee.order.get_invoice_number()) if attendee.order else '-',
87-
str(attendee.order.created_at.strftime('%B %-d, %Y %H:%M %z'))
64+
data = {
65+
'Order#': str(attendee.order.get_invoice_number()) if attendee.order else '-',
66+
'Order Date': str(attendee.order.created_at.strftime('%B %-d, %Y %H:%M %z'))
8867
if attendee.order and attendee.order.created_at
8968
else '-',
90-
str(attendee.order.status)
69+
'Status': str(attendee.order.status)
9170
if attendee.order and attendee.order.status
9271
else '-',
93-
str(attendee.order.paid_via)
72+
'Payment Type': str(attendee.order.paid_via)
9473
if attendee.order and attendee.order.paid_via
9574
else '',
96-
str(attendee.order.payment_mode)
75+
'Payment Mode': str(attendee.order.payment_mode)
9776
if attendee.order and attendee.order.payment_mode
9877
else '',
99-
str(attendee.ticket.name) if attendee.ticket and attendee.ticket.name else '',
100-
str(attendee.ticket.price)
78+
'Ticket Name': str(attendee.ticket.name)
79+
if attendee.ticket and attendee.ticket.name else '',
80+
'Ticket Price': str(attendee.ticket.price)
10181
if attendee.ticket and attendee.ticket.price
10282
else '0',
103-
str(attendee.ticket.type) if attendee.ticket and attendee.ticket.type else '',
104-
str(attendee.order.tax_business_info)
83+
'Ticket Type': str(attendee.ticket.type)
84+
if attendee.ticket and attendee.ticket.type else '',
85+
'Tax ID': str(attendee.order.tax_business_info)
10586
if attendee.order.tax_business_info
10687
else '',
107-
str(attendee.order.address) if attendee.order.address else '',
108-
str(attendee.order.company) if attendee.order.company else '',
109-
str(attendee.order.country) if attendee.order.country else '',
110-
str(attendee.order.state) if attendee.order.state else '',
111-
str(attendee.order.city) if attendee.order.city else '',
112-
str(attendee.order.zipcode) if attendee.order.zipcode else '',
113-
]
88+
'Address': str(attendee.order.address) if attendee.order.address else '',
89+
'Company': str(attendee.order.company) if attendee.order.company else '',
90+
'Country': str(attendee.order.country) if attendee.order.country else '',
91+
'State': str(attendee.order.state) if attendee.order.state else '',
92+
'City': str(attendee.order.city) if attendee.order.city else '',
93+
'Zipcode': str(attendee.order.zipcode) if attendee.order.zipcode else '',
94+
}
95+
11496
for field in custom_forms:
97+
# keys don't match up, for keys like
98+
# acceptVideoRecording vs accept_video_recording ..
99+
key_mapping = {}
100+
101+
for k in attendee_form_dict.keys():
102+
key_mapping[k.replace("_", "").lower()] = k
103+
104+
field_raw = field.identifier.replace("_", "").lower()
105+
key = key_mapping.get(field_raw)
106+
converted_header = attendee_form_dict.get(key)
115107
if field.is_complex:
116108
fields_dict = attendee.complex_field_values
117-
column.append(
118-
fields_dict.get(field.identifier, '') if fields_dict else ''
119-
)
109+
data[converted_header] = fields_dict.get(
110+
field.identifier, '') if fields_dict else ''
120111
else:
121-
column.append(getattr(attendee, field.identifier, ''))
112+
dict_value = (getattr(attendee, field.identifier, ''))
113+
dict_value = "Yes" if str(dict_value) == "True" \
114+
else "No" if str(dict_value) == "False" else dict_value
115+
data[converted_header] = dict_value
116+
return_dict_list.append(data)
122117

123-
rows.append(column)
124-
125-
return rows
118+
return return_dict_list
126119

127120

128121
def export_sessions_csv(sessions):

app/api/helpers/tasks.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from app.api.imports import import_event_task_base
4040
from app.instance import create_app
4141
from app.models import db
42-
from app.models.custom_form import CustomForms
42+
from app.models.custom_form import CustomForms, ATTENDEE_CUSTOM_FORM
4343
from app.models.discount_code import DiscountCode
4444
from app.models.event import Event
4545
from app.models.exhibitor import Exhibitor
@@ -52,8 +52,8 @@
5252
from app.models.user import User
5353
from app.models.user_follow_group import UserFollowGroup
5454
from app.settings import get_settings
55-
5655
from .import_helpers import update_import_job
56+
from app.api.helpers.csv_jobs_util import export_attendees_csv
5757

5858
"""
5959
Define all API v2 celery tasks here
@@ -541,20 +541,43 @@ def export_attendees_csv_task(self, event_id):
541541
custom_forms = db.session.query(CustomForms).filter_by(
542542
event_id=event_id, form=CustomForms.TYPE.ATTENDEE, is_included=True
543543
)
544+
545+
field_headers = list(ATTENDEE_CUSTOM_FORM.keys())
546+
547+
def custom_form_validation(cf_orm, field_headers):
548+
# set() is O(1) in membership testing
549+
field_headers_set = set(field_headers)
550+
forms_result = [None] * len(field_headers_set)
551+
552+
for row in cf_orm:
553+
if row.field_identifier in field_headers_set:
554+
555+
field_headers_set.discard(row.field_identifier)
556+
index_append = field_headers.index(row.field_identifier)
557+
# forms_result.append(row)
558+
forms_result.insert(index_append, row)
559+
560+
forms_result = [e for e in forms_result if e is not None]
561+
return forms_result
562+
544563
try:
564+
custom_forms = custom_form_validation(custom_forms, field_headers)
545565
filedir = os.path.join(current_app.config.get('BASE_DIR'), 'static/uploads/temp/')
546566
if not os.path.isdir(filedir):
547567
os.makedirs(filedir)
548568
filename = f"attendees-{uuid.uuid1().hex}.csv"
549569
file_path = os.path.join(filedir, filename)
550570

571+
dict_list = export_attendees_csv(attendees, custom_forms, ATTENDEE_CUSTOM_FORM)
572+
csv_headers = list(dict_list[0].keys())
573+
551574
with open(file_path, "w") as temp_file:
552-
writer = csv.writer(temp_file)
553-
from app.api.helpers.csv_jobs_util import export_attendees_csv
575+
writer = csv.DictWriter(temp_file, fieldnames=csv_headers)
576+
writer.writeheader()
554577

555-
content = export_attendees_csv(attendees, custom_forms)
556-
for row in content:
578+
for row in dict_list:
557579
writer.writerow(row)
580+
558581
attendees_csv_file = UploadedFile(file_path=file_path, filename=filename)
559582
attendees_csv_url = upload(
560583
attendees_csv_file,

tests/all/integration/api/helpers/test_csv_jobs_util.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from tests.factories.order import OrderFactory
1212
from tests.factories.session import SessionSubFactory
1313
from tests.factories.speaker import SpeakerFactory
14+
from app.models.custom_form import ATTENDEE_CUSTOM_FORM
1415

1516

1617
class TestExportCSV(OpenEventTestCase):
@@ -32,8 +33,10 @@ def test_export_attendees_csv(self):
3233
test_order = OrderFactory(created_at=datetime.now())
3334
test_attendee.order = test_order
3435
custom_forms = CustomFormFactory()
35-
field_data = export_attendees_csv([test_attendee], [custom_forms])
36-
assert field_data[1][8] == 'tax id'
36+
field_data = export_attendees_csv(
37+
[test_attendee], [custom_forms], ATTENDEE_CUSTOM_FORM)
38+
# new export_attendees_csv will return list of dictionary for csv_writer
39+
assert field_data[0].get("Tax ID") == "tax id"
3740

3841
def _test_export_session_csv(self, test_session=None):
3942
with self.app.test_request_context():

0 commit comments

Comments
 (0)