diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index 83af42eb8..0b4607bd1 100644 --- a/sapl/sessao/forms.py +++ b/sapl/sessao/forms.py @@ -2,15 +2,16 @@ from datetime import datetime import django_filters from crispy_forms.helper import FormHelper -from crispy_forms.layout import Fieldset, Layout +from crispy_forms.layout import HTML, Button, Fieldset, Layout from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.forms import ModelForm from django.utils.translation import ugettext_lazy as _ from sapl.crispy_layout_mixin import form_actions, to_row +from sapl.materia.forms import MateriaLegislativaFilterSet from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa -from sapl.utils import RANGE_DIAS_MES, RANGE_MESES +from sapl.utils import RANGE_DIAS_MES, RANGE_MESES, autor_label, autor_modal from .models import Bancada, ExpedienteMateria, SessaoPlenaria @@ -171,3 +172,76 @@ class SessaoPlenariaFilterSet(django_filters.FilterSet): row1, form_actions(save_label='Pesquisar')) ) + + +class AdicionarVariasMateriasFilterSet(MateriaLegislativaFilterSet): + class Meta: + model = MateriaLegislativa + fields = ['numero', + 'numero_protocolo', + 'ano', + 'tipo', + 'data_apresentacao', + 'data_publicacao', + 'autoria__autor__tipo', + 'autoria__partido', + 'relatoria__parlamentar_id', + 'local_origem_externa', + 'em_tramitacao', + ] + + order_by = ( + ('', 'Selecione'), + ('dataC', 'Data, Tipo, Ano, Numero - Ordem Crescente'), + ('dataD', 'Data, Tipo, Ano, Numero - Ordem Decrescente'), + ('tipoC', 'Tipo, Ano, Numero, Data - Ordem Crescente'), + ('tipoD', 'Tipo, Ano, Numero, Data - Ordem Decrescente') + ) + + def __init__(self, *args, **kwargs): + super(MateriaLegislativaFilterSet, self).__init__(*args, **kwargs) + + self.filters['tipo'].label = 'Tipo de Matéria' + self.filters['autoria__autor__tipo'].label = 'Tipo de Autor' + self.filters['autoria__partido'].label = 'Partido do Autor' + self.filters['relatoria__parlamentar_id'].label = 'Relatoria' + + row1 = to_row( + [('tipo', 12)]) + row2 = to_row( + [('numero', 4), + ('ano', 4), + ('numero_protocolo', 4)]) + row3 = to_row( + [('data_apresentacao', 6), + ('data_publicacao', 6)]) + row4 = to_row( + [('autoria__autor', 0), + (Button('pesquisar', + 'Pesquisar Autor', + css_class='btn btn-primary btn-sm'), 2), + (Button('limpar', + 'limpar Autor', + css_class='btn btn-primary btn-sm'), 10)]) + row5 = to_row( + [('autoria__autor__tipo', 6), + ('autoria__partido', 6)]) + row6 = to_row( + [('relatoria__parlamentar_id', 6), + ('local_origem_externa', 6)]) + row7 = to_row( + [('em_tramitacao', 6), + ('o', 6)]) + row8 = to_row( + [('ementa', 12)]) + + self.form.helper = FormHelper() + self.form.helper.form_method = 'GET' + self.form.helper.layout = Layout( + Fieldset(_('Pesquisa de Matéria'), + row1, row2, row3, + HTML(autor_label), + HTML(autor_modal), + row4, row5, row6, row7, row8, + form_actions(save_label='Pesquisar')) + ) diff --git a/sapl/sessao/migrations/0021_adicionamultiplasmaterias.py b/sapl/sessao/migrations/0021_adicionamultiplasmaterias.py new file mode 100644 index 000000000..7eb3dbd48 --- /dev/null +++ b/sapl/sessao/migrations/0021_adicionamultiplasmaterias.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-03 14:27 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0038_auto_20160612_1506'), + ('sessao', '0020_auto_20160517_1450'), + ] + + operations = [ + migrations.CreateModel( + name='AdicionaMultiplasMaterias', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('materia', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.MateriaLegislativa')), + ], + options={ + 'verbose_name_plural': 'Tabela de Adicionar Várias Matérias', + 'verbose_name': 'Tabela de Adicionar Várias Matérias', + }, + ), + ] diff --git a/sapl/sessao/migrations/0022_auto_20160805_0943.py b/sapl/sessao/migrations/0022_auto_20160805_0943.py new file mode 100644 index 000000000..51acbf4ef --- /dev/null +++ b/sapl/sessao/migrations/0022_auto_20160805_0943.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-08-05 12:43 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sessao', '0021_adicionamultiplasmaterias'), + ] + + operations = [ + migrations.RemoveField( + model_name='adicionamultiplasmaterias', + name='materia', + ), + migrations.DeleteModel( + name='AdicionaMultiplasMaterias', + ), + ] diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index ef1a4c7be..28ceb8517 100644 --- a/sapl/sessao/urls.py +++ b/sapl/sessao/urls.py @@ -1,6 +1,8 @@ from django.conf.urls import include, url -from sapl.sessao.views import (BancadaCrud, CargoBancadaCrud, +from sapl.sessao.views import (AdicionarVariasMateriasExpediente, + AdicionarVariasMateriasOrdemDia, + BancadaCrud, CargoBancadaCrud, EditMateriaOrdemDiaView, ExpedienteMateriaCrud, ExpedienteView, ListMateriaOrdemDiaView, MateriaOrdemDiaView, MesaView, OradorCrud, @@ -49,6 +51,12 @@ urlpatterns = [ include(BancadaCrud.get_urls())), url(r'^sistema/cargo-bancada/', include(CargoBancadaCrud.get_urls())), + url(r'^sessao/(?P\d+)/adicionar-varias-materias-expediente/', + AdicionarVariasMateriasExpediente.as_view(), + name='adicionar_varias_materias_expediente'), + url(r'^sessao/(?P\d+)/adicionar-varias-materias-ordem-dia/', + AdicionarVariasMateriasOrdemDia.as_view(), + name='adicionar_varias_materias_ordem_dia'), # PAUTA SESSÃO url(r'^pauta-sessao$', diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 7cdb90d2a..9fb5417de 100644 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -6,9 +6,10 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.urlresolvers import reverse from django.forms.utils import ErrorList from django.http.response import HttpResponseRedirect +from django.utils.datastructures import MultiValueDictKeyError from django.utils.html import strip_tags from django.utils.translation import ugettext_lazy as _ -from django.views.generic import ListView, TemplateView +from django.views.generic import FormView, ListView, TemplateView from django.views.generic.edit import FormMixin from django_filters.views import FilterView from rest_framework import generics @@ -17,13 +18,16 @@ from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudDetailView, CrudListView, CrudUpdateView, make_pagination) from sapl.crud.masterdetail import MasterDetailCrud +from sapl.materia.forms import pega_ultima_tramitacao from sapl.materia.models import (Autoria, DocumentoAcessorio, TipoMateriaLegislativa, Tramitacao) +from sapl.materia.views import MateriaLegislativaPesquisaView from sapl.norma.models import NormaJuridica from sapl.parlamentares.models import Parlamentar from sapl.sessao.serializers import SessaoPlenariaSerializer -from .forms import (BancadaForm, ExpedienteForm, ExpedienteMateriaForm, +from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, + ExpedienteForm, ExpedienteMateriaForm, ListMateriaForm, MateriaOrdemDiaForm, MesaForm, PresencaForm, SessaoPlenariaFilterSet, VotacaoEditForm, VotacaoForm, VotacaoNominalForm) @@ -1958,3 +1962,154 @@ class PesquisarSessaoPlenariaView(FilterView): ) return self.render_to_response(context) + + +def filtra_tramitacao_ordem_dia(): + lista = pega_ultima_tramitacao() + return Tramitacao.objects.filter( + id__in=lista, + status__descricao='Ordem do Dia').distinct().values_list( + 'materia_id', flat=True) + + +def retira_materias_ja_adicionadas(id_sessao, model): + lista = model.objects.filter( + sessao_plenaria_id=id_sessao) + lista_id_materias = [l.materia_id for l in lista] + return lista_id_materias + + +class AdicionarVariasMateriasExpediente(MateriaLegislativaPesquisaView): + filterset_class = AdicionarVariasMateriasFilterSet + template_name = 'sessao/adicionar_varias_materias_expediente.html' + + def get_filterset_kwargs(self, filterset_class): + super(AdicionarVariasMateriasExpediente, + self).get_filterset_kwargs(filterset_class) + + kwargs = {'data': self.request.GET or None} + + qs = self.get_queryset() + + lista_ordem_dia = filtra_tramitacao_ordem_dia() + + lista_materias_adicionadas = retira_materias_ja_adicionadas( + self.kwargs['pk'], ExpedienteMateria) + + qs = qs.filter(id__in=lista_ordem_dia).exclude( + id__in=lista_materias_adicionadas).distinct() + + kwargs.update({ + 'queryset': qs, + }) + return kwargs + + def get_context_data(self, **kwargs): + # import ipdb; ipdb.set_trace() + context = super(MateriaLegislativaPesquisaView, + self).get_context_data(**kwargs) + + context['title'] = _('Pesquisar Matéria Legislativa') + + self.filterset.form.fields['o'].label = _('Ordenação') + + qr = self.request.GET.copy() + + context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context['pk_sessao'] = self.kwargs['pk'] + + return context + + def post(self, request, *args, **kwargs): + marcadas = request.POST.getlist('materia_id') + + for m in marcadas: + try: + tipo_votacao = request.POST['tipo_votacao_%s' % m] + except MultiValueDictKeyError: + msg = _('Formulário Inválido. Você esqueceu de selecionar ' + + 'o tipo de votação de %s' % + MateriaLegislativa.objects.get(id=m)) + messages.add_message(request, messages.ERROR, msg) + return self.get(request, self.kwargs) + + if tipo_votacao: + lista_materias_expediente = ExpedienteMateria.objects.filter( + sessao_plenaria_id=self.kwargs[ + 'pk']) + + materia = MateriaLegislativa.objects.get(id=m) + + expediente = ExpedienteMateria() + expediente.sessao_plenaria_id = self.kwargs['pk'] + expediente.materia_id = materia.id + if lista_materias_expediente: + posicao = lista_materias_expediente.last().numero_ordem + 1 + expediente.numero_ordem = posicao + else: + expediente.numero_ordem = 1 + expediente.data_ordem = datetime.now() + expediente.tipo_votacao = request.POST['tipo_votacao_%s' % m] + expediente.save() + + return self.get(request, self.kwargs) + + +class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente): + filterset_class = AdicionarVariasMateriasFilterSet + template_name = 'sessao/adicionar_varias_materias_ordem.html' + + def get_filterset_kwargs(self, filterset_class): + super(AdicionarVariasMateriasExpediente, + self).get_filterset_kwargs(filterset_class) + + kwargs = {'data': self.request.GET or None} + + qs = self.get_queryset() + + lista_ordem_dia = filtra_tramitacao_ordem_dia() + + lista_materias_adicionadas = retira_materias_ja_adicionadas( + self.kwargs['pk'], OrdemDia) + + qs = qs.filter(id__in=lista_ordem_dia).exclude( + id__in=lista_materias_adicionadas).distinct() + + kwargs.update({ + 'queryset': qs, + }) + return kwargs + + def post(self, request, *args, **kwargs): + marcadas = request.POST.getlist('materia_id') + + for m in marcadas: + try: + tipo_votacao = request.POST['tipo_votacao_%s' % m] + except MultiValueDictKeyError: + msg = _('Formulário Inválido. Você esqueceu de selecionar ' + + 'o tipo de votação de %s' % + MateriaLegislativa.objects.get(id=m)) + messages.add_message(request, messages.ERROR, msg) + return self.get(request, self.kwargs) + + if tipo_votacao: + lista_materias_ordem_dia = OrdemDia.objects.filter( + sessao_plenaria_id=self.kwargs[ + 'pk']) + + materia = MateriaLegislativa.objects.get(id=m) + + ordem_dia = OrdemDia() + ordem_dia.sessao_plenaria_id = self.kwargs['pk'] + ordem_dia.materia_id = materia.id + if lista_materias_ordem_dia: + posicao = lista_materias_ordem_dia.last().numero_ordem + 1 + ordem_dia.numero_ordem = posicao + else: + ordem_dia.numero_ordem = 1 + ordem_dia.data_ordem = datetime.now() + ordem_dia.tipo_votacao = tipo_votacao + ordem_dia.save() + + return self.get(request, self.kwargs) diff --git a/sapl/templates/sessao/adicionar_varias_materias_expediente.html b/sapl/templates/sessao/adicionar_varias_materias_expediente.html new file mode 100644 index 000000000..eb224c8d6 --- /dev/null +++ b/sapl/templates/sessao/adicionar_varias_materias_expediente.html @@ -0,0 +1,96 @@ +{% extends "crud/detail.html" %} +{% load i18n %} +{% load crispy_forms_tags %} +{% block actions %}{% endblock %} + +{% block sections_nav %} +{% endblock %} + + + + + +{% block detail_content %} + {% block buttons %} + + {% if filter_url %} + + + + + {% endif %} + + {% endblock %} + + {% if not filter_url %} + {% crispy filter.form %} + {% endif %} + +

+ {% if filter_url %} + + + + + + + + {% if paginator.count %} + {% if paginator.count > 1 %} +

{% blocktrans with paginator.count as total_materias %}Pesquisa concluída com sucesso! Foram encontradas {{total_materias}} matérias.{% endblocktrans %}

+ {% elif paginator.count == 1 %} +

{% trans 'Pesquisa concluída com sucesso! Foi encontrada 1 matéria.'%}

+ {% endif %} + + + {% csrf_token %} + + {% for m in page_obj %} + + + + + {% endfor %} + + {% else %} + + + {% endif %} + +

{% trans "Matérias" %}

{% trans "Tipo de Votação" %}

+ + {{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}}
+ Autores: + {% for a in m.autoria_set.all %} + {% if not forloop.first %} + ,    {{a.autor|default_if_none:"Não Informado"}} + {% else %} +  {{a.autor|default_if_none:"Não Informado"}} + {% endif %} + {% endfor %} +
+ Localização Atual:  {{m.tramitacao_set.last.unidade_tramitacao_destino|default_if_none:"Não Informada"}}
+ Status:  {{m.tramitacao_set.last.status|default_if_none:"Não Informada"}}
+ Data da última Tramitação:  {{m.tramitacao_set.last.data_tramitacao|default_if_none:"Não Informada"}}
+ Ementa: {{ m.ementa|safe }}
+

+
+ +
+ +
+ +
+

Nenhuma matéria encontrada com essas especificações

+
+ + + + +{% endif %} + +{% endblock detail_content %} diff --git a/sapl/templates/sessao/adicionar_varias_materias_ordem.html b/sapl/templates/sessao/adicionar_varias_materias_ordem.html new file mode 100644 index 000000000..6cb555ee7 --- /dev/null +++ b/sapl/templates/sessao/adicionar_varias_materias_ordem.html @@ -0,0 +1,18 @@ +{% extends "sessao/adicionar_varias_materias_expediente.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block buttons %} + + {% if filter_url %} + + + + + {% endif %} + + {% endblock %} \ No newline at end of file diff --git a/sapl/templates/sessao/expedientemateria_list.html b/sapl/templates/sessao/expedientemateria_list.html index 1844124e0..01cf53b61 100644 --- a/sapl/templates/sessao/expedientemateria_list.html +++ b/sapl/templates/sessao/expedientemateria_list.html @@ -6,4 +6,7 @@ {% blocktrans with verbose_name=view.verbose_name %} Reordenar Matérias {% endblocktrans %} + + {% blocktrans with verbose_name=view.verbose_name %} Adicionar Várias Matérias {% endblocktrans %} + {% endblock more_buttons %} diff --git a/sapl/templates/sessao/materia_ordemdia_list.html b/sapl/templates/sessao/materia_ordemdia_list.html index 33d33fe84..bbf2708fb 100644 --- a/sapl/templates/sessao/materia_ordemdia_list.html +++ b/sapl/templates/sessao/materia_ordemdia_list.html @@ -78,7 +78,7 @@ Matérias da Ordem do Dia         - + {% trans 'Adicionar Várias Matérias' %} {% endblock detail_content %}