Setup payment interface
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
parent
7c9083a6b8
commit
4d157b2bd7
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: TFJM\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-12 22:29+0100\n"
|
||||
"POT-Creation-Date: 2024-02-18 22:25+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"
|
||||
|
@ -29,12 +29,12 @@ msgstr "équipes"
|
|||
#: draw/admin.py:40 draw/admin.py:56 draw/models.py:24
|
||||
#: participation/admin.py:16 participation/admin.py:73
|
||||
#: participation/admin.py:104 participation/models.py:419
|
||||
#: participation/models.py:443 participation/models.py:512
|
||||
#: participation/models.py:443 participation/models.py:513
|
||||
msgid "tournament"
|
||||
msgstr "tournoi"
|
||||
|
||||
#: draw/admin.py:60 draw/models.py:231 draw/models.py:426
|
||||
#: participation/models.py:516
|
||||
#: participation/models.py:517
|
||||
msgid "round"
|
||||
msgstr "tour"
|
||||
|
||||
|
@ -168,7 +168,7 @@ msgstr "La poule en cours, où les équipes choisissent leurs problèmes"
|
|||
msgid "rounds"
|
||||
msgstr "tours"
|
||||
|
||||
#: draw/models.py:254 participation/models.py:530
|
||||
#: draw/models.py:254 participation/models.py:531
|
||||
msgid "letter"
|
||||
msgstr "lettre"
|
||||
|
||||
|
@ -207,17 +207,17 @@ msgid "Pool {letter}{number}"
|
|||
msgstr "Poule {letter}{number}"
|
||||
|
||||
#: draw/models.py:407 draw/models.py:434 participation/admin.py:69
|
||||
#: participation/admin.py:88 participation/models.py:582
|
||||
#: participation/models.py:591 participation/tables.py:83
|
||||
#: participation/admin.py:88 participation/models.py:583
|
||||
#: participation/models.py:592 participation/tables.py:83
|
||||
msgid "pool"
|
||||
msgstr "poule"
|
||||
|
||||
#: draw/models.py:408 participation/models.py:583
|
||||
#: draw/models.py:408 participation/models.py:584
|
||||
msgid "pools"
|
||||
msgstr "poules"
|
||||
|
||||
#: draw/models.py:420 participation/models.py:502 participation/models.py:752
|
||||
#: participation/models.py:782 participation/models.py:820
|
||||
#: draw/models.py:420 participation/models.py:503 participation/models.py:753
|
||||
#: participation/models.py:783 participation/models.py:821
|
||||
msgid "participation"
|
||||
msgstr "participation"
|
||||
|
||||
|
@ -241,8 +241,8 @@ msgid ""
|
|||
msgstr ""
|
||||
"L'ordre de choix dans la poule, entre 0 et la taille de la poule moins 1."
|
||||
|
||||
#: draw/models.py:457 draw/models.py:480 participation/models.py:605
|
||||
#: participation/models.py:789
|
||||
#: draw/models.py:457 draw/models.py:480 participation/models.py:606
|
||||
#: participation/models.py:790
|
||||
#, python-brace-format
|
||||
msgid "Problem #{problem}"
|
||||
msgstr "Problème n°{problem}"
|
||||
|
@ -368,8 +368,8 @@ msgstr "Êtes-vous sûr·e de vouloir annuler le tirage au sort ?"
|
|||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
#: draw/views.py:31 participation/views.py:151 participation/views.py:438
|
||||
#: participation/views.py:469
|
||||
#: draw/views.py:31 participation/views.py:151 participation/views.py:444
|
||||
#: participation/views.py:475
|
||||
msgid "You are not in a team."
|
||||
msgstr "Vous n'êtes pas dans une équipe."
|
||||
|
||||
|
@ -447,21 +447,21 @@ msgid "selected for final"
|
|||
msgstr "sélectionnée pour la finale"
|
||||
|
||||
#: participation/admin.py:57 participation/admin.py:116
|
||||
#: participation/models.py:612 participation/tables.py:111
|
||||
#: participation/models.py:613 participation/tables.py:111
|
||||
msgid "defender"
|
||||
msgstr "défenseur⋅se"
|
||||
|
||||
#: participation/admin.py:61 participation/models.py:619
|
||||
#: participation/models.py:832
|
||||
#: participation/admin.py:61 participation/models.py:620
|
||||
#: participation/models.py:833
|
||||
msgid "opponent"
|
||||
msgstr "opposant⋅e"
|
||||
|
||||
#: participation/admin.py:65 participation/models.py:626
|
||||
#: participation/models.py:833
|
||||
#: participation/admin.py:65 participation/models.py:627
|
||||
#: participation/models.py:834
|
||||
msgid "reporter"
|
||||
msgstr "rapporteur⋅e"
|
||||
|
||||
#: participation/admin.py:120 participation/models.py:787
|
||||
#: participation/admin.py:120 participation/models.py:788
|
||||
msgid "problem"
|
||||
msgstr "numéro de problème"
|
||||
|
||||
|
@ -484,13 +484,14 @@ msgstr "Aucune équipe n'a été trouvée avec ce code d'accès."
|
|||
#: participation/forms.py:86 participation/forms.py:351
|
||||
#: registration/forms.py:122 registration/forms.py:144
|
||||
#: registration/forms.py:166 registration/forms.py:188
|
||||
#: registration/forms.py:235
|
||||
#: registration/forms.py:234 registration/forms.py:267
|
||||
msgid "The uploaded file size must be under 2 Mo."
|
||||
msgstr "Le fichier envoyé doit peser moins de 2 Mo."
|
||||
|
||||
#: participation/forms.py:88 registration/forms.py:124
|
||||
#: registration/forms.py:146 registration/forms.py:168
|
||||
#: registration/forms.py:190 registration/forms.py:237
|
||||
#: registration/forms.py:190 registration/forms.py:236
|
||||
#: registration/forms.py:269
|
||||
msgid "The uploaded file must be a PDF, PNG of JPEG file."
|
||||
msgstr "Le fichier envoyé doit être au format PDF, PNG ou JPEG."
|
||||
|
||||
|
@ -818,11 +819,11 @@ msgstr ""
|
|||
"notification de bourse) pour participer au tournoi.</p><p>Les participant⋅es "
|
||||
"qui n'ont pas encore payé sont : {participants}.</p>"
|
||||
|
||||
#: participation/models.py:477
|
||||
#: participation/models.py:478
|
||||
msgid "Missing payments"
|
||||
msgstr "Paiements manquants"
|
||||
|
||||
#: participation/models.py:484
|
||||
#: participation/models.py:485
|
||||
msgid ""
|
||||
"<p>The solutions for the tournament of {tournament} are due on the {date:%Y-"
|
||||
"%m-%d %H:%M}.</p><p>You have currently sent <strong>{nb_solutions}</strong> "
|
||||
|
@ -837,36 +838,36 @@ msgstr ""
|
|||
"pouvez envoyer vos solutions sur <a href='{url}'>votre page de "
|
||||
"participation</a>.</p>"
|
||||
|
||||
#: participation/models.py:493
|
||||
#: participation/models.py:494
|
||||
msgid "Solutions due"
|
||||
msgstr "Rendu des solutions"
|
||||
|
||||
#: participation/models.py:503 participation/models.py:536
|
||||
#: participation/models.py:504 participation/models.py:537
|
||||
msgid "participations"
|
||||
msgstr "participations"
|
||||
|
||||
#: participation/models.py:518 participation/models.py:519
|
||||
#: participation/models.py:519 participation/models.py:520
|
||||
#, python-brace-format
|
||||
msgid "Round {round}"
|
||||
msgstr "Tour {round}"
|
||||
|
||||
#: participation/models.py:542
|
||||
#: participation/models.py:543
|
||||
msgid "juries"
|
||||
msgstr "jurys"
|
||||
|
||||
#: participation/models.py:549
|
||||
#: participation/models.py:550
|
||||
msgid "BigBlueButton URL"
|
||||
msgstr "Lien BigBlueButton"
|
||||
|
||||
#: participation/models.py:550
|
||||
#: participation/models.py:551
|
||||
msgid "The link of the BBB visio for this pool."
|
||||
msgstr "Le lien du salon BBB pour cette poule."
|
||||
|
||||
#: participation/models.py:555
|
||||
#: participation/models.py:556
|
||||
msgid "results available"
|
||||
msgstr "résultats disponibles"
|
||||
|
||||
#: participation/models.py:556
|
||||
#: participation/models.py:557
|
||||
msgid ""
|
||||
"Check this case when results become accessible to teams. They stay "
|
||||
"accessible to you. Only averages are given."
|
||||
|
@ -875,28 +876,28 @@ msgstr ""
|
|||
"Ils restent toujours accessibles pour vous. Seules les moyennes sont "
|
||||
"communiquées."
|
||||
|
||||
#: participation/models.py:576
|
||||
#: participation/models.py:577
|
||||
#, python-brace-format
|
||||
msgid "Pool of day {round} for tournament {tournament} with teams {teams}"
|
||||
msgstr "Poule du jour {round} du tournoi {tournament} avec les équipes {teams}"
|
||||
|
||||
#: participation/models.py:596
|
||||
#: participation/models.py:597
|
||||
msgid "position"
|
||||
msgstr "position"
|
||||
|
||||
#: participation/models.py:603
|
||||
#: participation/models.py:604
|
||||
msgid "defended solution"
|
||||
msgstr "solution défendue"
|
||||
|
||||
#: participation/models.py:636
|
||||
#: participation/models.py:637
|
||||
msgid "observer"
|
||||
msgstr "observateur⋅rice"
|
||||
|
||||
#: participation/models.py:641
|
||||
#: participation/models.py:642
|
||||
msgid "penalties"
|
||||
msgstr "pénalités"
|
||||
|
||||
#: participation/models.py:643
|
||||
#: participation/models.py:644
|
||||
msgid ""
|
||||
"Number of penalties for the defender. The defender will loose a 0.5 "
|
||||
"coefficient per penalty."
|
||||
|
@ -904,124 +905,124 @@ msgstr ""
|
|||
"Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 "
|
||||
"sur sa présentation orale par pénalité."
|
||||
|
||||
#: participation/models.py:719 participation/models.py:722
|
||||
#: participation/models.py:725 participation/models.py:728
|
||||
#: participation/models.py:720 participation/models.py:723
|
||||
#: participation/models.py:726 participation/models.py:729
|
||||
#, python-brace-format
|
||||
msgid "Team {trigram} is not registered in the pool."
|
||||
msgstr "L'équipe {trigram} n'est pas inscrite dans la poule."
|
||||
|
||||
#: participation/models.py:733
|
||||
#: participation/models.py:734
|
||||
#, python-brace-format
|
||||
msgid "Passage of {defender} for problem {problem}"
|
||||
msgstr "Passage de {defender} pour le problème {problem}"
|
||||
|
||||
#: participation/models.py:737 participation/models.py:746
|
||||
#: participation/models.py:827 participation/models.py:869
|
||||
#: participation/models.py:738 participation/models.py:747
|
||||
#: participation/models.py:828 participation/models.py:870
|
||||
msgid "passage"
|
||||
msgstr "passage"
|
||||
|
||||
#: participation/models.py:738
|
||||
#: participation/models.py:739
|
||||
msgid "passages"
|
||||
msgstr "passages"
|
||||
|
||||
#: participation/models.py:757
|
||||
#: participation/models.py:758
|
||||
msgid "difference"
|
||||
msgstr "différence"
|
||||
|
||||
#: participation/models.py:758
|
||||
#: participation/models.py:759
|
||||
msgid "Score to add/remove on the final score"
|
||||
msgstr "Score à ajouter/retrancher au score final"
|
||||
|
||||
#: participation/models.py:765
|
||||
#: participation/models.py:766
|
||||
msgid "tweak"
|
||||
msgstr "harmonisation"
|
||||
|
||||
#: participation/models.py:766
|
||||
#: participation/models.py:767
|
||||
msgid "tweaks"
|
||||
msgstr "harmonisations"
|
||||
|
||||
#: participation/models.py:794
|
||||
#: participation/models.py:795
|
||||
msgid "solution for the final tournament"
|
||||
msgstr "solution pour la finale"
|
||||
|
||||
#: participation/models.py:799 participation/models.py:838
|
||||
#: participation/models.py:800 participation/models.py:839
|
||||
msgid "file"
|
||||
msgstr "fichier"
|
||||
|
||||
#: participation/models.py:805
|
||||
#: participation/models.py:806
|
||||
#, python-brace-format
|
||||
msgid "Solution of team {team} for problem {problem}"
|
||||
msgstr "Solution de l'équipe {team} pour le problème {problem}"
|
||||
|
||||
#: participation/models.py:807
|
||||
#: participation/models.py:808
|
||||
msgid "for final"
|
||||
msgstr "pour la finale"
|
||||
|
||||
#: participation/models.py:810
|
||||
#: participation/models.py:811
|
||||
msgid "solution"
|
||||
msgstr "solution"
|
||||
|
||||
#: participation/models.py:811
|
||||
#: participation/models.py:812
|
||||
msgid "solutions"
|
||||
msgstr "solutions"
|
||||
|
||||
#: participation/models.py:844
|
||||
#: participation/models.py:845
|
||||
#, python-brace-format
|
||||
msgid "Synthesis of {team} as {type} for problem {problem} of {defender}"
|
||||
msgstr ""
|
||||
"Note de synthèse de l'équipe {team} en tant que {type} pour le problème "
|
||||
"{problem} de {defender}"
|
||||
|
||||
#: participation/models.py:852
|
||||
#: participation/models.py:853
|
||||
msgid "synthesis"
|
||||
msgstr "note de synthèse"
|
||||
|
||||
#: participation/models.py:853
|
||||
#: participation/models.py:854
|
||||
msgid "syntheses"
|
||||
msgstr "notes de synthèse"
|
||||
|
||||
#: participation/models.py:862
|
||||
#: participation/models.py:863
|
||||
msgid "jury"
|
||||
msgstr "jury"
|
||||
|
||||
#: participation/models.py:874
|
||||
#: participation/models.py:875
|
||||
msgid "defender writing note"
|
||||
msgstr "note d'écrit de la défense"
|
||||
|
||||
#: participation/models.py:880
|
||||
#: participation/models.py:881
|
||||
msgid "defender oral note"
|
||||
msgstr "note d'oral de la défense"
|
||||
|
||||
#: participation/models.py:886
|
||||
#: participation/models.py:887
|
||||
msgid "opponent writing note"
|
||||
msgstr "note d'écrit de l'opposition"
|
||||
|
||||
#: participation/models.py:892
|
||||
#: participation/models.py:893
|
||||
msgid "opponent oral note"
|
||||
msgstr "note d'oral de l'opposition"
|
||||
|
||||
#: participation/models.py:898
|
||||
#: participation/models.py:899
|
||||
msgid "reporter writing note"
|
||||
msgstr "note d'écrit du rapportage"
|
||||
|
||||
#: participation/models.py:904
|
||||
#: participation/models.py:905
|
||||
msgid "reporter oral note"
|
||||
msgstr "note d'oral du rapportage"
|
||||
|
||||
#: participation/models.py:910
|
||||
#: participation/models.py:911
|
||||
msgid "observer note"
|
||||
msgstr "note de l'observation"
|
||||
|
||||
#: participation/models.py:939
|
||||
#: participation/models.py:940
|
||||
#, python-brace-format
|
||||
msgid "Notes of {jury} for {passage}"
|
||||
msgstr "Notes de {jury} pour le {passage}"
|
||||
|
||||
#: participation/models.py:946
|
||||
#: participation/models.py:947
|
||||
msgid "note"
|
||||
msgstr "note"
|
||||
|
||||
#: participation/models.py:947
|
||||
#: participation/models.py:948
|
||||
msgid "notes"
|
||||
msgstr "notes"
|
||||
|
||||
|
@ -1090,7 +1091,6 @@ msgstr "Rejoindre"
|
|||
#: participation/templates/participation/update_team.html:12
|
||||
#: registration/templates/registration/update_user.html:16
|
||||
#: registration/templates/registration/user_detail.html:186
|
||||
#: registration/templates/registration/user_detail.html:223
|
||||
msgid "Update"
|
||||
msgstr "Modifier"
|
||||
|
||||
|
@ -1498,7 +1498,7 @@ msgid "Invalidate"
|
|||
msgstr "Invalider"
|
||||
|
||||
#: participation/templates/participation/team_detail.html:186
|
||||
#: participation/views.py:323
|
||||
#: participation/views.py:329
|
||||
msgid "Upload motivation letter"
|
||||
msgstr "Envoyer la lettre de motivation"
|
||||
|
||||
|
@ -1507,7 +1507,7 @@ msgid "Update team"
|
|||
msgstr "Modifier l'équipe"
|
||||
|
||||
#: participation/templates/participation/team_detail.html:196
|
||||
#: participation/views.py:432
|
||||
#: participation/views.py:438
|
||||
msgid "Leave team"
|
||||
msgstr "Quitter l'équipe"
|
||||
|
||||
|
@ -1641,7 +1641,7 @@ msgstr "Vous êtes déjà dans une équipe."
|
|||
msgid "Join team"
|
||||
msgstr "Rejoindre une équipe"
|
||||
|
||||
#: participation/views.py:152 participation/views.py:470
|
||||
#: participation/views.py:152 participation/views.py:476
|
||||
msgid "You don't participate, so you don't have any team."
|
||||
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
|
||||
|
||||
|
@ -1677,95 +1677,95 @@ msgstr "Vous n'êtes pas un⋅e organisateur⋅rice du tournoi."
|
|||
msgid "This team has no pending validation."
|
||||
msgstr "L'équipe n'a pas de validation en attente."
|
||||
|
||||
#: participation/views.py:266
|
||||
#: participation/views.py:272
|
||||
msgid "You must specify if you validate the registration or not."
|
||||
msgstr "Vous devez spécifier si vous validez l'inscription ou non."
|
||||
|
||||
#: participation/views.py:301
|
||||
#: participation/views.py:307
|
||||
#, python-brace-format
|
||||
msgid "Update team {trigram}"
|
||||
msgstr "Mise à jour de l'équipe {trigram}"
|
||||
|
||||
#: participation/views.py:362 participation/views.py:418
|
||||
#: participation/views.py:368 participation/views.py:424
|
||||
#, python-brace-format
|
||||
msgid "Motivation letter of {team}.{ext}"
|
||||
msgstr "Lettre de motivation de {team}.{ext}"
|
||||
|
||||
#: participation/views.py:393
|
||||
#: participation/views.py:399
|
||||
#, python-brace-format
|
||||
msgid "Photo authorization of {participant}.{ext}"
|
||||
msgstr "Autorisation de droit à l'image de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:399
|
||||
#: participation/views.py:405
|
||||
#, python-brace-format
|
||||
msgid "Parental authorization of {participant}.{ext}"
|
||||
msgstr "Autorisation parentale de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:406
|
||||
#: participation/views.py:412
|
||||
#, python-brace-format
|
||||
msgid "Health sheet of {participant}.{ext}"
|
||||
msgstr "Fiche sanitaire de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:412
|
||||
#: participation/views.py:418
|
||||
#, python-brace-format
|
||||
msgid "Vaccine sheet of {participant}.{ext}"
|
||||
msgstr "Carnet de vaccination de {participant}.{ext}"
|
||||
|
||||
#: participation/views.py:422
|
||||
#: participation/views.py:428
|
||||
#, python-brace-format
|
||||
msgid "Photo authorizations of team {trigram}.zip"
|
||||
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
|
||||
|
||||
#: participation/views.py:440
|
||||
#: participation/views.py:446
|
||||
msgid "The team is already validated or the validation is pending."
|
||||
msgstr "La validation de l'équipe est déjà faite ou en cours."
|
||||
|
||||
#: participation/views.py:484
|
||||
#: participation/views.py:490
|
||||
msgid "The team is not validated yet."
|
||||
msgstr "L'équipe n'est pas encore validée."
|
||||
|
||||
#: participation/views.py:498
|
||||
#: participation/views.py:504
|
||||
#, python-brace-format
|
||||
msgid "Participation of team {trigram}"
|
||||
msgstr "Participation de l'équipe {trigram}"
|
||||
|
||||
#: participation/views.py:634
|
||||
#: participation/views.py:640
|
||||
msgid "You can't upload a solution after the deadline."
|
||||
msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
|
||||
|
||||
#: participation/views.py:742
|
||||
#: participation/views.py:748
|
||||
#, python-brace-format
|
||||
msgid "Solutions for pool {pool} of tournament {tournament}.zip"
|
||||
msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip"
|
||||
|
||||
#: participation/views.py:743
|
||||
#: participation/views.py:749
|
||||
#, python-brace-format
|
||||
msgid "Syntheses for pool {pool} of tournament {tournament}.zip"
|
||||
msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip"
|
||||
|
||||
#: participation/views.py:761
|
||||
#: participation/views.py:767
|
||||
#, python-brace-format
|
||||
msgid "Jurys of {pool}"
|
||||
msgstr "Juré⋅es de la {pool}"
|
||||
|
||||
#: participation/views.py:788
|
||||
#: participation/views.py:794
|
||||
msgid "New TFJM² jury account"
|
||||
msgstr "Nouveau compte de juré⋅e pour le TFJM²"
|
||||
|
||||
#: participation/views.py:801
|
||||
#: participation/views.py:807
|
||||
#, python-brace-format
|
||||
msgid "The jury {name} has been successfully added!"
|
||||
msgstr "{name} a été ajouté⋅e avec succès en tant que juré⋅e !"
|
||||
|
||||
#: participation/views.py:838
|
||||
#: participation/views.py:844
|
||||
msgid "The following user is not registered as a jury:"
|
||||
msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e :"
|
||||
|
||||
#: participation/views.py:852
|
||||
#: participation/views.py:858
|
||||
msgid "Notes were successfully uploaded."
|
||||
msgstr "Les notes ont bien été envoyées."
|
||||
|
||||
#: participation/views.py:1516
|
||||
#: participation/views.py:1522
|
||||
msgid "You can't upload a synthesis after the deadline."
|
||||
msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
|
||||
|
||||
|
@ -1799,7 +1799,7 @@ msgstr "encadrant⋅e"
|
|||
msgid "Pending"
|
||||
msgstr "En attente"
|
||||
|
||||
#: registration/forms.py:245
|
||||
#: registration/forms.py:244 registration/forms.py:277
|
||||
msgid "You must upload your receipt."
|
||||
msgstr "Vous devez envoyer votre justificatif."
|
||||
|
||||
|
@ -1848,6 +1848,7 @@ msgid "Male"
|
|||
msgstr "Homme"
|
||||
|
||||
#: registration/models.py:155
|
||||
#: registration/templates/registration/payment_form.html:73
|
||||
msgid "Other"
|
||||
msgstr "Autre"
|
||||
|
||||
|
@ -2162,11 +2163,17 @@ msgstr "type"
|
|||
msgid "No payment"
|
||||
msgstr "Pas de paiement"
|
||||
|
||||
#: registration/models.py:529
|
||||
#: registration/templates/registration/payment_form.html:56
|
||||
msgid "Credit card"
|
||||
msgstr "Carte bancaire"
|
||||
|
||||
#: registration/models.py:530
|
||||
msgid "Scholarship"
|
||||
msgstr "Notification de bourse"
|
||||
|
||||
#: registration/models.py:531
|
||||
#: registration/templates/registration/payment_form.html:61
|
||||
msgid "Bank transfer"
|
||||
msgstr "Virement bancaire"
|
||||
|
||||
|
@ -2207,7 +2214,7 @@ msgstr "paiement valide"
|
|||
#: registration/models.py:571
|
||||
#, python-brace-format
|
||||
msgid "Payment of {registrations}"
|
||||
msgstr "Paiements de {registration}"
|
||||
msgstr "Paiements de {registrations}"
|
||||
|
||||
#: registration/models.py:574
|
||||
msgid "payment"
|
||||
|
@ -2378,6 +2385,54 @@ msgstr ""
|
|||
msgid "Reset my password"
|
||||
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."
|
||||
|
||||
#: registration/templates/registration/payment_form.html:13
|
||||
msgid "This price includes the registrations of all members of your team."
|
||||
msgstr "Ce prix inclut les inscriptions de tous les membres de votre équipe."
|
||||
|
||||
#: registration/templates/registration/payment_form.html:17
|
||||
msgid ""
|
||||
"This price includes only your own registration. You are exempt from payment "
|
||||
"if you have a scholarship, but you must then send us a proof of your "
|
||||
"scholarship."
|
||||
msgstr ""
|
||||
"Ce prix inclut seulement votre propre inscription. Vous êtes exempté⋅e de "
|
||||
"paiement si vous avez une bourse, mais vous devez alors nous envoyer un "
|
||||
"justificatif de votre bourse."
|
||||
|
||||
#: registration/templates/registration/payment_form.html:27
|
||||
msgid ""
|
||||
"You want finally that each member pays its own registration? Then click on "
|
||||
"the button:"
|
||||
msgstr ""
|
||||
"Vous voulez finalement que chaque membre paie sa propre inscription ? Alors "
|
||||
"cliquez sur le bouton :"
|
||||
|
||||
#: registration/templates/registration/payment_form.html:32
|
||||
msgid "Back to single payments"
|
||||
msgstr "Retour aux paiements individuels"
|
||||
|
||||
#: registration/templates/registration/payment_form.html:36
|
||||
msgid ""
|
||||
"You want to pay for the registrations of all members of your team, or your "
|
||||
"school will pay for all registrations? Then click on the button:"
|
||||
msgstr ""
|
||||
"Vous voulez payer pour les inscriptions de tous les membres de votre équipe, "
|
||||
"ou votre école paiera pour toutes les inscriptions ? Alors cliquez sur le "
|
||||
"bouton :"
|
||||
|
||||
#: registration/templates/registration/payment_form.html:42
|
||||
msgid "Group the payments of my team"
|
||||
msgstr "Regrouper les paiements de mon équipe"
|
||||
|
||||
#: registration/templates/registration/payment_form.html:67
|
||||
msgid "I have a scholarship"
|
||||
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
|
||||
|
@ -2526,7 +2581,7 @@ msgid "valid:"
|
|||
msgstr "valide :"
|
||||
|
||||
#: registration/templates/registration/user_detail.html:163
|
||||
#: registration/templates/registration/user_detail.html:222
|
||||
#: registration/views.py:458
|
||||
msgid "Update payment"
|
||||
msgstr "Modifier le paiement"
|
||||
|
||||
|
@ -2597,30 +2652,30 @@ msgstr "Détails de l'utilisateur⋅rice {user}"
|
|||
msgid "Update user {user}"
|
||||
msgstr "Mise à jour de l'utilisateur⋅rice {user}"
|
||||
|
||||
#: registration/views.py:492
|
||||
#: registration/views.py:503
|
||||
#, python-brace-format
|
||||
msgid "Photo authorization of {student}.{ext}"
|
||||
msgstr "Autorisation de droit à l'image de {student}.{ext}"
|
||||
|
||||
#: registration/views.py:515
|
||||
#: registration/views.py:526
|
||||
#, python-brace-format
|
||||
msgid "Health sheet of {student}.{ext}"
|
||||
msgstr "Fiche sanitaire de {student}.{ext}"
|
||||
|
||||
#: registration/views.py:538
|
||||
#: registration/views.py:549
|
||||
#, python-brace-format
|
||||
msgid "Vaccine sheet of {student}.{ext}"
|
||||
msgstr "Carnet de vaccination de {student}.{ext}"
|
||||
|
||||
#: registration/views.py:561
|
||||
#: registration/views.py:572
|
||||
#, python-brace-format
|
||||
msgid "Parental authorization of {student}.{ext}"
|
||||
msgstr "Autorisation parentale de {student}.{ext}"
|
||||
|
||||
#: registration/views.py:583
|
||||
#: registration/views.py:594
|
||||
#, python-brace-format
|
||||
msgid "Scholarship attestation of {user}.{ext}"
|
||||
msgstr "Notification de bourse de {user}.{ext}"
|
||||
msgid "Payment receipt of {user}.{ext}"
|
||||
msgstr "Justificatif de paiement de {user}.{ext}"
|
||||
|
||||
#: tfjm/settings.py:164
|
||||
msgid "English"
|
||||
|
@ -2783,3 +2838,7 @@ msgstr "Aucun résultat."
|
|||
#: tfjm/templates/sidebar.html:10 tfjm/templates/sidebar.html:21
|
||||
msgid "Informations"
|
||||
msgstr "Informations"
|
||||
|
||||
#, python-brace-format
|
||||
#~ msgid "Scholarship attestation of {user}.{ext}"
|
||||
#~ msgstr "Notification de bourse de {user}.{ext}"
|
||||
|
|
|
@ -219,7 +219,7 @@ class VolunteerRegistrationForm(forms.ModelForm):
|
|||
fields = ('professional_activity', 'admin', 'give_contact_to_animath', 'email_confirmed',)
|
||||
|
||||
|
||||
class PaymentForm(forms.ModelForm):
|
||||
class PaymentAdminForm(forms.ModelForm):
|
||||
"""
|
||||
Indicate payment information
|
||||
"""
|
||||
|
@ -228,7 +228,6 @@ class PaymentForm(forms.ModelForm):
|
|||
self.fields["valid"].widget.choices[0] = ('unknown', _("Pending"))
|
||||
|
||||
def clean_receipt(self):
|
||||
print(self.files)
|
||||
if "receipt" in self.files:
|
||||
file = self.files["receipt"]
|
||||
if file.size > 2e6:
|
||||
|
@ -241,7 +240,7 @@ class PaymentForm(forms.ModelForm):
|
|||
cleaned_data = super().clean()
|
||||
|
||||
if "type" in cleaned_data and cleaned_data['type'] in ["scholarship", "bank_transfer"] \
|
||||
and "receipt" not in self.files and not self.instance.scholarship_file:
|
||||
and "receipt" not in self.files and not self.instance.receipt:
|
||||
self.add_error("receipt", _("You must upload your receipt."))
|
||||
|
||||
return cleaned_data
|
||||
|
@ -249,3 +248,37 @@ class PaymentForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = Payment
|
||||
fields = ('type', 'receipt', 'additional_information', 'valid',)
|
||||
|
||||
|
||||
class PaymentForm(forms.ModelForm):
|
||||
"""
|
||||
Indicate payment information
|
||||
"""
|
||||
def __init__(self, payment_type, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['type'].widget = forms.HiddenInput(attrs={'value': payment_type})
|
||||
self.fields['receipt'].required = payment_type in ["scholarship", "bank_transfer"]
|
||||
self.fields['additional_information'].required = payment_type in ["other"]
|
||||
|
||||
def clean_receipt(self):
|
||||
if "receipt" in self.files:
|
||||
file = self.files["receipt"]
|
||||
if file.size > 2e6:
|
||||
raise ValidationError(_("The uploaded file size must be under 2 Mo."))
|
||||
if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]:
|
||||
raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
|
||||
return self.cleaned_data["receipt"]
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
||||
if "type" in cleaned_data and cleaned_data['type'] in ["scholarship", "bank_transfer"] \
|
||||
and "receipt" not in self.files and not self.instance.receipt:
|
||||
self.add_error("receipt", _("You must upload your receipt."))
|
||||
|
||||
return cleaned_data
|
||||
|
||||
class Meta:
|
||||
model = Payment
|
||||
fields = ('type', 'receipt', 'additional_information',)
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ class Migration(migrations.Migration):
|
|||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('type', models.CharField(blank=True, choices=[('', 'No payment'), ('helloasso', 'Hello Asso'), ('scholarship', 'Scholarship'), ('bank_transfer', 'Bank transfer'), ('other', 'Other (please indicate)'), ('free', 'The tournament is free')], default='', max_length=16, verbose_name='type')),
|
||||
('scholarship_file', models.FileField(blank=True, default='', help_text='only if you have a scholarship.', upload_to=registration.models.get_scholarship_filename, verbose_name='scholarship file')),
|
||||
('scholarship_file', models.FileField(blank=True, default='', help_text='only if you have a scholarship.', upload_to=registration.models.get_receipt_filename, verbose_name='scholarship file')),
|
||||
('additional_information', models.TextField(blank=True, default='', help_text='To help us to find your payment.', verbose_name='additional information')),
|
||||
('valid', models.BooleanField(default=False, null=True, verbose_name='valid')),
|
||||
('registration', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='payment', to='registration.participantregistration', verbose_name='registration')),
|
||||
|
|
|
@ -60,7 +60,7 @@ class Migration(migrations.Migration):
|
|||
blank=True,
|
||||
default="",
|
||||
help_text="only if you have a scholarship or if you chose a bank transfer.",
|
||||
upload_to=registration.models.get_scholarship_filename,
|
||||
upload_to=registration.models.get_receipt_filename,
|
||||
verbose_name="receipt",
|
||||
),
|
||||
),
|
||||
|
|
|
@ -492,8 +492,8 @@ class VolunteerRegistration(Registration):
|
|||
verbose_name_plural = _("volunteer registrations")
|
||||
|
||||
|
||||
def get_scholarship_filename(instance, filename):
|
||||
return f"authorization/scholarship/scholarship_{instance.registration.pk}"
|
||||
def get_receipt_filename(instance, filename):
|
||||
return f"authorization/receipt/receipt_{instance.id}"
|
||||
|
||||
|
||||
class Payment(models.Model):
|
||||
|
@ -526,7 +526,7 @@ class Payment(models.Model):
|
|||
max_length=16,
|
||||
choices=[
|
||||
('', _("No payment")),
|
||||
('helloasso', "Hello Asso"),
|
||||
('helloasso', _("Credit card")),
|
||||
('scholarship', _("Scholarship")),
|
||||
('bank_transfer', _("Bank transfer")),
|
||||
('other', _("Other (please indicate)")),
|
||||
|
@ -546,7 +546,7 @@ class Payment(models.Model):
|
|||
receipt = models.FileField(
|
||||
verbose_name=_("receipt"),
|
||||
help_text=_("only if you have a scholarship or if you chose a bank transfer."),
|
||||
upload_to=get_scholarship_filename,
|
||||
upload_to=get_receipt_filename,
|
||||
blank=True,
|
||||
default="",
|
||||
)
|
||||
|
|
|
@ -3,8 +3,140 @@
|
|||
{% load crispy_forms_filters i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="alert alert-warning">
|
||||
Le formulaire de paiement est temporairement désactivé. Il sera accessible d'ici quelques jours.
|
||||
</div>
|
||||
{% if payment.valid is False %}
|
||||
<div class="alert alert-info">
|
||||
<p>
|
||||
{% blocktrans trimmed with amount=payment.amount %}
|
||||
You must pay {{ amount }} € for your registration.
|
||||
{% endblocktrans %}
|
||||
{% if payment.grouped %}
|
||||
{% blocktrans trimmed %}
|
||||
This price includes the registrations of all members of your team.
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans trimmed %}
|
||||
This price includes only your own registration.
|
||||
You are exempt from payment if you have a scholarship,
|
||||
but you must then send us a proof of your scholarship.
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{% if payment.grouped %}
|
||||
{% blocktrans trimmed %}
|
||||
You want finally that each member pays its own registration? Then click on the button:
|
||||
{% endblocktrans %}
|
||||
<div class="text-center">
|
||||
<button class="btn btn-warning">
|
||||
<i class="fas fa-user"></i> {% trans "Back to single payments" %}
|
||||
</button>
|
||||
</div>
|
||||
{% else %}
|
||||
{% blocktrans trimmed %}
|
||||
You want to pay for the registrations of all members of your team,
|
||||
or your school will pay for all registrations? Then click on the button:
|
||||
{% endblocktrans %}
|
||||
<div class="text-center">
|
||||
<button class="btn btn-warning">
|
||||
<i class="fas fa-users"></i> {% trans "Group the payments of my team" %}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<nav>
|
||||
<div class="nav nav-tabs card-header-tabs" id="payment-method-tab" role="tablist">
|
||||
<button class="nav-link active" id="credit-card-tab" data-bs-toggle="tab"
|
||||
data-bs-target="#credit-card" type="button" role="tab"
|
||||
aria-controls="credit-card" aria-selected="true">
|
||||
<i class="fas fa-credit-card"></i> {% trans "Credit card" %}
|
||||
</button>
|
||||
<button class="nav-link" id="bank-transfer-tab" data-bs-toggle="tab"
|
||||
data-bs-target="#bank-transfer" type="button" role="tab"
|
||||
aria-controls="bank-transfer" aria-selected="true">
|
||||
<i class="fas fa-money-check"></i> {% trans "Bank transfer" %}
|
||||
</button>
|
||||
{% if not payment.grouped %}
|
||||
<button class="nav-link" id="scholarship-tab" data-bs-toggle="tab"
|
||||
data-bs-target="#scholarship" type="button" role="tab"
|
||||
aria-controls="scholarship" aria-selected="true">
|
||||
<i class="fas fa-file-invoice"></i> {% trans "I have a scholarship" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<button class="nav-link" id="other-tab" data-bs-toggle="tab"
|
||||
data-bs-target="#other" type="button" role="tab"
|
||||
aria-controls="other" aria-selected="true">
|
||||
<i class="fas fa-question"></i> {% trans "Other" %}
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="tab-content" id="payment-form">
|
||||
<div class="tab-pane fade show active" id="credit-card" role="tabpanel" aria-labelledby="credit-card-tab">
|
||||
Le paiement par carte bancaire s'effectue via Hello Asso. Pour cela, vous pouvez cliquer sur
|
||||
le bouton ci-dessous, qui vous redirigera vers la page de paiement sécurisée de Hello Asso.
|
||||
La validation du paiement sera ensuite faite automatiquement, sous quelques minutes.
|
||||
Si un tiers doit payer pour vous (parents, lycée,…), vous pouvez lui transmettre le lien pour
|
||||
payer pour vous.
|
||||
|
||||
<div class="text-center">
|
||||
<a href="#" class="btn btn-primary">
|
||||
<i class="fas fa-credit-card"></i> Aller sur la page Hello Asso
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="bank-transfer" role="tabpanel" aria-labelledby="bank-transfer-tab">
|
||||
<form id="bank-transfer-form" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ bank_transfer_form|crispy }}
|
||||
<input type="submit" class="btn btn-primary" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="scholarship" role="tabpanel" aria-labelledby="scholarship-tab">
|
||||
<form id="scholarship-form" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ scholarship_form|crispy }}
|
||||
<input type="submit" class="btn btn-primary" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="other" role="tabpanel" aria-labelledby="other-tab">
|
||||
<form id="other-form" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ other_form|crispy }}
|
||||
<input type="submit" class="btn btn-primary" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
||||
{% block extrajavascript %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (document.location.hash) {
|
||||
// Open the tab of the tournament that is present in the hash
|
||||
document.querySelectorAll('button[data-bs-toggle="tab"]').forEach(elem => {
|
||||
if ('#' + elem.getAttribute('aria-controls') === document.location.hash.toLowerCase()) {
|
||||
elem.click()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// When a tab is opened, add the tournament name in the hash
|
||||
document.querySelectorAll('button[data-bs-toggle="tab"]').forEach(
|
||||
elem => elem.addEventListener(
|
||||
'click', () => document.location.hash = '#' + elem.getAttribute('aria-controls')))
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -29,7 +29,7 @@ from tfjm.views import UserMixin, UserRegistrationMixin, VolunteerMixin
|
|||
|
||||
from .forms import AddOrganizerForm, CoachRegistrationForm, HealthSheetForm, \
|
||||
ParentalAuthorizationForm, PaymentForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm, \
|
||||
VaccineSheetForm, VolunteerRegistrationForm
|
||||
VaccineSheetForm, VolunteerRegistrationForm, PaymentAdminForm
|
||||
from .models import ParticipantRegistration, Payment, Registration, StudentRegistration
|
||||
from .tables import RegistrationTable
|
||||
|
||||
|
@ -443,7 +443,7 @@ class InstructionsTemplateView(AuthorizationTemplateView):
|
|||
|
||||
class PaymentUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Payment
|
||||
form_class = PaymentForm
|
||||
form_class = PaymentAdminForm
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not self.request.user.is_authenticated or \
|
||||
|
@ -453,22 +453,33 @@ class PaymentUpdateView(LoginRequiredMixin, UpdateView):
|
|||
return self.handle_no_permission()
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
if not self.request.user.registration.is_admin:
|
||||
form.fields["type"].widget.choices = list(form.fields["type"].widget.choices)[:-1]
|
||||
del form.fields["valid"]
|
||||
return form
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data()
|
||||
context['title'] = _("Update payment")
|
||||
context['bank_transfer_form'] = PaymentForm(payment_type='bank_transfer',
|
||||
data=self.request.POST or None,
|
||||
instance=self.object)
|
||||
|
||||
context['scholarship_form'] = PaymentForm(payment_type='scholarship',
|
||||
data=self.request.POST or None,
|
||||
instance=self.object)
|
||||
|
||||
context['other_form'] = PaymentForm(payment_type='other',
|
||||
data=self.request.POST or None,
|
||||
instance=self.object)
|
||||
return context
|
||||
|
||||
def form_valid(self, form):
|
||||
if not self.request.user.registration.is_admin:
|
||||
form.instance.valid = None
|
||||
form.instance.valid = None
|
||||
old_instance = Payment.objects.get(pk=self.object.pk)
|
||||
if old_instance.receipt:
|
||||
old_instance.receipt.delete()
|
||||
old_instance.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy("registration:user_detail", args=(self.object.registrations.first().user.pk,))
|
||||
|
||||
|
||||
class PhotoAuthorizationView(LoginRequiredMixin, View):
|
||||
"""
|
||||
|
@ -562,9 +573,9 @@ class ParentalAuthorizationView(LoginRequiredMixin, View):
|
|||
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
|
||||
|
||||
|
||||
class ScholarshipView(LoginRequiredMixin, View):
|
||||
class ReceiptView(LoginRequiredMixin, View):
|
||||
"""
|
||||
Display the sent scholarship paper.
|
||||
Display the sent payment receipt or scholarship notification.
|
||||
"""
|
||||
def get(self, request, *args, **kwargs):
|
||||
filename = kwargs["filename"]
|
||||
|
@ -573,14 +584,14 @@ class ScholarshipView(LoginRequiredMixin, View):
|
|||
raise Http404
|
||||
payment = Payment.objects.get(receipt__endswith=filename)
|
||||
user = request.user
|
||||
if not (user.registration in payment.registrations or user.registration.is_admin):
|
||||
if not (user.registration in payment.registrations.all() or user.registration.is_admin):
|
||||
raise PermissionDenied
|
||||
# Guess mime type of the file
|
||||
mime = Magic(mime=True)
|
||||
mime_type = mime.from_file(path)
|
||||
ext = mime_type.split("/")[1].replace("jpeg", "jpg")
|
||||
# Replace file name
|
||||
true_file_name = _("Scholarship attestation of {user}.{ext}").format(user=str(user.registration), ext=ext)
|
||||
true_file_name = _("Payment receipt of {user}.{ext}").format(user=str(user.registration), ext=ext)
|
||||
return FileResponse(open(path, "rb"), content_type=mime_type, filename=true_file_name)
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ from django.views.defaults import bad_request, page_not_found, permission_denied
|
|||
from django.views.generic import TemplateView
|
||||
from participation.views import MotivationLetterView
|
||||
from registration.views import HealthSheetView, ParentalAuthorizationView, PhotoAuthorizationView, \
|
||||
ScholarshipView, SolutionView, SynthesisView, VaccineSheetView
|
||||
ReceiptView, SolutionView, SynthesisView, VaccineSheetView
|
||||
|
||||
from .views import AdminSearchView
|
||||
|
||||
|
@ -49,10 +49,10 @@ urlpatterns = [
|
|||
name='vaccine_sheet'),
|
||||
path('media/authorization/parental/<str:filename>/', ParentalAuthorizationView.as_view(),
|
||||
name='parental_authorization'),
|
||||
path('media/authorization/scholarship/<str:filename>/', ScholarshipView.as_view(),
|
||||
name='scholarship'),
|
||||
path('media/authorization/receipt/<str:filename>/', ReceiptView.as_view(),
|
||||
name='receipt'),
|
||||
path('media/authorization/motivation_letters/<str:filename>/', MotivationLetterView.as_view(),
|
||||
name='scholarship'),
|
||||
name='motivation_letter'),
|
||||
|
||||
path('media/solutions/<str:filename>/', SolutionView.as_view(),
|
||||
name='solution'),
|
||||
|
|
Loading…
Reference in New Issue