Compare commits

..

5 Commits

Author SHA1 Message Date
Yohann D'ANELLO 93f7e1d45b Fix check consistency script 2020-08-05 23:53:50 +02:00
Yohann D'ANELLO 199219861c Fix check consistency script 2020-08-05 23:51:59 +02:00
Yohann D'ANELLO 8b66bcc3d5 Fix cron 2020-08-05 23:50:30 +02:00
Yohann D'ANELLO 6759586ef3 Setup crons 2020-08-05 23:19:30 +02:00
Yohann D'ANELLO 33806967c8 Prepare weekly reports 2020-08-05 23:19:17 +02:00
11 changed files with 287 additions and 200 deletions

View File

@ -11,7 +11,7 @@
git:
repo: https://gitlab.crans.org/bde/nk20.git
dest: /var/www/note_kfet
version: master
version: beta
force: true
- name: Use default env vars (should be updated!)
@ -28,3 +28,16 @@
recurse: yes
owner: www-data
group: www-data
- name: Setup cron jobs
file:
src: /var/www/note_kfet/note.cron
dest: /etc/cron.d/note
state: link
owner: root
group: root
- name: Restart cron service
systemd:
name: cron
state: restarted

View File

@ -17,6 +17,7 @@ class ProfileInline(admin.StackedInline):
Inline user profile in user admin
"""
model = Profile
form = ProfileForm
can_delete = False
@ -25,7 +26,6 @@ class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline,)
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_select_related = ('profile',)
form = ProfileForm
def get_inline_instances(self, request, obj=None):
"""

View File

@ -37,6 +37,7 @@ class ProfileForm(forms.ModelForm):
"""
A form for the extras field provided by the :model:`member.Profile` model.
"""
last_report = forms.DateField(required=False, disabled=True, label=_("Last report date"))
def save(self, commit=True):
if not self.instance.section or (("department" in self.changed_data

View File

@ -11,6 +11,7 @@ from django.db import models
from django.db.models import Q
from django.template import loader
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import gettext_lazy as _
@ -92,6 +93,16 @@ class Profile(models.Model):
default=False,
)
report_frequency = models.PositiveSmallIntegerField(
verbose_name=_("report frequency (in days)"),
default=0,
)
last_report = models.DateField(
verbose_name=_("last report date"),
default=timezone.now,
)
email_confirmed = models.BooleanField(
verbose_name=_("email confirmed"),
default=False,

View File

@ -71,6 +71,8 @@ class UserUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
context['profile_form'] = self.profile_form(instance=context['user_object'].profile,
data=self.request.POST if self.request.POST else None)
if not self.object.profile.report_frequency:
del context['profile_form'].fields["last_report"]
return context

View File

@ -41,6 +41,8 @@ class UserCreateView(CreateView):
context = super().get_context_data(**kwargs)
context["profile_form"] = self.second_form(self.request.POST if self.request.POST else None)
del context["profile_form"].fields["section"]
del context["profile_form"].fields["report_frequency"]
del context["profile_form"].fields["last_report"]
return context

@ -1 +1 @@
Subproject commit 034d8c43b663ac3a33f6e3d06bcdcbbeea0bc517
Subproject commit 47dc4dd9e6742c3fd0f0d4ea654b1e9a0a39f4f7

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-05 21:06+0200\n"
"POT-Creation-Date: 2020-08-05 23:17+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -44,7 +44,7 @@ msgid "You can't invite more than 3 people to this activity."
msgstr ""
#: apps/activity/models.py:24 apps/activity/models.py:49
#: apps/member/models.py:162 apps/note/models/notes.py:212
#: apps/member/models.py:173 apps/note/models/notes.py:212
#: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45
#: apps/note/models/transactions.py:298 apps/permission/models.py:332
#: apps/wei/models.py:67 apps/wei/models.py:119
@ -83,7 +83,7 @@ msgstr ""
msgid "type"
msgstr ""
#: apps/activity/models.py:67 apps/logs/models.py:22 apps/member/models.py:270
#: apps/activity/models.py:67 apps/logs/models.py:22 apps/member/models.py:281
#: apps/note/models/notes.py:126 apps/treasury/models.py:222
#: apps/wei/models.py:161 templates/treasury/sogecredit_detail.html:14
#: templates/wei/survey.html:16
@ -186,13 +186,13 @@ msgstr ""
msgid "Type"
msgstr ""
#: apps/activity/tables.py:77 apps/member/forms.py:103
#: apps/activity/tables.py:77 apps/member/forms.py:104
#: apps/registration/forms.py:70 apps/treasury/forms.py:130
#: apps/wei/forms/registration.py:95
msgid "Last name"
msgstr ""
#: apps/activity/tables.py:79 apps/member/forms.py:108
#: apps/activity/tables.py:79 apps/member/forms.py:109
#: apps/registration/forms.py:75 apps/treasury/forms.py:132
#: apps/wei/forms/registration.py:100 templates/note/transaction_form.html:129
msgid "First name"
@ -292,21 +292,21 @@ msgstr ""
msgid "changelogs"
msgstr ""
#: apps/member/admin.py:52 apps/member/models.py:189
#: apps/member/admin.py:52 apps/member/models.py:200
#: templates/member/club_info.html:41
msgid "membership fee (paid students)"
msgstr ""
#: apps/member/admin.py:53 apps/member/models.py:194
#: apps/member/admin.py:53 apps/member/models.py:205
#: templates/member/club_info.html:44
msgid "membership fee (unpaid students)"
msgstr ""
#: apps/member/admin.py:67 apps/member/models.py:281
#: apps/member/admin.py:67 apps/member/models.py:292
msgid "roles"
msgstr ""
#: apps/member/admin.py:68 apps/member/models.py:295
#: apps/member/admin.py:68 apps/member/models.py:306
msgid "fee"
msgstr ""
@ -314,260 +314,272 @@ msgstr ""
msgid "member"
msgstr ""
#: apps/member/forms.py:59 apps/member/views.py:84
#: apps/member/forms.py:40
msgid "Last report date"
msgstr ""
#: apps/member/forms.py:60 apps/member/views.py:86
#: apps/registration/forms.py:28
msgid "An alias with a similar name already exists."
msgstr ""
#: apps/member/forms.py:82 apps/registration/forms.py:50
#: apps/member/forms.py:83 apps/registration/forms.py:50
msgid "Inscription paid by Société Générale"
msgstr ""
#: apps/member/forms.py:84 apps/registration/forms.py:52
#: apps/member/forms.py:85 apps/registration/forms.py:52
msgid "Check this case is the Société Générale paid the inscription."
msgstr ""
#: apps/member/forms.py:89 apps/registration/forms.py:57
#: apps/member/forms.py:90 apps/registration/forms.py:57
#: apps/wei/forms/registration.py:82
msgid "Credit type"
msgstr ""
#: apps/member/forms.py:90 apps/registration/forms.py:58
#: apps/member/forms.py:91 apps/registration/forms.py:58
#: apps/wei/forms/registration.py:83
msgid "No credit"
msgstr ""
#: apps/member/forms.py:92
#: apps/member/forms.py:93
msgid "You can credit the note of the user."
msgstr ""
#: apps/member/forms.py:96 apps/registration/forms.py:63
#: apps/member/forms.py:97 apps/registration/forms.py:63
#: apps/wei/forms/registration.py:88
msgid "Credit amount"
msgstr ""
#: apps/member/forms.py:113 apps/registration/forms.py:80
#: apps/member/forms.py:114 apps/registration/forms.py:80
#: apps/treasury/forms.py:134 apps/wei/forms/registration.py:105
#: templates/note/transaction_form.html:135
msgid "Bank"
msgstr ""
#: apps/member/forms.py:140
#: apps/member/forms.py:141
msgid "User"
msgstr ""
#: apps/member/forms.py:154
#: apps/member/forms.py:155
msgid "Roles"
msgstr ""
#: apps/member/models.py:38
#: apps/member/models.py:39
#: templates/registration/future_profile_detail.html:40
#: templates/wei/weimembership_form.html:48
msgid "phone number"
msgstr ""
#: apps/member/models.py:45 templates/member/profile_info.html:29
#: apps/member/models.py:46 templates/member/profile_info.html:29
#: templates/registration/future_profile_detail.html:34
#: templates/wei/weimembership_form.html:42
msgid "section"
msgstr ""
#: apps/member/models.py:46
#: apps/member/models.py:47
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr ""
#: apps/member/models.py:54 templates/wei/weimembership_form.html:36
#: apps/member/models.py:55 templates/wei/weimembership_form.html:36
msgid "department"
msgstr ""
#: apps/member/models.py:56
#: apps/member/models.py:57
msgid "Informatics (A0)"
msgstr ""
#: apps/member/models.py:57
#: apps/member/models.py:58
msgid "Mathematics (A1)"
msgstr ""
#: apps/member/models.py:58
#: apps/member/models.py:59
msgid "Physics (A2)"
msgstr ""
#: apps/member/models.py:59
#: apps/member/models.py:60
msgid "Applied physics (A'2)"
msgstr ""
#: apps/member/models.py:60
#: apps/member/models.py:61
msgid "Chemistry (A''2)"
msgstr ""
#: apps/member/models.py:61
#: apps/member/models.py:62
msgid "Biology (A3)"
msgstr ""
#: apps/member/models.py:62
#: apps/member/models.py:63
msgid "SAPHIRE (B1234)"
msgstr ""
#: apps/member/models.py:63
#: apps/member/models.py:64
msgid "Mechanics (B1)"
msgstr ""
#: apps/member/models.py:64
#: apps/member/models.py:65
msgid "Civil engineering (B2)"
msgstr ""
#: apps/member/models.py:65
#: apps/member/models.py:66
msgid "Mechanical engineering (B3)"
msgstr ""
#: apps/member/models.py:66
#: apps/member/models.py:67
msgid "EEA (B4)"
msgstr ""
#: apps/member/models.py:67
#: apps/member/models.py:68
msgid "Design (C)"
msgstr ""
#: apps/member/models.py:68
#: apps/member/models.py:69
msgid "Economy-management (D2)"
msgstr ""
#: apps/member/models.py:69
#: apps/member/models.py:70
msgid "Social sciences (D3)"
msgstr ""
#: apps/member/models.py:70
#: apps/member/models.py:71
msgid "English (E)"
msgstr ""
#: apps/member/models.py:71
#: apps/member/models.py:72
msgid "External (EXT)"
msgstr ""
#: apps/member/models.py:78
#: apps/member/models.py:79
msgid "promotion"
msgstr ""
#: apps/member/models.py:79
#: apps/member/models.py:80
msgid "Year of entry to the school (None if not ENS student)"
msgstr ""
#: apps/member/models.py:83 templates/member/profile_info.html:32
#: apps/member/models.py:84 templates/member/profile_info.html:32
#: templates/registration/future_profile_detail.html:37
#: templates/wei/weimembership_form.html:45
msgid "address"
msgstr ""
#: apps/member/models.py:90
#: apps/member/models.py:91
#: templates/registration/future_profile_detail.html:43
#: templates/wei/weimembership_form.html:51
msgid "paid"
msgstr ""
#: apps/member/models.py:91
#: apps/member/models.py:92
msgid "Tells if the user receive a salary."
msgstr ""
#: apps/member/models.py:96
#: apps/member/models.py:97
msgid "report frequency (in days)"
msgstr ""
#: apps/member/models.py:102
msgid "last report date"
msgstr ""
#: apps/member/models.py:107
msgid "email confirmed"
msgstr ""
#: apps/member/models.py:101
#: apps/member/models.py:112
msgid "registration valid"
msgstr ""
#: apps/member/models.py:130 apps/member/models.py:131
#: apps/member/models.py:141 apps/member/models.py:142
msgid "user profile"
msgstr ""
#: apps/member/models.py:138
#: apps/member/models.py:149
msgid "Activate your Note Kfet account"
msgstr ""
#: apps/member/models.py:167 templates/member/club_info.html:57
#: apps/member/models.py:178 templates/member/club_info.html:57
#: templates/registration/future_profile_detail.html:22
#: templates/wei/weiclub_info.html:52 templates/wei/weimembership_form.html:24
msgid "email"
msgstr ""
#: apps/member/models.py:174
#: apps/member/models.py:185
msgid "parent club"
msgstr ""
#: apps/member/models.py:183
#: apps/member/models.py:194
msgid "require memberships"
msgstr ""
#: apps/member/models.py:184
#: apps/member/models.py:195
msgid "Uncheck if this club don't require memberships."
msgstr ""
#: apps/member/models.py:200 templates/member/club_info.html:33
#: apps/member/models.py:211 templates/member/club_info.html:33
msgid "membership duration"
msgstr ""
#: apps/member/models.py:201
#: apps/member/models.py:212
msgid "The longest time (in days) a membership can last (NULL = infinite)."
msgstr ""
#: apps/member/models.py:208 templates/member/club_info.html:23
#: apps/member/models.py:219 templates/member/club_info.html:23
msgid "membership start"
msgstr ""
#: apps/member/models.py:209
#: apps/member/models.py:220
msgid "How long after January 1st the members can renew their membership."
msgstr ""
#: apps/member/models.py:216 templates/member/club_info.html:28
#: apps/member/models.py:227 templates/member/club_info.html:28
msgid "membership end"
msgstr ""
#: apps/member/models.py:217
#: apps/member/models.py:228
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
msgstr ""
#: apps/member/models.py:251 apps/member/models.py:276
#: apps/member/models.py:262 apps/member/models.py:287
#: apps/note/models/notes.py:163
msgid "club"
msgstr ""
#: apps/member/models.py:252
#: apps/member/models.py:263
msgid "clubs"
msgstr ""
#: apps/member/models.py:286
#: apps/member/models.py:297
msgid "membership starts on"
msgstr ""
#: apps/member/models.py:290
#: apps/member/models.py:301
msgid "membership ends on"
msgstr ""
#: apps/member/models.py:342
#: apps/member/models.py:353
#, python-brace-format
msgid "The role {role} does not apply to the club {club}."
msgstr ""
#: apps/member/models.py:353 apps/member/views.py:588
#: apps/member/models.py:364 apps/member/views.py:590
msgid "User is already a member of the club"
msgstr ""
#: apps/member/models.py:400
#: apps/member/models.py:411
msgid "User is not a member of the parent club"
msgstr ""
#: apps/member/models.py:453
#: apps/member/models.py:464
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr ""
#: apps/member/models.py:456
#: apps/member/models.py:467
msgid "membership"
msgstr ""
#: apps/member/models.py:457
#: apps/member/models.py:468
msgid "memberships"
msgstr ""
@ -585,71 +597,71 @@ msgstr ""
msgid "This address must be valid."
msgstr ""
#: apps/member/views.py:133
#: apps/member/views.py:135
msgid "Profile detail"
msgstr ""
#: apps/member/views.py:167
#: apps/member/views.py:169
msgid "Search user"
msgstr ""
#: apps/member/views.py:201 apps/member/views.py:387
#: apps/member/views.py:203 apps/member/views.py:389
msgid "Note aliases"
msgstr ""
#: apps/member/views.py:215
#: apps/member/views.py:217
msgid "Update note picture"
msgstr ""
#: apps/member/views.py:273 templates/member/profile_info.html:43
#: apps/member/views.py:275 templates/member/profile_info.html:43
msgid "Manage auth token"
msgstr ""
#: apps/member/views.py:301
#: apps/member/views.py:303
msgid "Create new club"
msgstr ""
#: apps/member/views.py:313
#: apps/member/views.py:315
msgid "Search club"
msgstr ""
#: apps/member/views.py:338
#: apps/member/views.py:340
msgid "Club detail"
msgstr ""
#: apps/member/views.py:404
#: apps/member/views.py:406
msgid "Update club"
msgstr ""
#: apps/member/views.py:438
#: apps/member/views.py:440
msgid "Add new member to the club"
msgstr ""
#: apps/member/views.py:579 apps/wei/views.py:862
#: apps/member/views.py:581 apps/wei/views.py:862
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
msgstr ""
#: apps/member/views.py:592
#: apps/member/views.py:594
msgid "The membership must start after {:%m-%d-%Y}."
msgstr ""
#: apps/member/views.py:597
#: apps/member/views.py:599
msgid "The membership must begin before {:%m-%d-%Y}."
msgstr ""
#: apps/member/views.py:614 apps/member/views.py:616 apps/member/views.py:618
#: apps/registration/views.py:290 apps/registration/views.py:292
#: apps/registration/views.py:294 apps/wei/views.py:867 apps/wei/views.py:871
#: apps/member/views.py:616 apps/member/views.py:618 apps/member/views.py:620
#: apps/registration/views.py:292 apps/registration/views.py:294
#: apps/registration/views.py:296 apps/wei/views.py:867 apps/wei/views.py:871
msgid "This field is required."
msgstr ""
#: apps/member/views.py:702
#: apps/member/views.py:704
msgid "Manage roles of an user in the club"
msgstr ""
#: apps/member/views.py:727
#: apps/member/views.py:729
msgid "Members of the club"
msgstr ""
@ -1116,52 +1128,52 @@ msgstr ""
msgid "Register new user"
msgstr ""
#: apps/registration/views.py:80
#: apps/registration/views.py:82
msgid "Email validation"
msgstr ""
#: apps/registration/views.py:82
#: apps/registration/views.py:84
msgid "Validate email"
msgstr ""
#: apps/registration/views.py:124
#: apps/registration/views.py:126
msgid "Email validation unsuccessful"
msgstr ""
#: apps/registration/views.py:135
#: apps/registration/views.py:137
msgid "Email validation email sent"
msgstr ""
#: apps/registration/views.py:143
#: apps/registration/views.py:145
msgid "Resend email validation link"
msgstr ""
#: apps/registration/views.py:161
#: apps/registration/views.py:163
msgid "Pre-registered users list"
msgstr ""
#: apps/registration/views.py:188
#: apps/registration/views.py:190
msgid "Unregistered users"
msgstr ""
#: apps/registration/views.py:201
#: apps/registration/views.py:203
msgid "Registration detail"
msgstr ""
#: apps/registration/views.py:256
#: apps/registration/views.py:258
msgid "You must join the BDE."
msgstr ""
#: apps/registration/views.py:278
#: apps/registration/views.py:280
msgid "You must join BDE club before joining Kfet club."
msgstr ""
#: apps/registration/views.py:283
#: apps/registration/views.py:285
msgid ""
"The entered amount is not enough for the memberships, should be at least {}"
msgstr ""
#: apps/registration/views.py:358
#: apps/registration/views.py:360
msgid "Invalidate pre-registration"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-05 21:06+0200\n"
"POT-Creation-Date: 2020-08-05 23:17+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -45,7 +45,7 @@ msgid "You can't invite more than 3 people to this activity."
msgstr "Vous ne pouvez pas inviter plus de 3 personnes à cette activité."
#: apps/activity/models.py:24 apps/activity/models.py:49
#: apps/member/models.py:162 apps/note/models/notes.py:212
#: apps/member/models.py:173 apps/note/models/notes.py:212
#: apps/note/models/transactions.py:25 apps/note/models/transactions.py:45
#: apps/note/models/transactions.py:298 apps/permission/models.py:332
#: apps/wei/models.py:67 apps/wei/models.py:119
@ -84,7 +84,7 @@ msgstr "description"
msgid "type"
msgstr "type"
#: apps/activity/models.py:67 apps/logs/models.py:22 apps/member/models.py:270
#: apps/activity/models.py:67 apps/logs/models.py:22 apps/member/models.py:281
#: apps/note/models/notes.py:126 apps/treasury/models.py:222
#: apps/wei/models.py:161 templates/treasury/sogecredit_detail.html:14
#: templates/wei/survey.html:16
@ -187,13 +187,13 @@ msgstr "supprimer"
msgid "Type"
msgstr "Type"
#: apps/activity/tables.py:77 apps/member/forms.py:103
#: apps/activity/tables.py:77 apps/member/forms.py:104
#: apps/registration/forms.py:70 apps/treasury/forms.py:130
#: apps/wei/forms/registration.py:95
msgid "Last name"
msgstr "Nom de famille"
#: apps/activity/tables.py:79 apps/member/forms.py:108
#: apps/activity/tables.py:79 apps/member/forms.py:109
#: apps/registration/forms.py:75 apps/treasury/forms.py:132
#: apps/wei/forms/registration.py:100 templates/note/transaction_form.html:129
msgid "First name"
@ -293,21 +293,21 @@ msgstr "journal de modification"
msgid "changelogs"
msgstr "journaux de modifications"
#: apps/member/admin.py:52 apps/member/models.py:189
#: apps/member/admin.py:52 apps/member/models.py:200
#: templates/member/club_info.html:41
msgid "membership fee (paid students)"
msgstr "cotisation pour adhérer (normalien élève)"
#: apps/member/admin.py:53 apps/member/models.py:194
#: apps/member/admin.py:53 apps/member/models.py:205
#: templates/member/club_info.html:44
msgid "membership fee (unpaid students)"
msgstr "cotisation pour adhérer (normalien étudiant)"
#: apps/member/admin.py:67 apps/member/models.py:281
#: apps/member/admin.py:67 apps/member/models.py:292
msgid "roles"
msgstr "rôles"
#: apps/member/admin.py:68 apps/member/models.py:295
#: apps/member/admin.py:68 apps/member/models.py:306
msgid "fee"
msgstr "cotisation"
@ -315,217 +315,229 @@ msgstr "cotisation"
msgid "member"
msgstr "adhérent"
#: apps/member/forms.py:59 apps/member/views.py:84
#: apps/member/forms.py:40
msgid "Last report date"
msgstr "Date de dernier rapport"
#: apps/member/forms.py:60 apps/member/views.py:86
#: apps/registration/forms.py:28
msgid "An alias with a similar name already exists."
msgstr "Un alias avec un nom similaire existe déjà."
#: apps/member/forms.py:82 apps/registration/forms.py:50
#: apps/member/forms.py:83 apps/registration/forms.py:50
msgid "Inscription paid by Société Générale"
msgstr "Inscription payée par la Société générale"
#: apps/member/forms.py:84 apps/registration/forms.py:52
#: apps/member/forms.py:85 apps/registration/forms.py:52
msgid "Check this case is the Société Générale paid the inscription."
msgstr "Cochez cette case si la Société Générale a payé l'inscription."
#: apps/member/forms.py:89 apps/registration/forms.py:57
#: apps/member/forms.py:90 apps/registration/forms.py:57
#: apps/wei/forms/registration.py:82
msgid "Credit type"
msgstr "Type de rechargement"
#: apps/member/forms.py:90 apps/registration/forms.py:58
#: apps/member/forms.py:91 apps/registration/forms.py:58
#: apps/wei/forms/registration.py:83
msgid "No credit"
msgstr "Pas de rechargement"
#: apps/member/forms.py:92
#: apps/member/forms.py:93
msgid "You can credit the note of the user."
msgstr "Vous pouvez créditer la note de l'utisateur avant l'adhésion."
#: apps/member/forms.py:96 apps/registration/forms.py:63
#: apps/member/forms.py:97 apps/registration/forms.py:63
#: apps/wei/forms/registration.py:88
msgid "Credit amount"
msgstr "Montant à créditer"
#: apps/member/forms.py:113 apps/registration/forms.py:80
#: apps/member/forms.py:114 apps/registration/forms.py:80
#: apps/treasury/forms.py:134 apps/wei/forms/registration.py:105
#: templates/note/transaction_form.html:135
msgid "Bank"
msgstr "Banque"
#: apps/member/forms.py:140
#: apps/member/forms.py:141
msgid "User"
msgstr "Utilisateur"
#: apps/member/forms.py:154
#: apps/member/forms.py:155
msgid "Roles"
msgstr "Rôles"
#: apps/member/models.py:38
#: apps/member/models.py:39
#: templates/registration/future_profile_detail.html:40
#: templates/wei/weimembership_form.html:48
msgid "phone number"
msgstr "numéro de téléphone"
#: apps/member/models.py:45 templates/member/profile_info.html:29
#: apps/member/models.py:46 templates/member/profile_info.html:29
#: templates/registration/future_profile_detail.html:34
#: templates/wei/weimembership_form.html:42
msgid "section"
msgstr "section"
#: apps/member/models.py:46
#: apps/member/models.py:47
msgid "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
msgstr "e.g. \"1A0\", \"9A♥\", \"SAPHIRE\""
#: apps/member/models.py:54 templates/wei/weimembership_form.html:36
#: apps/member/models.py:55 templates/wei/weimembership_form.html:36
msgid "department"
msgstr "département"
#: apps/member/models.py:56
#: apps/member/models.py:57
msgid "Informatics (A0)"
msgstr "Informatique (A0)"
#: apps/member/models.py:57
#: apps/member/models.py:58
msgid "Mathematics (A1)"
msgstr "Mathématiques (A1)"
#: apps/member/models.py:58
#: apps/member/models.py:59
msgid "Physics (A2)"
msgstr "Physique (A2)"
#: apps/member/models.py:59
#: apps/member/models.py:60
msgid "Applied physics (A'2)"
msgstr "Physique appliquée (A'2)"
#: apps/member/models.py:60
#: apps/member/models.py:61
msgid "Chemistry (A''2)"
msgstr "Chimie (A''2)"
#: apps/member/models.py:61
#: apps/member/models.py:62
msgid "Biology (A3)"
msgstr "Biologie (A3)"
#: apps/member/models.py:62
#: apps/member/models.py:63
msgid "SAPHIRE (B1234)"
msgstr "SAPHIRE (B1234)"
#: apps/member/models.py:63
#: apps/member/models.py:64
msgid "Mechanics (B1)"
msgstr "Mécanique (B1)"
#: apps/member/models.py:64
#: apps/member/models.py:65
msgid "Civil engineering (B2)"
msgstr "Génie civil (B2)"
#: apps/member/models.py:65
#: apps/member/models.py:66
msgid "Mechanical engineering (B3)"
msgstr "Génie mécanique (B3)"
#: apps/member/models.py:66
#: apps/member/models.py:67
msgid "EEA (B4)"
msgstr "EEA (B4)"
#: apps/member/models.py:67
#: apps/member/models.py:68
msgid "Design (C)"
msgstr "Design (C)"
#: apps/member/models.py:68
#: apps/member/models.py:69
msgid "Economy-management (D2)"
msgstr "Économie-gestion (D2)"
#: apps/member/models.py:69
#: apps/member/models.py:70
msgid "Social sciences (D3)"
msgstr "Sciences sociales (D3)"
#: apps/member/models.py:70
#: apps/member/models.py:71
msgid "English (E)"
msgstr "Anglais (E)"
#: apps/member/models.py:71
#: apps/member/models.py:72
msgid "External (EXT)"
msgstr "Externe (EXT)"
#: apps/member/models.py:78
#: apps/member/models.py:79
msgid "promotion"
msgstr "promotion"
#: apps/member/models.py:79
#: apps/member/models.py:80
msgid "Year of entry to the school (None if not ENS student)"
msgstr "Année d'entrée dans l'école (None si non-étudiant·e de l'ENS)"
#: apps/member/models.py:83 templates/member/profile_info.html:32
#: apps/member/models.py:84 templates/member/profile_info.html:32
#: templates/registration/future_profile_detail.html:37
#: templates/wei/weimembership_form.html:45
msgid "address"
msgstr "adresse"
#: apps/member/models.py:90
#: apps/member/models.py:91
#: templates/registration/future_profile_detail.html:43
#: templates/wei/weimembership_form.html:51
msgid "paid"
msgstr "payé"
#: apps/member/models.py:91
#: apps/member/models.py:92
msgid "Tells if the user receive a salary."
msgstr "Indique si l'utilisateur perçoit un salaire."
#: apps/member/models.py:96
#: apps/member/models.py:97
msgid "report frequency (in days)"
msgstr "fréquence des rapports (en jours)"
#: apps/member/models.py:102
msgid "last report date"
msgstr "date de dernier rapport"
#: apps/member/models.py:107
msgid "email confirmed"
msgstr "adresse email confirmée"
#: apps/member/models.py:101
#: apps/member/models.py:112
msgid "registration valid"
msgstr "inscription valid"
#: apps/member/models.py:130 apps/member/models.py:131
#: apps/member/models.py:141 apps/member/models.py:142
msgid "user profile"
msgstr "profil utilisateur"
#: apps/member/models.py:138
#: apps/member/models.py:149
msgid "Activate your Note Kfet account"
msgstr "Activez votre compte Note Kfet"
#: apps/member/models.py:167 templates/member/club_info.html:57
#: apps/member/models.py:178 templates/member/club_info.html:57
#: templates/registration/future_profile_detail.html:22
#: templates/wei/weiclub_info.html:52 templates/wei/weimembership_form.html:24
msgid "email"
msgstr "courriel"
#: apps/member/models.py:174
#: apps/member/models.py:185
msgid "parent club"
msgstr "club parent"
#: apps/member/models.py:183
#: apps/member/models.py:194
msgid "require memberships"
msgstr "nécessite des adhésions"
#: apps/member/models.py:184
#: apps/member/models.py:195
msgid "Uncheck if this club don't require memberships."
msgstr "Décochez si ce club n'utilise pas d'adhésions."
#: apps/member/models.py:200 templates/member/club_info.html:33
#: apps/member/models.py:211 templates/member/club_info.html:33
msgid "membership duration"
msgstr "durée de l'adhésion"
#: apps/member/models.py:201
#: apps/member/models.py:212
msgid "The longest time (in days) a membership can last (NULL = infinite)."
msgstr "La durée maximale (en jours) d'une adhésion (NULL = infinie)."
#: apps/member/models.py:208 templates/member/club_info.html:23
#: apps/member/models.py:219 templates/member/club_info.html:23
msgid "membership start"
msgstr "début de l'adhésion"
#: apps/member/models.py:209
#: apps/member/models.py:220
msgid "How long after January 1st the members can renew their membership."
msgstr ""
"Combien de temps après le 1er Janvier les adhérents peuvent renouveler leur "
"adhésion."
#: apps/member/models.py:216 templates/member/club_info.html:28
#: apps/member/models.py:227 templates/member/club_info.html:28
msgid "membership end"
msgstr "fin de l'adhésion"
#: apps/member/models.py:217
#: apps/member/models.py:228
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
@ -533,46 +545,46 @@ msgstr ""
"Combien de temps l'adhésion peut durer après le 1er Janvier de l'année "
"suivante avant que les adhérents peuvent renouveler leur adhésion."
#: apps/member/models.py:251 apps/member/models.py:276
#: apps/member/models.py:262 apps/member/models.py:287
#: apps/note/models/notes.py:163
msgid "club"
msgstr "club"
#: apps/member/models.py:252
#: apps/member/models.py:263
msgid "clubs"
msgstr "clubs"
#: apps/member/models.py:286
#: apps/member/models.py:297
msgid "membership starts on"
msgstr "l'adhésion commence le"
#: apps/member/models.py:290
#: apps/member/models.py:301
msgid "membership ends on"
msgstr "l'adhésion finit le"
#: apps/member/models.py:342
#: apps/member/models.py:353
#, python-brace-format
msgid "The role {role} does not apply to the club {club}."
msgstr "Le rôle {role} ne s'applique pas au club {club}."
#: apps/member/models.py:353 apps/member/views.py:588
#: apps/member/models.py:364 apps/member/views.py:590
msgid "User is already a member of the club"
msgstr "L'utilisateur est déjà membre du club"
#: apps/member/models.py:400
#: apps/member/models.py:411
msgid "User is not a member of the parent club"
msgstr "L'utilisateur n'est pas membre du club parent"
#: apps/member/models.py:453
#: apps/member/models.py:464
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Adhésion de {user} pour le club {club}"
#: apps/member/models.py:456
#: apps/member/models.py:467
msgid "membership"
msgstr "adhésion"
#: apps/member/models.py:457
#: apps/member/models.py:468
msgid "memberships"
msgstr "adhésions"
@ -590,47 +602,47 @@ msgstr "Modifier le profil"
msgid "This address must be valid."
msgstr "Cette adresse doit être valide."
#: apps/member/views.py:133
#: apps/member/views.py:135
msgid "Profile detail"
msgstr "Détails de l'utilisateur"
#: apps/member/views.py:167
#: apps/member/views.py:169
msgid "Search user"
msgstr "Chercher un utilisateur"
#: apps/member/views.py:201 apps/member/views.py:387
#: apps/member/views.py:203 apps/member/views.py:389
msgid "Note aliases"
msgstr "Alias de la note"
#: apps/member/views.py:215
#: apps/member/views.py:217
msgid "Update note picture"
msgstr "Modifier la photo de la note"
#: apps/member/views.py:273 templates/member/profile_info.html:43
#: apps/member/views.py:275 templates/member/profile_info.html:43
msgid "Manage auth token"
msgstr "Gérer les jetons d'authentification"
#: apps/member/views.py:301
#: apps/member/views.py:303
msgid "Create new club"
msgstr "Créer un nouveau club"
#: apps/member/views.py:313
#: apps/member/views.py:315
msgid "Search club"
msgstr "Chercher un club"
#: apps/member/views.py:338
#: apps/member/views.py:340
msgid "Club detail"
msgstr "Détails du club"
#: apps/member/views.py:404
#: apps/member/views.py:406
msgid "Update club"
msgstr "Modifier le club"
#: apps/member/views.py:438
#: apps/member/views.py:440
msgid "Add new member to the club"
msgstr "Ajouter un nouveau membre au club"
#: apps/member/views.py:579 apps/wei/views.py:862
#: apps/member/views.py:581 apps/wei/views.py:862
msgid ""
"This user don't have enough money to join this club, and can't have a "
"negative balance."
@ -638,25 +650,25 @@ msgstr ""
"Cet utilisateur n'a pas assez d'argent pour rejoindre ce club et ne peut pas "
"avoir un solde négatif."
#: apps/member/views.py:592
#: apps/member/views.py:594
msgid "The membership must start after {:%m-%d-%Y}."
msgstr "L'adhésion doit commencer après le {:%d/%m/%Y}."
#: apps/member/views.py:597
#: apps/member/views.py:599
msgid "The membership must begin before {:%m-%d-%Y}."
msgstr "L'adhésion doit commencer avant le {:%d/%m/%Y}."
#: apps/member/views.py:614 apps/member/views.py:616 apps/member/views.py:618
#: apps/registration/views.py:290 apps/registration/views.py:292
#: apps/registration/views.py:294 apps/wei/views.py:867 apps/wei/views.py:871
#: apps/member/views.py:616 apps/member/views.py:618 apps/member/views.py:620
#: apps/registration/views.py:292 apps/registration/views.py:294
#: apps/registration/views.py:296 apps/wei/views.py:867 apps/wei/views.py:871
msgid "This field is required."
msgstr "Ce champ est requis."
#: apps/member/views.py:702
#: apps/member/views.py:704
msgid "Manage roles of an user in the club"
msgstr "Gérer les rôles d'un utilisateur dans le club"
#: apps/member/views.py:727
#: apps/member/views.py:729
msgid "Members of the club"
msgstr "Membres du club"
@ -1143,54 +1155,54 @@ msgstr "Adhérer au club Kfet"
msgid "Register new user"
msgstr "Enregistrer un nouvel utilisateur"
#: apps/registration/views.py:80
#: apps/registration/views.py:82
msgid "Email validation"
msgstr "Validation de l'adresse mail"
#: apps/registration/views.py:82
#: apps/registration/views.py:84
msgid "Validate email"
msgstr "Valider l'adresse e-mail"
#: apps/registration/views.py:124
#: apps/registration/views.py:126
msgid "Email validation unsuccessful"
msgstr " La validation de l'adresse mail a échoué"
#: apps/registration/views.py:135
#: apps/registration/views.py:137
msgid "Email validation email sent"
msgstr "L'email de vérification de l'adresse email a bien été envoyé."
#: apps/registration/views.py:143
#: apps/registration/views.py:145
msgid "Resend email validation link"
msgstr "Renvoyer le lien de validation"
#: apps/registration/views.py:161
#: apps/registration/views.py:163
msgid "Pre-registered users list"
msgstr "Liste des utilisateurs en attente d'inscription"
#: apps/registration/views.py:188
#: apps/registration/views.py:190
msgid "Unregistered users"
msgstr "Utilisateurs en attente d'inscription"
#: apps/registration/views.py:201
#: apps/registration/views.py:203
msgid "Registration detail"
msgstr "Détails de l'inscription"
#: apps/registration/views.py:256
#: apps/registration/views.py:258
msgid "You must join the BDE."
msgstr "Vous devez adhérer au BDE."
#: apps/registration/views.py:278
#: apps/registration/views.py:280
msgid "You must join BDE club before joining Kfet club."
msgstr "Vous devez adhérer au club BDE avant d'adhérer au club Kfet."
#: apps/registration/views.py:283
#: apps/registration/views.py:285
msgid ""
"The entered amount is not enough for the memberships, should be at least {}"
msgstr ""
"Le montant crédité est trop faible pour adhérer, il doit être au minimum de "
"{}"
#: apps/registration/views.py:358
#: apps/registration/views.py:360
msgid "Invalidate pre-registration"
msgstr "Invalider l'inscription"

19
note.cron Normal file
View File

@ -0,0 +1,19 @@
# Attention, il faut *copier* ce fichier dans /etc/cron.d, owner root:root et droits 644
# Les cronjobs dont a besoin la Note Kfet
# m h dom mon dow user command
# Envoyer les mails en attente
* * * * * root cd /var/www/note_kfet && env/bin/python manage.py send_mail >> /var/www/note_kfet/cron_mail.log
* * * * * root cd /var/www/note_kfet && env/bin/python manage.py retry_deferred >> /var/www/note_kfet/cron_mail_deferred.log
00 0 * * * root cd /var/www/note_kfet && env/bin/python manage.py purge_mail_log 7 >> /var/www/note_kfet/cron_mail_purge.log
# Vérifier la cohérence de la base et mailer en cas de problème
00 4 * * * root cd /var/www/note_kfet && env/bin/python manage.py check_consistency --sum-all --check-all --mail
# TODO
# Mettre à jour le wiki (modification sans (dé)validation, activités passées)
#30 5 * * * root /home/note/note-kfet-2015-serveur/serveur/Wiki.py --human --raw
# Spammer les gens en négatif
00 5 * * 2 root cd /var/www/note_kfet && env/bin/python manage.py send_mail_to_negative_balances --spam
# Envoyer le rapport mensuel aux trésoriers et respos info
00 8 6 * * root cd /var/www/note_kfet && env/bin/python manage.py send_mail_to_negative_balances --report
# Envoyer les rapports aux gens
55 6 * * * root cd /var/www/note_kfet && env/bin/python manage.py send_reports

View File

@ -16,9 +16,24 @@
crossorigin="anonymous"></script>
</head>
<body>
<p>
Bonjour,
</p>
<p>
Vous recevez ce mail car vous avez défini une « Fréquence des rapports » dans la Note.<br>
Le premier rapport récapitule toutes vos consommations depuis la création de votre compte.<br>
Ensuite, un rapport vous est envoyé à la fréquence demandée seulement si vous avez consommé
depuis le dernier rapport.<br>
Pour arrêter de recevoir des rapports, il vous suffit de modifier votre profil Note et de
mettre la fréquence des rapports à 0 ou -1.<br>
Pour toutes suggestions par rapport à ce service, contactez
<a href="mailto:notekfet2020@lists.crans.org">notekfet2020@lists.crans.org</a>.
</p>
<p>
Rapport d'activité de {{ user.first_name }} {{ user.last_name }} (note : {{ user }})
depuis le {{ last_week }} jusqu'au {{ now }}.
depuis le {{ last_report }} jusqu'au {{ now }}.
</p>
<p>