Compare commits

...

79 commits

Author SHA1 Message Date
Martin Pépin ac4dc0c192 tmp 2017-07-23 19:57:18 +01:00
Martin Pépin 75bfe98006 Add the COF registration view 2017-06-23 00:10:46 +01:00
Martin Pépin 0f491ef396 Generic registration view 2017-06-23 00:10:38 +01:00
Martin Pépin f93a68b942 Remove the old user registration material 2017-06-23 00:10:38 +01:00
Martin Pépin 8a346bf834 Reformat code in 79 columns 2017-04-01 18:29:36 +01:00
Aurélien Delobelle 95b96d470f Merge branch 'Kerl/1_11_urls' into 'supportBDS'
Properly include ddt's urls using `include`

See merge request !190
2017-03-26 15:41:12 +02:00
Martin Pepin 33dedc7474 Merge branch 'aureplop/1_11/fix_querysets' into 'supportBDS'
Aureplop/1 11/fix querysets

See merge request !183
2017-03-19 16:16:05 +01:00
Martin Pépin 1a107be4ba Properly include ddt's urls using include 2017-03-18 19:14:51 +00:00
Aurélien Delobelle e2c4214efc fix history kpsul view 2017-02-25 01:36:53 +01:00
Aurélien Delobelle a98c6b233e fix checkout data error on k-psul 2017-02-25 01:30:26 +01:00
Qwann e1713a1d4f Merge branch 'Kerl/datetime_warnings' into supportBDS 2017-02-24 15:02:27 +01:00
Qwann 9c6f5533ec Merge branch 'supportBDS' of git.eleves.ens.fr:cof-geek/gestioCOF into supportBDS 2017-02-23 19:00:58 +01:00
Qwann 486d3c4ced Merge branch 'Kerl/fix_autocomplete' into supportBDS 2017-02-23 18:53:55 +01:00
Martin Pépin 80f1514d39 handle timezones in petits_cours_views 2017-02-23 18:35:38 +01:00
Martin Pépin 1663a03a33 Use timezones everywhere in migrations 2017-02-23 18:33:44 +01:00
Martin Pepin 0e4cfc5121 Merge branch 'Kerl/django111-packages' into 'supportBDS'
Upgrade to Django 1.11

- We upgrade our django packages to 1.11 (beta 1)
- We apply some necessary changes in the settings file
- We prepare to upgrade Django-autocomplete-light
- We upgrade some other packages

See merge request !179
2017-02-23 17:58:28 +01:00
Martin Pépin 856faf2b73 Merge branch 'supportBDS' into Kerl/django111-packages 2017-02-23 17:56:12 +01:00
Martin Pepin 646b213d97 Merge branch 'Kerl/django111-urls' into 'supportBDS'
Write modern-style urls

- Proper use of include
- Defining namespaces (I do not use them for now because many urls are
  going to change)
- Do not try to reverse with old-style references: 'cof.views.XXX'

See merge request !178
2017-02-23 17:32:05 +01:00
Martin Pepin cc25685aa3 Merge branch 'Kerl/bds_groups' into 'supportBDS'
BDS groups and permissions

Creates groups and permissions for the BDS members and staff.

Fixes #136 

See merge request !176
2017-02-23 12:58:44 +01:00
Martin Pépin 5ce4809f06 Merge branch 'supportBDS' into Kerl/bds_groups 2017-02-23 12:58:10 +01:00
Martin Pepin 4d825b485d Merge branch 'Kerl/clubs_support' into 'supportBDS'
Kerl/clubs support

- Add the club-related models
- Register them into the admin site in order to be able to play with them

See #133 

See merge request !175
2017-02-23 12:46:27 +01:00
Martin Pépin 7988fb24a0 Merge branch 'supportBDS' into Kerl/clubs_support 2017-02-23 12:35:37 +01:00
Martin Pepin 4b4d570e07 Merge branch 'Kerl/fix_generic_team_ath' into 'supportBDS'
Change CofProfile to Profile in kfet/backends.py

- K-Fêt accounts are now linked to profiles
- There is no need to perform the `get_or_create` as long as the profile
  creation has been automated.
- This file is now PEP8 compliant

See merge request !180
2017-02-23 12:31:55 +01:00
Martin Pépin 83e73376ad Change CofProfile to Profile in kfet/backends.py
- K-Fêt accounts are now linked to profiles
- There is no need to perform the `get_or_create` as long as the profile
  creation has been automated.
- This file is now PEP8 compliant
2017-02-23 12:04:33 +01:00
Martin Pépin 7742ad999f Typo in url reverse name
`liste_bda_diff` -> `liste_bdadiff`
2017-02-23 11:05:53 +01:00
Martin Pepin 6444ae3b92 Merge branch 'Kerl/django111-models' into 'supportBDS'
Specify `on_delete`

Two kind of files are affected: 
- Models
- Migrations

You can use the `-Wall` flag to check that the warning `RemovedInDjango20Warning: on_delete…` is not raised:

    python -Wall manage.py runserver 0.0.0.0:8000

See merge request !177
2017-02-23 11:04:26 +01:00
Martin Pépin 213c11721e Prevent petits cours demandes deletion 2017-02-23 11:03:28 +01:00
Martin Pépin 7d1c1fc868 Specify the on_delete strategy
- Remove an absurd debug line in the migration
- Specify the on_delete strategy for the club-related models
2017-02-23 10:56:36 +01:00
Martin Pépin 6c34742cc4 Remove an erroneous RegistrationUserForm
This form appeared twice in `cof/forms.py` and the second occurrence
(which was used by the views) was erroneous.
2017-02-23 10:36:25 +01:00
Martin Pépin 7abcf28666 Move the registration_form template 2017-02-23 10:35:46 +01:00
Martin Pépin 3f52af8ca0 Upgrade requirements
- Upgrade some dependencies
- We do not specify the version for some packages: we use them in a very
  simple way so we may not be affected by upgrades.
2017-02-23 02:03:15 +01:00
Martin Pépin 6bf16441e6 Drop old context processors
Some context processors disappear in Django 1.11, we have to drop them
2017-02-23 02:02:22 +01:00
Martin Pépin 69f748acbd Django1.11-style MiddleWares
The design of middlewares has changed in Django 1.11
2017-02-23 02:00:34 +01:00
Martin Pépin 8b905f66dc Remove dependencies of an old version of dal
Django-autocomplete-light does not support the `modelform_factory`
anymore in recent versions. We are actually using an old version of dal
because of this.

This had to be dropped at some point… So now is a good time
2017-02-23 01:57:50 +01:00
Martin Pépin e1bab7e4ed Use the AppConfig class 2017-02-23 01:56:59 +01:00
Martin Pépin 68c0ff559d Drop Grappelli
It's ugly and does not really improve the admin site
2017-02-23 01:55:43 +01:00
Martin Pépin 2dcc17298a Use Django 1.11 (beta 1)
Starting to use Django 1.11.
The final version will be released before we push this to production.
2017-02-23 01:55:26 +01:00
Martin Pépin 1aed36330f Write modern-style urls
- Proper use of include
- Defining namespaces (I do not use them for now because many urls are
  going to change)
- Do not try to reverse with old-style references: 'cof.views.XXX'
2017-02-23 01:52:55 +01:00
Martin Pépin 9f401b66e9 Specify the on_delete attribute everywhere
- Models
- Migrations
2017-02-23 01:40:25 +01:00
Martin Pépin c81b849785 Prevent conflicts in COF perm migration
There may be a conflict during the migration cof 0009 if the permissions
are referenced only by their codename.
2017-02-22 18:21:23 +01:00
Martin Pépin d36d69238d Add groups and permissions for BDS staff & members 2017-02-22 18:19:49 +01:00
Martin Pépin f8a8465630 Remove useless imports 2017-02-22 15:23:37 +01:00
Martin Pépin 5632cdaa22 Uses the cof_members groups in kfet's autocomplete
The is_cof attribute cannot be used in database queries anymore
2017-02-22 15:03:34 +01:00
Martin Pépin 68b38228a9 Apply the new db structure to autocomplete in cof
- The autocompletion feature works again
- The template is a bit more readable (indentation)
- The `options` variable in the template is no longer a integer but a
  boolean.
2017-02-22 14:49:34 +01:00
Martin Pépin 1f85f75896 Include the Clubs into the admin site 2017-02-20 01:16:50 +01:00
Martin Pépin 669129e30d Move the club model to the gestion app
- Move the model
- Add some BDS-related fields
- Add an `associations` fields to be able to separate the clubs between
  the different associations using groups
2017-02-20 01:12:06 +01:00
Martin Pépin 859f191894 Simpler admin interface 2017-02-18 19:06:43 +01:00
Martin Pépin 52bdd9824a Merge branch 'supportBDS' of git.eleves.ens.fr:michele.orru/gestioCOF into michele 2017-02-18 13:00:21 +01:00
Martin Pépin d7a13229ad Fix CI config
- The setting file has moved to `gestioCOF/`
2017-02-13 13:41:34 +01:00
Martin Pépin 7f5132961f Add the cof_members group
GestioCOF cannot run without it.
There is no permission associated to it: this has to been thought about
2017-02-12 19:49:30 +01:00
Martin Pépin 659c6e720a Merge branch 'master' into supportBDS 2017-02-12 19:36:17 +01:00
Martin Pépin e1a8c0e8dd Add missing files 2017-02-12 19:21:53 +01:00
Martin Pépin 1d7499d3b2 simplify profile edition and test it 2017-02-12 19:21:53 +01:00
Martin Pépin 0420839b20 Test the authentication
- An "outsider" must use django's authentication backend
- A user with a login_clipper should use CAS
2017-02-12 15:38:20 +01:00
Martin Pépin 8b620a5319 PEP8 in gestion/tests.py 2017-02-12 15:38:20 +01:00
Martin Pépin a28c00e474 Move the auth stuff to gestion/
- The login views are in `gestion/`
- The templates are under `gestion/templates/gestion/`
- `cof/shared.py` moves to `gestion/` and is splitted into 3 files:
    - The auth backends are in `backends.py`.
    - The context_processor is in `context_processor.py`
    - The LOCK/UNLOCK functions remain in `shared.py`
2017-02-12 15:38:14 +01:00
Martin Pépin 50b667993f Merge branch 'master' into supportBDS
- Mise en page
- Cleanup des petits cours
- Utilisation de custommail
- Utilisation du ldap du SPI pour fetch les nouveaux comptes
2017-02-12 04:26:43 +01:00
Michele Orrù 94937fc7cd Add groups cof_members and cof_buro.
- remove is_buro from the database in the same way we did for is_cof
- make a decent migration that *SHOULD* take into account is_cof for old
  databases. note, this has been tested only through unittests.
- make unittests pass again accordin=gly fixing views.

Note: we should make a method for filtering with specific group members,
something like
map(lambda x: x.profile.cof, filter… group…)
2017-02-11 23:05:51 +01:00
Qwann b5037329dd small fixes + migration
enable admin interface for bds
2017-02-11 20:36:16 +01:00
Qwann d46ab87e9b Merge branch 'michele.orru/gestioCOF-supportBDS' into supportBDS 2017-02-11 20:17:23 +01:00
Qwann f53ced6a33 Merge branch 'supportBDS' into michele.orru/gestioCOF-supportBDS 2017-02-11 19:21:23 +01:00
Michele Orrù ee1f29b17d Make is_cof a property and start developing permissions.
Rmeove the is_cof flag to check permission and start implementing
a group and a permission for the respective cof members.
XXX. note: migrations do NOT add old is_cof members to the new group
(as actually they're just on the tests…)
2017-02-11 18:48:13 +01:00
Qwann b9ed7320ec Fix user registration 2017-02-11 18:41:47 +01:00
Qwann fcf392f40d Merge remote-tracking branch 'origin/tmp' into michele.orru/gestioCOF-supportBDS 2017-02-11 18:02:05 +01:00
Martin Pépin 3365d7b9a1 Updates the decorators 2017-02-11 18:00:01 +01:00
Qwann b16219f8ee fixing profile view 2017-02-11 17:57:37 +01:00
Martin Pépin 6c3e1bd2db Fix the loaddevdata script 2017-02-11 17:18:42 +01:00
Michele Orrù a2b8dee022 Fix #134.
Fill bds.models with the required fields; add migration scripts, and a stupid
unittests that checks the model really works.
Note: old fields will migrate to datetime.now().
2017-02-11 17:13:48 +01:00
Michele Orrù f0c3def935 Make the test really works.
This fixes the proble with debug_toolbar,
the fucking toolbar that messes all your tests.
2017-02-11 15:47:31 +01:00
Michele Orrù 376e829502 Reaching a point where I can query /k-fet.
Edit forms and views in app kfet to make the depend on gestion.Profile and not
on cof.CofProfile.
2017-02-11 15:07:45 +01:00
Michele Orrù f50ef1d51a Merge remote-tracking branch 'origin/supportBDS-fixes1' into supportBDS 2017-02-11 14:26:55 +01:00
Martin Pépin b639c04549 Fix the registration forms
- The former `RegistrationUserProfileForm` is splitted in two.
- There is a new form: `RegistrationCofProfileForm`
2017-02-11 12:42:36 +01:00
Martin Pépin b1cf96d0ae Move profile editing to gestion 2017-02-11 01:43:17 +00:00
Michele Orrù 815a5f274c Fix some reviewing considerations.
- appropriate naming for migration
- remove __future__ imports.
- remove "CofProfile" left in kfet/models.py
2017-02-11 00:33:46 +01:00
Michele Orrù 25c3106168 Add some tests about how profiles types should relate to each other. 2017-02-11 00:33:36 +01:00
Michele Orrù 22da04c3e2 s/cofprofile/profile/g into k-fêt.
This commit also restores the only unittest present.
2017-02-11 00:32:58 +01:00
Martin Pépin 58d708b791 Move profile editing to gestion 2017-02-10 23:50:19 +01:00
Ubuntu f39d1545f0 Generic profiles and migrations.
Creating profiles for BDS, COF and K-Fêt.
2017-02-10 22:12:03 +01:00
Martin Pépin 5aff771d9c Set the new structure of gestioCOF
- `cof` is renamed `gestioCOF`
- `gestioncof` become `cof` (yes it looks pretty stupid but it is not)
- `bds` is created
2017-02-09 21:28:36 +01:00
175 changed files with 2390 additions and 1727 deletions

View file

@ -4,7 +4,7 @@ services:
variables:
# GestioCOF settings
DJANGO_SETTINGS_MODULE: "cof.settings_dev"
DJANGO_SETTINGS_MODULE: "gestioCOF.settings_dev"
DBNAME: "cof_gestion"
DBUSER: "cof_gestion"
DBPASSWD: "cof_password"

View file

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
import autocomplete_light
from datetime import timedelta
from custommail.shortcuts import send_mass_custom_mail
@ -119,8 +118,6 @@ class AttributionAdmin(admin.ModelAdmin):
class ChoixSpectacleAdmin(admin.ModelAdmin):
form = autocomplete_light.modelform_factory(ChoixSpectacle, exclude=[])
def tirage(self, obj):
return obj.participant.tirage
list_display = ("participant", "tirage", "spectacle", "priority",

6
bda/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class BdAConfig(AppConfig):
name = "bda"
verbose_name = "Gestion des tirages du BdA"

View file

@ -1,18 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import autocomplete_light
from bda.models import Participant, Spectacle
autocomplete_light.register(
Participant, search_fields=('user__username', 'user__first_name',
'user__last_name'),
autocomplete_js_attributes={'placeholder': 'participant...'})
autocomplete_light.register(
Spectacle, search_fields=('title', ),
autocomplete_js_attributes={'placeholder': 'spectacle...'})

View file

@ -6,9 +6,9 @@ import os
import random
from django.utils import timezone
from django.contrib.auth.models import User
from django.contrib.auth.models import Group
from gestioncof.management.base import MyBaseCommand
from cof.management.base import MyBaseCommand
from bda.models import Tirage, Spectacle, Salle, Participant, ChoixSpectacle
from bda.views import do_tirage
@ -77,7 +77,8 @@ class Command(MyBaseCommand):
self.stdout.write("Inscription des utilisateurs aux tirages")
ChoixSpectacle.objects.all().delete()
choices = []
for user in User.objects.filter(profile__is_cof=True):
cof_members = Group.objects.get(name="cof_members")
for user in cof_members.user_set.all():
for tirage in tirages:
part, _ = Participant.objects.get_or_create(
user=user,

View file

@ -59,7 +59,9 @@ class Migration(migrations.Migration):
('price', models.FloatField(verbose_name=b"Prix d'une place", blank=True)),
('slots', models.IntegerField(verbose_name=b'Places')),
('priority', models.IntegerField(default=1000, verbose_name=b'Priorit\xc3\xa9')),
('location', models.ForeignKey(to='bda.Salle')),
('location', models.ForeignKey(
on_delete=models.CASCADE,
to='bda.Salle')),
],
options={
'ordering': ('priority', 'date', 'title'),
@ -79,27 +81,39 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='participant',
name='user',
field=models.OneToOneField(to=settings.AUTH_USER_MODEL),
field=models.OneToOneField(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='choixspectacle',
name='participant',
field=models.ForeignKey(to='bda.Participant'),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='bda.Participant'),
),
migrations.AddField(
model_name='choixspectacle',
name='spectacle',
field=models.ForeignKey(related_name='participants', to='bda.Spectacle'),
field=models.ForeignKey(
on_delete=models.CASCADE,
related_name='participants',
to='bda.Spectacle'),
),
migrations.AddField(
model_name='attribution',
name='participant',
field=models.ForeignKey(to='bda.Participant'),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='bda.Participant'),
),
migrations.AddField(
model_name='attribution',
name='spectacle',
field=models.ForeignKey(related_name='attribues', to='bda.Spectacle'),
field=models.ForeignKey(
related_name='attribues',
on_delete=models.CASCADE,
to='bda.Spectacle'),
),
migrations.AlterUniqueTogether(
name='choixspectacle',

View file

@ -39,18 +39,26 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='participant',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='participant',
name='tirage',
field=models.ForeignKey(default=1, to='bda.Tirage'),
field=models.ForeignKey(
on_delete=models.CASCADE,
default=1,
to='bda.Tirage'),
preserve_default=False,
),
migrations.AddField(
model_name='spectacle',
name='tirage',
field=models.ForeignKey(default=1, to='bda.Tirage'),
field=models.ForeignKey(
on_delete=models.CASCADE,
default=1,
to='bda.Tirage'),
preserve_default=False,
),
]

View file

@ -72,8 +72,11 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='spectacle',
name='category',
field=models.ForeignKey(blank=True, to='bda.CategorieSpectacle',
null=True),
field=models.ForeignKey(
on_delete=models.CASCADE,
blank=True,
to='bda.CategorieSpectacle',
null=True),
),
migrations.AddField(
model_name='spectacle',
@ -84,6 +87,8 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='quote',
name='spectacle',
field=models.ForeignKey(to='bda.Spectacle'),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='bda.Spectacle'),
),
]

View file

@ -46,21 +46,28 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='spectaclerevente',
name='attribution',
field=models.OneToOneField(to='bda.Attribution',
related_name='revente'),
field=models.OneToOneField(
to='bda.Attribution',
on_delete=models.CASCADE,
related_name='revente'),
),
migrations.AddField(
model_name='spectaclerevente',
name='seller',
field=models.ForeignKey(to='bda.Participant',
verbose_name='Vendeur',
related_name='original_shows'),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='bda.Participant',
verbose_name='Vendeur',
related_name='original_shows'),
),
migrations.AddField(
model_name='spectaclerevente',
name='soldTo',
field=models.ForeignKey(to='bda.Participant',
verbose_name='Vendue à', null=True,
blank=True),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='bda.Participant',
verbose_name='Vendue à',
null=True,
blank=True),
),
]

View file

@ -46,9 +46,14 @@ class CategorieSpectacle(models.Model):
class Spectacle(models.Model):
title = models.CharField("Titre", max_length=300)
category = models.ForeignKey(CategorieSpectacle, blank=True, null=True)
category = models.ForeignKey(
CategorieSpectacle,
on_delete=models.CASCADE,
blank=True,
null=True
)
date = models.DateTimeField("Date & heure")
location = models.ForeignKey(Salle)
location = models.ForeignKey(Salle, on_delete=models.CASCADE)
vips = models.TextField('Personnalités', blank=True)
description = models.TextField("Description", blank=True)
slots_description = models.TextField("Description des places", blank=True)
@ -58,7 +63,7 @@ class Spectacle(models.Model):
max_length=500)
price = models.FloatField("Prix d'une place")
slots = models.IntegerField("Places")
tirage = models.ForeignKey(Tirage)
tirage = models.ForeignKey(Tirage, on_delete=models.CASCADE)
listing = models.BooleanField("Les places sont sur listing")
rappel_sent = models.DateTimeField("Mail de rappel envoyé", blank=True,
null=True)
@ -116,7 +121,7 @@ class Spectacle(models.Model):
class Quote(models.Model):
spectacle = models.ForeignKey(Spectacle)
spectacle = models.ForeignKey(Spectacle, on_delete=models.CASCADE)
text = models.TextField('Citation')
author = models.CharField('Auteur', max_length=200)
@ -130,7 +135,7 @@ PAYMENT_TYPES = (
class Participant(models.Model):
user = models.ForeignKey(User)
user = models.ForeignKey(User, on_delete=models.CASCADE)
choices = models.ManyToManyField(Spectacle,
through="ChoixSpectacle",
related_name="chosen_by")
@ -141,7 +146,7 @@ class Participant(models.Model):
paymenttype = models.CharField("Moyen de paiement",
max_length=6, choices=PAYMENT_TYPES,
blank=True)
tirage = models.ForeignKey(Tirage)
tirage = models.ForeignKey(Tirage, on_delete=models.CASCADE)
choicesrevente = models.ManyToManyField(Spectacle,
related_name="subscribed",
blank=True)
@ -157,8 +162,15 @@ DOUBLE_CHOICES = (
class ChoixSpectacle(models.Model):
participant = models.ForeignKey(Participant)
spectacle = models.ForeignKey(Spectacle, related_name="participants")
participant = models.ForeignKey(
Participant,
on_delete=models.CASCADE
)
spectacle = models.ForeignKey(
Spectacle,
on_delete=models.CASCADE,
related_name="participants"
)
priority = models.PositiveIntegerField("Priorité")
double_choice = models.CharField("Nombre de places",
default="1", choices=DOUBLE_CHOICES,
@ -185,8 +197,15 @@ class ChoixSpectacle(models.Model):
class Attribution(models.Model):
participant = models.ForeignKey(Participant)
spectacle = models.ForeignKey(Spectacle, related_name="attribues")
participant = models.ForeignKey(
Participant,
on_delete=models.CASCADE
)
spectacle = models.ForeignKey(
Spectacle,
on_delete=models.CASCADE,
related_name="attribues"
)
given = models.BooleanField("Donnée", default=False)
def __str__(self):
@ -195,19 +214,29 @@ class Attribution(models.Model):
class SpectacleRevente(models.Model):
attribution = models.OneToOneField(Attribution,
related_name="revente")
attribution = models.OneToOneField(
Attribution,
on_delete=models.CASCADE,
related_name="revente"
)
date = models.DateTimeField("Date de mise en vente",
default=timezone.now)
answered_mail = models.ManyToManyField(Participant,
related_name="wanted",
blank=True)
seller = models.ForeignKey(Participant,
related_name="original_shows",
verbose_name="Vendeur")
soldTo = models.ForeignKey(Participant, blank=True, null=True,
verbose_name="Vendue à")
seller = models.ForeignKey(
Participant,
on_delete=models.CASCADE,
related_name="original_shows",
verbose_name="Vendeur"
)
soldTo = models.ForeignKey(
Participant,
on_delete=models.CASCADE,
blank=True,
null=True,
verbose_name="Vendue à"
)
notif_sent = models.BooleanField("Notification envoyée",
default=False)
tirage_done = models.BooleanField("Tirage effectué",

View file

@ -16,7 +16,7 @@
<h4 class="bda-prix">Total à payer : {{ total|floatformat }}€</h4>
<br/>
<p>Ne manque pas un spectacle avec le
<a href="{% url "gestioncof.views.calendar" %}">calendrier
<a href="{% url "calendar" %}">calendrier
automatique&#8239;!</a></p>
{% else %}
<h3>Vous n'avez aucune place :(</h3>

View file

@ -5,7 +5,7 @@ from __future__ import print_function
from __future__ import unicode_literals
from django.conf.urls import url
from gestioncof.decorators import buro_required
from cof.decorators import buro_required
from bda.views import SpectacleListView
from bda import views

View file

@ -21,7 +21,7 @@ from django.conf import settings
from django.utils import timezone, formats
from django.views.generic.list import ListView
from gestioncof.decorators import cof_required, buro_required
from cof.decorators import cof_required, buro_required
from bda.models import Spectacle, Participant, ChoixSpectacle, Attribution,\
Tirage, SpectacleRevente
from bda.algorithm import Algorithm

4
bds/admin.py Normal file
View file

@ -0,0 +1,4 @@
from django.contrib import admin
from .models import BdsProfile
admin.site.register(BdsProfile)

6
bds/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class BDSConfig(AppConfig):
name = "bds"
verbose_name = "Application de gestion du BDS"

View file

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import bds.models
class Migration(migrations.Migration):
dependencies = [
('gestion', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='BdsProfile',
fields=[
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
('ASPSL_number', models.CharField(null=True, blank=True, verbose_name='Numéro AS PSL', max_length=50)),
('FFSU_number', models.CharField(null=True, blank=True, verbose_name='Numéro FFSU', max_length=50)),
('have_certificate', models.BooleanField(verbose_name='Certificat médical', default=False)),
('certificate_file', models.FileField(blank=True, upload_to=bds.models.BdsProfile.issue_file_name, verbose_name='Fichier de certificat médical')),
('cotisation_period', models.CharField(choices=[('ANN', 'Année'), ('SE1', 'Premier semestre'), ('SE2', 'Deuxième semestre')], verbose_name='Inscription', max_length=3, default='ANN')),
('registration_date', models.DateField(verbose_name="Date d'inscription", auto_now_add=True)),
('payment_method', models.CharField(choices=[('CASH', 'Liquide'), ('BANK', 'Transfer bancaire'), ('CHEQUE', 'Cheque'), ('OTHER', 'Autre')], verbose_name='Methode de paiement', max_length=6, default='CASH')),
('profile', models.OneToOneField(
related_name='bds',
on_delete=models.CASCADE,
to='gestion.Profile')),
],
),
]

View file

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def create_groups(apps, schema_editor):
"""
Creates the groups for BDS members and staff
"""
Group = apps.get_model("auth", "Group")
Group.objects.get_or_create(name="bds_members")
Group.objects.get_or_create(name="bds_buro")
class Migration(migrations.Migration):
dependencies = [
('bds', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='bdsprofile',
options={
'permissions': [
('member', 'Is a BDS member'),
('buro', 'Is part of the BDS staff')
],
'verbose_name': 'Profil BDS',
'verbose_name_plural': 'Profils BDS'
},
),
migrations.RunPython(create_groups, migrations.RunPython.noop),
]

65
bds/models.py Normal file
View file

@ -0,0 +1,65 @@
import os.path
from django.utils import timezone
from django.db import models
from gestion.models import Profile
class BdsProfile(models.Model):
profile = models.OneToOneField(Profile,
related_name='bds',
on_delete=models.CASCADE)
def issue_file_name(sportif, filename):
fn, extension = os.path.splitext(filename)
year = timezone.now().year
return "certifs/{!s}-{:d}{:s}".format(sportif, year, extension)
COTIZ_DURATION_CHOICES = (
('ANN', 'Année'),
('SE1', 'Premier semestre'),
('SE2', 'Deuxième semestre'),
)
PAYMENT_METHOD_CHOICES = (
('CASH', 'Liquide'),
('BANK', 'Transfer bancaire'),
('CHEQUE', 'Cheque'),
('OTHER', 'Autre'),
)
ASPSL_number = models.CharField("Numéro AS PSL",
max_length=50,
blank=True,
null=True)
FFSU_number = models.CharField("Numéro FFSU",
max_length=50,
blank=True,
null=True)
have_certificate = models.BooleanField("Certificat médical",
default=False)
certificate_file = models.FileField("Fichier de certificat médical",
upload_to=issue_file_name,
blank=True)
cotisation_period = models.CharField("Inscription",
default="ANN",
choices=COTIZ_DURATION_CHOICES,
max_length=3)
registration_date = models.DateField(auto_now_add=True,
verbose_name="Date d'inscription")
payment_method = models.CharField('Methode de paiement',
default='CASH',
choices=PAYMENT_METHOD_CHOICES,
max_length=6)
class Meta:
verbose_name = "Profil BDS"
verbose_name_plural = "Profils BDS"
permissions = [
("member", "Is a BDS member"),
("buro", "Is part of the BDS staff")
]

12
bds/tests.py Normal file
View file

@ -0,0 +1,12 @@
from django.test import TestCase
from gestion.tests import create_profile
from .models import BdsProfile
class TestBdsProfile(TestCase):
def test_profile(self):
# each bdspofile should have an associated profile
p = create_profile('foo')
bdsp = BdsProfile.objects.create(profile=p)
self.assertEqual(p.bds, bdsp)

3
bds/views.py Normal file
View file

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

145
cof/admin.py Normal file
View file

@ -0,0 +1,145 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from django.core.urlresolvers import reverse
from django.utils.safestring import mark_safe
import django.utils.six as six
from .petits_cours_models import PetitCoursDemande, \
PetitCoursSubject, PetitCoursAbility, PetitCoursAttribution, \
PetitCoursAttributionCounter
from .models import (
SurveyQuestionAnswer, SurveyQuestion, CofProfile, EventOption,
EventOptionChoice, Event, EventCommentField, EventRegistration,
Survey
)
def add_link_field(target_model='', field='', link_text=six.text_type,
desc_text=six.text_type):
def add_link(cls):
reverse_name = target_model or cls.model.__name__.lower()
def link(self, instance):
app_name = instance._meta.app_label
reverse_path = "admin:%s_%s_change" % (app_name, reverse_name)
link_obj = getattr(instance, field, None) or instance
if not link_obj.id:
return ""
url = reverse(reverse_path, args=(link_obj.id,))
return mark_safe("<a href='%s'>%s</a>"
% (url, link_text(link_obj)))
link.allow_tags = True
link.short_description = desc_text(reverse_name + ' link')
cls.link = link
cls.readonly_fields =\
list(getattr(cls, 'readonly_fields', [])) + ['link']
return cls
return add_link
class SurveyQuestionAnswerInline(admin.TabularInline):
model = SurveyQuestionAnswer
@add_link_field(desc_text=lambda x: "Réponses",
link_text=lambda x: "Éditer les réponses")
class SurveyQuestionInline(admin.TabularInline):
model = SurveyQuestion
class SurveyQuestionAdmin(admin.ModelAdmin):
search_fields = ('survey__title', 'answer')
inlines = [
SurveyQuestionAnswerInline,
]
class SurveyAdmin(admin.ModelAdmin):
search_fields = ('title', 'details')
inlines = [
SurveyQuestionInline,
]
class EventOptionChoiceInline(admin.TabularInline):
model = EventOptionChoice
@add_link_field(desc_text=lambda x: "Choix",
link_text=lambda x: "Éditer les choix")
class EventOptionInline(admin.TabularInline):
model = EventOption
class EventCommentFieldInline(admin.TabularInline):
model = EventCommentField
class EventOptionAdmin(admin.ModelAdmin):
search_fields = ('event__title', 'name')
inlines = [
EventOptionChoiceInline,
]
class EventAdmin(admin.ModelAdmin):
search_fields = ('title', 'location', 'description')
inlines = [
EventOptionInline,
EventCommentFieldInline,
]
class EventRegistrationAdmin(admin.ModelAdmin):
list_display = ('__unicode__' if six.PY2 else '__str__', 'event', 'user',
'paid')
list_filter = ('paid',)
search_fields = ('user__username', 'user__first_name', 'user__last_name',
'user__email', 'event__title')
class PetitCoursAbilityAdmin(admin.ModelAdmin):
list_display = ('user', 'matiere', 'niveau', 'agrege')
search_fields = ('user__username', 'user__first_name', 'user__last_name',
'user__email', 'matiere__name', 'niveau')
list_filter = ('matiere', 'niveau', 'agrege')
class PetitCoursAttributionAdmin(admin.ModelAdmin):
list_display = ('user', 'demande', 'matiere', 'rank', )
search_fields = ('user__username', 'matiere__name')
class PetitCoursAttributionCounterAdmin(admin.ModelAdmin):
list_display = ('user', 'matiere', 'count', )
list_filter = ('matiere',)
search_fields = ('user__username', 'user__first_name', 'user__last_name',
'user__email', 'matiere__name')
actions = ['reset', ]
actions_on_bottom = True
def reset(self, request, queryset):
queryset.update(count=0)
reset.short_description = "Remise à zéro du compteur"
class PetitCoursDemandeAdmin(admin.ModelAdmin):
list_display = ('name', 'email', 'agrege_requis', 'niveau', 'created',
'traitee', 'processed')
list_filter = ('traitee', 'niveau')
search_fields = ('name', 'email', 'phone', 'lieu', 'remarques')
admin.site.register(Survey, SurveyAdmin)
admin.site.register(SurveyQuestion, SurveyQuestionAdmin)
admin.site.register(Event, EventAdmin)
admin.site.register(EventOption, EventOptionAdmin)
admin.site.register(CofProfile)
admin.site.register(PetitCoursSubject)
admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin)
admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin)
admin.site.register(PetitCoursAttributionCounter,
PetitCoursAttributionCounterAdmin)
admin.site.register(PetitCoursDemande, PetitCoursDemandeAdmin)
admin.site.register(EventRegistration, EventRegistrationAdmin)

6
cof/apps.py Normal file
View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class COFConfig(AppConfig):
name = "cof"
verbose_name = "Application de gestion du COF"

View file

@ -5,12 +5,10 @@ from ldap3 import Connection
from django import shortcuts
from django.http import Http404
from django.db.models import Q
from django.contrib.auth.models import User
from django.contrib.auth.models import User, Group
from .decorators import buro_required
from django.conf import settings
from gestioncof.models import CofProfile
from gestioncof.decorators import buro_required
class Clipper(object):
def __init__(self, clipper, fullname):
@ -23,22 +21,21 @@ def autocomplete(request):
if "q" not in request.GET:
raise Http404
q = request.GET['q']
data = {
'q': q,
}
data = {'q': q}
cof_members = Group.objects.get(name="cof_members")
queries = {}
bits = q.split()
# Fetching data from User and CofProfile tables
queries['members'] = CofProfile.objects.filter(is_cof=True)
queries['users'] = User.objects.filter(profile__is_cof=False)
# Fetching data from User and Profile tables
queries['members'] = User.objects.filter(groups=cof_members)
queries['users'] = User.objects.exclude(groups=cof_members)
for bit in bits:
queries['members'] = queries['members'].filter(
Q(user__first_name__icontains=bit)
| Q(user__last_name__icontains=bit)
| Q(user__username__icontains=bit)
| Q(login_clipper__icontains=bit))
Q(first_name__icontains=bit)
| Q(last_name__icontains=bit)
| Q(username__icontains=bit)
| Q(profile__login_clipper__icontains=bit))
queries['users'] = queries['users'].filter(
Q(first_name__icontains=bit)
| Q(last_name__icontains=bit)
@ -48,7 +45,8 @@ def autocomplete(request):
# Clearing redundancies
usernames = (
set(queries['members'].values_list('login_clipper', flat='True'))
set(queries['members'].values_list('profile__login_clipper',
flat='True'))
| set(queries['users'].values_list('profile__login_clipper',
flat='True'))
)
@ -57,7 +55,7 @@ def autocomplete(request):
if hasattr(settings, 'LDAP_SERVER_URL'):
# Fetching
ldap_query = '(|{:s})'.format(''.join(
['(cn=*{bit:s}*)(uid=*{bit:s}*)'.format(**{"bit": bit})
['(cn=*{bit:s}*)(uid=*{bit:s}*)'.format(bit=bit)
for bit in bits]
))
with Connection(settings.LDAP_SERVER_URL) as conn:
@ -75,6 +73,6 @@ def autocomplete(request):
# Resulting data
data.update(queries)
data['options'] = sum(len(query) for query in queries)
data['options'] = any(bool(query) for query in queries.values())
return shortcuts.render(request, "autocomplete_user.html", data)
return shortcuts.render(request, "cof/autocomplete_user.html", data)

8
cof/decorators.py Normal file
View file

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from django.contrib.auth.decorators import permission_required
cof_required = permission_required('cof.member')
cof_required_customdenied = permission_required('cof.member',
login_url="cof-denied")
buro_required = permission_required('cof.buro')

View file

@ -6,7 +6,7 @@
"survey_open": true,
"title": "Sort du barde"
},
"model": "gestioncof.survey",
"model": "cof.survey",
"pk": 1
},
{
@ -15,7 +15,7 @@
"survey": 1,
"multi_answers": true
},
"model": "gestioncof.surveyquestion",
"model": "cof.surveyquestion",
"pk": 1
},
{
@ -24,7 +24,7 @@
"survey": 1,
"multi_answers": false
},
"model": "gestioncof.surveyquestion",
"model": "cof.surveyquestion",
"pk": 2
},
{
@ -32,7 +32,7 @@
"answer": "On l'ernestise",
"survey_question": 1
},
"model": "gestioncof.surveyquestionanswer",
"model": "cof.surveyquestionanswer",
"pk": 1
},
{
@ -40,7 +40,7 @@
"answer": "On ligote",
"survey_question": 1
},
"model": "gestioncof.surveyquestionanswer",
"model": "cof.surveyquestionanswer",
"pk": 2
},
{
@ -48,7 +48,7 @@
"answer": "On le prive de banquet",
"survey_question": 1
},
"model": "gestioncof.surveyquestionanswer",
"model": "cof.surveyquestionanswer",
"pk": 3
},
{
@ -56,7 +56,7 @@
"answer": "Oui",
"survey_question": 2
},
"model": "gestioncof.surveyquestionanswer",
"model": "cof.surveyquestionanswer",
"pk": 4
},
{
@ -64,7 +64,7 @@
"answer": "Non",
"survey_question": 2
},
"model": "gestioncof.surveyquestionanswer",
"model": "cof.surveyquestionanswer",
"pk": 5
},
{
@ -78,7 +78,7 @@
"registration_open": true,
"start_date": "2016-09-09T00:00:00Z"
},
"model": "gestioncof.event",
"model": "cof.event",
"pk": 1
},
{
@ -88,7 +88,7 @@
"fieldtype": "text",
"name": "Commentaires"
},
"model": "gestioncof.eventcommentfield",
"model": "cof.eventcommentfield",
"pk": 1
},
{
@ -97,7 +97,7 @@
"event": 1,
"name": "Potion magique"
},
"model": "gestioncof.eventoption",
"model": "cof.eventoption",
"pk": 1
},
{
@ -105,7 +105,7 @@
"event_option": 1,
"value": "Je suis alergique"
},
"model": "gestioncof.eventoptionchoice",
"model": "cof.eventoptionchoice",
"pk": 1
},
{
@ -113,7 +113,7 @@
"event_option": 1,
"value": "J'en veux"
},
"model": "gestioncof.eventoptionchoice",
"model": "cof.eventoptionchoice",
"pk": 2
},
{
@ -121,35 +121,35 @@
"event_option": 1,
"value": "Je suis tomb\u00e9 dans la marmite quand j'\u00e9tais petit"
},
"model": "gestioncof.eventoptionchoice",
"model": "cof.eventoptionchoice",
"pk": 3
},
{
"fields": {
"name": "Bagarre"
},
"model": "gestioncof.petitcourssubject",
"model": "cof.petitcourssubject",
"pk": 1
},
{
"fields": {
"name": "Lancer de menhir"
},
"model": "gestioncof.petitcourssubject",
"model": "cof.petitcourssubject",
"pk": 2
},
{
"fields": {
"name": "Pr\u00e9paration de potions"
},
"model": "gestioncof.petitcourssubject",
"model": "cof.petitcourssubject",
"pk": 3
},
{
"fields": {
"name": "Chant"
},
"model": "gestioncof.petitcourssubject",
"model": "cof.petitcourssubject",
"pk": 4
},
{
@ -171,7 +171,7 @@
"email": "jules.cesar@polytechnique.edu",
"processed": null
},
"model": "gestioncof.petitcoursdemande",
"model": "cof.petitcoursdemande",
"pk": 1
},
{
@ -193,7 +193,7 @@
"email": "jules.cesar@polytechnique.edu",
"processed": null
},
"model": "gestioncof.petitcoursdemande",
"model": "cof.petitcoursdemande",
"pk": 2
}
]

View file

@ -1,24 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
from django.forms.formsets import BaseFormSet, formset_factory
from django.db.models import Max
from django.core.validators import MinLengthValidator
from gestioncof.models import CofProfile, EventCommentValue, \
CalendarSubscription, Club
from gestioncof.widgets import TriStateCheckbox
from gestioncof.shared import lock_table, unlock_table
from django.utils.translation import ugettext_lazy as _
from bda.models import Spectacle
from .models import CofProfile, EventCommentValue, CalendarSubscription
from .widgets import TriStateCheckbox
class EventForm(forms.Form):
def __init__(self, *args, **kwargs):
@ -177,109 +166,23 @@ class EventStatusFilterForm(forms.Form):
yield ("has_paid", None, value)
class UserProfileForm(forms.ModelForm):
first_name = forms.CharField(label=_('Prénom'), max_length=30)
last_name = forms.CharField(label=_('Nom'), max_length=30)
class COFProfileRegistrationForm(forms.ModelForm):
member = forms.BooleanField(
label=_("Membre du COF"),
required=False,
)
def __init__(self, *args, **kw):
super(UserProfileForm, self).__init__(*args, **kw)
self.fields['first_name'].initial = self.instance.user.first_name
self.fields['last_name'].initial = self.instance.user.last_name
def save(self, *args, **kw):
super(UserProfileForm, self).save(*args, **kw)
self.instance.user.first_name = self.cleaned_data.get('first_name')
self.instance.user.last_name = self.cleaned_data.get('last_name')
self.instance.user.save()
def save(self, **kwargs):
super().save()
self.instance.is_cof = True
class Meta:
model = CofProfile
fields = ["first_name", "last_name", "phone", "mailing_cof",
"mailing_bda", "mailing_bda_revente"]
fields = [
"type_cotiz", "mailing", "mailing_bda", "mailing_bda_revente",
]
class RegistrationUserForm(forms.ModelForm):
def __init__(self, *args, **kw):
super(RegistrationUserForm, self).__init__(*args, **kw)
self.fields['username'].help_text = ""
def force_long_username(self):
self.fields['username'].validators = [MinLengthValidator(9)]
class Meta:
model = User
fields = ("username", "first_name", "last_name", "email")
class RegistrationPassUserForm(RegistrationUserForm):
"""
Formulaire pour changer le mot de passe d'un utilisateur.
"""
password1 = forms.CharField(label=_('Mot de passe'),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_('Confirmation du mot de passe'),
widget=forms.PasswordInput)
def clean_password2(self):
pass1 = self.cleaned_data['password1']
pass2 = self.cleaned_data['password2']
if pass1 and pass2:
if pass1 != pass2:
raise forms.ValidationError(_('Mots de passe non identiques.'))
return pass2
def save(self, commit=True, *args, **kwargs):
user = super(RegistrationPassUserForm, self).save(commit, *args,
**kwargs)
user.set_password(self.cleaned_data['password2'])
if commit:
user.save()
return user
class RegistrationProfileForm(forms.ModelForm):
def __init__(self, *args, **kw):
super(RegistrationProfileForm, self).__init__(*args, **kw)
self.fields['mailing_cof'].initial = True
self.fields['mailing_bda'].initial = True
self.fields['mailing_bda_revente'].initial = True
self.fields['num'].widget.attrs['readonly'] = True
self.fields.keyOrder = [
'login_clipper',
'phone',
'occupation',
'departement',
'is_cof',
'num',
'type_cotiz',
'mailing_cof',
'mailing_bda',
'mailing_bda_revente',
'comments'
]
def save(self, *args, **kw):
instance = super(RegistrationProfileForm, self).save(*args, **kw)
if instance.is_cof and not instance.num:
# Generate new number
try:
lock_table(CofProfile)
aggregate = CofProfile.objects.aggregate(Max('num'))
instance.num = aggregate['num__max'] + 1
instance.save()
self.cleaned_data['num'] = instance.num
self.data['num'] = instance.num
finally:
unlock_table(CofProfile)
return instance
class Meta:
model = CofProfile
fields = ("login_clipper", "num", "phone", "occupation",
"departement", "is_cof", "type_cotiz", "mailing_cof",
"mailing_bda", "mailing_bda_revente", "comments")
STATUS_CHOICES = (('no', 'Non'),
('wait', 'Oui mais attente paiement'),
('paid', 'Oui payé'),)
@ -392,14 +295,3 @@ class CalendarForm(forms.ModelForm):
model = CalendarSubscription
fields = ['subscribe_to_events', 'subscribe_to_my_shows',
'other_shows']
class ClubsForm(forms.Form):
"""
Formulaire d'inscription d'un membre à plusieurs clubs du COF.
"""
clubs = forms.ModelMultipleChoiceField(
label="Inscriptions aux clubs du COF",
queryset=Club.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=False)

View file

@ -13,12 +13,14 @@ import random
from django.contrib.auth.models import User
from django.core.management import call_command
from gestioncof.management.base import MyBaseCommand
from gestioncof.petits_cours_models import (
from cof.management.base import MyBaseCommand
from cof.petits_cours_models import (
PetitCoursAbility, PetitCoursSubject, LEVELS_CHOICES,
PetitCoursAttributionCounter
)
from cof.models import CofProfile
# Où sont stockés les fichiers json
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)),
'data')
@ -47,8 +49,10 @@ class Command(MyBaseCommand):
# Gaulois
gaulois = self.from_json('gaulois.json', DATA_DIR, User)
for user in gaulois:
user.profile.is_cof = True
user.profile.save()
cofprofile = CofProfile.objects.create(
profile=user.profile,
)
cofprofile.is_cof = True
# Romains
self.from_json('romains.json', DATA_DIR, User)
@ -65,10 +69,12 @@ class Command(MyBaseCommand):
root.set_password('root')
root.is_staff = True
root.is_superuser = True
root.profile.is_cof = True
root.profile.is_buro = True
root.profile.save()
root.save()
CofProfile.objects.create(
profile=root.profile,
is_cof=True,
is_buro=True
)
# ---
# Petits cours

View file

@ -48,7 +48,10 @@ class Migration(migrations.Migration):
('is_buro', models.BooleanField(default=False, verbose_name=b'Membre du Bur\xc3\xb4')),
('petits_cours_accept', models.BooleanField(default=False, verbose_name=b'Recevoir des petits cours')),
('petits_cours_remarques', models.TextField(default=b'', verbose_name='Remarques et pr\xe9cisions pour les petits cours', blank=True)),
('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)),
('user', models.OneToOneField(
related_name='profile',
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Profil COF',
@ -91,7 +94,10 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=200, verbose_name=b'Champ')),
('fieldtype', models.CharField(default=b'text', max_length=10, verbose_name=b'Type', choices=[(b'text', 'Texte long'), (b'char', 'Texte court')])),
('default', models.TextField(verbose_name=b'Valeur par d\xc3\xa9faut', blank=True)),
('event', models.ForeignKey(related_name='commentfields', to='gestioncof.Event')),
('event', models.ForeignKey(
related_name='commentfields',
on_delete=models.CASCADE,
to='cof.Event')),
],
options={
'verbose_name': 'Champ',
@ -102,7 +108,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('content', models.TextField(null=True, verbose_name=b'Contenu', blank=True)),
('commentfield', models.ForeignKey(related_name='values', to='gestioncof.EventCommentField')),
('commentfield', models.ForeignKey(
related_name='values',
on_delete=models.CASCADE,
to='cof.EventCommentField')),
],
),
migrations.CreateModel(
@ -111,7 +120,10 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=200, verbose_name=b'Option')),
('multi_choices', models.BooleanField(default=False, verbose_name=b'Choix multiples')),
('event', models.ForeignKey(related_name='options', to='gestioncof.Event')),
('event', models.ForeignKey(
related_name='options',
on_delete=models.CASCADE,
to='cof.Event')),
],
options={
'verbose_name': 'Option',
@ -122,7 +134,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('value', models.CharField(max_length=200, verbose_name=b'Valeur')),
('event_option', models.ForeignKey(related_name='choices', to='gestioncof.EventOption')),
('event_option', models.ForeignKey(
related_name='choices',
on_delete=models.CASCADE,
to='cof.EventOption')),
],
options={
'verbose_name': 'Choix',
@ -133,10 +148,14 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('paid', models.BooleanField(default=False, verbose_name=b'A pay\xc3\xa9')),
('event', models.ForeignKey(to='gestioncof.Event')),
('filledcomments', models.ManyToManyField(to='gestioncof.EventCommentField', through='gestioncof.EventCommentValue')),
('options', models.ManyToManyField(to='gestioncof.EventOptionChoice')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
('event', models.ForeignKey(
on_delete=models.CASCADE,
to='cof.Event')),
('filledcomments', models.ManyToManyField(to='cof.EventCommentField', through='cof.EventCommentValue')),
('options', models.ManyToManyField(to='cof.EventOptionChoice')),
('user', models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Inscription',
@ -205,7 +224,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=30, verbose_name='Mati\xe8re')),
('users', models.ManyToManyField(related_name='petits_cours_matieres', through='gestioncof.PetitCoursAbility', to=settings.AUTH_USER_MODEL)),
('users', models.ManyToManyField(related_name='petits_cours_matieres', through='cof.PetitCoursAbility', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Mati\xe8re de petits cours',
@ -240,7 +259,10 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('question', models.CharField(max_length=200, verbose_name=b'Question')),
('multi_answers', models.BooleanField(default=False, verbose_name=b'Choix multiples')),
('survey', models.ForeignKey(related_name='questions', to='gestioncof.Survey')),
('survey', models.ForeignKey(
on_delete=models.CASCADE,
related_name='questions',
to='cof.Survey')),
],
options={
'verbose_name': 'Question',
@ -251,7 +273,10 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('answer', models.CharField(max_length=200, verbose_name=b'R\xc3\xa9ponse')),
('survey_question', models.ForeignKey(related_name='answers', to='gestioncof.SurveyQuestion')),
('survey_question', models.ForeignKey(
related_name='answers',
on_delete=models.CASCADE,
to='cof.SurveyQuestion')),
],
options={
'verbose_name': 'R\xe9ponse',
@ -260,67 +285,96 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='surveyanswer',
name='answers',
field=models.ManyToManyField(related_name='selected_by', to='gestioncof.SurveyQuestionAnswer'),
field=models.ManyToManyField(related_name='selected_by', to='cof.SurveyQuestionAnswer'),
),
migrations.AddField(
model_name='surveyanswer',
name='survey',
field=models.ForeignKey(to='gestioncof.Survey'),
field=models.ForeignKey(
on_delete=models.CASCADE,
to='cof.Survey'),
),
migrations.AddField(
model_name='surveyanswer',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='petitcoursdemande',
name='matieres',
field=models.ManyToManyField(related_name='demandes', verbose_name='Mati\xe8res', to='gestioncof.PetitCoursSubject'),
field=models.ManyToManyField(related_name='demandes', verbose_name='Mati\xe8res', to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursdemande',
name='traitee_par',
field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True),
field=models.ForeignKey(
on_delete=models.PROTECT,
blank=True,
to=settings.AUTH_USER_MODEL,
null=True),
),
migrations.AddField(
model_name='petitcoursattributioncounter',
name='matiere',
field=models.ForeignKey(verbose_name='Matiere', to='gestioncof.PetitCoursSubject'),
field=models.ForeignKey(
on_delete=models.PROTECT,
verbose_name='Matiere',
to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursattributioncounter',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.PROTECT,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='petitcoursattribution',
name='demande',
field=models.ForeignKey(verbose_name='Demande', to='gestioncof.PetitCoursDemande'),
field=models.ForeignKey(
on_delete=models.CASCADE,
verbose_name='Demande',
to='cof.PetitCoursDemande'),
),
migrations.AddField(
model_name='petitcoursattribution',
name='matiere',
field=models.ForeignKey(verbose_name='Mati\xe8re', to='gestioncof.PetitCoursSubject'),
field=models.ForeignKey(
on_delete=models.PROTECT,
verbose_name='Mati\xe8re',
to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursattribution',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='petitcoursability',
name='matiere',
field=models.ForeignKey(verbose_name='Mati\xe8re', to='gestioncof.PetitCoursSubject'),
field=models.ForeignKey(
on_delete=models.CASCADE,
verbose_name='Mati\xe8re',
to='cof.PetitCoursSubject'),
),
migrations.AddField(
model_name='petitcoursability',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
field=models.ForeignKey(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='eventcommentvalue',
name='registration',
field=models.ForeignKey(related_name='comments', to='gestioncof.EventRegistration'),
field=models.ForeignKey(
on_delete=models.CASCADE,
related_name='comments',
to='cof.EventRegistration'),
),
migrations.AlterUniqueTogether(
name='surveyanswer',

View file

@ -7,7 +7,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0001_initial'),
('cof', '0001_initial'),
]
operations = [

View file

@ -7,7 +7,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0002_enable_unprocessed_demandes'),
('cof', '0002_enable_unprocessed_demandes'),
]
operations = [

View file

@ -5,7 +5,7 @@ from django.db import migrations
def create_mail(apps, schema_editor):
CustomMail = apps.get_model("gestioncof", "CustomMail")
CustomMail = apps.get_model("cof", "CustomMail")
db_alias = schema_editor.connection.alias
if CustomMail.objects.filter(shortname="bienvenue").count() == 0:
CustomMail.objects.using(db_alias).bulk_create([
@ -24,7 +24,7 @@ def create_mail(apps, schema_editor):
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0003_event_image'),
('cof', '0003_event_image'),
]
operations = [

View file

@ -7,7 +7,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0004_registration_mail'),
('cof', '0004_registration_mail'),
]
operations = [

View file

@ -10,7 +10,7 @@ class Migration(migrations.Migration):
dependencies = [
('bda', '0004_mails-rappel'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('gestioncof', '0005_encoding'),
('cof', '0005_encoding'),
]
operations = [
@ -23,7 +23,9 @@ class Migration(migrations.Migration):
('subscribe_to_events', models.BooleanField(default=True)),
('subscribe_to_my_shows', models.BooleanField(default=True)),
('other_shows', models.ManyToManyField(to='bda.Spectacle')),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
('user', models.OneToOneField(
on_delete=models.CASCADE,
to=settings.AUTH_USER_MODEL)),
],
),
migrations.AlterModelOptions(

View file

@ -8,7 +8,7 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0006_add_calendar'),
('cof', '0006_add_calendar'),
]
operations = [

View file

@ -5,14 +5,14 @@ from django.db import models, migrations
def forwards(apps, schema_editor):
Profile = apps.get_model("gestioncof", "CofProfile")
Profile = apps.get_model("cof", "CofProfile")
Profile.objects.update(comments="")
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0007_alter_club'),
('cof', '0007_alter_club'),
]
operations = [

View file

@ -0,0 +1,131 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib.auth.models import Group
from django.db import migrations, models
def create_profile(apps, schema_editor):
CofProfile = apps.get_model("cof", "CofProfile")
Profile = apps.get_model("gestion", "Profile")
for p in CofProfile.objects.all():
profile = Profile.objects.create(
id=p.id,
user=p.user,
login_clipper=p.login_clipper,
phone=p.phone,
occupation=p.occupation,
departement=p.departement,
comments=p.comments
)
p.profile = profile
p.save()
def preserve_perms(apps, schema_editor):
# from django.contrib.auth.management import create_permissions
# apps.models_module = True
# create_permissions(apps, verbosity=0)
# apps.models_module = None
CofProfile = apps.get_model("cof", "CofProfile")
# memberp = Permission.objects.get(codename='member')
# burop = Permission.objects.get(codename='buro')
# creates the groups for COF members and
member = Group.objects.create(name='cof_members')
buro = Group.objects.create(name='cof_buro')
# associate permissions to the respective groups.
# buro.permissions = [burop, memberp]
# member.permissions = [memberp]
for cofp in CofProfile.objects.filter(is_cof=True):
cofp.profile.user.groups.add(member)
for cofp in CofProfile.objects.filter(is_buro=True):
cofp.profile.user.groups.add(buro)
def remove_profile(apps, schema_editor):
raise NotImplementedError
fuckup_perms = remove_profile
class Migration(migrations.Migration):
dependencies = [
('gestion', '0001_initial'),
('cof', '0008_py3'),
]
operations = [
migrations.RenameField(
model_name='cofprofile',
old_name='mailing_cof',
new_name='mailing',
),
migrations.AddField(
model_name='cofprofile',
name='profile',
field=models.OneToOneField(
on_delete=models.CASCADE,
to='gestion.Profile',
null=True,
related_name='cof'
),
preserve_default=False,
),
migrations.AlterModelOptions(
name='cofprofile',
options={
'permissions': (('member', 'Is a COF member'),
('buro', 'Is part of COF staff')),
'verbose_name': 'Profil COF',
'verbose_name_plural': 'Profils COF'},
),
migrations.RunPython(create_profile, remove_profile),
migrations.AlterField(
model_name='cofprofile',
name='profile',
field=models.OneToOneField(
on_delete=models.CASCADE,
to='gestion.Profile',
related_name='cof'
),
),
migrations.RemoveField(
model_name='cofprofile',
name='comments',
),
migrations.RemoveField(
model_name='cofprofile',
name='departement',
),
migrations.RemoveField(
model_name='cofprofile',
name='login_clipper',
),
migrations.RemoveField(
model_name='cofprofile',
name='occupation',
),
migrations.RemoveField(
model_name='cofprofile',
name='phone',
),
migrations.RunPython(preserve_perms, fuckup_perms),
migrations.RemoveField(
model_name='cofprofile',
name='is_cof',
),
migrations.RemoveField(
model_name='cofprofile',
name='is_buro',
),
migrations.RemoveField(
model_name='cofprofile',
name='user',
),
]

View file

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
def create_cof_group(apps, schema_editor):
Group = apps.get_model("auth", "Group")
Group.objects.get_or_create(name="cof_members")
def create_buro_group(apps, schema_editor):
Group = apps.get_model("auth", "Group")
Group.objects.get_or_create(name="cof_buro")
class Migration(migrations.Migration):
dependencies = [
('cof', '0009_generic_profiles'),
]
operations = [
migrations.RunPython(create_cof_group, migrations.RunPython.noop),
migrations.RunPython(create_buro_group, migrations.RunPython.noop),
]

View file

@ -7,11 +7,14 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('gestioncof', '0008_py3'),
('cof', '0010_create_cof_group'),
]
operations = [
migrations.DeleteModel(
name='Clipper',
),
migrations.DeleteModel(
name='CustomMail',
),
]

View file

@ -0,0 +1,23 @@
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('cof', '0011_delete_clipper_and_custommail'),
('gestion', '0002_club_support')
]
operations = [
migrations.RemoveField(
model_name='club',
name='membres',
),
migrations.RemoveField(
model_name='club',
name='respos',
),
migrations.DeleteModel(
name='Club',
),
]

View file

@ -1,27 +1,15 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.dispatch import receiver
from django.contrib.auth.models import User
from django.contrib.auth.models import Group, User
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import python_2_unicode_compatible
import django.utils.six as six
from django.db.models.signals import post_save, post_delete
from gestioncof.petits_cours_models import choices_length
from gestion.models import Profile
from bda.models import Spectacle
OCCUPATION_CHOICES = (
('exterieur', _("Extérieur")),
('1A', _("1A")),
('2A', _("2A")),
('3A', _("3A")),
('4A', _("4A")),
('archicube', _("Archicube")),
('doctorant', _("Doctorant")),
('CST', _("CST")),
)
from .petits_cours_models import choices_length
TYPE_COTIZ_CHOICES = (
('etudiant', _("Normalien étudiant")),
@ -35,32 +23,23 @@ TYPE_COMMENT_FIELD = (
)
@python_2_unicode_compatible
class CofProfile(models.Model):
user = models.OneToOneField(User, related_name="profile")
login_clipper = models.CharField("Login clipper", max_length=8, blank=True)
is_cof = models.BooleanField("Membre du COF", default=False)
profile = models.OneToOneField(Profile,
on_delete=models.CASCADE,
related_name="cof")
num = models.IntegerField("Numéro d'adhérent", blank=True, default=0)
phone = models.CharField("Téléphone", max_length=20, blank=True)
occupation = models.CharField(_("Occupation"),
default="1A",
choices=OCCUPATION_CHOICES,
max_length=choices_length(
OCCUPATION_CHOICES))
departement = models.CharField(_("Département"), max_length=50,
blank=True)
type_cotiz = models.CharField(_("Type de cotisation"),
default="normalien",
choices=TYPE_COTIZ_CHOICES,
max_length=choices_length(
TYPE_COTIZ_CHOICES))
mailing_cof = models.BooleanField("Recevoir les mails COF", default=False)
mailing = models.BooleanField("Recevoir les mails COF", default=False)
# XXX. remove the following and put in a BDA profile
mailing_bda = models.BooleanField("Recevoir les mails BdA", default=False)
mailing_bda_revente = models.BooleanField(
"Recevoir les mails de revente de places BdA", default=False)
comments = models.TextField(
"Commentaires visibles par l'utilisateur", blank=True)
is_buro = models.BooleanField("Membre du Burô", default=False)
petits_cours_accept = models.BooleanField(
"Recevoir des petits cours", default=False)
petits_cours_remarques = models.TextField(
@ -70,32 +49,34 @@ class CofProfile(models.Model):
class Meta:
verbose_name = "Profil COF"
verbose_name_plural = "Profils COF"
permissions = (
('member', 'Is a COF member'),
('buro', 'Is part of COF staff'),
)
@property
def is_cof(self):
return self.profile.user.has_perm('cof.member')
@is_cof.setter
def is_cof(self, really):
if really:
g = Group.objects.get(name='cof_members')
self.profile.user.groups.add(g)
# XXX. remove the following and use django auth.
@property
def is_buro(self):
return self.profile.user.has_perm('cof.buro')
@is_buro.setter
def is_buro(self, really):
if really:
g = Group.objects.get(name='cof_buro')
self.profile.user.groups.add(g)
def __str__(self):
return six.text_type(self.user.username)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
CofProfile.objects.get_or_create(user=instance)
@receiver(post_delete, sender=CofProfile)
def post_delete_user(sender, instance, *args, **kwargs):
instance.user.delete()
@python_2_unicode_compatible
class Club(models.Model):
name = models.CharField("Nom", max_length=200, unique=True)
description = models.TextField("Description", blank=True)
respos = models.ManyToManyField(User, related_name="clubs_geres",
blank=True)
membres = models.ManyToManyField(User, related_name="clubs", blank=True)
def __str__(self):
return self.name
return self.profile.user.username
@python_2_unicode_compatible
@ -120,7 +101,11 @@ class Event(models.Model):
@python_2_unicode_compatible
class EventCommentField(models.Model):
event = models.ForeignKey(Event, related_name="commentfields")
event = models.ForeignKey(
Event,
on_delete=models.CASCADE,
related_name="commentfields"
)
name = models.CharField("Champ", max_length=200)
fieldtype = models.CharField("Type", max_length=10,
choices=TYPE_COMMENT_FIELD, default="text")
@ -135,9 +120,16 @@ class EventCommentField(models.Model):
@python_2_unicode_compatible
class EventCommentValue(models.Model):
commentfield = models.ForeignKey(EventCommentField, related_name="values")
registration = models.ForeignKey("EventRegistration",
related_name="comments")
commentfield = models.ForeignKey(
EventCommentField,
on_delete=models.CASCADE,
related_name="values"
)
registration = models.ForeignKey(
"EventRegistration",
on_delete=models.CASCADE,
related_name="comments"
)
content = models.TextField("Contenu", blank=True, null=True)
def __str__(self):
@ -146,7 +138,11 @@ class EventCommentValue(models.Model):
@python_2_unicode_compatible
class EventOption(models.Model):
event = models.ForeignKey(Event, related_name="options")
event = models.ForeignKey(
Event,
on_delete=models.CASCADE,
related_name="options"
)
name = models.CharField("Option", max_length=200)
multi_choices = models.BooleanField("Choix multiples", default=False)
@ -159,7 +155,11 @@ class EventOption(models.Model):
@python_2_unicode_compatible
class EventOptionChoice(models.Model):
event_option = models.ForeignKey(EventOption, related_name="choices")
event_option = models.ForeignKey(
EventOption,
on_delete=models.CASCADE,
related_name="choices"
)
value = models.CharField("Valeur", max_length=200)
class Meta:
@ -172,8 +172,14 @@ class EventOptionChoice(models.Model):
@python_2_unicode_compatible
class EventRegistration(models.Model):
user = models.ForeignKey(User)
event = models.ForeignKey(Event)
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
event = models.ForeignKey(
Event,
on_delete=models.CASCADE
)
options = models.ManyToManyField(EventOptionChoice)
filledcomments = models.ManyToManyField(EventCommentField,
through=EventCommentValue)
@ -204,7 +210,11 @@ class Survey(models.Model):
@python_2_unicode_compatible
class SurveyQuestion(models.Model):
survey = models.ForeignKey(Survey, related_name="questions")
survey = models.ForeignKey(
Survey,
on_delete=models.CASCADE,
related_name="questions"
)
question = models.CharField("Question", max_length=200)
multi_answers = models.BooleanField("Choix multiples", default=False)
@ -217,7 +227,11 @@ class SurveyQuestion(models.Model):
@python_2_unicode_compatible
class SurveyQuestionAnswer(models.Model):
survey_question = models.ForeignKey(SurveyQuestion, related_name="answers")
survey_question = models.ForeignKey(
SurveyQuestion,
on_delete=models.CASCADE,
related_name="answers"
)
answer = models.CharField("Réponse", max_length=200)
class Meta:
@ -229,8 +243,14 @@ class SurveyQuestionAnswer(models.Model):
@python_2_unicode_compatible
class SurveyAnswer(models.Model):
user = models.ForeignKey(User)
survey = models.ForeignKey(Survey)
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
survey = models.ForeignKey(
Survey,
on_delete=models.CASCADE
)
answers = models.ManyToManyField(SurveyQuestionAnswer,
related_name="selected_by")
@ -247,7 +267,10 @@ class SurveyAnswer(models.Model):
@python_2_unicode_compatible
class CalendarSubscription(models.Model):
token = models.UUIDField()
user = models.OneToOneField(User)
user = models.OneToOneField(
User,
on_delete=models.CASCADE
)
other_shows = models.ManyToManyField(Spectacle)
subscribe_to_events = models.BooleanField(default=True)
subscribe_to_my_shows = models.BooleanField(default=True)

View file

@ -7,7 +7,7 @@ from django.forms import ModelForm
from django.forms.models import inlineformset_factory, BaseInlineFormSet
from django.contrib.auth.models import User
from gestioncof.petits_cours_models import PetitCoursDemande, PetitCoursAbility
from .petits_cours_models import PetitCoursDemande, PetitCoursAbility
class BaseMatieresFormSet(BaseInlineFormSet):

View file

@ -35,8 +35,15 @@ class PetitCoursSubject(models.Model):
class PetitCoursAbility(models.Model):
user = models.ForeignKey(User)
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière"))
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
matiere = models.ForeignKey(
PetitCoursSubject,
on_delete=models.CASCADE,
verbose_name=_("Matière")
)
niveau = models.CharField(_("Niveau"),
choices=LEVELS_CHOICES,
max_length=choices_length(LEVELS_CHOICES))
@ -84,7 +91,11 @@ class PetitCoursDemande(models.Model):
remarques = models.TextField(_("Remarques et précisions"), blank=True)
traitee = models.BooleanField(_("Traitée"), default=False)
traitee_par = models.ForeignKey(User, blank=True, null=True)
traitee_par = models.ForeignKey(
User,
on_delete=models.CASCADE,
blank=True, null=True
)
processed = models.DateTimeField(_("Date de traitement"),
blank=True, null=True)
created = models.DateTimeField(_("Date de création"), auto_now_add=True)
@ -126,9 +137,20 @@ class PetitCoursDemande(models.Model):
class PetitCoursAttribution(models.Model):
user = models.ForeignKey(User)
demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande"))
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière"))
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
demande = models.ForeignKey(
PetitCoursDemande,
on_delete=models.CASCADE,
verbose_name=_("Demande")
)
matiere = models.ForeignKey(
PetitCoursSubject,
on_delete=models.CASCADE,
verbose_name=_("Matière")
)
date = models.DateTimeField(_("Date d'attribution"), auto_now_add=True)
rank = models.IntegerField("Rang dans l'email")
selected = models.BooleanField(_("Sélectionné par le demandeur"),
@ -145,8 +167,15 @@ class PetitCoursAttribution(models.Model):
class PetitCoursAttributionCounter(models.Model):
user = models.ForeignKey(User)
matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere"))
user = models.ForeignKey(
User,
on_delete=models.CASCADE
)
matiere = models.ForeignKey(
PetitCoursSubject,
on_delete=models.CASCADE,
verbose_name=_("Matiere")
)
count = models.IntegerField("Nombre d'envois", default=0)
@classmethod

View file

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
import json
from datetime import datetime
from custommail.shortcuts import render_custom_mail
from django.shortcuts import render, get_object_or_404, redirect
@ -12,15 +11,17 @@ from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.utils import timezone
from gestioncof.models import CofProfile
from gestioncof.petits_cours_models import (
from .models import CofProfile
from .petits_cours_models import (
PetitCoursDemande, PetitCoursAttribution, PetitCoursAttributionCounter,
PetitCoursAbility, PetitCoursSubject
)
from gestioncof.petits_cours_forms import DemandeForm, MatieresFormSet
from gestioncof.decorators import buro_required
from gestioncof.shared import lock_table, unlock_tables
from .decorators import buro_required
from .petits_cours_forms import DemandeForm, MatieresFormSet
from gestion.shared import lock_table, unlock_tables
class DemandeListView(ListView):
@ -34,7 +35,7 @@ class DemandeListView(ListView):
class DemandeDetailView(DetailView):
model = PetitCoursDemande
template_name = "gestioncof/details_demande_petit_cours.html"
template_name = "cof/details_demande_petit_cours.html"
context_object_name = "demande"
def get_context_data(self, **kwargs):
@ -104,7 +105,7 @@ def _finalize_traitement(request, demande, proposals, proposed_for,
})
for error in errors:
messages.error(request, error)
return render(request, "gestioncof/traitement_demande_petit_cours.html",
return render(request, "cof/traitement_demande_petit_cours.html",
{"demande": demande,
"unsatisfied": unsatisfied,
"proposals": proposals,
@ -278,10 +279,10 @@ def _traitement_post(request, demande):
unlock_tables()
demande.traitee = True
demande.traitee_par = request.user
demande.processed = datetime.now()
demande.processed = timezone.now()
demande.save()
return render(request,
"gestioncof/traitement_demande_petit_cours_success.html",
"cof/traitement_demande_petit_cours_success.html",
{"demande": demande,
"redo": redo,
})

View file

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View file

Before

Width:  |  Height:  |  Size: 438 B

After

Width:  |  Height:  |  Size: 438 B

View file

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 663 B

View file

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 378 B

View file

@ -1,4 +1,4 @@
{% extends "gestioncof/base_header.html" %}
{% extends "cof/base_header.html" %}
{% block interm_content %}
<div class="container hidden-xs espace"></div>

View file

@ -0,0 +1,57 @@
{% load utils %}
<ul>
{% if members %}
<li class="autocomplete-header">Membres du COF</li>
{% for member in members %}
{% if forloop.counter < 5 %}
<li class="autocomplete-value">
<a href="{% url 'cof:registration-form' member.username %}?user_type=normal">
{{ member|highlight_user:q }}
</a>
</li>
{% elif forloop.counter == 5 %}
<li class="autocomplete-more">...</li>
{% endif %}
{% endfor %}
{% endif %}
{% if users %}
<li class="autocomplete-header">Utilisateurs de GestioCOF</li>
{% for user in users %}
{% if forloop.counter < 5 %}
<li class="autocomplete-value">
<a href="{% url 'cof:registration-form' user.username %}?user_type=normal">
{{ user|highlight_user:q }}
</a>
</li>
{% elif forloop.counter == 5 %}
<li class="autocomplete-more">...</li>
{% endif %}
{% endfor %}
{% endif %}
{% if clippers %}
<li class="autocomplete-header">Utilisateurs <tt>clipper</tt></li>
{% for clipper in clippers %}
{% if forloop.counter < 5 %}
<li class="autocomplete-value">
<a href="{% url 'cof:registration-form' clipper.clipper %}?user_type=clipper&?fullname={{ clipper.fullname }}">
{{ clipper|highlight_clipper:q }}
</a>
</li>
{% elif forloop.counter == 5 %}
<li class="autocomplete-more">...</li>
{% endif %}
{% endfor %}
{% endif %}
{% if not options %}
<li class="autocomplete-header">Aucune correspondance trouvée</li>
{% else %}
<li class="autocomplete-header">Pas dans la liste ?</li>
{% endif %}
<li><a href="{% url 'cof:registration-form' "" %}">Créer un compte</a></li>
</ul>

View file

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block content %}
<header>
<div class="container banner">
<a href="{% url "home" %}">
<h1>GestioCOF</h1>
{% block homelink %}
<span class="glyphicon glyphicon-home" aria-hidden=true></span>
{% endblock %}
</a>
<div class="secondary">
<span class="hidden-xxs">&nbsp;&nbsp;|&nbsp; </span>
<span><a href="{% url "gestion:logout" %}">
Se déconnecter&nbsp;<span class="glyphicon glyphicon-log-out"></span>
</a></span>
</div>
<h2 class="member-status">{% if user.first_name %}{{ user.first_name }}{% else %}<tt>{{ user.username }}</tt>{% endif %}, {% if user.profile.is_cof %}<tt class="user-is-cof">au COF{% else %}<tt class="user-is-not-cof">non-COF{% endif %}</tt></h2>
</div><!-- /.container -->
</header>
{% block interm_content %}{% endblock %}
{% endblock %}

View file

@ -12,7 +12,7 @@ souscrire aux événements du COF et/ou aux spectacles BdA.
{% if token %}
<p>Votre calendrier (compatible avec toutes les applications d'agenda) se trouve à
<a href="{% url 'gestioncof.views.calendar_ics' token %}">cette adresse</a>.</p>
<a href="{% url 'calendar.ics' token %}">cette adresse</a>.</p>
<ul>
<li>Pour l'ajouter à Thunderbird (lightning), il faut copier ce lien et aller

View file

@ -2,10 +2,13 @@
{% block realcontent %}
<h2>Événement: {{ event.title }}</h2>
{% if success %}
<p class="success">Votre inscription a bien été enregistrée ! Vous pouvez cependant la modifier jusqu'à la fin des inscriptions.</p>
{% endif %}
{% if event.details %}
<p>{{ event.details }}</p>
{% endif %}
<form method="post" action="{% url 'gestioncof.views.event' event.id %}">
<form method="post" action="{% url 'event' event.id %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn-submit" value="Enregistrer" />

View file

@ -5,10 +5,17 @@
{% block realcontent %}
<h2>Sondage: {{ survey.title }}</h2>
{% if success %}
{% if deleted %}
<p class="success">Votre réponse a bien été supprimée !</p>
{% else %}
<p class="success">Votre réponse a bien été enregistrée ! Vous pouvez cependant la modifier jusqu'à la fin du sondage.</p>
{% endif %}
{% endif %}
{% if survey.details %}
<p>{{ survey.details }}</p>
{% endif %}
<form class="form-horizontal" method="post" action="{% url 'gestioncof.views.survey' survey.id %}">
<form class="form-horizontal" method="post" action="{% url 'survey' survey.id %}">
{% csrf_token %}
{{ form | bootstrap}}

View file

@ -0,0 +1,24 @@
{% extends "base_title.html" %}
{% block homelink %}
{% endblock %}
{% block realcontent %}
<h2>Liens utiles du COF</h2>
<h3>COF</h3>
<ul>
<li><a href="{% url 'export.members' %}">Export des membres du COF</a></li>
<li><a href="{% url 'liste_diffcof' %}">Diffusion COF</a></li>
</ul>
<h3>Mega</h3>
<ul>
<li><a href="{% url 'export.mega.participants' %}">Export des non-orgas uniquement</a></li>
<li><a href="{% url 'export.mega.orgas' %}">Export des orgas uniquement</a></li>
<li><a href="{% url 'export.mega' %}">Export de tout le monde</a></li>
</ul>
<p>Note&nbsp;: pour ouvrir les fichiers .csv avec Excel, il faut
passer par <tt>Fichier &gt; Importer</tt> et sélectionner la
virgule comme séparateur.</p>
{% endblock %}

View file

@ -7,7 +7,7 @@
{% if success %}
<p class="success">Votre demande a été enregistrée avec succès !</p>
{% else %}
<form id="demandecours" method="post" action="{% url "gestioncof.petits_cours_views.demande_raw" %}">
<form id="demandecours" method="post" action="{% url "cof.petits_cours_views.demande_raw" %}">
{% csrf_token %}
<table>
{{ form | bootstrap }}

View file

@ -5,7 +5,7 @@
{% if success %}
<p class="success">Votre demande a été enregistrée avec succès !</p>
{% else %}
<form id="demandecours" method="post" action="{% url "gestioncof.petits_cours_views.demande" %}">
<form id="demandecours" method="post" action="{% url "cof.petits_cours_views.demande" %}">
{% csrf_token %}
<table>
{{ form.as_table }}

View file

@ -4,14 +4,14 @@
{% block page_size %}col-sm-8{% endblock %}
{% block realcontent %}
<h2>Événement: {{ event.title }}{% if user.is_staff %} <a class="title-link" href="{% url 'admin:gestioncof_event_change' event.id %}"><span class="glyphicon glyphicon-link"></span> Administration</a>{% endif %}</h2>
<h2>Événement: {{ event.title }}{% if user.is_staff %} <a class="title-link" href="{% url 'admin:cof_event_change' event.id %}"><span class="glyphicon glyphicon-link"></span> Administration</a>{% endif %}</h2>
{% if event.details %}
<p>{{ event.details }}</p>
<hr/>
{% endif %}
{% include "tristate_js.html" %}
<h3>Filtres</h3>
<form method="post" action="{% url 'gestioncof.views.event_status' event.id %}">
<form method="post" action="{% url 'event.status' event.id %}">
{% csrf_token %}
{{ form.as_p }}
<input style="margin-top:10px;" type="submit" class="btn btn-primary" value="Filtrer" />

View file

@ -1,4 +1,4 @@
{% extends "gestioncof/base_header.html" %}
{% extends "cof/base_header.html" %}
{% block homelink %}
{% endblock %}
@ -7,13 +7,13 @@
<div class="container hidden-xs espace"></div>
<div class="container">
<div class="home-menu row">
<div class="{% if user.profile.is_buro %}col-sm-6 {% else %}col-sm-8 col-sm-offset-2 col-xs-12 {%endif%}normal-user-hm">
<div class="{% if user.profile.cof.is_buro %}col-sm-6 {% else %}col-sm-8 col-sm-offset-2 col-xs-12 {%endif%}normal-user-hm">
<!-- {% if open_events %}
<h3 class="block-title">Événements<span class="pull-right glyphicon glyphicon-calendar"></span></h3>
<div class="hm-block">
<ul>
{% for event in open_events %}
<li><a href="{% url "gestioncof.views.event" event.id %}">{{ event.title }}</a></li>
<li><a href="{% url "event" event.id %}">{{ event.title }}</a></li>
{% endfor %}
</ul>
</div>
@ -23,14 +23,14 @@
<div class="hm-block">
<ul>
{% for survey in open_surveys %}
<li><a href="{% url "gestioncof.views.survey" survey.id %}">{{ survey.title }}</a></li>
<li><a href="{% url "survey" survey.id %}">{{ survey.title }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if user.profile.is_cof %}
{% if user.profile.cof.is_cof %}
{% if open_tirages %}
<h3 class="block-title">Tirages du BdA<span class="pull-right glyphicon glyphicon-th-list"></span></h3>
<div class="hm-block">
@ -54,16 +54,16 @@
<h3 class="block-title">Divers<span class="pull-right glyphicon glyphicon-question-sign"></span></h3>
<div class="hm-block">
<ul>
<li><a href="{% url "gestioncof.views.calendar" %}">Calendrier dynamique</a></li>
{% if user.profile.is_cof %}<li><a href="{% url "petits-cours-inscription" %}">Inscription pour donner des petits cours</a></li>{% endif %}
<li><a href="{% url "calendar" %}">Calendrier dynamique</a></li>
{% if user.profile.cof.is_cof %}<li><a href="{% url "petits-cours-inscription" %}">Inscription pour donner des petits cours</a></li>{% endif %}
<li><a href="{% url "gestioncof.views.profile" %}">Éditer mon profil</a></li>
{% if not user.profile.login_clipper %}<li><a href="{% url "django.contrib.auth.views.password_change" %}">Changer mon mot de passe</a></li>{% endif %}
<li><a href="{% url "gestion:profile" %}">Éditer mon profil</a></li>
{% if not user.profile.login_clipper %}<li><a href="{% url "password_change" %}">Changer mon mot de passe</a></li>{% endif %}
</ul>
</div>
{% endif %}
</div>
{% if user.profile.is_buro %}
{% if user.profile.cof.is_buro %}
<div class="col-sm-6 buro-user-hm">
<h3 class="block-title">Administration<span class="pull-right glyphicon glyphicon-cog"></span></h3>
<div class="hm-block">
@ -71,16 +71,15 @@
<h4>Général</h4>
<li><a href="{% url "admin:index" %}">Administration générale</a></li>
<li><a href="{% url "petits-cours-demandes-list" %}">Demandes de petits cours</a></li>
<li><a href="{% url "gestioncof.views.registration" %}">Inscription d'un nouveau membre</a></li>
<li><a href="{% url "liste-clubs" %}">Gestion des clubs</a></li>
<li><a href="{% url "cof:registration" %}">Inscription d'un nouveau membre</a></li>
</ul>
<ul>
<h4>Évènements & Sondages</h4>
{% for event in events %}
<li><a href="{% url "gestioncof.views.event_status" event.id %}">Événement : {{ event.title }}</a></li>
<li><a href="{% url "event.status" event.id %}">Événement : {{ event.title }}</a></li>
{% endfor %}
{% for survey in surveys %}
<li><a href="{% url "gestioncof.views.survey_status" survey.id %}">Sondage : {{ survey.title }}</a></li>
<li><a href="{% url "survey.status" survey.id %}">Sondage : {{ survey.title }}</a></li>
{% endfor %}
</ul>
</div>
@ -105,15 +104,15 @@
<h3 class="block-title">Liens utiles<span class="pull-right glyphicon glyphicon-link"></span></h3>
<div class="hm-block">
<ul>
<li><a href="{% url "gestioncof.views.utile_cof" %}">Liens utiles du COF</a></li>
<li><a href="{% url "gestioncof.views.utile_bda" %}">Liens utiles BdA</a></li>
<li><a href="{% url "utile_cof" %}">Liens utiles du COF</a></li>
<li><a href="{% url "utile_bda" %}">Liens utiles BdA</a></li>
</ul>
</div>
</div>
{% endif %}
</div> <!-- /.row.home-menu -->
<div class="container hidden-xs espace"></div>
{% if not user.profile.is_buro %}
{% if not user.profile.cof.is_buro %}
<div class="home-menu row row-centered">
<div class="col-sm-8 col-sm-offset-2 col-xs-12 normal-user-hm">
<div class="foot-banner">

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