Index: remit/finance_core/urls.py
===================================================================
--- remit/finance_core/urls.py	(revision 92ca60ed46c225b17cbff5fcda7a045dd5710fae)
+++ remit/finance_core/urls.py	(revision ed4ccc7840c928311d1f921509bbfb9c2e58e1f1)
@@ -4,3 +4,4 @@
 urlpatterns = patterns('',
     (r'^display_accounts', finance_core.views.display_tree),
+    url(r'reporting/', finance_core.views.reporting, name='reporting', ),
 )
Index: remit/finance_core/views.py
===================================================================
--- remit/finance_core/views.py	(revision 86817cf18a4910cba5d699ae6f8adaf84ef374cf)
+++ remit/finance_core/views.py	(revision ed4ccc7840c928311d1f921509bbfb9c2e58e1f1)
@@ -1,6 +1,71 @@
 from django.http import HttpResponse
 import finance_core.models
+from django.contrib.auth.decorators import user_passes_test
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+from django.http import Http404, HttpResponseRedirect
+from django.db.models import Q, Sum
+from decimal import Decimal
 
 def display_tree(request):
     root = finance_core.models.BudgetArea.get_by_path(['Accounts'])
     return HttpResponse(root.dump_to_html())
+
+def reporting(request):
+    line_items = finance_core.models.LineItem.objects.all()
+    term_name = 'All'
+    if 'term' in request.REQUEST:
+        term_obj = get_object_or_404(finance_core.models.BudgetTerm, slug=request.REQUEST['term'])
+        term_name = term_obj.name
+        line_items = line_items.filter(budget_term=term_obj)
+    if 'area' in request.REQUEST:
+        base_area_obj = get_object_or_404(finance_core.models.BudgetArea, pk=request.REQUEST['area'])
+    else:
+        base_area_obj = finance_core.models.BudgetArea.get_by_path(['Accounts'])
+    line_items = line_items.filter(budget_area__in=base_area_obj.get_descendants())
+    base_area_depth = base_area_obj.depth
+    print base_area_obj
+
+    primary_name = 'Budget Areas'
+    primary_axis = [
+        (area.indented_name(base_area_depth), Q(budget_area=area), ) for area in base_area_obj.get_descendants()
+    ]
+    secondary_name = 'Layers'
+    secondary_axis = [ (finance_core.models.layer_name(layer), Q(layer=finance_core.models.layer_num(layer)), ) for layer in finance_core.models.layers ]
+
+    primary_axis.append(('Total', Q(), ))
+    secondary_axis.append(('Total', Q(), ))
+
+    primary_labels = [ primary[0] for primary in primary_axis ]
+    secondary_labels = [ secondary[0] for secondary in secondary_axis ]
+
+    zero = Decimal('0.00')
+    def total_amount(queryset):
+        amount = queryset.aggregate(Sum('amount'))['amount__sum']
+        if amount is None: return zero
+        else: return amount
+    table = [ # Primary axis
+            [ # Secondary axis
+                total_amount(line_items.filter(primary[1], secondary[1]))
+            for secondary in secondary_axis]
+        for primary in primary_axis]
+
+    debug = False
+    if debug:
+        from django.db import connection
+        print connection.queries
+        print "Number of queries:\t%d" % (len(connection.queries),)
+        print "Table size:\t%dx%d" % (len(primary_labels), len(secondary_labels), )
+
+    context = {
+        'pagename':'reporting',
+        'term_name': term_name,
+        'area': base_area_obj,
+        'primary_name': primary_name,
+        'secondary_name': secondary_name,
+        'primary_labels': primary_labels,
+        'secondary_labels': secondary_labels,
+        'table': table,
+        'table_with_row_labels': zip(primary_labels, table),
+    }
+    return render_to_response('finance_core/reporting.html', context, context_instance=RequestContext(request), )
Index: remit/media/style/style.css
===================================================================
--- remit/media/style/style.css	(revision f114f8bb2e70d64e4c1d94449d637a86e1e7d924)
+++ remit/media/style/style.css	(revision ed4ccc7840c928311d1f921509bbfb9c2e58e1f1)
@@ -78,2 +78,13 @@
     background: #F88;
 }
+
+table.money-table td
+{
+    text-align: right;
+}
+table.money-table th
+{
+    white-space: pre-wrap;
+    text-align: left;
+    font-weight: normal;
+}
Index: remit/remit_templates/base.html
===================================================================
--- remit/remit_templates/base.html	(revision 3a0c51b887d800089162a9247b1e52d5948fce2b)
+++ remit/remit_templates/base.html	(revision ed4ccc7840c928311d1f921509bbfb9c2e58e1f1)
@@ -16,4 +16,5 @@
         <li{% ifequal pagename "list_requests" %} class='selected'{% endifequal %}><a href="{% url list_requests %}">List requests</a></li>
         {% endif %}
+        <li{% ifequal pagename "reporting" %} class='selected'{% endifequal %}><a href="{% url reporting %}">Reporting</a></li>
     </ul>
     <div id='content'>
Index: remit/remit_templates/finance_core/reporting.html
===================================================================
--- remit/remit_templates/finance_core/reporting.html	(revision ed4ccc7840c928311d1f921509bbfb9c2e58e1f1)
+++ remit/remit_templates/finance_core/reporting.html	(revision ed4ccc7840c928311d1f921509bbfb9c2e58e1f1)
@@ -0,0 +1,42 @@
+{% extends "base.html" %}
+{% load misc %}
+
+{% block title %}Reporting{% endblock %}
+{% block content %}
+
+<h2>Reporting</h2>
+
+<h3>Parameters</h3>
+
+<table class='pretty-table'>
+<tr>
+    <th>Term</th>
+    <td>{{term_name}}</td>
+</tr>
+<tr>
+    <th>Budget Area</th>
+    <td>{{area}}</td>
+</tr>
+</table>
+
+<h3>Data</h3>
+
+<table class='pretty-table money-table'>
+<tr>
+    <th></th>
+{% for label in secondary_labels %}
+    <th>{{label}}</th>
+{% endfor %}
+</tr>
+{% for label, row in table_with_row_labels %}
+<tr>
+    <th>{{label}}</th>
+    {% for cell in row %}
+    <td>{% if cell %}<strong>{% endif %}${{cell}}{% if cell %}</strong>{% endif %}</td>
+    {% endfor %}
+</tr>
+{% endfor %}
+
+</table>
+
+{% endblock %}
