From b9f832433358e86c424ba90babdb20ee19d58a70 Mon Sep 17 00:00:00 2001
From: Jonas 12t
Date: Thu, 23 Sep 2021 16:14:59 +0400
Subject: [PATCH] check carte sur serveur cashless
---
DjangoFiles/Administration/admin_tenant.py | 38 +++++-
DjangoFiles/AuthBillet/views.py | 3 +-
DjangoFiles/BaseBillet/models.py | 39 ++++--
DjangoFiles/PaiementStripe/__init__.py | 0
DjangoFiles/PaiementStripe/admin.py | 3 +
DjangoFiles/PaiementStripe/apps.py | 5 +
.../PaiementStripe/migrations/__init__.py | 0
DjangoFiles/PaiementStripe/models.py | 41 ++++++
DjangoFiles/PaiementStripe/tests.py | 3 +
DjangoFiles/PaiementStripe/views.py | 3 +
DjangoFiles/QrcodeCashless/__init__.py | 0
DjangoFiles/QrcodeCashless/admin.py | 3 +
DjangoFiles/QrcodeCashless/apps.py | 5 +
.../QrcodeCashless/migrations/__init__.py | 0
DjangoFiles/QrcodeCashless/models.py | 27 ++++
.../templates/RechargementWebUuid.html | 61 +++++++++
DjangoFiles/QrcodeCashless/tests.py | 3 +
DjangoFiles/QrcodeCashless/urls.py | 7 ++
DjangoFiles/QrcodeCashless/views.py | 119 ++++++++++++++++++
DjangoFiles/TiBillet/settings.py | 2 +
DjangoFiles/TiBillet/urls_tenants.py | 1 +
21 files changed, 353 insertions(+), 10 deletions(-)
create mode 100644 DjangoFiles/PaiementStripe/__init__.py
create mode 100644 DjangoFiles/PaiementStripe/admin.py
create mode 100644 DjangoFiles/PaiementStripe/apps.py
create mode 100644 DjangoFiles/PaiementStripe/migrations/__init__.py
create mode 100644 DjangoFiles/PaiementStripe/models.py
create mode 100644 DjangoFiles/PaiementStripe/tests.py
create mode 100644 DjangoFiles/PaiementStripe/views.py
create mode 100644 DjangoFiles/QrcodeCashless/__init__.py
create mode 100644 DjangoFiles/QrcodeCashless/admin.py
create mode 100644 DjangoFiles/QrcodeCashless/apps.py
create mode 100644 DjangoFiles/QrcodeCashless/migrations/__init__.py
create mode 100644 DjangoFiles/QrcodeCashless/models.py
create mode 100644 DjangoFiles/QrcodeCashless/templates/RechargementWebUuid.html
create mode 100644 DjangoFiles/QrcodeCashless/tests.py
create mode 100644 DjangoFiles/QrcodeCashless/urls.py
create mode 100644 DjangoFiles/QrcodeCashless/views.py
diff --git a/DjangoFiles/Administration/admin_tenant.py b/DjangoFiles/Administration/admin_tenant.py
index a843b11..973aceb 100644
--- a/DjangoFiles/Administration/admin_tenant.py
+++ b/DjangoFiles/Administration/admin_tenant.py
@@ -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):
diff --git a/DjangoFiles/AuthBillet/views.py b/DjangoFiles/AuthBillet/views.py
index 6e67343..1e9c394 100644
--- a/DjangoFiles/AuthBillet/views.py
+++ b/DjangoFiles/AuthBillet/views.py
@@ -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()
diff --git a/DjangoFiles/BaseBillet/models.py b/DjangoFiles/BaseBillet/models.py
index 5e610f8..4d9b910 100644
--- a/DjangoFiles/BaseBillet/models.py
+++ b/DjangoFiles/BaseBillet/models.py
@@ -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}"
diff --git a/DjangoFiles/PaiementStripe/__init__.py b/DjangoFiles/PaiementStripe/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/DjangoFiles/PaiementStripe/admin.py b/DjangoFiles/PaiementStripe/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/DjangoFiles/PaiementStripe/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/DjangoFiles/PaiementStripe/apps.py b/DjangoFiles/PaiementStripe/apps.py
new file mode 100644
index 0000000..12f2881
--- /dev/null
+++ b/DjangoFiles/PaiementStripe/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class PaiementstripeConfig(AppConfig):
+ name = 'PaiementStripe'
diff --git a/DjangoFiles/PaiementStripe/migrations/__init__.py b/DjangoFiles/PaiementStripe/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/DjangoFiles/PaiementStripe/models.py b/DjangoFiles/PaiementStripe/models.py
new file mode 100644
index 0000000..50299cb
--- /dev/null
+++ b/DjangoFiles/PaiementStripe/models.py
@@ -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
+
+
+
diff --git a/DjangoFiles/PaiementStripe/tests.py b/DjangoFiles/PaiementStripe/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/DjangoFiles/PaiementStripe/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/DjangoFiles/PaiementStripe/views.py b/DjangoFiles/PaiementStripe/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/DjangoFiles/PaiementStripe/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/DjangoFiles/QrcodeCashless/__init__.py b/DjangoFiles/QrcodeCashless/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/DjangoFiles/QrcodeCashless/admin.py b/DjangoFiles/QrcodeCashless/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/DjangoFiles/QrcodeCashless/apps.py b/DjangoFiles/QrcodeCashless/apps.py
new file mode 100644
index 0000000..ca31b20
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class QrcodecashlessConfig(AppConfig):
+ name = 'QrcodeCashless'
diff --git a/DjangoFiles/QrcodeCashless/migrations/__init__.py b/DjangoFiles/QrcodeCashless/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/DjangoFiles/QrcodeCashless/models.py b/DjangoFiles/QrcodeCashless/models.py
new file mode 100644
index 0000000..63fd1c0
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/models.py
@@ -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)
\ No newline at end of file
diff --git a/DjangoFiles/QrcodeCashless/templates/RechargementWebUuid.html b/DjangoFiles/QrcodeCashless/templates/RechargementWebUuid.html
new file mode 100644
index 0000000..268584b
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/templates/RechargementWebUuid.html
@@ -0,0 +1,61 @@
+
+
+
+
+ Rechargement Online
+
+
+
+
+
+
+
+
+
+
+ {# #}
+
+ {# #}
+
+
+
+Rechargement Cashless {{ domain.capitalize }}
+{% if liste_assets %}
+ Disponible sur votre carte :
+ {% for asset in liste_assets %}
+
{{ asset }}
+ {% endfor %}
+
+{% else %}
+ Votre carte est vide.
+{% endif %}
+
+
+
+
+
diff --git a/DjangoFiles/QrcodeCashless/tests.py b/DjangoFiles/QrcodeCashless/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/DjangoFiles/QrcodeCashless/urls.py b/DjangoFiles/QrcodeCashless/urls.py
new file mode 100644
index 0000000..9a4e228
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/urls.py
@@ -0,0 +1,7 @@
+from django.urls import include, path, re_path
+
+from .views import index_scan
+
+urlpatterns = [
+ path('', index_scan.as_view()),
+]
\ No newline at end of file
diff --git a/DjangoFiles/QrcodeCashless/views.py b/DjangoFiles/QrcodeCashless/views.py
new file mode 100644
index 0000000..2f244b7
--- /dev/null
+++ b/DjangoFiles/QrcodeCashless/views.py
@@ -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
\ No newline at end of file
diff --git a/DjangoFiles/TiBillet/settings.py b/DjangoFiles/TiBillet/settings.py
index 5d6f317..2c6fcf3 100644
--- a/DjangoFiles/TiBillet/settings.py
+++ b/DjangoFiles/TiBillet/settings.py
@@ -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',
)
diff --git a/DjangoFiles/TiBillet/urls_tenants.py b/DjangoFiles/TiBillet/urls_tenants.py
index 4da9246..5c0643a 100644
--- a/DjangoFiles/TiBillet/urls_tenants.py
+++ b/DjangoFiles/TiBillet/urls_tenants.py
@@ -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')),