Ajout membership

This commit is contained in:
Jonas 12t 2021-11-15 10:02:16 +04:00
parent 7299fb55ae
commit 20ec80cad4
11 changed files with 254 additions and 107 deletions

View File

@ -137,6 +137,34 @@ class ReservationSerializer(serializers.ModelSerializer):
] ]
depth = 1 depth = 1
class MembreshipValidator(serializers.Serializer):
email = serializers.EmailField()
first_name = serializers.CharField(max_length=200,)
last_name = serializers.CharField(max_length=200,)
phone = serializers.CharField(max_length=20, required=False)
postal_code = serializers.IntegerField(required=False)
birth_date = serializers.DateField(required=False)
contribution_value = serializers.FloatField()
def validate_email(self, value):
User: TibilletUser = get_user_model()
user_paiement, created = User.objects.get_or_create(
email=value, username=value)
if created:
user_paiement: HumanUser
user_paiement.client_source = connection.tenant
user_paiement.client_achat.add(connection.tenant)
user_paiement.is_active = False
else:
user_paiement.client_achat.add(connection.tenant)
user_paiement.save()
return user_paiement.email
class ReservationValidator(serializers.Serializer): class ReservationValidator(serializers.Serializer):
email = serializers.EmailField() email = serializers.EmailField()
@ -157,7 +185,6 @@ class ReservationValidator(serializers.Serializer):
user_paiement.client_achat.add(connection.tenant) user_paiement.client_achat.add(connection.tenant)
user_paiement.save() user_paiement.save()
self.user_commande = user_paiement
return user_paiement.email return user_paiement.email
def validate_prices(self, value): def validate_prices(self, value):

View File

@ -11,6 +11,7 @@ router.register(r'events', api_view.EventsViewSet, basename='event')
router.register(r'products', api_view.ProductViewSet, basename='product') router.register(r'products', api_view.ProductViewSet, basename='product')
router.register(r'prices', api_view.TarifBilletViewSet, basename='price') router.register(r'prices', api_view.TarifBilletViewSet, basename='price')
router.register(r'reservations', api_view.ReservationViewset, basename='reservation') router.register(r'reservations', api_view.ReservationViewset, basename='reservation')
router.register(r'membership', api_view.MembershipViewset, basename='membership')
urlpatterns = [ urlpatterns = [

View File

@ -11,7 +11,7 @@ from rest_framework.permissions import AllowAny
from rest_framework.response import Response from rest_framework.response import Response
from ApiBillet.serializers import EventSerializer, PriceSerializer, ProductSerializer, ReservationSerializer, \ from ApiBillet.serializers import EventSerializer, PriceSerializer, ProductSerializer, ReservationSerializer, \
ReservationValidator ReservationValidator, MembreshipValidator
from AuthBillet.models import TenantAdminPermission from AuthBillet.models import TenantAdminPermission
from Customers.models import Client, Domain from Customers.models import Client, Domain
from BaseBillet.models import Event, Price, Product, Reservation, Configuration, Ticket from BaseBillet.models import Event, Price, Product, Reservation, Configuration, Ticket
@ -143,54 +143,25 @@ class ReservationViewset(viewsets.ViewSet):
return [permission() for permission in permission_classes] return [permission() for permission in permission_classes]
class Membership(viewsets.ViewSet): class MembershipViewset(viewsets.ViewSet):
permission_classes = [AllowAny]
def send_mail_to_cashless_for_membership(request, data: dict, carte: any): def create(self, request):
sess = requests.Session() print(request.data)
configuration = Configuration.get_solo() validator = MembreshipValidator(data=request.data, context={'request': request})
if validator.is_valid():
# serializer.save()
return Response(validator.data, status=status.HTTP_201_CREATED)
return Response(validator.errors, status=status.HTTP_400_BAD_REQUEST)
r = sess.post(
f'{configuration.server_cashless}/api/billetterie_qrcode_adhesion',
headers={
'Authorization': f'Api-Key {configuration.key_cashless}'
},
data={
'prenom': data.get('prenom'),
'name': data.get('name'),
'email': data.get('email'),
'tel': data.get('tel'),
'uuid_carte': carte.uuid,
})
sess.close()
# nouveau membre crée avec uniquement l'email on demande la suite.
# HTTP_202_ACCEPTED
# HTTP_201_CREATED
if r.status_code in (201, 204):
messages.success(request, f"{data.get('email')}", extra_tags='email')
return HttpResponseRedirect(f'#demande_nom_prenom_tel')
# partial information :
elif r.status_code == 206:
partial = json.loads(r.text)
messages.success(request, f"{data.get('email')}", extra_tags='email')
if partial.get('name'):
messages.success(request, f"Email déja connu. Name déja connu", extra_tags='name')
if partial.get('prenom'):
messages.success(request, f"Email déja connu. prenom déja connu", extra_tags='prenom')
if partial.get('tel'):
messages.success(request, f"Email déja connu. tel déja connu", extra_tags='tel')
return HttpResponseRedirect(f'#demande_nom_prenom_tel')
# nouveau membre crée, on demande la suite.
elif r.status_code == 202:
messages.success(request, f"Carte liée au membre {data.get('email')}")
return HttpResponseRedirect(f'#adhesionsuccess')
def get_permissions(self):
if self.action in ['create']:
permission_classes = [permissions.AllowAny]
else: else:
messages.error(request, f'Erreur {r.status_code} {r.text}') permission_classes = [TenantAdminPermission]
return HttpResponseRedirect(f'#erreur')
return [permission() for permission in permission_classes]
class TicketPdf(WeasyTemplateView): class TicketPdf(WeasyTemplateView):

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2 on 2021-11-12 07:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('AuthBillet', '0004_auto_20211111_1627'),
]
operations = [
migrations.AlterField(
model_name='tibilletuser',
name='first_name',
field=models.CharField(max_length=200),
),
migrations.AlterField(
model_name='tibilletuser',
name='last_name',
field=models.CharField(max_length=200),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2 on 2021-11-12 07:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('AuthBillet', '0005_auto_20211112_1146'),
]
operations = [
migrations.AlterField(
model_name='tibilletuser',
name='first_name',
field=models.CharField(blank=True, max_length=200, null=True),
),
migrations.AlterField(
model_name='tibilletuser',
name='last_name',
field=models.CharField(blank=True, max_length=200, null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 2.2 on 2021-11-15 05:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('AuthBillet', '0006_auto_20211112_1147'),
]
operations = [
migrations.AddField(
model_name='membership',
name='contribution_value',
field=models.FloatField(blank=True, null=True),
),
]

View File

@ -67,6 +67,10 @@ class TibilletUser(AbstractUser):
email = models.EmailField(_('email'), unique=True) # changes email to unique and blank to false email = models.EmailField(_('email'), unique=True) # changes email to unique and blank to false
username = models.CharField(max_length=200, unique=True) username = models.CharField(max_length=200, unique=True)
first_name = models.CharField(max_length=200, null=True, blank=True)
last_name = models.CharField(max_length=200, null=True, blank=True)
phone = models.CharField(max_length=20, null=True, blank=True) phone = models.CharField(max_length=20, null=True, blank=True)
last_see = models.DateTimeField(auto_now=True) last_see = models.DateTimeField(auto_now=True)
@ -216,11 +220,13 @@ class HumanUser(TibilletUser):
class Membership(models.Model): class Membership(models.Model):
user = models.ForeignKey(TibilletUser, on_delete=models.PROTECT, related_name='membership') user = models.ForeignKey(TibilletUser, on_delete=models.PROTECT, related_name='membership')
tenant = models.ForeignKey(Client, on_delete=models.PROTECT) tenant = models.ForeignKey(Client, on_delete=models.PROTECT)
date_added = models.DateTimeField(auto_now_add=True) date_added = models.DateTimeField(auto_now_add=True)
first_contribution = models.DateField(null=True, blank=True) first_contribution = models.DateField(null=True, blank=True)
last_contribution = models.DateField(null=True, blank=True) last_contribution = models.DateField(null=True, blank=True)
contribution_value = models.FloatField(null=True, blank=True)

View File

@ -66,7 +66,7 @@ def set_paiement_and_reservation_valid(old_instance, new_instance):
logger.info( logger.info(
f" TRIGGER LIGNE ARTICLE set_paiement_and_reservation_valid {new_instance.price}. On test si toute les lignes sont validées") f" TRIGGER LIGNE ARTICLE set_paiement_and_reservation_valid {new_instance.price}. On test si toute les lignes sont validées")
# On exclu l'instance en cours car elle n'est pas encore validé en DB comme Valide. # On exclu l'instance en cours car elle n'est pas encore validé en DB comme Valide : on est sur du signal pre_save
# on test ici : Si toute les autre ligne sont valide et que celle ci l'est aussi. # on test ici : Si toute les autre ligne sont valide et que celle ci l'est aussi.
lignes_dans_paiement_stripe = new_instance.paiement_stripe.lignearticle_set.all().exclude( lignes_dans_paiement_stripe = new_instance.paiement_stripe.lignearticle_set.all().exclude(
uuid=new_instance.uuid) uuid=new_instance.uuid)

View File

@ -23,6 +23,7 @@
<!-- START ADHESION MODAL MENU --> <!-- START ADHESION MODAL MENU -->
<div class="search" id="adhesion_one"> <div class="search" id="adhesion_one">
<form method="post" action="#" class="form-search"> <form method="post" action="#" class="form-search">
{% csrf_token %}
<div class="div-label-search"> <div class="div-label-search">
<label for="msg" class="label-search"> <label for="msg" class="label-search">
<span href="pages/artiste.html" class="icone" <span href="pages/artiste.html" class="icone"
@ -41,3 +42,87 @@
</form> </form>
</div> </div>
<!-- END ADHESION MODAL MENU --> <!-- END ADHESION MODAL MENU -->
<!-- START NOM PRENOM TEL MODAL MENU -->
<div class="search" id="demande_nom_prenom_tel">
<h2>Adhésion</h2>
<h2 class="major">{{ client_name }}</h2>
<h4 id="knew_text">Nous avons déja : </h4>
<h4>Il nous manque ces informations pour votre adhésion :</h4>
<form method="post" action="#" class="form-search">
{% csrf_token %}
{% csrf_token %}
<div class="fields">
<input id="adhesion_email" name="email" required="True" type="email" style="display: none"/>
<div id="adhesion_name" class="field half">
<label for="name">Nom</label>
<input id="name" name="name" required="True" type="text"/>
</div>
<div id="adhesion_prenom" class="field half">
<label for="prenom">Prénom</label>
<input id="prenom" name="prenom" required="True" type="text"/>
</div>
<div id="adhesion_tel" class="field half">
<label for="tel">Téléphone</label>
<input id="tel" name="tel" required="True" type="tel"/>
</div>
</div>
<ul class="actions">
<li><input type="submit" value="Adhérer" class="primary"/></li>
</ul>
<a href="#" class="btn-adherer" title="demande_nom_prenom_tel" onClick="asideswipe.call(this);">Fermer</a>
</form>
</div>
<!-- END NOM PRENOM TEL MODAL MENU -->
<!-- START ERROR MODAL MENU -->
<div class="search" id="demande_nom_prenom_tel">
<h2 class="major">ERREUR</h2>
<h3>Oups, Quelque chose s'est mal passé.</h3>
{% if messages %}
{% for message in messages %}
<h3>{{ message }}</h3>
{% endfor %}
{% endif %}
</div>
<!-- END ERROR MODAL MENU -->
{# Script qui n'affiche que les champs dont nous avons besoin lors de l'adhésion #}
<script type="text/javascript">
document.getElementById("knew_text").hidden = true;
{% if messages %}
{% for message in messages %}
{% if message.extra_tags == 'email' %}
document.getElementById("adhesion_email").value = "{{ message }}";
{% endif %}
{% if message.extra_tags == 'name' %}
document.getElementById("adhesion_name").hidden = true;
document.getElementById("name").readOnly = true;
document.getElementById("name").value = "connu";
document.getElementById("knew_text").textContent += "votre nom,";
document.getElementById("knew_text").hidden = false;
{% endif %}
{% if message.extra_tags == 'prenom' %}
document.getElementById("adhesion_prenom").hidden = true;
document.getElementById("prenom").readOnly = true;
document.getElementById("prenom").value = "connu";
document.getElementById("knew_text").textContent += "votre prénom,";
document.getElementById("knew_text").hidden = false;
{% endif %}
{% if message.extra_tags == 'tel' %}
document.getElementById("adhesion_tel").hidden = true;
document.getElementById("tel").readOnly = true;
document.getElementById("tel").value = "connu";
document.getElementById("knew_text").textContent += "votre numéro de téléphone,";
document.getElementById("knew_text").hidden = false;
{% endif %}
{% endfor %}
{% endif %}
</script>

View File

@ -6,19 +6,14 @@ from django.shortcuts import render
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
from rest_framework.views import APIView from rest_framework.views import APIView
from BaseBillet.models import Configuration, Event, Ticket, Product from BaseBillet.models import Configuration, Event, Ticket, Product
import base64
import segno import segno
import barcode import barcode
from djoser import utils from djoser import utils
from io import StringIO, BytesIO from io import BytesIO
from django.template import engines
from django.http import HttpResponse
from PIL import Image
class index(APIView): class index(APIView):
@ -29,11 +24,10 @@ class index(APIView):
if not configuration.activer_billetterie: if not configuration.activer_billetterie:
return HttpResponseRedirect('https://www.tibillet.re') return HttpResponseRedirect('https://www.tibillet.re')
first_event = None
events = Event.objects.filter(datetime__gt=datetime.now()) events = Event.objects.filter(datetime__gt=datetime.now())
if len(events) > 0: if len(events) > 0:
first_event = events[0] first_event = events[0]
else:
first_event = None
context = { context = {
'configuration': configuration, 'configuration': configuration,

View File

@ -3,7 +3,6 @@ from datetime import datetime
import requests, json import requests, json
from django.contrib import messages from django.contrib import messages
from django.db import connection from django.db import connection
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.shortcuts import render from django.shortcuts import render
from django.utils import timezone from django.utils import timezone
@ -11,14 +10,10 @@ from rest_framework.generics import get_object_or_404
from django.views import View from django.views import View
from rest_framework import status from rest_framework import status
from ApiBillet.views import Membership
from BaseBillet.models import Configuration, Product, LigneArticle, Price, Paiement_stripe from BaseBillet.models import Configuration, Product, LigneArticle, Price, Paiement_stripe
from PaiementStripe.views import creation_paiement_stripe from PaiementStripe.views import creation_paiement_stripe
from QrcodeCashless.models import CarteCashless from QrcodeCashless.models import CarteCashless
from django.db.models.signals import pre_save
from django.dispatch import receiver
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -214,49 +209,53 @@ class index_scan(View):
# Email seul sans montant, c'est une adhésion # Email seul sans montant, c'est une adhésion
elif data.get('email'): elif data.get('email'):
return Membership.send_mail_to_cashless_for_membership(request, data, carte) logger.info(f'send_mail_to_cashless_for_membership : {data}')
# sess = requests.Session()
# sess = requests.Session() configuration = Configuration.get_solo()
# configuration = Configuration.get_solo()
# r = sess.post( uuid_carte = None
# f'{configuration.server_cashless}/api/billetterie_qrcode_adhesion', if carte:
# headers={ uuid_carte = carte.uuid
# 'Authorization': f'Api-Key {configuration.key_cashless}'
# }, r = sess.post(
# data={ f'{configuration.server_cashless}/api/billetterie_qrcode_adhesion',
# 'prenom': data.get('prenom'), headers={
# 'name': data.get('name'), 'Authorization': f'Api-Key {configuration.key_cashless}'
# 'email': data.get('email'), },
# 'tel': data.get('tel'), data={
# 'uuid_carte': carte.uuid, 'prenom': data.get('prenom'),
# }) 'name': data.get('name'),
# 'email': data.get('email'),
# sess.close() 'tel': data.get('tel'),
# 'uuid_carte': uuid_carte,
# # nouveau membre crée avec uniquement l'email on demande la suite. })
# # HTTP_202_ACCEPTED
# # HTTP_201_CREATED sess.close()
# if r.status_code in (201, 204):
# messages.success(request, f"{data.get('email')}", extra_tags='email') # nouveau membre crée avec uniquement l'email on demande la suite.
# return HttpResponseRedirect(f'#demande_nom_prenom_tel') # HTTP_202_ACCEPTED
# # HTTP_201_CREATED
# # partial information : if r.status_code in (201, 204):
# elif r.status_code == 206: messages.success(request, f"{data.get('email')}", extra_tags='email')
# partial = json.loads(r.text) return HttpResponseRedirect(f'#demande_nom_prenom_tel')
# messages.success(request, f"{data.get('email')}", extra_tags='email')
# if partial.get('name'): # partial information :
# messages.success(request, f"Email déja connu. Name déja connu", extra_tags='name') elif r.status_code == 206:
# if partial.get('prenom'): partial = json.loads(r.text)
# messages.success(request, f"Email déja connu. prenom déja connu", extra_tags='prenom') messages.success(request, f"{data.get('email')}", extra_tags='email')
# if partial.get('tel'): if partial.get('name'):
# messages.success(request, f"Email déja connu. tel déja connu", extra_tags='tel') messages.success(request, f"Email déja connu. Name déja connu", extra_tags='name')
# return HttpResponseRedirect(f'#demande_nom_prenom_tel') if partial.get('prenom'):
# messages.success(request, f"Email déja connu. prenom déja connu", extra_tags='prenom')
# # nouveau membre crée, on demande la suite. if partial.get('tel'):
# elif r.status_code == 202: messages.success(request, f"Email déja connu. tel déja connu", extra_tags='tel')
# messages.success(request, f"Carte liée au membre {data.get('email')}") return HttpResponseRedirect(f'#demande_nom_prenom_tel')
# return HttpResponseRedirect(f'#adhesionsuccess')
# # nouveau membre crée, on demande la suite.
# else: elif r.status_code == 202:
# messages.error(request, f'Erreur {r.status_code} {r.text}') messages.success(request, f"Carte liée au membre {data.get('email')}")
# return HttpResponseRedirect(f'#erreur') return HttpResponseRedirect(f'#adhesionsuccess')
else:
messages.error(request, f'Erreur {r.status_code} {r.text}')
return HttpResponseRedirect(f'#erreur')