Conjunto de cambios 8edb1df en consulta_publica para consulta


Ignorar:
Fecha y hora:
08/06/2017 09:04:50 (hace 7 años)
Autor:
rudmanmrrod <rudman22@…>
Branches:
constituyente, estudiantes, general, plan_patria, sala
Children:
be17cf0
Parents:
4d11fe2
Mensaje:

Añadido reporte con filtro por territorio(estado,municipio o parroquia)

Ubicación:
consulta
Ficheros:
2 añadidos
7 editados

Leyenda

No modificado
Añadido
Eliminado
  • consulta/forms.py

    r2d85efb r8edb1df  
    1414# @version 1.0
    1515from django import forms
    16 from base.functions import cargar_tipo_pregunta
    1716from .models import Consulta
     17from base.functions import (
     18    cargar_tipo_pregunta, cargar_entidad, cargar_municipios,
     19    cargar_parroquias, cargar_preguntas
     20    )
     21from base.constant import (
     22    OBJETIVOS, SECTORES, PARTICIPACION,
     23    SECTOR_ESTUDIANTE, SECTOR_TRABAJADOR
     24    )
    1825
    1926class ConsultaForm(forms.ModelForm):
     
    8188        model = Consulta
    8289        exclude = ['user']
     90       
     91class ConsultaSearchForm(forms.Form):
     92    """!
     93    Clase del formulario para realizar busquedas y generar reportes
     94
     95    @author Rodrigo Boet (rboet at cenditel.gob.ve)
     96    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
     97    @date 31-05-2017
     98    @version 1.0.0
     99    """
     100    def __init__(self, *args, **kwargs):
     101        """!
     102        Metodo que sobreescribe cuando se inicializa el formulario
     103   
     104        @author Rodrigo Boet (rboet at cenditel.gob.ve)
     105        @copyright GNU/GPLv2
     106        @date 31-05-2017
     107        @param self <b>{object}</b> Objeto que instancia la clase
     108        @param args <b>{list}</b> Lista de los argumentos
     109        @param kwargs <b>{dict}</b> Diccionario con argumentos
     110        @return Retorna el formulario validado
     111        """
     112        super(ConsultaSearchForm, self).__init__(*args, **kwargs)
     113               
     114        self.fields['estado'].choices = cargar_entidad()
     115        self.fields['municipio'].choices = cargar_municipios()
     116        self.fields['parroquia'].choices = cargar_parroquias()
     117        self.fields['tipo_pregunta'].choices = cargar_preguntas(1)
     118   
     119    ## Tipo de pregunta para generar el reporte
     120    tipo_pregunta = forms.ChoiceField(widget=forms.Select(attrs={'class':'form-control'}),
     121        label="Tipo de Pregunta")
     122   
     123    ## Objetivo de la constituyente
     124    objetivo = forms.ChoiceField(
     125        widget=forms.Select(attrs={'class':'form-control'}),
     126        label="Objetivo de la Asamblea Nacional Constituyente",
     127        choices = (('','Seleccione...'),)+OBJETIVOS
     128        )
     129   
     130    ## estado
     131    estado = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control input-md',
     132        'onchange': "actualizar_combo(this.value,'base','Municipio','entidad','codigo','nombre','id_municipio')"}),
     133        required = False)
     134   
     135    ## municipio
     136    municipio = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control input-md',
     137        'onchange': "actualizar_combo(this.value,'base','Parroquia','municipio','codigo','nombre','id_parroquia')"}),
     138        required = False)
     139   
     140    ## parroquia
     141    parroquia = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control input-md',}),
     142        required = False)
     143   
     144    ## sector
     145    sector = forms.ChoiceField(
     146        widget=forms.Select(attrs={'class': 'form-control input-md','onchange':'mostrar_sector(this.value);'}),
     147        label="Sector",choices=(('','Seleccione...'),)+SECTORES,required = False
     148        )
     149   
     150    ## sector trabajador
     151    sector_trabajador = forms.ChoiceField(
     152        widget=forms.Select(attrs={'class': 'form-control input-md'}),
     153        label="Sector Trabajador",choices=(('','Seleccione...'),)+SECTOR_TRABAJADOR,
     154        required = False
     155        )
     156   
     157    ## sector estudiante
     158    sector_estudiante = forms.ChoiceField(
     159        widget=forms.Select(attrs={'class': 'form-control input-md',}),
     160        label="Sector Estudiante",choices=(('','Seleccione...'),)+SECTOR_ESTUDIANTE,
     161        required = False
     162        )
  • consulta/templates/consulta.base.column.graphic.html

    r7310249 r8edb1df  
    66        var total = 0;
    77        var datos = []
    8         $.each(valores,function(key,value){
    9             total+=value;
    10         });
    118        $.each(opciones,function(key){
    12             datos.push([opciones[key],(valores[key]/total)*100])
     9            datos.push([opciones[key],valores[key]])
    1310        });
    1411        // Build the chart
     
    2421            },
    2522            tooltip: {
    26                 pointFormat: '{series.name}: <b>{point.y:.1f}%</b>'
     23                pointFormat: '{series.name}: <b>{point.y}</b>'
    2724            },
    2825            xAxis: {
     
    3936                min: 0,
    4037                title: {
    41                     text: 'Porcentaje'
     38                    text: 'Cantidad'
    4239                }
    4340            },
     
    5451                    color: '#FFFFFF',
    5552                    align: 'right',
    56                     format: '{point.y:.1f}', // one decimal
     53                    format: '{point.y}', // one decimal
    5754                    y: 10, // 10 pixels down from the top
    5855                    style: {
  • consulta/templates/consulta.base.pie.graphic.html

    r7310249 r8edb1df  
    44        var opciones = {{item.opciones|safe}};
    55        var valores = {{item.valores}};
    6         var total = 0;
    76        var datos = []
    8         $.each(valores,function(key,value){
    9             total+=value;
    10         });
    117        $.each(opciones,function(key){
    12             datos.push({'name':opciones[key],'y':valores[key]/total})
     8            datos.push({'name':opciones[key],'y':valores[key]})
    139        });
    1410   
     
    2521            },
    2622            tooltip: {
    27                 pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
     23                pointFormat: '{series.name}: <b>{point.y}</b>'
    2824            },
    2925            plotOptions: {
     
    3834            },
    3935            series: [{
    40                 name: 'Porcentaje',
     36                name: 'Usuarios',
    4137                colorByPoint: true,
    4238                data: datos
  • consulta/templates/consulta.detail.html

    r250830e r8edb1df  
    2929    {% if respuestas %}
    3030        <a type="button" class="btn btn-white" href="{% url 'consulta_stats' consulta.id %}"> Estadísticas <i class="glyphicon glyphicon-stats"></i></a>
     31        <a type="button" class="btn btn-white" href="{% url 'consulta_report' consulta.id %}"> Generar Reportes <i class="glyphicon glyphicon-list-alt"></i></a>
    3132    {% endif %}
    3233    {% if respuestas_abierta %}
  • consulta/templates/consulta.stats.html

    rbf6bc0b r8edb1df  
    77{% block contenido %}
    88    <h1 class="text-center">Resultados de la Consulta</h1>
    9     {% for item in preguntas_opciones %}
    10         {% include 'consulta.base.column.graphic.html' with item=item counter=forloop.counter name='opciones'%}
     9    {% for item in participacion %}
     10        {% include 'consulta.base.column.graphic.html' with item=item counter=forloop.counter name='objetivos'%}
    1111    {% endfor %}
    12     {% for item in preguntas_sino %}
    13         {% include 'consulta.base.pie.graphic.html' with item=item counter=forloop.counter name='sino' %}
     12    {% for item in usuarios %}
     13        {% include 'consulta.base.pie.graphic.html' with item=item counter=forloop.counter name='usuarios'%}
    1414    {% endfor %}
     15
    1516{% endblock %}
  • consulta/urls.py

    r7310249 r8edb1df  
    2424    url(r'^list$', ConsultaList.as_view(), name = "consulta_list"),
    2525    url(r'^stats/(?P<pk>\d+)$', ConsultaStats.as_view(), name = "consulta_stats"),
     26    url(r'^report/(?P<pk>\d+)$', ConsultaReport.as_view(), name = "consulta_report"),
     27    url(r'^pdf/(?P<pk>\d+)/(?P<tipo_pregunta>\d+)/(?P<objetivo>\d+)$', ConsultaPdf.as_view(), name = "consulta_pdf"),
    2628    url(r'^delete/(?P<pk>\d+)$', ConsultaDelete.as_view(), name = "consulta_delete"),
    2729    url(r'^detail/(?P<pk>\d+)$', ConsultaDetail.as_view(), name = "consulta_detail"),
  • consulta/views.py

    r0b2127c r8edb1df  
    1515import json
    1616from django.shortcuts import render
     17from django.conf import settings
    1718from django.core.urlresolvers import reverse_lazy
    1819from django.http import JsonResponse
    1920from django.contrib.auth.models import User
    20 from django.views.generic import CreateView, ListView, TemplateView, DeleteView, DetailView, UpdateView
     21from django.views.generic import (
     22    CreateView, ListView, TemplateView, DeleteView,
     23    DetailView, UpdateView, FormView
     24    )
    2125from django.contrib.messages.views import SuccessMessageMixin
    2226from django.contrib.auth.mixins import LoginRequiredMixin
    2327from braces.views import GroupRequiredMixin
     28from easy_pdf.views import PDFTemplateView
    2429from .models import Consulta, Pregunta, TipoPregunta, Opcion
    25 from .forms import ConsultaForm, ConsultaPreguntaForm
     30from .forms import ConsultaForm, ConsultaPreguntaForm, ConsultaSearchForm
    2631from participacion.models import RespuestaSino, RespuestaOpciones, RespuestaAbierta
     32from users.models import Perfil
     33from base.constant import OBJETIVOS
     34from base.models import Entidad, Municipio, Parroquia
    2735 
    2836class ConsultaIndex(GroupRequiredMixin, LoginRequiredMixin, TemplateView):
     
    250258        @return Retorna los datos de contexto
    251259        """
    252         preguntas_opciones = []
    253         preguntas_sino = []
    254         for pregunta in Pregunta.objects.filter(consulta_id=self.kwargs['pk']).exclude(tipo_pregunta_id=5).all():
    255             if pregunta.tipo_pregunta_id<3:
    256                 preguntas_opciones.append(self.get_pregunta_opciones(pregunta.id,pregunta.texto_pregunta))
    257             elif pregunta.tipo_pregunta_id<5:
    258                 preguntas_sino.append(self.get_pregunta_sino(pregunta.id,pregunta.texto_pregunta))
    259         kwargs['preguntas_opciones'] = preguntas_opciones
    260         kwargs['preguntas_sino'] = preguntas_sino
    261                        
     260        participacion = {}
     261        opciones = []
     262        valores = []
     263        for item in OBJETIVOS:
     264            respuesta = RespuestaAbierta.objects.filter(pregunta__consulta_id=self.kwargs['pk'],objetivo=item[0]).count()
     265            opciones.append(item[1].encode('utf8'))
     266            valores.append(respuesta)
     267        kwargs['usuarios'] = [self.get_users()]
     268        kwargs['participacion'] = [{'titulo':'Respuestas por Objetivo de la Constituyente','opciones':json.dumps(opciones),'valores':valores}]
    262269        return super(ConsultaStats, self).get_context_data(**kwargs)
     270   
     271    def get_users(self):
     272        """!
     273        Metodo que permite cargar los usuarios por grupos de roles
     274   
     275        @author Rodrigo Boet (rboet at cenditel.gob.ve)
     276        @copyright GNU/GPLv2
     277        @date 31-05-2017
     278        @param self <b>{object}</b> Objeto que instancia la clase
     279        @return Retorna los datos del usuario
     280        """
     281        participantes = User.objects.filter(groups__name='Participante').count()
     282        administradores = User.objects.filter(groups__name='Administrador').count()
     283        data = {}
     284        data['titulo'] = 'Usuarios Registrados'
     285        data['opciones'] = ['Participante','Administrador']
     286        data['valores'] = [participantes, administradores]
     287        return data
     288       
    263289   
    264290    def get_pregunta_opciones(self,id,titulo):
     
    303329        return data
    304330   
     331class ConsultaReport(GroupRequiredMixin, LoginRequiredMixin, FormView):
     332    """!
     333    Clase que gestiona la vista principal de los reportes
     334
     335    @author Rodrigo Boet (rboet at cenditel.gob.ve)
     336    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
     337    @date 31-05-2017
     338    @version 1.0.0
     339    """
     340    template_name = "consulta.report.html"
     341    group_required = u"Administrador"
     342    form_class = ConsultaSearchForm
     343   
     344    def get_success_url(self):
     345        """!
     346        Metodo que permite definir la url de dirección al ser válido el formulario
     347       
     348        @author Rodrigo Boet (rboet at cenditel.gob.ve)
     349        @copyright GNU/GPLv2
     350        @date 01-06-2017
     351        @param self <b>{object}</b> Objeto que instancia la clase
     352        @return Retorna la url
     353        """
     354        tipo_pregunta = self.request.POST['tipo_pregunta']
     355        objetivo = self.request.POST['objetivo']
     356        estado = self.request.POST.get('estado','')
     357        municipio = self.request.POST.get('municipio','')
     358        parroquia = self.request.POST.get('parroquia','')
     359        sector = self.request.POST.get('sector','')
     360        sector_trabajador = self.request.POST.get('sector_trabajador','')
     361        sector_estudiante = self.request.POST.get('sector_estudiante','')
     362        url = '%s?estado=%s&municipio=%s&parroquia=%s&sector=%s&sector_trabajador=%s&sector_estudiante=%s' % (reverse_lazy('consulta_pdf',
     363            kwargs={'pk': self.kwargs['pk'],'tipo_pregunta': tipo_pregunta,'objetivo': objetivo}),
     364            estado,municipio,parroquia,sector,sector_trabajador,sector_estudiante)
     365        return url
     366   
     367    def get_context_data(self, **kwargs):
     368        """!
     369        Metodo que permite cargar de nuevo valores en los datos de contexto de la vista
     370   
     371        @author Rodrigo Boet (rboet at cenditel.gob.ve)
     372        @copyright GNU/GPLv2
     373        @date 17-02-2017
     374        @param self <b>{object}</b> Objeto que instancia la clase
     375        @param kwargs <b>{object}</b> Objeto que contiene los datos de contexto
     376        @return Retorna los datos de contexto
     377        """
     378        kwargs['pk'] = self.kwargs['pk']
     379        return super(ConsultaReport, self).get_context_data(**kwargs)
     380   
     381class ConsultaPdf(PDFTemplateView):
     382    """!
     383    Clase que gestiona la renderización de reportes en PDF
     384
     385    @author Rodrigo Boet (rboet at cenditel.gob.ve)
     386    @copyright <a href='http://www.gnu.org/licenses/gpl-2.0.html'>GNU Public License versión 2 (GPLv2)</a>
     387    @date 01-06-2017
     388    @version 1.0.0
     389    """
     390    template_name = 'consulta.pdf.template.html'
     391
     392    def get_context_data(self, **kwargs):
     393        """!
     394        Metodo que permite cargar de nuevo valores en los datos de contexto de la vista
     395   
     396        @author Rodrigo Boet (rboet at cenditel.gob.ve)
     397        @copyright GNU/GPLv2
     398        @date 01-06-2017
     399        @param self <b>{object}</b> Objeto que instancia la clase
     400        @param kwargs <b>{object}</b> Objeto que contiene los datos de contexto
     401        @return Retorna los datos de contexto
     402        """
     403        pk = int(self.kwargs['pk'])
     404        tipo_pregunta = int(self.kwargs['tipo_pregunta'])
     405        objetivo = int(self.kwargs['objetivo'])
     406        ## Variables por get
     407        estado = self.request.GET['estado']
     408        municipio = self.request.GET['municipio']
     409        parroquia = self.request.GET['parroquia']
     410        sector = self.request.GET['sector']
     411        sector_trabajador = self.request.GET['sector_trabajador']
     412        sector_estudiante = self.request.GET['sector_estudiante']
     413        resp = 0
     414        est, mun, parr = 0, 0, 0
     415        preg = Pregunta.objects.get(pk=pk).texto_pregunta
     416        if tipo_pregunta == 1:
     417            resp = RespuestaSino.objects.filter(pregunta__consulta_id=pk,objetivo=objetivo)
     418        elif tipo_pregunta == 2:
     419            resp = RespuestaAbierta.objects.filter(pregunta__consulta_id=pk,objetivo=objetivo)
     420        elif tipo_pregunta == 3:   
     421            resp = RespuestaOpciones.objects.filter(opcion__pregunta__consulta_id=pk,objetivo=objetivo)
     422        ## Se validan los filtros por territorio
     423        if estado == '':
     424            datos = []
     425            for estado in Entidad.objects.all():
     426                data = Perfil.objects.filter(parroquia__municipio__entidad_id=estado.id,user_id__in=resp.values_list('user_id',flat=True)).count()
     427                datos.append([estado.nombre,data])
     428            kwargs['estados'] = datos
     429        elif estado !='' and (municipio=='' and parroquia==''):
     430            est = Perfil.objects.filter(parroquia__municipio__entidad_id=estado,user_id__in=resp.values_list('user_id',flat=True))
     431            kwargs['lugar'] = est.count()
     432            kwargs['ubicacion'] = Entidad.objects.get(pk=estado)
     433        elif municipio!='' and parroquia=='':
     434            mun = Perfil.objects.filter(parroquia__municipio_id=municipio,user_id__in=resp.values_list('user_id',flat=True))
     435            kwargs['lugar'] = mun.count()
     436            kwargs['ubicacion'] = Municipio.objects.filter(pk=municipio)
     437        elif parroquia!='':
     438            parr = Perfil.objects.filter(parroquia_id=parroquia,user_id__in=resp.values_list('user_id',flat=True))
     439            kwargs['lugar'] = parr.count()
     440            kwargs['ubicacion'] = Parroquia.objects.get(pk=parroquia)
     441        ## Se validan los filtros por sector
     442        if sector!='':
     443            pass
     444        kwargs['respuestas'] = resp.count()
     445        kwargs['pregunta_texto'] = preg
     446        kwargs['objetivo_texto'] = OBJETIVOS[objetivo-1][1]
     447        return super(ConsultaPdf, self).get_context_data(**kwargs)
     448
    305449   
    306450class OpcionesCreate(GroupRequiredMixin, LoginRequiredMixin,CreateView):
     
    316460    fields = ['texto_opcion']
    317461    template_name = "consulta.create.html"
    318     success_url = reverse_lazy('consulta_index')
    319462    group_required = u"Administrador"
    320463           
Nota: Vea TracChangeset para ayuda en el uso del visor de conjuntos de cambios.