Makes the reporting framework a bit more DRY.
This commit is contained in:
		
							parent
							
								
									3607fb19b8
								
							
						
					
					
						commit
						32b887fed3
					
				
					 1 changed files with 97 additions and 107 deletions
				
			
		|  | @ -31,22 +31,15 @@ A table | ||||||
| 
 | 
 | ||||||
| class Report(object): | class Report(object): | ||||||
| 
 | 
 | ||||||
|     def __init__(self, title, form, headings, data): |     def __init__(self, title, headings, data): | ||||||
|         self._title = title |  | ||||||
|         self._form = form |  | ||||||
|         self._headings = headings |         self._headings = headings | ||||||
|         self._data = data |         self._data = data | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def title(self): |     def title(self): | ||||||
|         ''' Returns the form. ''' |         ''' Returns the title for this report. ''' | ||||||
|         return self._title |         return self._title | ||||||
| 
 | 
 | ||||||
|     @property |  | ||||||
|     def form(self): |  | ||||||
|         ''' Returns the form. ''' |  | ||||||
|         return self._form |  | ||||||
| 
 |  | ||||||
|     @property |     @property | ||||||
|     def headings(self): |     def headings(self): | ||||||
|         ''' Returns the headings for the table. ''' |         ''' Returns the headings for the table. ''' | ||||||
|  | @ -58,139 +51,136 @@ class Report(object): | ||||||
|         return self._data |         return self._data | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def report(view): | def report(title, form_type): | ||||||
|     ''' Decorator that converts a report view function into something that |     ''' Decorator that converts a report view function into something that | ||||||
|     displays a Report. |     displays a Report. | ||||||
| 
 | 
 | ||||||
|  |     Arguments: | ||||||
|  |         form_type: A form class that can make this report display things. | ||||||
|  | 
 | ||||||
|     ''' |     ''' | ||||||
| 
 | 
 | ||||||
|     @wraps(view) |     def _report(view): | ||||||
|     def inner_view(request, *a, **k): |  | ||||||
|         report = view(request, *a, **k) |  | ||||||
| 
 | 
 | ||||||
|         ctx = { |         @wraps(view) | ||||||
|             "title": report.title, |         def inner_view(request, *a, **k): | ||||||
|             "form": report.form, |  | ||||||
|             "report": report, |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         return render(request, "registrasion/report.html", ctx) |             form = form_type(request.GET) | ||||||
|  |             if form.is_valid() and form.has_changed(): | ||||||
|  |                 report = view(request, form, *a, **k) | ||||||
|  |             else: | ||||||
|  |                 report = None | ||||||
| 
 | 
 | ||||||
|     return inner_view |             ctx = { | ||||||
|  |                 "title": title, | ||||||
|  |                 "form": form, | ||||||
|  |                 "report": report, | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return render(request, "registrasion/report.html", ctx) | ||||||
|  | 
 | ||||||
|  |         return inner_view | ||||||
|  |     return _report | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @report | @report("Paid items", forms.ProductAndCategoryForm) | ||||||
| def items_sold(request): | def items_sold(request, form): | ||||||
|     ''' Summarises the items sold and discounts granted for a given set of |     ''' Summarises the items sold and discounts granted for a given set of | ||||||
|     products, or products from categories. ''' |     products, or products from categories. ''' | ||||||
| 
 | 
 | ||||||
|     title = "Paid items" |  | ||||||
| 
 |  | ||||||
|     form = forms.ProductAndCategoryForm(request.GET) |  | ||||||
| 
 |  | ||||||
|     data = None |     data = None | ||||||
|     headings = None |     headings = None | ||||||
| 
 | 
 | ||||||
|     if form.is_valid() and form.has_changed(): |     products = form.cleaned_data["product"] | ||||||
|         products = form.cleaned_data["product"] |     categories = form.cleaned_data["category"] | ||||||
|         categories = form.cleaned_data["category"] |  | ||||||
| 
 | 
 | ||||||
|         line_items = commerce.LineItem.objects.filter( |     line_items = commerce.LineItem.objects.filter( | ||||||
|             Q(product__in=products) | Q(product__category__in=categories), |         Q(product__in=products) | Q(product__category__in=categories), | ||||||
|             invoice__status=commerce.Invoice.STATUS_PAID, |         invoice__status=commerce.Invoice.STATUS_PAID, | ||||||
|         ).select_related("invoice") |     ).select_related("invoice") | ||||||
| 
 | 
 | ||||||
|         line_items = line_items.order_by( |     line_items = line_items.order_by( | ||||||
|             # sqlite requires an order_by for .values() to work |         # sqlite requires an order_by for .values() to work | ||||||
|             "-price", "description", |         "-price", "description", | ||||||
|         ).values( |     ).values( | ||||||
|             "price", "description", |         "price", "description", | ||||||
|         ).annotate( |     ).annotate( | ||||||
|             total_quantity=Sum("quantity"), |         total_quantity=Sum("quantity"), | ||||||
|         ) |     ) | ||||||
| 
 | 
 | ||||||
|         print line_items |     print line_items | ||||||
| 
 | 
 | ||||||
|         headings = ["Description", "Quantity", "Price", "Total"] |     headings = ["Description", "Quantity", "Price", "Total"] | ||||||
| 
 |  | ||||||
|         data = [] |  | ||||||
|         total_income = 0 |  | ||||||
|         for line in line_items: |  | ||||||
|             cost = line["total_quantity"] * line["price"] |  | ||||||
|             data.append([ |  | ||||||
|                 line["description"], line["total_quantity"], |  | ||||||
|                 line["price"], cost, |  | ||||||
|             ]) |  | ||||||
|             total_income += cost |  | ||||||
| 
 | 
 | ||||||
|  |     data = [] | ||||||
|  |     total_income = 0 | ||||||
|  |     for line in line_items: | ||||||
|  |         cost = line["total_quantity"] * line["price"] | ||||||
|         data.append([ |         data.append([ | ||||||
|             "(TOTAL)", "--", "--", total_income, |             line["description"], line["total_quantity"], | ||||||
|  |             line["price"], cost, | ||||||
|         ]) |         ]) | ||||||
|  |         total_income += cost | ||||||
| 
 | 
 | ||||||
|     return Report(title, form, headings, data) |     data.append([ | ||||||
|  |         "(TOTAL)", "--", "--", total_income, | ||||||
|  |     ]) | ||||||
|  | 
 | ||||||
|  |     return Report("Paid items", headings, data) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @report | @report("Inventory", forms.ProductAndCategoryForm) | ||||||
| def inventory(request): | def inventory(request, form): | ||||||
|     ''' Summarises the inventory status of the given items, grouping by |     ''' Summarises the inventory status of the given items, grouping by | ||||||
|     invoice status. ''' |     invoice status. ''' | ||||||
| 
 | 
 | ||||||
|     title = "Inventory" |     products = form.cleaned_data["product"] | ||||||
|  |     categories = form.cleaned_data["category"] | ||||||
| 
 | 
 | ||||||
|     form = forms.ProductAndCategoryForm(request.GET) |     items = commerce.ProductItem.objects.filter( | ||||||
|  |         Q(product__in=products) | Q(product__category__in=categories), | ||||||
|  |     ).select_related("cart", "product") | ||||||
| 
 | 
 | ||||||
|     data = None |     # TODO annotate with whether the item is reserved or not. | ||||||
|     headings = None |  | ||||||
| 
 | 
 | ||||||
|     if form.is_valid() and form.has_changed(): |     items = items.annotate(is_reserved=Case( | ||||||
|         products = form.cleaned_data["product"] |         When(cart__in=commerce.Cart.reserved_carts(), then=Value(1)), | ||||||
|         categories = form.cleaned_data["category"] |         default=Value(0), | ||||||
|  |         output_field=models.BooleanField(), | ||||||
|  |     )) | ||||||
| 
 | 
 | ||||||
|         items = commerce.ProductItem.objects.filter( |     items = items.order_by( | ||||||
|             Q(product__in=products) | Q(product__category__in=categories), |         "cart__status", | ||||||
|         ).select_related("cart", "product") |         "product__category__order", | ||||||
|  |         "product__order", | ||||||
|  |     ).values( | ||||||
|  |         "product", | ||||||
|  |         "product__category__name", | ||||||
|  |         "product__name", | ||||||
|  |         "cart__status", | ||||||
|  |         "is_reserved", | ||||||
|  |     ).annotate( | ||||||
|  |         total_quantity=Sum("quantity"), | ||||||
|  |     ) | ||||||
| 
 | 
 | ||||||
|         # TODO annotate with whether the item is reserved or not. |     headings = ["Product", "Status", "Quantity"] | ||||||
|  |     data = [] | ||||||
| 
 | 
 | ||||||
|         items = items.annotate(is_reserved=Case( |     def status(reserved, status): | ||||||
|             When(cart__in=commerce.Cart.reserved_carts(), then=Value(1)), |         r = "Reserved" if reserved else "Unreserved" | ||||||
|             default=Value(0), |         # This is a bit weird -- can we simplify? | ||||||
|             output_field=models.BooleanField(), |         s = "".join( | ||||||
|         )) |             "%s" % i[1] for i in commerce.Cart.STATUS_TYPES if i[0]==status | ||||||
| 
 |  | ||||||
|         items = items.order_by( |  | ||||||
|             "cart__status", |  | ||||||
|             "product__category__order", |  | ||||||
|             "product__order", |  | ||||||
|         ).values( |  | ||||||
|             "product", |  | ||||||
|             "product__category__name", |  | ||||||
|             "product__name", |  | ||||||
|             "cart__status", |  | ||||||
|             "is_reserved", |  | ||||||
|         ).annotate( |  | ||||||
|             total_quantity=Sum("quantity"), |  | ||||||
|         ) |         ) | ||||||
|  |         return "%s - %s" % (r, s) | ||||||
| 
 | 
 | ||||||
|         headings = ["Product", "Status", "Quantity"] |     for item in items: | ||||||
|         data = [] |         data.append([ | ||||||
|  |             "%s - %s" % ( | ||||||
|  |                 item["product__category__name"], item["product__name"] | ||||||
|  |             ), | ||||||
|  |             status(item["is_reserved"], item["cart__status"]), | ||||||
|  |             item["total_quantity"], | ||||||
|  |         ]) | ||||||
| 
 | 
 | ||||||
|         def status(reserved, status): |     return Report("Inventory", headings, data) | ||||||
|             r = "Reserved" if reserved else "Unreserved" |  | ||||||
|             s = "".join( |  | ||||||
|                 "%s" % i[1] |  | ||||||
|                 for i in commerce.Cart.STATUS_TYPES if i[0]==status |  | ||||||
|             ) |  | ||||||
|             return "%s - %s" % (r, s) |  | ||||||
| 
 |  | ||||||
|         for item in items: |  | ||||||
|             print commerce.Cart.STATUS_TYPES |  | ||||||
|             data.append([ |  | ||||||
|                 "%s - %s" % ( |  | ||||||
|                     item["product__category__name"], item["product__name"] |  | ||||||
|                 ), |  | ||||||
|                 status(item["is_reserved"], item["cart__status"]), |  | ||||||
|                 item["total_quantity"], |  | ||||||
|             ]) |  | ||||||
| 
 |  | ||||||
|     return Report(title, form, headings, data) |  | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Christopher Neugebauer
						Christopher Neugebauer