From 7299fb55ae11aaeb536cef696d7a42a9cb06c546 Mon Sep 17 00:00:00 2001 From: Jonas 12t Date: Fri, 12 Nov 2021 10:33:59 +0400 Subject: [PATCH] =?UTF-8?q?Correction=20bug=20validation=20les=20lignes=20?= =?UTF-8?q?pour=20cashless.=20Si=20toute=20les=20lignes=20d'un=20paiement?= =?UTF-8?q?=20sont=20valid=C3=A9es,=20et=20200=20ok=20pour=20serveur=20cas?= =?UTF-8?q?hless,=20on=20passe=20le=20paiement=20en=20valid=C3=A9=20aussi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DjangoFiles/ApiBillet/views.py | 56 ++++++++++- DjangoFiles/BaseBillet/signals.py | 69 +++++++++----- .../templates/arnaud_mvc/modals.html | 23 ----- DjangoFiles/PaiementStripe/views.py | 41 +++++---- DjangoFiles/QrcodeCashless/views.py | 92 ++++++++++--------- 5 files changed, 171 insertions(+), 110 deletions(-) diff --git a/DjangoFiles/ApiBillet/views.py b/DjangoFiles/ApiBillet/views.py index 235d5d7..24c63e4 100644 --- a/DjangoFiles/ApiBillet/views.py +++ b/DjangoFiles/ApiBillet/views.py @@ -1,4 +1,9 @@ # Create your views here. +import json + +import requests +from django.contrib import messages +from django.http import HttpResponseRedirect from django.utils import timezone from django_weasyprint import WeasyTemplateView from rest_framework.generics import get_object_or_404 @@ -137,7 +142,56 @@ class ReservationViewset(viewsets.ViewSet): permission_classes = [TenantAdminPermission] return [permission() for permission in permission_classes] -# class Adhesion(viewsets.ViewSet): + +class Membership(viewsets.ViewSet): + + def send_mail_to_cashless_for_membership(request, data: dict, carte: any): + sess = requests.Session() + configuration = Configuration.get_solo() + + 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') + + else: + messages.error(request, f'Erreur {r.status_code} {r.text}') + return HttpResponseRedirect(f'#erreur') + class TicketPdf(WeasyTemplateView): permission_classes = [AllowAny] diff --git a/DjangoFiles/BaseBillet/signals.py b/DjangoFiles/BaseBillet/signals.py index 677a873..b754511 100644 --- a/DjangoFiles/BaseBillet/signals.py +++ b/DjangoFiles/BaseBillet/signals.py @@ -12,6 +12,7 @@ from BaseBillet.tasks import ticket_celery_mailer # from TiBillet import settings import logging + logger = logging.getLogger(__name__) @@ -28,7 +29,7 @@ def set_ligne_article_paid(old_instance, new_instance): old_instance: Paiement_stripe new_instance: Paiement_stripe - logger.info(f" TRIGGER PAIEMENT STRIPE set_ligne_article_paid {old_instance}.") + logger.info(f" TRIGGER PAIEMENT STRIPE set_ligne_article_paid {new_instance}.") logger.info(f" On passe toutes les lignes d'article non validées en payées !") lignes_article = new_instance.lignearticle_set.exclude(status=LigneArticle.VALID) @@ -53,6 +54,7 @@ def expire_paiement_stripe(old_instance, new_instance): def valide_stripe_paiement(old_instance, new_instance): logger.info(f" TRIGGER PAIEMENT STRIPE valide_stripe_paiement {old_instance.status} to {new_instance.status}") + ######################## TRIGGER LIGNE ARTICLE ######################## # post_save ici nécéssaire pour mettre a jour le status du paiement stripe en validé @@ -60,17 +62,27 @@ def valide_stripe_paiement(old_instance, new_instance): # @receiver(post_save, sender=LigneArticle) def set_paiement_and_reservation_valid(old_instance, new_instance): - lignes_dans_paiement_stripe = new_instance.paiement_stripe.lignearticle_set.all() - # TODO: calculer -1 ?? - if len(lignes_dans_paiement_stripe) == len(lignes_dans_paiement_stripe.filter(status=LigneArticle.VALID)) : - # on passe le status du paiement stripe en VALID - logger.info(f" TRIGGER LIGNE ARTICLE set_paiement_and_reservation_valid {new_instance.price} " - f"paiement stripe {new_instance.paiement_stripe} {new_instance.paiement_stripe.status} à VALID") - new_instance.paiement_stripe.status = Paiement_stripe.VALID - new_instance.paiement_stripe.traitement_en_cours = False - new_instance.paiement_stripe.save() + if new_instance.status == LigneArticle.VALID: + logger.info( + 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 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( + uuid=new_instance.uuid) + lignes_valide_dans_paiement_stripe = lignes_dans_paiement_stripe.filter(status=LigneArticle.VALID).exclude( + uuid=new_instance.uuid) + if len(lignes_dans_paiement_stripe) == len(lignes_valide_dans_paiement_stripe): + # on passe le status du paiement stripe en VALID + logger.info( + f" paiement stripe {new_instance.paiement_stripe} {new_instance.paiement_stripe.status} à VALID") + new_instance.paiement_stripe.status = Paiement_stripe.VALID + new_instance.paiement_stripe.traitement_en_cours = False + new_instance.paiement_stripe.save() + else: + logger.info( + f" len(lignes_dans_paiement_stripe) {len(lignes_dans_paiement_stripe)} != len(lignes_valide_dans_paiement_stripe) {len(lignes_valide_dans_paiement_stripe)} ") def send_to_cashless(instance): @@ -100,14 +112,14 @@ def send_to_cashless(instance): sess.close() logger.info( - f" demande au serveur cashless pour un rechargement. réponse : {r.status_code} ") + f" demande au serveur cashless pour {instance.price}. réponse : {r.status_code} ") - if r.status_code == 200: - instance.status = LigneArticle.VALID - else: + if r.status_code != 200: logger.error( f"erreur réponse serveur cashless {r.status_code} {r.text} pour paiement stripe {instance.price} uuid {instance.uuid}") + return r.status_code + def check_paid(old_instance, new_instance): # Type : @@ -117,7 +129,9 @@ def check_paid(old_instance, new_instance): if new_instance.price.product.categorie_article in \ [Product.RECHARGE_CASHLESS, Product.ADHESION]: - send_to_cashless(new_instance) + if send_to_cashless(new_instance) == 200: + new_instance.status = LigneArticle.VALID + set_paiement_and_reservation_valid(old_instance, new_instance) ######################## TRIGGER RESERVATION ######################## @@ -137,33 +151,37 @@ def send_billet_to_mail(old_instance, new_instance): # import ipdb; ipdb.set_trace() # On vérifie qu'on a pas déja envoyé le mail - if not new_instance.mail_send : + if not new_instance.mail_send: logger.info(f" TRIGGER RESERVATION send_billet_to_mail {new_instance.status}") - new_instance : Reservation + new_instance: Reservation if new_instance.user_commande.email: # import ipdb; ipdb.set_trace() task = ticket_celery_mailer.delay(new_instance.pk) # https://github.com/psf/requests/issues/5832 - else : - logger.info(f" TRIGGER RESERVATION mail déja envoyé {new_instance} : {new_instance.mail_send} - status : {new_instance.status}") + else: + logger.info( + f" TRIGGER RESERVATION mail déja envoyé {new_instance} : {new_instance.mail_send} - status : {new_instance.status}") set_paiement_valid(old_instance, new_instance) def set_paiement_valid(old_instance, new_instance): new_instance: Reservation - if new_instance.mail_send : - logger.info(f" TRIGGER RESERVATION set_paiement_valid Mail envoyé {new_instance.mail_send}, on valide les paiement payés") + if new_instance.mail_send: + logger.info( + f" TRIGGER RESERVATION set_paiement_valid Mail envoyé {new_instance.mail_send}, on valide les paiement payés") for paiement in new_instance.paiements.filter(status=Paiement_stripe.PAID): paiement.status = Paiement_stripe.VALID paiement.traitement_en_cours = False paiement.save() + def error_in_mail(old_instance, new_instance): logger.info(f" TRIGGER RESERVATION error_in_mail") - new_instance.paiements.all().update(traitement_en_cours = False) + new_instance.paiements.all().update(traitement_en_cours=False) # TODO: Prévenir l'admin q'un billet a été acheté, mais pas envoyé + ######################## MOTEUR TRIGGER ######################## def error_regression(old_instance, new_instance): @@ -197,6 +215,9 @@ TRANSITIONS = { }, 'LIGNEARTICLE': { + LigneArticle.CREATED: { + LigneArticle.PAID: check_paid, + }, LigneArticle.UNPAID: { LigneArticle.PAID: check_paid, }, @@ -211,6 +232,9 @@ TRANSITIONS = { }, 'RESERVATION': { + Reservation.CREATED: { + Reservation.PAID: send_billet_to_mail, + }, Reservation.UNPAID: { Reservation.PAID: send_billet_to_mail, }, @@ -226,6 +250,7 @@ TRANSITIONS = { }, } + @receiver(pre_save) def pre_save_signal_status(sender, instance, **kwargs): # if not create diff --git a/DjangoFiles/BaseBillet/templates/arnaud_mvc/modals.html b/DjangoFiles/BaseBillet/templates/arnaud_mvc/modals.html index c2cae07..02873ff 100644 --- a/DjangoFiles/BaseBillet/templates/arnaud_mvc/modals.html +++ b/DjangoFiles/BaseBillet/templates/arnaud_mvc/modals.html @@ -41,26 +41,3 @@ - -

Adhésion

-

{{ client_name }}

-
- {% csrf_token %} -
- -
- {% if email %} - - - {% else %} - - - {% endif %} -
-
- -
\ No newline at end of file diff --git a/DjangoFiles/PaiementStripe/views.py b/DjangoFiles/PaiementStripe/views.py index 311236e..c3956a0 100644 --- a/DjangoFiles/PaiementStripe/views.py +++ b/DjangoFiles/PaiementStripe/views.py @@ -15,6 +15,7 @@ from AuthBillet.models import HumanUser from BaseBillet.models import Configuration, LigneArticle, Paiement_stripe, Reservation import logging + logger = logging.getLogger(__name__) @@ -48,7 +49,9 @@ class creation_paiement_stripe(): def _user_paiement(self): User = get_user_model() user_paiement, created = User.objects.get_or_create( - email=self.email_paiement) + email=self.email_paiement, + username=self.email_paiement, + ) # On ne lie pas tout de suite la carte a l'user, # on attendra une réponse positive du serveur cashless. @@ -163,19 +166,19 @@ class retour_stripe(View): def get(self, request, uuid_stripe): paiement_stripe = get_object_or_404(Paiement_stripe, uuid=uuid_stripe) - if paiement_stripe.traitement_en_cours : + if paiement_stripe.traitement_en_cours: return HttpResponse( - 'traitement_en_cours') + 'traitement_en_cours') - if paiement_stripe.reservation.status == Reservation.PAID_ERROR : - return HttpResponse( + if paiement_stripe.reservation: + if paiement_stripe.reservation.status == Reservation.PAID_ERROR: + return HttpResponse( "Erreur dans l'envoie du mail. Merci de vérifier l'adresse") - if paiement_stripe.status == Paiement_stripe.VALID or paiement_stripe.reservation.status == Reservation.VALID : + if paiement_stripe.status == Paiement_stripe.VALID or paiement_stripe.reservation.status == Reservation.VALID: return HttpResponse( 'Paiement déja validé !') - configuration = Configuration.get_solo() if configuration.stripe_mode_test: stripe.api_key = configuration.stripe_test_api_key @@ -183,8 +186,7 @@ class retour_stripe(View): stripe.api_key = configuration.stripe_api_key print(paiement_stripe.status) - if paiement_stripe.status != Paiement_stripe.VALID and \ - paiement_stripe.reservation.status != Reservation.VALID : + if paiement_stripe.status != Paiement_stripe.VALID: checkout_session = stripe.checkout.Session.retrieve(paiement_stripe.id_stripe) @@ -193,7 +195,7 @@ class retour_stripe(View): if checkout_session.payment_status == "unpaid": paiement_stripe.status = Paiement_stripe.PENDING - if datetime.now().timestamp() > checkout_session.expires_at : + if datetime.now().timestamp() > checkout_session.expires_at: paiement_stripe.status = Paiement_stripe.EXPIRE paiement_stripe.save() return HttpResponse( @@ -222,25 +224,24 @@ class retour_stripe(View): else: raise Http404 - # on vérifie que le status n'ai pas changé paiement_stripe.refresh_from_db() # import ipdb; ipdb.set_trace() # si c'est depuis le qrcode, on renvoie vers la vue mobile : - if paiement_stripe.source == Paiement_stripe.QRCODE : + if paiement_stripe.source == Paiement_stripe.QRCODE: # SI le paiement est valide, c'est que les presave et postsave # ont validé la réponse du serveur cashless pour les recharges - if paiement_stripe.status == Paiement_stripe.VALID : + if paiement_stripe.status == Paiement_stripe.VALID: # on boucle ici pour récuperer l'uuid de la carte. for ligne_article in paiement_stripe.lignearticle_set.all(): if ligne_article.carte: messages.success(request, f"Paiement validé. Merci !") return HttpResponseRedirect(f"/qr/{ligne_article.carte.uuid}#success") - else : + else: # on boucle ici pour récuperer l'uuid de la carte. for ligne_article in paiement_stripe.lignearticle_set.all(): if ligne_article.carte: @@ -249,18 +250,20 @@ class retour_stripe(View): f"Merci de vérifier votre moyen de paiement et/ou contactez un responsable.") return HttpResponseRedirect(f"/qr/{ligne_article.carte.uuid}#erreurpaiement") - elif paiement_stripe.source == Paiement_stripe.API_BILLETTERIE : - if paiement_stripe.status == Paiement_stripe.VALID or paiement_stripe.reservation.status == Reservation.VALID : + elif paiement_stripe.source == Paiement_stripe.API_BILLETTERIE: + if paiement_stripe.reservation: + if paiement_stripe.reservation.status == Reservation.VALID: + return HttpResponse( + 'Paiement déja validé !') + if paiement_stripe.status == Paiement_stripe.VALID: return HttpResponse( 'Paiement déja validé !') - elif paiement_stripe.status == Paiement_stripe.PAID : + elif paiement_stripe.status == Paiement_stripe.PAID: logger.info(f"Paiement_stripe.API_BILLETTERIE : {paiement_stripe.status}") return HttpResponse( 'Paiement okay, on lance les process de validation.') - - raise Http404(f'{paiement_stripe.status}') diff --git a/DjangoFiles/QrcodeCashless/views.py b/DjangoFiles/QrcodeCashless/views.py index 8c4559c..005ea5c 100644 --- a/DjangoFiles/QrcodeCashless/views.py +++ b/DjangoFiles/QrcodeCashless/views.py @@ -11,6 +11,7 @@ from rest_framework.generics import get_object_or_404 from django.views import View from rest_framework import status +from ApiBillet.views import Membership from BaseBillet.models import Configuration, Product, LigneArticle, Price, Paiement_stripe from PaiementStripe.views import creation_paiement_stripe from QrcodeCashless.models import CarteCashless @@ -213,48 +214,49 @@ class index_scan(View): # Email seul sans montant, c'est une adhésion elif data.get('email'): - - sess = requests.Session() - configuration = Configuration.get_solo() - 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') - - else: - messages.error(request, f'Erreur {r.status_code} {r.text}') - return HttpResponseRedirect(f'#erreur') + return Membership.send_mail_to_cashless_for_membership(request, data, carte) + # + # sess = requests.Session() + # configuration = Configuration.get_solo() + # 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') + # + # else: + # messages.error(request, f'Erreur {r.status_code} {r.text}') + # return HttpResponseRedirect(f'#erreur')