diff --git a/indo/forms.py b/indo/forms.py index cb805d510321a68c4056ad4429300a734a749eeb..1eddf53208c33120434c14ab5eaab28027babfc1 100644 --- a/indo/forms.py +++ b/indo/forms.py @@ -188,3 +188,9 @@ class EvaluadorForm(forms.ModelForm): class Meta: fields = ('evaluador',) model = Proyecto + + +class ResolucionForm(forms.ModelForm): + class Meta: + fields = ('aceptacion_comision', 'ayuda_concedida', 'tipo_gasto', 'observaciones') + model = Proyecto diff --git a/indo/migrations/0009_auto_20200622_0844.py b/indo/migrations/0009_auto_20200622_0844.py new file mode 100644 index 0000000000000000000000000000000000000000..604fb26f0984bcc6232af0e38bafb520c9e79a45 --- /dev/null +++ b/indo/migrations/0009_auto_20200622_0844.py @@ -0,0 +1,81 @@ +# Generated by Django 3.0.7 on 2020-06-22 06:44 + +from django.apps import apps as django_apps +from django.db import migrations, models + + +def add_permission_to_group(apps, schema_editor): + group = apps.get_model('auth', 'Group') + permission = apps.get_model('auth', 'Permission') + + gestores = group.objects.get(name='Gestores') + permiso = permission.objects.get(codename='editar_aceptacion') + gestores.permissions.add(permiso) + + +def geo_post_migrate_signal(apps, schema_editor): + """Emit the post-migrate signal during the migration. + + Permissions are not actually created during or after an individual migration, + but are triggered by a post-migrate signal which is sent after the + `python manage.py migrate` command completes successfully. + + This is necessary because this permission is used later in this migration. + """ + indo_config = django_apps.get_app_config('indo') + models.signals.post_migrate.send( + sender=indo_config, + app_config=indo_config, + verbosity=2, + interactive=False, + using=schema_editor.connection.alias, + ) + + +class Migration(migrations.Migration): + + dependencies = [('indo', '0008_auto_20200611_1002')] + + operations = [ + migrations.AlterModelOptions( + name='proyecto', + options={ + 'permissions': [ + ('listar_proyectos', 'Puede ver el listado de todos los proyectos.'), + ('ver_proyecto', 'Puede ver cualquier proyecto.'), + ('editar_proyecto', 'Puede editar cualquier proyecto en cualquier momento.'), + ('listar_evaluadores', 'Puede ver el listado de evaluadores.'), + ('editar_evaluador', 'Puede editar el evaluador de un proyecto.'), + ('editar_aceptacion', 'Puede editar la decisión de la Comisión Evaluadora.'), + ] + }, + ), + migrations.AddField( + model_name='proyecto', + name='aceptacion_comision', + field=models.BooleanField(null=True, verbose_name='Aceptación por la comisión'), + ), + migrations.AddField( + model_name='proyecto', + name='ayuda_concedida', + field=models.PositiveIntegerField(null=True, verbose_name='Ayuda económica concedida'), + ), + migrations.AddField( + model_name='proyecto', + name='observaciones', + field=models.TextField( + null=True, verbose_name='Observaciones para comunicar al coordinador' + ), + ), + migrations.AddField( + model_name='proyecto', + name='tipo_gasto', + field=models.TextField( + help_text='Indicar los gastos autorizados indicados por la Comisión.', + null=True, + verbose_name='Tipo de gasto posible', + ), + ), + migrations.RunPython(geo_post_migrate_signal), + migrations.RunPython(add_permission_to_group), + ] diff --git a/indo/models.py b/indo/models.py index 5880b4eea262ace78aa496f8f51d372c4a4330a2..fbb91b6020a68af0d9dc478bb78511e2f60cd323 100644 --- a/indo/models.py +++ b/indo/models.py @@ -445,6 +445,15 @@ class Proyecto(models.Model): on_delete=models.PROTECT, related_name='proyectos_evaluados', ) + # Aprobación de la Comisión Evaluadora + aceptacion_comision = models.BooleanField(_('Aceptación por la comisión'), null=True) + ayuda_concedida = models.PositiveIntegerField(_('Ayuda económica concedida'), null=True) + tipo_gasto = models.TextField( + _('Tipo de gasto posible'), + help_text=_('Indicar los gastos autorizados indicados por la Comisión.'), + null=True, + ) + observaciones = models.TextField(_('Observaciones para comunicar al coordinador'), null=True) class Meta: permissions = [ @@ -453,6 +462,7 @@ class Proyecto(models.Model): ('editar_proyecto', _('Puede editar cualquier proyecto en cualquier momento.')), ('listar_evaluadores', _('Puede ver el listado de evaluadores.')), ('editar_evaluador', _('Puede editar el evaluador de un proyecto.')), + ('editar_aceptacion', _('Puede editar la decisión de la Comisión Evaluadora.')), ] def __str__(self): diff --git a/indo/tables.py b/indo/tables.py index 0a2e90d336c173fef7eab2088f4ef8e72d5229a4..39f4d634855a383770e5cda219ee57227084f1e0 100644 --- a/indo/tables.py +++ b/indo/tables.py @@ -18,8 +18,8 @@ class EvaluadoresTable(tables.Table): def render_editar(self, record): enlace = reverse('evaluador_update', args=[record.id]) return mark_safe( - f''' + f''' ''' ) @@ -46,8 +46,8 @@ class EvaluacionProyectosTable(tables.Table): def render_evaluacion(self, record): enlace = reverse('ver_evaluacion', args=[record.id]) return mark_safe( - f''' + f''' ''' if record.valoraciones.first() @@ -55,7 +55,15 @@ class EvaluacionProyectosTable(tables.Table): ) def render_resolucion(self, record): - return 'FIXME' + enlace = reverse('resolucion_update', args=[record.id]) + return mark_safe( + f''' + + ''' + if record.valoraciones.first() + else '—' + ) class Meta: attrs = {'class': 'table table-striped table-hover cabecera-azul'} @@ -78,8 +86,8 @@ class ProyectosEvaluadosTable(tables.Table): def render_boton_evaluar(self, record): enlace = reverse('evaluacion', args=[record.id]) return mark_safe( - f''' + f'''  {_('Evaluar')} ''' @@ -99,7 +107,7 @@ class ProyectosTable(tables.Table): def render_titulo(self, record): enlace = reverse('proyecto_detail', args=[record.id]) - return mark_safe(f"{record.titulo}") + return mark_safe(f'{record.titulo}') coordinadores = tables.Column( empty_values=(), orderable=False, verbose_name=_('Coordinador(es)') @@ -107,7 +115,7 @@ class ProyectosTable(tables.Table): def render_coordinadores(self, record): coordinadores = record.get_coordinadores() - enlaces = [f"{c.get_full_name()}" for c in coordinadores] + enlaces = [f'{c.get_full_name()}' for c in coordinadores] return mark_safe(', '.join(enlaces)) class Meta: diff --git a/indo/urls.py b/indo/urls.py index 0c0554690d6116320fbb56506ef74a905cdd17d8..67fe715aaf6eaf2ace8a29b42c69c5154eca7c1c 100644 --- a/indo/urls.py +++ b/indo/urls.py @@ -19,6 +19,7 @@ from .views import ( ProyectoEvaluacionesTableView, ProyectoEvaluadorTableView, ProyectoEvaluadorUpdateView, + ProyectoResolucionUpdateView, ProyectoTableView, ProyectoPresentarView, ProyectoUpdateFieldView, @@ -58,6 +59,11 @@ urlpatterns = [ ProyectoEvaluadorUpdateView.as_view(), name='evaluador_update', ), + path( + 'gestion/proyecto//editar_resolucion/', + ProyectoResolucionUpdateView.as_view(), + name='resolucion_update', + ), path( 'gestion/proyecto//evaluacion/', EvaluacionVerView.as_view(), name='ver_evaluacion' ), diff --git a/indo/views.py b/indo/views.py index a73e0e13dd71e239ba03b706cf8f4824c899aa7a..a399175b4af795b935be8e1dfef95ec240ce858c 100644 --- a/indo/views.py +++ b/indo/views.py @@ -21,6 +21,7 @@ from django.contrib.auth.mixins import ( UserPassesTestMixin, ) from django.contrib.auth.models import Group +from django.contrib.messages.views import SuccessMessageMixin from django.core.exceptions import ValidationError from django.core.validators import validate_email from django.forms.models import modelform_factory @@ -34,7 +35,7 @@ from django.views.generic import DetailView, RedirectView, TemplateView from django.views.generic.edit import CreateView, DeleteView, UpdateView # Local Django -from .forms import EvaluadorForm, InvitacionForm, ProyectoForm +from .forms import EvaluadorForm, InvitacionForm, ProyectoForm, ResolucionForm from .models import ( Centro, Convocatoria, @@ -316,6 +317,27 @@ class ProyectoEvaluadorUpdateView(LoginRequiredMixin, PermissionRequiredMixin, U return reverse('evaluadores_table', kwargs={'anyo': self.object.convocatoria}) +class ProyectoResolucionUpdateView( + LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageMixin, UpdateView +): + """Actualizar la resolución de la Comisión Evaluadora sobre un proyecto.""" + + permission_required = 'indo.editar_resolucion' + permission_denied_message = _('Sólo los gestores pueden acceder a esta página.') + model = Proyecto + success_message = _( + 'Se ha guardado la resolución de la comisión sobre el proyecto «%(titulo)s».' + ) + template_name = 'gestion/proyecto/editar_resolucion.html' + form_class = ResolucionForm + + def get_success_message(self, cleaned_data): + return self.success_message % dict(cleaned_data, titulo=self.object.titulo) + + def get_success_url(self): + return reverse_lazy('evaluaciones_table', args=[self.object.convocatoria_id]) + + class HomePageView(TemplateView): template_name = 'home.html' diff --git a/templates/gestion/proyecto/editar_evaluador.html b/templates/gestion/proyecto/editar_evaluador.html index cefd507971c8ca4ac9cf5b667edca67609d1e94b..c4b6157095819a14ad901350c1b81b1498b031c0 100644 --- a/templates/gestion/proyecto/editar_evaluador.html +++ b/templates/gestion/proyecto/editar_evaluador.html @@ -60,7 +60,7 @@ {{ form.as_p }}
- + {% trans 'Retroceder' %} + + +

{% trans 'Aquí puede editar la resolución de la Comisión Evaluadora sobre el proyecto.' %}

+

+ +

{{ proyecto.titulo }}

+
+ {% csrf_token %} + {{ form.as_p }} +
+
+ + {% trans 'Retroceder' %} + + +
+
+ +{% endblock content %} \ No newline at end of file