Added DonatorStatus model in order to know if an donator has canceled or not his monthly donation, Now we create a DonatorStatus for the user after receiving his first donation. Added DonatorStatus view. Added donator_status.html in order to allow an user view his donation status , Added action to allow user to cancel his monthly donations. Now the user can logout using navbar. added Donation model to admin.Added command make_donations_charges in order to create stripe current monthly donations from all donators
This commit is contained in:
		
					parent
					
						
							
								cb520f6b58
							
						
					
				
			
			
				commit
				
					
						4580a75f89
					
				
			
		
					 22 changed files with 611 additions and 232 deletions
				
			
		|  | @ -1,21 +0,0 @@ | |||
| from .base import * | ||||
| REGISTRATION_MESSAGE['message'] = REGISTRATION_MESSAGE['message'].format(host='dynamicweb-development.ungleich.ch',slug='{slug}') | ||||
| ALLOWED_HOSTS = [ | ||||
|     "*" | ||||
|     ] | ||||
| 
 | ||||
| EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' | ||||
| 
 | ||||
| CACHES = { | ||||
|     'default': { | ||||
|         'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', | ||||
|         'LOCATION': 'unique-snowflake' | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| MIDDLEWARE_CLASSES+=("debug_toolbar.middleware.DebugToolbarMiddleware",) | ||||
| 
 | ||||
| INSTALLED_APPS+=( | ||||
|     'django_extensions', | ||||
|     'debug_toolbar' | ||||
|     ) | ||||
|  | @ -3,7 +3,6 @@ from django.utils.html import format_html | |||
| from django.core.urlresolvers import reverse | ||||
| 
 | ||||
| from utils.mailer import BaseEmail | ||||
| from utils.stripe_utils import StripeUtils | ||||
| 
 | ||||
| from .forms import HostingOrderAdminForm | ||||
| from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder | ||||
|  |  | |||
|  | @ -56,7 +56,7 @@ $( document ).ready(function() { | |||
| 
 | ||||
|                 //set token  on a hidden input
 | ||||
|                 $('#id_token').val(token); | ||||
|                 $('#billing-form').submit(); | ||||
|                 $('#donation-form').submit(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  |  | |||
|  | @ -1,3 +1,22 @@ | |||
| from django.contrib import admin | ||||
| from django.utils.html import format_html | ||||
| from django.core.urlresolvers import reverse | ||||
| 
 | ||||
| from .models import Donation | ||||
| 
 | ||||
| 
 | ||||
| # Register your models here. | ||||
| 
 | ||||
| 
 | ||||
| class DonationAdmin(admin.ModelAdmin): | ||||
| 
 | ||||
|     list_display = ('id', 'donation', 'donator') | ||||
|     search_fields = ['id', 'donator__user__email'] | ||||
| 
 | ||||
|     def user(self, obj): | ||||
|         email = obj.customer.user.email | ||||
|         user_url = reverse("admin:membership_customuser_change", args=[obj.customer.user.id]) | ||||
|         return format_html("<a href='{url}'>{email}</a>", url=user_url, email=email) | ||||
| 
 | ||||
| 
 | ||||
| admin.site.register(Donation, DonationAdmin) | ||||
|  |  | |||
|  | @ -1,7 +1,11 @@ | |||
| from django import forms | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| 
 | ||||
| 
 | ||||
| from utils.forms import LoginFormMixin, SignupFormMixin | ||||
| from utils.forms import LoginFormMixin, SignupFormMixin, BillingAddressForm | ||||
| from utils.models import BillingAddress | ||||
| 
 | ||||
| from .models import Donation, DonatorStatus | ||||
| 
 | ||||
| 
 | ||||
| class LoginForm(LoginFormMixin): | ||||
|  | @ -10,5 +14,38 @@ class LoginForm(LoginFormMixin): | |||
| 
 | ||||
| 
 | ||||
| class SignupForm(SignupFormMixin): | ||||
|     confirm_password = forms.CharField(widget=forms.EmailInput()) | ||||
|     confirm_password = forms.CharField(widget=forms.PasswordInput()) | ||||
|     password = forms.CharField(widget=forms.PasswordInput()) | ||||
| 
 | ||||
| 
 | ||||
| class DonationForm(forms.ModelForm): | ||||
| 
 | ||||
|     class Meta: | ||||
|         model = Donation | ||||
|         fields = ['donation', 'donator', 'billing_address', | ||||
|                   'last4', 'cc_brand', 'stripe_charge_id'] | ||||
| 
 | ||||
|     def save(self, commit=True): | ||||
|         instance = super(DonationForm, self).save(commit=False) | ||||
| 
 | ||||
|         if commit: | ||||
|             DonatorStatus.create(self.cleaned_data['donator'].user) | ||||
|             instance.save() | ||||
| 
 | ||||
|         return instance | ||||
| 
 | ||||
| 
 | ||||
| class DonationBillingForm(BillingAddressForm): | ||||
|     token = forms.CharField(widget=forms.HiddenInput()) | ||||
|     donation_amount = forms.FloatField(widget=forms.TextInput(attrs={'placeholder': 'Amount'})) | ||||
| 
 | ||||
|     class Meta: | ||||
|         model = BillingAddress | ||||
|         fields = ['donation_amount', 'street_address', 'city', 'postal_code', 'country'] | ||||
|         labels = { | ||||
|             'amount': _('Amount'), | ||||
|             'street_address': _('Street Address'), | ||||
|             'city': _('City'), | ||||
|             'postal_code': _('Postal Code'), | ||||
|             'Country': _('Country'), | ||||
|         } | ||||
|  |  | |||
							
								
								
									
										0
									
								
								nosystemd/management/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								nosystemd/management/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								nosystemd/management/commands/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								nosystemd/management/commands/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										51
									
								
								nosystemd/management/commands/make_donation_charges.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								nosystemd/management/commands/make_donation_charges.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| from django.core.management.base import BaseCommand | ||||
| 
 | ||||
| from nosystem.models import DonatorStatus, Donation | ||||
| from datetime import datetime | ||||
| 
 | ||||
| from utils.stripe_utils import StripeUtils | ||||
| from .forms import DonationForm | ||||
| 
 | ||||
| 
 | ||||
| class Command(BaseCommand): | ||||
|     help = 'Make the monthly stripe charge to all donators' | ||||
| 
 | ||||
|     def handle(self, *args, **options): | ||||
|         donators = DonatorStatus.objects.filter(status=DonatorStatus.ACTIVE) | ||||
|         current_month = datetime.now().month | ||||
|         current_year = datetime.now().year | ||||
|         for donator in donators: | ||||
|             current_month_donation = Donation.objects.get(created_at__month=current_month, | ||||
|                                                           created_at__year=current_year) | ||||
|             if not current_month_donation: | ||||
|                 last_donation = Donation.objects.filter(donator=donator).last() | ||||
| 
 | ||||
|                 donation_amount = last_donation.donation | ||||
|                 # Make stripe charge to a customer | ||||
|                 stripe_utils = StripeUtils() | ||||
|                 stripe_utils.CURRENCY = 'usd' | ||||
|                 charge_response = stripe_utils.make_charge(amount=donation_amount, | ||||
|                                                            customer=donator.stripe_id) | ||||
|                 charge = charge_response.get('response_object') | ||||
| 
 | ||||
|                 # Check if the payment was approved | ||||
|                 if not charge: | ||||
|                     # TODO save error | ||||
|                     context = { | ||||
|                         'paymentError': charge_response.get('error'), | ||||
|                     } | ||||
|                     print(context) | ||||
|                 # Create a donation | ||||
|                 charge = charge_response.get('response_object') | ||||
|                 donation_data = { | ||||
|                     'cc_brand': charge.source.brand, | ||||
|                     'stripe_charge_id': charge.id, | ||||
|                     'last4': charge.source.last4, | ||||
|                     'billing_address': last_donation.billing_address.id, | ||||
|                     'donator': donator.id, | ||||
|                     'donation': donation_amount | ||||
|                 } | ||||
|                 donation_form = DonationForm(donation_data) | ||||
|                 if donation_form.is_valid(): | ||||
|                     donation = donation_form.save() | ||||
|                     print(donation) | ||||
							
								
								
									
										33
									
								
								nosystemd/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								nosystemd/migrations/0001_initial.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,33 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.9.4 on 2016-07-22 06:51 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.conf import settings | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     initial = True | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('utils', '0002_billingaddress'), | ||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Donation', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||
|                 ('donation', models.FloatField()), | ||||
|                 ('created_at', models.DateTimeField(auto_now_add=True)), | ||||
|                 ('last4', models.CharField(max_length=4)), | ||||
|                 ('cc_brand', models.CharField(max_length=10)), | ||||
|                 ('stripe_charge_id', models.CharField(max_length=100, null=True)), | ||||
|                 ('billing_address', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='utils.BillingAddress')), | ||||
|                 ('donator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||||
|             ], | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										21
									
								
								nosystemd/migrations/0002_auto_20160723_1848.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								nosystemd/migrations/0002_auto_20160723_1848.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.9.4 on 2016-07-23 18:48 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('nosystemd', '0001_initial'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='donation', | ||||
|             name='donator', | ||||
|             field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='membership.StripeCustomer'), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										26
									
								
								nosystemd/migrations/0003_donatorstatus.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								nosystemd/migrations/0003_donatorstatus.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.9.4 on 2016-07-26 01:53 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.conf import settings | ||||
| from django.db import migrations, models | ||||
| import django.db.models.deletion | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||
|         ('nosystemd', '0002_auto_20160723_1848'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='DonatorStatus', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||
|                 ('status', models.CharField(choices=[('active', 'Active'), ('canceled', 'Canceled')], max_length=10)), | ||||
|                 ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), | ||||
|             ], | ||||
|         ), | ||||
|     ] | ||||
|  | @ -1,15 +1,28 @@ | |||
| from django.db import models | ||||
| from membership.models import CustomUser | ||||
| from membership.models import StripeCustomer, CustomUser | ||||
| from utils.models import BillingAddress | ||||
| 
 | ||||
| 
 | ||||
| # Create your models here. | ||||
| class DonatorStatus(models.Model): | ||||
|     ACTIVE = 'active' | ||||
|     CANCELED = 'canceled' | ||||
| 
 | ||||
|     STATUS_CHOICES = ( | ||||
|         (ACTIVE, 'Active'), | ||||
|         (CANCELED, 'Canceled') | ||||
|     ) | ||||
|     user = models.OneToOneField(CustomUser) | ||||
|     status = models.CharField(choices=STATUS_CHOICES, max_length=10, default=ACTIVE) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def create(cls, user): | ||||
|         cls.objects.get_or_create(user=user) | ||||
| 
 | ||||
| 
 | ||||
| class Donation(models.Model): | ||||
| 
 | ||||
|     donation = models.FloatField() | ||||
|     donator = models.ForeignKey(CustomUser) | ||||
|     donator = models.ForeignKey(StripeCustomer) | ||||
|     created_at = models.DateTimeField(auto_now_add=True) | ||||
|     billing_address = models.ForeignKey(BillingAddress) | ||||
|     last4 = models.CharField(max_length=4) | ||||
|  | @ -20,3 +33,9 @@ class Donation(models.Model): | |||
|     def create(cls, data): | ||||
|         obj = cls.objects.create(**data) | ||||
|         return obj | ||||
| 
 | ||||
|     def set_stripe_charge(self, stripe_charge): | ||||
|         self.stripe_charge_id = stripe_charge.id | ||||
|         self.last4 = stripe_charge.source.last4 | ||||
|         self.cc_brand = stripe_charge.source.brand | ||||
|         self.save | ||||
|  |  | |||
							
								
								
									
										124
									
								
								nosystemd/static/nosystemd/js/donation.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								nosystemd/static/nosystemd/js/donation.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,124 @@ | |||
| $( document ).ready(function() { | ||||
| 
 | ||||
|     $.ajaxSetup({  | ||||
|          beforeSend: function(xhr, settings) { | ||||
|              function getCookie(name) { | ||||
|                  var cookieValue = null; | ||||
|                  if (document.cookie && document.cookie != '') { | ||||
|                      var cookies = document.cookie.split(';'); | ||||
|                      for (var i = 0; i < cookies.length; i++) { | ||||
|                          var cookie = jQuery.trim(cookies[i]); | ||||
|                          // Does this cookie string begin with the name we want?
 | ||||
|                          if (cookie.substring(0, name.length + 1) == (name + '=')) { | ||||
|                              cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); | ||||
|                              break; | ||||
|                          } | ||||
|                      } | ||||
|                  } | ||||
|                  return cookieValue; | ||||
|              } | ||||
|              if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { | ||||
|                  // Only send the token to relative URLs i.e. locally.
 | ||||
|                  xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); | ||||
|              } | ||||
|          }  | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     var $form = $('#payment-form'); | ||||
|     $form.submit(payWithStripe); | ||||
| 
 | ||||
|     /* If you're using Stripe for payments */ | ||||
|     function payWithStripe(e) { | ||||
|         e.preventDefault(); | ||||
| 
 | ||||
|         /* Visual feedback */ | ||||
|         $form.find('[type=submit]').html('Validating <i class="fa fa-spinner fa-pulse"></i>'); | ||||
| 
 | ||||
|         var PublishableKey = window.stripeKey; | ||||
|         Stripe.setPublishableKey(PublishableKey); | ||||
|         Stripe.card.createToken($form, function stripeResponseHandler(status, response) { | ||||
|             if (response.error) { | ||||
|                 /* Visual feedback */ | ||||
|                 $form.find('[type=submit]').html('Try again'); | ||||
|                 /* Show Stripe errors on the form */ | ||||
|                 $form.find('.payment-errors').text(response.error.message); | ||||
|                 $form.find('.payment-errors').closest('.row').show(); | ||||
|             } else { | ||||
|                 /* Visual feedback */ | ||||
|                 $form.find('[type=submit]').html('Processing <i class="fa fa-spinner fa-pulse"></i>'); | ||||
|                 /* Hide Stripe errors on the form */ | ||||
|                 $form.find('.payment-errors').closest('.row').hide(); | ||||
|                 $form.find('.payment-errors').text(""); | ||||
|                 // response contains id and card, which contains additional card details
 | ||||
|                 var token = response.id; | ||||
|                 // AJAX
 | ||||
| 
 | ||||
|                 //set token  on a hidden input
 | ||||
|                 $('#id_token').val(token); | ||||
|                 $('#donation-form').submit(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /* Form validation */ | ||||
|     $.validator.addMethod("month", function(value, element) { | ||||
|       return this.optional(element) || /^(01|02|03|04|05|06|07|08|09|10|11|12)$/.test(value); | ||||
|     }, "Please specify a valid 2-digit month."); | ||||
| 
 | ||||
|     $.validator.addMethod("year", function(value, element) { | ||||
|       return this.optional(element) || /^[0-9]{2}$/.test(value); | ||||
|     }, "Please specify a valid 2-digit year."); | ||||
| 
 | ||||
|     validator = $form.validate({ | ||||
|         rules: { | ||||
|             cardNumber: { | ||||
|                 required: true, | ||||
|                 creditcard: true, | ||||
|                 digits: true | ||||
|             }, | ||||
|             expMonth: { | ||||
|                 required: true, | ||||
|                 month: true | ||||
|             }, | ||||
|             expYear: { | ||||
|                 required: true, | ||||
|                 year: true | ||||
|             }, | ||||
|             cvCode: { | ||||
|                 required: true, | ||||
|                 digits: true | ||||
|             } | ||||
|         }, | ||||
|         highlight: function(element) { | ||||
|             $(element).closest('.form-control').removeClass('success').addClass('error'); | ||||
|         }, | ||||
|         unhighlight: function(element) { | ||||
|             $(element).closest('.form-control').removeClass('error').addClass('success'); | ||||
|         }, | ||||
|         errorPlacement: function(error, element) { | ||||
|             $(element).closest('.form-group').append(error); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     paymentFormReady = function() { | ||||
|         if ($form.find('[name=cardNumber]').hasClass("success") && | ||||
|             $form.find('[name=expMonth]').hasClass("success") && | ||||
|             $form.find('[name=expYear]').hasClass("success") && | ||||
|             $form.find('[name=cvCode]').val().length > 1) { | ||||
|             return true; | ||||
|         } else { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     $form.find('[type=submit]').prop('disabled', true); | ||||
|     var readyInterval = setInterval(function() { | ||||
|         if (paymentFormReady()) { | ||||
|             $form.find('[type=submit]').prop('disabled', false); | ||||
|             clearInterval(readyInterval); | ||||
|         } | ||||
|     }, 250); | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
|  | @ -1,4 +1,4 @@ | |||
| {% load static bootstrap3 %} | ||||
| {% load static bootstrap3 i18n %} | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| 
 | ||||
|  | @ -59,9 +59,20 @@ | |||
|                     <li> | ||||
|                         <a class="page-scroll" href="#contact">Contact</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a class="page-scroll" href="{% url 'nosystemd:login' %}">Login</a> | ||||
|                     </li>                | ||||
|                     {% if request.user.is_authenticated %} | ||||
|                         <li class="dropdown"> | ||||
|                           <a class="dropdown-toggle" role="button" data-toggle="dropdown" href="#"> | ||||
|                             <i class="glyphicon glyphicon-user"></i> {{request.user.name}} <span class="caret"></span></a> | ||||
|                           <ul id="g-account-menu" class="dropdown-menu" role="menu"> | ||||
|                             <li><a href="{% url 'nosystemd:logout' %}"><i class="glyphicon glyphicon-lock"></i> {% trans "Logout"%} </a></li> | ||||
|                             <li><a href="{% url 'nosystemd:donator_status' %}"><i class="fa fa-heart-o" aria-hidden="true"></i> {% trans "Donation"%} </a></li> | ||||
|                           </ul> | ||||
|                         </li>               | ||||
|                     {% else %} | ||||
|                         <li> | ||||
|                             <a class="page-scroll" href="{% url 'nosystemd:login' %}">Login</a> | ||||
|                         </li>  | ||||
|                     {% endif %} | ||||
|                 </ul> | ||||
|             </div> | ||||
|             <!-- /.navbar-collapse --> | ||||
|  | @ -90,7 +101,7 @@ | |||
|     <script type="text/javascript" src="//js.stripe.com/v2/"></script> | ||||
| 
 | ||||
|     <!-- Proccess payment lib --> | ||||
|     <script type="text/javascript" src="{% static 'hosting/js/payment.js' %}"></script> | ||||
|     <script type="text/javascript" src="{% static 'nosystemd/js/donation.js' %}"></script> | ||||
| 
 | ||||
| </body> | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,36 +8,41 @@ | |||
|         	<div class="header-content-inner"> | ||||
| 
 | ||||
| 				<div class="container payment-container"> | ||||
| 					<div class="row"> | ||||
| 						<div class="col-xs-12 col-md-4 col-md-offset-3" > | ||||
| 							<h3><b>Monthly Donation</b></h3> | ||||
| 							<hr> | ||||
| 							<form role="form" novalidate> | ||||
| 		                        <div class="row"> | ||||
| 		                            <div class="col-xs-9 col-md-4 col-md-offset-4"> | ||||
| 										<div class="form-group"> | ||||
| 											<div class="input-group"> | ||||
| 												<input  type="number" class="form-control" placeholder="Amount to donate"  name="donation_amount" /> | ||||
| 					<form role="form" id="donation-form" name="donation-form" method="post" action="{% url 'nosystemd:donations' %}" novalidate> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-xs-12 col-md-4 col-md-offset-3" > | ||||
| 								<h3><b>Monthly Donation</b></h3> | ||||
| 								<hr> | ||||
| 								<!-- <form role="form" novalidate> --> | ||||
| 			                        <div class="row"> | ||||
| 			                            <div class="col-xs-9 col-md-4 col-md-offset-4"> | ||||
| 											<div class="form-group"> | ||||
| 												<div class="input-group"> | ||||
| 													{% bootstrap_field form.donation_amount show_label=False type='fields'%} | ||||
| 													<!-- <input  type="number" class="form-control" placeholder="Amount to donate"  name="donation" /> --> | ||||
| 												</div> | ||||
| 											</div> | ||||
| 										</div> | ||||
| 									</div> | ||||
| 								</div> | ||||
| 							</form> | ||||
| 								<!-- </form> --> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="row"> | ||||
| 						<div class="col-xs-12 col-md-4 col-md-offset-3 billing"> | ||||
| 							<h3><b>Billing Address</b></h3> | ||||
| 							<hr> | ||||
| 							<form role="form" id="billing-form" method="post" action="{% url 'hosting:payment' %}" novalidate> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-xs-12 col-md-4 col-md-offset-3 billing"> | ||||
| 								<h3><b>Billing Address</b></h3> | ||||
| 								<hr> | ||||
| 				                {% for field in form %} | ||||
| 			                        {% csrf_token %} | ||||
| 				                    {% bootstrap_field field show_label=False type='fields'%} | ||||
| 
 | ||||
| 			                        {% if not field.name == 'donation_amount' %} | ||||
| 				                    	{% bootstrap_field field show_label=False type='fields'%} | ||||
| 				                    {% endif %} | ||||
| 				                {% endfor %} | ||||
| 				                {% bootstrap_form_errors form type='non_fields'%} | ||||
| 			                </form> | ||||
| 				                 | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					</form> | ||||
| 				    <div class="row"> | ||||
| 				        <div class="col-xs-12 col-sm-6 col-md-4 col-md-offset-3 creditcard-box"> | ||||
| 							<h3><b>Payment Details</b></h3> | ||||
|  |  | |||
							
								
								
									
										74
									
								
								nosystemd/templates/nosystemd/donation_detail.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								nosystemd/templates/nosystemd/donation_detail.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | |||
| {% extends "nosystemd/base.html" %} | ||||
| {% load staticfiles bootstrap3 %} | ||||
| {% load i18n %} | ||||
| {% block content %}  | ||||
| 
 | ||||
| <div class="container  order-detail-container"> | ||||
|     <div class="row"> | ||||
|         <div class="col-xs-8 col-xs-offset-2"> | ||||
|     		<div class="invoice-title"> | ||||
|     			<h2>{% trans "Invoice"%}</h2><h3 class="pull-right">{% trans "Donation #"%} {{donation.id}}</h3> | ||||
|     		</div> | ||||
|     		<div class="row"> | ||||
|     			<div class="col-xs-6"> | ||||
|     				<address> | ||||
|                     <h3><b>{% trans "Billing Address:"%}</b></h3> | ||||
|     					{{user.name}}<br> | ||||
|                         {{donation.billing_address.street_address}},{{donation.billing_address.postal_code}}<br> | ||||
|                         {{donation.billing_address.city}}, {{donation.billing_address.country}}. | ||||
|     				</address> | ||||
|     			</div> | ||||
|                 <div class="col-xs-6 text-right"> | ||||
|                     <address> | ||||
|                         <strong>{% trans "Date:"%}</strong><br> | ||||
|                         {{donation.created_at}}<br><br> | ||||
|                         <br><br> | ||||
|                     </address> | ||||
| 
 | ||||
|                 </div> | ||||
|     		</div> | ||||
|     		<div class="row"> | ||||
|     			<div class="col-xs-6"> | ||||
|     				<address> | ||||
|     					<strong>{% trans "Payment Method:"%}</strong><br> | ||||
|     					{{donation.cc_brand}} ending **** {{donation.last4}}<br> | ||||
|     					{{user.email}} | ||||
|     				</address> | ||||
|     			</div> | ||||
|     		</div> | ||||
|     	</div> | ||||
|     </div> | ||||
|      | ||||
|     <div class="row"> | ||||
|         <div class="col-md-8 col-md-offset-2"> | ||||
|             <h3><b>{% trans "Donation summary"%}</b></h3> | ||||
|             <hr> | ||||
|             <div class="content"> | ||||
|                 <p><b>{% trans "Donation"%}-{{donation.created_at|date:"M Y"}}</b> <span class="pull-right">{{donation.donation}} USD</span></p> | ||||
|                 <hr> | ||||
|                 <h4>{% trans "Total"%}<p class="pull-right"><b>{{donation.donation}} USD</b></p></h4> | ||||
|             </div> | ||||
|             <br/> | ||||
|             {% url 'hosting:payment' as payment_url %} | ||||
|             {% if payment_url in request.META.HTTP_REFERER  %} | ||||
|             <div class=" content pull-right"> | ||||
|                 <a href="{% url 'hosting:virtual_machine_key' order.vm_plan.id %}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a> | ||||
|             </div> | ||||
|             {% endif %} | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|         <div class="col-md-8 col-md-offset-2"> | ||||
|             <hr> | ||||
|             {% trans "Thanks for you donation, you can cancel your monthly donation at any time going to profile > cancel danation"%} | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|         <div class="col-md-8 col-md-offset-2"> | ||||
|             <div class=" content pull-right"> | ||||
|                 <a href="{% url 'nosystemd:landing' %}" ><button class="btn btn-info">{% trans "Return to home"%}</button></a> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| {%endblock%} | ||||
							
								
								
									
										40
									
								
								nosystemd/templates/nosystemd/donator_status.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								nosystemd/templates/nosystemd/donator_status.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| {% extends "nosystemd/base.html" %} | ||||
| {% load staticfiles bootstrap3 i18n %} | ||||
| {% block content %} | ||||
| 
 | ||||
|     <header> | ||||
|         <div class="header-content"> | ||||
|             <div class="header-content-inner"> | ||||
|                 <div class="col-md-4 col-md-offset-4"> | ||||
| 
 | ||||
| 
 | ||||
|                     {% if messages %} | ||||
|                         <ul class="list-unstyled"> | ||||
|                         {% for message in messages %} | ||||
|                             <li>{{ message }}</li> | ||||
|                         {% endfor %} | ||||
|                         </ul> | ||||
|                     {% endif %} | ||||
| 
 | ||||
|                     <h1 id="homeHeading">Thanks you</h1> | ||||
|                     <hr> | ||||
|                     <p>Your monthly donation status is {{donator_status.status}}</p> | ||||
|                     <form action="{% url 'nosystemd:change_donator_status' donator_status.id %}" method="post" class="form" novalidate> | ||||
|                         {% csrf_token %} | ||||
|                         <button type="submit" class="btn btn-primary btn-xl page-scroll"> | ||||
|                             {% if donator_status.status == 'active'%} | ||||
|                                 {% trans "Cancel Donation"%} | ||||
|                             {% else %} | ||||
|                                 {% trans "Reanude Donation"%} | ||||
|                             {% endif %} | ||||
|                              | ||||
|                         </button> | ||||
|                     </form> | ||||
|                     <br/> | ||||
| 
 | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </header> | ||||
| 
 | ||||
| {% endblock %} | ||||
|  | @ -1,79 +1,6 @@ | |||
| {% load static bootstrap3 %} | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| 
 | ||||
| <head> | ||||
| 
 | ||||
|     <meta charset="utf-8"> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
|     <meta name="description" content=""> | ||||
|     <meta name="author" content=""> | ||||
| 
 | ||||
|     <title>Creative - Start Bootstrap Theme</title> | ||||
| 
 | ||||
|     <!-- Bootstrap Core CSS --> | ||||
|     <link href="{% static 'nosystemd/vendor/bootstrap/css/bootstrap.min.css' %}" rel="stylesheet"> | ||||
| 
 | ||||
|     <!-- Custom Fonts --> | ||||
|     <link href="{% static 'nosystemd/vendor/font-awesome/css/font-awesome.min.css' %}" rel="stylesheet" type="text/css"> | ||||
|     <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'> | ||||
|     <link href='https://fonts.googleapis.com/css?family=Merriweather:400,300,300italic,400italic,700,700italic,900,900italic' rel='stylesheet' type='text/css'> | ||||
| 
 | ||||
|     <!-- Plugin CSS --> | ||||
|     <link href="{% static 'nosystemd/vendor/magnific-popup/magnific-popup.css' %}" rel="stylesheet"> | ||||
| 
 | ||||
|     <!-- Theme CSS --> | ||||
|     <link href="{% static 'nosystemd/css/creative.css' %}" rel="stylesheet"> | ||||
| 
 | ||||
|     <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||||
|     <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> | ||||
|     <!--[if lt IE 9]> | ||||
|         <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> | ||||
|         <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> | ||||
|     <![endif]--> | ||||
| 
 | ||||
| </head> | ||||
| 
 | ||||
| <body id="page-top"> | ||||
| 
 | ||||
|     <nav id="mainNav" class="navbar navbar-default navbar-fixed-top"> | ||||
|         <div class="container-fluid"> | ||||
|             <!-- Brand and toggle get grouped for better mobile display --> | ||||
|             <div class="navbar-header"> | ||||
|                 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> | ||||
|                     <span class="sr-only">Toggle navigation</span> Menu <i class="fa fa-bars"></i> | ||||
|                 </button> | ||||
|                 <a class="navbar-brand page-scroll" href="#page-top">nosystemd</a> | ||||
|             </div> | ||||
| 
 | ||||
|             <!-- Collect the nav links, forms, and other content for toggling --> | ||||
|             <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | ||||
|                 <ul class="nav navbar-nav navbar-right"> | ||||
|                     <li> | ||||
|                         <a class="page-scroll" href="#about">About</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a class="page-scroll" href="#services">Services</a> | ||||
|                     </li> | ||||
|                     <li> | ||||
|                         <a class="page-scroll" href="#contact">Contact</a> | ||||
|                     </li> | ||||
|                     {% if not request.user.is_authenticated %} | ||||
|                     <li> | ||||
|                         <a class="page-scroll" href="{% url 'nosystemd:login' %}">Login</a> | ||||
|                     </li> | ||||
|                     {% else %}      | ||||
|                     <li> | ||||
|                         <a class="page-scroll" href=" {% url 'nosystemd:logout' %}">Logout</a> | ||||
|                     </li>                     | ||||
|                     {% endif %}            | ||||
|                 </ul> | ||||
|             </div> | ||||
|             <!-- /.navbar-collapse --> | ||||
|         </div> | ||||
|         <!-- /.container-fluid --> | ||||
|     </nav> | ||||
| {% extends "nosystemd/base.html" %} | ||||
| {% load staticfiles bootstrap3 i18n %} | ||||
| {% block content %} | ||||
| 
 | ||||
|     <header> | ||||
|         <div class="header-content"> | ||||
|  | @ -81,7 +8,7 @@ | |||
|                 <h1 id="homeHeading">No more SYSTEMD</h1> | ||||
|                 <hr> | ||||
|                 <p>We want to remove systemd from the famous linux distros and create a good replacement</p> | ||||
|                 <a href="{% url 'nosystemd:donation' %}" class="btn btn-primary btn-xl page-scroll">DONATE NOW</a> | ||||
|                 <a href="{% url 'nosystemd:donations' %}" class="btn btn-primary btn-xl page-scroll">DONATE NOW</a> | ||||
|             </div> | ||||
|         </div> | ||||
|     </header> | ||||
|  | @ -170,21 +97,5 @@ | |||
|             </div> | ||||
|         </div> | ||||
|     </section> | ||||
| {% endblock %} | ||||
| 
 | ||||
|     <!-- jQuery --> | ||||
|     <script src="{% static 'nosystemd/vendor/jquery/jquery.min.js' %}"></script> | ||||
| 
 | ||||
|     <!-- Bootstrap Core JavaScript --> | ||||
|     <script src="{% static 'nosystemd/vendor/bootstrap/js/bootstrap.min.js' %}"></script> | ||||
| 
 | ||||
|     <!-- Plugin JavaScript --> | ||||
|     <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script> | ||||
|     <script src="{% static 'nosystemd/vendor/scrollreveal/scrollreveal.min.js' %}"></script> | ||||
|     <script src="{% static 'nosystemd/vendor/magnific-popup/jquery.magnific-popup.min.js' %}"></script> | ||||
| 
 | ||||
|     <!-- Theme JavaScript --> | ||||
|     <script src="{% static 'nosystemd/js/creative.min.js' %}"></script> | ||||
| 
 | ||||
| </body> | ||||
| 
 | ||||
| </html> | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| from django.conf.urls import url | ||||
| 
 | ||||
| from .views import LandingView, LoginView, SignupView, PasswordResetView,\ | ||||
|     PasswordResetConfirmView, DonationView | ||||
|     PasswordResetConfirmView, DonationView, DonationDetailView, ChangeDonatorStatusDetailView,\ | ||||
|     DonatorStatusDetailView | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|     url(r'^$', LandingView.as_view(), name='landing'), | ||||
|  | @ -13,6 +14,12 @@ urlpatterns = [ | |||
|     url(r'reset-password-confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', | ||||
|         PasswordResetConfirmView.as_view(), name='reset_password_confirm'), | ||||
| 
 | ||||
|     url(r'^donation/?$', DonationView.as_view(), name='donation'), | ||||
|     url(r'^donations/?$', DonationView.as_view(), name='donations'), | ||||
|     url(r'donations/(?P<pk>\d+)/?$', DonationDetailView.as_view(), name='donations'), | ||||
|     url(r'donations/status/?$', DonatorStatusDetailView.as_view(), | ||||
|         name='donator_status'), | ||||
|     url(r'donations/status/(?P<pk>\d+)/?$', ChangeDonatorStatusDetailView.as_view(), | ||||
|         name='change_donator_status'), | ||||
|     # url(r'^donation/invoice?$', DonationView.as_view(), name='donation_detail'), | ||||
| 
 | ||||
| ] | ||||
|  |  | |||
|  | @ -1,15 +1,20 @@ | |||
| from django.views.generic import TemplateView, CreateView, FormView | ||||
| from django.views.generic import TemplateView, CreateView, FormView, DetailView, UpdateView | ||||
| from django.http import HttpResponseRedirect | ||||
| from django.shortcuts import render | ||||
| from django.core.urlresolvers import reverse_lazy, reverse | ||||
| from django.contrib.auth import authenticate, login | ||||
| from django.contrib.auth.mixins import LoginRequiredMixin | ||||
| from django.conf import settings | ||||
| from django.contrib import messages | ||||
| 
 | ||||
| from membership.models import CustomUser | ||||
| 
 | ||||
| from membership.models import CustomUser, StripeCustomer | ||||
| from utils.stripe_utils import StripeUtils | ||||
| from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin | ||||
| from utils.forms import PasswordResetRequestForm, BillingAddressForm | ||||
| from utils.forms import PasswordResetRequestForm | ||||
| 
 | ||||
| from .forms import LoginForm, SignupForm | ||||
| from .forms import LoginForm, SignupForm, DonationForm, DonationBillingForm | ||||
| from .models import Donation, DonatorStatus | ||||
| 
 | ||||
| 
 | ||||
| class LandingView(TemplateView): | ||||
|  | @ -74,7 +79,8 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin): | |||
| class DonationView(LoginRequiredMixin, FormView): | ||||
|     template_name = 'nosystemd/donation.html' | ||||
|     login_url = reverse_lazy('nosystemd:login') | ||||
|     form_class = BillingAddressForm | ||||
|     form_class = DonationBillingForm | ||||
|     success_url = reverse_lazy('nosystemd:donations') | ||||
| 
 | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(DonationView, self).get_context_data(**kwargs) | ||||
|  | @ -84,86 +90,103 @@ class DonationView(LoginRequiredMixin, FormView): | |||
| 
 | ||||
|         return context | ||||
| 
 | ||||
|     # def post(self, request, *args, **kwargs): | ||||
|     #     form = self.get_form() | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         form = self.get_form() | ||||
| 
 | ||||
|     #     if form.is_valid(): | ||||
|     #         context = self.get_context_data() | ||||
|     #         specifications = request.session.get('vm_specs') | ||||
|     #         vm_type = specifications.get('hosting_company') | ||||
|     #         vm = VirtualMachineType.objects.get(hosting_company=vm_type) | ||||
|     #         final_price = vm.calculate_price(specifications) | ||||
|         if form.is_valid(): | ||||
|             context = self.get_context_data() | ||||
|             token = form.cleaned_data.get('token') | ||||
|             donation_amount = form.cleaned_data.get('donation_amount') | ||||
| 
 | ||||
|     #         plan_data = { | ||||
|     #             'vm_type': vm, | ||||
|     #             'cores': specifications.get('cores'), | ||||
|     #             'memory': specifications.get('memory'), | ||||
|     #             'disk_size': specifications.get('disk_size'), | ||||
|     #             'configuration': specifications.get('configuration'), | ||||
|     #             'price': final_price | ||||
|     #         } | ||||
|     #         token = form.cleaned_data.get('token') | ||||
|             # 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)) | ||||
| 
 | ||||
|     #         # 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() | ||||
| 
 | ||||
|     #         # Create Virtual Machine Plan | ||||
|     #         plan = VirtualMachinePlan.create(plan_data, request.user) | ||||
|             # 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') | ||||
| 
 | ||||
|     #         # Create Billing Address | ||||
|     #         billing_address = form.save() | ||||
|             # 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 Hosting Order | ||||
|     #         order = HostingOrder.create(vm_plan=plan, customer=customer, | ||||
|     #                                     billing_address=billing_address) | ||||
|             # 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(): | ||||
|                 donation = donation_form.save() | ||||
|                 return HttpResponseRedirect(reverse('nosystemd:donations', | ||||
|                                                     kwargs={'pk': donation.id})) | ||||
|             else: | ||||
|                 self.form_invalid(donation_form) | ||||
| 
 | ||||
|     #         # Make stripe charge to a customer | ||||
|     #         stripe_utils = StripeUtils() | ||||
|     #         charge_response = stripe_utils.make_charge(amount=final_price, | ||||
|     #                                                    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) | ||||
| 
 | ||||
|     #         charge = charge_response.get('response_object') | ||||
| 
 | ||||
|     #         # Associate an order with a stripe payment | ||||
|     #         order.set_stripe_charge(charge) | ||||
| 
 | ||||
|     #         # If the Stripe payment was successed, set order status approved | ||||
|     #         order.set_approved() | ||||
| 
 | ||||
|     #         # Send notification to ungleich as soon as VM has been booked | ||||
|     #         # TODO send email using celery | ||||
| 
 | ||||
|     #         context = { | ||||
|     #             'vm': plan, | ||||
|     #             'order': order, | ||||
|     #             'base_url': "{0}://{1}".format(request.scheme, request.get_host()) | ||||
| 
 | ||||
|     #         } | ||||
|     #         email_data = { | ||||
|     #             'subject': 'New VM request', | ||||
|     #             'to': request.user.email, | ||||
|     #             'context': context, | ||||
|     #             'template_name': 'new_booked_vm', | ||||
|     #             'template_path': 'hosting/emails/' | ||||
|     #         } | ||||
|     #         email = BaseEmail(**email_data) | ||||
|     #         email.send() | ||||
| 
 | ||||
|     #         return HttpResponseRedirect(reverse('hosting:orders', kwargs={'pk': order.id})) | ||||
|     #     else: | ||||
|     #         return self.form_invalid(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 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:donator_status')) | ||||
|  |  | |||
|  | @ -11,6 +11,9 @@ class BillingAddress(models.Model): | |||
|     postal_code = models.CharField(max_length=50) | ||||
|     country = CountryField() | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return self.street_address | ||||
| 
 | ||||
| 
 | ||||
| class ContactMessage(models.Model): | ||||
|     name = models.CharField(max_length=200) | ||||
|  |  | |||
|  | @ -11,7 +11,6 @@ def handleStripeError(f): | |||
|             'error': None | ||||
|         } | ||||
|         common_message = "Currently its not possible to make payments." | ||||
| 
 | ||||
|         try: | ||||
|             response_object = f(*args, **kwargs) | ||||
|             response = { | ||||
|  | @ -85,7 +84,6 @@ class StripeUtils(object): | |||
|     @handleStripeError | ||||
|     def make_charge(self, amount=None, customer=None): | ||||
|         amount = int(amount * 100)  # stripe amount unit, in cents | ||||
| 
 | ||||
|         charge = self.stripe.Charge.create( | ||||
|             amount=amount,  # in cents | ||||
|             currency=self.CURRENCY, | ||||
|  | @ -93,7 +91,6 @@ class StripeUtils(object): | |||
|         ) | ||||
|         return charge | ||||
| 
 | ||||
| 
 | ||||
|     @handleStripeError | ||||
|     def create_plan(self, amount, name, id): | ||||
|         self.stripe.Plan.create( | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue