Add link between CorpContact and Section, export according to that link

This commit is contained in:
Claude Paroz 2016-01-15 21:01:07 +01:00
parent 2c5bb00c8d
commit d45742d88f
6 changed files with 65 additions and 22 deletions

View file

@ -41,15 +41,29 @@ class CorpContactAdmin(admin.ModelAdmin):
list_display = ('__str__', 'corporation', 'role')
ordering = ('last_name', 'first_name')
search_fields = ('last_name', 'first_name', 'role')
fields = (('corporation', 'is_main', 'always_cc'),
fields = (('corporation',), ('sections', 'is_main', 'always_cc'),
('title', 'last_name', 'first_name'),
'role', ('tel', 'email'))
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
class ContactInline(admin.StackedInline):
model = CorpContact
fields = (('is_main', 'always_cc'), ('title', 'last_name', 'first_name'),
fields = (('sections', 'is_main', 'always_cc'),
('title', 'last_name', 'first_name'),
('role', 'tel', 'email'))
extra = 1
formfield_overrides = {
models.ManyToManyField: {'widget': forms.CheckboxSelectMultiple},
}
class CorporationAdmin(admin.ModelAdmin):
list_display = ('name', 'short_name', 'pcode', 'city')

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-15 18:24
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stages', '0003_add_corp_fields'),
]
operations = [
migrations.AddField(
model_name='corpcontact',
name='sections',
field=models.ManyToManyField(blank=True, to='stages.Section'),
),
]

View file

@ -151,6 +151,7 @@ class CorpContact(models.Model):
role = models.CharField(max_length=40, verbose_name='Fonction', blank=True)
tel = models.CharField(max_length=20, blank=True, verbose_name='Téléphone')
email = models.CharField(max_length=100, blank=True, verbose_name='Courriel')
sections = models.ManyToManyField(Section, blank=True)
class Meta:
verbose_name = "Contact"

View file

@ -17,7 +17,7 @@ class StagesTest(TestCase):
self.client.login(username='me', password='mepassword')
def test_export(self):
response1 = self.client.get(reverse('stages_export'))
response1 = self.client.get(reverse('stages_export', args=['all']))
self.assertEqual(response1.status_code, 200)
response2 = self.client.get(reverse('stages_export'), {'period': '2', 'non_attr': '0'})

View file

@ -1,6 +1,3 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
import json
from collections import OrderedDict
from datetime import date, datetime, timedelta
@ -215,7 +212,8 @@ def del_training(request):
EXPORT_FIELDS = [
('Prénom', 'student__first_name'), ('Nom', 'student__last_name'),
('ID externe', 'student__ext_id'),
('Classe', 'student__klass__name'), ('Filière', 'student__klass__section__name'),
('Classe', 'student__klass__name'),
('Filière', 'student__klass__section__name'),
('Nom du stage', 'availability__period__title'),
('Début', 'availability__period__start_date'), ('Fin', 'availability__period__end_date'),
('Remarques stage', 'comment'),
@ -258,7 +256,6 @@ NON_ATTR_EXPORT_FIELDS = [
]
def stages_export(request, scope=None):
from datetime import date
from openpyxl import Workbook
from openpyxl.styles import Font, Style
from openpyxl.writer.excel import save_virtual_workbook
@ -266,7 +263,7 @@ def stages_export(request, scope=None):
period_filter = request.GET.get('period')
non_attributed = bool(int(request.GET.get('non_attr', 0)))
export_fields = EXPORT_FIELDS
export_fields = OrderedDict(EXPORT_FIELDS)
contact_test_field = 'availability__contact__last_name'
corp_name_field = 'availability__corporation__name'
@ -274,7 +271,7 @@ def stages_export(request, scope=None):
if non_attributed:
# Export non attributed availabilities for a specific period
query = Availability.objects.filter(period_id=period_filter, training__isnull=True)
export_fields = NON_ATTR_EXPORT_FIELDS
export_fields = OrderedDict(NON_ATTR_EXPORT_FIELDS)
contact_test_field = 'contact__last_name'
corp_name_field = 'corporation__name'
else:
@ -288,38 +285,49 @@ def stages_export(request, scope=None):
query = Training.objects.filter(availability__period__end_date__gt=school_year_start())
# Prepare "default" contacts (when not defined on training)
default_contacts = dict((c, '') for c in Corporation.objects.all().values_list('name', flat=True))
always_ccs = dict((c, []) for c in Corporation.objects.all().values_list('name', flat=True))
for contact in CorpContact.objects.all().select_related('corporation').order_by('corporation'):
if not default_contacts[contact.corporation.name] or contact.is_main is True:
default_contacts[contact.corporation.name] = contact
if contact.always_cc:
always_ccs[contact.corporation.name].append(contact)
section_names = Section.objects.all().values_list('name', flat=True)
default_contacts = dict(
(c, {s: '' for s in section_names})
for c in Corporation.objects.all().values_list('name', flat=True)
)
always_ccs = dict(
(c, {s: [] for s in section_names})
for c in Corporation.objects.all().values_list('name', flat=True)
)
for contact in CorpContact.objects.all().select_related('corporation'
).prefetch_related('sections').order_by('corporation'):
for section in contact.sections.all():
if not default_contacts[contact.corporation.name][section.name] or contact.is_main is True:
default_contacts[contact.corporation.name][section.name] = contact
if contact.always_cc:
always_ccs[contact.corporation.name][section.name].append(contact)
wb = Workbook()
ws = wb.get_active_sheet()
ws.title = 'Stages'
bold = Style(font=Font(bold=True))
# Headers
for col_idx, header in enumerate([f[0] for f in export_fields], start=1):
for col_idx, header in enumerate(export_fields.keys(), start=1):
cell = ws.cell(row=1, column=col_idx)
cell.value = header
cell.style = bold
# Data
query_keys = [f[1] for f in export_fields if f[1] is not None]
query_keys = [f for f in export_fields.values() if f is not None]
for row_idx, tr in enumerate(query.values(*query_keys), start=2):
for col_idx, field in enumerate(query_keys, start=1):
ws.cell(row=row_idx, column=col_idx).value = tr[field]
if tr[contact_test_field] is None:
# Use default contact
contact = default_contacts.get(tr[corp_name_field])
contact = default_contacts.get(tr[corp_name_field], {}).get(tr[export_fields['Filière']])
if contact:
ws.cell(row=row_idx, column=col_idx-3).value = contact.title
ws.cell(row=row_idx, column=col_idx-2).value = contact.first_name
ws.cell(row=row_idx, column=col_idx-1).value = contact.last_name
ws.cell(row=row_idx, column=col_idx).value = contact.email
if always_ccs[tr[corp_name_field]]:
ws.cell(row=row_idx, column=col_idx+1).value = "; ".join([c.email for c in always_ccs[tr[corp_name_field]]])
if always_ccs[tr[corp_name_field]].get(tr[export_fields['Filière']]):
ws.cell(row=row_idx, column=col_idx+1).value = "; ".join(
[c.email for c in always_ccs[tr[corp_name_field]].get(tr[export_fields['Filière']])]
)
response = HttpResponse(save_virtual_workbook(wb), content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename=%s%s.xlsx' % (