# -*- coding: utf-8 -*-
"""
Sistema de Consulta Pública
Copyleft (@) 2017 CENDITEL nodo Mérida - https://planificacion.cenditel.gob.ve/trac/wiki/ModeladoTopicos_2017
"""
## @package participacion.views
#
# Vistas correspondientes a la aplicación participacion
# @author Rodrigo Boet (rboet at cenditel.gob.ve)
# @author Centro Nacional de Desarrollo e Investigación en Tecnologías Libres
# (CENDITEL) nodo Mérida - Venezuela
# @copyright GNU Public License versión 2 (GPLv2)
# @version 1.0
import json
from django.shortcuts import render, redirect
from django.core.urlresolvers import reverse_lazy
from django.http import JsonResponse
from django.views.generic import FormView, TemplateView
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
from braces.views import GroupRequiredMixin
from base.constant import OBJETIVOS_DEFINICION
from .forms import ParticipacionSelectForm, ParticipacionSearchForm
from .models import RespuestaAbierta, RespuestaOpciones, RespuestaSino
from consulta.models import Pregunta, Opcion
import requests
class ParticipacionIndex(GroupRequiredMixin,LoginRequiredMixin,FormView):
"""!
Clase que gestiona la vista principal de la participación
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU Public License versión 2 (GPLv2)
@date 22-02-2017
@version 1.0.0
"""
template_name = "participacion.index.html"
form_class = ParticipacionSelectForm
group_required = u"Participante"
def get_success_url(self):
"""!
Metodo que permite definir la url de dirección al ser válido el formulario
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 22-02-2017
@param self {object} Objeto que instancia la clase
@return Retorna la url
"""
consulta = self.request.POST['consultas']
if(consulta!="3"):
return reverse_lazy('participacion_busqueda',
kwargs={'pk': consulta})
else:
return reverse_lazy('participacion_simple', kwargs={'pk': consulta})
class ParticipacionSearch(GroupRequiredMixin,LoginRequiredMixin,FormView):
"""!
Clase que gestiona la busqueda para la participación
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU Public License versión 2 (GPLv2)
@date 23-02-2017
@version 1.0.0
"""
template_name = "participacion.search.html"
form_class = ParticipacionSearchForm
group_required = u"Participante"
def get_success_url(self):
"""!
Metodo que permite definir la url de dirección al ser válido el formulario
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 23-02-2017
@param self {object} Objeto que instancia la clase
@return Retorna la url
"""
objetivo = self.request.POST['objetivo']
return reverse_lazy('participacion_consulta', kwargs={'pk': self.kwargs['pk'],'id_objetivo':objetivo})
class ParticipacionCreate(GroupRequiredMixin,LoginRequiredMixin,TemplateView):
"""!
Clase que gestiona la vista principal de la participación
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU Public License versión 2 (GPLv2)
@date 22-02-2017
@version 1.0.0
"""
template_name = "participacion.create.html"
group_required = u"Participante"
def get_context_data(self, **kwargs):
"""!
Metodo que permite cargar de nuevo valores en los datos de contexto de la vista
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 23-02-2017
@param self {object} Objeto que instancia la clase
@param kwargs {object} Objeto que contiene los datos de contexto
@return Retorna los datos de contexto
"""
valores = {}
for pregunta in Pregunta.objects.filter(consulta_id=kwargs['pk']).all():
label = ''
campo = ''
if pregunta.tipo_pregunta.id == 1:
campo = ''
for opcion in Opcion.objects.filter(pregunta_id=pregunta.id).all():
campo += ''
elif pregunta.tipo_pregunta.id == 2:
campo = ''
for opcion in Opcion.objects.filter(pregunta_id=pregunta.id).all():
campo += ''
elif pregunta.tipo_pregunta.id > 2 and pregunta.tipo_pregunta.id < 5:
if(pregunta.tipo_pregunta.id == 3):
campo += ''
campo += ''
else:
campo += ''
campo += ''
campo += '
'
campo += '
'
else:
campo += ' '
campo += ''
campo += ''
valores[pregunta.id] = {'label':label,'field':campo}
kwargs['preguntas'] = valores
kwargs['objetivo'] = OBJETIVOS_DEFINICION[int(kwargs['id_objetivo'])-1][1]
return super(ParticipacionCreate, self).get_context_data(**kwargs)
def post(self,request,pk,id_objetivo):
"""!
Metodo que sobreescribe el post del formulario
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 20-03-2017
@param self {object} Objeto que instancia la clase
@param request {object} Objeto que instancia la petición
@param pk {int} Recibe el id de la consulta
@param id_ente {int} Recibe el id del ente
@return Retorna los datos de contexto
"""
data = dict(request.POST)
del data['csrfmiddlewaretoken']
if self.request.is_ajax():
for key in data.keys():
parent_id = key.split("_")[-1]
if 'sino' in key:
value = True if data[key][0] == 'Si' else False
justify_id = 'consulta_respuesta_justificar_'+str(parent_id)
self.crear_respuesta_sino(parent_id,value,id_objetivo,self.request.user.id)
if(not value and justify_id in data.keys()):
respuesta = data[justify_id][0]
self.crear_respuesta_abierta(parent_id,respuesta,id_objetivo,self.request.user.id,True)
elif 'radio' in key or 'check' in key:
for value in data[key]:
self.crear_respuesta_opciones(value,id_objetivo,self.request.user.id)
elif 'abierta' in key:
value = data[key][0]
self.crear_respuesta_abierta(parent_id,value,id_objetivo,self.request.user.id)
return JsonResponse({"code":True})
return redirect(reverse_lazy('participacion_busqueda',kwargs={'pk':pk}))
def crear_respuesta_sino(self,parent_id,value,id_objetivo,user_id):
"""!
Metodo para crear una respuesta de si/no
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 27-03-2017
@param self {object} Objeto que instancia la clase
@param parent_id {int} Recibe el número del id del padre
@param value {bool} Recibe el valor de la respuesta
@param id_objetivo {int} Recibe el id del objetivo
@param user_id {int} Recibe el id del user
@return Retorna los datos de contexto
"""
user = User.objects.get(id=user_id)
parent = Pregunta.objects.get(pk=parent_id)
respuesta = RespuestaSino()
respuesta.pregunta = parent
respuesta.respuesta = value
respuesta.user = user
respuesta.save()
def crear_respuesta_opciones(self,parent_id,id_objetivo,user_id):
"""!
Metodo para crear una respuesta de selección simple y múltiple
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 28-03-2017
@param self {object} Objeto que instancia la clase
@param parent_id {int} Recibe el número del id del padre
@param id_objetivo {int} Recibe el id del objetivo
@param user_id {int} Recibe el id del user
@return Retorna los datos de contexto
"""
user = User.objects.get(id=user_id)
parent = Opcion.objects.get(pk=parent_id)
respuesta = RespuestaOpciones()
respuesta.opcion = parent
respuesta.user = user
respuesta.save()
def crear_respuesta_abierta(self,parent_id,value,id_objetivo,user_id,es_justificacion = False):
"""!
Metodo para crear una respuesta abierta
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 28-03-2017
@param self {object} Objeto que instancia la clase
@param parent_id {int} Recibe el número del id del padre
@param value {str} Recibe el valor de la respuesta
@param ente {int} Recibe el id del ente
@param user_id {int} Recibe el id del user
@param es_justificacion {bool} Recibe el párametro que indica si es una justifiación
@return Retorna los datos de contexto
"""
user = User.objects.get(id=user_id)
parent = Pregunta.objects.get(pk=parent_id)
respuesta = RespuestaAbierta()
respuesta.pregunta = parent
respuesta.objetivo = id_objetivo
respuesta.texto_respuesta = value
respuesta.user = user
respuesta.es_justificacion = es_justificacion
respuesta.save()
def validar_participacion(request):
"""!
Función que valida si un usuario ya participó en la consulta con un ente en particular
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 21-04-2017
@param request {object} Objeto que contiene la petición
@return Retorna un json con la respuesta
"""
if not request.is_ajax():
return JsonResponse({'mensaje': False, 'error': str('La solicitud no es ajax')})
objetivo = request.GET.get('objetivo', None)
consulta = request.GET.get('consulta', None)
if(objetivo and consulta):
respuesta_sino = RespuestaSino.objects.filter(pregunta__consulta=consulta)
respuesta_abierta = RespuestaAbierta.objects.filter(pregunta__consulta=consulta,objetivo=objetivo)
respuesta_opciones = RespuestaOpciones.objects.filter(opcion__pregunta__consulta=consulta)
if(respuesta_sino or respuesta_abierta or respuesta_opciones):
return JsonResponse({'mensaje': True,'participacion':True})
return JsonResponse({'mensaje': True,'participacion':False})
else:
return JsonResponse({'mensaje': False, 'error': str('No envío el ente y/o el id de la consulta')})
class ParticipacionSimpleCreate(GroupRequiredMixin,LoginRequiredMixin,TemplateView):
"""!
Clase que gestiona la vista principal de la participación simple
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU Public License versión 2 (GPLv2)
@date 18-07-2017
@version 1.0.0
"""
template_name = "participacion.create.simple.html"
group_required = u"Participante"
def get_context_data(self, **kwargs):
"""!
Metodo que permite cargar de nuevo valores en los datos de contexto de la vista
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 23-02-2017
@param self {object} Objeto que instancia la clase
@param kwargs {object} Objeto que contiene los datos de contexto
@return Retorna los datos de contexto
"""
valores = {}
for pregunta in Pregunta.objects.filter(consulta_id=kwargs['pk']).all():
label = ''
campo = ''
if pregunta.tipo_pregunta.id == 1:
campo = ''
for opcion in Opcion.objects.filter(pregunta_id=pregunta.id).all():
campo += ''
elif pregunta.tipo_pregunta.id == 2:
campo = ''
for opcion in Opcion.objects.filter(pregunta_id=pregunta.id).all():
campo += ''
elif pregunta.tipo_pregunta.id > 2 and pregunta.tipo_pregunta.id < 5:
if(pregunta.tipo_pregunta.id == 3):
campo += ''
campo += ''
else:
campo += ''
campo += ''
campo += '
'
campo += '
'
valores[pregunta.id] = {'label':label,'field':campo}
kwargs['preguntas'] = valores
return super(ParticipacionSimpleCreate, self).get_context_data(**kwargs)
def post(self,request,pk,id_objetivo):
"""!
Metodo que sobreescribe el post del formulario
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 20-03-2017
@param self {object} Objeto que instancia la clase
@param request {object} Objeto que instancia la petición
@param pk {int} Recibe el id de la consulta
@param id_ente {int} Recibe el id del ente
@return Retorna los datos de contexto
"""
data = dict(request.POST)
del data['csrfmiddlewaretoken']
if self.request.is_ajax():
for key in data.keys():
parent_id = key.split("_")[-1]
if 'sino' in key:
value = True if data[key][0] == 'Si' else False
justify_id = 'consulta_respuesta_justificar_'+str(parent_id)
self.crear_respuesta_sino(parent_id,value,id_objetivo,self.request.user.id)
if(not value and justify_id in data.keys()):
respuesta = data[justify_id][0]
self.crear_respuesta_abierta(parent_id,respuesta,id_objetivo,self.request.user.id,True)
elif 'radio' in key or 'check' in key:
for value in data[key]:
self.crear_respuesta_opciones(value,id_objetivo,self.request.user.id)
return JsonResponse({"code":True})
return redirect(reverse_lazy('participacion_busqueda',kwargs={'pk':pk}))
def crear_respuesta_sino(self,parent_id,value,id_objetivo,user_id):
"""!
Metodo para crear una respuesta de si/no
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 27-03-2017
@param self {object} Objeto que instancia la clase
@param parent_id {int} Recibe el número del id del padre
@param value {bool} Recibe el valor de la respuesta
@param id_objetivo {int} Recibe el id del objetivo
@param user_id {int} Recibe el id del user
@return Retorna los datos de contexto
"""
user = User.objects.get(id=user_id)
parent = Pregunta.objects.get(pk=parent_id)
respuesta = RespuestaSino()
respuesta.pregunta = parent
respuesta.respuesta = value
respuesta.user = user
respuesta.save()
def crear_respuesta_opciones(self,parent_id,id_objetivo,user_id):
"""!
Metodo para crear una respuesta de selección simple y múltiple
@author Rodrigo Boet (rboet at cenditel.gob.ve)
@copyright GNU/GPLv2
@date 28-03-2017
@param self {object} Objeto que instancia la clase
@param parent_id {int} Recibe el número del id del padre
@param id_objetivo {int} Recibe el id del objetivo
@param user_id {int} Recibe el id del user
@return Retorna los datos de contexto
"""
user = User.objects.get(id=user_id)
parent = Opcion.objects.get(pk=parent_id)
respuesta = RespuestaOpciones()
respuesta.opcion = parent
respuesta.user = user
respuesta.save()