Compare commits

..

229 commits

Author SHA1 Message Date
2126224e15 Merge pull request 'Thubrecht/daphne' (#815) from thubrecht/daphne into master
Reviewed-on: #815
2024-07-30 18:40:56 +02:00
d6109a9312 dev: update requirements and directly read the files 2024-07-12 14:54:14 +02:00
a69bd0426f kfet/open: Add comment to test 2024-07-12 14:54:14 +02:00
81a4dbef7c dev: set explicitely DJANGO_SETTINGS_MODULE 2024-07-12 14:54:14 +02:00
4fedf3453d kfet: remove redundant static tag 2024-07-12 14:54:14 +02:00
8607d77c84 dev: update requirements 2024-07-12 14:54:14 +02:00
bc55a3067e Remove useless migrations 2024-07-12 14:54:14 +02:00
dd68ad91cd Update django-hCaptcha 2024-07-12 14:54:14 +02:00
2f71246509 assertDictContainsSubset is deprecated 2024-07-12 14:54:14 +02:00
a20a1c11d6 Explicitely set transform=repr in assertQuerysetEquals 2024-07-12 14:54:14 +02:00
0e1ff1765a assertEquals is deprecated 2024-07-12 14:54:14 +02:00
177d413f4c Use AutoField instead of BigAutoField 2024-07-12 14:54:14 +02:00
01dd16c795 url -> re_path 2024-07-12 14:54:14 +02:00
84c87c1b4b Replace unique_together by UniqueConstraint 2024-07-12 14:54:14 +02:00
1b143b322f Update changelog 2024-07-12 14:54:14 +02:00
f9456e3c29 cof has been renamed to gestioasso 2024-07-12 14:54:14 +02:00
dd1350f1c2 Fix typo 2024-07-12 14:54:14 +02:00
8f4cb68d31 Only run kf tests in sequential mode (to fix issues with channels) 2024-07-12 14:54:14 +02:00
3a3f96a8df Try not running tests in parallel 2024-07-12 14:54:14 +02:00
7d8926e459 Try to flush old messages in tests 2024-07-12 14:54:14 +02:00
3fee014384 Update kfet.open tests 2024-07-12 14:54:14 +02:00
cd351786bb Remove default_app_config 2024-07-12 14:54:14 +02:00
7362c2fa2a Update django-djconfig 2024-07-12 14:54:14 +02:00
efbc947145 Change backend name as the old one is deprecated 2024-07-12 14:54:14 +02:00
0c45262fbc ugettext -> gettext 2024-07-12 14:54:14 +02:00
cabd277b4a Update redis, and implement a custom channel layer to send datetime/decimal objects 2024-07-12 14:54:14 +02:00
4108efe8c9 Fix kfet.ope tests 2024-07-12 14:54:14 +02:00
693e4252d5 Fix kpsul tests 2024-07-12 14:54:14 +02:00
3aa928e8f0 Simplify group_send for kpsul 2024-07-12 14:54:14 +02:00
5e2e68960b Channels 3 2024-07-12 14:54:14 +02:00
91e9beee11 Add default django asgi handler 2024-07-12 14:54:14 +02:00
ac286209ed Fix app import 2024-07-12 14:54:14 +02:00
b03cda5962 keyOrder is deprecated, using a list in Meta gives the correct order 2024-07-12 14:54:14 +02:00
4feb567af7 Update django-redis-cache and fix vagrant setup 2024-07-12 14:54:14 +02:00
1ac47885d0 Update django version 2024-07-12 14:54:14 +02:00
071c810605 Update base consumers 2024-07-12 14:54:14 +02:00
7f00ce0ff1 Add default http router 2024-07-12 14:54:14 +02:00
95136cb4eb Update daphne version 2024-07-12 14:54:14 +02:00
e299997aa8 Update to django channels 2 2024-07-12 14:54:14 +02:00
40f34926bb Fix vagrant setup w/ daphne 2024-07-12 14:54:14 +02:00
69976a878a Merge pull request 'Envoi de mail lors de la création d'un trigramme' (#833) from agroudiev/mail-creation-trigramme into master
Reviewed-on: #833
2024-07-06 16:54:25 +02:00
6621ae3950 style(kfet): suppression de return 2024-07-06 16:49:35 +02:00
9288daaf9e feat(kfet): envoi de mail lors de la création d'un trigramme 2024-07-06 12:14:49 +02:00
e92c500940 feat(shell.nix): Switch to python 3.9 2024-02-11 19:59:29 +01:00
Tom Hubrecht
d75eaf583f Merge branch 'master' into 'master'
Modification du délai pour l'indicateur K-Fêt ouverte

See merge request klub-dev-ens/gestioCOF!529
2023-12-10 10:11:33 +01:00
55bd3ab51d
Modification du délai du websocket 2023-12-08 21:17:53 +01:00
Tom Hubrecht
f640a25f59 Merge branch 'petitcours-template-tweak' into 'master'
[petitcours] Tweak `eleve.txt` template

See merge request klub-dev-ens/gestioCOF!528
2023-10-03 15:20:40 +02:00
Leo Lanteri--Thauvin
f881c7cd8b [petitcours] Tweak eleve.txt template 2023-09-11 16:44:45 +02:00
b548b87c25 Version 0.15.1 et Changelog 2023-06-15 13:52:53 +02:00
Tom Hubrecht
a72302291f Merge branch 'send_neg' into 'master'
feat(kfet): Change l'adresse utilisée pour envoyer les mails de négatif

See merge request klub-dev-ens/gestioCOF!526
2023-06-15 13:33:44 +02:00
a0bde75f50 feat(kfet): Change l'adresse utilisée pour envoyer les mails de négatif 2023-06-15 13:03:54 +02:00
Tom Hubrecht
44b19c12e5 Merge branch 'send_neg' into 'master'
fix(kfet): Récupère lors d'une erreur due à smtplib

See merge request klub-dev-ens/gestioCOF!525
2023-06-15 10:48:23 +02:00
f97d339a1c fix(kfet): Récupère lors d'une erreur due à smtplib 2023-06-14 20:56:25 +02:00
Tom Hubrecht
094116e88d Merge branch 'thubrecht/date-adhesion' into 'master'
Rajout de la date d'adhésion sur les profils COF

Closes #303

See merge request klub-dev-ens/gestioCOF!521
2023-05-26 09:31:45 +02:00
b32a07fc22 Version 0.15 et mise à jour du Changelog 2023-05-22 20:42:23 +02:00
Tom Hubrecht
4fc9902cf6 Merge branch 'thubrecht/contact-soiree' into 'master'
feat(kfet): Ajout d'un formulaire de demande de soirée

See merge request klub-dev-ens/gestioCOF!523
2023-05-22 20:37:38 +02:00
7164cfa37a feat(kfet): Ajout d'un formulaire de demande de soirée 2023-05-22 20:30:05 +02:00
Tom Hubrecht
90f96fb5c9 Merge branch 'thubrecht/contact' into 'master'
feat(kfet): Ajoute un formulaire de contact

Closes #302

See merge request klub-dev-ens/gestioCOF!520
2023-05-22 19:06:26 +02:00
e50249355d feat(kfet): Ajoute un formulaire de contact 2023-05-22 18:59:46 +02:00
Tom Hubrecht
c304d734d9 Merge branch 'thubrecht/comptes-inactifs' into 'master'
feat(kfet): Désactive l'envoi des mails pour les comptes gelés

See merge request klub-dev-ens/gestioCOF!522
2023-05-22 18:34:51 +02:00
c36dd30bce fix(kfet): Affiche la bonne information 2023-05-22 18:26:24 +02:00
2571cc955e feat(kfet): Désactive l'envoi des mails pour les comptes gelés
On utilise la fonctionnalité `is_frozen` pour marquer les comptes qui n'ont plus d'adresse valide, et on répare le formulaire de màj de compte.
2023-05-22 18:23:50 +02:00
3eaac5c68f feat(cof): Rajoute la date d'adhésion dans les profils 2023-05-22 11:28:23 +02:00
af4c8e0744 Update shell.nix and use django-types 2023-05-22 10:57:11 +02:00
14e0a3ef0a Version 0.14 et mise à jour du changelog 2023-05-19 20:18:11 +02:00
Tom Hubrecht
83078d4726 Merge branch 'thubrecht/date-js' into 'master'
Thubrecht/date js

See merge request klub-dev-ens/gestioCOF!518
2023-05-19 17:34:27 +02:00
cb262ad479 fix(kfet): Update timezone data for moment.js 2023-05-19 16:45:15 +02:00
5c47118834 Update gitignore and shell.nix 2023-05-19 15:14:55 +02:00
30e842ce80 shell.nix: Update to use virtualenv 2023-05-19 14:59:19 +02:00
892bf51163 Run black on all files 2023-05-19 14:57:48 +02:00
e20d7ca6c2 requirements: Fix required versions 2023-05-19 14:43:25 +02:00
Tom Hubrecht
1b09293206 Version 0.13 && Update changelog 2023-02-19 10:32:47 +01:00
Tom Hubrecht
e7da476697 Merge branch 'thubrecht/surnom' into 'master'
Rend le surnom lisible par la personne

Closes #297

See merge request klub-dev-ens/gestioCOF!506
2023-01-31 17:06:28 +01:00
Tom Hubrecht
761ab6df90 Merge branch '_aandres/inventory_sum_amounts' into 'master'
Affiche les montants des valeurs des stocks sur l'affichage d'un inventaire

See merge request klub-dev-ens/gestioCOF!515
2023-01-28 15:34:56 +01:00
Tom Hubrecht
a8d4035d33 Merge branch 'thubrecht/rappels_negatifs' into 'master'
On n'envoie des mails de rappel que lorsque le négatif est toujours d'actualité

Closes #298

See merge request klub-dev-ens/gestioCOF!509
2023-01-28 15:33:23 +01:00
b80426c56f feat(kfet): message info about prices 2023-01-28 15:28:54 +01:00
429e611daa feat(kfet): more values and formatting 2023-01-28 15:28:54 +01:00
Tom Hubrecht
5160da7862 Merge branch '292_fix_cancel_js' into 'master'
fix(kfet): fix js error when cancelling already canceled operation

Closes #292

See merge request klub-dev-ens/gestioCOF!516
2023-01-28 15:20:53 +01:00
aad3775222 fix(kfet): fix js error when cancelling already canceled operation 2023-01-28 15:13:55 +01:00
4b92716092 feat: poc inventory amount value
and lint
2023-01-23 21:53:46 +01:00
dfa5b4bf69 changelog: add current date 2022-10-03 18:37:41 +02:00
Tom Hubrecht
1be5dcb6af Merge branch 'thubrecht/kfetcms-css' into 'master'
kfetcms: Update the fixtures and fix the navbar behaviour due to a longer menu

See merge request klub-dev-ens/gestioCOF!513
2022-10-03 10:54:37 +02:00
a891ec56a6 dev: add nixos setup 2022-10-03 10:34:06 +02:00
7a52690a63 kfet: fix pipeline 2022-10-03 10:33:29 +02:00
a2f396ce7a Changelog: Update 2022-10-03 10:33:04 +02:00
85e30056a6 kfetcms: Update the fixtures and fix the navbar behaviour due to a longer menu 2022-10-03 10:22:32 +02:00
Tom Hubrecht
69de48f285 Version 0.12 2022-06-17 21:45:34 +02:00
Tom Hubrecht
eba36f2712 Merge branch 'dodo/kfet-history-limit-exceptions' into 'master'
Dodo/kfet history limit exceptions

See merge request klub-dev-ens/gestioCOF!508
2022-05-20 12:08:59 +02:00
Dorian Lesbre
bfdb34aae7 Dodo/kfet history limit exceptions 2022-05-20 12:08:59 +02:00
fcf2002cd7 On n'affiche le négatif que s'il existe vraiment 2022-01-11 18:10:00 +01:00
b236d6a950 Si last_rappel vaut None il n'est pas inclus dans le __lt 2022-01-11 18:10:00 +01:00
4b29097f02 On sauvegarde la date de fin du négatif 2022-01-11 18:10:00 +01:00
87f383bef1 On n'envoie des mails de rappel que lorsque le négatif est toujours d'actualité 2022-01-11 18:10:00 +01:00
Tom Hubrecht
1ad025e046 Merge branch 'dodo/fix_stat_labels' into 'master'
Dodo/fix stat labels

Closes #296

See merge request klub-dev-ens/gestioCOF!510
2022-01-07 11:07:51 +01:00
Dorian Lesbre
b3c047738a Ajout accent K-Fêt 2022-01-06 16:00:26 +01:00
Dorian Lesbre
17a9ae3302 Update CHANGELOG 2022-01-05 10:50:45 +01:00
Dorian Lesbre
e41bcbb6d7 Removed duplicate import to please flake8 2022-01-05 10:48:04 +01:00
Dorian Lesbre
e384bfb0f3 Fix issue #296 2022-01-05 10:45:32 +01:00
373ff1f62c Rend le surnom lisible par la personne 2021-11-25 14:44:40 +01:00
Martin Pepin
65eb95a3c9 Merge branch 'thubrecht/bds-membres' into 'master'
Réinitialisation des adhésions

Closes #294

See merge request klub-dev-ens/gestioCOF!503
2021-10-27 14:33:18 +02:00
Martin Pépin
1c880b265e
Version 1.11 2021-10-26 19:49:05 +02:00
Martin Pépin
75fbdc7efb
CHANGELOG: todo prod: faire un compte hcaptcha 2021-10-26 19:47:38 +02:00
1b8dd971b0 Ajoute un mécanisme de réinitialisation des adhésions 2021-10-26 10:26:22 +02:00
713d686047 Corrige l'affichage de la date dans le formulaire 2021-10-26 09:24:44 +02:00
Martin Pepin
77aa269c90 Merge branch 'Mails_rappel_kfet' into 'master'
Reminder mails for negative K-Psul accounts

See merge request klub-dev-ens/gestioCOF!492
2021-10-22 22:44:55 +02:00
Martin Pépin
9a143521d5
Update changelog 2021-10-22 22:37:56 +02:00
Martin Pépin
a77cf59b18
Rappels négatifs K-Fêt: ajustements cosmétiques 2021-10-22 22:36:30 +02:00
Alseidon
d8cabda678
First draft of reminder mail for negative K-Psul accounts 2021-10-22 21:29:34 +02:00
Martin Pépin
f086140dad
Update changelog 2021-10-22 21:12:16 +02:00
Martin Pepin
4d1ae8f540 Merge branch 'thubrecht/embed' into 'master'
On utilise |richtext pour les champs RichText, ce qui permet de bien faire les rendus

Closes #274

See merge request klub-dev-ens/gestioCOF!500
2021-10-22 21:04:20 +02:00
Ludovic Stephan
6d824a58be Merge branch 'thubrecht/ordre-consos' into 'master'
Corrige le tri des articles dans K-Psul

See merge request klub-dev-ens/gestioCOF!502
2021-10-12 16:05:26 +02:00
20880114aa Corrige le tri des articles dans K-Psul 2021-10-12 15:57:09 +02:00
Ludovic Stephan
df180d7446 Merge branch 'thubrecht/promo' into 'master'
Déplace le choix de la promo dans le formulaire

Closes #215

See merge request klub-dev-ens/gestioCOF!501
2021-07-01 09:03:47 +00:00
ef1793a348 Avec une seule majuscule 2021-07-01 10:29:54 +02:00
2d677b2093 Utilise des callables pour les choix 2021-07-01 10:29:14 +02:00
f70eacfc37 Déplace le choix de la promo dans le formulaire 2021-06-27 00:23:49 +02:00
264a0a852f On utilise |richtext pour les champs RichText, ce qui permet de bien faire les rendus 2021-06-26 22:52:23 +02:00
7ca7f7298a Update CHANGELOG 2021-06-17 21:28:08 +02:00
Tom Hubrecht
a5c822e7f7 Merge branch 'Aufinal/remove_negative' into 'master'
Fonctionnement du négatif + erreurs de K-Psul

Closes #279

See merge request klub-dev-ens/gestioCOF!494
2021-06-17 19:22:14 +00:00
Ludovic Stephan
6b316c482b Remove obsolete section 2021-06-17 17:22:17 +02:00
Ludovic Stephan
4060730ec5 Remove logging 2021-06-17 10:49:35 +02:00
Ludovic Stephan
c6cfc311e0 CHANGELOG 2021-06-17 10:45:53 +02:00
Ludovic Stephan
4326ba9016 Oublis de renaming 2021-06-17 10:42:15 +02:00
Ludovic Stephan
4205e0ad0e Tests 2021-06-17 10:42:15 +02:00
Ludovic Stephan
964eec6ab1 Adapte le JS aux nouvelles erreurs 2021-06-17 10:42:13 +02:00
Ludovic Stephan
29236e0b0e Nouvelle gestion des erreurs JSON 2021-06-17 10:40:51 +02:00
Ludovic Stephan
1939a54fef Tests du nouveau comportement 2021-06-17 10:40:51 +02:00
Ludovic Stephan
348881d207 Migration 2021-06-17 10:40:51 +02:00
Ludovic Stephan
ef8c1b8bf2 Nouveau fonctionnement des négatifs 2021-06-17 10:40:51 +02:00
Tom Hubrecht
8743301105 Merge branch 'Aufinal/let_it_go' into 'master'
Change le fonctionnement du gel de compte

Closes #280

See merge request klub-dev-ens/gestioCOF!493
2021-06-15 15:24:44 +00:00
Ludovic Stephan
6a11139588 Fix tests 2021-06-15 16:52:56 +02:00
Ludovic Stephan
a34b83c236 Use backend to enforce frozen accounts 2021-06-15 16:52:50 +02:00
Ludovic Stephan
02584982f6 gnagnagna 2021-06-15 14:48:35 +02:00
Ludovic Stephan
7bf0c5f09e Fix frozen forms 2021-06-15 14:07:43 +02:00
Ludovic Stephan
b9aaf6a19c Fix test 2021-06-15 14:07:43 +02:00
Ludovic Stephan
16dee0c143 Remove print 2021-06-15 14:07:43 +02:00
Ludovic Stephan
a947b9d3f2 Fix decorator 2021-06-15 14:07:43 +02:00
Ludovic Stephan
93d283fecb Remove unused permission 2021-06-15 14:07:43 +02:00
Ludovic Stephan
63738e8e02 Frozen error display 2021-06-15 14:07:40 +02:00
Ludovic Stephan
1e44550e12 New frozen function 2021-06-15 14:05:39 +02:00
Ludovic Stephan
4136cb6868 Unfreeze every account 2021-06-15 14:05:39 +02:00
Ludovic Stephan
99809209e0 Change les permissions pour geler/dégeler un compte 2021-06-15 14:05:39 +02:00
Ludovic Stephan
0351f6728b CHANGELOG 2021-05-05 02:10:44 +02:00
Ludovic Stephan
7efc7e6b94 Merge branch 'thubrecht/autocomplete-css' into 'master'
On modifie le curseur quand on survole un compte dans l'autocomplete

See merge request klub-dev-ens/gestioCOF!499
2021-05-05 00:06:15 +00:00
7d21a5a1fc On supprime des sélecteurs inutiles 2021-05-05 01:57:46 +02:00
dba785bf13 Pareil, mais dans gestiocof 2021-05-05 00:59:47 +02:00
71878caf2c On modifie le curseur quand on survole un compte dans l'autocomplete 2021-05-05 00:03:52 +02:00
Tom Hubrecht
db42028228 Merge branch 'Aufinal/backbone' into 'master'
Refactor le JS de K-Psul via Backbone : 2e étape

Closes #267 and #290

See merge request klub-dev-ens/gestioCOF!400
2021-05-04 21:17:09 +00:00
Ludovic Stephan
7171a7567c Remove double negative 2021-05-04 21:43:48 +02:00
Ludovic Stephan
339223bec0 Black 2021-05-04 18:12:47 +02:00
Ludovic Stephan
d62a8d61de Search fix and CSS update 2021-05-04 17:52:13 +02:00
Ludovic Stephan
f6c83dc692 FINALLY fix this f***ing whitespace mess 2021-05-04 17:52:13 +02:00
Ludovic Stephan
a984d1fd6f Clarity 2021-05-04 17:52:13 +02:00
Ludovic Stephan
f901ea9396 Remove useless kpsul.html code 2021-05-04 17:52:13 +02:00
Ludovic Stephan
17d96f1775 New account manager logic 2021-05-04 17:52:13 +02:00
Ludovic Stephan
c10e5fe45c Refactor Account model a bit 2021-05-04 17:52:13 +02:00
Martin Pépin
9bbe3f50cb
Update CHANGELOG.md 2021-04-18 18:17:38 +02:00
Martin Pépin
1f4a4ec76f
Update CHANGELOG.md 2021-04-18 17:46:54 +02:00
Martin Pepin
2befa584aa Merge branch 'Aufinal/remove_24' into 'master'
Remove limit for purchases

Closes #289

See merge request klub-dev-ens/gestioCOF!498
2021-04-18 08:35:24 +00:00
Ludovic Stephan
b48d32f4bc Remove limit for purchases 2021-04-16 16:42:12 +02:00
Tom Hubrecht
e36e88e77a Merge branch 'Aufinal/no_warnings' into 'master'
Fix : plus de warnings chelous pendant les tests

See merge request klub-dev-ens/gestioCOF!495
2021-03-17 22:12:01 +00:00
Tom Hubrecht
8e9fc341ca Merge branch 'Aufinal/forbidden_kfet' into 'master'
Test plus général pour l'erreur de permissions K-Fêt

See merge request klub-dev-ens/gestioCOF!491
2021-03-16 23:22:18 +01:00
Ludovic Stephan
c14c2d54a5 More general forbidden test 2021-03-16 23:04:03 +01:00
Tom Hubrecht
6adfaba8e9 Merge branch 'Aufinal/account_update_forms' into 'master'
Refactor la vue `account_update`

Closes #232 and #119

See merge request klub-dev-ens/gestioCOF!490
2021-03-16 23:02:12 +01:00
Tom Hubrecht
06005014f9 Merge branch 'Aufinal/delete_balance_offset' into 'master'
Supprime le champ `balance_offset` et harmonise la gestion des négatifs

Closes #281

See merge request klub-dev-ens/gestioCOF!489
2021-03-16 22:42:13 +01:00
Ludovic Stephan
4268a30d51 CHANGELOG 2021-03-16 22:10:33 +01:00
Tom Hubrecht
c71e6d22bf Merge branch 'Aufinal/hcaptcha' into 'master'
Remplace recaptcha par hcaptcha

Closes #262

See merge request klub-dev-ens/gestioCOF!497
2021-03-16 22:00:48 +01:00
Ludovic Stephan
4df3ef4dd9 Fix secret import 2021-03-04 23:28:55 +01:00
Ludovic Stephan
af95e64344 TODO de prod 2021-03-04 23:14:10 +01:00
Ludovic Stephan
ac8ad15ad1 Fix tests: mock captcha clean method 2021-03-04 18:30:51 +01:00
Ludovic Stephan
47dd078b6a Remplace recaptcha par hcaptcha 2021-03-04 17:56:42 +01:00
Ludovic Stephan
472a44c30f Remove useless buttons 2021-03-03 23:11:39 +01:00
Ludovic Stephan
b72ea9ebf9 Forgot a warning 2021-02-28 02:56:12 +01:00
Ludovic Stephan
f9958e4da0 Fix : plus de warnings chelous pendant les tests 2021-02-28 02:35:40 +01:00
Ludovic Stephan
47f406e09e Fix tests 2021-02-23 22:52:39 +01:00
Ludovic Stephan
1450b65dcd Rework complet de account_update 2021-02-23 22:52:39 +01:00
Ludovic Stephan
aac94afcd0 Améliore le formulaire de mdp K-Fêt 2021-02-23 22:52:39 +01:00
Ludovic Stephan
209360f535 Delete self-update form 2021-02-23 22:52:39 +01:00
Ludovic Stephan
b224fedf28 Fix frozen account display 2021-02-23 22:52:39 +01:00
Ludovic Stephan
1ab071d16e LINT 2021-02-23 22:52:27 +01:00
Ludovic Stephan
1cf6f6f3e7 Fix migration conflict 2021-02-23 22:41:04 +01:00
Ludovic Stephan
a421bec625 Fix templates 2021-02-23 22:33:00 +01:00
Ludovic Stephan
4e758fbba0 Delete balance_offset field 2021-02-23 22:33:00 +01:00
Martin Pepin
2350109a33 Merge branch 'Aufinal/migration_checks' into 'master'
CI: ne lance `migration_checks` que sur nos propres apps

See merge request klub-dev-ens/gestioCOF!488
2021-02-23 21:18:36 +01:00
Ludovic Stephan
778637d60e Merge branch 'dodo/limit-history-acces' into 'master'
Limit kfet history access

See merge request klub-dev-ens/gestioCOF!487
2021-02-20 22:58:59 +01:00
Dorian Lesbre
23f7865140 Switch back from config to settings 2021-02-20 20:59:54 +01:00
Dorian Lesbre
cc7c4306f4 Added change description to CHANGELOG 2021-02-20 19:10:49 +01:00
Dorian Lesbre
1183e50f60 Fixed tests 2021-02-19 13:48:12 +01:00
Dorian Lesbre
a8de7e0ae0 makemigrations 2021-02-19 13:38:36 +01:00
Dorian Lesbre
30a39ef2f6 Switch from account test to user test 2021-02-19 12:16:43 +01:00
Dorian Lesbre
9a635148bb Switched from datetime.today() to timezone.now() 2021-02-19 12:13:23 +01:00
Dorian Lesbre
4b95b65be2 Removed unused import 2021-02-19 11:55:18 +01:00
Dorian Lesbre
884ec2535b Fixed stupid errors 2021-02-19 11:51:48 +01:00
Dorian Lesbre
beba3052dd Switched from hardcoded settings to config 2021-02-19 11:46:42 +01:00
Dorian Lesbre
46242ad2c0 Added separate permission for chef/trez 2021-02-19 10:48:24 +01:00
Dorian Lesbre
fa8c57269c Added help_text to history form 2021-02-19 10:32:12 +01:00
Dorian Lesbre
b97bc8bfa8 Changed accoutn comparaison from id to equality 2021-02-19 10:26:05 +01:00
Dorian Lesbre
89fc309c01 Returned 403 on dubious history request 2021-02-19 10:18:47 +01:00
Ludovic Stephan
d7367476bc Fix app names 2021-02-18 17:41:52 +01:00
Ludovic Stephan
7297baaf7e Only check migrations for custom apps 2021-02-18 17:30:28 +01:00
Ludovic Stephan
8bf7914728 Merge branch 'kerl/fix_bds_production_urls' into 'master'
Hotfixes appliqués en production pour GestioBDS

See merge request klub-dev-ens/gestioCOF!484
2021-02-18 17:02:21 +01:00
Ludovic Stephan
71fbbcff8a Merge branch 'kerl/rm_login_clipper' into 'master'
Admin : supprime la colonne login_clipper dans la liste des Users

See merge request klub-dev-ens/gestioCOF!486
2021-02-18 17:01:05 +01:00
Dorian Lesbre
9303772f9a Renamed week_ago => history_limit and removed print 2021-02-10 22:19:52 +01:00
559b36b6f0 Limite le datepicker pour ne pas demander plus de temps que possible dans l'historique 2021-02-10 22:13:50 +01:00
Dorian Lesbre
fbafdb7134 Added kfet history date limit when not accessing own account 2021-02-10 21:32:44 +01:00
Martin Pépin
a53bd94737
admin: rm the login_clipper column in the user list 2021-02-09 22:42:49 +01:00
Ludovic Stephan
46ef12309a Merge branch 'kerl/rename_cof_gestioAsso' into 'master'
Renomme le dossier cof/ en gestioasso/

See merge request klub-dev-ens/gestioCOF!485
2021-02-08 19:29:07 +01:00
Martin Pépin
4f60ba35eb
Update the settings' docstrings 2021-02-08 19:19:54 +01:00
Martin Pépin
f29b3f0187
Make "GestioBDS" appear in the README 2021-02-07 18:11:17 +01:00
Martin Pépin
aa3462aaee
Update the CI config wrt the new project name 2021-02-07 18:11:06 +01:00
Martin Pépin
7c35357060
Fix a reverse url resolution on the BDS home page 2021-02-07 17:39:28 +01:00
Martin Pépin
726b3f55a0
Rename the cof/ folder to gestioasso/
This is a much more sensible name since it contains configuration
applicable to both GestioCOF and GestioBDS.

The next logical step would be to rename the `gestioncof/` folder to
`cof/`.
2021-02-07 17:17:15 +01:00
Martin Pepin
63eeb5b7a9 Merge branch 'Aufinal/single_checkout' into 'master'
Fix "Checkout is not iterable" error

See merge request klub-dev-ens/gestioCOF!483
2021-02-07 16:40:48 +01:00
Martin Pépin
7081380058
Only redirect / → /gestion in development 2021-02-07 16:29:47 +01:00
Ludovic Stephan
288de95c49 Checkout form is single-option now 2021-02-06 18:58:25 +01:00
Martin Pépin
9a01d1e877
CHANGELOG: add missing items in the v0.9 release 2021-02-06 17:17:47 +01:00
Martin Pépin
10746c0469
Version 0.9 2021-02-06 17:01:22 +01:00
Basile Clement
5c8eca15b6 Merge branch 'kerl/admin_autocomplete' into 'master'
Admin: on utilise la recherche builtin de Django

See merge request klub-dev-ens/gestioCOF!476
2021-02-04 22:16:27 +01:00
Martin Pepin
ef64f9ce5c Merge branch 'Buro_rights_by_BDS' into 'master'
Added basic buro right handling while updating member

See merge request klub-dev-ens/gestioCOF!482
2021-01-30 15:06:52 +01:00
Alseidon
9762838921
Basic Buro right handling - minor corrections 2021-01-30 14:59:04 +01:00
Alseidon
bf6d6d6430
Added basic buro right handling while updating member 2021-01-30 14:57:24 +01:00
Martin Pepin
ba9aa06b4f Merge branch 'dodo/bds_export_csv' into 'master'
Dodo/bds export csv

Closes #285

See merge request klub-dev-ens/gestioCOF!481
2021-01-29 19:38:55 +01:00
Dorian Lesbre
880dc31353 Update CHANGELOG.md 2021-01-29 09:37:37 +01:00
Dorian Lesbre
9a78fca507 Switched to named url 2021-01-29 09:34:56 +01:00
Ludovic Stephan
4bc56d34e0 Fix tests 2021-01-21 21:08:57 +01:00
Ludovic Stephan
79f0757e9f Fix kfet stats 2021-01-21 20:55:23 +01:00
Dorian Lesbre
a2eed13717 Added download button to home template 2021-01-21 20:38:15 +01:00
Dorian Lesbre
830aba984e Added bds/members to export members list as CSV 2021-01-21 20:32:36 +01:00
Martin Pépin
49fde85187
Admin: on utilise la recherche builtin de Django 2020-12-04 19:33:17 +01:00
312 changed files with 3653 additions and 1820 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use nix

4
.gitignore vendored
View file

@ -5,6 +5,7 @@ cof/settings.py
settings.py
*~
venv/
.venv/
.vagrant
/src
media/
@ -18,4 +19,5 @@ media/
.cache
# VSCode
.vscode/
.vscode/
.direnv

View file

@ -17,12 +17,15 @@ variables:
# psql password authentication
PGPASSWORD: $POSTGRES_PASSWORD
# apps to check migrations for
MIGRATION_APPS: "bda bds cofcms clubs events gestioncof kfet kfetauth kfetcms open petitscours shared"
.test_template:
before_script:
- mkdir -p vendor/{pip,apt}
- apt-get update -q && apt-get -o dir::cache::archives="vendor/apt" install -yqq postgresql-client libldap2-dev libsasl2-dev
- sed -E 's/^REDIS_HOST.*/REDIS_HOST = "redis"/' cof/settings/secret_example.py > cof/settings/secret.py
- sed -i.bak -E 's;^REDIS_PASSWD = .*$;REDIS_PASSWD = "";' cof/settings/secret.py
- sed -E 's/^REDIS_HOST.*/REDIS_HOST = "redis"/' gestioasso/settings/secret_example.py > gestioasso/settings/secret.py
- sed -i.bak -E 's;^REDIS_PASSWD = .*$;REDIS_PASSWD = "";' gestioasso/settings/secret.py
# Remove the old test database if it has not been done yet
- psql --username=$POSTGRES_USER --host=$DBHOST -c "DROP DATABASE IF EXISTS test_$POSTGRES_DB"
- pip install --upgrade -r requirements-prod.txt coverage tblib
@ -40,19 +43,27 @@ variables:
# Keep this disabled for now, as it may kill GitLab...
# coverage: '/TOTAL.*\s(\d+\.\d+)\%$/'
kfettest:
stage: test
extends: .test_template
variables:
DJANGO_SETTINGS_MODULE: "gestioasso.settings.cof_prod"
script:
- coverage run manage.py test kfet
coftest:
stage: test
extends: .test_template
variables:
DJANGO_SETTINGS_MODULE: "cof.settings.cof_prod"
DJANGO_SETTINGS_MODULE: "gestioasso.settings.cof_prod"
script:
- coverage run manage.py test gestioncof bda kfet petitscours shared --parallel
- coverage run manage.py test gestioncof bda petitscours shared --parallel
bdstest:
stage: test
extends: .test_template
variables:
DJANGO_SETTINGS_MODULE: "cof.settings.bds_prod"
DJANGO_SETTINGS_MODULE: "gestioasso.settings.bds_prod"
script:
- coverage run manage.py test bds clubs events --parallel
@ -65,7 +76,7 @@ linters:
- black --check .
- isort --check --diff .
# Print errors only
- flake8 --exit-zero bda bds clubs cof events gestioncof kfet petitscours provisioning shared
- flake8 --exit-zero bda bds clubs gestioasso events gestioncof kfet petitscours provisioning shared
cache:
key: linters
paths:
@ -75,14 +86,14 @@ linters:
migration_checks:
stage: test
variables:
DJANGO_SETTINGS_MODULE: "cof.settings.local"
DJANGO_SETTINGS_MODULE: "gestioasso.settings.local"
before_script:
- mkdir -p vendor/{pip,apt}
- apt-get update -q && apt-get -o dir::cache::archives="vendor/apt" install -yqq postgresql-client libldap2-dev libsasl2-dev
- cp cof/settings/secret_example.py cof/settings/secret.py
- cp gestioasso/settings/secret_example.py gestioasso/settings/secret.py
- pip install --upgrade -r requirements-devel.txt
- python --version
script: python manage.py makemigrations --dry-run --check
script: python manage.py makemigrations --dry-run --check $MIGRATION_APPS
services:
# this should not be necessary…
- postgres:11.7

View file

@ -21,13 +21,122 @@ Liste des changements notables dans GestioCOF depuis la version 0.1 (septembre
Uniquement un modèle simple de clubs avec des respos. Aucune gestion des
adhérents ni des cotisations.
## Version ??? - dans un futur proche
## TODO Prod
- Lancer `python manage.py update_translation_fields` après la migration
- Mettre à jour les units systemd `daphne.service` et `worker.service`
- Créer un compte hCaptcha (https://www.hcaptcha.com/), au COF, et remplacer les secrets associés
## Version ??? - ??/??/????
## Version 0.15.1 - 15/06/2023
### K-Fêt
- Rattrape les erreurs d'envoi de mail de négatif
- Utilise l'adresse chefs pour les envois de négatifs
## Version 0.15 - 22/05/2023
### K-Fêt
- Rajoute un formulaire de contact
- Rajoute un formulaire de demande de soirée
- Désactive les mails d'envoi de négatifs sur les comptes gelés
## Version 0.14 - 19/05/2023
- Répare les dépendances en spécifiant toutes les versions
### K-Fêt
- Répare la gestion des changement d'heure via moment.js
## Version 0.13 - 19/02/2023
### K-Fêt
- Rajoute la valeur des inventaires
- Résout les problèmes de négatif ne disparaissant pas
- Affiche son surnom s'il y en a un
- Bugfixes
## Version 0.12.1 - 03/10/2022
### K-Fêt
- Fixe un problème de rendu causé par l'agrandissement du menu
- Mise à jour vers Channels 3.x et Django 3.2
## Version 0.12 - 17/06/2022
### K-Fêt
- Ajoute une exception à la limite d'historique pour les comptes `LIQ` et `#13`
- Répare le problème des étiquettes LIQ/Comptes K-Fêt inversées dans les stats des articles K-Fêt
## Version 0.11 - 26/10/2021
### COF
- Répare un problème de rendu sur le wagtail du COF
### K-Fêt
- Ajoute de mails de rappels pour les comptes en négatif
- La recherche de comptes sur K-Psul remarche normalement
- Le pointeur de la souris change de forme quand on survole un item d'autocomplétion
- Modification du gel de compte:
- on ne peut plus geler/dégeler son compte soi-même (il faut la permission "Gérer les permissions K-Fêt")
- on ne peut rien compter sur un compte gelé (aucune override possible), et les K-Fêteux·ses dont le compte est gelé perdent tout accès à K-Psul
- les comptes actuellement gelés (sur l'ancien système) sont dégelés automatiquement
- Modification du fonctionnement des négatifs
- impossible d'avoir des négatifs inférieurs à `kfet_config.overdraft_amount`
- il n'y a plus de limite de temps sur les négatifs
- supression des autorisations de négatif
- il n'est plus possible de réinitialiser la durée d'un négatif en faisant puis en annulant une charge
- La gestion des erreurs passe du client au serveur, ce qui permet d'avoir des messages plus explicites
- La supression d'opérations anciennes est réparée
## Version 0.10 - 18/04/2021
### K-Fêt
- On fait sauter la limite qui empêchait de vendre plus de 24 unités d'un item à
la fois.
- L'interface indique plus clairement quand on fait une erreur en modifiant un
compte.
- On supprime la fonction "décalage de balance".
- L'accès à l'historique est maintenant limité à 7 jours pour raison de
confidentialité. Les chefs/trez peuvent disposer d'une permission
supplémentaire pour accéder à jusqu'à 30 jours en cas de problème de compta.
L'accès à son historique personnel n'est pas limité. Les durées sont
configurables dans `settings/cof_prod.py`.
### COF
- Le Captcha sur la page de demande de petits cours utilise maintenant hCaptcha
au lieu de ReCaptcha, pour mieux respecter la vie privée des utilisateur·ices
## Version 0.9 - 06/02/2020
### COF / BdA
- Le COF peut remettre à zéro la liste de ses adhérents en août (sans passer par
KDE).
- La page d'accueil affiche la date de fermeture des tirages BdA.
- On peut revendre une place dès qu'on l'a payée, plus besoin de payer toutes
ses places pour pouvoir revendre.
- On s'assure que les emails dans les demandes de petits cours sont valides.
- On s'assure que l'email fourni lors d'une demande de petit cours est valide.
### BDS
- Le burô peut maintenant accorder ou révoquer le statut de membre du Burô
en modifiant le profil d'un membre du BDS.
- Le burô peut exporter la liste de ses membres avec email au format CSV depuis
la page d'accueil.
### K-Fêt

View file

@ -1,4 +1,4 @@
# GestioCOF
# GestioCOF / GestioBDS
[![pipeline status](https://git.eleves.ens.fr/cof-geek/gestioCOF/badges/master/pipeline.svg)](https://git.eleves.ens.fr/cof-geek/gestioCOF/commits/master)
[![coverage report](https://git.eleves.ens.fr/cof-geek/gestioCOF/badges/master/coverage.svg)](https://git.eleves.ens.fr/cof-geek/gestioCOF/commits/master)
@ -38,11 +38,11 @@ Vous pouvez maintenant installer les dépendances Python depuis le fichier
pip install -U pip # parfois nécessaire la première fois
pip install -r requirements-devel.txt
Pour terminer, copier le fichier `cof/settings/secret_example.py` vers
`cof/settings/secret.py`. Sous Linux ou Mac, préférez plutôt un lien symbolique
Pour terminer, copier le fichier `gestioasso/settings/secret_example.py` vers
`gestioasso/settings/secret.py`. Sous Linux ou Mac, préférez plutôt un lien symbolique
pour profiter de façon transparente des mises à jour du fichier:
ln -s secret_example.py cof/settings/secret.py
ln -s secret_example.py gestioasso/settings/secret.py
Nous avons un git hook de pre-commit pour formatter et vérifier que votre code
vérifie nos conventions. Pour bénéficier des mises à jour du hook, préférez

View file

@ -33,20 +33,6 @@ class ReadOnlyMixin(object):
return readonly_fields + self.readonly_fields_update
class ChoixSpectacleAdminForm(forms.ModelForm):
class Meta:
widgets = {
"participant": ModelSelect2(url="bda-participant-autocomplete"),
"spectacle": ModelSelect2(url="bda-spectacle-autocomplete"),
}
class ChoixSpectacleInline(admin.TabularInline):
model = ChoixSpectacle
form = ChoixSpectacleAdminForm
sortable_field_name = "priority"
class AttributionTabularAdminForm(forms.ModelForm):
listing = None
@ -225,7 +211,6 @@ class AttributionAdminForm(forms.ModelForm):
class AttributionAdmin(ReadOnlyMixin, admin.ModelAdmin):
list_display = ("id", "spectacle", "participant", "given", "paid")
search_fields = (
"spectacle__title",
@ -238,7 +223,7 @@ class AttributionAdmin(ReadOnlyMixin, admin.ModelAdmin):
class ChoixSpectacleAdmin(admin.ModelAdmin):
form = ChoixSpectacleAdminForm
autocomplete_fields = ["participant", "spectacle"]
def tirage(self, obj):
return obj.participant.tirage

View file

@ -2,7 +2,6 @@ import random
class Algorithm(object):
shows = None
ranks = None
origranks = None

View file

@ -81,7 +81,7 @@ class Command(MyBaseCommand):
shows = random.sample(
list(tirage.spectacle_set.all()), tirage.spectacle_set.count() // 2
)
for (rank, show) in enumerate(shows):
for rank, show in enumerate(shows):
choices.append(
ChoixSpectacle(
participant=part,

View file

@ -22,7 +22,7 @@ class Command(BaseCommand):
delay = timedelta(days=4)
shows = (
Spectacle.objects.filter(date__range=(now, now + delay))
.filter(tirage__active=True, tirage__send_rappels_auto=True)
.filter(tirage__active=True)
.filter(rappel_sent__isnull=True)
.all()
)

View file

@ -6,7 +6,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
operations = [

View file

@ -35,7 +35,6 @@ def fill_tirage_fields(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [("bda", "0001_initial")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0002_add_tirage")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0003_update_tirage_and_spectacle")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0004_mails-rappel")]
operations = [

View file

@ -18,7 +18,6 @@ def forwards_func(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [("bda", "0005_encoding")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0006_add_tirage_switch")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0007_extends_spectacle")]
operations = [

View file

@ -6,7 +6,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0008_py3")]
operations = [

View file

@ -21,7 +21,6 @@ def forwards_func(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [("bda", "0009_revente")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0010_spectaclerevente_shotgun")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0011_tirage_appear_catalogue")]
operations = [

View file

@ -13,7 +13,6 @@ def swap_double_choice(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [("bda", "0011_tirage_appear_catalogue")]
operations = [

View file

@ -6,7 +6,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("bda", "0012_notif_time"), ("bda", "0012_swap_double_choice")]
operations = []

View file

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0013_merge_20180524_2123")]
operations = [

View file

@ -29,7 +29,6 @@ def set_participant_payment(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [("bda", "0014_attribution_paid_field")]
operations = [

View file

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("bda", "0015_move_bda_payment")]
operations = [

View file

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("bda", "0016_delete_participant_paid")]
operations = [

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bda", "0017_participant_accepte_charte"),
]

View file

@ -0,0 +1,23 @@
# Generated by Django 3.2.13 on 2022-06-30 10:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bda", "0018_auto_20201021_1818"),
]
operations = [
migrations.AlterUniqueTogether(
name="choixspectacle",
unique_together=set(),
),
migrations.AddConstraint(
model_name="choixspectacle",
constraint=models.UniqueConstraint(
fields=("participant", "spectacle"), name="unique_participation"
),
),
]

View file

@ -1,20 +0,0 @@
# Generated by Django 2.2.17 on 2021-01-08 15:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bda", "0018_auto_20201021_1818"),
]
operations = [
migrations.AddField(
model_name="tirage",
name="send_rappels_auto",
field=models.BooleanField(
default=True, verbose_name="Envoi automatique des mails de rappel"
),
),
]

View file

@ -32,9 +32,6 @@ class Tirage(models.Model):
)
enable_do_tirage = models.BooleanField("Le tirage peut être lancé", default=False)
archived = models.BooleanField("Archivé", default=False)
send_rappels_auto = models.BooleanField(
"Envoi automatique des mails de rappel", default=True
)
def __str__(self):
return "%s - %s" % (
@ -256,7 +253,11 @@ class ChoixSpectacle(models.Model):
class Meta:
ordering = ("priority",)
unique_together = (("participant", "spectacle"),)
constraints = [
models.UniqueConstraint(
fields=["participant", "spectacle"], name="unique_participation"
)
]
verbose_name = "voeu"
verbose_name_plural = "voeux"

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block extra_head %}
<link type="text/css" rel="stylesheet" href="{% static "bda/css/bda.css" %}" />

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block realcontent %}
<h2>État des inscriptions BdA</h2>

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block extra_head %}
<script type="text/javascript" src="{% static 'vendor/jquery/jquery-ui.min.js' %}" ></script>

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block realcontent %}
<h2>{{ spectacle }}</h2>

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{%block realcontent %}

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block realcontent %}
<h2>Inscription à une revente</h2>

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block realcontent %}

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block realcontent %}

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles%}
{% load static %}
{% block realcontent %}
<h2>Inscriptions pour BdA-Revente</h2>

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block realcontent %}

View file

@ -1,5 +1,5 @@
{% extends "base_title.html" %}
{% load staticfiles %}
{% load static %}
{% block extra_head %}
<link type="text/css" rel="stylesheet" href="{% static "bda/css/bda.css" %}" />

View file

@ -356,7 +356,9 @@ class TestReventeManageTest(TestCase):
def test_can_get(self):
client = Client()
client.force_login(self.user)
client.force_login(
self.user, backend="django.contrib.auth.backends.ModelBackend"
)
r = client.get(self.url)
self.assertEqual(r.status_code, 200)

View file

@ -1,80 +1,80 @@
from django.conf.urls import url
from django.urls import path
from django.urls import re_path
from bda import views
from bda.views import SpectacleListView
from gestioncof.decorators import buro_required
urlpatterns = [
url(
re_path(
r"^inscription/(?P<tirage_id>\d+)$",
views.inscription,
name="bda-tirage-inscription",
),
url(r"^places/(?P<tirage_id>\d+)$", views.places, name="bda-places-attribuees"),
url(r"^etat-places/(?P<tirage_id>\d+)$", views.etat_places, name="bda-etat-places"),
url(r"^tirage/(?P<tirage_id>\d+)$", views.tirage, name="bda-tirage"),
url(
re_path(r"^places/(?P<tirage_id>\d+)$", views.places, name="bda-places-attribuees"),
re_path(
r"^etat-places/(?P<tirage_id>\d+)$", views.etat_places, name="bda-etat-places"
),
re_path(r"^tirage/(?P<tirage_id>\d+)$", views.tirage, name="bda-tirage"),
re_path(
r"^spectacles/(?P<tirage_id>\d+)$",
buro_required(SpectacleListView.as_view()),
name="bda-liste-spectacles",
),
url(
re_path(
r"^spectacles/(?P<tirage_id>\d+)/(?P<spectacle_id>\d+)$",
views.spectacle,
name="bda-spectacle",
),
url(
re_path(
r"^spectacles/unpaid/(?P<tirage_id>\d+)$",
views.UnpaidParticipants.as_view(),
name="bda-unpaid",
),
url(
re_path(
r"^spectacles/autocomplete$",
views.spectacle_autocomplete,
name="bda-spectacle-autocomplete",
),
url(
re_path(
r"^participants/autocomplete$",
views.participant_autocomplete,
name="bda-participant-autocomplete",
),
# Urls BdA-Revente
url(
re_path(
r"^revente/(?P<tirage_id>\d+)/manage$",
views.revente_manage,
name="bda-revente-manage",
),
url(
re_path(
r"^revente/(?P<tirage_id>\d+)/subscribe$",
views.revente_subscribe,
name="bda-revente-subscribe",
),
url(
re_path(
r"^revente/(?P<tirage_id>\d+)/tirages$",
views.revente_tirages,
name="bda-revente-tirages",
),
url(
re_path(
r"^revente/(?P<spectacle_id>\d+)/buy$",
views.revente_buy,
name="bda-revente-buy",
),
url(
re_path(
r"^revente/(?P<revente_id>\d+)/confirm$",
views.revente_confirm,
name="bda-revente-confirm",
),
url(
re_path(
r"^revente/(?P<tirage_id>\d+)/shotgun$",
views.revente_shotgun,
name="bda-revente-shotgun",
),
url(r"^mails-rappel/(?P<spectacle_id>\d+)$", views.send_rappel, name="bda-rappels"),
url(r"^catalogue/(?P<request_type>[a-z]+)$", views.catalogue, name="bda-catalogue"),
path(
"toggle-rappels/<int:tirage_id>",
views.toggle_rappels,
name="bda-toggle-rappels",
re_path(
r"^mails-rappel/(?P<spectacle_id>\d+)$", views.send_rappel, name="bda-rappels"
),
re_path(
r"^catalogue/(?P<request_type>[a-z]+)$", views.catalogue, name="bda-catalogue"
),
]

View file

@ -274,13 +274,13 @@ def do_tirage(tirage_elt, token):
results = Algorithm(data["shows"], data["members"], choices)(token)
# On compte les places attribuées et les déçus
for (_, members, losers) in results:
for _, members, losers in results:
data["total_slots"] += len(members)
data["total_losers"] += len(losers)
# On calcule le déficit et les bénéfices pour le BdA
# FIXME: le traitement de l'opéra est sale
for (show, members, _) in results:
for show, members, _ in results:
deficit = (show.slots - len(members)) * show.price
data["total_sold"] += show.slots * show.price
if deficit >= 0:
@ -293,8 +293,8 @@ def do_tirage(tirage_elt, token):
# so assign a single object for each Participant id
members_uniq = {}
members2 = {}
for (show, members, _) in results:
for (member, _, _, _) in members:
for show, members, _ in results:
for member, _, _, _ in members:
if member.id not in members_uniq:
members_uniq[member.id] = member
members2[member] = []
@ -734,18 +734,6 @@ class SpectacleListView(ListView):
return context
def toggle_rappels(request, tirage_id):
"""
Permet de désactiver ou de réactiver les envois de mails automatiques pour
les spectacles appartenant à ce tirage.
"""
tirage = get_object_or_404(Tirage, id=tirage_id)
tirage.send_rappels_auto = not tirage.send_rappels_auto
tirage.save()
return HttpResponseRedirect(reverse("home"))
class UnpaidParticipants(BuroRequiredMixin, ListView):
context_object_name = "unpaid"
template_name = "bda-unpaid.html"

View file

@ -1 +0,0 @@
default_app_config = "bds.apps.BdsConfig"

View file

@ -1,5 +1,4 @@
from django import apps as global_apps
from django.apps import AppConfig
from django.apps import AppConfig, apps as global_apps
from django.db.models import Q
from django.db.models.signals import post_migrate

View file

@ -1,6 +1,7 @@
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django.utils.translation import gettext_lazy as _
from bds.models import BDSProfile
@ -8,6 +9,8 @@ User = get_user_model()
class UserForm(forms.ModelForm):
is_buro = forms.BooleanField(label=_("Membre du Burô"), required=False)
class Meta:
model = User
fields = ["email", "first_name", "last_name"]
@ -33,4 +36,6 @@ class ProfileForm(forms.ModelForm):
class Meta:
model = BDSProfile
exclude = ["user"]
widgets = {"birthdate": forms.DateInput(attrs={"type": "date"})}
widgets = {
"birthdate": forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d")
}

View file

@ -8,7 +8,6 @@ import bds.models
class Migration(migrations.Migration):
initial = True
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]

View file

@ -9,7 +9,6 @@ def create_bds_buro_group(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [("bds", "0001_initial")]
operations = [

View file

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("bds", "0002_bds_group"),
]

View file

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bds", "0003_staff_permission"),
]

View file

@ -4,7 +4,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("bds", "0004_is_member_cotiz_type"),
]

View file

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bds", "0005_remove_bdsprofile_certificate_file"),
]

View file

@ -3,6 +3,7 @@ from os.path import splitext
from django.contrib.auth import get_user_model
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from shared.utils import choices_length
@ -93,6 +94,16 @@ class BDSProfile(models.Model):
),
)
@classmethod
def expired_members(cls):
now = timezone.now()
qs = cls.objects.filter(is_member=True)
if now.month > 1 and now.month < 7:
return qs.filter(cotisation_period="SE1")
elif now.month < 2 or now.month > 8:
return qs.none()
return qs
class Meta:
verbose_name = _("Profil BDS")
verbose_name_plural = _("Profils BDS")

View file

@ -1,4 +1,4 @@
{% load staticfiles %}
{% load static %}
{% load bulma_utils %}
<!DOCTYPE html>

View file

@ -0,0 +1,22 @@
{% extends "bds/base.html" %}
{% block content %}
<h1 class="title">Liste des adhésions expirées</h1>
{% if object_list %}
<div class="content">
<ul>
{% for p in object_list %}
<li>{{ p.user.first_name }} {{ p.user.last_name }} ({{ p.user.username }}), {{ p.get_cotisation_period_display }}</li>
{% endfor %}
</ul>
</div>
<div class="buttons is-centered">
<a class="button is-danger" href="{% url 'bds:members.reset' %}">Réinitialiser les adhésions expirées</a>
</div>
{% endif %}
{% endblock %}

View file

@ -7,7 +7,7 @@
<section class="section">
<div class="box">
<div class="content has-text-centered">
<h1>{{ member_count }}</h1>
<h1>{{ member_count }}</h1>
adhérent·e·s
</div>
</div>
@ -34,6 +34,13 @@
<br>
<br>
<a class=button href="{% url 'bds:export.members' %}">Télécharger la liste des membres (CSV)</a>
<a class=button href="{% url 'bds:members.expired' %}">Liste des adhésions expirées ({{ nb_expired }})</a>
<br>
<br>
Le site est encore en développement.
<br>
Suivez notre avancement sur
@ -52,4 +59,4 @@
{% endblock layout %}

View file

@ -5,100 +5,100 @@
{% block content %}
{% for form in forms.values %}
{% for error in form.non_field_errors %}
<div class="notification is-danger">
{{ error }}
</div>
{% endfor %}
{% for error in form.non_field_errors %}
<div class="notification is-danger">
{{ error }}
</div>
{% endfor %}
{% endfor %}
<h1 class="title">{% trans "Modification du profil " %}{{ view.user.username }}</h1>
<div class="container">
<form method="post" action="" id="user-update-form">
{% csrf_token %}
<form method="post" action="" id="user-update-form">
{% csrf_token %}
{% for form in forms.values %}
{% include "bds/forms/form.html" with form=form errors=False %}
{% endfor %}
</form>
{% for form in forms.values %}
{% include "bds/forms/form.html" with form=form errors=False %}
{% endfor %}
</form>
<form method="post" action="{% url 'bds:user.delete' view.user.pk %}" id="user-delete-form">
{% csrf_token %}
</form>
<div class="columns is-gapless mt-5">
<div class="column is-5">
<button id="user-update-button" class="button is-fullwidth is-primary">Enregistrer</button>
<form method="post" action="{% url 'bds:user.delete' view.user.pk %}" id="user-delete-form">
{% csrf_token %}
</form>
<div class="columns is-gapless mt-5">
<div class="column is-5">
<button id="user-update-button" class="button is-fullwidth is-primary">Enregistrer</button>
</div>
<div class="column is-2">
</div>
<div class="column is-5">
<button id="user-delete-button" class="button is-fullwidth is-danger">Supprimer</button>
</div>
</div>
<div class="column is-2">
</div>
<div class="column is-5">
<button id="user-delete-button" class="button is-fullwidth is-danger">Supprimer</button>
</div>
</div>
</div>
<!-- Hidden by default -->
<div id="confirm-delete-modal" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Confirmer la suppression</p>
<button id= "modal-close" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
Voulez-vous réellement supprimer ce compte ? Attention, cette opération est irréversible !
</section>
<footer class="modal-card-foot">
<button id="confirm-delete-button" class="button is-primary">Supprimer</button>
<button id="cancel-delete-button" class="button">Annuler</button>
</footer>
</div>
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Confirmer la suppression</p>
<button id="modal-close" class="delete" aria-label="close"></button>
</header>
<section class="modal-card-body">
Voulez-vous réellement supprimer ce compte ? Attention, cette opération est irréversible !
</section>
<footer class="modal-card-foot">
<button id="confirm-delete-button" class="button is-primary">Supprimer</button>
<button id="cancel-delete-button" class="button">Annuler</button>
</footer>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
"use strict";
$(document).ready(function() {
"use strict";
// Adapted from https://bulma.io/lib/main.js
function openModal(target) {
$(document).addClass('is-clipped');
$(`#${target}`).addClass('is-active');
}
// Adapted from https://bulma.io/lib/main.js
function openModal(target) {
$(document).addClass('is-clipped');
$(`#${target}`).addClass('is-active');
}
function closeModals() {
$(document).removeClass('is-clipped');
$(".modal").removeClass('is-active');
}
function closeModals() {
$(document).removeClass('is-clipped');
$(".modal").removeClass('is-active');
}
// Si on clique sur enregistrer, ça marche
$("#user-update-button").on("click", function() {
$("#user-update-form").submit();
})
// Si on clique sur enregistrer, ça marche
$("#user-update-button").on("click", function() {
$("#user-update-form").submit();
})
// Si on clique sur supprimer, confirmation demandée
$("#user-delete-button").on("click", function() {
openModal("confirm-delete-modal");
});
$(".modal-background, #modal-close, #cancel-delete-button").on("click", closeModals);
$("#confirm-delete-button").on("click", function() {
$("#user-delete-form").submit();
});
$(document).on("keydown", function(e) {
if (e.key == "Escape") {
closeModals();
}
if (e.key == "Enter") {
$("#user-update-form").submit();
}
});
// Si on clique sur supprimer, confirmation demandée
$("#user-delete-button").on("click", function () {
openModal("confirm-delete-modal");
});
$(".modal-background, #modal-close, #cancel-delete-button").on("click", closeModals);
$("#confirm-delete-button").on("click", function() {
$("#user-delete-form").submit();
});
$(document).on("keydown", function (e) {
if (e.key == "Escape") {
closeModals();
}
if (e.key == "Enter") {
$("#user-update-form").submit();
}
});
});
</script>
{% endblock %}

View file

@ -22,6 +22,18 @@ def login_url(next=None):
return "{}?next={}".format(login_url, next)
class TestHomeView(TestCase):
@mock.patch("gestioncof.signals.messages")
def test_get(self, mock_messages):
user = User.objects.create_user(username="random_user")
give_bds_buro_permissions(user)
self.client.force_login(
user, backend="django.contrib.auth.backends.ModelBackend"
)
resp = self.client.get(reverse("bds:home"))
self.assertEqual(resp.status_code, 200)
class TestRegistrationView(TestCase):
@mock.patch("gestioncof.signals.messages")
def test_get_autocomplete(self, mock_messages):
@ -34,14 +46,14 @@ class TestRegistrationView(TestCase):
self.assertRedirects(resp, login_url(next=url))
# Logged-in but unprivileged GET
client.force_login(user)
client.force_login(user, backend="django.contrib.auth.backends.ModelBackend")
resp = client.get(url)
self.assertEquals(resp.status_code, 403)
self.assertEqual(resp.status_code, 403)
# Burô user GET
give_bds_buro_permissions(user)
resp = client.get(url)
self.assertEquals(resp.status_code, 200)
self.assertEqual(resp.status_code, 200)
@mock.patch("gestioncof.signals.messages")
def test_get(self, mock_messages):
@ -54,11 +66,11 @@ class TestRegistrationView(TestCase):
self.assertRedirects(resp, login_url(next=url))
# Logged-in but unprivileged GET
client.force_login(user)
client.force_login(user, backend="django.contrib.auth.backends.ModelBackend")
resp = client.get(url)
self.assertEquals(resp.status_code, 403)
self.assertEqual(resp.status_code, 403)
# Burô user GET
give_bds_buro_permissions(user)
resp = client.get(url)
self.assertEquals(resp.status_code, 200)
self.assertEqual(resp.status_code, 200)

View file

@ -14,4 +14,11 @@ urlpatterns = [
name="user.create.fromclipper",
),
path("user/delete/<int:pk>", views.UserDeleteView.as_view(), name="user.delete"),
path("members", views.export_members, name="export.members"),
path(
"members/expired",
views.ResetMembershipListView.as_view(),
name="members.expired",
),
path("members/reset", views.ResetMembershipView.as_view(), name="members.reset"),
]

View file

@ -1,9 +1,14 @@
import csv
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.models import Permission
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import DeleteView, TemplateView
from django.views.generic import DeleteView, ListView, RedirectView, TemplateView
from bds.autocomplete import bds_search
from bds.forms import ProfileForm, UserForm, UserFromClipperForm, UserFromScratchForm
@ -25,6 +30,7 @@ class Home(StaffRequiredMixin, TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["member_count"] = BDSProfile.objects.filter(is_member=True).count()
context["nb_expired"] = BDSProfile.expired_members().count()
return context
@ -36,6 +42,9 @@ class UserUpdateView(StaffRequiredMixin, MultipleFormView):
"profile": ProfileForm,
}
def get_user_initial(self):
return {"is_buro": self.get_user_instance().has_perm("bds.is_team")}
def dispatch(self, request, *args, **kwargs):
self.user = get_object_or_404(User, pk=self.kwargs["pk"])
return super().dispatch(request, *args, **kwargs)
@ -52,6 +61,11 @@ class UserUpdateView(StaffRequiredMixin, MultipleFormView):
def form_valid(self, forms):
user = forms["user"].save()
profile = forms["profile"].save(commit=False)
perm = Permission.objects.get(content_type__app_label="bds", codename="is_team")
if forms["user"].cleaned_data["is_buro"]:
user.user_permissions.add(perm)
else:
user.user_permissions.remove(perm)
profile.user = user
profile.save()
messages.success(self.request, _("Profil mis à jour avec succès !"))
@ -128,3 +142,43 @@ class UserDeleteView(StaffRequiredMixin, DeleteView):
messages.success(request, self.success_message)
return super().delete(request, *args, **kwargs)
class ResetMembershipListView(StaffRequiredMixin, ListView):
model = BDSProfile
template_name = "bds/expired_members.html"
def get_queryset(self):
return BDSProfile.expired_members()
class ResetMembershipView(StaffRequiredMixin, RedirectView):
url = reverse_lazy("bds:members.expired")
def get(self, request, *args, **kwargs):
qs = BDSProfile.expired_members()
nb = qs.count()
qs.update(cotisation_period="NO", is_member=False, mails_bds=False)
messages.success(request, f"{nb} adhésions réinitialisées")
return super().get(request, *args, **kwargs)
@permission_required("bds.is_team")
def export_members(request):
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = "attachment; filename=membres_bds.csv"
writer = csv.writer(response)
for profile in BDSProfile.objects.filter(is_member=True).all():
user = profile.user
bits = [
user.username,
user.get_full_name(),
user.email,
]
writer.writerow([str(bit) for bit in bits])
return response

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]

View file

@ -1,8 +0,0 @@
import os
from channels.asgi import get_channel_layer
if "DJANGO_SETTINGS_MODULE" not in os.environ:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings")
channel_layer = get_channel_layer()

View file

@ -1,3 +0,0 @@
from channels.routing import include
routing = [include("kfet.routing.routing", path=r"^/ws/k-fet")]

View file

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []

View file

@ -5,7 +5,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("events", "0001_event"),

View file

@ -6,7 +6,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("events", "0002_event_subscribers"),

View file

@ -5,7 +5,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("events", "0003_options_and_extra_fields"),

View file

@ -0,0 +1,63 @@
# Generated by Django 3.2.13 on 2022-06-30 10:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("events", "0004_unique_constraints"),
]
operations = [
migrations.AlterUniqueTogether(
name="extrafield",
unique_together=set(),
),
migrations.AlterUniqueTogether(
name="extrafieldcontent",
unique_together=set(),
),
migrations.AlterUniqueTogether(
name="option",
unique_together=set(),
),
migrations.AlterUniqueTogether(
name="optionchoice",
unique_together=set(),
),
migrations.AlterUniqueTogether(
name="registration",
unique_together=set(),
),
migrations.AddConstraint(
model_name="extrafield",
constraint=models.UniqueConstraint(
fields=("event", "name"), name="unique_extra_field"
),
),
migrations.AddConstraint(
model_name="extrafieldcontent",
constraint=models.UniqueConstraint(
fields=("field", "registration"), name="unique_extra_field_content"
),
),
migrations.AddConstraint(
model_name="option",
constraint=models.UniqueConstraint(
fields=("event", "name"), name="unique_event_option"
),
),
migrations.AddConstraint(
model_name="optionchoice",
constraint=models.UniqueConstraint(
fields=("option", "choice"), name="unique_option_choice"
),
),
migrations.AddConstraint(
model_name="registration",
constraint=models.UniqueConstraint(
fields=("event", "user"), name="unique_registration"
),
),
]

View file

@ -72,9 +72,13 @@ class Option(models.Model):
multi_choices = models.BooleanField(_("choix multiples"), default=False)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["event", "name"], name="unique_event_option"
)
]
verbose_name = _("option d'événement")
verbose_name_plural = _("options d'événement")
unique_together = [["event", "name"]]
def __str__(self):
return self.name
@ -87,9 +91,13 @@ class OptionChoice(models.Model):
choice = models.CharField(_("choix"), max_length=200)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["option", "choice"], name="unique_option_choice"
)
]
verbose_name = _("choix d'option d'événement")
verbose_name_plural = _("choix d'option d'événement")
unique_together = [["option", "choice"]]
def __str__(self):
return self.choice
@ -118,7 +126,9 @@ class ExtraField(models.Model):
field_type = models.CharField(_("type de champ"), max_length=9, choices=FIELD_TYPE)
class Meta:
unique_together = [["event", "name"]]
constraints = [
models.UniqueConstraint(fields=["event", "name"], name="unique_extra_field")
]
class ExtraFieldContent(models.Model):
@ -137,9 +147,13 @@ class ExtraFieldContent(models.Model):
)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["field", "registration"], name="unique_extra_field_content"
)
]
verbose_name = _("contenu d'un champ événement supplémentaire")
verbose_name_plural = _("contenus d'un champ événement supplémentaire")
unique_together = [["field", "registration"]]
def __str__(self):
max_length = 50
@ -163,9 +177,13 @@ class Registration(models.Model):
)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["event", "user"], name="unique_registration"
)
]
verbose_name = _("inscription à un événement")
verbose_name_plural = _("inscriptions à un événement")
unique_together = [["event", "user"]]
def __str__(self):
return "inscription de {} à {}".format(self.user, self.event)

View file

@ -54,7 +54,9 @@ class CSVExportAccessTest(MessagePatch, TestCase):
def test_get(self):
client = Client()
client.force_login(self.staff)
client.force_login(
self.staff, backend="django.contrib.auth.backends.ModelBackend"
)
r = client.get(self.url)
self.assertEqual(r.status_code, 200)
@ -66,7 +68,7 @@ class CSVExportAccessTest(MessagePatch, TestCase):
def test_unauthorised(self):
client = Client()
client.force_login(self.u1)
client.force_login(self.u1, backend="django.contrib.auth.backends.ModelBackend")
r = client.get(self.url)
self.assertEqual(r.status_code, 403)
@ -86,7 +88,9 @@ class CSVExportContentTest(MessagePatch, CSVResponseMixin, TestCase):
)
self.staff = make_staff_user("staff")
self.client = Client()
self.client.force_login(self.staff)
self.client.force_login(
self.staff, backend="django.contrib.auth.backends.ModelBackend"
)
def test_simple_event(self):
self.event.subscribers.set([self.u1, self.u2])

15
gestioasso/asgi.py Normal file
View file

@ -0,0 +1,15 @@
"""
ASGI entrypoint. Configures Django and then runs the application
defined in the ASGI_APPLICATION setting.
"""
import os
import django
from channels.routing import get_default_application
if "DJANGO_SETTINGS_MODULE" not in os.environ:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gestioasso.settings.local")
django.setup()
application = get_default_application()

20
gestioasso/routing.py Normal file
View file

@ -0,0 +1,20 @@
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from django.urls import path
from kfet.routing import KFRouter
application = ProtocolTypeRouter(
{
# WebSocket chat handler
"websocket": AuthMiddlewareStack(
URLRouter(
[
path("ws/k-fet", KFRouter),
]
)
),
"http": get_asgi_application(),
}
)

View file

@ -1,7 +1,9 @@
"""
Django development settings for the cof project.
The settings that are not listed here are imported from .common
Settings de production de GestioBDS.
Surcharge les settings définis dans common.py
"""
from .common import * # NOQA
from .common import INSTALLED_APPS

View file

@ -1,8 +1,13 @@
"""
Django development settings for the cof project.
The settings that are not listed here are imported from .common
Settings de production de GestioCOF.
Surcharge les settings définis dans common.py
"""
import os
from datetime import timedelta
from django.utils import timezone
from .common import * # NOQA
from .common import (
@ -23,8 +28,8 @@ REDIS_DB = import_secret("REDIS_DB")
REDIS_HOST = import_secret("REDIS_HOST")
REDIS_PORT = import_secret("REDIS_PORT")
RECAPTCHA_PUBLIC_KEY = import_secret("RECAPTCHA_PUBLIC_KEY")
RECAPTCHA_PRIVATE_KEY = import_secret("RECAPTCHA_PRIVATE_KEY")
HCAPTCHA_SITEKEY = import_secret("HCAPTCHA_SITEKEY")
HCAPTCHA_SECRET = import_secret("HCAPTCHA_SECRET")
KFETOPEN_TOKEN = import_secret("KFETOPEN_TOKEN")
# ---
@ -47,7 +52,7 @@ INSTALLED_APPS = (
+ [
"bda",
"petitscours",
"captcha",
"hcaptcha",
"kfet",
"kfet.open",
"channels",
@ -80,7 +85,6 @@ MIDDLEWARE = (
+ MIDDLEWARE
+ [
"djconfig.middleware.DjConfigMiddleware",
"wagtail.core.middleware.SiteMiddleware",
"wagtail.contrib.redirects.middleware.RedirectMiddleware",
]
)
@ -104,15 +108,23 @@ MEDIA_URL = "/gestion/media/"
CORS_ORIGIN_WHITELIST = ("bda.ens.fr", "www.bda.ens.fr" "cof.ens.fr", "www.cof.ens.fr")
ASGI_APPLICATION = "gestioasso.routing.application"
# ---
# Auth-related stuff
# ---
AUTHENTICATION_BACKENDS += [
"gestioncof.shared.COFCASBackend",
"kfet.auth.backends.GenericBackend",
]
AUTHENTICATION_BACKENDS = (
[
# Must be in first
"kfet.auth.backends.BlockFrozenAccountBackend"
]
+ AUTHENTICATION_BACKENDS
+ [
"gestioncof.shared.COFCASBackend",
"kfet.auth.backends.GenericBackend",
]
)
LOGIN_URL = "cof-login"
LOGIN_REDIRECT_URL = "home"
@ -136,7 +148,7 @@ CACHES = {
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgi_redis.RedisChannelLayer",
"BACKEND": "shared.channels.ChannelLayer",
"CONFIG": {
"hosts": [
(
@ -149,11 +161,9 @@ CHANNEL_LAYERS = {
)
]
},
"ROUTING": "cof.routing.routing",
}
}
# ---
# reCAPTCHA settings
# https://github.com/praekelt/django-recaptcha
@ -195,8 +205,29 @@ MAIL_DATA = {
"REPLYTO": "cof@ens.fr",
},
"rappels": {"FROM": "Le BdA <bda@ens.fr>", "REPLYTO": "Le BdA <bda@ens.fr>"},
"kfet": {
"FROM": "La K-Fêt <chefs-k-fet@ens.fr>",
"REPLYTO": "La K-Fêt <chefs-k-fet@ens.fr>",
},
"revente": {
"FROM": "BdA-Revente <bda-revente@ens.fr>",
"REPLYTO": "BdA-Revente <bda-revente@ens.fr>",
},
}
# ---
# kfet history limits
# ---
# L'historique n'est accesible que d'aujourd'hui
# à aujourd'hui - KFET_HISTORY_DATE_LIMIT
KFET_HISTORY_DATE_LIMIT = timedelta(days=7)
# Limite plus longue pour les chefs/trez
# (qui ont la permission kfet.access_old_history)
KFET_HISTORY_LONG_DATE_LIMIT = timedelta(days=30)
# These accounts don't represent actual people and can be freely accessed
# Identification based on trigrammes
KFET_HISTORY_NO_DATE_LIMIT_TRIGRAMMES = ["LIQ", "#13"]
KFET_HISTORY_NO_DATE_LIMIT = timezone.datetime(1794, 10, 30) # AKA the distant past

View file

@ -1,8 +1,5 @@
"""
Django common settings for cof project.
Everything which is supposed to be identical between the production server and
the local development server should be here.
Settings par défaut et settings communs à GestioCOF et GestioBDS.
"""
import os
@ -65,7 +62,7 @@ INSTALLED_APPS = [
"django.contrib.messages",
"django.contrib.admin",
"django.contrib.admindocs",
"cof.apps.IgnoreSrcStaticFilesConfig",
"gestioasso.apps.IgnoreSrcStaticFilesConfig",
"django_cas_ng",
"bootstrapform",
"widget_tweaks",
@ -82,7 +79,7 @@ MIDDLEWARE = [
"django.middleware.locale.LocaleMiddleware",
]
ROOT_URLCONF = "cof.urls"
ROOT_URLCONF = "gestioasso.urls"
TEMPLATES = [
{
@ -104,7 +101,7 @@ TEMPLATES = [
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"ENGINE": "django.db.backends.postgresql",
"NAME": DBNAME,
"USER": DBUSER,
"PASSWORD": DBPASSWD,
@ -114,6 +111,7 @@ DATABASES = {
SITE_ID = 1
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
# ---
# Internationalization
@ -126,7 +124,7 @@ USE_I18N = True
USE_L10N = True
USE_TZ = True
LANGUAGES = (("fr", "Français"), ("en", "English"))
FORMAT_MODULE_PATH = "cof.locale"
FORMAT_MODULE_PATH = "gestioasso.locale"
# ---

View file

@ -1,4 +1,10 @@
"""Django local development settings."""
"""
Settings utilisés dans la VM Vagrant.
Active toutes les applications (de GestioCOF et de GestioBDS).
Surcharge les settings définis dans common.py
"""
import os
from . import bds_prod

View file

@ -1,4 +1,9 @@
"""Django local development settings."""
"""
Settings utilisés lors d'un développement en local (dans un virtualenv).
Active toutes les applications (de GestioCOF et de GestioBDS).
Surcharge les settings définis dans common.py
"""
import os
from . import bds_prod
@ -42,8 +47,7 @@ CACHES = {"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"
# Use the default in memory asgi backend for local development
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgiref.inmemory.ChannelLayer",
"ROUTING": "cof.routing.routing",
"BACKEND": "channels.layers.InMemoryChannelLayer",
}
}

View file

@ -1,3 +1,7 @@
"""
Secrets à re-définir en production.
"""
SECRET_KEY = "q()(zn4m63i%5cp4)f+ww4-28_w+ly3q9=6imw2ciu&_(5_4ah"
ADMINS = None
SERVER_EMAIL = "root@vagrant"
@ -12,8 +16,8 @@ REDIS_PORT = 6379
REDIS_DB = 0
REDIS_HOST = "127.0.0.1"
RECAPTCHA_PUBLIC_KEY = "DUMMY"
RECAPTCHA_PRIVATE_KEY = "DUMMY"
HCAPTCHA_SITEKEY = "10000000-ffff-ffff-ffff-000000000001"
HCAPTCHA_SECRET = "0x0000000000000000000000000000000000000000"
EMAIL_HOST = None

View file

@ -8,20 +8,22 @@ from django.contrib import admin
from django.urls import include, path
from django.views.generic.base import RedirectView
bds_is_alone = (
"bds" in settings.INSTALLED_APPS and "gestioncof" not in settings.INSTALLED_APPS
)
admin.autodiscover()
urlpatterns = [
# Redirection / → /gestion, only useful for developpers.
path("", RedirectView.as_view(url="gestion/")),
# Website administration (independent from installed apps)
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls),
]
# App-specific urls
if not bds_is_alone:
# Redirection / → /gestion, only useful for developpers.
urlpatterns.append(path("", RedirectView.as_view(url="gestion/")))
bds_is_alone = (
"bds" in settings.INSTALLED_APPS and "gestioncof" not in settings.INSTALLED_APPS
)
# App-specific urls
app_dict = {
"bds": "" if bds_is_alone else "bds/",
@ -33,7 +35,7 @@ app_dict = {
"events": "gestion/event_v2/", # the events module is still experimental !
"authens": "gestion/authens/",
}
for (app_name, url_prefix) in app_dict.items():
for app_name, url_prefix in app_dict.items():
if app_name in settings.INSTALLED_APPS:
urlpatterns += [path(url_prefix, include("{}.urls".format(app_name)))]

View file

@ -2,5 +2,5 @@ import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "cof.settings.bds_prod")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gestioasso.settings.bds_prod")
application = get_wsgi_application()

View file

@ -1 +0,0 @@
default_app_config = "gestioncof.apps.GestioncofConfig"

View file

@ -6,7 +6,7 @@ from django.contrib.auth.models import Group, Permission, User
from django.db.models import Q
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from gestioncof.models import (
Club,
@ -100,28 +100,6 @@ class CofProfileInline(admin.StackedInline):
inline_classes = ("collapse open",)
class FkeyLookup(object):
def __init__(self, fkeydecl, short_description=None, admin_order_field=None):
self.fk, fkattrs = fkeydecl.split("__", 1)
self.fkattrs = fkattrs.split("__")
self.short_description = short_description or self.fkattrs[-1]
self.admin_order_field = admin_order_field or fkeydecl
def __get__(self, obj, klass):
if obj is None:
"""
hack required to make Django validate (if obj is
None, then we're a class, and classes are callable
<wink>)
"""
return self
item = getattr(obj, self.fk)
for attr in self.fkattrs:
item = getattr(item, attr)
return item
def ProfileInfo(field, short_description, boolean=False):
def getter(self):
try:
@ -134,7 +112,6 @@ def ProfileInfo(field, short_description, boolean=False):
return getter
User.profile_login_clipper = FkeyLookup("profile__login_clipper", "Login clipper")
User.profile_phone = ProfileInfo("phone", "Téléphone")
User.profile_occupation = ProfileInfo("occupation", "Occupation")
User.profile_departement = ProfileInfo("departement", "Departement")
@ -163,7 +140,6 @@ class UserProfileAdmin(UserAdmin):
is_cof.boolean = True
list_display = UserAdmin.list_display + (
"profile_login_clipper",
"profile_phone",
"profile_occupation",
"profile_mailing_cof",

View file

@ -1 +0,0 @@
default_app_config = "gestioncof.cms.apps.COFCMSAppConfig"

View file

@ -13,7 +13,6 @@ import gestioncof.cms.models
class Migration(migrations.Migration):
initial = True
dependencies = [

View file

@ -4,7 +4,6 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [("cofcms", "0001_initial")]
operations = [

View file

@ -6,7 +6,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("cofcms", "0002_auto_20190523_1521"),
]

View file

@ -6,7 +6,6 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("cofcms", "0003_directory_entry_optional_links"),
]

View file

@ -16,7 +16,7 @@
<link rel="stylesheet" type="text/css" href="{% static "fonts/SourceSansPro/sourceSansPro.css" %}"/>
<link rel="stylesheet" type="text/css" href="{% static "cofcms/css/screen.css" %}"/>
{% block extra_head %}{% endblock %}
<meta name="viewport" content="width=device-width, initial-scale=1.0; minimum-scale=1.0;">
</head>
@ -32,27 +32,27 @@
<section class="bottom-menu">
<nav>
{% flat_menu "cof-nav-int" template="cofcms/base_nav.html" apply_active_classes=True %}
{% get_current_language as curlang %}
<div class="lang-select">
{% get_current_language as curlang %}
<div class="lang-select">
{% if curlang == 'en' %}
{% language 'fr' %}
<a href="{% pageurl self %}" title="Français"><img src="{% static "cofcms/images/fr.png" %}"></a>
{% endlanguage %}
{% language 'fr' %}
<a href="{% pageurl self %}" title="Français"><img src="{% static "cofcms/images/fr.png" %}"></a>
{% endlanguage %}
{% else %}
{% language 'en' %}
<a href="{% pageurl self %}" title="English"><img src="{% static "cofcms/images/en.png" %}"></a>
{% language 'en' %}
<a href="{% pageurl self %}" title="English"><img src="{% static "cofcms/images/en.png" %}"></a>
{% endlanguage %}
{% endif %}
</div>
</div>
</nav>
</section>
</header>
<div class="container">
{% block superaside %}{% endblock %}
<div class="content">
{% block content %}{% endblock %}
</div>

View file

@ -17,17 +17,17 @@
{% block content %}
<section class="intro">
<h1>{{ page.title }}</h1>
<div>{{ page.introduction|safe }}</div>
<div>{{ page.introduction|richtext }}</div>
</section>
<section class="actulist">
{% if actus.has_previous %}
<a class="block prev-actus" href="?page={{ actus.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus récentes" %}</a>
{% endif %}
<a class="block prev-actus" href="?page={{ actus.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus récentes" %}</a>
{% endif %}
{% if actus.has_next %}
<a class="block next-actus" href="?page={{ actus.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus anciennes" %}</a>
{% endif %}
<a class="block next-actus" href="?page={{ actus.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus anciennes" %}</a>
{% endif %}
{% for actu in page.actus %}
<article class="actu">
<div class="actu-image" {% if actu.image %}{% image actu.image fill-400x200 as img %}style="background-image:url('{{ img.url }}');"{% endif %}></div>
@ -36,7 +36,7 @@
{% if actu.is_event %}
<p><span class="actu-dates">{{ actu|dates|capfirst }}</span><br />{{ actu.chapo }}</p>
{% else %}
{{ actu.body|safe|truncatewords_html:15 }}
{{ actu.body|richtext|truncatewords_html:15 }}
{% endif %}
<a href="{% pageurl actu %}">{% trans "Lire plus" %} &gt;</a>
</div>
@ -44,10 +44,10 @@
{% endfor %}
{% if actus.has_previous %}
<a class="block prev-actus" href="?page={{ actus.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus récentes" %}</a>
{% endif %}
<a class="block prev-actus" href="?page={{ actus.previous_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus récentes" %}</a>
{% endif %}
{% if actus.has_next %}
<a class="block next-actus" href="?page={{ actus.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus anciennes" %}</a>
{% endif %}
<a class="block next-actus" href="?page={{ actus.next_page_number }}{% for key,value in request.GET.items %}{% ifnotequal key 'page' %}&amp;{{ key }}={{ value }}{% endifnotequal %}{% endfor %}">{% trans "Actualités plus anciennes" %}</a>
{% endif %}
</section>
{% endblock %}

Some files were not shown because too many files have changed in this diff Show more