Skip to content

Commit f48e82e

Browse files
committed
Added checkout app and stripe functionality
1 parent 34004e5 commit f48e82e

16 files changed

+391
-0
lines changed

checkout/__init__.py

Whitespace-only changes.

checkout/admin.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from django.contrib import admin
2+
from .models import Order, OrderLineItem
3+
4+
# Register your models here.
5+
6+
7+
class OrderLineAdminInline(admin.TabularInline):
8+
model = OrderLineItem
9+
10+
11+
class OrderAdmin(admin.ModelAdmin):
12+
inlines = (OrderLineAdminInline, )
13+
14+
15+
admin.site.register(Order, OrderAdmin)

checkout/apps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class CheckoutConfig(AppConfig):
5+
name = 'checkout'

checkout/forms.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from django import forms
2+
from .models import Order
3+
4+
5+
class MakePaymentForm(forms.Form):
6+
7+
MONTH_CHOICES = [(i, i) for i in range(1, 13)]
8+
YEAR_CHOICES = [(i, i) for i in range(2020, 2036)]
9+
10+
credit_card_number = forms.CharField(
11+
label='Credit card number', required=False)
12+
cvv = forms.CharField(label='Security code (CVV)',
13+
required=False)
14+
expiry_month = forms.ChoiceField(
15+
label='Month', choices=MONTH_CHOICES, required=False)
16+
expiry_year = forms.ChoiceField(
17+
label='Year', choices=YEAR_CHOICES, required=False)
18+
stripe_id = forms.CharField(widget=forms.HiddenInput)
19+
20+
21+
class OrderForm(forms.ModelForm):
22+
23+
class Meta:
24+
model = Order
25+
widgets = {
26+
'full_name': forms.TextInput(attrs={'placeholder': 'Full Name'}),
27+
'street_address1': forms.TextInput(attrs={'placeholder': 'Street Address (line 1)'}),
28+
'street_address2': forms.TextInput(attrs={'placeholder': 'Street Address (line 2)'}),
29+
'town_or_city': forms.TextInput(attrs={'placeholder': 'Town/City'}),
30+
'county': forms.TextInput(attrs={'placeholder': 'County'}),
31+
'country': forms.TextInput(attrs={'placeholder': 'Country'}),
32+
'phone_number': forms.TextInput(attrs={'placeholder': 'Phone Number'}),
33+
'postcode': forms.TextInput(attrs={'placeholder': 'Postcode'})
34+
}
35+
fields = (
36+
'full_name', 'phone_number', 'country', 'postcode',
37+
'town_or_city', 'street_address1', 'street_address2',
38+
'county'
39+
)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.24 on 2020-03-10 17:03
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
import django.db.models.deletion
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
initial = True
12+
13+
dependencies = [
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name='Order',
19+
fields=[
20+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21+
('full_name', models.CharField(max_length=50)),
22+
('phone_number', models.CharField(max_length=20)),
23+
('country', models.CharField(max_length=40)),
24+
('postcode', models.CharField(blank=True, max_length=20)),
25+
('town_or_city', models.CharField(max_length=40)),
26+
('street_address1', models.CharField(max_length=40)),
27+
('street_address2', models.CharField(max_length=40)),
28+
('county', models.CharField(max_length=40)),
29+
('date', models.DateField()),
30+
],
31+
),
32+
migrations.CreateModel(
33+
name='OrderLineItem',
34+
fields=[
35+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
36+
('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='checkout.Order')),
37+
],
38+
),
39+
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.24 on 2020-03-10 21:30
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('checkout', '0001_initial'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='orderlineitem',
17+
name='product',
18+
field=models.CharField(default='PRO', max_length=20),
19+
),
20+
migrations.AddField(
21+
model_name='orderlineitem',
22+
name='quantity',
23+
field=models.IntegerField(default=1),
24+
),
25+
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.24 on 2020-03-23 14:07
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('checkout', '0002_auto_20200310_2130'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='order',
17+
name='street_address2',
18+
field=models.CharField(blank=True, max_length=40),
19+
),
20+
]

checkout/migrations/__init__.py

Whitespace-only changes.

checkout/models.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from django.db import models
2+
3+
# Create your models here.
4+
5+
6+
class Order(models.Model):
7+
full_name = models.CharField(max_length=50, blank=False)
8+
phone_number = models.CharField(max_length=20, blank=False)
9+
country = models.CharField(max_length=40, blank=False)
10+
postcode = models.CharField(max_length=20, blank=True)
11+
town_or_city = models.CharField(max_length=40, blank=False)
12+
street_address1 = models.CharField(max_length=40, blank=False)
13+
street_address2 = models.CharField(max_length=40, blank=True)
14+
county = models.CharField(max_length=40, blank=False)
15+
date = models.DateField()
16+
17+
def __str__(self):
18+
return "{0}-{1}-{2}".format(self.id, self.date, self.full_name)
19+
20+
21+
class OrderLineItem(models.Model):
22+
order = models.ForeignKey(Order, null=False)
23+
product = models.CharField(max_length=20, default="PRO")
24+
quantity = models.IntegerField(default=1)
25+
26+
def __str__(self):
27+
return "1x PRO @ 9.90 EUR"

checkout/templates/checkout.html

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{% extends "base.html" %}
2+
{% load static from staticfiles %}
3+
{% load crispy_forms_tags %}
4+
{% block title %}TrackIt | Checkout | Go PRO{% endblock %}
5+
{% block head %}
6+
<!-- Stripe JS -->
7+
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
8+
<script type="text/javascript">
9+
//<![CDATA[
10+
Stripe.publishableKey = '{{ publishable }}';
11+
//]]>
12+
</script>
13+
<!-- Stripe JS -->
14+
<script type="text/javascript" src="{% static 'js/stripe.js' %}"></script>
15+
{% endblock head %}
16+
{% block page_heading %}<span class="material-icons">
17+
shopping_cart
18+
</span> Checkout<br>
19+
<hr>{% endblock %}
20+
{% block container-class %}checkout-container{% endblock %}
21+
{% block content %}
22+
<div class="jumbotron mx-auto" style="max-width: 1200px;">
23+
<div class="row">
24+
<div class="col-12">
25+
<h3>Go PRO</h3>
26+
<b>Includes:</b>
27+
<ul>
28+
<li>Unlimited Tickets/month</li>
29+
<li>KANBAN View</li>
30+
<li>24/7 Live Support</li>
31+
</ul>
32+
<p class="lead">Total Due: 9.90 EUR (Single Payment)</p>
33+
<!-- <p><span class="glyphicon glyphicon-euro" aria-hidden="true"></span>{{ total }}</p> -->
34+
<form role="form" method="post" id="payment-form" action="{% url 'checkout' %}" enctype="multipart/form-data">
35+
{% csrf_token %}
36+
<div class="row">
37+
<div id="credit-card-errors" style="display: none;">
38+
<div id="alert-message block-message error" id="stripe-error-message"></div>
39+
</div>
40+
</div>
41+
<div class="row">
42+
<div class="col-md-9 col-lg-6">
43+
<legend>Your Details</legend>
44+
{{ order_form.full_name | as_crispy_field }}
45+
</div>
46+
</div>
47+
<div class="row">
48+
<div class="col-md-9 col-lg-6">
49+
{{ order_form.phone_number | as_crispy_field }}
50+
</div>
51+
</div>
52+
<div class="row">
53+
<div class="col-md-12">
54+
{{ order_form.street_address1 | as_crispy_field }}
55+
</div>
56+
<div class="col-md-12">
57+
{{ order_form.street_address2 | as_crispy_field }}
58+
</div>
59+
<div class="col-md-6 col-lg-3">
60+
{{ order_form.town_or_city | as_crispy_field }}
61+
</div>
62+
<div class="col-md-6 col-lg-3">
63+
{{ order_form.county | as_crispy_field }}
64+
</div>
65+
</div>
66+
<div class="row">
67+
<div class="col-md-6 col-lg-3">
68+
{{ order_form.country | as_crispy_field }}
69+
</div>
70+
<div class="col-md-6 col-lg-3">
71+
{{ order_form.postcode | as_crispy_field }}
72+
</div>
73+
</div>
74+
<div class="row">
75+
<legend>Payment Details</legend>
76+
<div class="col-md-12 col-lg-6">
77+
{{ payment_form.credit_card_number | as_crispy_field }}
78+
</div>
79+
</div>
80+
<div class="row">
81+
<div class="col-6 col-lg-2">
82+
{{ payment_form.expiry_month | as_crispy_field }}
83+
</div>
84+
<div class="col-6 col-lg-2">
85+
{{ payment_form.expiry_year | as_crispy_field }}
86+
</div>
87+
<div class="col-6 col-lg-2">
88+
{{ payment_form.cvv | as_crispy_field }}
89+
</div>
90+
</div>
91+
<hr>
92+
{{ payment_form.stripe_id | as_crispy_field }}
93+
<div class="col-md-12">
94+
<input class=" btn btn-primary" id="submit_payment_btn" name="commit" type="submit"
95+
value="Submit Payment">
96+
<a href="{% url 'tickets' %}" class="float-right">Cancel</a>
97+
</div>
98+
</div>
99+
</form>
100+
</div>
101+
</div>
102+
</div>
103+
{% endblock %}

0 commit comments

Comments
 (0)