check carte sur serveur cashless
This commit is contained in:
parent
a5b64511f6
commit
b9f8324333
|
|
@ -97,9 +97,45 @@ staff_admin_site.register(TermUser, TermUserAdmin)
|
|||
|
||||
|
||||
########################################################################
|
||||
class ConfigurationAdmin(SingletonModelAdmin):
|
||||
# readonly_fields = []
|
||||
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (
|
||||
'organisation',
|
||||
'short_description',
|
||||
'adresse',
|
||||
'phone',
|
||||
'email',
|
||||
'twitter',
|
||||
'facebook',
|
||||
'instagram',
|
||||
'img',
|
||||
)
|
||||
}),
|
||||
('Paiements', {
|
||||
'fields': (
|
||||
'mollie_api_key',
|
||||
),
|
||||
}),
|
||||
('Billetterie', {
|
||||
'fields': (
|
||||
'jauge_max',
|
||||
'option_generale_radio',
|
||||
'option_generale_checkbox',
|
||||
),
|
||||
}),
|
||||
('Cashless', {
|
||||
'fields': (
|
||||
'server_cashless',
|
||||
'key_cashless',
|
||||
),
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
staff_admin_site.register(Configuration, SingletonModelAdmin)
|
||||
staff_admin_site.register(Configuration, ConfigurationAdmin)
|
||||
|
||||
|
||||
class EventAdmin(admin.ModelAdmin):
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from TiBillet import settings
|
|||
from djoser import utils
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class activate(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
|
|
@ -22,7 +23,7 @@ class activate(APIView):
|
|||
print(uid)
|
||||
print(token)
|
||||
|
||||
import ipdb; ipdb.set_trace()
|
||||
# import ipdb; ipdb.set_trace()
|
||||
user = User.objects.get(pk=utils.decode_uid(uid))
|
||||
|
||||
PR = PasswordResetTokenGenerator()
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from stdimage import StdImageField
|
||||
from stdimage.validators import MaxSizeValidator
|
||||
|
||||
from PaiementStripe.models import Paiement_stripe
|
||||
from TiBillet import settings
|
||||
|
||||
|
||||
|
||||
class OptionGenerale(models.Model):
|
||||
name = models.CharField(max_length=30)
|
||||
poids = models.PositiveSmallIntegerField(default=0, verbose_name=_("Poids"))
|
||||
|
|
@ -28,7 +30,7 @@ class OptionGenerale(models.Model):
|
|||
|
||||
|
||||
@receiver(post_save, sender=OptionGenerale)
|
||||
def poids_option_generaler(sender, instance: OptionGenerale, created, **kwargs):
|
||||
def poids_option_generale(sender, instance: OptionGenerale, created, **kwargs):
|
||||
if created:
|
||||
# poids d'apparition
|
||||
if instance.poids == 0:
|
||||
|
|
@ -76,6 +78,20 @@ class Configuration(SingletonModel):
|
|||
related_name="checkbox")
|
||||
|
||||
|
||||
server_cashless = models.URLField(
|
||||
max_length=300,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Adresse du serveur Cashless"
|
||||
)
|
||||
|
||||
key_cashless = models.CharField(
|
||||
max_length=41,
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Clé d'API du serveur cashless"
|
||||
)
|
||||
|
||||
class Billet(models.Model):
|
||||
name = models.CharField(max_length=50,
|
||||
blank=True, null=True)
|
||||
|
|
@ -133,6 +149,9 @@ class Event(models.Model):
|
|||
else:
|
||||
return False
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.datetime.strftime('%d/%m')} {self.name}"
|
||||
|
||||
class Meta:
|
||||
ordering = ('datetime',)
|
||||
verbose_name = _('Evenement')
|
||||
|
|
@ -189,7 +208,7 @@ class Reservation(models.Model):
|
|||
return " - ".join([f"{option.name}" for option in self.options.all()])
|
||||
|
||||
@receiver(post_save, sender=Reservation)
|
||||
def poids_option_generaler(sender, instance: Reservation, created, **kwargs):
|
||||
def verif_mail_valide(sender, instance: Reservation, created, **kwargs):
|
||||
if created:
|
||||
if not instance.user_commande.is_active :
|
||||
instance.status = instance.MAIL_NON_VALIDEE
|
||||
|
|
@ -199,14 +218,18 @@ def poids_option_generaler(sender, instance: Reservation, created, **kwargs):
|
|||
|
||||
class LigneArticle(models.Model):
|
||||
uuid = models.UUIDField(primary_key=True, db_index=True, default=uuid.uuid4)
|
||||
reservation = models.ForeignKey(Reservation, on_delete=models.CASCADE, verbose_name="lignes_article")
|
||||
reservation = models.ForeignKey(Reservation, on_delete=models.CASCADE, blank=True, null=True)
|
||||
article = models.ForeignKey(Article, on_delete=models.CASCADE, blank=True, null=True)
|
||||
billet = models.ForeignKey(Billet, on_delete=models.CASCADE, blank=True, null=True)
|
||||
qty = models.SmallIntegerField()
|
||||
reste = models.SmallIntegerField()
|
||||
paiement_stripe = models.ForeignKey(Paiement_stripe, on_delete=models.PROTECT, blank=True, null=True)
|
||||
|
||||
# def __str__(self):
|
||||
# if self.reservation :
|
||||
# if self.article :
|
||||
# return f"{self.reservation.user_commande.email} {self.qty} {self.article}"
|
||||
# if self.billet :
|
||||
# return f"{self.reservation.user_commande.email} {self.qty} {self.billet}"
|
||||
|
||||
|
||||
def __str__(self):
|
||||
if self.article :
|
||||
return f"{self.reservation.user_commande.email} {self.qty} {self.article}"
|
||||
if self.billet :
|
||||
return f"{self.reservation.user_commande.email} {self.qty} {self.billet}"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PaiementstripeConfig(AppConfig):
|
||||
name = 'PaiementStripe'
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
from django.db import models
|
||||
import uuid
|
||||
# Create your models here.
|
||||
|
||||
|
||||
class Paiement_stripe(models.Model):
|
||||
"""
|
||||
La commande
|
||||
"""
|
||||
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, db_index=True)
|
||||
|
||||
id_stripe = models.CharField(max_length=20, blank=True, null=True)
|
||||
|
||||
order_date = models.DateTimeField(auto_now=True, verbose_name="Date")
|
||||
|
||||
NON, OPEN, PENDING, PAID, VALID, CANCELED = 'N', 'O', 'W', 'P', 'V', 'C'
|
||||
STATUT_CHOICES = (
|
||||
(NON, 'Lien de paiement non crée'),
|
||||
(OPEN, 'Envoyée a Stripe'),
|
||||
(PENDING, 'En attente de paiement'),
|
||||
(PAID, 'Payée'),
|
||||
(VALID, 'Payée et validée'), # envoyé sur serveur cashless
|
||||
(CANCELED, 'Annulée'),
|
||||
)
|
||||
status = models.CharField(max_length=1, choices=STATUT_CHOICES, default=NON, verbose_name="Statut de la commande")
|
||||
|
||||
# a remplir par default sur le front par User.email.
|
||||
email_billet = models.CharField(max_length=30, verbose_name="Email de récéption des billets", blank=True)
|
||||
|
||||
# def total(self):
|
||||
# total = 0
|
||||
# for article in ArticleCommande.objects.filter(commande=self):
|
||||
# total += article.total()
|
||||
#
|
||||
# return total
|
||||
|
||||
def __str__(self):
|
||||
return self.status
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class QrcodecashlessConfig(AppConfig):
|
||||
name = 'QrcodeCashless'
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
from Customers.models import Client as Customers_Client
|
||||
|
||||
|
||||
class CarteCashless(models.Model):
|
||||
tag_id = models.CharField(
|
||||
db_index=True,
|
||||
max_length=8,
|
||||
unique=True
|
||||
)
|
||||
|
||||
uuid_qrcode = models.UUIDField(
|
||||
blank=True, null=True,
|
||||
verbose_name='Uuid',
|
||||
)
|
||||
|
||||
number = models.CharField(
|
||||
db_index=True,
|
||||
max_length=8,
|
||||
blank=True,
|
||||
null=True,
|
||||
unique=True
|
||||
)
|
||||
|
||||
origine = models.ForeignKey(Customers_Client, on_delete=models.PROTECT)
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Rechargement Online</title>
|
||||
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
|
||||
<!-- Bootstrap core CSS -->
|
||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Material Design Bootstrap -->
|
||||
{# <link href="css/mdb.min.css" rel="stylesheet">#}
|
||||
<!-- Your custom styles (optional) -->
|
||||
{# <link href="css/style.css" rel="stylesheet">#}
|
||||
</head>
|
||||
<body>
|
||||
<br>
|
||||
<p class="h3 mb-4 text-center">Rechargement Cashless {{ domain.capitalize }}</p>
|
||||
{% if liste_assets %}
|
||||
<p class="h5 mb-5 text-center">Disponible sur votre carte :
|
||||
{% for asset in liste_assets %}
|
||||
<p class="h6 mb-6 text-center"> {{ asset }} </p>
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% else %}
|
||||
<p class="h4 mb-4 text-center">Votre carte est vide.</p>
|
||||
{% endif %}
|
||||
<br>
|
||||
<form class="border border-light p-5" name="form" method="POST">
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
|
||||
<label for="numero_carte">Merci de vérifier votre numéro de la carte cashless ( au dessous du QRCode ) :</label>
|
||||
<input type="text" id="numero_carte_cashless" class="form-control" placeholder="Numéro de la carte cashless"
|
||||
value="{{ numero_carte }}" name="numero_carte_cashless" required="True" readonly>
|
||||
<br>
|
||||
|
||||
<label for="Email">Email :</label>
|
||||
{% if email %}
|
||||
<input type="email" id="Email" class="form-control mb-4" placeholder="E-mail" name="email" required="True"
|
||||
value="{{ email }}">
|
||||
{% else %}
|
||||
<input type="email" id="Email" class="form-control mb-4" placeholder="E-mail" name="email" required="True">
|
||||
{% endif %}
|
||||
|
||||
<br>
|
||||
|
||||
<label for="thune">Somme à recharger (€) :</label>
|
||||
<input id="thune" class="form-control" type="number" min="1" step="any" name="thune" required="True"/>
|
||||
|
||||
|
||||
<button class="btn btn-info btn-block" type="submit">Payer</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
from django.urls import include, path, re_path
|
||||
|
||||
from .views import index_scan
|
||||
|
||||
urlpatterns = [
|
||||
path('<uuid:uuid>', index_scan.as_view()),
|
||||
]
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
import requests, json
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
from django.views import View
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
|
||||
from BaseBillet.models import Configuration
|
||||
|
||||
|
||||
class index_scan(View):
|
||||
template_name = "RechargementWebUuid.html"
|
||||
|
||||
def check_carte(self, uuid):
|
||||
configuration = Configuration.get_solo()
|
||||
# on questionne le serveur cashless pour voir si la carte existe :
|
||||
|
||||
sess = requests.Session()
|
||||
try:
|
||||
reponse = sess.post(
|
||||
f'{configuration.server_cashless}/api/billetterie_endpoint',
|
||||
headers={
|
||||
'Authorization': f'Api-Key {configuration.key_cashless}'
|
||||
},
|
||||
data={
|
||||
'uuid': f'{uuid}',
|
||||
})
|
||||
except requests.exceptions.ConnectionError:
|
||||
reponse = HttpResponse("Serveur non disponible. Merci de revenir ultérieurement.", status=status.HTTP_503_SERVICE_UNAVAILABLE)
|
||||
|
||||
sess.close()
|
||||
return reponse
|
||||
|
||||
def post(self, request, uuid):
|
||||
data = request.POST
|
||||
reponse_server_cashless = self.check_carte(uuid)
|
||||
|
||||
if data.get('numero_carte_cashless') == str(uuid).split('-')[0].upper() and \
|
||||
reponse_server_cashless.status_code == 200:
|
||||
|
||||
userWeb, created = User.objects.get_or_create(
|
||||
username="RechargementWeb",
|
||||
email="rechargementweb@tibillet.re")
|
||||
|
||||
vat, created = VAT.objects.get_or_create(percent=0)
|
||||
|
||||
commande = Commande.objects.create(
|
||||
user=userWeb,
|
||||
email_billet=data.get('email'),
|
||||
)
|
||||
|
||||
art, created = Product.objects.get_or_create(
|
||||
name="CashlessRechargementWeb",
|
||||
price_ttc="1",
|
||||
publish=False,
|
||||
vat=vat
|
||||
)
|
||||
|
||||
ArticleCommande.objects.create(
|
||||
product=art,
|
||||
quantity=data.get('thune'),
|
||||
commande=commande,
|
||||
)
|
||||
|
||||
domain = get_domain(request)
|
||||
sub_domain = str(domain).split('.')[0]
|
||||
absolute_domain = request.build_absolute_uri().partition('/qr')[0]
|
||||
|
||||
Paiement = CreationPaiementMollie(commande, domain,
|
||||
description=f"Rechargez votre carte {sub_domain.capitalize()}",
|
||||
redirectUrl=f"{absolute_domain}/RechargementWebAfterMollie/{commande.uuid}",
|
||||
webhookUrl=f"{absolute_domain}/RechargementWebAfterMollie/{commande.uuid}",
|
||||
numero_carte_cashless=data.get('numero_carte_cashless'))
|
||||
|
||||
if Paiement.is_send():
|
||||
return HttpResponseRedirect(Paiement.is_send())
|
||||
|
||||
|
||||
def get(self, request, uuid):
|
||||
|
||||
# pour rediriger les carte imprimés a la raffinerie vers le bon tenant.
|
||||
address = request.build_absolute_uri()
|
||||
host = address.partition('://')[2]
|
||||
sub_addr = host.partition('.')[0]
|
||||
if sub_addr == "m":
|
||||
return HttpResponseRedirect(address.replace("://m.", "://raffinerie."))
|
||||
|
||||
configuration = Configuration.get_solo()
|
||||
if not configuration.server_cashless:
|
||||
return HttpResponse(
|
||||
"L'adresse du serveur cashless n'est pas renseignée dans la configuration de la billetterie.")
|
||||
|
||||
reponse_server_cashless = self.check_carte(uuid)
|
||||
json_reponse = json.loads(reponse_server_cashless.json())
|
||||
liste_assets = json_reponse.get('liste_assets')
|
||||
email = json_reponse.get('email')
|
||||
|
||||
if reponse_server_cashless.status_code == 200:
|
||||
return render(
|
||||
request,
|
||||
self.template_name,
|
||||
{
|
||||
'numero_carte': str(uuid).split('-')[0].upper(),
|
||||
'domain': sub_addr,
|
||||
'informations_carte': reponse_server_cashless.text,
|
||||
'liste_assets': liste_assets,
|
||||
'email': email,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
elif reponse_server_cashless.status_code == 400:
|
||||
# Carte non trouvée
|
||||
return HttpResponse('Carte inconnue', status=status.HTTP_400_BAD_REQUEST)
|
||||
elif reponse_server_cashless.status_code == 500:
|
||||
# Serveur cashless hors ligne
|
||||
return reponse_server_cashless
|
||||
|
|
@ -43,6 +43,7 @@ SHARED_APPS = (
|
|||
# everything below here is optional
|
||||
'django.contrib.auth',
|
||||
'AuthBillet',
|
||||
'QrcodeCashless',
|
||||
|
||||
'rest_framework',
|
||||
'rest_framework.authtoken',
|
||||
|
|
@ -70,6 +71,7 @@ TENANT_APPS = (
|
|||
|
||||
'BaseBillet',
|
||||
'ApiBillet',
|
||||
'PaiementStripe',
|
||||
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ urlpatterns = [
|
|||
re_path(r'^user/', include('AuthBillet.urls')),
|
||||
|
||||
re_path(r'api/', include('ApiBillet.urls')),
|
||||
re_path(r'qr/', include('QrcodeCashless.urls')),
|
||||
|
||||
|
||||
path('', include('BaseBillet.urls')),
|
||||
|
|
|
|||
Loading…
Reference in New Issue