epcstages/stages/forms.py

141 lines
5.4 KiB
Python

from django import forms
from django.contrib.admin.widgets import AutocompleteSelect
from django.db import transaction
from django.db.models.deletion import Collector
from django.forms import inlineformset_factory
from django.urls import reverse
from django_summernote.widgets import SummernoteWidget
from tabimport import FileFactory, UnsupportedFileFormat
from .models import Corporation, Period, Section, Student, StudentFile
class StudentImportForm(forms.Form):
upload = forms.FileField()
def __init__(self, file_label='Fichier', mandatory_headers=None, **kwargs):
super().__init__(**kwargs)
self.fields['upload'].label = file_label
self.mandatory_headers = mandatory_headers
def clean_upload(self):
f = self.cleaned_data['upload']
try:
imp_file = FileFactory(f)
except UnsupportedFileFormat as e:
raise forms.ValidationError("Erreur: %s" % e)
# Check needed headers are present
headers = imp_file.get_headers()
missing = set(self.mandatory_headers) - set(headers)
if missing:
raise forms.ValidationError("Erreur: il manque les colonnes %s" % (
", ".join(missing)))
return f
class PeriodForm(forms.Form):
section = forms.ModelChoiceField(queryset=Section.objects.all())
period = forms.ModelChoiceField(queryset=None)
def __init__(self, data, *args, **kwargs):
pass
class UploadHPFileForm(forms.Form):
upload = forms.FileField(label='Fichier HyperPlanning')
class UploadReportForm(forms.Form):
semester = forms.ChoiceField(label='Semestre', choices=(('1', '1'), ('2', '2')), required=True)
upload = forms.FileField(label='Bulletins CLOEE (pdf)')
class EmailBaseForm(forms.Form):
sender = forms.CharField(widget=forms.HiddenInput())
to = forms.CharField(widget=forms.TextInput(attrs={'size': '60'}))
cci = forms.CharField(widget=forms.TextInput(attrs={'size': '60'}))
subject = forms.CharField(widget=forms.TextInput(attrs={'size': '60'}))
message = forms.CharField(widget=forms.Textarea(attrs={'rows': 20, 'cols': 120}))
class CorpAutocompleteSelect(AutocompleteSelect):
model = Corporation
def __init__(self, **kwargs):
super().__init__(None, None, **kwargs)
def get_url(self):
return reverse(self.url_name % ('admin', self.model._meta.app_label, self.model._meta.model_name))
class CorporationMergeForm(forms.Form):
corp_merge_from = forms.ModelChoiceField(
label="L'institution", queryset=Corporation.objects.filter(archived=False),
widget=CorpAutocompleteSelect
)
corp_merge_to = forms.ModelChoiceField(
label="Sera fusionnée dans", queryset=Corporation.objects.filter(archived=False),
widget=CorpAutocompleteSelect
)
def merge_corps(self):
def check_no_links(instance):
collector = Collector(using='default')
collector.collect(instance._meta.model.objects.filter(pk=instance.pk))
if len(collector.data) > 1:
raise Exception(collector.data)
with transaction.atomic():
# Try first to merge corpcontacts with same name
merge_to_contacts = {
(cont.last_name, cont.first_name): cont
for cont in self.cleaned_data['corp_merge_to'].corpcontact_set.all()
}
for contact in self.cleaned_data['corp_merge_from'].corpcontact_set.all():
ckey = (contact.last_name, contact.first_name)
if ckey in merge_to_contacts:
# Merge contacts
for rel in (
'availability_set', 'candidate_set', 'rel_expert', 'rel_mentor',
'rel_supervisor', 'student_set', 'supervisionbill_set'):
relation = getattr(contact, rel)
relation.all().update(**{relation.field.name: merge_to_contacts[ckey]})
check_no_links(contact)
contact.delete()
# Merge corporation now
self.cleaned_data['corp_merge_from'].corpcontact_set.all(
).update(corporation=self.cleaned_data['corp_merge_to'])
self.cleaned_data['corp_merge_from'].availability_set.all(
).update(corporation=self.cleaned_data['corp_merge_to'])
self.cleaned_data['corp_merge_from'].student_set.all(
).update(corporation=self.cleaned_data['corp_merge_to'])
self.cleaned_data['corp_merge_from'].candidate_set.all(
).update(corporation=self.cleaned_data['corp_merge_to'])
check_no_links(self.cleaned_data['corp_merge_from'])
self.cleaned_data['corp_merge_from'].delete()
class StudentCommentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('mc_comment',)
widgets = {
'mc_comment': SummernoteWidget,
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
FilesFormSet = inlineformset_factory(self._meta.model, StudentFile, fields='__all__', extra=1)
self.files_fset = FilesFormSet(
instance=self.instance, data=kwargs.get('data'), files=kwargs.get('files')
)
def is_valid(self):
return all([super().is_valid(), self.files_fset.is_valid()])
def save(self, **kwargs):
obj = super().save(**kwargs)
self.files_fset.save()
return obj