diff --git a/common/urls.py b/common/urls.py index 68d1e40..8b9ad0e 100644 --- a/common/urls.py +++ b/common/urls.py @@ -18,6 +18,9 @@ urlpatterns = patterns('', url(r'^attribution/$', views.AttributionView.as_view(), name='attribution'), url(r'^stages/export/$', 'stages.views.stages_export', name='stages_export'), + url(r'^institutions/$', views.CorporationListView.as_view(), name='corporations'), + url(r'^institutions/(?P\d+)/$', views.CorporationView.as_view(), name='corporation'), + # AJAX/JSON urls url(r'^section/(?P\d+)/periods/', 'stages.views.section_periods'), url(r'^section/(?P\d+)/classes/', 'stages.views.section_classes'), diff --git a/stages/models.py b/stages/models.py index d9ca6d1..c6198fd 100644 --- a/stages/models.py +++ b/stages/models.py @@ -163,6 +163,19 @@ class Period(models.Model): def dates(self): return '%s - %s' % (self.start_date, self.end_date) + @property + def school_year(self): + if self.start_date.month < 8: + start_year = self.start_date.year - 1 + else: + start_year = self.start_date.year + return "%d — %d" % (start_year, start_year + 1) + + @property + def weeks(self): + """ Return the number of weeks of this period """ + return (self.end_date - self.start_date).days // 7 + class Availability(models.Model): """ Disponibilités des institutions """ diff --git a/stages/static/img/edit.png b/stages/static/img/edit.png new file mode 100644 index 0000000..cb1bd1a Binary files /dev/null and b/stages/static/img/edit.png differ diff --git a/stages/tests.py b/stages/tests.py index 2feed15..5a0b7f6 100644 --- a/stages/tests.py +++ b/stages/tests.py @@ -1,8 +1,11 @@ +# -*- encoding: utf-8 -*- +from __future__ import unicode_literals + from django.contrib.auth.models import User from django.core.urlresolvers import reverse from django.test import TestCase -from .models import Student, Availability, Referent +from .models import Period, Student, Availability, Referent class StagesTest(TestCase): fixtures = ['test_fixture.json'] @@ -29,4 +32,12 @@ class StagesTest(TestCase): self.assertEqual(response.content, b'OK') avail = Availability.objects.get(pk=2) self.assertEqual(avail.training.student, student) - + + def test_period_schoolyear(self): + per = Period.objects.get(pk=1) + self.assertEqual(per.school_year, "2012 — 2013") + + def test_period_weeks(self): + per = Period.objects.get(pk=1) + self.assertEqual(per.weeks, 1) + diff --git a/stages/views.py b/stages/views.py index 2c5d6e1..0c75a0c 100644 --- a/stages/views.py +++ b/stages/views.py @@ -7,6 +7,7 @@ from datetime import date from django.db.models import Count from django.http import HttpResponse, HttpResponseNotAllowed from django.shortcuts import get_object_or_404 +from django.utils.datastructures import SortedDict from django.views.generic import DetailView, TemplateView, ListView from .forms import PeriodForm @@ -23,6 +24,41 @@ def school_year_start(): return date(current_year, 8, 1) +class CorporationListView(ListView): + model = Corporation + template_name = 'corporations.html' + + +class CorporationView(DetailView): + model = Corporation + template_name = 'corporation.html' + context_object_name = 'corp' + + def get_context_data(self, **kwargs): + context = super(CorporationView, self).get_context_data(**kwargs) + # Create a structure like: + # {'2011-2012': {'avails': [avail1, avail2, ...], 'stats': {'fil': num}}, + # '2012-2013': ...} + school_years = SortedDict() + for av in Availability.objects.filter(corporation=self.object + ).select_related('training__student__klass', 'period__section' + ).order_by('period__start_date'): + if av.period.school_year not in school_years: + school_years[av.period.school_year] = {'avails': [], 'stats': {}} + school_years[av.period.school_year]['avails'].append(av) + if av.period.section.name not in school_years[av.period.school_year]['stats']: + school_years[av.period.school_year]['stats'][av.period.section.name] = 0 + try: + av.training + # Only add to stats if training exists + school_years[av.period.school_year]['stats'][av.period.section.name] += av.period.weeks + except Training.DoesNotExist: + pass + + context['years'] = school_years + return context + + class StudentSummaryView(DetailView): model = Student template_name = 'student_summary.html' @@ -69,11 +105,14 @@ class AttributionView(TemplateView): context = super(AttributionView, self).get_context_data(**kwargs) # Need 2 queries, because referents with no training item would not appear in the second query referents = Referent.objects.all().order_by('last_name', 'first_name') + + # Populate each referent with the number of referencies done during the current school year ref_counts = dict([(ref.id, ref.num_refs) for ref in Referent.objects.filter(training__availability__period__end_date__gte=school_year_start ).annotate(num_refs=Count('training'))]) for ref in referents: ref.num_refs = ref_counts.get(ref.id, 0) + context.update({ #'period_form': PeriodForm(), 'sections': Section.objects.all(), diff --git a/templates/admin/index.html b/templates/admin/index.html index 6493ea8..ca10402 100644 --- a/templates/admin/index.html +++ b/templates/admin/index.html @@ -2,7 +2,13 @@ {% load i18n admin_static %} {% load url from future %} -{% block extrastyle %}{{ block.super }}{% endblock %} +{% block extrastyle %}{{ block.super }} + + +{% endblock %} {% block coltype %}colMS{% endblock %} @@ -13,6 +19,10 @@ {% block content %}
+ + {% if app_list %} {% for app in app_list %}
diff --git a/templates/corporation.html b/templates/corporation.html new file mode 100644 index 0000000..262aca6 --- /dev/null +++ b/templates/corporation.html @@ -0,0 +1,56 @@ +{% extends "admin/base_site.html" %} +{% load i18n %} + +{% block extrastyle %} + +{% endblock %} + +{% block breadcrumbs %} + +{% endblock %} + +{% block content %} +
+

{{ corp.name }}

+ + + + + + + + + + +
Adresse :{{ corp.street }}
+ {{ corp.pcode }} {{ corp.city }}
+ Tél: {{ corp.tel }}
+ {% if corp.email %}{{ corp.email }}
{% endif %} + {% if corp.web %}{{ corp.web }}
{% endif %} +
Type de structure :{{ corp.typ }}
Contacts :{% for cont in corp.corpcontact_set.all %} + {{ cont.first_name }} {{ cont.last_name }} {% if cont.role %} ({{ cont.role }}){% endif %}{% endfor %} +
+ +{% for year, data in years.items %} +

{{ year }}

+ + {% for avail in data.avails %} + + + + + {% endfor %} + + + +
{{ avail.period.dates }}{% if not avail.training %}Disponibilité{% else %}{{ avail.training.student }} ({{ avail.training.student.klass }}){% endif %}{{ avail.period.section }}
Totaux :{% for fil, num in data.stats.items %}{{ fil }} : {{ num }} semaine(s)
{% endfor %}
+{% endfor %} + +{% endblock %} diff --git a/templates/corporations.html b/templates/corporations.html new file mode 100644 index 0000000..4778ea2 --- /dev/null +++ b/templates/corporations.html @@ -0,0 +1,12 @@ +{% extends "admin/base_site.html" %} + +{% block content %} +

Liste des institutions

+ + +{% for corp in object_list %} + + +{% endfor %} +
{{ corp.name }}{{ corp.pcode }} {{ corp.city }}
+{% endblock %}