from django.views.generic import TemplateView, FormView, DetailView, UpdateView,\ ListView from django.http import HttpResponseRedirect from django.shortcuts import render from django.core.urlresolvers import reverse_lazy, reverse from django.contrib.auth.mixins import LoginRequiredMixin from django.conf import settings from django.contrib import messages from membership.models import StripeCustomer from utils.stripe_utils import StripeUtils from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin,\ SignupViewMixin from utils.forms import PasswordResetRequestForm from utils.mailer import BaseEmail from .forms import LoginForm, SignupForm, DonationForm, DonationBillingForm from .models import Donation, DonatorStatus class LandingView(TemplateView): template_name = "nosystemd/landing.html" def get_context_data(self, *args, **kwargs): allow_donation = self.request.user.is_anonymous() or \ (self.request.user.is_authenticated() and not DonatorStatus.objects.filter(user=self.request.user).exists()) total_donations_amount = Donation.get_total_donations_amount() context = { 'total_donations_amount': total_donations_amount, 'allow_donation': allow_donation } return context class LoginView(LoginViewMixin): template_name = "nosystemd/login.html" form_class = LoginForm success_url = reverse_lazy('nosystemd:landing') class SignupView(SignupViewMixin): template_name = "nosystemd/signup.html" form_class = SignupForm success_url = reverse_lazy('nosystemd:landing') class PasswordResetView(PasswordResetViewMixin): template_name = 'nosystemd/reset_password.html' success_url = reverse_lazy('nosystemd:login') form_class = PasswordResetRequestForm template_email_path = 'nosystemd/emails/' class PasswordResetConfirmView(PasswordResetConfirmViewMixin): template_name = 'nosystemd/confirm_reset_password.html' success_url = reverse_lazy('nosystemd:login') class DonationView(LoginRequiredMixin, FormView): template_name = 'nosystemd/donation.html' form_class = DonationBillingForm success_url = reverse_lazy('nosystemd:make_donation') def get_login_url(self): return "%s?next=%s" % (reverse('nosystemd:signup'), reverse('nosystemd:make_donation')) def get_context_data(self, **kwargs): context = super(DonationView, self).get_context_data(**kwargs) context.update({ 'stripe_key': settings.STRIPE_API_PUBLIC_KEY }) return context def get(self, request, *args, **kwargs): # if DonatorStatus.objects.filter(user=self.request.user).exists(): # messages.success(self.request, 'Your already are a monthly contributor') # return HttpResponseRedirect(reverse_lazy('nosystemd:donations')) return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): form = self.get_form() if form.is_valid(): context = self.get_context_data() token = form.cleaned_data.get('token') donation_amount = form.cleaned_data.get('donation_amount') # Get or create stripe customer customer = StripeCustomer.get_or_create(email=self.request.user.email, token=token) if not customer: form.add_error("__all__", "Invalid credit card") return self.render_to_response(self.get_context_data(form=form)) # Create Billing Address billing_address = form.save() # Make stripe charge to a customer stripe_utils = StripeUtils() stripe_utils.CURRENCY = 'usd' charge_response = stripe_utils.make_charge(amount=donation_amount, customer=customer.stripe_id) charge = charge_response.get('response_object') # Check if the payment was approved if not charge: context.update({ 'paymentError': charge_response.get('error'), 'form': form }) return render(request, self.template_name, context) # Create a donation charge = charge_response.get('response_object') donation_data = request.POST.copy() donation_data.update({ 'cc_brand': charge.source.brand, 'stripe_charge_id': charge.id, 'last4': charge.source.last4, 'billing_address': billing_address.id, 'donator': customer.id, 'donation': donation_amount }) donation_form = DonationForm(donation_data) if donation_form.is_valid(): # reactivate donation status donation = donation_form.save() try: donator_status = DonatorStatus.objects.get(user=self.request.user) donator_status.set_active() except DonatorStatus.DoesNotExist: pass donation = donation_form.save() context = { 'donation': donation, 'base_url': "{0}://{1}".format(request.scheme, request.get_host()) } email_data = { 'subject': 'Your donation have been charged', 'to': request.user.email, 'context': context, 'template_name': 'donation_charge', 'template_path': 'nosystemd/emails/' } email = BaseEmail(**email_data) email.send() return HttpResponseRedirect(reverse('nosystemd:donations', kwargs={'pk': donation.id})) else: self.form_invalid(donation_form) else: return self.form_invalid(form) class DonationDetailView(LoginRequiredMixin, DetailView): template_name = "nosystemd/donation_detail.html" context_object_name = "donation" login_url = reverse_lazy('nosystemd:login') model = Donation class DonationListView(LoginRequiredMixin, ListView): template_name = "nosystemd/donations.html" context_object_name = "donations" login_url = reverse_lazy('nosystemd:login') model = Donation paginate_by = 10 def get_context_data(self, **kwargs): context = super(DonationListView, self).get_context_data(**kwargs) status = None try: status = self.request.user.donatorstatus except DonatorStatus.DoesNotExist: pass context.update({ 'donator_status': status }) return context def get_queryset(self): queryset = super(DonationListView, self).get_queryset() queryset = queryset.filter(donator__user=self.request.user) return queryset class DonatorStatusDetailView(LoginRequiredMixin, TemplateView): template_name = "nosystemd/donator_status.html" login_url = reverse_lazy('nosystemd:login') model = DonatorStatus def get_context_data(self, **kwargs): context = super(DonatorStatusDetailView, self).get_context_data(**kwargs) context.update({ 'donator_status': self.request.user.donatorstatus if self.request.user.donatorstatus else None }) return context def get(self, request, *args, **kwargs): if not request.user.donatorstatus: HttpResponseRedirect('nosystemd:landing') return super(DonatorStatusDetailView, self).get(request, *args, **kwargs) class ChangeDonatorStatusDetailView(LoginRequiredMixin, UpdateView): template_name = "nosystemd/donator_status.html" context_object_name = "donator_status" login_url = reverse_lazy('nosystemd:login') model = DonatorStatus def get_object(self, queryset=None): return self.request.user.donatorstatus def post(self, *args, **kwargs): donator_status = self.get_object() donator_status.status = DonatorStatus.ACTIVE \ if donator_status.status == DonatorStatus.CANCELED else DonatorStatus.CANCELED donator_status.save() messages.success(self.request, 'Your monthly donation status has been changed.') return HttpResponseRedirect(reverse_lazy('nosystemd:donations'))