7bc8226771b580fc0e68ac68e11bb30f204180c2
[wolnelektury.git] / apps / funding / views.py
1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 #
5 from datetime import date
6 from django.views.decorators.cache import never_cache
7 from django.conf import settings
8 from django.core.urlresolvers import reverse
9 from django.http import Http404
10 from django.shortcuts import redirect, get_object_or_404
11 from django.utils.decorators import method_decorator
12 from django.views.generic import TemplateView, FormView, DetailView, ListView
13 import getpaid.backends.payu
14 from getpaid.models import Payment
15 from .forms import FundingForm
16 from .models import Offer, Spent, Funding
17
18
19 def mix(*streams):
20     substreams = []
21     for stream, read_date, tag in streams:
22         iterstream = iter(stream)
23         try:
24             item = next(iterstream)
25         except StopIteration:
26             pass
27         else:
28             substreams.append([read_date(item), item, iterstream, read_date, tag])
29     while substreams:
30         i, substream = max(enumerate(substreams), key=lambda x: x[1][0])
31         yield substream[4], substream[1]
32         try:
33             item = next(substream[2])
34         except StopIteration:
35             del substreams[i]
36         else:
37             substream[0:2] = [substream[3](item), item]
38
39
40 class WLFundView(TemplateView):
41     template_name = "funding/wlfund.html"
42
43     def get_context_data(self):
44         def add_total(total, it):
45             for tag, e in it:
46                 e.total = total
47                 if tag == 'spent':
48                     total += e.amount
49                 else:
50                     total -= e.wlfund
51                 yield tag, e
52
53         ctx = super(WLFundView, self).get_context_data()
54         offers = []
55         
56         for o in Offer.past():
57             if o.is_win():
58                 o.wlfund = o.sum() - o.target
59                 if o.wlfund > 0:
60                     offers.append(o)
61             else:
62                 o.wlfund = o.sum()
63                 if o.wlfund > 0:
64                     offers.append(o)
65         amount = sum(o.wlfund for o in offers) - sum(o.amount for o in Spent.objects.all())
66         print offers
67
68         ctx['amount'] = amount
69         ctx['log'] = add_total(amount, mix(
70             (offers, lambda x: x.end, 'offer'),
71             (Spent.objects.all(), lambda x: x.timestamp, 'spent'),
72         ))
73         return ctx
74
75
76 class OfferDetailView(FormView):
77     form_class = FundingForm
78     template_name = "funding/offer_detail.html"
79     backend = 'getpaid.backends.payu'
80
81     def dispatch(self, request, slug=None):
82         if getattr(self, 'object', None) is None:
83             if slug:
84                 self.object = get_object_or_404(Offer.public(), slug=slug)
85             else:
86                 self.object = Offer.current()
87                 if self.object is None:
88                     raise Http404
89         return super(OfferDetailView, self).dispatch(request, slug)
90
91     def get_form(self, form_class):
92         if self.request.method == 'POST':
93             return form_class(self.object, self.request.POST)
94         else:
95             return form_class(self.object, initial={'amount': settings.FUNDING_DEFAULT})
96
97     def get_context_data(self, *args, **kwargs):
98         ctx = super(OfferDetailView, self).get_context_data(*args, **kwargs)
99         ctx['object'] = self.object
100         if self.object.is_current():
101             ctx['funding_no_show_current'] = True
102         return ctx
103
104     def form_valid(self, form):
105         funding = form.save()
106         # Skip getpaid.forms.PaymentMethodForm, go directly to the broker.
107         payment = Payment.create(funding, self.backend)
108         gateway_url_tuple = payment.get_processor()(payment).get_gateway_url(self.request)
109         payment.change_status('in_progress')
110         return redirect(gateway_url_tuple[0])
111
112
113 class CurrentView(OfferDetailView):
114     def dispatch(self, request, slug=None):
115         self.object = Offer.current()
116         if self.object is None:
117             raise Http404
118         elif slug != self.object.slug:
119             return redirect(reverse('funding_current', args=[self.object.slug]))
120         return super(CurrentView, self).dispatch(request, slug)
121
122
123 class OfferListView(ListView):
124     queryset = Offer.public()
125
126     def get_context_data(self, *args, **kwargs):
127         ctx = super(OfferListView, self).get_context_data(*args, **kwargs)
128         ctx['funding_no_show_current'] = True
129         return ctx
130
131
132 class ThanksView(TemplateView):
133     template_name = "funding/thanks.html"
134
135     def get_context_data(self, *args, **kwargs):
136         ctx = super(ThanksView, self).get_context_data(*args, **kwargs)
137         ctx['offer'] = Offer.current()
138         ctx['funding_no_show_current'] = True
139         return ctx
140
141 class NoThanksView(TemplateView):
142     template_name = "funding/no_thanks.html"