feat Descargar CSV con las valoraciones de todos los proyectos presentados

parent 0a61a719
Pipeline #580 failed with stage
in 0 seconds
from django.db import models
from django.db import connection, models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
......@@ -547,3 +547,49 @@ class Valoracion(models.Model):
class Meta:
verbose_name = _('valoración')
verbose_name_plural = _('valoraciones')
@classmethod
def get_todas(cls, anyo):
"""Devuelve las valoraciones de todos los proyectos presentados en el año indicado."""
criterios = Criterio.objects.filter(convocatoria_id=anyo).all()
with connection.cursor() as cursor:
cursor.execute(
f'''
SELECT DISTINCT prog.nombre_corto, l.nombre, p.id, p.titulo
FROM indo_valoracion v
JOIN indo_proyecto p ON v.proyecto_id = p.id
JOIN indo_programa prog ON p.programa_id = prog.id
JOIN indo_linea l ON p.linea_id = l.id
WHERE prog.convocatoria_id = {anyo}
ORDER BY proyecto_id;
'''
)
rows = cursor.fetchall()
valoraciones = list(zip(*rows))
for criterio in criterios:
cursor.execute(
f'''
SELECT CASE
WHEN c.tipo = 'opcion' THEN o.puntuacion
WHEN c.tipo = 'texto' THEN v.texto
ELSE NULL
END AS valoracion
FROM indo_valoracion v
JOIN indo_criterio c ON v.criterio_id = c.id
LEFT JOIN indo_opcion o ON v.opcion_id = o.id
WHERE v.criterio_id = {criterio.id}
ORDER BY v.proyecto_id, c.parte, c.peso;
'''
)
rows = cursor.fetchall()
fila_plana = [row[0] for row in rows]
valoraciones.append(fila_plana)
valoraciones = list(zip(*valoraciones))
cabeceras = [('Programa'), _('Línea'), _('ID'), _('Título')]
cabeceras.extend([criterio.descripcion for criterio in criterios])
valoraciones.insert(0, cabeceras)
return valoraciones
......@@ -15,6 +15,7 @@ from .views import (
ProyectoAnularView,
ProyectoCreateView,
ProyectoDetailView,
ProyectoEvaluacionesCsvView,
ProyectoEvaluacionesTableView,
ProyectoEvaluadorTableView,
ProyectoEvaluadorUpdateView,
......@@ -42,6 +43,11 @@ urlpatterns = [
ProyectoEvaluacionesTableView.as_view(),
name='evaluaciones_table',
),
path(
'gestion/proyectos/<int:anyo>/csv_evaluaciones/',
ProyectoEvaluacionesCsvView.as_view(),
name='csv_evaluaciones',
),
path(
'gestion/proyectos/<int:anyo>/evaluadores/',
ProyectoEvaluadorTableView.as_view(),
......
# Standard library
import csv
import json
from datetime import date
......@@ -23,11 +24,12 @@ from django.contrib.auth.models import Group
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.forms.models import modelform_factory
from django.http import Http404
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse, reverse_lazy
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.generic import DetailView, RedirectView, TemplateView
from django.views.generic.edit import CreateView, DeleteView, UpdateView
......@@ -288,7 +290,7 @@ class ProyectoEvaluadorUpdateView(LoginRequiredMixin, PermissionRequiredMixin, U
def get(self, request, *args, **kwargs):
# Obtenemos los NIPs de los usuarios con vinculación «Evaluador externo innovacion ACPUA».
nip_evaluadores = [136040, 327618, 329639, 370109] # FIXME - WS G.I.
nip_evaluadores = [136_040, 327_618, 329_639, 370_109] # FIXME - WS G.I.
# Creamos los usuarios que no existan ya en la aplicación.
User = get_user_model()
evaluadores = Group.objects.get(name='Evaluadores')
......@@ -564,6 +566,21 @@ class ProyectoDetailView(LoginRequiredMixin, ChecksMixin, DetailView):
return self.esta_vinculado_o_es_decano_o_es_coordinador(proyecto_id)
class ProyectoEvaluacionesCsvView(LoginRequiredMixin, PermissionRequiredMixin, View):
"""Devuelve un fichero CSV con las valoraciones de todos los proyectos presentados."""
permission_required = 'indo.listar_evaluaciones'
permission_denied_message = _('Sólo los gestores pueden acceder a esta página.')
def get(self, request, *args, **kwargs):
valoraciones = Valoracion.get_todas(kwargs.get('anyo'))
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="valoraciones.csv"'
writer = csv.writer(response)
writer.writerows(valoraciones)
return response
class ProyectoEvaluacionesTableView(LoginRequiredMixin, PermissionRequiredMixin, SingleTableView):
"""Muestra los proyectos presentados y enlaces a su evaluación y resolución de la Comisión."""
......@@ -629,9 +646,9 @@ class ProyectoPresentarView(LoginRequiredMixin, ChecksMixin, RedirectView):
request,
_(
f'''No puede presentar esta solicitud porque ya forma parte
del número máximo de equipos de trabajo permitido ({num_max_equipos}).
Para poder presentar esta solicitud de proyecto, antes debería renunciar
a participar en algún otro proyecto.'''
del número máximo de equipos de trabajo permitido ({num_max_equipos}).
Para poder presentar esta solicitud de proyecto, antes debería renunciar
a participar en algún otro proyecto.'''
),
)
return super().post(request, *args, **kwargs)
......
......@@ -14,12 +14,20 @@
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<span class="fas fa-info-circle"></span>
{% blocktrans %}
Desde esta página puede ver las evaluaciones de los proyectos presentados en esta convocatoria,
así como introducir la resolución de la Comisión Evaluadora.
{% endblocktrans %}
<p>{% trans 'Desde esta página puede:' %}</p>
<ul>
<li>{% trans 'Ver las evaluaciones de los proyectos presentados en esta convocatoria' %}</li>
<li>{% trans 'Introducir la resolución de la Comisión Evaluadora' %}</li>
<li>{% trans 'Descargar una hoja de cálculo con todas las evaluaciones' %}</li>
</ul>
</div><br />
{% render_table table %}
<div>
<a href="{% url 'csv_evaluaciones' anyo %}" class="btn btn-info">
<span class="fas fa-file-csv"></span>&nbsp; {% trans "Descargar evaluaciones" %}
</a>
</div
</div>
{% endblock content %}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment