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