Moteur de billetterie, envoie de mail, traitement en cours
This commit is contained in:
parent
047d66cbc3
commit
2d70329a2c
|
|
@ -227,6 +227,7 @@ class PaiementStripeAdmin(admin.ModelAdmin):
|
|||
'total',
|
||||
'order_date',
|
||||
'status',
|
||||
'traitement_en_cours',
|
||||
'source',
|
||||
)
|
||||
ordering = ('-order_date',)
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ class ReservationValidator(serializers.Serializer):
|
|||
def validate_email(self, value):
|
||||
User: TibilletUser = get_user_model()
|
||||
user_paiement, created = User.objects.get_or_create(
|
||||
email=value)
|
||||
email=value, username=value)
|
||||
|
||||
if created:
|
||||
user_paiement: HumanUser
|
||||
|
|
@ -150,6 +150,7 @@ class ReservationValidator(serializers.Serializer):
|
|||
user_paiement.is_active = False
|
||||
else:
|
||||
user_paiement.client_achat.add(connection.tenant)
|
||||
|
||||
user_paiement.save()
|
||||
self.user_commande = user_paiement
|
||||
return user_paiement.email
|
||||
|
|
|
|||
|
|
@ -326,12 +326,13 @@ class Reservation(models.Model):
|
|||
on_delete=models.PROTECT,
|
||||
related_name="reservation")
|
||||
|
||||
CANCELED, CREATED, UNPAID, PAID, VALID, = 'C', 'R', 'U', 'P', 'V'
|
||||
CANCELED, CREATED, UNPAID, PAID, PAID_ERROR, VALID, = 'C', 'R', 'U', 'P', 'PE', 'V'
|
||||
TYPE_CHOICES = [
|
||||
(CANCELED, _('Annulée')),
|
||||
(CREATED, _('Crée')),
|
||||
(UNPAID, _('Non payée')),
|
||||
(PAID, _('Payée')),
|
||||
(PAID_ERROR, _('Payée mais mail non valide')),
|
||||
(VALID, _('Validée')),
|
||||
]
|
||||
|
||||
|
|
@ -339,6 +340,7 @@ class Reservation(models.Model):
|
|||
verbose_name=_("Status de la réservation"))
|
||||
|
||||
mail_send = models.BooleanField(default=False)
|
||||
mail_error = models.BooleanField(default=False)
|
||||
# paiement = models.OneToOneField(Paiement_stripe, on_delete=models.PROTECT, blank=True, null=True,
|
||||
# related_name='reservation')
|
||||
|
||||
|
|
@ -483,6 +485,8 @@ class Paiement_stripe(models.Model):
|
|||
)
|
||||
status = models.CharField(max_length=1, choices=STATUT_CHOICES, default=NON, verbose_name="Statut de la commande")
|
||||
|
||||
traitement_en_cours = models.BooleanField(default=False)
|
||||
|
||||
reservation = models.ForeignKey(Reservation, on_delete=models.PROTECT, blank=True, null=True,
|
||||
related_name="paiements")
|
||||
|
||||
|
|
|
|||
|
|
@ -52,8 +52,6 @@ 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}")
|
||||
pass
|
||||
|
||||
|
||||
######################## TRIGGER LIGNE ARTICLE ########################
|
||||
|
||||
|
|
@ -69,6 +67,7 @@ def set_paiement_and_reservation_valid(old_instance, new_instance):
|
|||
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()
|
||||
|
||||
|
||||
|
|
@ -148,8 +147,23 @@ def send_billet_to_mail(old_instance, new_instance):
|
|||
# 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}")
|
||||
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")
|
||||
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)
|
||||
# TODO: Prévenir l'admin q'un billet a été acheté, mais pas envoyé
|
||||
|
||||
######################## MOTEUR TRIGGER ########################
|
||||
|
||||
def error_regression(old_instance, new_instance):
|
||||
|
|
@ -169,6 +183,9 @@ TRANSITIONS = {
|
|||
Paiement_stripe.EXPIRE: expire_paiement_stripe,
|
||||
Paiement_stripe.CANCELED: expire_paiement_stripe,
|
||||
},
|
||||
Paiement_stripe.EXPIRE: {
|
||||
Paiement_stripe.PAID: set_ligne_article_paid,
|
||||
},
|
||||
Paiement_stripe.PAID: {
|
||||
Paiement_stripe.PAID: set_ligne_article_paid,
|
||||
Paiement_stripe.VALID: valide_stripe_paiement,
|
||||
|
|
@ -198,8 +215,9 @@ TRANSITIONS = {
|
|||
Reservation.PAID: send_billet_to_mail,
|
||||
},
|
||||
Reservation.PAID: {
|
||||
Reservation.VALID: send_billet_to_mail,
|
||||
Reservation.PAID_ERROR: error_in_mail,
|
||||
Reservation.PAID: send_billet_to_mail,
|
||||
Reservation.VALID: set_paiement_valid,
|
||||
'_else_': error_regression,
|
||||
},
|
||||
Reservation.VALID: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# import base64
|
||||
import os
|
||||
import smtplib
|
||||
from io import BytesIO
|
||||
import segno
|
||||
import barcode
|
||||
|
|
@ -169,14 +170,26 @@ def ticket_celery_mailer(reservation_uuid: str):
|
|||
},
|
||||
attached_files=attached_files,
|
||||
)
|
||||
mail.send()
|
||||
try :
|
||||
mail.send()
|
||||
logger.info(f"mail.sended : {mail.sended}")
|
||||
|
||||
logger.info(f"mail.sended : {mail.sended}")
|
||||
if mail.sended :
|
||||
reservation.mail_send = True
|
||||
reservation.status = Reservation.VALID
|
||||
if mail.sended :
|
||||
reservation.mail_send = True
|
||||
reservation.status = Reservation.VALID
|
||||
reservation.save()
|
||||
|
||||
except smtplib.SMTPRecipientsRefused as e:
|
||||
|
||||
logger.error(f"ERROR {timezone.now()} Erreur envoie de mail pour reservation {reservation} : {e}")
|
||||
logger.error(f"mail.sended : {mail.sended}")
|
||||
reservation.mail_send = False
|
||||
reservation.mail_error = True
|
||||
|
||||
reservation.status = Reservation.PAID_ERROR
|
||||
reservation.save()
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{timezone.now()} Erreur envoie de mail pour reservation {reservation} : {e}")
|
||||
raise Exception
|
||||
|
|
|
|||
|
|
@ -163,6 +163,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 :
|
||||
return HttpResponse(
|
||||
'traitement_en_cours')
|
||||
|
||||
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 :
|
||||
return HttpResponse(
|
||||
'Paiement déja validé !')
|
||||
|
||||
|
||||
configuration = Configuration.get_solo()
|
||||
if configuration.stripe_mode_test:
|
||||
stripe.api_key = configuration.stripe_test_api_key
|
||||
|
|
@ -170,7 +183,8 @@ class retour_stripe(View):
|
|||
stripe.api_key = configuration.stripe_api_key
|
||||
|
||||
print(paiement_stripe.status)
|
||||
if paiement_stripe.status != Paiement_stripe.VALID:
|
||||
if paiement_stripe.status != Paiement_stripe.VALID and \
|
||||
paiement_stripe.reservation.status != Reservation.VALID :
|
||||
|
||||
checkout_session = stripe.checkout.Session.retrieve(paiement_stripe.id_stripe)
|
||||
|
||||
|
|
@ -179,14 +193,12 @@ class retour_stripe(View):
|
|||
|
||||
if checkout_session.payment_status == "unpaid":
|
||||
paiement_stripe.status = Paiement_stripe.PENDING
|
||||
if checkout_session.expires_at > datetime.now().timestamp():
|
||||
# import ipdb; ipdb.set_trace()
|
||||
if datetime.now().timestamp() > checkout_session.expires_at :
|
||||
paiement_stripe.status = Paiement_stripe.EXPIRE
|
||||
paiement_stripe.save()
|
||||
|
||||
elif checkout_session.payment_status == "paid":
|
||||
paiement_stripe.status = Paiement_stripe.PAID
|
||||
logger.info(f"retour_stripe - checkout_session.payment_status : {checkout_session.payment_status}")
|
||||
|
||||
|
||||
# le .save() lance le process pre_save BaseBillet.models.send_to_cashless
|
||||
# qui modifie le status de chaque ligne
|
||||
|
|
@ -194,8 +206,14 @@ class retour_stripe(View):
|
|||
# si validé par le serveur cashless, alors la ligne sera VALID.
|
||||
# Si toute les lignes sont VALID, le paiement_stripe sera aussi VALID
|
||||
# grace au post_save BaseBillet.models.check_status_stripe
|
||||
|
||||
logger.info(f"retour_stripe - checkout_session.payment_status : {checkout_session.payment_status}")
|
||||
paiement_stripe.status = Paiement_stripe.PAID
|
||||
paiement_stripe.last_action = timezone.now()
|
||||
paiement_stripe.traitement_en_cours = True
|
||||
paiement_stripe.save()
|
||||
logger.info(f"retour_stripe - paiement_stripe.save() {paiement_stripe.status}")
|
||||
|
||||
|
||||
else:
|
||||
paiement_stripe.status = Paiement_stripe.CANCELED
|
||||
|
|
@ -203,8 +221,10 @@ 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 :
|
||||
|
|
@ -229,13 +249,15 @@ class retour_stripe(View):
|
|||
return HttpResponseRedirect(f"/qr/{ligne_article.carte.uuid}#erreurpaiement")
|
||||
|
||||
elif paiement_stripe.source == Paiement_stripe.API_BILLETTERIE :
|
||||
if paiement_stripe.status == Paiement_stripe.PAID :
|
||||
if paiement_stripe.status == Paiement_stripe.VALID or paiement_stripe.reservation.status == Reservation.VALID :
|
||||
return HttpResponse(
|
||||
'Paiement déja validé !')
|
||||
|
||||
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.')
|
||||
|
||||
if paiement_stripe.status == Paiement_stripe.VALID :
|
||||
return HttpResponse(
|
||||
'Paiement validé !')
|
||||
|
||||
|
||||
raise Http404(f'{paiement_stripe.status}')
|
||||
|
|
|
|||
|
|
@ -223,7 +223,6 @@ CELERY_RESULT_BACKEND=os.environ.get('CELERY_BACKEND', 'redis://redis:6379/0')
|
|||
|
||||
# Jet Menu
|
||||
# -------------------------------------/
|
||||
|
||||
JET_SIDE_MENU_COMPACT = True
|
||||
JET_CHANGE_FORM_SIBLING_LINKS = False
|
||||
|
||||
|
|
@ -238,11 +237,11 @@ LOGGING = {
|
|||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'DEBUG',
|
||||
'level': 'INFO',
|
||||
'class': 'logging.StreamHandler',
|
||||
},
|
||||
'logfile': {
|
||||
'level': 'DEBUG',
|
||||
'level': 'INFO',
|
||||
'class': 'logging.handlers.RotatingFileHandler',
|
||||
'filename': f"{BASE_DIR}/www/Djangologfile",
|
||||
'formatter': 'simple',
|
||||
|
|
@ -250,7 +249,7 @@ LOGGING = {
|
|||
},
|
||||
},
|
||||
'root': {
|
||||
'level': 'DEBUG',
|
||||
'level': 'INFO',
|
||||
'handlers': ['console', 'logfile']
|
||||
},
|
||||
}
|
||||
Loading…
Reference in New Issue