Skip to content
This repository has been archived by the owner on Mar 16, 2018. It is now read-only.

Compostage #11

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
models.Categorie,
models.Client,
models.Order,
models.Participant)
models.Participant,
models.Compostage,
models.File,
)
class BasicAdmin(admin.ModelAdmin):
pass
28 changes: 28 additions & 0 deletions api/migrations/0012_compostage_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-14 17:00
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0011_auto_20171211_1858'),
]

operations = [

migrations.CreateModel(
name='File',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nom', models.CharField(max_length=100)),
('active', models.BooleanField(default=False)),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Event')),
('file_parente', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='api.File')),
('product_type', models.ManyToManyField(blank=True, null=True, to='api.Product')),
],
),
]
20 changes: 20 additions & 0 deletions api/migrations/0013_auto_20171214_1801.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-14 17:01
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0012_compostage_file'),
]

operations = [
migrations.AlterField(
model_name='file',
name='product_type',
field=models.ManyToManyField(blank=True, to='api.Product'),
),
]
26 changes: 26 additions & 0 deletions api/migrations/0014_auto_20171214_1808.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-14 17:08
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0013_auto_20171214_1801'),
]

operations = [
migrations.AddField(
model_name='file',
name='option_type',
field=models.ManyToManyField(blank=True, to='api.Option'),
),
migrations.AddField(
model_name='file',
name='validation_type',
field=models.IntegerField(choices=[(0, 'Aucun mode défini'), (1, 'Validation de produits'), (2, "Validation d'options")], default=0),
preserve_default=False,
),
]
20 changes: 20 additions & 0 deletions api/migrations/0015_auto_20171214_1808.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-14 17:08
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0014_auto_20171214_1808'),
]

operations = [
migrations.AlterField(
model_name='file',
name='validation_type',
field=models.IntegerField(choices=[(0, 'Aucun mode défini'), (1, 'Validation de produits'), (2, "Validation d'options")], default=0),
),
]
30 changes: 30 additions & 0 deletions api/migrations/0016_auto_20171214_1821.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-12-14 17:21
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0015_auto_20171214_1808'),
]

operations = [
migrations.CreateModel(
name='Compostage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateTimeField(auto_created=True)),
('billet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Billet')),
('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.File')),
],
),
migrations.AddField(
model_name='billet',
name='files',
field=models.ManyToManyField(blank=True, through='api.Compostage', to='api.File'),
),
]
41 changes: 36 additions & 5 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,39 @@
)


class File(models.Model):
"""
Représente un file de lecture de billet
"""
VALIDATION_MODES = (
(0, "Aucun mode défini"),
(1, "Validation de produits"),
(2, "Validation d'options"),
)

nom = models.CharField(max_length=100)
event = models.ForeignKey('Event')
active = models.BooleanField(default=False)
file_parente = models.ForeignKey('File', null=True, blank=True)
product_type = models.ManyToManyField('Product', blank=True)
option_type = models.ManyToManyField('Option', blank=True)
validation_type = models.IntegerField(choices=VALIDATION_MODES, default=0)

def __str__(self):
return "File {}".format(self.nom)

class Compostage(models.Model):
"""
Fait la liaison entre les files et les billets.
"""
billet = models.ForeignKey("Billet")
file = models.ForeignKey("File")
date = models.DateTimeField(auto_created=True,auto_now_add=True)

def __str__(self):
return "Billet "+ str(self.billet.id) +" validé à la file "+ str(self.file.nom)


class Membership(models.Model):
LEVEL_ADMIN = 0
LEVEL_MANAGER = 100
Expand Down Expand Up @@ -134,7 +167,7 @@ def reserved_units(self, billets=None):
return billets.filter(product=self).aggregate(total=Count('id'))['total']
if type(self) is Option:
return BilletOption.objects.filter(billet__in=billets, option=self) \
.aggregate(total=Sum('amount'))['total'] or 0
.aggregate(total=Sum('amount'))['total'] or 0

def reserved_seats(self, billets=None):
return self.reserved_units(billets) * (self.seats or 1)
Expand Down Expand Up @@ -241,6 +274,7 @@ class Billet(models.Model):
product = models.ForeignKey(Product, null=True, blank=True, related_name='billets')
options = models.ManyToManyField(Option, through=BilletOption, related_name='billets')
order = models.ForeignKey('Order', null=True, related_name='billets')
files = models.ManyToManyField(File,through='Compostage',blank=True)

@staticmethod
def validated():
Expand Down Expand Up @@ -347,7 +381,6 @@ def __str__(self):


class Answer(models.Model):

order = models.ForeignKey('Order', related_name='answers')
question = models.ForeignKey(Question)
participant = models.ForeignKey(Participant, null=True, blank=True)
Expand Down Expand Up @@ -434,7 +467,7 @@ class Meta:
updated_at = models.DateTimeField(auto_now=True)
client = models.ForeignKey(Client, blank=True, null=True, related_name="orders")
status = models.IntegerField(verbose_name=_('status'), default=0, choices=STATUSES)
transaction = models.ForeignKey(TransactionRequest,default=None, null=True)
transaction = models.ForeignKey(TransactionRequest, default=None, null=True)
event = models.ForeignKey(Event)

def destroy_all(self):
Expand Down Expand Up @@ -508,5 +541,3 @@ def update_order_on_card_transaction(instance, **kwargs):
order.save()
except Order.DoesNotExist:
pass


8 changes: 7 additions & 1 deletion api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@
from rest_framework.relations import PrimaryKeyRelatedField

from api import models
from api.models import Billet, Product, Option
from api.models import Billet, Product, Option, Compostage


class CompostageSerializer(serializers.ModelSerializer):
class Meta:
model = Compostage
fields = ("id","billet","file")
depth = 0

class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
Expand Down
2 changes: 2 additions & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
router.register(r'options', views.OptionViewSet, 'options')
router.register(r'billets', views.BilletViewSet, 'billet')
router.register(r'order', views.OrderViewSet, 'orders')
router.register(r'compostages',views.CompostageViewSet,'compostages')

admin_router = routers.SimpleRouter()
admin_router.register(r'events', admin.EventViewSet, 'events')
Expand All @@ -19,6 +20,7 @@
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^billetcheck/', views.billet_check),
url(r'^authenticate/invitation$', views.InvitationAuthentication.as_view()),
url(r'^authenticate$', obtain_jwt_token),
url(r'^authenticate/refresh$', refresh_jwt_token),
Expand Down
48 changes: 43 additions & 5 deletions api/views.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
from datetime import datetime, timedelta

from django.core.exceptions import ValidationError
from django.core.signing import TimestampSigner
from django.core.signing import TimestampSigner, Signer
from django.db import transaction
from django.utils.decorators import method_decorator
from django.utils import timezone
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from rest_framework import viewsets, status
from rest_framework.decorators import detail_route, authentication_classes, permission_classes
from rest_framework.decorators import detail_route, authentication_classes, permission_classes, api_view
from rest_framework.exceptions import APIException
from rest_framework.permissions import IsAuthenticated
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_jwt.settings import api_settings

from api import permissions
from api.models import Event, Order, Option, Product, Billet, Categorie, Invitation, Client, BilletOption
from api.models import Event, Order, Option, Product, Billet, Categorie, Invitation, File, BilletOption, Compostage
from api.permissions import IsEventManager
from api.serializers import BilletSerializer, CategorieSerializer, InvitationSerializer, ParticipantSerializer, \
AnswerSerializer, BilletOptionSerializer, BilletOptionInputSerializer, UserSerializer
AnswerSerializer, BilletOptionSerializer, BilletOptionInputSerializer, UserSerializer, CompostageSerializer
from mercanet.models import TransactionRequest
from .serializers import EventSerializer, OrderSerializer, OptionSerializer, \
ProductSerializer
Expand All @@ -27,6 +28,43 @@
plus_disponible_view = Response("Ce que vous demandez n'est plus disponible", status=status.HTTP_200_OK)
invalid_request_view = Response("Requête invalide, les paramètres spécifiés dans le POST sont non conformes",
status=status.HTTP_400_BAD_REQUEST)
@csrf_exempt
@api_view(['GET','POST'])
@permission_classes((AllowAny,))
@detail_route(methods=["POST"])
def billet_check(request):
"""
Prend en paramètre POST id l'id signé du billet. Nécessite d'être authentifié en tant que manager de l'évenement

:return: Le billet si il existe.
"""
data = request.data['id']
id = Signer().unsign(data)

return Response(BilletSerializer(Billet.objects.get(id=id)).data)

class CompostageViewSet(viewsets.ModelViewSet):
"""
Le viewset pour les compostages: @see le model Compostage
"""
queryset = Compostage.objects.all()
serializer_class = CompostageSerializer
permission_classes = [AllowAny]

def create(self, request, *args, **kwargs):
try:
file = File.objects.get(id=request.data['file'])

if Compostage.objects.filter(billet=request.data["billet"], file=file.id).count()>0:
return Response("Attention ! Ce billet a déja été validé")

compostage = Compostage(billet=Billet.objects.get(id=request.data["billet"]),file=file)
compostage.save()
return Response(CompostageSerializer(compostage).data)
except File.DoesNotExist as e:
return Response("La file demandée n'existe pas !")
except Billet.DoesNotExist as e:
return Response("le billet demandé n'existe pas !")


class EventsViewSet(viewsets.ModelViewSet):
Expand Down