Restructure payment model

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2024-02-12 22:30:27 +01:00
parent ece128836a
commit 7c9083a6b8
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
11 changed files with 343 additions and 273 deletions

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-02-11 23:19+0100\n" "POT-Creation-Date: 2024-02-12 22:29+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n" "Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -368,8 +368,8 @@ msgstr "Êtes-vous sûr·e de vouloir annuler le tirage au sort ?"
msgid "Close" msgid "Close"
msgstr "Fermer" msgstr "Fermer"
#: draw/views.py:31 participation/views.py:151 participation/views.py:440 #: draw/views.py:31 participation/views.py:151 participation/views.py:438
#: participation/views.py:471 #: participation/views.py:469
msgid "You are not in a team." msgid "You are not in a team."
msgstr "Vous n'êtes pas dans une équipe." msgstr "Vous n'êtes pas dans une équipe."
@ -710,7 +710,7 @@ msgstr ""
"L'équipe {trigram} n'a pas encore été validée par les organisateurices. " "L'équipe {trigram} n'a pas encore été validée par les organisateurices. "
"Merci de patienter." "Merci de patienter."
#: participation/models.py:193 registration/models.py:481 #: participation/models.py:193 registration/models.py:482
msgid "Pending validation" msgid "Pending validation"
msgstr "Validation en attente" msgstr "Validation en attente"
@ -814,9 +814,9 @@ msgid ""
"not paid yet are: {participants}.</p>" "not paid yet are: {participants}.</p>"
msgstr "" msgstr ""
"<p>L'équipe {trigram} a {nb_missing_payments} paiements manquants. Chaque " "<p>L'équipe {trigram} a {nb_missing_payments} paiements manquants. Chaque "
"membre de l'équipe doit avoir un paiement valide (ou envoyer une notification " "membre de l'équipe doit avoir un paiement valide (ou envoyer une "
"de bourse) pour participer au tournoi.</p><p>Les participant⋅es qui n'ont pas " "notification de bourse) pour participer au tournoi.</p><p>Les participant⋅es "
"encore payé sont : {participants}.</p>" "qui n'ont pas encore payé sont : {participants}.</p>"
#: participation/models.py:477 #: participation/models.py:477
msgid "Missing payments" msgid "Missing payments"
@ -1088,10 +1088,9 @@ msgstr "Rejoindre"
#: participation/templates/participation/team_detail.html:192 #: participation/templates/participation/team_detail.html:192
#: participation/templates/participation/tournament_form.html:12 #: participation/templates/participation/tournament_form.html:12
#: participation/templates/participation/update_team.html:12 #: participation/templates/participation/update_team.html:12
#: registration/templates/registration/payment_form.html:49
#: registration/templates/registration/update_user.html:16 #: registration/templates/registration/update_user.html:16
#: registration/templates/registration/user_detail.html:179 #: registration/templates/registration/user_detail.html:186
#: registration/templates/registration/user_detail.html:216 #: registration/templates/registration/user_detail.html:223
msgid "Update" msgid "Update"
msgstr "Modifier" msgstr "Modifier"
@ -1157,11 +1156,11 @@ msgstr "Envoyer une solution"
#: registration/templates/registration/upload_parental_authorization.html:17 #: registration/templates/registration/upload_parental_authorization.html:17
#: registration/templates/registration/upload_photo_authorization.html:18 #: registration/templates/registration/upload_photo_authorization.html:18
#: registration/templates/registration/upload_vaccine_sheet.html:13 #: registration/templates/registration/upload_vaccine_sheet.html:13
#: registration/templates/registration/user_detail.html:189 #: registration/templates/registration/user_detail.html:196
#: registration/templates/registration/user_detail.html:194 #: registration/templates/registration/user_detail.html:201
#: registration/templates/registration/user_detail.html:199 #: registration/templates/registration/user_detail.html:206
#: registration/templates/registration/user_detail.html:204 #: registration/templates/registration/user_detail.html:211
#: registration/templates/registration/user_detail.html:209 #: registration/templates/registration/user_detail.html:216
msgid "Upload" msgid "Upload"
msgstr "Téléverser" msgstr "Téléverser"
@ -1499,7 +1498,7 @@ msgid "Invalidate"
msgstr "Invalider" msgstr "Invalider"
#: participation/templates/participation/team_detail.html:186 #: participation/templates/participation/team_detail.html:186
#: participation/views.py:325 #: participation/views.py:323
msgid "Upload motivation letter" msgid "Upload motivation letter"
msgstr "Envoyer la lettre de motivation" msgstr "Envoyer la lettre de motivation"
@ -1508,7 +1507,7 @@ msgid "Update team"
msgstr "Modifier l'équipe" msgstr "Modifier l'équipe"
#: participation/templates/participation/team_detail.html:196 #: participation/templates/participation/team_detail.html:196
#: participation/views.py:434 #: participation/views.py:432
msgid "Leave team" msgid "Leave team"
msgstr "Quitter l'équipe" msgstr "Quitter l'équipe"
@ -1642,7 +1641,7 @@ msgstr "Vous êtes déjà dans une équipe."
msgid "Join team" msgid "Join team"
msgstr "Rejoindre une équipe" msgstr "Rejoindre une équipe"
#: participation/views.py:152 participation/views.py:472 #: participation/views.py:152 participation/views.py:470
msgid "You don't participate, so you don't have any team." msgid "You don't participate, so you don't have any team."
msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe." msgstr "Vous ne participez pas, vous n'avez donc pas d'équipe."
@ -1678,95 +1677,95 @@ msgstr "Vous n'êtes pas un⋅e organisateur⋅rice du tournoi."
msgid "This team has no pending validation." msgid "This team has no pending validation."
msgstr "L'équipe n'a pas de validation en attente." msgstr "L'équipe n'a pas de validation en attente."
#: participation/views.py:268 #: participation/views.py:266
msgid "You must specify if you validate the registration or not." msgid "You must specify if you validate the registration or not."
msgstr "Vous devez spécifier si vous validez l'inscription ou non." msgstr "Vous devez spécifier si vous validez l'inscription ou non."
#: participation/views.py:303 #: participation/views.py:301
#, python-brace-format #, python-brace-format
msgid "Update team {trigram}" msgid "Update team {trigram}"
msgstr "Mise à jour de l'équipe {trigram}" msgstr "Mise à jour de l'équipe {trigram}"
#: participation/views.py:364 participation/views.py:420 #: participation/views.py:362 participation/views.py:418
#, python-brace-format #, python-brace-format
msgid "Motivation letter of {team}.{ext}" msgid "Motivation letter of {team}.{ext}"
msgstr "Lettre de motivation de {team}.{ext}" msgstr "Lettre de motivation de {team}.{ext}"
#: participation/views.py:395 #: participation/views.py:393
#, python-brace-format #, python-brace-format
msgid "Photo authorization of {participant}.{ext}" msgid "Photo authorization of {participant}.{ext}"
msgstr "Autorisation de droit à l'image de {participant}.{ext}" msgstr "Autorisation de droit à l'image de {participant}.{ext}"
#: participation/views.py:401 #: participation/views.py:399
#, python-brace-format #, python-brace-format
msgid "Parental authorization of {participant}.{ext}" msgid "Parental authorization of {participant}.{ext}"
msgstr "Autorisation parentale de {participant}.{ext}" msgstr "Autorisation parentale de {participant}.{ext}"
#: participation/views.py:408 #: participation/views.py:406
#, python-brace-format #, python-brace-format
msgid "Health sheet of {participant}.{ext}" msgid "Health sheet of {participant}.{ext}"
msgstr "Fiche sanitaire de {participant}.{ext}" msgstr "Fiche sanitaire de {participant}.{ext}"
#: participation/views.py:414 #: participation/views.py:412
#, python-brace-format #, python-brace-format
msgid "Vaccine sheet of {participant}.{ext}" msgid "Vaccine sheet of {participant}.{ext}"
msgstr "Carnet de vaccination de {participant}.{ext}" msgstr "Carnet de vaccination de {participant}.{ext}"
#: participation/views.py:424 #: participation/views.py:422
#, python-brace-format #, python-brace-format
msgid "Photo authorizations of team {trigram}.zip" msgid "Photo authorizations of team {trigram}.zip"
msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip" msgstr "Autorisations de droit à l'image de l'équipe {trigram}.zip"
#: participation/views.py:442 #: participation/views.py:440
msgid "The team is already validated or the validation is pending." msgid "The team is already validated or the validation is pending."
msgstr "La validation de l'équipe est déjà faite ou en cours." msgstr "La validation de l'équipe est déjà faite ou en cours."
#: participation/views.py:486 #: participation/views.py:484
msgid "The team is not validated yet." msgid "The team is not validated yet."
msgstr "L'équipe n'est pas encore validée." msgstr "L'équipe n'est pas encore validée."
#: participation/views.py:500 #: participation/views.py:498
#, python-brace-format #, python-brace-format
msgid "Participation of team {trigram}" msgid "Participation of team {trigram}"
msgstr "Participation de l'équipe {trigram}" msgstr "Participation de l'équipe {trigram}"
#: participation/views.py:636 #: participation/views.py:634
msgid "You can't upload a solution after the deadline." msgid "You can't upload a solution after the deadline."
msgstr "Vous ne pouvez pas envoyer de solution après la date limite." msgstr "Vous ne pouvez pas envoyer de solution après la date limite."
#: participation/views.py:744 #: participation/views.py:742
#, python-brace-format #, python-brace-format
msgid "Solutions for pool {pool} of tournament {tournament}.zip" msgid "Solutions for pool {pool} of tournament {tournament}.zip"
msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip" msgstr "Solutions pour la poule {pool} du tournoi {tournament}.zip"
#: participation/views.py:745 #: participation/views.py:743
#, python-brace-format #, python-brace-format
msgid "Syntheses for pool {pool} of tournament {tournament}.zip" msgid "Syntheses for pool {pool} of tournament {tournament}.zip"
msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip" msgstr "Notes de synthèses pour la poule {pool} du tournoi {tournament}.zip"
#: participation/views.py:763 #: participation/views.py:761
#, python-brace-format #, python-brace-format
msgid "Jurys of {pool}" msgid "Jurys of {pool}"
msgstr "Juré⋅es de la {pool}" msgstr "Juré⋅es de la {pool}"
#: participation/views.py:790 #: participation/views.py:788
msgid "New TFJM² jury account" msgid "New TFJM² jury account"
msgstr "Nouveau compte de juré⋅e pour le TFJM²" msgstr "Nouveau compte de juré⋅e pour le TFJM²"
#: participation/views.py:803 #: participation/views.py:801
#, python-brace-format #, python-brace-format
msgid "The jury {name} has been successfully added!" msgid "The jury {name} has been successfully added!"
msgstr "{name} a été ajouté⋅e avec succès en tant que juré⋅e !" msgstr "{name} a été ajouté⋅e avec succès en tant que juré⋅e !"
#: participation/views.py:840 #: participation/views.py:838
msgid "The following user is not registered as a jury:" 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 :" msgstr "L'utilisateur⋅rice suivant n'est pas inscrit⋅e en tant que juré⋅e :"
#: participation/views.py:854 #: participation/views.py:852
msgid "Notes were successfully uploaded." msgid "Notes were successfully uploaded."
msgstr "Les notes ont bien été envoyées." msgstr "Les notes ont bien été envoyées."
#: participation/views.py:1518 #: participation/views.py:1516
msgid "You can't upload a synthesis after the deadline." 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." msgstr "Vous ne pouvez pas envoyer de note de synthèse après la date limite."
@ -1780,9 +1779,9 @@ msgstr "prénom"
msgid "last name" msgid "last name"
msgstr "nom de famille" msgstr "nom de famille"
#: registration/admin.py:105 #: registration/admin.py:106
msgid "registration type" msgid "concerned people"
msgstr "type d'inscription" msgstr "personnes concernées"
#: registration/forms.py:22 #: registration/forms.py:22
msgid "role" msgid "role"
@ -1792,7 +1791,7 @@ msgstr "rôle"
msgid "participant" msgid "participant"
msgstr "participant⋅e" msgstr "participant⋅e"
#: registration/forms.py:25 registration/models.py:415 #: registration/forms.py:25 registration/models.py:416
msgid "coach" msgid "coach"
msgstr "encadrant⋅e" msgstr "encadrant⋅e"
@ -1801,8 +1800,8 @@ msgid "Pending"
msgstr "En attente" msgstr "En attente"
#: registration/forms.py:245 #: registration/forms.py:245
msgid "You must upload your scholarship attestation." msgid "You must upload your receipt."
msgstr "Vous devez envoyer votre attestation de bourse." msgstr "Vous devez envoyer votre justificatif."
#: registration/models.py:36 #: registration/models.py:36
msgid "Grant Animath to contact me in the future about other actions" msgid "Grant Animath to contact me in the future about other actions"
@ -1828,11 +1827,11 @@ msgstr ""
"avez reçu par mail. Vous pouvez renvoyer un mail en cliquant sur <a " "avez reçu par mail. Vous pouvez renvoyer un mail en cliquant sur <a "
"href=\"{send_email_url}\">ce lien</a>." "href=\"{send_email_url}\">ce lien</a>."
#: registration/models.py:118 registration/models.py:503 #: registration/models.py:118
msgid "registration" msgid "registration"
msgstr "inscription" msgstr "inscription"
#: registration/models.py:119 #: registration/models.py:119 registration/models.py:503
msgid "registrations" msgid "registrations"
msgstr "inscriptions" msgstr "inscriptions"
@ -2027,7 +2026,7 @@ msgstr ""
msgid "Vaccine sheet" msgid "Vaccine sheet"
msgstr "Carnet de vaccination" msgstr "Carnet de vaccination"
#: registration/models.py:368 #: registration/models.py:369
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"You have to pay {amount} € for your registration, or send a scholarship " "You have to pay {amount} € for your registration, or send a scholarship "
@ -2038,27 +2037,27 @@ msgstr ""
"notification de bourse ou un justificatif de paiement. Vous pouvez le faire " "notification de bourse ou un justificatif de paiement. Vous pouvez le faire "
"sur <a href=\"{url}\">la page de paiement</a>." "sur <a href=\"{url}\">la page de paiement</a>."
#: registration/models.py:374 registration/models.py:383 #: registration/models.py:375 registration/models.py:384
msgid "Payment" msgid "Payment"
msgstr "Paiement" msgstr "Paiement"
#: registration/models.py:380 #: registration/models.py:381
msgid "Your payment is under approval." msgid "Your payment is under approval."
msgstr "Votre paiement est en cours de validation." msgstr "Votre paiement est en cours de validation."
#: registration/models.py:392 #: registration/models.py:393
msgid "student registration" msgid "student registration"
msgstr "inscription d'élève" msgstr "inscription d'élève"
#: registration/models.py:393 #: registration/models.py:394
msgid "student registrations" msgid "student registrations"
msgstr "inscriptions d'élève" msgstr "inscriptions d'élève"
#: registration/models.py:404 #: registration/models.py:405
msgid "most recent degree in mathematics, computer science or physics" msgid "most recent degree in mathematics, computer science or physics"
msgstr "Dernier diplôme obtenu en mathématiques, informatique ou physique" msgstr "Dernier diplôme obtenu en mathématiques, informatique ou physique"
#: registration/models.py:405 #: registration/models.py:406
msgid "" msgid ""
"Your most recent degree in maths, computer science or physics, or your last " "Your most recent degree in maths, computer science or physics, or your last "
"entrance exam (CAPES, Agrégation,…)" "entrance exam (CAPES, Agrégation,…)"
@ -2066,23 +2065,23 @@ msgstr ""
"Votre dernier diplôme en mathématiques, informatique ou physique, ou votre " "Votre dernier diplôme en mathématiques, informatique ou physique, ou votre "
"dernier concours obtenu (CAPES, Agrégation, …)" "dernier concours obtenu (CAPES, Agrégation, …)"
#: registration/models.py:410 registration/models.py:432 #: registration/models.py:411 registration/models.py:433
msgid "professional activity" msgid "professional activity"
msgstr "activité professionnelle" msgstr "activité professionnelle"
#: registration/models.py:423 #: registration/models.py:424
msgid "coach registration" msgid "coach registration"
msgstr "inscription d'encadrant⋅e" msgstr "inscription d'encadrant⋅e"
#: registration/models.py:424 #: registration/models.py:425
msgid "coach registrations" msgid "coach registrations"
msgstr "inscriptions d'encadrant⋅es" msgstr "inscriptions d'encadrant⋅es"
#: registration/models.py:436 #: registration/models.py:437
msgid "administrator" msgid "administrator"
msgstr "administrateur⋅rice" msgstr "administrateur⋅rice"
#: registration/models.py:437 #: registration/models.py:438
msgid "" msgid ""
"An administrator has all rights. Please don't give this right to all juries " "An administrator has all rights. Please don't give this right to all juries "
"and volunteers." "and volunteers."
@ -2090,15 +2089,15 @@ msgstr ""
"Un⋅e administrateur⋅rice a tous les droits. Merci de ne pas donner ce droit " "Un⋅e administrateur⋅rice a tous les droits. Merci de ne pas donner ce droit "
"à toustes les juré⋅es et bénévoles." "à toustes les juré⋅es et bénévoles."
#: registration/models.py:447 #: registration/models.py:448
msgid "admin" msgid "admin"
msgstr "admin" msgstr "admin"
#: registration/models.py:447 #: registration/models.py:448
msgid "volunteer" msgid "volunteer"
msgstr "bénévole" msgstr "bénévole"
#: registration/models.py:460 #: registration/models.py:461
msgid "" msgid ""
"Registrations for tournament {tournament} are closing on {date:%Y-%m-%d %H:" "Registrations for tournament {tournament} are closing on {date:%Y-%m-%d %H:"
"%M}. There are for now {validated_teams} validated teams (+ {pending_teams} " "%M}. There are for now {validated_teams} validated teams (+ {pending_teams} "
@ -2108,11 +2107,11 @@ msgstr ""
"%M}. Il y a pour l'instant {validated_teams} équipes validées (+ " "%M}. Il y a pour l'instant {validated_teams} équipes validées (+ "
"{pending_teams} en attente) sur {max_teams} attendues." "{pending_teams} en attente) sur {max_teams} attendues."
#: registration/models.py:468 #: registration/models.py:469
msgid "Registrations" msgid "Registrations"
msgstr "Inscriptions" msgstr "Inscriptions"
#: registration/models.py:475 #: registration/models.py:476
#, python-brace-format #, python-brace-format
msgid "" msgid ""
"The team {trigram} requested to be validated for the tournament of " "The team {trigram} requested to be validated for the tournament of "
@ -2123,68 +2122,98 @@ msgstr ""
"Vous pouvez vérifier le statut de l'équipe sur la <a href=\"{url}\">page de " "Vous pouvez vérifier le statut de l'équipe sur la <a href=\"{url}\">page de "
"l'équipe</a>." "l'équipe</a>."
#: registration/models.py:490 #: registration/models.py:491
msgid "volunteer registration" msgid "volunteer registration"
msgstr "inscription de bénévole" msgstr "inscription de bénévole"
#: registration/models.py:491 #: registration/models.py:492
msgid "volunteer registrations" msgid "volunteer registrations"
msgstr "inscriptions de bénévoles" msgstr "inscriptions de bénévoles"
#: registration/models.py:507 #: registration/models.py:507
msgid "grouped"
msgstr "groupé"
#: registration/models.py:509
msgid ""
"If set to true, then one payment is made for the full team, for example if "
"the school pays for all."
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
msgid "total amount"
msgstr "montant total"
#: registration/models.py:515
msgid "Corresponds to the total required amount to pay, in euros."
msgstr "Correspond au montant total à payer, en euros."
#: registration/models.py:520
msgid "for final tournament"
msgstr "pour la finale"
#: registration/models.py:525
msgid "type" msgid "type"
msgstr "type" msgstr "type"
#: registration/models.py:510 #: registration/models.py:528
msgid "No payment" msgid "No payment"
msgstr "Pas de paiement" msgstr "Pas de paiement"
#: registration/models.py:512 #: registration/models.py:530
msgid "Scholarship" msgid "Scholarship"
msgstr "Notification de bourse" msgstr "Notification de bourse"
#: registration/models.py:513 #: registration/models.py:531
msgid "Bank transfer" msgid "Bank transfer"
msgstr "Virement bancaire" msgstr "Virement bancaire"
#: registration/models.py:514 #: registration/models.py:532
msgid "Other (please indicate)" msgid "Other (please indicate)"
msgstr "Autre (veuillez spécifier)" msgstr "Autre (veuillez spécifier)"
#: registration/models.py:515 #: registration/models.py:533
msgid "The tournament is free" msgid "The tournament is free"
msgstr "Le tournoi est gratuit" msgstr "Le tournoi est gratuit"
#: registration/models.py:522 #: registration/models.py:540
msgid "scholarship file" msgid "Hello Asso checkout intent ID"
msgstr "Notification de bourse" msgstr "ID de l'intention de paiement Hello Asso"
#: registration/models.py:523 #: registration/models.py:547
msgid "only if you have a scholarship." msgid "receipt"
msgstr "Nécessaire seulement si vous déclarez être boursier." msgstr "justificatif"
#: registration/models.py:530 #: registration/models.py:548
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
msgid "additional information" msgid "additional information"
msgstr "informations additionnelles" msgstr "informations additionnelles"
#: registration/models.py:531 #: registration/models.py:556
msgid "To help us to find your payment." msgid "To help us to find your payment."
msgstr "Pour nous aider à retrouver votre paiement, si nécessaire." msgstr "Pour nous aider à retrouver votre paiement, si nécessaire."
#: registration/models.py:537 #: registration/models.py:562
msgid "payment valid" msgid "payment valid"
msgstr "paiement valide" msgstr "paiement valide"
#: registration/models.py:546 #: registration/models.py:571
#, python-brace-format #, python-brace-format
msgid "Payment of {registration}" msgid "Payment of {registrations}"
msgstr "Paiement de {registration}" msgstr "Paiements de {registration}"
#: registration/models.py:549 #: registration/models.py:574
msgid "payment" msgid "payment"
msgstr "paiement" msgstr "paiement"
#: registration/models.py:550 #: registration/models.py:575
msgid "payments" msgid "payments"
msgstr "paiements" msgstr "paiements"
@ -2349,56 +2378,6 @@ msgstr ""
msgid "Reset my password" msgid "Reset my password"
msgstr "Réinitialiser mon mot de passe" msgstr "Réinitialiser mon mot de passe"
#: registration/templates/registration/payment_form.html:10
#, python-format
msgid ""
"The price of the tournament is %(price)s €. The participation fee is offered "
"for coaches and for students who have a scholarship. If so, please send us "
"your scholarship attestation."
msgstr ""
"Le prix du tournoi est de %(price)s €. Les frais de participation sont "
"offerts pour les encadrant⋅es et les élèves boursièr⋅es. Si c'est le cas, "
"merci de nous transmettre votre notification de bourse."
#: registration/templates/registration/payment_form.html:17
msgid ""
"You can pay with a credit card through <a class=\"alert-link\" "
"href=\"https://www.helloasso.com/associations/animath/evenements/tfjm-2023-"
"tournois-regionaux\">our Hello Asso page</a>. To make the validation of the "
"payment easier, <span class=\"text-danger\">please use the same e-mail "
"address that you use on this platform.</span> The payment verification will "
"be checked automatically under 10 minutes, you don't necessary need to fill "
"this form."
msgstr ""
"Vous pouvez payer par carte bancaire sur <a class=\"alert-link\" "
"href=\"https://www.helloasso.com/associations/animath/evenements/tfjm-2023-"
"tournois-regionaux\">notre page Hello Asso</a>. Pour rendre la validation du "
"paiement plus facile, <span class=\"text-danger\">merci d'utiliser la même "
"adresse e-mail que vous utilisez sur cette plateforme.</span> La "
"vérification du paiement sera faite automatiquement sous 10 minutes, vous "
"n'avez pas nécessairement besoin de remplir ce formulaire."
#: registration/templates/registration/payment_form.html:27
msgid ""
"You can also send a bank transfer to the bank account of Animath. You must "
"put in the reference of the transfer the mention \"TFJMpu\" followed by the "
"last name and the first name of the student."
msgstr ""
"Vous pouvez également faire un virement bancaire sur le compte d'Animath. "
"Vous devez alors mettre dans la référence du transfert la mention \"TFJMpu\" "
"suivie du nom et du prénom de l'élève."
#: registration/templates/registration/payment_form.html:39
msgid ""
"If any payment mean is available to you, please contact us at <a "
"class=\"alert-link\" href=\"mailto:contact@tfjm.org\">contact@tfjm.org</a> "
"to find a solution to your difficulties."
msgstr ""
"Si aucun moyen de paiement ne vous convient, merci de nous contecter à "
"l'adresse <a class=\"alert-link\" href=\"mailto:contact@tfjm."
"org\">contact@tfjm.org</a> pour que nous puissions trouver une solution à "
"vos difficultés."
#: registration/templates/registration/signup.html:5 #: registration/templates/registration/signup.html:5
#: registration/templates/registration/signup.html:12 #: 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:44
@ -2533,49 +2512,53 @@ msgstr "Administrateur⋅rice :"
msgid "Grant Animath to contact me in the future about other actions:" msgid "Grant Animath to contact me in the future about other actions:"
msgstr "Autorise Animath à recontacter à propos d'autres actions :" msgstr "Autorise Animath à recontacter à propos d'autres actions :"
#: registration/templates/registration/user_detail.html:149 #: registration/templates/registration/user_detail.html:150
msgid "Payment information:" msgid "Payment information:"
msgstr "Informations de paiement :" msgstr "Informations de paiement :"
#: registration/templates/registration/user_detail.html:151 #: registration/templates/registration/user_detail.html:152
msgid "yes,no,pending" msgid "yes,no,pending"
msgstr "oui,non,en attente" msgstr "oui,non,en attente"
#: registration/templates/registration/user_detail.html:155 #: registration/templates/registration/user_detail.html:156
#: registration/templates/registration/user_detail.html:158 #: registration/templates/registration/user_detail.html:159
msgid "valid:" msgid "valid:"
msgstr "valide :" msgstr "valide :"
#: registration/templates/registration/user_detail.html:162 #: registration/templates/registration/user_detail.html:163
#: registration/templates/registration/user_detail.html:215 #: registration/templates/registration/user_detail.html:222
msgid "Update payment" msgid "Update payment"
msgstr "Modifier le paiement" msgstr "Modifier le paiement"
#: registration/templates/registration/user_detail.html:168 #: registration/templates/registration/user_detail.html:171
msgid "Download scholarship attestation" msgid "Download scholarship attestation"
msgstr "Télécharger l'attestation de bourse" msgstr "Télécharger l'attestation de bourse"
#: registration/templates/registration/user_detail.html:181 #: registration/templates/registration/user_detail.html:173
msgid "Download bank transfer receipt"
msgstr "Télécharger le justificatif de virement bancaire"
#: registration/templates/registration/user_detail.html:188
msgid "Impersonate" msgid "Impersonate"
msgstr "Impersonifier" msgstr "Impersonifier"
#: registration/templates/registration/user_detail.html:188 #: registration/templates/registration/user_detail.html:195
#: registration/views.py:313 #: registration/views.py:313
msgid "Upload photo authorization" msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image" msgstr "Téléverser l'autorisation de droit à l'image"
#: registration/templates/registration/user_detail.html:193 #: registration/templates/registration/user_detail.html:200
#: registration/views.py:334 #: registration/views.py:334
msgid "Upload health sheet" msgid "Upload health sheet"
msgstr "Téléverser la fiche sanitaire" msgstr "Téléverser la fiche sanitaire"
#: registration/templates/registration/user_detail.html:198 #: registration/templates/registration/user_detail.html:205
#: registration/views.py:355 #: registration/views.py:355
msgid "Upload vaccine sheet" msgid "Upload vaccine sheet"
msgstr "Téléverser le carnet de vaccination" msgstr "Téléverser le carnet de vaccination"
#: registration/templates/registration/user_detail.html:203 #: registration/templates/registration/user_detail.html:210
#: registration/templates/registration/user_detail.html:208 #: registration/templates/registration/user_detail.html:215
#: registration/views.py:376 #: registration/views.py:376
msgid "Upload parental authorization" msgid "Upload parental authorization"
msgstr "Téléverser l'autorisation parentale" msgstr "Téléverser l'autorisation parentale"
@ -2614,27 +2597,27 @@ msgstr "Détails de l'utilisateur⋅rice {user}"
msgid "Update user {user}" msgid "Update user {user}"
msgstr "Mise à jour de l'utilisateur⋅rice {user}" msgstr "Mise à jour de l'utilisateur⋅rice {user}"
#: registration/views.py:494 #: registration/views.py:492
#, python-brace-format #, python-brace-format
msgid "Photo authorization of {student}.{ext}" msgid "Photo authorization of {student}.{ext}"
msgstr "Autorisation de droit à l'image de {student}.{ext}" msgstr "Autorisation de droit à l'image de {student}.{ext}"
#: registration/views.py:517 #: registration/views.py:515
#, python-brace-format #, python-brace-format
msgid "Health sheet of {student}.{ext}" msgid "Health sheet of {student}.{ext}"
msgstr "Fiche sanitaire de {student}.{ext}" msgstr "Fiche sanitaire de {student}.{ext}"
#: registration/views.py:540 #: registration/views.py:538
#, python-brace-format #, python-brace-format
msgid "Vaccine sheet of {student}.{ext}" msgid "Vaccine sheet of {student}.{ext}"
msgstr "Carnet de vaccination de {student}.{ext}" msgstr "Carnet de vaccination de {student}.{ext}"
#: registration/views.py:563 #: registration/views.py:561
#, python-brace-format #, python-brace-format
msgid "Parental authorization of {student}.{ext}" msgid "Parental authorization of {student}.{ext}"
msgstr "Autorisation parentale de {student}.{ext}" msgstr "Autorisation parentale de {student}.{ext}"
#: registration/views.py:585 #: registration/views.py:583
#, python-brace-format #, python-brace-format
msgid "Scholarship attestation of {user}.{ext}" msgid "Scholarship attestation of {user}.{ext}"
msgstr "Notification de bourse de {user}.{ext}" msgstr "Notification de bourse de {user}.{ext}"

View File

@ -14,7 +14,7 @@ from django.utils import timezone
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.text import format_lazy from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from registration.models import VolunteerRegistration, Payment from registration.models import Payment, VolunteerRegistration
from tfjm.lists import get_sympa_client from tfjm.lists import get_sympa_client
@ -465,14 +465,15 @@ class Participation(models.Model):
def important_informations(self): def important_informations(self):
informations = [] informations = []
missing_payments = Payment.objects.filter(registration__in=self.team.participants.all(), valid=False) missing_payments = Payment.objects.filter(registrations__in=self.team.participants.all(), valid=False)
if missing_payments.exists(): if missing_payments.exists():
text = _("<p>The team {trigram} has {nb_missing_payments} missing payments. Each member of the team " text = _("<p>The team {trigram} has {nb_missing_payments} missing payments. Each member of the team "
"must have a valid payment (or send a scholarship notification) " "must have a valid payment (or send a scholarship notification) "
"to participate to the tournament.</p>" "to participate to the tournament.</p>"
"<p>Participants that have not paid yet are: {participants}.</p>") "<p>Participants that have not paid yet are: {participants}.</p>")
content = format_lazy(text, trigram=self.team.trigram, nb_missing_payments=missing_payments.count(), content = format_lazy(text, trigram=self.team.trigram, nb_missing_payments=missing_payments.count(),
participants=", ".join(str(p.registration) for p in missing_payments.all())) participants=", ".join(", ".join(str(r) for r in p.registrations.all())
for p in missing_payments.all()))
informations.append({ informations.append({
'title': _("Missing payments"), 'title': _("Missing payments"),
'type': "danger", 'type': "danger",

View File

@ -30,7 +30,7 @@ from odf.opendocument import OpenDocumentSpreadsheet
from odf.style import Style, TableCellProperties, TableColumnProperties, TextProperties from odf.style import Style, TableCellProperties, TableColumnProperties, TextProperties
from odf.table import CoveredTableCell, Table, TableCell, TableColumn, TableRow from odf.table import CoveredTableCell, Table, TableCell, TableColumn, TableRow
from odf.text import P from odf.text import P
from registration.models import StudentRegistration, VolunteerRegistration from registration.models import Payment, StudentRegistration, VolunteerRegistration
from tfjm.lists import get_sympa_client from tfjm.lists import get_sympa_client
from tfjm.views import AdminMixin, VolunteerMixin from tfjm.views import AdminMixin, VolunteerMixin
@ -246,16 +246,20 @@ class TeamDetailView(LoginRequiredMixin, FormMixin, ProcessFormView, DetailView)
mail_html = render_to_string("participation/mails/team_validated.html", mail_context) mail_html = render_to_string("participation/mails/team_validated.html", mail_context)
send_mail("[TFJM²] Équipe validée", mail_plain, None, [self.object.email], html_message=mail_html) send_mail("[TFJM²] Équipe validée", mail_plain, None, [self.object.email], html_message=mail_html)
if self.object.participation.tournament.price == 0: for student in self.object.students.all():
for registration in self.object.participants.all(): payment_qs = Payment.objects.filter(registrations=student)
registration.payment.type = "free" if payment_qs.exists():
registration.payment.valid = True payment = payment_qs.get()
registration.payment.save()
else: else:
for coach in self.object.coaches.all(): payment = Payment.objects.create()
coach.payment.type = "free" payment.registrations.add(student)
coach.payment.valid = True payment.save()
coach.payment.save() payment.amount = self.object.participation.tournament.price
if payment.amount == 0:
payment.type = "free"
payment.valid = True
payment.save()
elif "invalidate" in self.request.POST: elif "invalidate" in self.request.POST:
self.object.participation.valid = None self.object.participation.valid = None
self.object.participation.save() self.object.participation.save()

View File

@ -97,11 +97,12 @@ class VolunteerRegistrationAdmin(PolymorphicChildModelAdmin):
@admin.register(Payment) @admin.register(Payment)
class PaymentAdmin(ModelAdmin): class PaymentAdmin(ModelAdmin):
list_display = ('registration', 'registration_type', 'type', 'valid', ) list_display = ('id', 'concerned_people', 'grouped', 'type', 'valid', )
search_fields = ('registration__user__last_name', 'registration__user__first_name', 'registration__user__email',) search_fields = ('registrations__user__last_name', 'registrations__user__first_name', 'registrations__user__email',)
list_filter = ('registration__team__participation__valid', 'type', 'type', 'valid',) list_filter = ('registrations__team__participation__valid', 'type',
autocomplete_fields = ('registration',) 'grouped', 'valid', 'registrations__polymorphic_ctype',)
autocomplete_fields = ('registrations',)
@admin.display(description=_('registration type'), ordering='registration__polymorphic_ctype') @admin.display(description=_('concerned people'))
def registration_type(self, record: Payment): def concerned_people(self, record: Payment):
return record.registration.get_real_instance().type return ", ".join(f"{reg.user.first_name} {reg.user.last_name}" for reg in record.registrations.all())

View File

@ -12,11 +12,8 @@ class RegistrationConfig(AppConfig):
name = 'registration' name = 'registration'
def ready(self): def ready(self):
from registration.signals import create_admin_registration, create_payment, \ from registration.signals import create_admin_registration, \
set_username, send_email_link set_username, send_email_link
pre_save.connect(set_username, "auth.User") pre_save.connect(set_username, "auth.User")
pre_save.connect(send_email_link, "auth.User") pre_save.connect(send_email_link, "auth.User")
post_save.connect(create_admin_registration, "auth.User") post_save.connect(create_admin_registration, "auth.User")
post_save.connect(create_payment, "registration.Registration")
post_save.connect(create_payment, "registration.StudentRegistration")
post_save.connect(create_payment, "registration.CoachRegistration")

View File

@ -227,25 +227,25 @@ class PaymentForm(forms.ModelForm):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields["valid"].widget.choices[0] = ('unknown', _("Pending")) self.fields["valid"].widget.choices[0] = ('unknown', _("Pending"))
def clean_scholarship_file(self): def clean_receipt(self):
print(self.files) print(self.files)
if "scholarship_file" in self.files: if "receipt" in self.files:
file = self.files["scholarship_file"] file = self.files["receipt"]
if file.size > 2e6: if file.size > 2e6:
raise ValidationError(_("The uploaded file size must be under 2 Mo.")) raise ValidationError(_("The uploaded file size must be under 2 Mo."))
if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]: 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.")) raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
return self.cleaned_data["scholarship_file"] return self.cleaned_data["receipt"]
def clean(self): def clean(self):
cleaned_data = super().clean() cleaned_data = super().clean()
if "type" in cleaned_data and cleaned_data["type"] == "scholarship" \ if "type" in cleaned_data and cleaned_data['type'] in ["scholarship", "bank_transfer"] \
and "scholarship_file" not in self.files and not self.instance.scholarship_file: and "receipt" not in self.files and not self.instance.scholarship_file:
self.add_error("scholarship_file", _("You must upload your scholarship attestation.")) self.add_error("receipt", _("You must upload your receipt."))
return cleaned_data return cleaned_data
class Meta: class Meta:
model = Payment model = Payment
fields = ('type', 'scholarship_file', 'additional_information', 'valid',) fields = ('type', 'receipt', 'additional_information', 'valid',)

View File

@ -0,0 +1,76 @@
# Generated by Django 5.0.1 on 2024-02-12 20:40
import registration.models
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("registration", "0010_coachregistration_last_degree"),
]
operations = [
migrations.RemoveField(
model_name="payment",
name="registration",
),
migrations.RemoveField(
model_name="payment",
name="scholarship_file",
),
migrations.AddField(
model_name="payment",
name="amount",
field=models.PositiveSmallIntegerField(
default=0,
help_text="Corresponds to the total required amount to pay, in euros.",
verbose_name="total amount",
),
),
migrations.AddField(
model_name="payment",
name="checkout_intent_id",
field=models.IntegerField(
blank=True,
default=None,
null=True,
verbose_name="Hello Asso checkout intent ID",
),
),
migrations.AddField(
model_name="payment",
name="final",
field=models.BooleanField(
default=False, verbose_name="for final tournament"
),
),
migrations.AddField(
model_name="payment",
name="grouped",
field=models.BooleanField(
default=False,
help_text="If set to true, then one payment is made for the full team, for example if the school pays for all.",
verbose_name="grouped",
),
),
migrations.AddField(
model_name="payment",
name="receipt",
field=models.FileField(
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,
verbose_name="receipt",
),
),
migrations.AddField(
model_name="payment",
name="registrations",
field=models.ManyToManyField(
related_name="payments",
to="registration.participantregistration",
verbose_name="registrations",
),
),
]

View File

@ -364,12 +364,13 @@ class StudentRegistration(ParticipantRegistration):
}) })
if self.team and self.team.participation.valid: if self.team and self.team.participation.valid:
if self.payment.valid is False: for payment in self.payments.all():
if payment.valid is False:
text = _("You have to pay {amount} € for your registration, or send a scholarship " text = _("You have to pay {amount} € for your registration, or send a scholarship "
"notification or a payment proof. " "notification or a payment proof. "
"You can do it on <a href=\"{url}\">the payment page</a>.") "You can do it on <a href=\"{url}\">the payment page</a>.")
url = reverse_lazy("registration:update_payment", args=(self.payment.id,)) url = reverse_lazy("registration:update_payment", args=(payment.id,))
content = format_lazy(text, amount=self.team.participation.tournament.price, url=url) content = format_lazy(text, amount=payment.amount, url=url)
informations.append({ informations.append({
'title': _("Payment"), 'title': _("Payment"),
'type': "danger", 'type': "danger",
@ -496,11 +497,28 @@ def get_scholarship_filename(instance, filename):
class Payment(models.Model): class Payment(models.Model):
registration = models.OneToOneField( registrations = models.ManyToManyField(
ParticipantRegistration, ParticipantRegistration,
on_delete=models.CASCADE, related_name="payments",
related_name="payment", verbose_name=_("registrations"),
verbose_name=_("registration"), )
grouped = models.BooleanField(
verbose_name=_("grouped"),
default=False,
help_text=_("If set to true, then one payment is made for the full team, "
"for example if the school pays for all."),
)
amount = models.PositiveSmallIntegerField(
verbose_name=_("total amount"),
help_text=_("Corresponds to the total required amount to pay, in euros."),
default=0,
)
final = models.BooleanField(
verbose_name=_("for final tournament"),
default=False,
) )
type = models.CharField( type = models.CharField(
@ -518,9 +536,16 @@ class Payment(models.Model):
default="", default="",
) )
scholarship_file = models.FileField( checkout_intent_id = models.IntegerField(
verbose_name=_("scholarship file"), verbose_name=_("Hello Asso checkout intent ID"),
help_text=_("only if you have a scholarship."), blank=True,
null=True,
default=None,
)
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_scholarship_filename,
blank=True, blank=True,
default="", default="",
@ -540,10 +565,10 @@ class Payment(models.Model):
) )
def get_absolute_url(self): def get_absolute_url(self):
return reverse_lazy("registration:user_detail", args=(self.registration.user.id,)) return reverse_lazy("registration:update_payment", args=(self.pk,))
def __str__(self): def __str__(self):
return _("Payment of {registration}").format(registration=self.registration) return _("Payment of {registrations}").format(registrations=", ".join(map(str, self.registrations.all())))
class Meta: class Meta:
verbose_name = _("payment") verbose_name = _("payment")

View File

@ -4,7 +4,7 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from tfjm.lists import get_sympa_client from tfjm.lists import get_sympa_client
from .models import Payment, Registration, VolunteerRegistration from .models import Registration, VolunteerRegistration
def set_username(instance, **_): def set_username(instance, **_):
@ -41,16 +41,3 @@ def create_admin_registration(instance, **_):
""" """
if instance.is_superuser: if instance.is_superuser:
VolunteerRegistration.objects.get_or_create(user=instance, admin=True) VolunteerRegistration.objects.get_or_create(user=instance, admin=True)
def create_payment(instance: Registration, raw, **_):
"""
When a user is saved, create the associated payment.
For a free tournament, the payment is valid.
"""
if instance.participates and not raw:
payment = Payment.objects.get_or_create(registration=instance)[0]
if instance.team and instance.team.participation.valid and instance.team.participation.tournament.price == 0:
payment.valid = True
payment.type = "free"
payment.save()

View File

@ -143,35 +143,42 @@
</dl> </dl>
{% if user_object.registration.participates and user_object.registration.team.participation.valid %} {% if user_object.registration.participates and user_object.registration.team.participation.valid %}
{% for payment in user_object.registration.payments.all %}
<hr> <hr>
<dl class="row"> <dl class="row">
<dt class="col-sm-6 text-end">{% trans "Payment information:" %}</dt> <dt class="col-sm-6 text-end">{% trans "Payment information:" %}</dt>
<dd class="col-sm-6"> <dd class="col-sm-6">
{% trans "yes,no,pending" as yesnodefault %} {% trans "yes,no,pending" as yesnodefault %}
{% with info=user_object.registration.payment.additional_information %} {% with info=payment.additional_information %}
{% if info %} {% if info %}
<abbr title="{{ info }}"> <abbr title="{{ info }}">
{{ user_object.registration.payment.get_type_display }}, {% trans "valid:" %} {{ user_object.registration.payment.valid|yesno:yesnodefault }} {{ payment.get_type_display }}, {% trans "valid:" %} {{ payment.valid|yesno:yesnodefault }}
</abbr> </abbr>
{% else %} {% else %}
{{ user_object.registration.payment.get_type_display }}, {% trans "valid:" %} {{ user_object.registration.payment.valid|yesno:yesnodefault }} {{ payment.get_type_display }}, {% trans "valid:" %} {{ payment.valid|yesno:yesnodefault }}
{% endif %} {% endif %}
{% if user.registration.is_admin or user_object.registration.payment.valid is False %} {% if user.registration.is_admin or payment.valid is False %}
<button class="btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#updatePaymentModal"> <a href="{% url "registration:update_payment" pk=payment.pk %}" class="btn btn-secondary">
<i class="fas fa-money-bill-wave"></i> {% trans "Update payment" %} <i class="fas fa-money-bill-wave"></i> {% trans "Update payment" %}
</button> </a>
{% endif %} {% endif %}
{% if user_object.registration.payment.type == "scholarship" %} {% if payment.type == "scholarship" or payment.type == "bank_transfer" %}
{% if user.registration.is_admin or user == user_object %} {% if user.registration.is_admin or user == user_object %}
<a href="{{ user_object.registration.payment.scholarship_file.url }}" class="btn btn-info"> <a href="{{ payment.receipt.url }}" class="btn btn-info">
<i class="fas fa-file-pdf"></i> {% trans "Download scholarship attestation" %} <i class="fas fa-file-pdf"></i>
{% if payment.type == "scholarship" %}
{% trans "Download scholarship attestation" %}
{% elif payment.type == "bank_transfer" %}
{% trans "Download bank transfer receipt" %}
{% endif %}
</a> </a>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endwith %} {% endwith %}
</dd> </dd>
</dl> </dl>
{% endfor %}
{% endif %} {% endif %}
</div> </div>
{% if user.pk == user_object.pk or user.registration.is_admin %} {% if user.pk == user_object.pk or user.registration.is_admin %}
@ -210,13 +217,6 @@
{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %} {% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk as modal_action %}
{% include "base_modal.html" with modal_id="uploadParentalAuthorization" modal_enctype="multipart/form-data" %} {% include "base_modal.html" with modal_id="uploadParentalAuthorization" modal_enctype="multipart/form-data" %}
{% endif %} {% endif %}
{% if user_object.registration.team.participation.valid %}
{% trans "Update payment" as modal_title %}
{% trans "Update" as modal_button %}
{% url "registration:update_payment" pk=user_object.registration.payment.pk as modal_action %}
{% include "base_modal.html" with modal_id="updatePayment" modal_additional_class="modal-xl" modal_enctype="multipart/form-data" %}
{% endif %}
{% endblock %} {% endblock %}
{% block extrajavascript %} {% block extrajavascript %}
@ -228,10 +228,6 @@
initModal("uploadVaccineSheet", "{% url "registration:upload_user_vaccine_sheet" pk=user_object.registration.pk %}") initModal("uploadVaccineSheet", "{% url "registration:upload_user_vaccine_sheet" pk=user_object.registration.pk %}")
initModal("uploadParentalAuthorization", "{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %}") initModal("uploadParentalAuthorization", "{% url "registration:upload_user_parental_authorization" pk=user_object.registration.pk %}")
{% endif %} {% endif %}
{% if user_object.registration.team.participation.valid %}
initModal("updatePayment", "{% url "registration:update_payment" pk=user_object.registration.payment.pk %}")
{% endif %}
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -448,7 +448,7 @@ class PaymentUpdateView(LoginRequiredMixin, UpdateView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
if not self.request.user.is_authenticated or \ if not self.request.user.is_authenticated or \
not self.request.user.registration.is_admin \ not self.request.user.registration.is_admin \
and (self.request.user != self.get_object().registration.user and (self.request.user.registration not in self.get_object().registrations.all()
or self.get_object().valid is not False): or self.get_object().valid is not False):
return self.handle_no_permission() return self.handle_no_permission()
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
@ -464,8 +464,8 @@ class PaymentUpdateView(LoginRequiredMixin, UpdateView):
if not self.request.user.registration.is_admin: 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) old_instance = Payment.objects.get(pk=self.object.pk)
if old_instance.scholarship_file: if old_instance.receipt:
old_instance.scholarship_file.delete() old_instance.receipt.delete()
old_instance.save() old_instance.save()
return super().form_valid(form) return super().form_valid(form)
@ -568,12 +568,12 @@ class ScholarshipView(LoginRequiredMixin, View):
""" """
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
filename = kwargs["filename"] filename = kwargs["filename"]
path = f"media/authorization/scholarship/{filename}" path = f"media/authorization/receipt/{filename}"
if not os.path.exists(path): if not os.path.exists(path):
raise Http404 raise Http404
payment = Payment.objects.get(scholarship_file__endswith=filename) payment = Payment.objects.get(receipt__endswith=filename)
user = request.user user = request.user
if not (payment.registration.user == user or user.registration.is_admin): if not (user.registration in payment.registrations or user.registration.is_admin):
raise PermissionDenied raise PermissionDenied
# Guess mime type of the file # Guess mime type of the file
mime = Magic(mime=True) mime = Magic(mime=True)