Configure Hello Asso return endpoint

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2024-02-20 22:54:12 +01:00
parent 8c7e9648dd
commit 8d08b18d08
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
5 changed files with 259 additions and 120 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-02-18 22:25+0100\n"
"POT-Creation-Date: 2024-02-20 22:48+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -326,7 +326,7 @@ msgstr "Continuer le tirage"
#: draw/templates/draw/tournament_content.html:216 participation/admin.py:100
#: participation/models.py:249 participation/models.py:434
#: registration/models.py:146
#: registration/models.py:156
msgid "team"
msgstr "équipe"
@ -377,7 +377,7 @@ msgstr "Vous n'êtes pas dans une équipe."
msgid "Logs"
msgstr "Logs"
#: logs/models.py:22 registration/models.py:31
#: logs/models.py:22 registration/models.py:33
msgid "user"
msgstr "utilisateur"
@ -711,7 +711,7 @@ msgstr ""
"L'équipe {trigram} n'a pas encore été validée par les organisateurices. "
"Merci de patienter."
#: participation/models.py:193 registration/models.py:482
#: participation/models.py:193 registration/models.py:492
msgid "Pending validation"
msgstr "Validation en attente"
@ -1791,7 +1791,7 @@ msgstr "rôle"
msgid "participant"
msgstr "participant⋅e"
#: registration/forms.py:25 registration/models.py:416
#: registration/forms.py:25 registration/models.py:426
msgid "coach"
msgstr "encadrant⋅e"
@ -1803,20 +1803,20 @@ msgstr "En attente"
msgid "You must upload your receipt."
msgstr "Vous devez envoyer votre justificatif."
#: registration/models.py:36
#: registration/models.py:38
msgid "Grant Animath to contact me in the future about other actions"
msgstr ""
"Autoriser Animath à me recontacter à l'avenir à propos d'autres actions"
#: registration/models.py:41
#: registration/models.py:43
msgid "email confirmed"
msgstr "email confirmé"
#: registration/models.py:49
#: registration/models.py:51
msgid "Activate your TFJM² account"
msgstr "Activez votre compte du TFJM²"
#: registration/models.py:98
#: registration/models.py:108
#, python-brace-format
msgid ""
"Your email address is not validated. Please click on the link you received "
@ -1827,52 +1827,52 @@ msgstr ""
"avez reçu par mail. Vous pouvez renvoyer un mail en cliquant sur <a "
"href=\"{send_email_url}\">ce lien</a>."
#: registration/models.py:118
#: registration/models.py:128
msgid "registration"
msgstr "inscription"
#: registration/models.py:119 registration/models.py:503
#: registration/models.py:129 registration/models.py:513
msgid "registrations"
msgstr "inscriptions"
#: registration/models.py:151
#: registration/models.py:161
msgid "gender"
msgstr "genre"
#: registration/models.py:153
#: registration/models.py:163
msgid "Female"
msgstr "Femme"
#: registration/models.py:154
#: registration/models.py:164
msgid "Male"
msgstr "Homme"
#: registration/models.py:155
#: registration/models.py:165
#: registration/templates/registration/payment_form.html:73
msgid "Other"
msgstr "Autre"
#: registration/models.py:162
#: registration/models.py:172
msgid "address"
msgstr "adresse"
#: registration/models.py:166
#: registration/models.py:176
msgid "zip code"
msgstr "code postal"
#: registration/models.py:172
#: registration/models.py:182
msgid "city"
msgstr "ville"
#: registration/models.py:176
#: registration/models.py:186
msgid "phone number"
msgstr "numéro de téléphone"
#: registration/models.py:181
#: registration/models.py:191
msgid "health issues"
msgstr "problèmes de santé"
#: registration/models.py:183
#: registration/models.py:193
msgid ""
"You can indicate here your allergies or anything that is important to know "
"for organizers."
@ -1880,11 +1880,11 @@ msgstr ""
"Vous pouvez indiquer ici vos allergies ou n'importe quoi qui peut être bon à "
"savoir pour les organisateur⋅rices."
#: registration/models.py:187
#: registration/models.py:197
msgid "housing constraints"
msgstr "contraintes de logement"
#: registration/models.py:189
#: registration/models.py:199
msgid ""
"You can fill in something here if you have any housing constraints, e.g. "
"medical problems, scheduling issues, gender issues, or anything else you "
@ -1897,11 +1897,11 @@ msgstr ""
"organisateur⋅rices. Laissez vide si vous n'avez rien de spécifique à "
"déclarer."
#: registration/models.py:196
#: registration/models.py:206
msgid "photo authorization"
msgstr "autorisation de droit à l'image"
#: registration/models.py:225
#: registration/models.py:235
#, python-brace-format
msgid ""
"You are not in a team. You can <a href=\"{create_url}\">create one</a> or <a "
@ -1911,11 +1911,11 @@ msgstr ""
"a> ou <a href=\"{join_url}\">rejoindre une équipe existante</a> pour "
"participer."
#: registration/models.py:231
#: registration/models.py:241
msgid "No team"
msgstr "Pas d'équipe"
#: registration/models.py:239
#: registration/models.py:249
#, python-brace-format
msgid ""
"You have not uploaded your photo authorization. You can do it by clicking on "
@ -1924,71 +1924,71 @@ msgstr ""
"Vous n'avez pas envoyé votre autorisation de droit à l'image. Vous pouvez le "
"faire en cliquant sur <a href=\"{photo_url}\">ce lien</a>."
#: registration/models.py:244
#: registration/models.py:254
msgid "Photo authorization"
msgstr "Autorisation de droit à l'image"
#: registration/models.py:255
#: registration/models.py:265
msgid "participant registration"
msgstr "inscription de participant⋅e"
#: registration/models.py:256
#: registration/models.py:266
msgid "participant registrations"
msgstr "inscriptions de participant⋅es"
#: registration/models.py:265
#: registration/models.py:275
msgid "birth date"
msgstr "date de naissance"
#: registration/models.py:271
#: registration/models.py:281
msgid "12th grade"
msgstr "Terminale"
#: registration/models.py:272
#: registration/models.py:282
msgid "11th grade"
msgstr "Première"
#: registration/models.py:273
#: registration/models.py:283
msgid "10th grade or lower"
msgstr "Seconde ou inférieur"
#: registration/models.py:275
#: registration/models.py:285
msgid "student class"
msgstr "classe"
#: registration/models.py:280
#: registration/models.py:290
msgid "school"
msgstr "école"
#: registration/models.py:285
#: registration/models.py:295
msgid "responsible name"
msgstr "nom d'un⋅e responsable légal⋅e"
#: registration/models.py:290
#: registration/models.py:300
msgid "responsible phone number"
msgstr "numéro de téléphone d'un⋅e responsable légal⋅e"
#: registration/models.py:295
#: registration/models.py:305
msgid "responsible email address"
msgstr "adresse e-mail d'un⋅e responsable légal⋅e"
#: registration/models.py:300
#: registration/models.py:310
msgid "parental authorization"
msgstr "autorisation parentale"
#: registration/models.py:307
#: registration/models.py:317
msgid "health sheet"
msgstr "fiche sanitaire"
#: registration/models.py:314
#: registration/models.py:324
msgid "vaccine sheet"
msgstr "carnet de vaccination"
#: registration/models.py:322
#: registration/models.py:332
msgid "student"
msgstr "élève"
#: registration/models.py:333
#: registration/models.py:343
#, python-brace-format
msgid ""
"You have not uploaded your parental authorization. You can do it by clicking "
@ -1997,11 +1997,11 @@ msgstr ""
"Vous n'avez pas envoyé votre autorisation parentale. Vous pouvez le faire en "
"cliquant sur <a href=\"{parental_url}\">ce lien</a>."
#: registration/models.py:338
#: registration/models.py:348
msgid "Parental authorization"
msgstr "Autorisation parentale"
#: registration/models.py:344
#: registration/models.py:354
#, python-brace-format
msgid ""
"You have not uploaded your health sheet. You can do it by clicking on <a "
@ -2010,11 +2010,11 @@ msgstr ""
"Vous n'avez pas envoyé votre fiche sanitaire. Vous pouvez le faire en "
"cliquant sur <a href=\"{health_url}\">ce lien</a>."
#: registration/models.py:349
#: registration/models.py:359
msgid "Health sheet"
msgstr "Fiche sanitaire"
#: registration/models.py:355
#: registration/models.py:365
#, python-brace-format
msgid ""
"You have not uploaded your vaccine sheet. You can do it by clicking on <a "
@ -2023,11 +2023,11 @@ msgstr ""
"Vous n'avez pas envoyé votre carnet de vaccination. Vous pouvez le faire en "
"cliquant sur <a href=\"{vaccine_url}\">ce lien</a>."
#: registration/models.py:360
#: registration/models.py:370
msgid "Vaccine sheet"
msgstr "Carnet de vaccination"
#: registration/models.py:369
#: registration/models.py:379
#, python-brace-format
msgid ""
"You have to pay {amount} € for your registration, or send a scholarship "
@ -2038,27 +2038,27 @@ msgstr ""
"notification de bourse ou un justificatif de paiement. Vous pouvez le faire "
"sur <a href=\"{url}\">la page de paiement</a>."
#: registration/models.py:375 registration/models.py:384
#: registration/models.py:385 registration/models.py:394
msgid "Payment"
msgstr "Paiement"
#: registration/models.py:381
#: registration/models.py:391
msgid "Your payment is under approval."
msgstr "Votre paiement est en cours de validation."
#: registration/models.py:393
#: registration/models.py:403
msgid "student registration"
msgstr "inscription d'élève"
#: registration/models.py:394
#: registration/models.py:404
msgid "student registrations"
msgstr "inscriptions d'élève"
#: registration/models.py:405
#: registration/models.py:415
msgid "most recent degree in mathematics, computer science or physics"
msgstr "Dernier diplôme obtenu en mathématiques, informatique ou physique"
#: registration/models.py:406
#: registration/models.py:416
msgid ""
"Your most recent degree in maths, computer science or physics, or your last "
"entrance exam (CAPES, Agrégation,…)"
@ -2066,23 +2066,23 @@ msgstr ""
"Votre dernier diplôme en mathématiques, informatique ou physique, ou votre "
"dernier concours obtenu (CAPES, Agrégation, …)"
#: registration/models.py:411 registration/models.py:433
#: registration/models.py:421 registration/models.py:443
msgid "professional activity"
msgstr "activité professionnelle"
#: registration/models.py:424
#: registration/models.py:434
msgid "coach registration"
msgstr "inscription d'encadrant⋅e"
#: registration/models.py:425
#: registration/models.py:435
msgid "coach registrations"
msgstr "inscriptions d'encadrant⋅es"
#: registration/models.py:437
#: registration/models.py:447
msgid "administrator"
msgstr "administrateur⋅rice"
#: registration/models.py:438
#: registration/models.py:448
msgid ""
"An administrator has all rights. Please don't give this right to all juries "
"and volunteers."
@ -2090,15 +2090,15 @@ msgstr ""
"Un⋅e administrateur⋅rice a tous les droits. Merci de ne pas donner ce droit "
"à toustes les juré⋅es et bénévoles."
#: registration/models.py:448
#: registration/models.py:458
msgid "admin"
msgstr "admin"
#: registration/models.py:448
#: registration/models.py:458
msgid "volunteer"
msgstr "bénévole"
#: registration/models.py:461
#: registration/models.py:471
msgid ""
"Registrations for tournament {tournament} are closing on {date:%Y-%m-%d %H:"
"%M}. There are for now {validated_teams} validated teams (+ {pending_teams} "
@ -2108,11 +2108,11 @@ msgstr ""
"%M}. Il y a pour l'instant {validated_teams} équipes validées (+ "
"{pending_teams} en attente) sur {max_teams} attendues."
#: registration/models.py:469
#: registration/models.py:479
msgid "Registrations"
msgstr "Inscriptions"
#: registration/models.py:476
#: registration/models.py:486
#, python-brace-format
msgid ""
"The team {trigram} requested to be validated for the tournament of "
@ -2123,19 +2123,19 @@ msgstr ""
"Vous pouvez vérifier le statut de l'équipe sur la <a href=\"{url}\">page de "
"l'équipe</a>."
#: registration/models.py:491
#: registration/models.py:501
msgid "volunteer registration"
msgstr "inscription de bénévole"
#: registration/models.py:492
#: registration/models.py:502
msgid "volunteer registrations"
msgstr "inscriptions de bénévoles"
#: registration/models.py:507
#: registration/models.py:517
msgid "grouped"
msgstr "groupé"
#: registration/models.py:509
#: registration/models.py:519
msgid ""
"If set to true, then one payment is made for the full team, for example if "
"the school pays for all."
@ -2143,84 +2143,84 @@ msgstr ""
"Si vrai, alors un seul paiement est fait pour toute l'équipe, par exemple si "
"le lycée paie pour tout le monde."
#: registration/models.py:514
#: registration/models.py:524
msgid "total amount"
msgstr "montant total"
#: registration/models.py:515
#: registration/models.py:525
msgid "Corresponds to the total required amount to pay, in euros."
msgstr "Correspond au montant total à payer, en euros."
#: registration/models.py:520
#: registration/models.py:530
msgid "for final tournament"
msgstr "pour la finale"
#: registration/models.py:525
#: registration/models.py:535
msgid "type"
msgstr "type"
#: registration/models.py:528
#: registration/models.py:538
msgid "No payment"
msgstr "Pas de paiement"
#: registration/models.py:529
#: registration/models.py:539
#: registration/templates/registration/payment_form.html:56
msgid "Credit card"
msgstr "Carte bancaire"
#: registration/models.py:530
#: registration/models.py:540
msgid "Scholarship"
msgstr "Notification de bourse"
#: registration/models.py:531
#: registration/models.py:541
#: registration/templates/registration/payment_form.html:61
msgid "Bank transfer"
msgstr "Virement bancaire"
#: registration/models.py:532
#: registration/models.py:542
msgid "Other (please indicate)"
msgstr "Autre (veuillez spécifier)"
#: registration/models.py:533
#: registration/models.py:543
msgid "The tournament is free"
msgstr "Le tournoi est gratuit"
#: registration/models.py:540
#: registration/models.py:550
msgid "Hello Asso checkout intent ID"
msgstr "ID de l'intention de paiement Hello Asso"
#: registration/models.py:547
#: registration/models.py:557
msgid "receipt"
msgstr "justificatif"
#: registration/models.py:548
#: registration/models.py:558
msgid "only if you have a scholarship or if you chose a bank transfer."
msgstr ""
"Nécessaire seulement si vous déclarez être boursièr⋅e ou si vous payez par "
"virement bancaire."
#: registration/models.py:555
#: registration/models.py:565
msgid "additional information"
msgstr "informations additionnelles"
#: registration/models.py:556
#: registration/models.py:566
msgid "To help us to find your payment."
msgstr "Pour nous aider à retrouver votre paiement, si nécessaire."
#: registration/models.py:562
#: registration/models.py:572
msgid "payment valid"
msgstr "paiement valide"
#: registration/models.py:571
#: registration/models.py:630
#, python-brace-format
msgid "Payment of {registrations}"
msgstr "Paiements de {registrations}"
#: registration/models.py:574
#: registration/models.py:633
msgid "payment"
msgstr "paiement"
#: registration/models.py:575
#: registration/models.py:634
msgid "payments"
msgstr "paiements"
@ -2228,7 +2228,7 @@ msgstr "paiements"
#: registration/templates/registration/add_organizer.html:12
#: registration/templates/registration/add_organizer.html:21
#: registration/templates/registration/user_list.html:9
#: registration/views.py:88
#: registration/views.py:90
msgid "Add organizer"
msgstr "Ajouter un⋅e organisateur⋅rice"
@ -2388,7 +2388,7 @@ msgstr "Réinitialiser mon mot de passe"
#: registration/templates/registration/payment_form.html:9
#, python-format
msgid "You must pay %(amount)s € for your registration."
msgstr "Vous devez payez %(amount)s € pour votre inscription."
msgstr "Vous devez payer %(amount)s € pour votre inscription."
#: registration/templates/registration/payment_form.html:13
msgid "This price includes the registrations of all members of your team."
@ -2435,7 +2435,7 @@ msgstr "J'ai une bourse"
#: registration/templates/registration/signup.html:5
#: registration/templates/registration/signup.html:12
#: registration/templates/registration/signup.html:19 registration/views.py:44
#: registration/templates/registration/signup.html:19 registration/views.py:46
msgid "Sign up"
msgstr "Inscription"
@ -2581,7 +2581,7 @@ msgid "valid:"
msgstr "valide :"
#: registration/templates/registration/user_detail.html:163
#: registration/views.py:458
#: registration/views.py:461
msgid "Update payment"
msgstr "Modifier le paiement"
@ -2598,90 +2598,135 @@ msgid "Impersonate"
msgstr "Impersonifier"
#: registration/templates/registration/user_detail.html:195
#: registration/views.py:313
#: registration/views.py:316
msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image"
#: registration/templates/registration/user_detail.html:200
#: registration/views.py:334
#: registration/views.py:337
msgid "Upload health sheet"
msgstr "Téléverser la fiche sanitaire"
#: registration/templates/registration/user_detail.html:205
#: registration/views.py:355
#: registration/views.py:358
msgid "Upload vaccine sheet"
msgstr "Téléverser le carnet de vaccination"
#: registration/templates/registration/user_detail.html:210
#: registration/templates/registration/user_detail.html:215
#: registration/views.py:376
#: registration/views.py:379
msgid "Upload parental authorization"
msgstr "Téléverser l'autorisation parentale"
#: registration/views.py:120
#: registration/views.py:122
msgid "New TFJM² organizer account"
msgstr "Nouveau compte organisateur⋅rice pour le TFJM²"
#: registration/views.py:146
#: registration/views.py:148
msgid "Email validation"
msgstr "Validation de l'adresse mail"
#: registration/views.py:148
#: registration/views.py:150
msgid "Validate email"
msgstr "Valider l'adresse mail"
#: registration/views.py:187
#: registration/views.py:189
msgid "Email validation unsuccessful"
msgstr "Échec de la validation de l'adresse mail"
#: registration/views.py:198
#: registration/views.py:200
msgid "Email validation email sent"
msgstr "Mail de confirmation de l'adresse mail envoyé"
#: registration/views.py:206
#: registration/views.py:208
msgid "Resend email validation link"
msgstr "Renvoyé le lien de validation de l'adresse mail"
#: registration/views.py:248
#: registration/views.py:251
#, python-brace-format
msgid "Detail of user {user}"
msgstr "Détails de l'utilisateur⋅rice {user}"
#: registration/views.py:273
#: registration/views.py:276
#, python-brace-format
msgid "Update user {user}"
msgstr "Mise à jour de l'utilisateur⋅rice {user}"
#: registration/views.py:503
msgid "This payment is already valid or pending validation."
msgstr "Le paiement est déjà validé ou en attente de validation."
#: registration/views.py:563
msgid "The payment is not found or is already validated."
msgstr "Le paiement n'est pas trouvé ou déjà validé."
#: registration/views.py:582
#, python-brace-format
msgid "An error occurred during the payment: {error}"
msgstr "Une erreur est survenue lors du paiement : {error}"
#: registration/views.py:588
msgid "The payment has been refused."
msgstr "Le paiement a été refusé."
#: registration/views.py:591
#, python-brace-format
msgid "The return code is unknown: {code}"
msgstr "Le code de retour est inconnu : {code}"
#: registration/views.py:594
#, python-brace-format
msgid "The return type is unknown: {type}"
msgstr "Le type de retour est inconnu : {type}"
#: registration/views.py:601
msgid ""
"The payment has been successfully validated! Your registration is now "
"complete."
msgstr ""
"Le paiement a été validé avec succès ! Votre inscription est désormais "
"complète."
#: registration/views.py:606
msgid ""
"Your payment is done! The validation of your payment may takes a few "
"minutes, and will be automatically done. If it is not the case, please "
"contact us."
msgstr ""
"Votre paiement est effectué ! La validation de votre paiement peut prendre "
"quelques minutes, et sera faite automatiquement. Si ce n'est pas le cas, "
"merci de nous contacter."
#: registration/views.py:641
#, python-brace-format
msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: registration/views.py:526
#: registration/views.py:665
#, python-brace-format
msgid "Health sheet of {student}.{ext}"
msgstr "Fiche sanitaire de {student}.{ext}"
#: registration/views.py:549
#: registration/views.py:689
#, python-brace-format
msgid "Vaccine sheet of {student}.{ext}"
msgstr "Carnet de vaccination de {student}.{ext}"
#: registration/views.py:572
#: registration/views.py:713
#, python-brace-format
msgid "Parental authorization of {student}.{ext}"
msgstr "Autorisation parentale de {student}.{ext}"
#: registration/views.py:594
#: registration/views.py:736
#, python-brace-format
msgid "Payment receipt of {user}.{ext}"
msgstr "Justificatif de paiement de {user}.{ext}"
#: tfjm/settings.py:164
#: tfjm/settings.py:167
msgid "English"
msgstr "Anglais"
#: tfjm/settings.py:165
#: tfjm/settings.py:168
msgid "French"
msgstr "Français"

View File

@ -80,6 +80,14 @@ class Registration(PolymorphicModel):
def participates(self):
return isinstance(self, ParticipantRegistration)
@property
def is_student(self):
return isinstance(self, StudentRegistration)
@property
def is_coach(self):
return isinstance(self, CoachRegistration)
@property
def is_admin(self):
return isinstance(self, VolunteerRegistration) and self.admin or self.user.is_superuser
@ -566,6 +574,17 @@ class Payment(models.Model):
default=False,
)
@property
def team(self):
return self.registrations.first().team
@property
def tournament(self):
if self.final:
from participation.models import Tournament
return Tournament.final_tournament()
return self.registrations.first().team.participation.tournament
def get_checkout_intent(self):
if self.checkout_intent_id is None:
return None
@ -576,17 +595,15 @@ class Payment(models.Model):
if checkout_intent is not None:
return checkout_intent
from participation.models import Tournament
tournament = self.registrations.first().team.participation.tournament \
if not self.final else Tournament.final_tournament()
tournament = self.tournament
year = datetime.now().year
base_site = "https://" + Site.objects.first().domain
checkout_intent = helloasso.create_checkout_intent(
amount=100 * self.amount,
name=f"Participation au TFJM² {year} - {tournament.name}",
back_url=base_site + reverse('registration:update_payment', args=(self.id,)),
error_url=base_site + reverse('registration:update_payment', args=(self.id,)),
return_url=base_site + reverse('registration:update_payment', args=(self.id,)),
error_url=f"{base_site}{reverse('registration:payment_hello_asso_return', args=(self.id,))}?type=error",
return_url=f"{base_site}{reverse('registration:payment_hello_asso_return', args=(self.id,))}?type=return",
contains_donation=False,
metadata=dict(
users=[

View File

@ -5,7 +5,7 @@ from django.urls import path
from .views import AddOrganizerView, AdultPhotoAuthorizationTemplateView, ChildPhotoAuthorizationTemplateView, \
InstructionsTemplateView, MyAccountDetailView, ParentalAuthorizationTemplateView, \
PaymentUpdateGroupView, PaymentUpdateView, PaymenRedirectHelloAssoView, \
PaymentHelloAssoReturnView, PaymentUpdateGroupView, PaymentUpdateView, PaymenRedirectHelloAssoView, \
ResetAdminView, SignupView, UserDetailView, UserImpersonateView, UserListView, UserResendValidationEmailView, \
UserUpdateView, UserUploadHealthSheetView, UserUploadParentalAuthorizationView, UserUploadPhotoAuthorizationView, \
UserUploadVaccineSheetView, UserValidateView, UserValidationEmailSentView
@ -41,6 +41,8 @@ urlpatterns = [
path("update-payment/<int:pk>/toggle-group-mode/", PaymentUpdateGroupView.as_view(),
name="update_payment_group_mode"),
path("update-payment/<int:pk>/hello-asso/", PaymenRedirectHelloAssoView.as_view(), name="payment_hello_asso"),
path("update-payment/<int:pk>/hello-asso/return/", PaymentHelloAssoReturnView.as_view(),
name="payment_hello_asso_return"),
path("user/<int:pk>/impersonate/", UserImpersonateView.as_view(), name="user_impersonate"),
path("user/list/", UserListView.as_view(), name="user_list"),
path("reset-admin/", ResetAdminView.as_view(), name="reset_admin"),

View File

@ -6,6 +6,7 @@ import subprocess
from tempfile import mkdtemp
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
@ -19,6 +20,7 @@ from django.urls import reverse_lazy
from django.utils import timezone, translation
from django.utils.crypto import get_random_string
from django.utils.http import urlsafe_base64_decode
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView, View
from django_tables2 import SingleTableView
@ -215,6 +217,7 @@ class MyAccountDetailView(LoginRequiredMixin, RedirectView):
"""
Redirect to our own profile detail page.
"""
def get_redirect_url(self, *args, **kwargs):
return reverse_lazy("registration:user_detail", args=(self.request.user.pk,))
@ -550,10 +553,76 @@ class PaymenRedirectHelloAssoView(LoginRequiredMixin, DetailView):
return redirect(checkout_intent["redirectUrl"])
class PaymentHelloAssoReturnView(DetailView):
model = Payment
def get(self, request, *args, **kwargs):
checkout_id = request.GET.get("checkoutIntentId")
payment = Payment.objects.get(checkout_intent_id=checkout_id).exclude(valid=True)
if payment != self.get_object():
messages.error(request, _("The payment is not found or is already validated."))
return redirect("index")
team = payment.team
tournament = payment.tournament
right_to_see = not request.user.is_anonymous \
and (request.user.registration.is_admin
or request.user.registration in payment.registrations.all()
or (request.user.registration.is_volunteer
and tournament in request.user.registration.organized_tournaments.all())
or (request.user.registration.is_coach and request.user.registration.team == team))
if right_to_see:
error_response = redirect("registration:update_payment", args=(payment.pk,))
else:
error_response = redirect("index")
return_type = request.GET.get("type")
if return_type == "error":
messages.error(request, format_lazy(_("An error occurred during the payment: {error}"),
error=request.GET.get("error")))
return error_response
elif return_type == "return":
code = request.GET.get("code")
if code == "refused":
messages.error(request, _("The payment has been refused."))
return error_response
elif code != "success":
messages.error(request, format_lazy(_("The return code is unknown: {code}"), code=code))
return error_response
else:
messages.error(request, format_lazy(_("The return type is unknown: {type}"), type=return_type))
return error_response
checkout_intent = payment.get_checkout_intent()
if 'order' in checkout_intent:
payment.valid = True
payment.save()
messages.success(request, _("The payment has been successfully validated! "
"Your registration is now complete."))
else:
payment.valid = None
payment.save()
messages.success(request, _("Your payment is done! "
"The validation of your payment may takes a few minutes, "
"and will be automatically done. "
"If it is not the case, please contact us."))
if request.user.registration in payment.registrations.all():
success_response = redirect("registration:user_detail", args=(request.user.pk,))
elif right_to_see:
success_response = redirect("participation:team_detail", args=(team.pk,))
else:
success_response = redirect("index")
return success_response
class PhotoAuthorizationView(LoginRequiredMixin, View):
"""
Display the sent photo authorization.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/photo/{filename}"
@ -577,6 +646,7 @@ class HealthSheetView(LoginRequiredMixin, View):
"""
Display the sent health sheet.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/health/{filename}"
@ -600,6 +670,7 @@ class VaccineSheetView(LoginRequiredMixin, View):
"""
Display the sent health sheet.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/vaccine/{filename}"
@ -623,6 +694,7 @@ class ParentalAuthorizationView(LoginRequiredMixin, View):
"""
Display the sent parental authorization.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/parental/{filename}"
@ -646,6 +718,7 @@ class ReceiptView(LoginRequiredMixin, View):
"""
Display the sent payment receipt or scholarship notification.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/authorization/receipt/{filename}"
@ -668,6 +741,7 @@ class SolutionView(LoginRequiredMixin, View):
"""
Display the sent solution.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/solutions/{filename}"
@ -686,7 +760,7 @@ class SolutionView(LoginRequiredMixin, View):
if not (user.registration.is_admin
or user.registration.is_volunteer and user.registration
in (solution.participation.tournament
if not solution.final_solution else Tournament.final_tournament()).organizers.all()
if not solution.final_solution else Tournament.final_tournament()).organizers.all()
or user.registration.is_volunteer
and Passage.objects.filter(Q(pool__juries=user.registration)
| Q(pool__tournament__in=user.registration.organized_tournaments.all()),
@ -711,6 +785,7 @@ class SynthesisView(LoginRequiredMixin, View):
"""
Display the sent synthesis.
"""
def get(self, request, *args, **kwargs):
filename = kwargs["filename"]
path = f"media/syntheses/{filename}"

View File

@ -57,7 +57,7 @@ def get_hello_asso_access_token():
return _access_token
def get_checkout_intent(checkout_id):
def get_checkout_intent(checkout_id, none_if_link_disabled=False):
base_url = _get_hello_asso_api_base_url()
token = get_hello_asso_access_token()
@ -72,7 +72,7 @@ def get_checkout_intent(checkout_id):
response.raise_for_status()
checkout_intent = response.json()
if requests.head(checkout_intent["redirectUrl"]).status_code == 404:
if none_if_link_disabled and requests.head(checkout_intent["redirectUrl"]).status_code == 404:
return None
return checkout_intent