1 from decimal import Decimal, ROUND_DOWN
2 from datetime import datetime, timedelta
5 from django.core.urlresolvers import reverse
6 from django.shortcuts import render_to_response
7 from django.template import RequestContext
8 from django.utils.safestring import mark_safe
9 from django.views.generic import ListView
11 from django_tables2 import Table, Column, LinkColumn
12 from django_tables2.utils import A
13 from django_tables2.views import SingleTableMixin
15 from .models import Company, Person, Ticker, Transaction
18 class NumberColumn(Column):
20 def _format_integer(integer, sep=','):
21 """Pretty-print an integer at thousands, millions, etc.
23 >>> NumberColumn._format_integer(1234567)
25 >>> NumberColumn._format_integer(-123456)
27 >>> NumberColumn._format_integer(1234567, sep=' ')
33 string = '{:d}'.format(abs(integer))
34 return sign + sep.join(re.findall('(.{1,3})', string[::-1]))[::-1]
36 def render(self, value):
39 classes.append('negative')
41 classes.append('positive')
42 if isinstance(value, Decimal):
43 integer = int(value.quantize(Decimal('1.'), rounding=ROUND_DOWN))
44 decimal = int(abs(value - integer) * 100)
45 value = '{}.{:02d}'.format(self._format_integer(integer), decimal)
46 elif isinstance(value, int):
47 value = self._format_integer(value)
49 raise NotImplementedError(type(value))
50 return mark_safe(u'<span class="{}">{}</span>'.format(
51 u' '.join(classes), value))
54 class TransactionTable(Table):
55 id = LinkColumn('transaction', args=[A('pk')])
56 person = LinkColumn('person', args=[A('person.pk')])
58 'date', kwargs=dict((x, A('date.{}'.format(x)))
59 for x in ['year', 'month', 'day']))
60 ticker = LinkColumn('ticker', args=[A('ticker.pk')])
61 shares = NumberColumn()
62 value = NumberColumn()
68 def render_source(self, value):
69 return mark_safe(u'<a href="{}">source</a>'.format(value))
72 class TransactionTableView(SingleTableMixin, ListView):
74 table_class = TransactionTable
77 def _detail(request, title, transactions):
78 table = TransactionTable(transactions, order_by=request.GET.get('sort'))
79 table.paginate(page=request.GET.get('page', 1))
80 return render_to_response(
81 'table.html', {'title': title, 'table': table},
82 context_instance=RequestContext(request))
84 def company(request, pk):
85 tickers = Ticker.objects.filter(company__id=pk)
86 #tks = [ticker.pk for ticker in tickers]
87 return _detail(request, Company.objects.get(pk=pk),
88 Transaction.objects.filter(ticker__in=tickers))
90 def person(request, pk):
91 return _detail(request, Person.objects.get(pk=pk),
92 Transaction.objects.filter(person__id=pk))
94 def ticker(request, pk):
95 ticker = Ticker.objects.get(pk=pk)
96 company = ticker.company
97 url = reverse('company', args=[company.id])
98 title = mark_safe(u'{} (<a href="{}">{}</a>)'.format(
99 ticker, url, company))
100 return _detail(request, title, Transaction.objects.filter(ticker__id=pk))
102 def date(request, **kwargs):
103 for k,v in kwargs.items():
105 date = datetime(**kwargs)
106 next_date = date.date() + timedelta(days=1)
107 return _detail(request, date.date().isoformat(),
108 Transaction.objects.filter(date__range=(date,next_date)))