diff --git a/registrasion/reporting/__init__.py b/registrasion/reporting/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/registrasion/reporting/reports.py b/registrasion/reporting/reports.py new file mode 100644 index 00000000..799711b7 --- /dev/null +++ b/registrasion/reporting/reports.py @@ -0,0 +1,89 @@ +from collections import namedtuple + +from django.contrib.auth.decorators import user_passes_test +from django.core.urlresolvers import reverse +from django.db import models +from django.db.models import F, Q +from django.db.models import Sum +from django.db.models import Case, When, Value +from django.http import Http404 +from django.shortcuts import render +from functools import wraps + +from registrasion import forms +from registrasion import views +from registrasion.models import commerce +from registrasion.models import inventory + + +''' A list of report views objects that can be used to load a list of +reports. ''' +_all_report_views = [] + + +class Report(object): + + def __init__(self, title, headings, data): + self._headings = headings + self._data = data + + @property + def title(self): + ''' Returns the title for this report. ''' + return self._title + + @property + def headings(self): + ''' Returns the headings for the table. ''' + return self._headings + + @property + def data(self): + ''' Returns the data rows for the table. ''' + return self._data + + +def report_view(title, form_type): + ''' Decorator that converts a report view function into something that + displays a Report. + + Arguments: + title (str): + The title of the report. + form_type: + A form class that can make this report display things. + + ''' + + def _report(view): + + @wraps(view) + @user_passes_test(views._staff_only) + def inner_view(request, *a, **k): + + form = form_type(request.GET) + if form.is_valid() and form.has_changed(): + report = view(request, form, *a, **k) + else: + report = None + + ctx = { + "title": title, + "form": form, + "report": report, + } + + return render(request, "registrasion/report.html", ctx) + + # Add this report to the list of reports -- makes this reversable. + _all_report_views.append(inner_view) + + # Return the callable + return inner_view + return _report + + +def get_all_reports(): + ''' Returns all the views that have been registered with @report ''' + + return list(_all_report_views) diff --git a/registrasion/staff_views.py b/registrasion/staff_views.py index c07c5a92..96ade521 100644 --- a/registrasion/staff_views.py +++ b/registrasion/staff_views.py @@ -16,87 +16,8 @@ from functools import wraps from models import commerce from models import inventory - -''' - -All reports must be viewable by staff only (permissions?) - -Reports can have: - -A form - * Reports are all *gettable* - you can save a URL and get back to the same - report - * Fetching a report *cannot* break the underlying data. -A table - * Headings - * Data lines - * Formats are pluggable - -''' - - -class Report(object): - - def __init__(self, title, headings, data): - self._headings = headings - self._data = data - - @property - def title(self): - ''' Returns the title for this report. ''' - return self._title - - @property - def headings(self): - ''' Returns the headings for the table. ''' - return self._headings - - @property - def data(self): - ''' Returns the data rows for the table. ''' - return self._data - - -''' A list of report views objects that can be used to load a list of -reports. ''' -_all_report_views = [] - - -def report(title, form_type): - ''' Decorator that converts a report view function into something that - displays a Report. - - Arguments: - form_type: A form class that can make this report display things. - - ''' - - def _report(view): - - @wraps(view) - @user_passes_test(views._staff_only) - def inner_view(request, *a, **k): - - form = form_type(request.GET) - if form.is_valid() and form.has_changed(): - report = view(request, form, *a, **k) - else: - report = None - - ctx = { - "title": title, - "form": form, - "report": report, - } - - return render(request, "registrasion/report.html", ctx) - - # Add this report to the list of reports -- makes this reversable. - _all_report_views.append(inner_view) - - # Return the callable - return inner_view - return _report +from reporting.reports import Report +from reporting.reports import report_view @user_passes_test(views._staff_only) @@ -118,15 +39,13 @@ def reports_list(request): "reports" : reports, } - print reports - return render(request, "registrasion/reports_list.html", ctx) # Report functions -@report("Paid items", forms.ProductAndCategoryForm) +@report_view("Paid items", forms.ProductAndCategoryForm) def items_sold(request, form): ''' Summarises the items sold and discounts granted for a given set of products, or products from categories. ''' @@ -172,7 +91,7 @@ def items_sold(request, form): return Report("Paid items", headings, data) -@report("Inventory", forms.ProductAndCategoryForm) +@report_view("Inventory", forms.ProductAndCategoryForm) def inventory(request, form): ''' Summarises the inventory status of the given items, grouping by invoice status. '''