parent
e3b662fb67
commit
2ed0a47f15
3 changed files with 119 additions and 4 deletions
|
@ -29,3 +29,22 @@ class UserIdForm(forms.Form):
|
||||||
label="User ID",
|
label="User ID",
|
||||||
required=False,
|
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)
|
@report_view("Attendee", form_type=forms.UserIdForm)
|
||||||
def attendee(request, form, user_id=None):
|
def attendee(request, form, user_id=None):
|
||||||
''' Returns a list of all manifested attendees if no attendee is specified,
|
''' 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.
|
# Sort by whether they've registered, then ID.
|
||||||
data.sort(key=lambda a: (-a[3], a[0]))
|
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 = [
|
reports = [
|
||||||
url(r"^$", rv.reports_list, name="reports_list"),
|
url(r"^$", rv.reports_list, name="reports_list"),
|
||||||
url(r"^attendee/?$", rv.attendee, name="attendee"),
|
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"^attendee/([0-9]*)$", rv.attendee, name="attendee"),
|
||||||
url(r"^credit_notes/?$", rv.credit_notes, name="credit_notes"),
|
url(r"^credit_notes/?$", rv.credit_notes, name="credit_notes"),
|
||||||
url(r"^discount_status/?$", rv.discount_status, name="discount_status"),
|
url(r"^discount_status/?$", rv.discount_status, name="discount_status"),
|
||||||
|
|
Loading…
Reference in a new issue