Browse Source

fix #1801 (#2260)

* Create Tipo Justificativa

* Adding the migrate

* Adding justificativa on map rules

* WIP

Co-authored-by: João Pedro Sconetto <sconetto.joao@gmail.com>

* wip

* Adding the migration

* fix #1801

* fix #1801

* Fix the reverse url

* Fix #1801

* Adding the migrations

* Fix #1801

* fix #1801

* fix #1801

* Remove ipdb

* Adding anexo on justificativa sessao

* Fixing some issues on map rules

* wip

* ajusta layout_key e corrige __init__ em form

* finish the create view

* Remove the template name from create view

* fixing conflicts with the migration

* isola em um commit ajustes de pep8

* add ao justifitiva de ausência m2m para registro do tipo matéria

* add apenas os presentes la lista de parlamentares

* Remove código desnecessário

* ajusta crud de justificativaausencia

* Remove the detail viewc

* Corrige o template de sistema

* muda combo de parlamentares

* Adiciona a justificativa de ausência no rules_group_sessao
pull/2365/head 3.1.132
Mariana Mendes 6 years ago
committed by Edward
parent
commit
acf3070571
  1. 3
      sapl/rules/map_rules.py
  2. 112
      sapl/sessao/forms.py
  3. 52
      sapl/sessao/migrations/0028_auto_20181024_0848.py
  4. 25
      sapl/sessao/migrations/0029_auto_20181024_0952.py
  5. 81
      sapl/sessao/models.py
  6. 10
      sapl/sessao/urls.py
  7. 100
      sapl/sessao/views.py
  8. 3
      sapl/templates/menu_tabelas_auxiliares.yaml
  9. 6
      sapl/templates/sessao/justificativaausencia_edit.html
  10. 25
      sapl/templates/sessao/justificativaausencia_form.html
  11. 15
      sapl/templates/sessao/layouts.yaml
  12. 2
      sapl/templates/sessao/subnav.yaml
  13. 1
      sapl/templates/sistema.html

3
sapl/rules/map_rules.py

@ -171,6 +171,7 @@ rules_group_sessao = {
(sessao.PresencaOrdemDia, __base__),
(sessao.RegistroVotacao, __base__),
(sessao.VotoParlamentar, __base__),
(sessao.JustificativaAusencia, __base__),
]
}
@ -264,6 +265,8 @@ rules_group_geral = {
(sessao.TipoSessaoPlenaria, __base__),
(sessao.TipoResultadoVotacao, __base__),
(sessao.TipoExpediente, __base__),
(sessao.TipoJustificativa, __base__),
(sessao.JustificativaAusencia, __base__),
(sessao.Bloco, __base__),
(sessao.ResumoOrdenacao, __base__),

112
sapl/sessao/forms.py

@ -6,12 +6,15 @@ from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import transaction
from django.db.models import Q
from django.forms import ModelForm
from django.forms.widgets import CheckboxSelectMultiple
from django.utils.translation import ugettext_lazy as _
import django_filters
from floppyforms import widgets
from sapl.base.models import Autor, TipoAutor
from sapl.crispy_layout_mixin import form_actions, to_row
from sapl.crispy_layout_mixin import form_actions, to_row, SaplFormLayout
from sapl.materia.forms import MateriaLegislativaFilterSet
from sapl.materia.models import (MateriaLegislativa, StatusTramitacao,
TipoMateriaLegislativa)
@ -20,9 +23,10 @@ from sapl.utils import (RANGE_DIAS_MES, RANGE_MESES,
MateriaPesquisaOrderingFilter, autor_label,
autor_modal, timezone)
from .models import (Bancada, Bloco, ExpedienteMateria, Orador,
OradorExpediente, OrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, TipoResultadoVotacao, OcorrenciaSessao)
from .models import (Bancada, Bloco, ExpedienteMateria, JustificativaAusencia,
Orador, OradorExpediente, OrdemDia, SessaoPlenaria,
SessaoPlenariaPresenca, TipoJustificativa, TipoResultadoVotacao,
OcorrenciaSessao)
def recupera_anos():
@ -413,13 +417,13 @@ class MesaForm(forms.Form):
class ExpedienteForm(forms.Form):
conteudo = forms.CharField(required=False, widget=forms.Textarea)
class OcorrenciaSessaoForm(ModelForm):
class Meta:
model = OcorrenciaSessao
fields = ['conteudo']
class VotacaoForm(forms.Form):
votos_sim = forms.CharField(label='Sim')
votos_nao = forms.CharField(label='Não')
@ -684,3 +688,101 @@ class ResumoOrdenacaoForm(forms.Form):
raise ValidationError(_(
'Não é possível ter campos repetidos'))
return self.cleaned_data
class JustificativaAusenciaForm(ModelForm):
class Meta:
model = JustificativaAusencia
fields = ['parlamentar',
'hora',
'data',
'upload_anexo',
'tipo_ausencia',
'ausencia',
'materias_do_expediente',
'materias_da_ordem_do_dia',
'observacao'
]
widgets = {
'materias_do_expediente': CheckboxSelectMultiple(),
'materias_da_ordem_do_dia': CheckboxSelectMultiple()}
def __init__(self, *args, **kwargs):
row1 = to_row(
[('parlamentar', 12)])
row2 = to_row(
[('data', 6),
('hora', 6)])
row3 = to_row(
[('upload_anexo', 6)])
row4 = to_row(
[('tipo_ausencia', 12)])
row5 = to_row(
[('ausencia', 12)])
row6 = to_row(
[('materias_do_expediente', 12)])
row7 = to_row(
[('materias_da_ordem_do_dia', 12)])
row8 = to_row(
[('observacao', 12)])
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(
Fieldset(_('Justificativa de Ausência'),
row1, row2, row3,
row4, row5,
row6,
row7,
row8)
)
q = Q(sessao_plenaria=kwargs['initial']['sessao_plenaria'])
ordens = OrdemDia.objects.filter(q)
expedientes = ExpedienteMateria.objects.filter(q)
legislatura = kwargs['initial']['sessao_plenaria'].legislatura
mandato = Mandato.objects.filter(legislatura=legislatura)
parlamentares = [m.parlamentar for m in mandato]
super(JustificativaAusenciaForm, self).__init__(
*args, **kwargs)
presencas = SessaoPlenariaPresenca.objects.filter(
q).order_by('parlamentar__nome_parlamentar')
presentes = [p.parlamentar for p in presencas]
setFinal = set(parlamentares) - set(presentes)
self.fields['materias_do_expediente'].choices = [
(e.id, e.materia) for e in expedientes]
self.fields['materias_da_ordem_do_dia'].choices = [
(o.id, o.materia) for o in ordens]
self.fields['parlamentar'].choices = [
("0", "------------")] + [(p.id, p) for p in setFinal]
def clean(self):
cleaned_data = super(JustificativaAusenciaForm, self).clean()
if not self.is_valid():
return self.cleaned_data
sessao_plenaria = self.instance.sessao_plenaria
if not sessao_plenaria.finalizada or sessao_plenaria.finalizada is None:
raise ValidationError(
"A sessão deve está finalizada para registrar uma Ausência")
else:
return self.cleaned_data
def save(self, commit=False):
justificativa = super().save(True)
if justificativa.ausencia == 2:
justificativa.materias_do_expediente.clear()
justificativa.materias_da_ordem_do_dia.clear()
return justificativa

52
sapl/sessao/migrations/0028_auto_20181024_0848.py

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-10-24 10:48
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import sapl.sessao.models
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0025_auto_20180924_1724'),
('sessao', '0027_auto_20181023_1239'),
]
operations = [
migrations.CreateModel(
name='JustificativaAusencia',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('data', models.DateField(verbose_name='Data')),
('hora', models.CharField(max_length=5, verbose_name='Horário (hh:mm)')),
('observacao', models.TextField(blank=True, max_length=150, verbose_name='Observação')),
('ausencia', models.PositiveIntegerField(choices=[(1, 'Matéria'), (2, 'Sessão')], default=1, verbose_name='Ausente em')),
('upload_anexo', models.FileField(blank=True, null=True, upload_to=sapl.sessao.models.anexo_upload_path, verbose_name='Anexo de Justificativa')),
('parlamentar', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar', verbose_name='Parlamentar')),
('sessao_plenaria', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sessao.SessaoPlenaria', verbose_name='Sessão Plenária')),
],
options={
'verbose_name': 'Justificativa de Ausência',
'verbose_name_plural': 'Justificativas de Ausências',
},
),
migrations.CreateModel(
name='TipoJustificativa',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('descricao', models.CharField(max_length=150, verbose_name='Descrição')),
],
options={
'verbose_name': 'Tipo de Justificativa',
'verbose_name_plural': 'Tipos de Justificativa',
'ordering': ['descricao'],
},
),
migrations.AddField(
model_name='justificativaausencia',
name='tipo_ausencia',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.TipoJustificativa', verbose_name='Tipo de Justificativa'),
),
]

25
sapl/sessao/migrations/0029_auto_20181024_0952.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2018-10-24 12:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sessao', '0028_auto_20181024_0848'),
]
operations = [
migrations.AddField(
model_name='justificativaausencia',
name='materias_da_ordem_do_dia',
field=models.ManyToManyField(blank=True, to='sessao.OrdemDia', verbose_name='Matérias do Ordem do Dia'),
),
migrations.AddField(
model_name='justificativaausencia',
name='materias_do_expediente',
field=models.ManyToManyField(blank=True, to='sessao.ExpedienteMateria', verbose_name='Matérias do Expediente'),
),
]

81
sapl/sessao/models.py

@ -478,7 +478,7 @@ class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar
'''
votacao = models.ForeignKey(RegistroVotacao,
blank=True,
null=True,on_delete=models.CASCADE)
null=True, on_delete=models.CASCADE)
parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT)
voto = models.CharField(max_length=10)
@ -582,3 +582,82 @@ class ResumoOrdenacao(models.Model):
def __str__(self):
return 'Ordenação do Resumo de uma Sessão'
@reversion.register()
class TipoJustificativa(models.Model):
descricao = models.CharField(max_length=150, verbose_name=_('Descrição'))
class Meta:
verbose_name = _('Tipo de Justificativa')
verbose_name_plural = _('Tipos de Justificativa')
ordering = ['descricao']
def __str__(self):
return self.descricao
@reversion.register()
class JustificativaAusencia(models.Model):
TIPO_AUSENCIA_CHOICES = Choices(
(1, 'materia', 'Matéria'),
(2, 'sessao', 'Sessão'),
)
parlamentar = models.ForeignKey(Parlamentar, on_delete=models.PROTECT,
verbose_name=_('Parlamentar'))
sessao_plenaria = models.ForeignKey(SessaoPlenaria,
on_delete=models.CASCADE,
verbose_name=_('Sessão Plenária'))
tipo_ausencia = models.ForeignKey(TipoJustificativa, on_delete=models.PROTECT,
verbose_name=_('Tipo de Justificativa'))
data = models.DateField(verbose_name=_('Data'))
hora = models.CharField(
max_length=5, verbose_name=_('Horário (hh:mm)'))
observacao = models.TextField(
max_length=150, blank=True, verbose_name=_('Observação'))
ausencia = models.PositiveIntegerField(
verbose_name=_('Ausente em'), choices=TIPO_AUSENCIA_CHOICES, default=1)
materias_do_expediente = models.ManyToManyField(
ExpedienteMateria, blank=True, verbose_name=_('Matérias do Expediente'))
materias_da_ordem_do_dia = models.ManyToManyField(
OrdemDia, blank=True, verbose_name=_('Matérias do Ordem do Dia'))
upload_anexo = models.FileField(
blank=True,
null=True,
upload_to=anexo_upload_path,
verbose_name=_('Anexo de Justificativa'))
class Meta:
verbose_name = _('Justificativa de Ausência')
verbose_name_plural = _('Justificativas de Ausências')
def __str__(self):
return 'Justificativa de Ausência'
def delete(self, using=None, keep_parents=False):
if self.upload_anexo:
self.upload_anexo.delete()
return models.Model.delete(
self, using=using, keep_parents=keep_parents)
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
if not self.pk and self.upload_anexo:
upload_anexo = self.upload_anexo
self.upload_anexo = None
models.Model.save(self, force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields)
self.upload_anexo = upload_anexo
return models.Model.save(self, force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields)

10
sapl/sessao/urls.py

@ -3,15 +3,15 @@ from django.conf.urls import include, url
from sapl.sessao.views import (AdicionarVariasMateriasExpediente,
AdicionarVariasMateriasOrdemDia, BancadaCrud,
BlocoCrud, CargoBancadaCrud,
ExpedienteMateriaCrud, ExpedienteView, OcorrenciaSessaoView,
MateriaOrdemDiaCrud, MesaView, OradorCrud,
ExpedienteMateriaCrud, ExpedienteView, JustificativaAusenciaCrud,
OcorrenciaSessaoView, MateriaOrdemDiaCrud, MesaView, OradorCrud,
OradorExpedienteCrud, PainelView,
PautaSessaoDetailView, PautaSessaoView,
PesquisarPautaSessaoView,
PesquisarSessaoPlenariaView,
PresencaOrdemDiaView, PresencaView,
ResumoOrdenacaoView, ResumoView, ResumoAtaView, SessaoCrud,
TipoExpedienteCrud, TipoResultadoVotacaoCrud,
TipoJustificativaCrud, TipoExpedienteCrud, TipoResultadoVotacaoCrud,
TipoSessaoCrud, VotacaoEditView,
VotacaoExpedienteEditView,
VotacaoExpedienteView, VotacaoNominalEditView,
@ -38,6 +38,7 @@ urlpatterns = [
url(r'^sessao/', include(SessaoCrud.get_urls() + OradorCrud.get_urls() +
OradorExpedienteCrud.get_urls() +
ExpedienteMateriaCrud.get_urls() +
JustificativaAusenciaCrud.get_urls() +
MateriaOrdemDiaCrud.get_urls())),
url(r'^sessao/(?P<pk>\d+)/mesa$', MesaView.as_view(), name='mesa'),
@ -73,6 +74,8 @@ urlpatterns = [
include(TipoResultadoVotacaoCrud.get_urls())),
url(r'^sistema/sessao-plenaria/tipo-expediente/',
include(TipoExpedienteCrud.get_urls())),
url(r'^sistema/sessao-plenaria/tipo-justificativa/',
include(TipoJustificativaCrud.get_urls())),
url(r'^sistema/bancada/',
include(BancadaCrud.get_urls())),
url(r'^sistema/bloco/',
@ -152,7 +155,6 @@ urlpatterns = [
url(r'^sessao/(?P<pk>\d+)/votacao-simbolica-transparencia/(?P<oid>\d+)/(?P<mid>\d+)$',
VotacaoSimbolicaTransparenciaDetailView.as_view(),
name='votacao_simbolica_transparencia'),
url(r'^sessao/mudar-ordem-materia-sessao/',
mudar_ordem_materia_sessao,
name='mudar_ordem_materia_sessao'),

100
sapl/sessao/views.py

@ -38,21 +38,23 @@ from sapl.sessao.forms import ExpedienteMateriaForm, OrdemDiaForm
from sapl.utils import show_results_filter_set, remover_acentos
from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, BlocoForm,
ExpedienteForm, OcorrenciaSessaoForm, ListMateriaForm, MesaForm,
OradorExpedienteForm, OradorForm, PautaSessaoFilterSet,
ExpedienteForm, JustificativaAusenciaForm, OcorrenciaSessaoForm, ListMateriaForm,
MesaForm, OradorExpedienteForm, OradorForm, PautaSessaoFilterSet,
PresencaForm, ResumoOrdenacaoForm, SessaoPlenariaFilterSet,
SessaoPlenariaForm, VotacaoEditForm, VotacaoForm,
VotacaoNominalForm)
from .models import (Bancada, Bloco, CargoBancada, CargoMesa,
ExpedienteMateria, ExpedienteSessao, OcorrenciaSessao, IntegranteMesa,
from .models import (Bancada, Bloco, CargoBancada, CargoMesa, ExpedienteMateria,
ExpedienteSessao, JustificativaAusencia, OcorrenciaSessao, IntegranteMesa,
MateriaLegislativa, Orador, OradorExpediente, OrdemDia,
PresencaOrdemDia, RegistroVotacao, ResumoOrdenacao,
SessaoPlenaria, SessaoPlenariaPresenca, TipoExpediente,
TipoResultadoVotacao, TipoSessaoPlenaria, VotoParlamentar)
TipoJustificativa, TipoResultadoVotacao, TipoSessaoPlenaria,
VotoParlamentar)
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoExpedienteCrud = CrudAux.build(TipoExpediente, 'tipo_expediente')
TipoJustificativaCrud = CrudAux.build(TipoJustificativa, 'tipo_justificativa')
CargoBancadaCrud = CrudAux.build(CargoBancada, '')
@ -153,7 +155,7 @@ def abrir_votacao(request, pk, spk):
presenca_model = SessaoPlenariaPresenca
redirect_url = 'expedientemateria_list'
if not model:
raise Http404
raise Http404()
if (verifica_presenca(request, presenca_model, spk) and
verifica_votacoes_abertas(request) and
@ -1506,7 +1508,8 @@ class ResumoView(DetailView):
# =====================================================================
# Ocorrẽncias da Sessão
ocorrencias_sessao = OcorrenciaSessao.objects.filter(sessao_plenaria_id=self.object.id)
ocorrencias_sessao = OcorrenciaSessao.objects.filter(
sessao_plenaria_id=self.object.id)
context.update({'ocorrencias_da_sessao': ocorrencias_sessao})
@ -1649,7 +1652,6 @@ class ExpedienteView(FormMixin, DetailView):
return reverse('sapl.sessao:expediente', kwargs={'pk': pk})
class OcorrenciaSessaoView(FormMixin, DetailView):
template_name = 'sessao/ocorrencia_sessao.html'
form_class = OcorrenciaSessaoForm
@ -1667,7 +1669,7 @@ class OcorrenciaSessaoView(FormMixin, DetailView):
msg = _('Registro deletado com sucesso')
messages.add_message(self.request, messages.SUCCESS, msg)
def save(self,form):
def save(self, form):
conteudo = form.cleaned_data['conteudo']
OcorrenciaSessao.objects.filter(sessao_plenaria=self.object).delete()
@ -2024,7 +2026,6 @@ class VotacaoNominalAbstract(SessaoPermissionMixin):
self.logger.error('user=' + username + '. Objeto ExpedienteMateria com id={} não existe.'.format(expediente_id))
raise Http404()
if form.is_valid():
votos_sim = 0
votos_nao = 0
@ -3135,3 +3136,82 @@ def mudar_ordem_materia_sessao(request):
materia_1.save()
return
class JustificativaAusenciaCrud(MasterDetailCrud):
model = JustificativaAusencia
public = [RP_LIST, RP_DETAIL, ]
parent_field = 'sessao_plenaria'
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['parlamentar', 'sessao_plenaria', 'ausencia', 'tipo_ausencia',
'data']
@property
def layout_display(self):
layout = super().layout_display
if self.object.ausencia == 2:
# rm materias_da_ordem_do_dia do detail
layout[0]['rows'].pop(6)
# rm materias_do_expediente do detail
layout[0]['rows'].pop(5)
return layout
class ListView(MasterDetailCrud.ListView):
paginate_by = 10
class CreateView(MasterDetailCrud.CreateView):
form_class = JustificativaAusenciaForm
layout_key = None
def get_context_data_old(self, **kwargs):
context = super().get_context_data(**kwargs)
presencas = SessaoPlenariaPresenca.objects.filter(
sessao_plenaria_id=kwargs['root_pk']
).order_by('parlamentar__nome_parlamentar')
parlamentares_sessao = [p.parlamentar for p in presencas]
context.update({'presenca_sessao': parlamentares_sessao})
expedientes = ExpedienteMateria.objects.filter(
sessao_plenaria_id=kwargs['root_pk'])
expedientes_materia = [e.materia for e in expedientes]
context.update({'expedientes': expedientes})
ordens = OrdemDia.objects.filter(
sessao_plenaria_id=kwargs['root_pk'])
ordem_materia = [o.materia for o in ordens]
context.update({'ordens': ordens})
return context
def get_initial(self):
sessao_plenaria = SessaoPlenaria.objects.get(id=self.kwargs['pk'])
return {'sessao_plenaria': sessao_plenaria}
def get_success_url(self):
return reverse('sapl.sessao:justificativaausencia_list',
kwargs={'pk': self.kwargs['pk']})
class UpdateView(MasterDetailCrud.UpdateView):
form_class = JustificativaAusenciaForm
layout_key = None
def get_initial(self):
sessao_plenaria = JustificativaAusencia.objects.get(
id=self.kwargs['pk']).sessao_plenaria
return {'sessao_plenaria': sessao_plenaria}
class DeleteView(MasterDetailCrud.DeleteView):
pass

3
sapl/templates/menu_tabelas_auxiliares.yaml

@ -155,6 +155,9 @@
- title: {% trans 'Ordenação do Resumo' %}
url: sapl.sessao:resumo_ordenacao
css_class: btn btn-link
- title: {% trans 'Tipo de Justificativa' %}
url: sapl.sessao:tipojustificativa_list
css_class: btn btn-link
- title: {% trans 'Módulo LexML' %}
css_class: head_title
children:

6
sapl/templates/sessao/justificativaausencia_edit.html

@ -0,0 +1,6 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
{% crispy form %}
{% endblock detail_content %}

25
sapl/templates/sessao/justificativaausencia_form.html

@ -0,0 +1,25 @@
{% extends "crud/form.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
{% crispy form %}
{% endblock detail_content %}
{% block extra_js %}
<script type="text/javascript">
$(function () {
$("#id_ausencia").change(function() {
var val = $(this).val();
if(val === "1") {
$("#div_id_materias_do_expediente, #div_id_materias_da_ordem_do_dia").show();
}
else if(val === "2") {
$("#div_id_materias_do_expediente, #div_id_materias_da_ordem_do_dia").hide();
}
});
$("#id_ausencia").change()
});
</script>
{% endblock %}

15
sapl/templates/sessao/layouts.yaml

@ -84,3 +84,18 @@ Bloco:
- data_criacao data_extincao
- partidos
- descricao
TipoJustificativa:
{% trans 'Tipo de Justificativa' %}:
- descricao
JustificativaAusencia:
{% trans 'Justificativa de Ausência' %}:
- parlamentar
- data hora
- upload_anexo
- tipo_ausencia
- ausencia
- materias_do_expediente
- materias_da_ordem_do_dia
- observacao

2
sapl/templates/sessao/subnav.yaml

@ -8,6 +8,8 @@
url: mesa
- title: {% trans 'Presença' %}
url: presenca
- title: {% trans 'Ausência' %}
url: justificativaausencia_list
- title: {% trans 'Explicações Pessoais' %}
url: orador_list
- title: {% trans 'Ocorrências da Sessão' %}

1
sapl/templates/sistema.html

@ -105,6 +105,7 @@
<div class="col-md-6"><a href="{% url 'sapl.sessao:tiporesultadovotacao_list' %}" class="btn btn-link">Tipo de Resultado da Votação</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:tipoexpediente_list' %}" class="btn btn-link">Tipo de Expediente</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:resumo_ordenacao' %}" class="btn btn-link">Ordenação do Resumo</a></div>
<div class="col-md-6"><a href="{% url 'sapl.sessao:tipojustificativa' %}" class="btn btn-link">Tipo de Justificativa de Ausência</a></div>
</div>
<hr />

Loading…
Cancel
Save