From f3e419d66d07b3ca6e718248a912944362d833c0 Mon Sep 17 00:00:00 2001 From: Christopher Neugebauer Date: Tue, 13 Sep 2016 15:32:55 +1000 Subject: [PATCH] Refactors reports so that rendering of links is done within Python code, not templates. --- registrasion/reporting/reports.py | 87 +++++++++++++++++++++++++++---- registrasion/reporting/views.py | 22 ++++---- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/registrasion/reporting/reports.py b/registrasion/reporting/reports.py index e756622e..2dc35d1d 100644 --- a/registrasion/reporting/reports.py +++ b/registrasion/reporting/reports.py @@ -1,5 +1,6 @@ from django.contrib.auth.decorators import user_passes_test from django.shortcuts import render +from django.core.urlresolvers import reverse from functools import wraps from registrasion import views @@ -12,35 +13,94 @@ _all_report_views = [] class Report(object): + def __init__(self): + pass + + def title(): + raise NotImplementedError + + def headings(): + ''' Returns the headings for the report. ''' + raise NotImplementedError + + def rows(content_type): + ''' + + Arguments: + content_type (str): The content-type for the output format of this + report. + + Returns: + An iterator, which yields each row of the data. Each row should + be an iterable containing the cells, rendered appropriately for + content_type. + ''' + raise NotImplementedError + + def _linked_text(self, content_type, address, text): + ''' + + Returns: + an HTML linked version of text, if the content_type for this report + is HTMLish, otherwise, the text. + ''' + + if content_type == "text/html": + return Report._html_link(address, text) + + @staticmethod + def _html_link(address, text): + return '%s' % (address, text) + + +class ReportTemplateWrapper(object): + + def __init__(self, content_type, report): + self.content_type = content_type + self.report = report + + def title(self): + return self.report.title() + + def headings(self): + return self.report.headings() + + def rows(self): + return self.report.rows(self.content_type) + + +class OldReport(Report): + def __init__(self, title, headings, data, link_view=None): + super(OldReport, self).__init__() self._title = title self._headings = headings self._data = data self._link_view = link_view - @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): + def rows(self, content_type): ''' Returns the data rows for the table. ''' - return self._data - @property - def link_view(self): - ''' Returns the URL name or the view callable that can be used to - view the row's detail. The left-most value is passed into `reverse` - as an argument. ''' + def cell_text(index, text): + if index > 0 or not self._link_view: + return text + else: + address = reverse(self._link_view, args=[text]) + return self._linked_text(content_type, address, text) - return self._link_view + for row in self._data: + yield [cell_text(i, cell) for i, cell in enumerate(row)] + def _get_link(self, argument): + return reverse(self._link_view, argument) def report_view(title, form_type=None): ''' Decorator that converts a report view function into something that @@ -72,6 +132,11 @@ def report_view(title, form_type=None): if isinstance(reports, Report): reports = [reports] + reports = [ + ReportTemplateWrapper("text/html", report) + for report in reports + ] + ctx = { "title": title, "form": form, diff --git a/registrasion/reporting/views.py b/registrasion/reporting/views.py index 962b7071..6a5522a5 100644 --- a/registrasion/reporting/views.py +++ b/registrasion/reporting/views.py @@ -14,7 +14,7 @@ from registrasion.models import people from registrasion import views from reports import get_all_reports -from reports import Report +from reports import OldReport from reports import report_view @@ -90,7 +90,7 @@ def items_sold(request, form): "(TOTAL)", "--", "--", total_income, ]) - return Report("Paid items", headings, data) + return OldReport("Paid items", headings, data) @report_view("Reconcilitation") @@ -128,7 +128,7 @@ def reconciliation(request, form): sales["total"] - payments["total"] - ucn["total"], ]) - return Report("Sales and Payments", headings, data) + return OldReport("Sales and Payments", headings, data) @report_view("Product status", form_type=forms.ProductAndCategoryForm) @@ -211,7 +211,7 @@ def product_status(request, form): item["total_refunded"], ]) - return Report("Inventory", headings, data) + return OldReport("Inventory", headings, data) @report_view("Credit notes") @@ -238,7 +238,7 @@ def credit_notes(request, form): note.value, ]) - return Report("Credit Notes", headings, data, link_view="credit_note") + return OldReport("Credit Notes", headings, data, link_view="credit_note") @report_view("Attendee", form_type=forms.UserIdForm) @@ -269,7 +269,7 @@ def attendee(request, form, user_id=None): pq.quantity, ]) - reports.append(Report("Paid Products", headings, data)) + reports.append(OldReport("Paid Products", headings, data)) # Unpaid products headings = ["Product", "Quantity"] @@ -281,7 +281,7 @@ def attendee(request, form, user_id=None): pq.quantity, ]) - reports.append( Report("Unpaid Products", headings, data)) + reports.append( OldReport("Unpaid Products", headings, data)) # Invoices headings = ["Invoice ID", "Status", "Value"] @@ -295,7 +295,7 @@ def attendee(request, form, user_id=None): invoice.id, invoice.get_status_display(), invoice.value, ]) - reports.append(Report("Invoices", headings, data, link_view="invoice")) + reports.append(OldReport("Invoices", headings, data, link_view="invoice")) # Credit Notes headings = ["Note ID", "Status", "Value"] @@ -310,7 +310,7 @@ def attendee(request, form, user_id=None): ]) reports.append( - Report("Credit Notes", headings, data, link_view="credit_note") + OldReport("Credit Notes", headings, data, link_view="credit_note") ) # All payments @@ -326,7 +326,7 @@ def attendee(request, form, user_id=None): ]) reports.append( - Report("Payments", headings, data, link_view="invoice") + OldReport("Payments", headings, data, link_view="invoice") ) @@ -364,4 +364,4 @@ def attendee_list(request): # Sort by whether they've registered, then ID. data.sort(key=lambda attendee: (-attendee[3], attendee[0])) - return Report("Attendees", headings, data, link_view="attendee") + return OldReport("Attendees", headings, data, link_view="attendee")