From acf3070571421d6d1b7500131bba0cc13c844396 Mon Sep 17 00:00:00 2001 From: Mariana Mendes Date: Tue, 6 Nov 2018 17:36:14 -0300 Subject: [PATCH] fix #1801 (#2260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create Tipo Justificativa * Adding the migrate * Adding justificativa on map rules * WIP Co-authored-by: João Pedro Sconetto * 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 --- sapl/rules/map_rules.py | 3 + sapl/sessao/forms.py | 112 +++++++++++++++++- .../migrations/0028_auto_20181024_0848.py | 52 ++++++++ .../migrations/0029_auto_20181024_0952.py | 25 ++++ sapl/sessao/models.py | 81 ++++++++++++- sapl/sessao/urls.py | 12 +- sapl/sessao/views.py | 100 ++++++++++++++-- sapl/templates/menu_tabelas_auxiliares.yaml | 3 + .../sessao/justificativaausencia_edit.html | 6 + .../sessao/justificativaausencia_form.html | 25 ++++ sapl/templates/sessao/layouts.yaml | 15 +++ sapl/templates/sessao/subnav.yaml | 2 + sapl/templates/sistema.html | 1 + 13 files changed, 416 insertions(+), 21 deletions(-) create mode 100644 sapl/sessao/migrations/0028_auto_20181024_0848.py create mode 100644 sapl/sessao/migrations/0029_auto_20181024_0952.py create mode 100644 sapl/templates/sessao/justificativaausencia_edit.html create mode 100644 sapl/templates/sessao/justificativaausencia_form.html diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py index 342f3383a..2b6204ec2 100644 --- a/sapl/rules/map_rules.py +++ b/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__), diff --git a/sapl/sessao/forms.py b/sapl/sessao/forms.py index f514ed6a7..a72a86109 100644 --- a/sapl/sessao/forms.py +++ b/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 diff --git a/sapl/sessao/migrations/0028_auto_20181024_0848.py b/sapl/sessao/migrations/0028_auto_20181024_0848.py new file mode 100644 index 000000000..825b6707e --- /dev/null +++ b/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'), + ), + ] diff --git a/sapl/sessao/migrations/0029_auto_20181024_0952.py b/sapl/sessao/migrations/0029_auto_20181024_0952.py new file mode 100644 index 000000000..880486834 --- /dev/null +++ b/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'), + ), + ] diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index 2ef2522e5..176b533b7 100644 --- a/sapl/sessao/models.py +++ b/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) diff --git a/sapl/sessao/urls.py b/sapl/sessao/urls.py index 1e3e4ae43..f2e2fbbcc 100644 --- a/sapl/sessao/urls.py +++ b/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\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,8 +155,7 @@ urlpatterns = [ url(r'^sessao/(?P\d+)/votacao-simbolica-transparencia/(?P\d+)/(?P\d+)$', VotacaoSimbolicaTransparenciaDetailView.as_view(), name='votacao_simbolica_transparencia'), - url(r'^sessao/mudar-ordem-materia-sessao/', mudar_ordem_materia_sessao, - name='mudar_ordem_materia_sessao'), + name='mudar_ordem_materia_sessao'), ] diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index bcd6482d0..766a6976e 100755 --- a/sapl/sessao/views.py +++ b/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 diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml index c1ae1767f..65ea6fd6f 100644 --- a/sapl/templates/menu_tabelas_auxiliares.yaml +++ b/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: diff --git a/sapl/templates/sessao/justificativaausencia_edit.html b/sapl/templates/sessao/justificativaausencia_edit.html new file mode 100644 index 000000000..28955d18e --- /dev/null +++ b/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 %} diff --git a/sapl/templates/sessao/justificativaausencia_form.html b/sapl/templates/sessao/justificativaausencia_form.html new file mode 100644 index 000000000..f2d01b706 --- /dev/null +++ b/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 %} + + +{% endblock %} + \ No newline at end of file diff --git a/sapl/templates/sessao/layouts.yaml b/sapl/templates/sessao/layouts.yaml index b0127565f..4e9e1118a 100644 --- a/sapl/templates/sessao/layouts.yaml +++ b/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 diff --git a/sapl/templates/sessao/subnav.yaml b/sapl/templates/sessao/subnav.yaml index 0a98b8a3b..40c5903c4 100644 --- a/sapl/templates/sessao/subnav.yaml +++ b/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' %} diff --git a/sapl/templates/sistema.html b/sapl/templates/sistema.html index 8e3882369..2283266b8 100644 --- a/sapl/templates/sistema.html +++ b/sapl/templates/sistema.html @@ -105,6 +105,7 @@ +