diff --git a/sapl/base/forms.py b/sapl/base/forms.py
index 5af6ee179..595814d34 100644
--- a/sapl/base/forms.py
+++ b/sapl/base/forms.py
@@ -10,6 +10,7 @@ from django.utils.translation import ugettext_lazy as _
from sapl.crispy_layout_mixin import form_actions, to_row
from sapl.materia.models import MateriaLegislativa
+from sapl.sessao.models import SessaoPlenaria
from sapl.settings import MAX_IMAGE_UPLOAD_SIZE
from sapl.utils import (RANGE_ANOS, ImageThumbnailFileInput, autor_label,
autor_modal)
@@ -37,6 +38,66 @@ class RangeWidgetOverride(forms.MultiWidget):
return ''.join(rendered_widgets)
+class RelatorioAtasFilterSet(django_filters.FilterSet):
+
+ filter_overrides = {models.DateField: {
+ 'filter_class': django_filters.DateFromToRangeFilter,
+ 'extra': lambda f: {
+ 'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')),
+ 'widget': RangeWidgetOverride}
+ }}
+
+ class Meta:
+ model = SessaoPlenaria
+ fields = ['data_inicio']
+
+ def __init__(self, *args, **kwargs):
+ super(RelatorioAtasFilterSet, self).__init__(
+ *args, **kwargs)
+
+ self.filters['data_inicio'].label = 'Período (Inicial - Final)'
+ self.form.fields['data_inicio'].required = True
+
+ row1 = to_row([('data_inicio', 12)])
+
+ self.form.helper = FormHelper()
+ self.form.helper.form_method = 'GET'
+ self.form.helper.layout = Layout(
+ Fieldset(_('Atas das Sessões Plenárias'),
+ row1, form_actions(save_label='Pesquisar'))
+ )
+
+
+class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet):
+
+ filter_overrides = {models.DateField: {
+ 'filter_class': django_filters.DateFromToRangeFilter,
+ 'extra': lambda f: {
+ 'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')),
+ 'widget': RangeWidgetOverride}
+ }}
+
+ class Meta:
+ model = SessaoPlenaria
+ fields = ['data_inicio']
+
+ def __init__(self, *args, **kwargs):
+ super(RelatorioPresencaSessaoFilterSet, self).__init__(
+ *args, **kwargs)
+
+ self.filters['data_inicio'].label = 'Período (Inicial - Final)'
+ self.form.fields['data_inicio'].required = True
+
+ row1 = to_row([('data_inicio', 12)])
+
+ self.form.helper = FormHelper()
+ self.form.helper.form_method = 'GET'
+ self.form.helper.layout = Layout(
+ Fieldset(_('Presença dos parlamentares nas sessões plenárias'),
+ row1, form_actions(save_label='Pesquisar'))
+ )
+
+
class RelatorioHistoricoTramitacaoFilterSet(django_filters.FilterSet):
filter_overrides = {models.DateField: {
diff --git a/sapl/base/urls.py b/sapl/base/urls.py
index b3dcac6ea..60804abea 100644
--- a/sapl/base/urls.py
+++ b/sapl/base/urls.py
@@ -4,11 +4,12 @@ from django.views.generic.base import TemplateView
from .apps import AppConfig
from .forms import LoginForm
-from .views import (CasaLegislativaCrud, HelpView,
+from .views import (CasaLegislativaCrud, HelpView, RelatorioAtasView,
RelatorioHistoricoTramitacaoView,
RelatorioMateriasPorAnoAutorTipoView,
RelatorioMateriasPorAutorView,
- RelatorioMateriasTramitacaoView)
+ RelatorioMateriasTramitacaoView,
+ RelatorioPresencaSessaoView)
app_name = AppConfig.name
@@ -39,5 +40,11 @@ urlpatterns = [
url(r'^relatorio/historico-tramitacoes$',
RelatorioHistoricoTramitacaoView.as_view(),
name='historico_tramitacoes'),
+ url(r'^relatorio/presenca$',
+ RelatorioPresencaSessaoView.as_view(),
+ name='presenca_sessao'),
+ url(r'^relatorio/atas$',
+ RelatorioAtasView.as_view(),
+ name='atas'),
]
diff --git a/sapl/base/views.py b/sapl/base/views.py
index ca5d735a3..d813d4aff 100644
--- a/sapl/base/views.py
+++ b/sapl/base/views.py
@@ -1,5 +1,8 @@
+from itertools import chain
+
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.urlresolvers import reverse
+from django.db.models import Count, Q
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView
@@ -8,12 +11,17 @@ from django_filters.views import FilterView
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView,
CrudDetailView, CrudUpdateView)
from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
+from sapl.parlamentares.models import Parlamentar
+from sapl.sessao.models import (OrdemDia, PresencaOrdemDia, SessaoPlenaria,
+ SessaoPlenariaPresenca)
from sapl.utils import permissao_tb_aux
-from .forms import (CasaLegislativaForm, RelatorioHistoricoTramitacaoFilterSet,
+from .forms import (CasaLegislativaForm, RelatorioAtasFilterSet,
+ RelatorioHistoricoTramitacaoFilterSet,
RelatorioMateriasPorAnoAutorTipoFilterSet,
RelatorioMateriasPorAutorFilterSet,
- RelatorioMateriasTramitacaoilterSet)
+ RelatorioMateriasTramitacaoilterSet,
+ RelatorioPresencaSessaoFilterSet)
from .models import CasaLegislativa
@@ -21,6 +29,91 @@ def get_casalegislativa():
return CasaLegislativa.objects.first()
+class RelatorioAtasView(FilterView):
+ model = SessaoPlenaria
+ filterset_class = RelatorioAtasFilterSet
+ template_name = 'base/RelatorioAtas_filter.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(RelatorioAtasView,
+ self).get_context_data(**kwargs)
+ context['title'] = _('Atas das Sessões Plenárias')
+
+ # Verifica se os campos foram preenchidos
+ if not self.filterset.form.is_valid():
+ return context
+
+ context['object_list'] = context['object_list'].exclude(upload_ata='')
+ qr = self.request.GET.copy()
+ context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
+ return context
+
+
+class RelatorioPresencaSessaoView(FilterView):
+ model = SessaoPlenaria
+ filterset_class = RelatorioPresencaSessaoFilterSet
+ template_name = 'base/RelatorioPresencaSessao_filter.html'
+
+ def calcular_porcentagem_presenca(self,
+ parlamentares,
+ total_sessao,
+ total_ordemdia):
+ for p in parlamentares:
+ p.sessao_porc = round(p.sessao_count * 100 / total_sessao, 1)
+ p.ordemdia_porc = round(p.ordemdia_count * 100 / total_ordemdia, 1)
+ return parlamentares
+
+ def get_context_data(self, **kwargs):
+ context = super(RelatorioPresencaSessaoView,
+ self).get_context_data(**kwargs)
+ context['title'] = _('Presença dos parlamentares nas sessões')
+
+ # Verifica se os campos foram preenchidos
+ if not self.filterset.form.is_valid():
+ return context
+
+ # =====================================================================
+ if 'salvar' in self.request.GET:
+ where = context['object_list'].query.where
+ _range = where.children[0].rhs
+
+ sufixo = 'sessao_plenaria__data_inicio__range'
+ param0 = {'%s' % sufixo: _range}
+ param1 = {'presencaordemdia__%s' % sufixo: _range}
+ param2 = {'sessaoplenariapresenca__%s' % sufixo: _range}
+
+ pls = Parlamentar.objects.filter(
+ Q(**param1) & Q(**param2)).annotate(
+ sessao_count=Count(
+ 'sessaoplenariapresenca__sessao_plenaria__data_inicio',
+ distinct=True),
+ ordemdia_count=Count(
+ 'presencaordemdia__sessao_plenaria',
+ distinct=True),
+ sessao_porc=Count(0),
+ ordemdia_porc=Count(0))
+
+ total_ordemdia = OrdemDia.objects.order_by(
+ 'sessao_plenaria').filter(**param0).distinct(
+ 'sessao_plenaria').count()
+
+ self.calcular_porcentagem_presenca(
+ pls,
+ context['object_list'].count(),
+ total_ordemdia)
+
+ context['total_ordemdia'] = total_ordemdia
+ context['total_sessao'] = context['object_list'].count()
+ context['parlamentares'] = pls
+ context['periodo'] = (
+ self.request.GET['data_inicio_0'] +
+ ' - ' + self.request.GET['data_inicio_1'])
+ # =====================================================================
+ qr = self.request.GET.copy()
+ context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
+ return context
+
+
class RelatorioHistoricoTramitacaoView(FilterView):
model = MateriaLegislativa
filterset_class = RelatorioHistoricoTramitacaoFilterSet
@@ -136,17 +229,12 @@ class CasaLegislativaCrud(Crud):
list_field_names = ['codigo', 'nome', 'sigla']
def has_permission(self):
- if self.request.user.is_superuser:
- return True
- else:
- return False
+ return permissao_tb_aux(self)
class CreateView(PermissionRequiredMixin, CrudCreateView):
- permission_required = {'base.add_casa_legislativa'}
form_class = CasaLegislativaForm
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
- permission_required = {'base.change_casalegislativa'}
form_class = CasaLegislativaForm
class DetailView(CrudDetailView):
diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py
index d4333f63d..55b262895 100644
--- a/sapl/comissoes/views.py
+++ b/sapl/comissoes/views.py
@@ -3,7 +3,7 @@ from django.core.urlresolvers import reverse
from django.views.generic import ListView
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView,
- CrudDeleteView, CrudUpdateView)
+ CrudDeleteView, CrudListView, CrudUpdateView)
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.materia.models import Tramitacao
from sapl.utils import permissao_tb_aux, permissoes_comissoes
@@ -137,6 +137,9 @@ class ComissaoCrud(Crud):
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_comissoes()
+ class ListView(CrudListView):
+ ordering = ['-ativa', 'sigla']
+
class BaseMixin(CrudBaseMixin):
list_field_names = ['nome', 'sigla', 'tipo', 'data_criacao', 'ativa']
diff --git a/sapl/materia/admin.py b/sapl/materia/admin.py
index 5c02ebd40..eef5d7213 100644
--- a/sapl/materia/admin.py
+++ b/sapl/materia/admin.py
@@ -1,3 +1,22 @@
+from django.contrib import admin
+from sapl.materia.models import Proposicao
+from sapl.settings import DEBUG
from sapl.utils import register_all_models_in_admin
register_all_models_in_admin(__name__)
+
+if not DEBUG:
+
+ admin.site.unregister(Proposicao)
+
+ class ProposicaoAdmin(admin.ModelAdmin):
+ def has_add_permission(self, request, obj=None):
+ return False
+
+ def has_change_permission(self, request, obj=None):
+ return False
+
+ def has_delete_permission(self, request, obj=None):
+ return False
+
+ admin.site.register(Proposicao, ProposicaoAdmin)
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index a91567a7f..851dd51ba 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -216,22 +216,91 @@ class TramitacaoForm(ModelForm):
'texto']
def clean(self):
+
+ if 'data_encaminhamento' in self.data:
+ data_enc_form = self.cleaned_data['data_encaminhamento']
+ if 'data_fim_prazo' in self.data:
+ data_prazo_form = self.cleaned_data['data_fim_prazo']
+ if 'data_tramitacao' in self.data:
+ data_tram_form = self.cleaned_data['data_tramitacao']
+
if self.errors:
return self.errors
ultima_tramitacao = Tramitacao.objects.filter(
- materia_id=self.instance.materia.id).last()
+ materia_id=self.instance.materia_id).exclude(
+ id=self.instance.id).last()
+
+ if not self.instance.data_tramitacao:
+
+ if ultima_tramitacao:
+ destino = ultima_tramitacao.unidade_tramitacao_destino
+ if (destino != self.cleaned_data['unidade_tramitacao_local']):
+ msg = _('A origem da nova tramitação deve ser igual ao '
+ 'destino da última adicionada!')
+ raise ValidationError(msg)
+
+ if self.cleaned_data['data_tramitacao'] > datetime.now().date():
+ msg = _(
+ 'A data de tramitação deve ser ' +
+ 'menor ou igual a data de hoje!')
+ raise ValidationError(msg)
+
+ if (ultima_tramitacao and
+ data_tram_form < ultima_tramitacao.data_tramitacao):
+ msg = _('A data da nova tramitação deve ser ' +
+ 'maior que a data da última tramitação!')
+ raise ValidationError(msg)
+
+ if data_enc_form:
+ if data_enc_form < data_tram_form:
+ msg = _('A data de encaminhamento deve ser ' +
+ 'maior que a data de tramitação!')
+ raise ValidationError(msg)
- if ultima_tramitacao:
- destino = ultima_tramitacao.unidade_tramitacao_destino
- if (destino != self.cleaned_data['unidade_tramitacao_local']):
- msg = _('A origem da nova tramitação deve ser igual ao '
- 'destino da última adicionada!')
+ if data_prazo_form:
+ if data_prazo_form < data_tram_form:
+ msg = _('A data fim de prazo deve ser ' +
+ 'maior que a data de tramitação!')
raise ValidationError(msg)
return self.cleaned_data
+class TramitacaoUpdateForm(TramitacaoForm):
+ unidade_tramitacao_local = forms.ModelChoiceField(
+ queryset=UnidadeTramitacao.objects.all(),
+ widget=forms.HiddenInput())
+
+ data_tramitacao = forms.DateField(widget=forms.HiddenInput())
+
+ class Meta:
+ model = Tramitacao
+ fields = ['data_tramitacao',
+ 'unidade_tramitacao_local',
+ 'status',
+ 'turno',
+ 'urgente',
+ 'unidade_tramitacao_destino',
+ 'data_encaminhamento',
+ 'data_fim_prazo',
+ 'texto',
+ ]
+
+ widgets = {
+ 'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'),
+ 'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'),
+ }
+
+ def clean(self):
+ local = self.instance.unidade_tramitacao_local
+ data_tram = self.instance.data_tramitacao
+
+ self.cleaned_data['data_tramitacao'] = data_tram
+ self.cleaned_data['unidade_tramitacao_local'] = local
+ return super(TramitacaoUpdateForm, self).clean()
+
+
class LegislacaoCitadaForm(ModelForm):
tipo = forms.ModelChoiceField(
diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py
index f400a453e..d3a9573c9 100644
--- a/sapl/materia/tests/test_materia.py
+++ b/sapl/materia/tests/test_materia.py
@@ -276,6 +276,8 @@ def test_tramitacao_submit(admin_client):
'urgente': True,
'status': status_tramitacao.pk,
'data_tramitacao': '2016-03-21',
+ 'data_fim_prazo': '2016-03-22',
+ 'data_encaminhamento': '2016-03-22',
'texto': 'Texto_Teste',
'salvar': 'salvar'},
follow=True)
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index 57a804be9..4f7966118 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -4,6 +4,7 @@ from string import ascii_letters, digits
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button
+from django.db.models import Q
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -31,14 +32,15 @@ from sapl.crud.masterdetail import MasterDetailCrud
from sapl.norma.models import LegislacaoCitada
from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo,
get_base_url, permissao_tb_aux, permissoes_autor,
- permissoes_materia)
+ permissoes_materia, permissoes_protocoloadm)
from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutorForm,
AutoriaForm, ConfirmarProposicaoForm, DespachoInicialForm,
DocumentoAcessorioForm, LegislacaoCitadaForm,
MateriaLegislativaFilterSet, NumeracaoForm, ProposicaoForm,
ReceberProposicaoForm, RelatoriaForm, TramitacaoForm,
- UnidadeTramitacaoForm, filtra_tramitacao_destino,
+ TramitacaoUpdateForm, UnidadeTramitacaoForm,
+ filtra_tramitacao_destino,
filtra_tramitacao_destino_and_status,
filtra_tramitacao_status)
from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria,
@@ -242,11 +244,12 @@ class UnidadeTramitacaoCrud(Crud):
permission_required = permissoes_materia()
-class ProposicaoDevolvida(ListView):
+class ProposicaoDevolvida(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_devolvidas_list.html'
model = Proposicao
ordering = ['data_envio']
paginate_by = 10
+ permission_required = permissoes_protocoloadm()
def get_queryset(self):
return Proposicao.objects.filter(
@@ -264,11 +267,12 @@ class ProposicaoDevolvida(ListView):
return context
-class ProposicaoPendente(ListView):
+class ProposicaoPendente(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_pendentes_list.html'
model = Proposicao
ordering = ['data_envio', 'autor', 'tipo', 'descricao']
paginate_by = 10
+ permission_required = permissoes_protocoloadm()
def get_queryset(self):
return Proposicao.objects.filter(
@@ -286,11 +290,12 @@ class ProposicaoPendente(ListView):
return context
-class ProposicaoRecebida(ListView):
+class ProposicaoRecebida(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_recebidas_list.html'
model = Proposicao
ordering = ['data_envio']
paginate_by = 10
+ permission_required = permissoes_protocoloadm()
def get_queryset(self):
return Proposicao.objects.filter(
@@ -308,9 +313,10 @@ class ProposicaoRecebida(ListView):
return context
-class ReceberProposicao(CreateView):
+class ReceberProposicao(PermissionRequiredMixin, CreateView):
template_name = "materia/receber_proposicao.html"
form_class = ReceberProposicaoForm
+ permission_required = permissoes_protocoloadm()
def get_context_data(self, **kwargs):
context = super(ReceberProposicao, self).get_context_data(**kwargs)
@@ -340,9 +346,10 @@ class ReceberProposicao(CreateView):
return reverse('sapl.materia:receber-proposicao')
-class ConfirmarProposicao(CreateView):
+class ConfirmarProposicao(PermissionRequiredMixin, CreateView):
template_name = "materia/confirmar_proposicao.html"
form_class = ConfirmarProposicaoForm
+ permission_required = permissoes_protocoloadm()
def get_context_data(self, **kwargs):
context = super(ConfirmarProposicao, self).get_context_data(**kwargs)
@@ -432,38 +439,36 @@ class ProposicaoCrud(Crud):
def has_permission(self):
perms = self.get_permission_required()
- if self.request.user.has_perms(perms):
- if (Proposicao.objects.filter(
- id=self.kwargs['pk'],
- autor__user_id=self.request.user.id).exists()):
- proposicao = Proposicao.objects.get(
- id=self.kwargs['pk'],
- autor__user_id=self.request.user.id)
- if not proposicao.data_recebimento:
- return True
- else:
- msg = _('Essa proposição já foi recebida. ' +
- 'Não pode mais ser editada')
- messages.add_message(self.request, messages.ERROR, msg)
- return False
- else:
+ if not self.request.user.has_perms(perms):
return False
+ if (Proposicao.objects.filter(
+ id=self.kwargs['pk'],
+ autor__user_id=self.request.user.id).exists()):
+ proposicao = Proposicao.objects.get(
+ id=self.kwargs['pk'],
+ autor__user_id=self.request.user.id)
+ if (not proposicao.data_recebimento or
+ proposicao.data_devolucao):
+ return True
+ else:
+ msg = _('Essa proposição já foi recebida. ' +
+ 'Não pode mais ser editada')
+ messages.add_message(self.request, messages.ERROR, msg)
+ return False
+
class DetailView(PermissionRequiredMixin, CrudDetailView):
permission_required = permissoes_autor()
def has_permission(self):
perms = self.get_permission_required()
- if self.request.user.has_perms(perms):
- if (Proposicao.objects.filter(
- id=self.kwargs['pk'],
- autor__user_id=self.request.user.id).exists()):
- return True
- else:
- return False
- else:
+ if not self.request.user.has_perms(perms):
return False
+ return (Proposicao.objects.filter(
+ id=self.kwargs['pk'],
+ autor__user_id=self.request.user.id).exists())
+
class ListView(PermissionRequiredMixin, CrudListView):
ordering = ['-data_envio', 'descricao']
permission_required = permissoes_autor()
@@ -479,35 +484,69 @@ class ProposicaoCrud(Crud):
obj.data_recebimento = 'Não recebida'
else:
obj.data_recebimento = obj.data_recebimento.strftime(
- "%d/%m/%Y %H:%M")
+ "%d/%m/%Y %H:%M")
return [self._as_row(obj) for obj in object_list]
def get_queryset(self):
+ # Só tem acesso as Proposicoes criadas por ele que ainda nao foram
+ # recebidas ou foram devolvidas
lista = Proposicao.objects.filter(
autor__user_id=self.request.user.id)
+ lista = lista.filter(
+ Q(data_recebimento__isnull=True) |
+ Q(data_devolucao__isnull=False))
+
return lista
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = {'materia.delete_proposicao'}
+ def has_permission(self):
+ perms = self.get_permission_required()
+ if not self.request.user.has_perms(perms):
+ return False
+
+ return (Proposicao.objects.filter(
+ id=self.kwargs['pk'],
+ autor__user_id=self.request.user.id).exists())
+
def delete(self, request, *args, **kwargs):
proposicao = Proposicao.objects.get(id=self.kwargs['pk'])
- if not proposicao.data_envio:
+ if not proposicao.data_envio or proposicao.data_devolucao:
proposicao.delete()
return HttpResponseRedirect(
reverse('sapl.materia:proposicao_list'))
- else:
+
+ elif not proposicao.data_recebimento:
proposicao.data_envio = None
proposicao.save()
return HttpResponseRedirect(
reverse('sapl.materia:proposicao_detail',
kwargs={'pk': proposicao.pk}))
+ else:
+ msg = _('Essa proposição já foi recebida. ' +
+ 'Não pode mais ser excluída/recuperada')
+ messages.add_message(self.request, messages.ERROR, msg)
+ return HttpResponseRedirect(
+ reverse('sapl.materia:proposicao_detail',
+ kwargs={'pk': proposicao.pk}))
+
class ReciboProposicaoView(TemplateView):
template_name = "materia/recibo_proposicao.html"
+ permission_required = permissoes_autor()
+
+ def has_permission(self):
+ perms = self.get_permission_required()
+ if not self.request.user.has_perms(perms):
+ return False
+
+ return (Proposicao.objects.filter(
+ id=self.kwargs['pk'],
+ autor__user_id=self.request.user.id).exists())
def get_context_data(self, **kwargs):
context = super(ReciboProposicaoView, self).get_context_data(
@@ -515,8 +554,8 @@ class ReciboProposicaoView(TemplateView):
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'])
context.update({'proposicao': proposicao,
'hash': gerar_hash_arquivo(
- proposicao.texto_original.path,
- self.kwargs['pk'])})
+ proposicao.texto_original.path,
+ self.kwargs['pk'])})
return context
@@ -573,14 +612,19 @@ class TramitacaoCrud(MasterDetailCrud):
return super(CreateView, self).post(request, *args, **kwargs)
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
- form_class = TramitacaoForm
+ form_class = TramitacaoUpdateForm
permission_required = permissoes_materia()
def post(self, request, *args, **kwargs):
- materia = MateriaLegislativa.objects.get(id=kwargs['pk'])
+ materia = MateriaLegislativa.objects.get(
+ tramitacao__id=kwargs['pk'])
do_envia_email_tramitacao(request, materia)
return super(UpdateView, self).post(request, *args, **kwargs)
+ @property
+ def layout_key(self):
+ return 'TramitacaoUpdate'
+
class ListView(MasterDetailCrud.ListView):
def get_queryset(self):
@@ -598,7 +642,7 @@ class TramitacaoCrud(MasterDetailCrud):
kwargs={'pk': tramitacao.materia.id})
if tramitacao.pk != materia.tramitacao_set.last().pk:
- msg = _('Somente a útlima tramitação pode ser deletada!')
+ msg = _('Somente a última tramitação pode ser deletada!')
messages.add_message(request, messages.ERROR, msg)
return HttpResponseRedirect(url)
else:
diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py
index d4c8d817a..1dd4db07f 100644
--- a/sapl/parlamentares/models.py
+++ b/sapl/parlamentares/models.py
@@ -18,11 +18,16 @@ class Legislatura(models.Model):
verbose_name = _('Legislatura')
verbose_name_plural = _('Legislaturas')
+ def atual(self):
+ current_year = datetime.now().year
+ if(self.data_inicio.year <= current_year and
+ self.data_fim.year >= current_year):
+ return True
+ else:
+ return False
+
def __str__(self):
- # XXX Usar id mesmo? Ou criar campo para nº legislatura?
- current_date = datetime.now().year
- if(self.data_inicio.year <= current_date and
- self.data_fim.year >= current_date):
+ if self.atual():
current = ' (%s)' % _('Atual')
else:
current = ''
diff --git a/sapl/parlamentares/urls.py b/sapl/parlamentares/urls.py
index 97f2a0347..09bc8bf3f 100644
--- a/sapl/parlamentares/urls.py
+++ b/sapl/parlamentares/urls.py
@@ -24,7 +24,7 @@ urlpatterns = [
ProposicaoParlamentarCrud.get_urls() +
RelatoriaParlamentarCrud.get_urls()
)),
- url(r'^coligacao/',
+ url(r'^sistema/coligacao/',
include(ColigacaoCrud.get_urls() +
ComposicaoColigacaoCrud.get_urls())),
diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py
index 0f2a8edfb..fda746e0e 100644
--- a/sapl/parlamentares/views.py
+++ b/sapl/parlamentares/views.py
@@ -332,6 +332,7 @@ class ParlamentarCrud(Crud):
class ListView(CrudListView):
template_name = "parlamentares/parlamentares_list.html"
paginate_by = None
+ ordering = '-nome_parlamentar'
def take_legislatura_id(self):
legislaturas = Legislatura.objects.all().order_by(
@@ -341,7 +342,9 @@ class ParlamentarCrud(Crud):
try:
legislatura_id = int(self.request.GET['periodo'])
except MultiValueDictKeyError:
- legislatura_id = legislaturas.first().id
+ for l in Legislatura.objects.all():
+ if l.atual():
+ return l.id
return legislatura_id
else:
return 0
@@ -349,7 +352,8 @@ class ParlamentarCrud(Crud):
def get_queryset(self):
if self.take_legislatura_id() != 0:
mandatos = Mandato.objects.filter(
- legislatura_id=self.take_legislatura_id())
+ legislatura_id=self.take_legislatura_id()).order_by(
+ 'parlamentar__nome_parlamentar')
return mandatos
return []
diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py
index 6f9e0ad19..e249a3312 100644
--- a/sapl/protocoloadm/tests/test_protocoloadm.py
+++ b/sapl/protocoloadm/tests/test_protocoloadm.py
@@ -1,4 +1,5 @@
import datetime
+
import pytest
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 805609b9b..d4f06f615 100644
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -209,43 +209,54 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
'pk': obj.sessao_plenaria_id,
'oid': obj.materia_id,
'mid': obj.pk})
-
- btn_registrar = '''
- Registrar Votação''' % (url)
- obj.resultado = btn_registrar
+ if self.request.user.has_perms(permissoes_sessao()):
+ btn_registrar = '''
+ Registrar Votação''' % (
+ url)
+ obj.resultado = btn_registrar
+ else:
+ obj.resultado = '''Não há resultado'''
else:
url = reverse('sapl.sessao:abrir_votacao', kwargs={
'pk': obj.pk, 'spk': obj.sessao_plenaria_id})
- btn_abrir = '''
- Matéria não votada
- Abrir Votação''' % (url)
- obj.resultado = btn_abrir
+
+ if self.request.user.has_perms(permissoes_sessao()):
+ btn_abrir = '''
+ Matéria não votada
+ Abrir Votação''' % (url)
+ obj.resultado = btn_abrir
+ else:
+ obj.resultado = '''Não há resultado'''
else:
- url = ''
- if obj.tipo_votacao == 1:
- url = reverse('sapl.sessao:votacaosimbolicaedit',
- kwargs={
- 'pk': obj.sessao_plenaria_id,
- 'oid': obj.materia_id,
- 'mid': obj.pk})
- elif obj.tipo_votacao == 2:
- url = reverse('sapl.sessao:votacaonominaledit',
- kwargs={
- 'pk': obj.sessao_plenaria_id,
- 'oid': obj.materia_id,
- 'mid': obj.pk})
- elif obj.tipo_votacao == 3:
- url = reverse('sapl.sessao:votacaosecretaedit',
- kwargs={
- 'pk': obj.sessao_plenaria_id,
- 'oid': obj.materia_id,
- 'mid': obj.pk})
- obj.resultado = '%s' % (url,
- obj.resultado)
+ if self.request.user.has_perms(permissoes_sessao()):
+ url = ''
+ if obj.tipo_votacao == 1:
+ url = reverse('sapl.sessao:votacaosimbolicaedit',
+ kwargs={
+ 'pk': obj.sessao_plenaria_id,
+ 'oid': obj.materia_id,
+ 'mid': obj.pk})
+ elif obj.tipo_votacao == 2:
+ url = reverse('sapl.sessao:votacaonominaledit',
+ kwargs={
+ 'pk': obj.sessao_plenaria_id,
+ 'oid': obj.materia_id,
+ 'mid': obj.pk})
+ elif obj.tipo_votacao == 3:
+ url = reverse('sapl.sessao:votacaosecretaedit',
+ kwargs={
+ 'pk': obj.sessao_plenaria_id,
+ 'oid': obj.materia_id,
+ 'mid': obj.pk})
+ obj.resultado = '%s' % (url,
+ obj.resultado)
+ else:
+ obj.resultado = '%s' % (obj.resultado)
+
return [self._as_row(obj) for obj in object_list]
@@ -449,19 +460,20 @@ class PresencaMixin:
yield (parlamentar, False)
-class PresencaView(PermissionRequiredMixin,
- FormMixin,
+class PresencaView(FormMixin,
PresencaMixin,
SessaoCrud.CrudDetailView):
template_name = 'sessao/presenca.html'
form_class = PresencaForm
model = SessaoPlenaria
- permission_required = permissoes_sessao()
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
+ if not self.request.user.has_perms(permissoes_sessao()):
+ return self.form_invalid(form)
+
if form.is_valid():
# Pegar os presentes salvos no banco
presentes_banco = SessaoPlenariaPresenca.objects.filter(
@@ -499,13 +511,11 @@ class PainelView(PermissionRequiredMixin, TemplateView):
permission_required = permissoes_painel()
-class PresencaOrdemDiaView(PermissionRequiredMixin,
- FormMixin,
+class PresencaOrdemDiaView(FormMixin,
PresencaMixin,
SessaoCrud.CrudDetailView):
template_name = 'sessao/presenca_ordemdia.html'
form_class = PresencaForm
- permission_required = permissoes_sessao()
def post(self, request, *args, **kwargs):
@@ -514,6 +524,9 @@ class PresencaOrdemDiaView(PermissionRequiredMixin,
pk = kwargs['pk']
+ if not self.request.user.has_perms(permissoes_sessao()):
+ return self.form_invalid(form)
+
if form.is_valid():
# Pegar os presentes salvos no banco
presentes_banco = PresencaOrdemDia.objects.filter(
@@ -920,17 +933,18 @@ class ResumoView(SessaoCrud.CrudDetailView):
return self.render_to_response(context)
-class ExpedienteView(PermissionRequiredMixin,
- FormMixin,
+class ExpedienteView(FormMixin,
SessaoCrud.CrudDetailView):
template_name = 'sessao/expediente.html'
form_class = ExpedienteForm
- permission_required = permissoes_sessao()
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = ExpedienteForm(request.POST)
+ if not self.request.user.has_perms(permissoes_sessao()):
+ return self.form_invalid(form)
+
if form.is_valid():
list_tipo = request.POST.getlist('tipo')
list_conteudo = request.POST.getlist('conteudo')
@@ -1986,7 +2000,8 @@ class PesquisarSessaoPlenariaView(FilterView):
qs = self.get_queryset()
- qs = qs.distinct()
+ qs = qs.distinct().order_by(
+ 'legislatura__id', 'data_inicio', 'numero')
kwargs.update({
'queryset': qs,
@@ -2045,9 +2060,11 @@ def retira_materias_ja_adicionadas(id_sessao, model):
return lista_id_materias
-class AdicionarVariasMateriasExpediente(MateriaLegislativaPesquisaView):
+class AdicionarVariasMateriasExpediente(PermissionRequiredMixin,
+ MateriaLegislativaPesquisaView):
filterset_class = AdicionarVariasMateriasFilterSet
template_name = 'sessao/adicionar_varias_materias_expediente.html'
+ permission_required = permissoes_sessao()
def get_filterset_kwargs(self, filterset_class):
super(AdicionarVariasMateriasExpediente,
@@ -2123,6 +2140,7 @@ class AdicionarVariasMateriasExpediente(MateriaLegislativaPesquisaView):
class AdicionarVariasMateriasOrdemDia(AdicionarVariasMateriasExpediente):
filterset_class = AdicionarVariasMateriasFilterSet
template_name = 'sessao/adicionar_varias_materias_ordem.html'
+ permission_required = permissoes_sessao()
def get_filterset_kwargs(self, filterset_class):
super(AdicionarVariasMateriasExpediente,
diff --git a/sapl/static/js/app.js b/sapl/static/js/app.js
index 4a8853cd3..127bf2b86 100644
--- a/sapl/static/js/app.js
+++ b/sapl/static/js/app.js
@@ -1,4 +1,4 @@
-function initTinymce(elements) {
+function initTinymce(elements, readonly=false) {
removeTinymce();
var config_tinymce = {
force_br_newlines : false,
@@ -11,6 +11,11 @@ function initTinymce(elements) {
border_css: "/static/styles/style_tinymce.css",
content_css: "/static/styles/style_tinymce.css",
}
+
+ if (readonly) {
+ config_tinymce.readonly = 1
+ }
+
if (elements != null) {
config_tinymce['elements'] = elements;
config_tinymce['mode'] = "exact";
diff --git a/sapl/templates/base.html b/sapl/templates/base.html
index df70b2252..363c1d7e0 100644
--- a/sapl/templates/base.html
+++ b/sapl/templates/base.html
@@ -42,13 +42,12 @@