- {{ ticket_type.name }}
+ {{ product.name }}
|
- {{ ticket_type.price }} DKK
+ {{ product.price }} DKK
|
- {{ ticket_type.available_in.lower }}
- {% if ticket_type.available_in.upper %}
- - {{ ticket_type.available_in.upper }}
+ {{ product.available_in.lower }}
+ {% if product.available_in.upper %}
+ - {{ product.available_in.upper }}
{% endif %}
|
- {% if ticket_type.is_available %}
-
+ {% if product.is_available %}
+
Order
{% else %}
@@ -47,7 +47,7 @@ Here you can see the different ticket types, their prices and availability.
-
+{% comment %}
{% if user.is_authenticated %}
Your tickets
@@ -71,5 +71,6 @@ Here you can see the different ticket types, their prices and availability.
Sign up or
login to buy tickets.
{% endif %}
+{% endcomment %}
{% endblock %}
diff --git a/tickets/templates/tickets/order.html b/shop/templates/shop/order.html
similarity index 100%
rename from tickets/templates/tickets/order.html
rename to shop/templates/shop/order.html
diff --git a/tickets/tests.py b/shop/tests.py
similarity index 100%
rename from tickets/tests.py
rename to shop/tests.py
diff --git a/shop/urls.py b/shop/urls.py
new file mode 100644
index 00000000..5b77c68e
--- /dev/null
+++ b/shop/urls.py
@@ -0,0 +1,27 @@
+from django.conf.urls import url
+
+from .views import (
+ ShopIndexView,
+ # EpayView,
+ # EpayCallbackView,
+)
+
+urlpatterns = [
+ #url(r'order/$', TicketOrderView.as_view(), name='order'),
+ #url(
+ #r'pay/credit_card/(?P[a-zA-Z0-9\-]+)/$',
+ #EpayView.as_view(),
+ #name='epay_form'
+ #),
+ #url(
+ #r'epay_callback/',
+ #EpayCallbackView,
+ #name='epay_callback'
+ #),
+ #url(
+ #r'detail/(?P[a-zA-Z0-9\-]+)/$',
+ #TicketDetailView.as_view(),
+ #name='detail'
+ #),
+ url(r'$', ShopIndexView.as_view(), name='index'),
+]
diff --git a/shop/views.py b/shop/views.py
new file mode 100644
index 00000000..a0efa63d
--- /dev/null
+++ b/shop/views.py
@@ -0,0 +1,102 @@
+import hashlib
+
+from django.http import HttpResponseRedirect, Http404
+from django.views.generic import CreateView, TemplateView, DetailView, View
+from django.core.urlresolvers import reverse_lazy
+from django.conf import settings
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.http import HttpResponse
+
+from .models import Order, Product, EpayCallback, EpayPayment
+
+
+class ShopIndexView(TemplateView):
+ template_name = "shop/index.html"
+
+ def get_context_data(self, **kwargs):
+ context = super(ShopIndexView, self).get_context_data(**kwargs)
+ context['tickets'] = Product.objects.filter(category__name='Tickets')
+ return context
+
+
+class ProductDetailView(LoginRequiredMixin, DetailView):
+ model = Product
+ template_name = 'product/detail.html'
+ context_object_name = 'product'
+
+
+# class EpayView(TemplateView):
+# template_name = 'tickets/epay_form.html'
+#
+# def get_context_data(self, **kwargs):
+# ticket = Ticket.objects.get(pk=kwargs.get('ticket_id'))
+# accept_url = ticket.get_absolute_url()
+# amount = ticket.ticket_type.price * 100
+# order_id = str(ticket.pk)
+# description = str(ticket.user.pk)
+#
+# hashstring = (
+# '{merchant_number}{description}11{amount}DKK'
+# '{order_id}{accept_url}{md5_secret}'
+# ).format(
+# merchant_number=settings.EPAY_MERCHANT_NUMBER,
+# description=description,
+# amount=str(amount),
+# order_id=str(order_id),
+# accept_url=accept_url,
+# md5_secret=settings.EPAY_MD5_SECRET,
+# )
+# epay_hash = hashlib.md5(hashstring).hexdigest()
+#
+# context = super(EpayView, self).get_context_data(**kwargs)
+# context['merchant_number'] = settings.EPAY_MERCHANT_NUMBER
+# context['description'] = description
+# context['order_id'] = order_id
+# context['accept_url'] = accept_url
+# context['amount'] = amount
+# context['epay_hash'] = epay_hash
+# return context
+#
+#
+# class EpayCallbackView(View):
+#
+# def get(self, request, **kwargs):
+#
+# callback = EpayCallback.objects.create(
+# payload=request.GET
+# )
+#
+# if 'orderid' in request.GET:
+# ticket = Ticket.objects.get(pk=request.GET.get('order_id'))
+# query = dict(
+# map(
+# lambda x: tuple(x.split('=')),
+# request.META['QUERY_STRING'].split('&')
+# )
+# )
+#
+# hashstring = (
+# '{merchant_number}{description}11{amount}DKK'
+# '{order_id}{accept_url}{md5_secret}'
+# ).format(
+# merchant_number=query.get('merchantnumber'),
+# description=query.get('description'),
+# amount=query.get('amount'),
+# order_id=query.get('orderid'),
+# accept_url=query.get('accepturl'),
+# md5_secret=settings.EPAY_MD5_SECRET,
+# )
+# epay_hash = hashlib.md5(hashstring).hexdigest()
+#
+# if not epay_hash == request.GET['hash']:
+# return HttpResponse(status=400)
+#
+# EpayPayment.objects.create(
+# ticket=ticket,
+# callback=callback,
+# txnid=request.GET['txnid'],
+# )
+# else:
+# return HttpResponse(status=400)
+#
+# return HttpResponse('OK')
diff --git a/tickets/admin.py b/tickets/admin.py
deleted file mode 100644
index 6519db95..00000000
--- a/tickets/admin.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from django.contrib import admin
-
-from .models import Ticket, TicketType
-
-
-@admin.register(Ticket)
-class TicketAdmin(admin.ModelAdmin):
- list_display = [
- 'user',
- 'ticket_type',
- 'payment_method',
- 'paid',
- ]
-
- list_filter = [
- 'paid',
- 'ticket_type',
- 'payment_method',
- ]
-
-
-@admin.register(TicketType)
-class TicketTypeAdmin(admin.ModelAdmin):
- list_display = [
- 'name',
- 'price',
- 'available_in',
- 'camp',
- ]
diff --git a/tickets/apps.py b/tickets/apps.py
deleted file mode 100644
index 3ea742ac..00000000
--- a/tickets/apps.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from django.apps import AppConfig
-
-
-class TicketsConfig(AppConfig):
- name = 'tickets'
diff --git a/tickets/forms.py b/tickets/forms.py
deleted file mode 100644
index 8cd05fee..00000000
--- a/tickets/forms.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from django import forms
-from .models import Ticket, TicketType
-
-
-class TicketForm(forms.ModelForm):
-
- class Meta:
- model = Ticket
- fields = [
- 'ticket_type',
- 'payment_method',
- ]
- widgets = {
- 'payment_method': forms.RadioSelect()
- }
-
- ticket_type = forms.ModelChoiceField(
- queryset=TicketType.objects.available()
- )
-
-
diff --git a/tickets/migrations/0001_initial.py b/tickets/migrations/0001_initial.py
deleted file mode 100644
index f70ef453..00000000
--- a/tickets/migrations/0001_initial.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9.2 on 2016-04-22 20:19
-from __future__ import unicode_literals
-
-from django.conf import settings
-import django.contrib.postgres.fields.ranges
-from django.db import migrations, models
-import django.db.models.deletion
-import uuid
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- ('camps', '0003_auto_20160422_2019'),
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Ticket',
- fields=[
- ('created', models.DateTimeField(auto_now_add=True)),
- ('updated', models.DateTimeField(auto_now=True)),
- ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
- ('paid', models.BooleanField(default=False, help_text='Whether the user has paid.', verbose_name='Paid?')),
- ('camp', models.ForeignKey(help_text='The camp this ticket is for.', on_delete=django.db.models.deletion.CASCADE, to='camps.Camp', verbose_name='Camp')),
- ],
- options={
- 'verbose_name_plural': 'Tickets',
- 'verbose_name': 'Ticket',
- },
- ),
- migrations.CreateModel(
- name='TicketType',
- fields=[
- ('created', models.DateTimeField(auto_now_add=True)),
- ('updated', models.DateTimeField(auto_now=True)),
- ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
- ('name', models.CharField(max_length=100)),
- ('price', models.IntegerField(help_text='Price of the ticket (in DKK).')),
- ('available_in', django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='Which period is this ticket available for purchase?')),
- ('camp', models.ForeignKey(help_text='The camp this ticket type is for.', on_delete=django.db.models.deletion.CASCADE, to='camps.Camp', verbose_name='Camp')),
- ],
- options={
- 'verbose_name_plural': 'Ticket Types',
- 'verbose_name': 'Ticket Type',
- },
- ),
- migrations.AddField(
- model_name='ticket',
- name='ticket_type',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType'),
- ),
- migrations.AddField(
- model_name='ticket',
- name='user',
- field=models.ForeignKey(help_text='The user this ticket belongs to.', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
- ),
- ]
diff --git a/tickets/migrations/0002_auto_20160506_1602.py b/tickets/migrations/0002_auto_20160506_1602.py
deleted file mode 100644
index 14455c1d..00000000
--- a/tickets/migrations/0002_auto_20160506_1602.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9.5 on 2016-05-06 16:02
-from __future__ import unicode_literals
-
-import django.contrib.postgres.fields.ranges
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('tickets', '0001_initial'),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name='ticket',
- name='camp',
- ),
- migrations.AlterField(
- model_name='ticket',
- name='ticket_type',
- field=models.ForeignKey(help_text='The type of the ticket.', on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType', verbose_name='Ticket type'),
- ),
- migrations.AlterField(
- model_name='tickettype',
- name='available_in',
- field=django.contrib.postgres.fields.ranges.DateTimeRangeField(help_text='Which period is this ticket available for purchase? | (Format: YYYY-MM-DD HH:MM) | Only one of start/end is required'),
- ),
- migrations.AlterField(
- model_name='tickettype',
- name='name',
- field=models.CharField(max_length=150),
- ),
- ]
diff --git a/tickets/migrations/0003_auto_20160506_2016.py b/tickets/migrations/0003_auto_20160506_2016.py
deleted file mode 100644
index ae2d5f46..00000000
--- a/tickets/migrations/0003_auto_20160506_2016.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9.5 on 2016-05-06 20:16
-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 = [
- ('tickets', '0002_auto_20160506_1602'),
- ]
-
- operations = [
- migrations.AlterModelOptions(
- name='tickettype',
- options={'ordering': ['available_in'], 'verbose_name': 'Ticket Type', 'verbose_name_plural': 'Ticket Types'},
- ),
- migrations.AlterField(
- model_name='ticket',
- name='ticket_type',
- field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.TicketType', verbose_name='Ticket type'),
- ),
- migrations.AlterField(
- model_name='ticket',
- name='user',
- field=models.ForeignKey(help_text='The user this ticket belongs to.', on_delete=django.db.models.deletion.CASCADE, related_name='tickets', to=settings.AUTH_USER_MODEL, verbose_name='User'),
- ),
- ]
diff --git a/tickets/migrations/0004_ticket_payment_method.py b/tickets/migrations/0004_ticket_payment_method.py
deleted file mode 100644
index ed92e3b2..00000000
--- a/tickets/migrations/0004_ticket_payment_method.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9.5 on 2016-05-08 11:21
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('tickets', '0003_auto_20160506_2016'),
- ]
-
- operations = [
- migrations.AddField(
- model_name='ticket',
- name='payment_method',
- field=models.CharField(choices=[('credit_card', 'Credit card'), ('altcoin', 'Altcoin'), ('bank_transfer', 'Bank transfer')], default='credit_card', max_length=50),
- ),
- ]
diff --git a/tickets/urls.py b/tickets/urls.py
deleted file mode 100644
index 9783e74a..00000000
--- a/tickets/urls.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from django.conf.urls import url
-
-from .views import (
- TicketIndexView,
- TicketOrderView,
- TicketDetailView,
- EpayView,
- EpayCallbackView,
-)
-
-urlpatterns = [
- url(r'order/$', TicketOrderView.as_view(), name='order'),
- url(
- r'pay/credit_card/(?P[a-zA-Z0-9\-]+)/$',
- EpayView.as_view(),
- name='epay_form'
- ),
- url(
- r'epay_callback/',
- EpayCallbackView,
- name='epay_callback'
- ),
- url(
- r'detail/(?P[a-zA-Z0-9\-]+)/$',
- TicketDetailView.as_view(),
- name='detail'
- ),
- url(r'$', TicketIndexView.as_view(), name='index'),
-]
diff --git a/tickets/views.py b/tickets/views.py
deleted file mode 100644
index 4b666b16..00000000
--- a/tickets/views.py
+++ /dev/null
@@ -1,150 +0,0 @@
-import hashlib
-
-from django.http import HttpResponseRedirect, Http404
-from django.views.generic import CreateView, TemplateView, DetailView, View
-from django.core.urlresolvers import reverse_lazy
-from django.conf import settings
-from django.contrib.auth.mixins import LoginRequiredMixin
-from django.http import HttpResponse
-
-from camps.models import Camp
-
-from .models import Ticket, TicketType, EpayPayment, EpayCallback
-from .forms import TicketForm
-
-
-class CampTicketSaleCheck(object):
- def dispatch(self, *args, **kwargs):
- current_camp = Camp.objects.current()
- if current_camp and current_camp.ticket_sale_open:
- return super(CampTicketSaleCheck, self).dispatch(*args, **kwargs)
- raise Http404()
-
-
-class TicketIndexView(CampTicketSaleCheck, TemplateView):
- template_name = "tickets/index.html"
-
- def get_context_data(self, **kwargs):
- context = super(TicketIndexView, self).get_context_data(**kwargs)
- context['ticket_types'] = TicketType.objects.all()
- return context
-
-
-class TicketDetailView(LoginRequiredMixin, CampTicketSaleCheck, DetailView):
- model = Ticket
- template_name = 'tickets/detail.html'
- context_object_name = 'ticket'
-
-
-class TicketOrderView(LoginRequiredMixin, CampTicketSaleCheck, CreateView):
- model = Ticket
- template_name = "tickets/order.html"
- form_class = TicketForm
-
- def get_form_kwargs(self):
- kwargs = super(TicketOrderView, self).get_form_kwargs()
- ticket_type = self.request.GET.get('ticket_type', None)
- if ticket_type:
- kwargs['initial'] = {
- 'ticket_type': ticket_type
- }
-
- return kwargs
-
- def form_valid(self, form):
- instance = form.save(commit=False)
- instance.user = self.request.user
- instance.save()
-
- if instance.payment_method == Ticket.ALTCOIN:
- return HttpResponse('Altcoin')
-
- if instance.payment_method == Ticket.CREDIT_CARD:
- return HttpResponseRedirect(
- reverse_lazy('tickets:epay_form', kwargs={
- 'ticket_id': str(instance.pk)
- })
- )
-
- return HttpResponseRedirect(
- reverse_lazy('tickets:detail', kwargs={
- 'pk': str(instance.pk)
- })
- )
-
-
-class EpayView(TemplateView):
- template_name = 'tickets/epay_form.html'
-
- def get_context_data(self, **kwargs):
- ticket = Ticket.objects.get(pk=kwargs.get('ticket_id'))
- accept_url = ticket.get_absolute_url()
- amount = ticket.ticket_type.price * 100
- order_id = str(ticket.pk)
- description = str(ticket.user.pk)
-
- hashstring = (
- '{merchant_number}{description}11{amount}DKK'
- '{order_id}{accept_url}{md5_secret}'
- ).format(
- merchant_number=settings.EPAY_MERCHANT_NUMBER,
- description=description,
- amount=str(amount),
- order_id=str(order_id),
- accept_url=accept_url,
- md5_secret=settings.EPAY_MD5_SECRET,
- )
- epay_hash = hashlib.md5(hashstring).hexdigest()
-
- context = super(EpayView, self).get_context_data(**kwargs)
- context['merchant_number'] = settings.EPAY_MERCHANT_NUMBER
- context['description'] = description
- context['order_id'] = order_id
- context['accept_url'] = accept_url
- context['amount'] = amount
- context['epay_hash'] = epay_hash
- return context
-
-
-class EpayCallbackView(View):
-
- def get(self, request, **kwargs):
-
- callback = EpayCallback.objects.create(
- payload=request.GET
- )
-
- if 'orderid' in request.GET:
- ticket = Ticket.objects.get(pk=request.GET.get('order_id'))
- query = dict(
- map(
- lambda x: tuple(x.split('=')),
- request.META['QUERY_STRING'].split('&')
- )
- )
-
- hashstring = (
- '{merchant_number}{description}11{amount}DKK'
- '{order_id}{accept_url}{md5_secret}'
- ).format(
- merchant_number=query.get('merchantnumber'),
- description=query.get('description'),
- amount=query.get('amount'),
- order_id=query.get('orderid'),
- accept_url=query.get('accepturl'),
- md5_secret=settings.EPAY_MD5_SECRET,
- )
- epay_hash = hashlib.md5(hashstring).hexdigest()
-
- if not epay_hash == request.GET['hash']:
- return HttpResponse(status=400)
-
- EpayPayment.objects.create(
- ticket=ticket,
- callback=callback,
- txnid=request.GET['txnid'],
- )
- else:
- return HttpResponse(status=400)
-
- return HttpResponse('OK')
|