epcstages/stages/admin.py

366 lines
13 KiB
Python
Raw Normal View History

2018-08-15 15:47:44 +02:00
from collections import OrderedDict
from django import forms
2012-11-06 17:54:33 +01:00
from django.contrib import admin
2019-02-21 09:46:44 +01:00
from django.contrib.auth.admin import GroupAdmin as AuthGroupAdmin
from django.contrib.auth.models import Group
from django.db import models
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
2019-02-21 09:46:44 +01:00
from django.utils.html import format_html, format_html_join
2012-11-06 17:54:33 +01:00
2018-02-05 09:38:14 +01:00
from .models import (
Teacher, Option, Student, StudentFile, Section, Level, Klass, Corporation,
2017-07-14 10:19:12 +02:00
CorpContact, Domain, Period, Availability, Training, Course,
2018-04-26 07:54:29 +02:00
LogBookReason, LogBook, ExamEDESession, SupervisionBill
2017-07-11 23:01:46 +02:00
)
2018-08-15 15:47:44 +02:00
from .views.export import OpenXMLExport
def print_charge_sheet(modeladmin, request, queryset):
return HttpResponseRedirect(
reverse('print-charge-sheet') + '?ids=%s' % ",".join(
request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
)
)
print_charge_sheet.short_description = "Imprimer les feuilles de charge"
2012-11-06 17:54:33 +01:00
class ArchivedListFilter(admin.BooleanFieldListFilter):
"""
Default filter that shows by default unarchived elements.
"""
def __init__(self, request, params, *args, **kwargs):
super().__init__(request, params, *args, **kwargs)
if self.lookup_val is None:
self.lookup_val = '0'
def choices(self, cl):
# Removing the "all" choice
return list(super().choices(cl))[1:]
def queryset(self, request, queryset):
if not self.used_parameters:
self.used_parameters[self.lookup_kwarg] = '0'
return super().queryset(request, queryset)
class KlassRelatedListFilter(admin.RelatedFieldListFilter):
def field_choices(self, field, request, model_admin):
return [
2018-06-16 18:14:29 +02:00
(k.pk, k.name) for k in Klass.active.order_by('name')
]
2018-02-05 09:46:36 +01:00
class StudentInline(admin.StackedInline):
model = Student
ordering = ('last_name', 'first_name')
fields = (
('last_name', 'first_name', 'birth_date'),
('pcode', 'city', 'tel', 'mobile', 'email'),
)
can_delete = False
extra = 0
2013-01-02 14:40:24 +01:00
class KlassAdmin(admin.ModelAdmin):
2017-07-11 23:15:00 +02:00
list_display = ('name', 'section')
2013-01-02 14:40:24 +01:00
ordering = ('name',)
2017-07-11 23:15:00 +02:00
list_filter = ('section', 'level',)
2019-02-06 17:46:24 +01:00
fields = (
('name',),
('section', 'level'),
('teacher', 'teacher_ecg', 'teacher_eps'),
)
2018-02-05 09:46:36 +01:00
inlines = [StudentInline]
2013-01-02 14:40:24 +01:00
class LogBookInline(admin.TabularInline):
model = LogBook
ordering = ('input_date',)
fields = ('start_date', 'end_date', 'reason', 'comment', 'nb_period')
extra = 0
2017-07-11 23:01:46 +02:00
class TeacherAdmin(admin.ModelAdmin):
list_display = ('__str__', 'abrev', 'email', 'contract', 'rate', 'total_logbook', 'archived')
2018-02-19 09:37:13 +01:00
list_filter = (('archived', ArchivedListFilter), 'contract')
fields = (('civility', 'last_name', 'first_name', 'abrev'),
('birth_date', 'email', 'ext_id'),
('contract', 'rate', 'can_examinate', 'archived'),
('previous_report', 'next_report', 'total_logbook'),
('user'))
readonly_fields = ('total_logbook',)
actions = [print_charge_sheet]
inlines = [LogBookInline]
2017-07-11 23:01:46 +02:00
2018-04-26 07:54:29 +02:00
class SupervisionBillInline(admin.TabularInline):
model = SupervisionBill
extra = 0
2012-11-06 17:54:33 +01:00
class StudentAdmin(admin.ModelAdmin):
2015-09-22 20:52:35 +02:00
list_display = ('__str__', 'pcode', 'city', 'klass', 'archived')
2013-01-02 14:40:24 +01:00
ordering = ('last_name', 'first_name')
list_filter = (('archived', ArchivedListFilter), ('klass', KlassRelatedListFilter))
search_fields = ('last_name', 'first_name', 'pcode', 'city', 'klass__name')
2018-02-15 16:05:25 +01:00
autocomplete_fields = ('corporation', 'instructor', 'supervisor', 'mentor', 'expert')
readonly_fields = ('report_sem1_sent', 'report_sem2_sent', 'examination_actions', 'date_soutenance_mailed')
fieldsets = (
(None, {
'fields': (('last_name', 'first_name', 'ext_id'), ('street', 'pcode', 'city', 'district'),
('email', 'tel', 'mobile'), ('gender', 'avs', 'birth_date'),
('archived', 'dispense_ecg', 'dispense_eps', 'soutien_dys'),
('klass', 'option_ase'),
('report_sem1', 'report_sem1_sent'),
('report_sem2', 'report_sem2_sent'),
('corporation', 'instructor',)
)
}
),
("Examen Qualification EDE", {
'classes': ('collapse',),
'fields': (
2018-04-26 08:07:14 +02:00
('supervisor', 'supervision_attest_received'),
('subject', 'title'),
('training_referent', 'referent', 'mentor'),
('internal_expert', 'expert'),
('session', 'date_exam', 'room', 'mark'),
('date_soutenance_mailed', 'date_confirm_received'),
('examination_actions',)
)
}),
)
actions = ['archive']
2018-04-26 07:54:29 +02:00
inlines = [SupervisionBillInline]
def get_inline_instances(self, request, obj=None):
# SupervisionBillInline is only adequate for EDE students
2019-08-30 14:01:14 +02:00
if obj is None or not obj.klass or obj.klass.section.name != 'EDE':
2018-04-26 07:54:29 +02:00
return []
return super().get_inline_instances(request, obj=obj)
def archive(self, request, queryset):
for student in queryset:
# Save each item individually to allow for custom save() logic.
student.archived = True
student.save()
archive.short_description = "Marquer les étudiants sélectionnés comme archivés"
2012-11-06 17:54:33 +01:00
def examination_actions(self, obj):
2019-08-30 14:01:14 +02:00
if obj.klass and obj.klass.section.name == 'EDE' and obj.klass.level.name == "3":
return format_html(
'<a class="button" href="{}">Courrier pour lexpert</a>&nbsp;'
2018-04-12 14:29:02 +02:00
'<a class="button" href="{}">Mail convocation soutenance</a>&nbsp;'
2018-04-23 15:44:50 +02:00
'<a class="button" href="{}">Indemnité au mentor</a>',
reverse('print-expert-compens-ede', args=[obj.pk]),
2018-04-23 19:02:23 +02:00
reverse('student-ede-convocation', args=[obj.pk]),
2018-04-23 15:44:50 +02:00
reverse('print-mentor-compens-ede', args=[obj.pk]),
)
else:
return ''
examination_actions.short_description = 'Actions pour les examens EDE'
2012-11-06 17:54:33 +01:00
class CorpContactAdmin(admin.ModelAdmin):
2015-09-22 20:52:35 +02:00
list_display = ('__str__', 'corporation', 'role')
list_filter = (('archived', ArchivedListFilter),)
2015-10-01 13:36:19 +02:00
ordering = ('last_name', 'first_name')
search_fields = ('last_name', 'first_name', 'role')
fields = (('civility', 'last_name', 'first_name'),
('street', 'pcode', 'city'),
('birth_date',),
('corporation',),
2016-01-18 12:55:57 +01:00
('sections', 'is_main', 'always_cc', 'archived'),
('role', 'ext_id'), ('tel', 'email'),
('ccp', 'bank', 'clearing' ),
('iban',),
('qualification', 'fields_of_interest'),
)
formfield_overrides = {
models.ManyToManyField: {'widget': forms.CheckboxSelectMultiple},
}
def get_form(self, *args, **kwargs):
form = super().get_form(*args, **kwargs)
form.base_fields['sections'].widget.can_add_related = False
return form
2018-02-14 18:13:22 +01:00
def get_search_results(self, request, qs, term):
qs, distinct = super().get_search_results(request, qs, term)
return qs.exclude(archived=True), distinct
2012-11-06 17:54:33 +01:00
2018-02-15 16:05:25 +01:00
2012-11-09 15:32:00 +01:00
class ContactInline(admin.StackedInline):
2012-11-06 17:54:33 +01:00
model = CorpContact
fields = (('civility', 'last_name', 'first_name'),
2016-01-18 12:55:57 +01:00
('sections', 'is_main', 'always_cc', 'archived'),
2012-11-09 15:32:00 +01:00
('role', 'tel', 'email'))
2012-11-06 17:54:33 +01:00
extra = 1
formfield_overrides = {
models.ManyToManyField: {'widget': forms.CheckboxSelectMultiple},
}
2012-11-06 17:54:33 +01:00
class CorporationAdmin(admin.ModelAdmin):
list_display = ('name', 'short_name', 'pcode', 'city', 'district', 'ext_id')
list_editable = ('short_name',) # Temporarily?
list_filter = (('archived', ArchivedListFilter),)
search_fields = ('name', 'street', 'pcode', 'city')
ordering = ('name',)
fields = (
('name', 'short_name'),
'parent',
('sector', 'typ', 'ext_id'),
'street',
('pcode', 'city', 'district'),
('tel', 'email'),
'web',
'archived',
)
2012-11-06 17:54:33 +01:00
inlines = [ContactInline]
2018-08-15 15:47:44 +02:00
actions = ['export_corporations']
2012-11-06 17:54:33 +01:00
2018-02-14 18:13:22 +01:00
def get_search_results(self, request, qs, term):
qs, distinct = super().get_search_results(request, qs, term)
return qs.exclude(archived=True), distinct
2018-08-15 15:47:44 +02:00
def export_corporations(self, request, queryset):
"""
Export all Corporations in Excel file.
"""
export_fields = OrderedDict([
(getattr(f, 'verbose_name', f.name), f.name)
for f in Corporation._meta.get_fields() if f.name in (
'name', 'short_name', 'sector', 'typ', 'street', 'pcode',
'city', 'district', 'tel', 'email', 'web', 'ext_id', 'archived'
)
])
export = OpenXMLExport('Exportation')
export.write_line(export_fields.keys(), bold=True)
for corp in queryset.values_list(*export_fields.values()):
values = []
for value, field_name in zip(corp, export_fields.values()):
if field_name == 'archived':
value = 'Oui' if value else ''
values.append(value)
export.write_line(values)
return export.get_http_response('corporations_export')
export_corporations.short_description = 'Exportation Excel'
2012-11-06 17:54:33 +01:00
class AvailabilityAdminForm(forms.ModelForm):
"""
Custom avail form to create several availabilities at once when inlined in
the PeriodAdmin interface
"""
num_avail = forms.IntegerField(label="Nombre de places", initial=1, required=False)
class Media:
js = ('admin/js/jquery.init.js', 'js/avail_form.js',)
class Meta:
model = Availability
fields = '__all__'
widgets = {
'num_avail': forms.TextInput(attrs={'size': 3}),
}
def __init__(self, data=None, files=None, **kwargs):
super(AvailabilityAdminForm, self).__init__(data=data, files=files, **kwargs)
if self.instance.pk is not None:
# Hide num_avail on existing instances
self.fields['num_avail'].widget = forms.HiddenInput()
# Limit CorpContact objects to contacts of chosen corporation
if data is None and self.instance.corporation_id:
self.fields['contact'].queryset = self.instance.corporation.corpcontact_set
def save(self, **kwargs):
instance = super(AvailabilityAdminForm, self).save(**kwargs)
# Create supplementary availabilities depending on num_avail
num_avail = self.cleaned_data.get('num_avail', 1) or 1
for i in range(1, num_avail):
Availability.objects.create(
corporation=instance.corporation,
period=instance.period,
domain=instance.domain,
contact=instance.contact,
comment=instance.comment)
return instance
2018-02-05 09:38:14 +01:00
class AvailabilityInline(admin.StackedInline):
model = Availability
form = AvailabilityAdminForm
ordering = ('corporation__name',)
extra = 1
formfield_overrides = {
models.TextField: {'widget': forms.Textarea(attrs={'rows':2, 'cols':40})},
}
autocomplete_fields = ['corporation']
2012-11-06 17:54:33 +01:00
class PeriodAdmin(admin.ModelAdmin):
2012-11-23 11:31:06 +01:00
list_display = ('title', 'dates', 'section', 'level')
list_filter = ('section', 'level')
inlines = [AvailabilityInline]
2012-11-06 17:54:33 +01:00
class AvailabilityAdmin(admin.ModelAdmin):
list_display = ('corporation', 'period', 'domain')
list_filter = ('period',)
fields = (('corporation', 'period'), 'domain', 'contact', 'priority', 'comment')
form = AvailabilityAdminForm
2012-11-06 17:54:33 +01:00
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "corporation":
kwargs["queryset"] = Corporation.objects.filter(archived=False).order_by('name')
2016-01-18 12:55:57 +01:00
if db_field.name == "contact":
kwargs["queryset"] = CorpContact.objects.filter(archived=False)
return super(AvailabilityAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
2012-11-06 17:54:33 +01:00
2012-12-13 00:00:04 +01:00
class TrainingAdmin(admin.ModelAdmin):
search_fields = ('student__first_name', 'student__last_name', 'availability__corporation__name')
2013-07-11 15:26:44 +02:00
raw_id_fields = ('availability',)
2012-12-13 00:00:04 +01:00
class CourseAdmin(admin.ModelAdmin):
list_display = ('teacher', 'public', 'subject', 'period', 'imputation')
2017-08-22 08:41:06 +02:00
list_filter = ('imputation', )
search_fields = ('teacher__last_name', 'public', 'subject')
2019-02-21 09:46:44 +01:00
class GroupAdmin(AuthGroupAdmin):
list_display = ['name', 'membres']
def membres(self, grp):
return format_html_join(', ', '<a href="{}">{}</a>', [
(reverse('admin:auth_user_change', args=(user.pk,)), user.username)
for user in grp.user_set.all().order_by('username')
])
2012-11-06 17:54:33 +01:00
admin.site.register(Section)
2012-11-23 11:31:06 +01:00
admin.site.register(Level)
2013-01-02 14:40:24 +01:00
admin.site.register(Klass, KlassAdmin)
2017-08-29 16:28:31 +02:00
admin.site.register(Option)
admin.site.register(Student, StudentAdmin)
admin.site.register(StudentFile)
2017-07-11 23:01:46 +02:00
admin.site.register(Teacher, TeacherAdmin)
admin.site.register(Course, CourseAdmin)
2012-11-06 17:54:33 +01:00
admin.site.register(Corporation, CorporationAdmin)
admin.site.register(CorpContact, CorpContactAdmin)
admin.site.register(Domain)
admin.site.register(Period, PeriodAdmin)
admin.site.register(Availability, AvailabilityAdmin)
2012-12-13 00:00:04 +01:00
admin.site.register(Training, TrainingAdmin)
2018-02-19 10:08:46 +01:00
admin.site.register(LogBookReason)
admin.site.register(LogBook)
admin.site.register(ExamEDESession)
2019-02-21 09:46:44 +01:00
admin.site.unregister(Group)
admin.site.register(Group, GroupAdmin)