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…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer