Add institution detail view with stats
This commit is contained in:
parent
f6ff281d4b
commit
4b6a8d50c3
8 changed files with 147 additions and 3 deletions
|
|
@ -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<pk>\d+)/$', views.CorporationView.as_view(), name='corporation'),
|
||||
|
||||
# AJAX/JSON urls
|
||||
url(r'^section/(?P<pk>\d+)/periods/', 'stages.views.section_periods'),
|
||||
url(r'^section/(?P<pk>\d+)/classes/', 'stages.views.section_classes'),
|
||||
|
|
|
|||
|
|
@ -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 """
|
||||
|
|
|
|||
BIN
stages/static/img/edit.png
Normal file
BIN
stages/static/img/edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@
|
|||
{% load i18n admin_static %}
|
||||
{% load url from future %}
|
||||
|
||||
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}" />{% endblock %}
|
||||
{% block extrastyle %}{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}">
|
||||
<style>
|
||||
ul#main { margin: 1em; }
|
||||
ul#main li { font-size: 14px; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block coltype %}colMS{% endblock %}
|
||||
|
||||
|
|
@ -13,6 +19,10 @@
|
|||
{% block content %}
|
||||
<div id="content-main">
|
||||
|
||||
<ul id="main">
|
||||
<li><b><a href="{% url 'corporations' %}">Liste des institutions</a></b></li>
|
||||
</ul>
|
||||
|
||||
{% if app_list %}
|
||||
{% for app in app_list %}
|
||||
<div class="module">
|
||||
|
|
|
|||
56
templates/corporation.html
Normal file
56
templates/corporation.html
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block extrastyle %}
|
||||
<style>
|
||||
h3 {background-color: #eee; padding: 4px;}
|
||||
tr.totaux td {font-style: italic;}
|
||||
tr.dispo td {font-style: italic; color: green;}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
|
||||
› <a href="{% url 'corporations' %}">Liste des institutions</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div style="float:right;"><a href="{% url 'admin:stages_corporation_change' corp.pk %}"><img src="{{ STATIC_URL }}img/edit.png" title="Modifier"></a></div>
|
||||
<h2>{{ corp.name }}</h2>
|
||||
<table width="100%">
|
||||
<tr><th rowspan="2">Adresse :</th>
|
||||
<td rowspan="2">{{ corp.street }}<br>
|
||||
{{ corp.pcode }} {{ corp.city }}<br>
|
||||
Tél: {{ corp.tel }}<br>
|
||||
{% if corp.email %}<a href="mailto:{{ corp.email }}">{{ corp.email }}</a><br>{% endif %}
|
||||
{% if corp.web %}<a href="{{ corp.web }}">{{ corp.web }}</a><br>{% endif %}
|
||||
</td>
|
||||
<th>Type de structure :</th>
|
||||
<td>{{ corp.typ }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Contacts :</th>
|
||||
<td>{% for cont in corp.corpcontact_set.all %}
|
||||
<a href="{% url 'admin:stages_corpcontact_change' cont.pk %}">{{ cont.first_name }} {{ cont.last_name }}</a> {% if cont.role %} ({{ cont.role }}){% endif %}{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
{% for year, data in years.items %}
|
||||
<h3>{{ year }}</h3>
|
||||
<table>
|
||||
{% for avail in data.avails %}
|
||||
<tr class="{% if not avail.training %}dispo{% endif %}">
|
||||
<td>{{ avail.period.dates }}</td>
|
||||
<td>{% if not avail.training %}Disponibilité{% else %}{{ avail.training.student }} ({{ avail.training.student.klass }}){% endif %}</td>
|
||||
<td>{{ avail.period.section }}</td></tr>
|
||||
{% endfor %}
|
||||
<tr class="totaux"><td colspan="2" align="right" valign="top">Totaux :</td>
|
||||
<td>{% for fil, num in data.stats.items %}{{ fil }} : {{ num }} semaine(s)<br>{% endfor %}</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
12
templates/corporations.html
Normal file
12
templates/corporations.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{% extends "admin/base_site.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Liste des institutions</h2>
|
||||
|
||||
<table>
|
||||
{% for corp in object_list %}
|
||||
<tr class="{% cycle 'row1' 'row2' %}">
|
||||
<td><a href="{% url 'corporation' corp.pk %}">{{ corp.name }}</a></td><td>{{ corp.pcode }} {{ corp.city }}</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue