diff --git a/sigi/apps/saberes/__init__.py b/sigi/apps/saberes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sigi/apps/saberes/admin.py b/sigi/apps/saberes/admin.py new file mode 100644 index 0000000..ab79b76 --- /dev/null +++ b/sigi/apps/saberes/admin.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +from django.utils.translation import ugettext as _ +from django.contrib import admin +from sigi.apps.saberes.models import CategoriasInteresse + +class CategoriasInteresseAdmin(admin.ModelAdmin): + list_display = ('prefixo', 'descricao', 'count_categorias',) + + def count_categorias(self, obj): + return obj.categorias().count() + count_categorias.short_description = _("Categorias que casam") +admin.site.register(CategoriasInteresse, CategoriasInteresseAdmin) \ No newline at end of file diff --git a/sigi/apps/saberes/models.py b/sigi/apps/saberes/models.py new file mode 100644 index 0000000..85dbdcd --- /dev/null +++ b/sigi/apps/saberes/models.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals +from django.utils.translation import ugettext as _ +from django.db import models +from django.db.models import Q +from sigi.apps.mdl.models import Course, CourseCategories, CourseCompletions, UserEnrolments + +class CategoriasInteresse(models.Model): + prefixo = models.CharField(_(u"Prefixo das categorias no Moodle"), max_length=100, + help_text=_(u"Identifica as categorias no Moodle (campo idnumber) relacionadas a este interesse")) + descricao = models.CharField(_(u"Descrição"), max_length=100) + sigla = models.CharField(_(u"Sigla"), max_length=20) + coorte = models.BooleanField(_(u"Usa Cohorte"), default=False, help_text=_(u"Usa cohorte para calcular o número de matrículas/alunos")) + apurar_alunos = models.BooleanField(_(u"Apurar alunos"), default=False, help_text=_(u"Indica que deve-se verificar o perfil da"\ + + " inscrição para saber se é um aluno ou se a matrícula foi rejeitada")) + apurar_conclusao = models.BooleanField(_(u"Apurar conclusão"), default=False, help_text=_(u"Indica se o dashboard mostrará o "\ + + "número de alunos aprovados, reprovados e desistentes")) + + class Meta: + verbose_name = _(u'Categorias de interesse') + + def __unicode__(self): + return self.descricao + + def categorias(self): + return CourseCategories.objects.filter(idnumber__startswith=self.prefixo) + + def get_all_courses(self, only_visible=False): + q = Course.objects.none() + for categoria in self.categorias(): + q = q | categoria.get_all_courses(only_visible=only_visible) + return q + + def get_all_completions(self): + q = CourseCompletions.objects.none() + for c in self.get_all_courses(): + q = q | c.coursecompletions_set.all() + return q + + def get_all_enrolments(self): + q = UserEnrolments.objects.none() + for c in self.get_all_courses(): + q = q | c.get_matriculas() + return q + + def total_alunos(self): + if self.coorte: + return sum(c.total_alunos_cohort() for c in self.categorias()) + else: + return sum([c.total_alunos() for c in self.categorias()]) \ No newline at end of file diff --git a/sigi/apps/saberes/templates/saberes/dashboard.html b/sigi/apps/saberes/templates/saberes/dashboard.html new file mode 100644 index 0000000..209b1c4 --- /dev/null +++ b/sigi/apps/saberes/templates/saberes/dashboard.html @@ -0,0 +1,20 @@ +{% extends "admin/base_site.html" %} + +{% block extrastyle %} + {{ block.super }} + +{% endblock %} + +{% block content %} +
+ {% include "saberes/snippets.html" %} +
+{% endblock %} diff --git a/sigi/apps/saberes/templates/saberes/snippets.html b/sigi/apps/saberes/templates/saberes/snippets.html new file mode 100644 index 0000000..7af7c2c --- /dev/null +++ b/sigi/apps/saberes/templates/saberes/snippets.html @@ -0,0 +1,22 @@ +{% load charts %} + +
+ {% for painel in paineis %} +
+
+
{{ painel.titulo }}
+
+ + {% for linha in painel.dados %} + + + + + {% endfor %} +
{{ linha.descricao }}{{ linha.valor }}
+
+
+
+ {% cycle '' '' '
' %} + {% endfor %} +
\ No newline at end of file diff --git a/sigi/apps/saberes/tests.py b/sigi/apps/saberes/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/sigi/apps/saberes/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/sigi/apps/saberes/urls.py b/sigi/apps/saberes/urls.py new file mode 100644 index 0000000..c4dc77e --- /dev/null +++ b/sigi/apps/saberes/urls.py @@ -0,0 +1,6 @@ +# coding: utf-8 +from django.conf.urls import patterns, url + +urlpatterns = patterns('sigi.apps.saberes.views', + url(r'^dashboard/$', 'dashboard', name="saberes-dashboard-view"), +) \ No newline at end of file diff --git a/sigi/apps/saberes/views.py b/sigi/apps/saberes/views.py new file mode 100644 index 0000000..b8a0082 --- /dev/null +++ b/sigi/apps/saberes/views.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- + +from django.utils.translation import ugettext as _ +from django.db.models import Count +from django.shortcuts import render, render_to_response +from django.template import RequestContext +from sigi.apps.mdl.models import User, CourseStatus +from sigi.apps.saberes.models import CategoriasInteresse + +def dashboard(request): + areas = [] + numeros = [ + {'descricao': _(u'Total de usuários cadastrados'), 'valor': User.objects.count()}, + {'descricao': _(u'Novos usuários cadastrados') , 'valor': User.objects.filter(firstaccess__gte=1392326052).count()} + ] + + for ci in CategoriasInteresse.objects.all(): + matriculas = ci.total_alunos() + numeros.append({'descricao': _(u'Total de matrículas em %s' % ci.descricao.lower()), 'valor': matriculas}) + area = {'titulo': ci.descricao, 'dados': [{'descricao': _(u'Total de matrículas'), 'valor': matriculas}]} + for course in ci.get_all_courses(only_visible=True): + area['dados'].append({'descricao': course.fullname, 'valor': course.total_alunos()}) +# if ci.apurar_alunos: # Apurar número de alunos +# valor = sum([curso.total_ativos() for curso in ci.get_all_courses()]) +# area['dados'].append({'descricao': _(u'Total de alunos aceitos'), 'valor': valor}) +# if ci.apurar_conclusao: +# cl = [curso.id for curso in ci.get_all_courses()] +# for cs in CourseStatus.objects.filter(courseid__in=cl).values('status').annotate(valor=Count('userid')): +# area['dados'].append({'descricao': cs['status'], 'valor': cs['valor']}) +# + areas.append(area) + + paineis = [{'titulo': _(u'Saberes em números'), 'dados': numeros}] + areas + + + totais = [] + +# for i in MapaCategorias.INTERESSE_CHOICES: +# totais.append({'nome': i[1], 'total_turmas': '', 'total_alunos': '', 'padding': 0}) +# for mapa in MapaCategorias.objects.filter(area_interesse=i[0]): +# totais.append({'nome': mapa.categoria.name, 'total_turmas': mapa.total_turmas(), 'total_alunos': mapa.total_alunos(), 'padding': 1}) +# for c in mapa.categoria.children.all(): +# totais.append({'nome': c.name, 'total_turmas': c.total_turmas(), 'total_alunos': c.total_alunos(), 'padding': 2}) + + tutorias = [] + +# for mapa in MapaCategorias.objects.filter(area_interesse='CT'): +# tutorias.append({'nome': mapa.categoria.name, 'inscritos': mapa.total_alunos(), 'padding': 0}) +# for c in mapa.categoria.courses.all(): +# tutorias.append({'nome': c.fullname, 'inscritos': c.total_alunos(), 'padding': 1}) + + extra_context = {'numeros': numeros, 'paineis': paineis, 'totais': totais, 'tutorias': tutorias} + + return render_to_response('saberes/dashboard.html', extra_context, context_instance=RequestContext(request)) \ No newline at end of file