parent
e3b662fb67
commit
2ed0a47f15
3 changed files with 119 additions and 4 deletions
|
@ -29,3 +29,22 @@ class UserIdForm(forms.Form):
|
|||
label="User ID",
|
||||
required=False,
|
||||
)
|
||||
|
||||
|
||||
def model_fields_form_factory(model):
|
||||
''' Creates a form for specifying fields from a model to display. '''
|
||||
|
||||
fields = model._meta.get_fields()
|
||||
|
||||
choices = []
|
||||
for field in fields:
|
||||
if hasattr(field, "verbose_name"):
|
||||
choices.append((field.name, field.verbose_name))
|
||||
|
||||
class ModelFieldsForm(forms.Form):
|
||||
fields = forms.MultipleChoiceField(
|
||||
choices=choices,
|
||||
required=False,
|
||||
)
|
||||
|
||||
return ModelFieldsForm
|
||||
|
|
|
@ -364,6 +364,12 @@ def credit_notes(request, form):
|
|||
)
|
||||
|
||||
|
||||
class AttendeeListReport(ListReport):
|
||||
|
||||
def get_link(self, argument):
|
||||
return reverse(self._link_view) + "?user=%d" % int(argument)
|
||||
|
||||
|
||||
@report_view("Attendee", form_type=forms.UserIdForm)
|
||||
def attendee(request, form, user_id=None):
|
||||
''' Returns a list of all manifested attendees if no attendee is specified,
|
||||
|
@ -484,9 +490,98 @@ def attendee_list(request):
|
|||
# Sort by whether they've registered, then ID.
|
||||
data.sort(key=lambda a: (-a[3], a[0]))
|
||||
|
||||
class Report(ListReport):
|
||||
return AttendeeListReport("Attendees", headings, data, link_view=attendee)
|
||||
|
||||
def get_link(self, argument):
|
||||
return reverse(self._link_view) + "?user=%d" % int(argument)
|
||||
|
||||
return Report("Attendees", headings, data, link_view=attendee)
|
||||
ProfileForm = forms.model_fields_form_factory(AttendeeProfile)
|
||||
class ProductCategoryProfileForm(forms.ProductAndCategoryForm, ProfileForm):
|
||||
pass
|
||||
|
||||
|
||||
@report_view(
|
||||
"Attendees By Product/Category",
|
||||
form_type=ProductCategoryProfileForm,
|
||||
)
|
||||
def attendee_data(request, form, user_id=None):
|
||||
''' Lists attendees for a given product/category selection along with
|
||||
profile data.'''
|
||||
|
||||
status_display = {
|
||||
commerce.Cart.STATUS_ACTIVE: "Unpaid",
|
||||
commerce.Cart.STATUS_PAID: "Paid",
|
||||
commerce.Cart.STATUS_RELEASED: "Refunded",
|
||||
}
|
||||
|
||||
output = []
|
||||
|
||||
products = form.cleaned_data["product"]
|
||||
categories = form.cleaned_data["category"]
|
||||
fields = form.cleaned_data["fields"]
|
||||
name_field = AttendeeProfile.name_field()
|
||||
|
||||
items = commerce.ProductItem.objects.filter(
|
||||
Q(product__in=products) | Q(product__category__in=categories),
|
||||
).exclude(
|
||||
cart__status=commerce.Cart.STATUS_RELEASED
|
||||
).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
|
||||
|
||||
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"
|
||||
|
||||
p = profiles.order_by(product, field).values(
|
||||
cart_status, product, product_name, category_name, field
|
||||
).annotate(count=Count("id"))
|
||||
output.append(ListReport(
|
||||
"Grouped by %s" % field_verbose,
|
||||
["Product", "Status", field_verbose, "count"],
|
||||
[
|
||||
(
|
||||
"%s - %s" % (i[category_name], i[product_name]),
|
||||
status_display[i[cart_status]],
|
||||
i[field],
|
||||
i["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
|
||||
data = []
|
||||
for item in items:
|
||||
profile = by_user[item.cart.user]
|
||||
line = [
|
||||
item.cart.user.id,
|
||||
getattr(profile, name_field),
|
||||
item.product,
|
||||
status_display[item.cart.status],
|
||||
] + [
|
||||
getattr(profile, field) for field in fields
|
||||
]
|
||||
data.append(line)
|
||||
|
||||
output.append(AttendeeListReport(
|
||||
"Attendees by item with profile data", headings, data, link_view=attendee
|
||||
))
|
||||
return output
|
||||
|
|
|
@ -43,6 +43,7 @@ public = [
|
|||
reports = [
|
||||
url(r"^$", rv.reports_list, name="reports_list"),
|
||||
url(r"^attendee/?$", rv.attendee, name="attendee"),
|
||||
url(r"^attendee_data/?$", rv.attendee_data, name="attendee_data"),
|
||||
url(r"^attendee/([0-9]*)$", rv.attendee, name="attendee"),
|
||||
url(r"^credit_notes/?$", rv.credit_notes, name="credit_notes"),
|
||||
url(r"^discount_status/?$", rv.discount_status, name="discount_status"),
|
||||
|
|
Loading…
Reference in a new issue