@@ -526,45 +526,59 @@ def attendee_data(request, form, user_id=None):
).select_related(
"cart", "product"
).order_by("cart__status")
# Get all of the relevant attendee profiles in one hit.
profiles = AttendeeProfile.objects.filter(
attendee__user__cart__productitem__in=items
).select_related("attendee__user")
by_user = {}
for profile in profiles:
by_user[profile.attendee.user] = profile
# Group the responses per-field.
for field in fields:
field_verbose = AttendeeProfile._meta.get_field(field).verbose_name
cart = "attendee__user__cart"
cart_status = cart + "__status"
product = cart + "__productitem__product"
product_name = product + "__name"
category_name = product + "__category__name"
status_count = lambda status: Case(When(
attendee__user__cart__status=status,
then=Value(1),
),
default=Value(0),
output_field=models.fields.IntegerField(),
)
paid_count = status_count(commerce.Cart.STATUS_PAID)
unpaid_count = status_count(commerce.Cart.STATUS_ACTIVE)
p = profiles.order_by(product, field).values(
cart_status, product, product_name, category_name, field
).annotate(count=Count("id"))
product, product_name, category_name, field
).annotate(
paid_count=Sum(paid_count),
unpaid_count=Sum(unpaid_count),
output.append(ListReport(
"Grouped by %s" % field_verbose,
["Product", "Status", field_verbose, "count"],
["Product", field_verbose, "paid", "unpaid"],
[
(
"%s - %s" % (i[category_name], i[product_name]),
status_display[i[cart_status]],
i[field],
i["count"] or 0,
i["paid_count"] or 0,
i["unpaid_count"] or 0,
for i in p
],
))
# DO the report for individual attendees
field_names = [
AttendeeProfile._meta.get_field(field).verbose_name for field in fields
]
headings = ["User ID", "Name", "Product", "Item Status"] + field_names