Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/eventyay/base/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,10 +345,11 @@ def _render_xlsx(self, form_data, output_file=None):
)

def render(self, form_data: dict, output_file=None) -> Tuple[str, str, bytes]:
if form_data.get('_format') == 'xlsx':
format_value = form_data.get('_format')
if format_value == 'xlsx':
return self._render_xlsx(form_data, output_file=output_file)
elif ':' in form_data.get('_format'):
sheet, f = form_data.get('_format').split(':')
elif format_value and ':' in format_value:
sheet, f = format_value.split(':')
if f == 'default':
return self._render_sheet_csv(
form_data,
Expand Down
2 changes: 1 addition & 1 deletion app/eventyay/base/exporters/dekodi.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class DekodiNREIExporter(BaseExporter):

def _encode_invoice(self, invoice: Invoice):
p_last = invoice.order.payments.filter(
state=[
state__in=[
OrderPayment.PAYMENT_STATE_CONFIRMED,
OrderPayment.PAYMENT_STATE_REFUNDED,
]
Expand Down
8 changes: 4 additions & 4 deletions app/eventyay/base/exporters/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def render(self, form_data):
for variation in item.variations.all()
],
}
for item in self.event.items.select_related('tax_rule').prefetch_related('variations')
for item in self.event.products.select_related('tax_rule').prefetch_related('variations')
],
'questions': [
{
Expand Down Expand Up @@ -83,7 +83,7 @@ def render(self, form_data):
'positions': [
{
'id': position.id,
'item': position.item_id,
'item': position.product_id,
'variation': position.variation_id,
'price': position.price,
'attendee_name': position.attendee_name,
Expand All @@ -107,10 +107,10 @@ def render(self, form_data):
{
'id': quota.id,
'size': quota.size,
'items': [item.id for item in quota.items.all()],
'items': [item.id for item in quota.products.all()],
'variations': [variation.id for variation in quota.variations.all()],
}
for quota in self.event.quotas.all().prefetch_related('items', 'variations')
for quota in self.event.quotas.all().prefetch_related('products', 'variations')
],
}
}
Expand Down
14 changes: 7 additions & 7 deletions app/eventyay/base/exporters/orderlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ def iterate_orders(self, form_data: dict):

qs = self._date_filter(qs, form_data, rel='')

if form_data['paid_only']:
if form_data.get('paid_only', True):
qs = qs.filter(status=Order.STATUS_PAID)
tax_rates = self._get_all_tax_rates(qs)

Expand Down Expand Up @@ -498,7 +498,7 @@ def iterate_fees(self, form_data: dict):
)
.select_related('order', 'order__invoice_address', 'tax_rule')
)
if form_data['paid_only']:
if form_data.get('paid_only', True):
qs = qs.filter(order__status=Order.STATUS_PAID)

qs = self._date_filter(qs, form_data, rel='order__')
Expand Down Expand Up @@ -614,14 +614,14 @@ def iterate_positions(self, form_data: dict):
.select_related(
'order',
'order__invoice_address',
'item',
'product',
'variation',
'voucher',
'tax_rule',
)
.prefetch_related('answers', 'answers__question', 'answers__options')
)
if form_data['paid_only']:
if form_data.get('paid_only', True):
qs = qs.filter(order__status=Order.STATUS_PAID)

qs = self._date_filter(qs, form_data, rel='order__')
Expand Down Expand Up @@ -678,7 +678,7 @@ def iterate_positions(self, form_data: dict):
for q in questions:
if q.type == Question.TYPE_CHOICE_MULTIPLE:
options[q.pk] = []
if form_data['group_multiple_choice']:
if form_data.get('group_multiple_choice', False):
for o in q.options.all():
options[q.pk].append(o)
headers.append(str(q.question))
Expand Down Expand Up @@ -750,7 +750,7 @@ def iterate_positions(self, form_data: dict):
row.append('')
row.append('')
row += [
str(op.item),
str(op.product),
str(op.variation) if op.variation else '',
op.price,
op.tax_rate,
Expand Down Expand Up @@ -797,7 +797,7 @@ def iterate_positions(self, form_data: dict):
acache[a.question_id] = str(a)
for q in questions:
if q.type == Question.TYPE_CHOICE_MULTIPLE:
if form_data['group_multiple_choice']:
if form_data.get('group_multiple_choice', False):
row.append(
', '.join(str(o.answer) for o in options[q.pk] if o.pk in acache.get(q.pk, set()))
)
Expand Down
22 changes: 11 additions & 11 deletions app/eventyay/base/exporters/waitinglist.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def iterate_list(self, form_data):
WaitingListEntry.objects.filter(
event__in=self.events,
)
.select_related('item', 'variation', 'voucher', 'subevent')
.select_related('product', 'variation', 'voucher', 'subevent')
.order_by('created')
)

Expand Down Expand Up @@ -118,16 +118,16 @@ def iterate_list(self, form_data):
datetime_format = '%Y-%m-%d %H:%M:%S %Z'

row = [
entry.created.astimezone(tz).strftime(datetime_format), # alternative: .isoformat(),
entry.name,
entry.email,
entry.phone,
str(entry.item) if entry.item else '',
str(entry.variation) if entry.variation else '',
entry.event.slug,
entry.event.name,
entry.subevent.name if entry.subevent else '',
event_for_date_columns.date_from.astimezone(tz).strftime(datetime_format),
entry.created.astimezone(tz).strftime(datetime_format), # alternative: .isoformat(),
entry.name,
entry.email,
entry.phone,
str(entry.product) if entry.product else '',
str(entry.variation) if entry.variation else '',
entry.event.slug,
entry.event.name,
entry.subevent.name if entry.subevent else '',
event_for_date_columns.date_from.astimezone(tz).strftime(datetime_format),
event_for_date_columns.date_to.astimezone(tz).strftime(datetime_format)
if event_for_date_columns.date_to
else '',
Expand Down
24 changes: 23 additions & 1 deletion app/eventyay/base/services/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ def set_progress(val):
'Your data table is too big for a PDF page. Please reduce the amount of data you are exporting.'
)
raise ExportError(msg) from e
except Exception as e:
logger.exception(f'Error during export with provider {provider}.')
# Provide specific error message based on exception type
error_msg = str(e) if str(e) else type(e).__name__
msg = gettext(
'An error occurred while generating your export: {error}. Please try again or contact support if the problem persists.'
).format(error=error_msg)
raise ExportError(msg) from e
if d is None:
raise ExportError(gettext('Your export did not contain any data.'))
file.filename, file.type, data = d
Expand Down Expand Up @@ -113,7 +121,21 @@ def set_progress(val):
continue
ex = response(events, set_progress)
if ex.identifier == provider:
d = ex.render(form_data)
try:
d = ex.render(form_data)
except LayoutError as e:
logger.exception('Error while making PDF.')
msg = gettext(
'Your data table is too big for a PDF page. Please reduce the amount of data you are exporting.'
)
raise ExportError(msg) from e
except Exception as e:
logger.exception(f'Error during multi-event export with provider {provider}.')
error_msg = str(e) if str(e) else type(e).__name__
msg = gettext(
'An error occurred while generating your export: {error}. Please try again or contact support if the problem persists.'
).format(error=error_msg)
raise ExportError(msg) from e
if d is None:
raise ExportError(gettext('Your export did not contain any data.'))
file.filename, file.type, data = d
Expand Down
3 changes: 3 additions & 0 deletions app/eventyay/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ def instance_name(request):
}
}

# Feature flag for JSON field support (PostgreSQL only)
JSON_FIELD_AVAILABLE = DATABASES['default']['ENGINE'].split('.')[-1] == 'postgresql'


AUTHENTICATION_BACKENDS = (
'rules.permissions.ObjectPermissionBackend',
Expand Down
5 changes: 3 additions & 2 deletions app/eventyay/plugins/badges/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ def render_page(positions):
if pagebuffer:
render_page(pagebuffer)

if not any:
raise OrderError(_('None of the selected products is configured to print badges.'))

output_pdf_writer.add_metadata(
{
'/Title': 'Badges',
Expand All @@ -240,8 +243,6 @@ def render_page(positions):
)
output_pdf_writer.write(outbuffer)
outbuffer.seek(0)
if not any:
raise OrderError(_('None of the selected products is configured to print badges.'))
return outbuffer


Expand Down
17 changes: 11 additions & 6 deletions app/eventyay/plugins/checkinlists/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def _get_queryset(self, cl, form_data):
)
.select_related(
'order',
'item',
'product',
'variation',
'addon_to',
'order__invoice_address',
Expand All @@ -195,7 +195,7 @@ def _get_queryset(self, cl, form_data):
)

if not cl.all_products:
qs = qs.filter(item__in=cl.limit_products.values_list('id', flat=True))
qs = qs.filter(product__in=cl.limit_products.values_list('id', flat=True))

if cl.subevent:
qs = qs.filter(subevent=cl.subevent)
Expand Down Expand Up @@ -311,9 +311,14 @@ def pagesize(self):
return pagesizes.landscape(pagesizes.A4)

def get_story(self, doc, form_data):
if 'list' not in form_data or not form_data['list']:
# Return empty story instead of None
from reportlab.platypus import Paragraph
return [Paragraph("No check-in list selected.", self.get_style())]

cl = self.event.checkin_lists.get(pk=form_data['list'])

questions = tuple(Question.objects.filter(event=self.event, id__in=form_data['questions']))
questions = tuple(Question.objects.filter(event=self.event, id__in=form_data.get('questions', [])))

headlinestyle = self.get_style()
headlinestyle.fontSize = 15
Expand Down Expand Up @@ -698,12 +703,12 @@ def iterate_list(self, form_data):
if form_data.get('list'):
qs = qs.filter(list_id=form_data.get('list'))
if form_data.get('items'):
qs = qs.filter(position__item_id__in=form_data['items'])
qs = qs.filter(position__product_id__in=form_data['items'])

yield self.ProgressSetTotal(total=qs.count())

qs = qs.select_related(
'position__item',
'position__product',
'position__order',
'position__order__invoice_address',
'position',
Expand All @@ -724,7 +729,7 @@ def iterate_list(self, form_data):
ci.position.order.code,
ci.position.positionid,
ci.position.secret,
str(ci.position.item),
str(ci.position.product),
ci.position.attendee_name or ia.name,
str(ci.device),
_('Yes') if ci.forced else _('No'),
Expand Down
21 changes: 13 additions & 8 deletions app/eventyay/plugins/reports/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,28 +375,33 @@ def _table_story(self, doc, form_data, net=False):
if tup[0]:
tdata.append([Paragraph(str(tup[0].name), tstyle_bold)])
for l, s in states:
tdata[-1].append(str(tup[0].num[l][0]))
tdata[-1].append(floatformat(tup[0].num[l][2 if net else 1], places))
num_data = tup[0].num.get(l, (0, 0, 0)) if hasattr(tup[0], 'num') and tup[0].num else (0, 0, 0)
tdata[-1].append(str(num_data[0] if len(num_data) > 0 else 0))
tdata[-1].append(floatformat(num_data[2 if net else 1] if len(num_data) > (2 if net else 1) else 0, places))
for item in tup[1]:
tdata.append([str(item)])
for l, s in states:
tdata[-1].append(str(item.num[l][0]))
tdata[-1].append(floatformat(item.num[l][2 if net else 1], places))
num_data = item.num.get(l, (0, 0, 0)) if hasattr(item, 'num') and item.num else (0, 0, 0)
tdata[-1].append(str(num_data[0] if len(num_data) > 0 else 0))
tdata[-1].append(floatformat(num_data[2 if net else 1] if len(num_data) > (2 if net else 1) else 0, places))
if item.has_variations:
for var in item.all_variations:
tdata.append([Paragraph(' ' + str(var), tstyle)])
for l, s in states:
tdata[-1].append(str(var.num[l][0]))
tdata[-1].append(floatformat(var.num[l][2 if net else 1], places))
num_data = var.num.get(l, (0, 0, 0)) if hasattr(var, 'num') and var.num else (0, 0, 0)
tdata[-1].append(str(num_data[0] if len(num_data) > 0 else 0))
tdata[-1].append(floatformat(num_data[2 if net else 1] if len(num_data) > (2 if net else 1) else 0, places))

tdata.append(
[
_('Total'),
]
)
for l, s in states:
tdata[-1].append(str(total['num'][l][0]))
tdata[-1].append(floatformat(total['num'][l][2 if net else 1], places))
# Safeguard for empty data
num_data = total.get('num', {}).get(l, (0, 0, 0))
tdata[-1].append(str(num_data[0] if len(num_data) > 0 else 0))
tdata[-1].append(floatformat(num_data[2 if net else 1] if len(num_data) > (2 if net else 1) else 0, places))

table = Table(tdata, colWidths=colwidths, repeatRows=3)
table.setStyle(TableStyle(tstyledata))
Expand Down
7 changes: 6 additions & 1 deletion app/eventyay/plugins/ticketoutputpdf/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,12 @@ def render(self, form_data):
)

o = PdfTicketOutput(Event.objects.none())
any_tickets = False
for op in qs:
if not op.generate_ticket:
continue


any_tickets = True
if op.order.event != o.event:
o = PdfTicketOutput(op.event)

Expand All @@ -156,6 +158,9 @@ def render(self, form_data):
outbuffer = o._draw_page(layout, op, op.order)
merger.append(ContentFile(outbuffer.read()))

if not any_tickets:
return None

outbuffer = BytesIO()
merger.write(outbuffer)
merger.close()
Expand Down