Add a corporation merge form (no link to UI yet)

This commit is contained in:
Claude Paroz 2019-01-10 15:49:20 +01:00
parent 6ad597b392
commit 59229c514b
5 changed files with 114 additions and 2 deletions

View file

@ -290,6 +290,7 @@ class AvailabilityInline(admin.StackedInline):
formfield_overrides = {
models.TextField: {'widget': forms.Textarea(attrs={'rows':2, 'cols':40})},
}
autocomplete_fields = ['corporation']
class PeriodAdmin(admin.ModelAdmin):

View file

@ -1,8 +1,12 @@
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.urls import reverse
from tabimport import FileFactory, UnsupportedFileFormat
from .models import Section, Period
from .models import Corporation, Section, Period
class StudentImportForm(forms.Form):
@ -51,3 +55,61 @@ class EmailBaseForm(forms.Form):
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()

View file

@ -19,7 +19,7 @@ from django.views.generic import DetailView, FormView, TemplateView, ListView
from .base import EmailConfirmationBaseView, ZippedFilesBaseView
from .export import OpenXMLExport
from .imports import HPContactsImportView, HPImportView, ImportReportsView, StudentImportView
from ..forms import EmailBaseForm
from ..forms import CorporationMergeForm, EmailBaseForm
from ..models import (
Klass, Section, Student, Teacher, Corporation, CorpContact, Period,
Training, Availability
@ -66,6 +66,27 @@ class CorporationView(DetailView):
return context
class CorporationMergeView(FormView):
form_class = CorporationMergeForm
template_name = 'corporation_merge.html'
success_url = reverse_lazy('corporations')
def form_valid(self, form):
if form.data['step'] != '2':
return self.render_to_response(self.get_context_data(form=form))
form.merge_corps()
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['step'] = '1'
if context['form'].is_bound and context['form'].is_valid():
context['step'] = '2'
context['contacts_from'] = context['form'].cleaned_data['corp_merge_from'].corpcontact_set.all()
context['contacts_to'] = context['form'].cleaned_data['corp_merge_to'].corpcontact_set.all()
return context
class KlassListView(ListView):
queryset = Klass.active.order_by('section', 'name')
template_name = 'classes.html'