From 63ad0dfae5b7645c7a0a62b368a5203d2b211650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeandroJata=C3=AD?= Date: Tue, 9 Aug 2022 08:56:26 -0300 Subject: [PATCH] =?UTF-8?q?Impl=20Issue=20#3326=20criando=20v=C3=ADnculo?= =?UTF-8?q?=20entre=20mat=C3=A9rias=20e=20docs=20adms=20(#3586)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * cria model VinculoDocAdminMateria * impl display em detailview de matéria e documentos * add unique_together a VinculoDocAdminMateria * impl crud de vinculodocadminmateria * impl vinculo em lote de docadm com matérias --- sapl/crispy_layout_mixin.py | 2 +- sapl/crud/base.py | 11 +- sapl/protocoloadm/forms.py | 104 +++++++++++- .../migrations/0041_auto_20220804_2239.py | 35 ++++ .../migrations/0042_auto_20220805_1236.py | 23 +++ sapl/protocoloadm/models.py | 63 ++++++- sapl/protocoloadm/urls.py | 13 +- sapl/protocoloadm/views.py | 160 +++++++++++++++++- .../materia/materialegislativa_detail.html | 35 +++- .../documentoadministrativo_detail.html | 24 +++ .../em_lote/vinculodocadminmateria.html | 74 ++++++++ sapl/templates/protocoloadm/layouts.yaml | 16 +- sapl/templates/protocoloadm/subnav.yaml | 2 + .../vinculodocadminmateria_form.html | 38 +++++ .../vinculodocadminmateria_list.html | 14 ++ 15 files changed, 590 insertions(+), 24 deletions(-) create mode 100644 sapl/protocoloadm/migrations/0041_auto_20220804_2239.py create mode 100644 sapl/protocoloadm/migrations/0042_auto_20220805_1236.py create mode 100644 sapl/templates/protocoloadm/em_lote/vinculodocadminmateria.html create mode 100644 sapl/templates/protocoloadm/vinculodocadminmateria_form.html create mode 100644 sapl/templates/protocoloadm/vinculodocadminmateria_list.html diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index ea92ce09f..0f85b669f 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -170,7 +170,7 @@ def get_field_display(obj, fieldname): display = '
{}
'.format(display) else: display = str(value) - return verbose_name, display + return verbose_name, display or ' ' class CrispyLayoutFormMixin: diff --git a/sapl/crud/base.py b/sapl/crud/base.py index 5b0aab24c..435bf06a6 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -1119,12 +1119,15 @@ class MasterDetailCrud(Crud): root_pk = self.kwargs['pk'] if 'pkk' not in self.request.GET\ else self.request.GET['pkk'] kwargs.setdefault('root_pk', root_pk) - context = super(CrudBaseMixin, self).get_context_data(**kwargs) - if parent_object: - context['title'] = '%s (%s)' % ( - self.object, parent_object) + title = '%s (%s)' % ( + self.object, + parent_object + ) if parent_object else '' + context = super(CrudBaseMixin, self).get_context_data(**kwargs) + if 'title' not in context and title: + context['title'] = title return context class ListView(Crud.ListView): diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index 1d70d3a31..744d30e5e 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -20,6 +20,7 @@ from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper, from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa, UnidadeTramitacao) +from sapl.protocoloadm.models import VinculoDocAdminMateria from sapl.utils import (AnoNumeroOrderingFilter, autor_label, autor_modal, choice_anos_com_documentoadministrativo, choice_anos_com_materias, timing, @@ -793,7 +794,7 @@ class TramitacaoAdmForm(ModelForm): ip=tramitacao.ip, ultima_edicao=tramitacao.ultima_edicao )) - ## TODO: BULK UPDATE não envia Signal para Tramitacao + # TODO: BULK UPDATE não envia Signal para Tramitacao TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao) return tramitacao @@ -915,7 +916,7 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): da.tramitacao = False if nova_tram_principal.status.indicador == "F" else True da.save() - ## TODO: refatorar? + # TODO: refatorar? return nova_tram_principal @@ -1694,7 +1695,7 @@ class TramitacaoEmLoteAdmForm(ModelForm): ip=tramitacao.ip, ultima_edicao=tramitacao.ultima_edicao )) - ## TODO: BULK UPDATE não envia Signal para Tramitacao + # TODO: BULK UPDATE não envia Signal para Tramitacao TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao) return tramitacao @@ -1732,3 +1733,100 @@ class TramitacaoEmLoteAdmFilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset(_('Tramitação em Lote'), row1, row2, form_actions(label=_('Pesquisar')))) + + +class VinculoDocAdminMateriaForm(ModelForm): + + logger = logging.getLogger(__name__) + + tipo = forms.ModelChoiceField( + label='Tipo', + required=True, + queryset=TipoMateriaLegislativa.objects.all(), + empty_label='Selecione', + ) + + numero = forms.IntegerField(label='Número', required=True) + + ano = forms.CharField(label='Ano', required=True) + + class Meta: + model = VinculoDocAdminMateria + fields = ['tipo', 'numero', 'ano', 'data_anexacao', 'data_desanexacao'] + + def __init__(self, *args, **kwargs): + return super().__init__(*args, **kwargs) + + def clean(self): + super().clean() + + if not self.is_valid(): + return self.cleaned_data + + cleaned_data = self.cleaned_data + + data_anexacao = cleaned_data['data_anexacao'] + data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao + + if data_anexacao > data_desanexacao: + self.logger.error( + "Data de anexação posterior à data de desanexação.") + raise ValidationError( + _("Data de anexação posterior à data de desanexação.")) + + try: + self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})." + .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) + materia = MateriaLegislativa.objects.get( + numero=cleaned_data['numero'], + ano=cleaned_data['ano'], + tipo=cleaned_data['tipo']) + except ObjectDoesNotExist: + msg = _('A {} {}/{} não existe no cadastro de matérias legislativas.' + .format(cleaned_data['tipo'], cleaned_data['numero'], cleaned_data['ano'])) + self.logger.warning( + "A matéria a ser anexada não existe no cadastro de matérias legislativas.") + raise ValidationError(msg) + + if VinculoDocAdminMateria.objects.filter( + documento=self.instance.documento, materia=materia + ).exclude(pk=self.instance.pk).exists(): + self.logger.error( + "Matéria já se encontra vinculada a este documento.") + raise ValidationError( + _('Matéria já se encontra vinculada a este documento')) + + cleaned_data['materia'] = materia + + return cleaned_data + + def save(self, commit=False): + vinculo = super().save(commit) + vinculo.materia = self.cleaned_data['materia'] + vinculo.save() + return vinculo + + +class VinculoDocAdminMateriaEmLoteFilterSet(django_filters.FilterSet): + + class Meta(FilterOverridesMetaMixin): + model = MateriaLegislativa + fields = ['tipo', 'data_apresentacao'] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.filters['tipo'].label = 'Tipo de Matéria' + self.filters['data_apresentacao'].label = 'Data (Inicial - Final)' + + self.form.fields['tipo'].required = True + self.form.fields['data_apresentacao'].required = True + + row1 = to_row([('tipo', 12)]) + row2 = to_row([('data_apresentacao', 12)]) + + self.form.helper = SaplFormHelper() + self.form.helper.form_method = 'GET' + self.form.helper.layout = Layout( + Fieldset(_('Pesquisa de Matérias'), + row1, row2, form_actions(label='Pesquisar'))) diff --git a/sapl/protocoloadm/migrations/0041_auto_20220804_2239.py b/sapl/protocoloadm/migrations/0041_auto_20220804_2239.py new file mode 100644 index 000000000..0e67fbc46 --- /dev/null +++ b/sapl/protocoloadm/migrations/0041_auto_20220804_2239.py @@ -0,0 +1,35 @@ +# Generated by Django 2.2.28 on 2022-08-05 01:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0081_auto_20220321_0934'), + ('protocoloadm', '0040_auto_20220321_0934'), + ] + + operations = [ + migrations.CreateModel( + name='VinculoDocAdminMateria', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('data_anexacao', models.DateField(verbose_name='Data Anexação')), + ('data_desanexacao', models.DateField(blank=True, null=True, verbose_name='Data Desanexação')), + ('documento', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='materialegislativa_vinculada_set', to='protocoloadm.DocumentoAdministrativo', verbose_name='Documento Administrativo')), + ('materia', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documentoadministrativo_vinculado_set', to='materia.MateriaLegislativa', verbose_name='Matéria Legislativa')), + ], + options={ + 'verbose_name': 'Vinculo entre Documento Administrativo e Matéria Legislativa', + 'verbose_name_plural': 'Vinculos entre Documento Administrativo e Matéria Legislativa', + 'ordering': ('id',), + }, + ), + migrations.AddField( + model_name='documentoadministrativo', + name='materiasvinculadas', + field=models.ManyToManyField(blank=True, related_name='docadmsvinculados', through='protocoloadm.VinculoDocAdminMateria', to='materia.MateriaLegislativa'), + ), + ] diff --git a/sapl/protocoloadm/migrations/0042_auto_20220805_1236.py b/sapl/protocoloadm/migrations/0042_auto_20220805_1236.py new file mode 100644 index 000000000..cc667daba --- /dev/null +++ b/sapl/protocoloadm/migrations/0042_auto_20220805_1236.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.28 on 2022-08-05 15:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0081_auto_20220321_0934'), + ('protocoloadm', '0041_auto_20220804_2239'), + ] + + operations = [ + migrations.AlterField( + model_name='documentoadministrativo', + name='materiasvinculadas', + field=models.ManyToManyField(blank=True, related_name='docadmvinculados', through='protocoloadm.VinculoDocAdminMateria', to='materia.MateriaLegislativa'), + ), + migrations.AlterUniqueTogether( + name='vinculodocadminmateria', + unique_together={('documento', 'materia')}, + ), + ] diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index 9b1a65d85..82f899465 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -5,7 +5,8 @@ from model_utils import Choices import reversion from sapl.base.models import Autor -from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao +from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao,\ + MateriaLegislativa from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, texto_upload_path, get_settings_auth_user_model, OverwriteStorage) @@ -91,7 +92,8 @@ class Protocolo(models.Model): blank=True ) de_proposicao = models.BooleanField(default=False) - # Não foi utilizado auto_now_add=True em timestamp porque ele usa datetime.now que não é timezone aware. + # Não foi utilizado auto_now_add=True em timestamp porque ele usa + # datetime.now que não é timezone aware. timestamp = models.DateTimeField( null=True, blank=True, @@ -160,7 +162,7 @@ class DocumentoAdministrativo(models.Model): numero = models.PositiveIntegerField(verbose_name=_('Número')) complemento = models.CharField(max_length=10, blank=True, - verbose_name=_('Complemento')) + verbose_name=_('Complemento')) ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), choices=RANGE_ANOS) @@ -214,6 +216,17 @@ class DocumentoAdministrativo(models.Model): ) ) + materiasvinculadas = models.ManyToManyField( + MateriaLegislativa, + blank=True, + through='VinculoDocAdminMateria', + related_name='docadmvinculados', + through_fields=( + 'documento', + 'materia' + ) + ) + user = models.ForeignKey( get_settings_auth_user_model(), verbose_name=_('Usuário'), @@ -242,6 +255,14 @@ class DocumentoAdministrativo(models.Model): 'tipo': self.tipo, 'assunto': self.assunto } + @property + def epigrafe(self): + return _('%(tipo)s - %(numero)s/%(ano)s') % { + 'tipo': self.tipo, + 'numero': self.numero, + 'ano': self.ano + } + def delete(self, using=None, keep_parents=False): texto_integral = self.texto_integral result = super().delete(using=using, keep_parents=keep_parents) @@ -436,6 +457,42 @@ class Anexado(models.Model): } +@reversion.register() +class VinculoDocAdminMateria(models.Model): + documento = models.ForeignKey( + DocumentoAdministrativo, related_name='materialegislativa_vinculada_set', + on_delete=models.CASCADE, + verbose_name=_('Documento Administrativo') + ) + materia = models.ForeignKey( + MateriaLegislativa, related_name='documentoadministrativo_vinculado_set', + on_delete=models.CASCADE, + verbose_name=_('Matéria Legislativa') + ) + data_anexacao = models.DateField(verbose_name=_('Data Anexação')) + data_desanexacao = models.DateField( + blank=True, null=True, verbose_name=_('Data Desanexação') + ) + + class Meta: + verbose_name = _( + 'Vinculo entre Documento Administrativo e Matéria Legislativa') + verbose_name_plural = _( + 'Vinculos entre Documento Administrativo e Matéria Legislativa') + ordering = ('id',) + unique_together = ( + ('documento', 'materia'), + ) + + def __str__(self): + return f'Vinculo: {self.documento} - {self.materia}' + + return _('Vinculo %(documento)s // %(materia)s') % { + 'documento': self.documento.epigrafe, + 'materia': self.materia + } + + @reversion.register() class AcompanhamentoDocumento(models.Model): usuario = models.CharField(max_length=50) diff --git a/sapl/protocoloadm/urls.py b/sapl/protocoloadm/urls.py index 2e3e07ac1..0d0290ac5 100644 --- a/sapl/protocoloadm/urls.py +++ b/sapl/protocoloadm/urls.py @@ -25,7 +25,9 @@ from sapl.protocoloadm.views import (AcompanhamentoDocumentoView, AnexadoCrud, DocumentoAnexadoEmLoteView, PrimeiraTramitacaoEmLoteAdmView, TramitacaoEmLoteAdmView, - apaga_protocolos_view) + apaga_protocolos_view, + VinculoDocAdminMateriaCrud, + VinculoDocAdminMateriaEmLoteView) from .apps import AppConfig @@ -34,18 +36,21 @@ app_name = AppConfig.name urlpatterns_documento_administrativo = [ url(r'^docadm/', include(DocumentoAdministrativoCrud.get_urls() + - AnexadoCrud.get_urls() + + AnexadoCrud.get_urls() + TramitacaoAdmCrud.get_urls() + - DocumentoAcessorioAdministrativoCrud.get_urls())), + DocumentoAcessorioAdministrativoCrud.get_urls() + + VinculoDocAdminMateriaCrud.get_urls())), url(r'^docadm/pesq-doc-adm', PesquisarDocumentoAdministrativoView.as_view(), name='pesq_doc_adm'), url(r'^docadm/texto_integral/(?P\d+)$', doc_texto_integral, name='doc_texto_integral'), - + url(r'^docadm/(?P\d+)/anexado_em_lote', DocumentoAnexadoEmLoteView.as_view(), name='anexado_em_lote'), + url(r'^docadm/(?P\d+)/vinculo-em-lote', VinculoDocAdminMateriaEmLoteView.as_view(), + name='vinculodocadminmateria_em_lote'), ] urlpatterns_protocolo = [ diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 01e525750..869c6d240 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -35,7 +35,10 @@ from sapl.crud.base import (Crud, CrudAux, MasterDetailCrud, make_pagination, from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa, UnidadeTramitacao from sapl.materia.views import gerar_pdf_impressos from sapl.parlamentares.models import Legislatura, Parlamentar -from sapl.protocoloadm.models import Protocolo, DocumentoAdministrativo +from sapl.protocoloadm.forms import VinculoDocAdminMateriaForm,\ + VinculoDocAdminMateriaEmLoteFilterSet +from sapl.protocoloadm.models import Protocolo, DocumentoAdministrativo,\ + VinculoDocAdminMateria from sapl.relatorios.views import relatorio_doc_administrativos from sapl.utils import (create_barcode, get_base_url, get_client_ip, get_mime_type_from_file_extension, lista_anexados, @@ -1126,7 +1129,7 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView): context['object_list'] = [] else: context['temp_object_list'] = context['object_list'].order_by( - 'numero', '-ano') + 'numero', '-ano') context['object_list'] = [] for obj in context['temp_object_list']: if not obj.pk == int(context['root_pk']): @@ -1155,7 +1158,6 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView): if not ciclico: context['object_list'].append(obj) - context['numero_res'] = len(context['object_list']) @@ -1300,7 +1302,6 @@ class TramitacaoAdmCrud(MasterDetailCrud): return initial - class ListView(DocumentoAdministrativoMixin, MasterDetailCrud.ListView): def get_queryset(self): @@ -1751,3 +1752,154 @@ def apaga_protocolos_view(request): return JsonResponse({'type': 'success', 'msg': ''}) else: return JsonResponse({'type': 'error', 'msg': 'Senha Incorreta'}) + + +class VinculoDocAdminMateriaCrud(MasterDetailCrud): + model = VinculoDocAdminMateria + parent_field = 'documento' + help_topic = 'vinculodocadminmateria' + public = [RP_LIST, RP_DETAIL] + + class BaseMixin(MasterDetailCrud.BaseMixin): + list_field_names = ['data_anexacao', ('materia', 'materia__ementa')] + + @property + def verbose_name(self): + return _('Vinculo') + + @property + def verbose_name_plural(self): + return _('Vinculos') + + @property + def title(self): + return self.object.documento.epigrafe + + class CreateView(MasterDetailCrud.CreateView): + form_class = VinculoDocAdminMateriaForm + + class UpdateView(MasterDetailCrud.UpdateView): + form_class = VinculoDocAdminMateriaForm + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['title'] = self.object.documento.epigrafe + return context + + def get_initial(self): + initial = super(UpdateView, self).get_initial() + initial['tipo'] = self.object.materia.tipo.id + initial['numero'] = self.object.materia.numero + initial['ano'] = self.object.materia.ano + return initial + + class DetailView(MasterDetailCrud.DetailView): + + @property + def layout_key(self): + return 'VinculoDocAdminMateriaDetail' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['title'] = self.object.documento.epigrafe + return context + + +class VinculoDocAdminMateriaEmLoteView(PermissionRequiredMixin, FilterView): + filterset_class = VinculoDocAdminMateriaEmLoteFilterSet + template_name = 'protocoloadm/em_lote/vinculodocadminmateria.html' + permission_required = ('protocoloadm.add_documentoadministrativo',) + + def get_context_data(self, **kwargs): + context = super(VinculoDocAdminMateriaEmLoteView, + self).get_context_data(**kwargs) + + context['root_pk'] = self.kwargs['pk'] + + context['subnav_template_name'] = 'protocoloadm/subnav.yaml' + + context['title'] = _('Matérias Vinculadas em Lote') + + # Verifica se os campos foram preenchidos + if not self.request.GET.get('tipo', " "): + msg = _('Por favor, selecione um tipo de matéria.') + messages.add_message(self.request, messages.ERROR, msg) + + if not self.request.GET.get('data_apresentacao_0', " ") or not self.request.GET.get('data_apresentacao_1', " "): + msg = _('Por favor, preencha as datas.') + messages.add_message(self.request, messages.ERROR, msg) + + return context + + if not self.request.GET.get('data_apresentacao_0', " ") or not self.request.GET.get('data_apresentacao_1', " "): + msg = _('Por favor, preencha as datas.') + messages.add_message(self.request, messages.ERROR, msg) + return context + + qr = self.request.GET.copy() + if not len(qr): + context['object_list'] = [] + else: + context['object_list'] = context['object_list'].order_by( + 'numero', '-ano') + documento = DocumentoAdministrativo.objects.get( + pk=self.kwargs['pk']) + not_list = [self.kwargs['pk']] + \ + [m for m in documento.materiasvinculadas.values_list( + 'id', flat=True)] + context['object_list'] = context['object_list'].exclude( + pk__in=not_list) + + context['numero_res'] = len(context['object_list']) + + context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + + context['show_results'] = show_results_filter_set(qr) + + return context + + def post(self, request, *args, **kwargs): + marcadas = request.POST.getlist('materia_id') + + data_anexacao = datetime.strptime( + request.POST['data_anexacao'], "%d/%m/%Y").date() + + if request.POST['data_desanexacao'] == '': + data_desanexacao = None + v_data_desanexacao = data_anexacao + else: + data_desanexacao = datetime.strptime( + request.POST['data_desanexacao'], "%d/%m/%Y").date() + v_data_desanexacao = data_desanexacao + + if len(marcadas) == 0: + msg = _('Nenhuma máteria foi selecionada.') + messages.add_message(request, messages.ERROR, msg) + + if data_anexacao > v_data_desanexacao: + msg = _('Data de anexação posterior à data de desanexação.') + messages.add_message(request, messages.ERROR, msg) + + return self.get(request, self.kwargs) + + if data_anexacao > v_data_desanexacao: + msg = _('Data de anexação posterior à data de desanexação.') + messages.add_message(request, messages.ERROR, msg) + return self.get(request, self.kwargs) + + documento = DocumentoAdministrativo.objects.get(pk=kwargs['pk']) + for materia in MateriaLegislativa.objects.filter(id__in=marcadas): + + v = VinculoDocAdminMateria() + v.documento = documento + v.materia = materia + v.data_anexacao = data_anexacao + v.data_desanexacao = data_desanexacao + v.save() + + msg = _('Matéria(s) vinculadas(s).') + messages.add_message(request, messages.SUCCESS, msg) + + success_url = reverse('sapl.protocoloadm:vinculodocadminmateria_list', + kwargs={'pk': kwargs['pk']}) + return HttpResponseRedirect(success_url) diff --git a/sapl/templates/materia/materialegislativa_detail.html b/sapl/templates/materia/materialegislativa_detail.html index 61568608a..3b736318f 100644 --- a/sapl/templates/materia/materialegislativa_detail.html +++ b/sapl/templates/materia/materialegislativa_detail.html @@ -1,6 +1,5 @@ {% extends "crud/detail.html" %} -{% load i18n %} -{% load tz %} +{% load i18n tz common_tags %} {% block sub_actions %} {{ block.super }} @@ -48,6 +47,38 @@ {{ object.normajuridica_set.last }} {% endif %} + + {% if object.docadmvinculados.all.exists %} + {% if "documentos_administrativos"|get_config_attr == 'O' or "documentos_administrativos"|get_config_attr == 'R' and not user.is_anonymous %} +
+
+
+

Documentos Administrativos Públicos Vinculados a Matéria

+
+
+ {% for vinculodocadmmateria in object.documentoadministrativo_vinculado_set.all %} + {% if not vinculodocadmmateria.documento.restrito or vinculodocadmmateria.documento.restrito and not user.is_anonymous %} + Data Anexação: {{vinculodocadmmateria.data_anexacao}} {% if vinculodocadmmateria.data_desanexacao %} - {{vinculodocadmmateria.data_desanexacao}}{% endif %} +
Documento: + + {{ vinculodocadmmateria.documento.epigrafe }} + +
{{ vinculodocadmmateria.documento.assunto}} + {% if vinculodocadmmateria.documento.restrito %} + + (Documento Restrito) + + {% endif %} + {% endif %} + {% if not forloop.last %}
{% endif %} + {% endfor %} +
+
+
+
+ {% endif %} + {% endif %} + {% if object.audienciapublica_set.exists %}

  Audiência(s) Pública(s)

diff --git a/sapl/templates/protocoloadm/documentoadministrativo_detail.html b/sapl/templates/protocoloadm/documentoadministrativo_detail.html index 02aad5ffc..2ab80b885 100644 --- a/sapl/templates/protocoloadm/documentoadministrativo_detail.html +++ b/sapl/templates/protocoloadm/documentoadministrativo_detail.html @@ -3,6 +3,30 @@ {% block detail_content %} {{ block.super }} + + {% if documentoadministrativo.materiasvinculadas.all.exists %} +
+
+
+

Matérias Legislativas Vinculadas

+
+
+ {% for vinculodocadmmateria in object.materialegislativa_vinculada_set.all %} + Data Anexação: {{vinculodocadmmateria.data_anexacao}} {% if vinculodocadmmateria.data_desanexacao %} - {{vinculodocadmmateria.data_desanexacao}}{% endif %} +
Matéria: + + {{ vinculodocadmmateria.materia }} + +
{{vinculodocadmmateria.materia.ementa}} + {% if not forloop.last %}
{% endif %} + {% endfor %} +
+
+
+
+ {% endif %} + + {% if user.is_superuser %}
{% if documentoadministrativo.user %} diff --git a/sapl/templates/protocoloadm/em_lote/vinculodocadminmateria.html b/sapl/templates/protocoloadm/em_lote/vinculodocadminmateria.html new file mode 100644 index 000000000..e4393b805 --- /dev/null +++ b/sapl/templates/protocoloadm/em_lote/vinculodocadminmateria.html @@ -0,0 +1,74 @@ +{% extends "crud/detail.html" %} +{% load i18n crispy_forms_tags %} +{% block actions %}{% endblock %} + +{% block detail_content %} + {% if not show_results %} + {% crispy filter.form %} + {% endif %} + {% if show_results %} + {% if numero_res > 0 %} + {% if numero_res == 1 %} +

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

+ {% else %} +

Foram encontradas {{ numero_res }} matérias.

+ {% endif %} +
+ {% csrf_token %} +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ Matérias para Vincular em Lote + +
+
+ +
+
+ + + {% for materia in object_list %} + + + + {% endfor %} + +
Matéria
+ +
+
+ +
+ {% else %} +

Nenhuma matéria encontrada.

+ {% endif %} + {% endif %} +{% endblock detail_content %} + +{% block extra_js %} + +{% endblock %} diff --git a/sapl/templates/protocoloadm/layouts.yaml b/sapl/templates/protocoloadm/layouts.yaml index 7bf96372f..c223f686a 100644 --- a/sapl/templates/protocoloadm/layouts.yaml +++ b/sapl/templates/protocoloadm/layouts.yaml @@ -5,9 +5,9 @@ TipoDocumentoAdministrativo: DocumentoAdministrativo: {% trans 'Identificação Básica' %}: - - tipo + - tipo - numero complemento ano - - data protocolo + - data protocolo - assunto - interessado autor tramitacao - texto_integral|urlize @@ -33,7 +33,7 @@ TramitacaoAdministrativo: {% trans 'Tramitação' %}: - data_tramitacao unidade_tramitacao_local - unidade_tramitacao_destino data_encaminhamento data_fim_prazo - - status urgente + - status urgente - texto Anexado: @@ -62,3 +62,13 @@ Protocolo: - assunto_ementa - autor - observacao + +VinculoDocAdminMateria: + {% trans 'Matéria Vinculada' %}: + - tipo numero ano + - data_anexacao data_desanexacao + +VinculoDocAdminMateriaDetail: + {% trans 'Matéria Vinculada' %}: + - materia|fk_urlize_for_detail data_anexacao:3 data_desanexacao:3 + - documento diff --git a/sapl/templates/protocoloadm/subnav.yaml b/sapl/templates/protocoloadm/subnav.yaml index 5e0c3021b..a431819fd 100644 --- a/sapl/templates/protocoloadm/subnav.yaml +++ b/sapl/templates/protocoloadm/subnav.yaml @@ -7,3 +7,5 @@ url: tramitacaoadministrativo_list - title: {% trans 'Documento Acessório' %} url: documentoacessorioadministrativo_list +- title: {% trans 'Matérias Vinculadas' %} + url: vinculodocadminmateria_list diff --git a/sapl/templates/protocoloadm/vinculodocadminmateria_form.html b/sapl/templates/protocoloadm/vinculodocadminmateria_form.html new file mode 100644 index 000000000..f3864dba7 --- /dev/null +++ b/sapl/templates/protocoloadm/vinculodocadminmateria_form.html @@ -0,0 +1,38 @@ +{% extends "crud/form.html" %} +{% load i18n %} + +{% block extra_js %} + +{% endblock %} diff --git a/sapl/templates/protocoloadm/vinculodocadminmateria_list.html b/sapl/templates/protocoloadm/vinculodocadminmateria_list.html new file mode 100644 index 000000000..791d62557 --- /dev/null +++ b/sapl/templates/protocoloadm/vinculodocadminmateria_list.html @@ -0,0 +1,14 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load common_tags %} + + +{% block more_buttons %} + +{% if perms|get_add_perm:view %} + + {% trans "Adicionar Vínculos em Lote" %} + +{% endif %} + +{% endblock more_buttons %}