From 33d02874392c43a4e9f5615e02ff94e610b5b154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Mon, 9 Dec 2019 11:57:15 -0300 Subject: [PATCH] =?UTF-8?q?Adiciona=20dados=20da=20=C3=BAltima=20altera?= =?UTF-8?q?=C3=A7=C3=A3o=20e=20Bug=20Fix=20(#2919)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Impl. #2909 - Tramitação de Matéria Legislativa * Impl. #2909 - Matéria Legislativa * Impl. #2909 - Norma Jurídica * Adicionar correções * Adicionar migrações * Impl. #2909 - Tramitação Documento Administrativo * Adicionar correções * Impl. #2936 * Evitar merge de migrações * Evitar merge de migrações * Evitar merge de migrações * Adicionar migrações * Adicionar migrations --- sapl/materia/forms.py | 48 ++++-- .../migrations/0056_auto_20190829_1206.py | 25 +++ .../migrations/0058_merge_20190926_1250.py | 16 ++ .../migrations/0061_merge_20191009_1814.py | 16 ++ sapl/materia/models.py | 8 + sapl/materia/views.py | 47 +++--- sapl/norma/forms.py | 7 +- .../0027_normajuridica_ultima_edicao.py | 20 +++ .../migrations/0028_merge_20191009_1814.py | 16 ++ sapl/norma/models.py | 4 + sapl/norma/views.py | 12 ++ sapl/protocoloadm/forms.py | 48 ++++-- ..._tramitacaoadministrativo_ultima_edicao.py | 20 +++ .../migrations/0025_auto_20190815_1539.py | 20 +++ .../migrations/0026_auto_20190815_1737.py | 33 ++++ .../migrations/0027_merge_20190926_1250.py | 16 ++ .../migrations/0028_merge_20191009_1814.py | 16 ++ sapl/protocoloadm/models.py | 22 +++ sapl/protocoloadm/views.py | 79 ++++++++- .../materia/materialegislativa_detail.html | 28 +++- sapl/templates/materia/tramitacao_detail.html | 26 ++- .../templates/norma/normajuridica_detail.html | 157 ++++++++++-------- .../documentoadministrativo_detail.html | 54 ++++++ .../tramitacaoadministrativo_detail.html | 52 ++++-- 24 files changed, 643 insertions(+), 147 deletions(-) create mode 100644 sapl/materia/migrations/0056_auto_20190829_1206.py create mode 100644 sapl/materia/migrations/0058_merge_20190926_1250.py create mode 100644 sapl/materia/migrations/0061_merge_20191009_1814.py create mode 100644 sapl/norma/migrations/0027_normajuridica_ultima_edicao.py create mode 100644 sapl/norma/migrations/0028_merge_20191009_1814.py create mode 100644 sapl/protocoloadm/migrations/0024_tramitacaoadministrativo_ultima_edicao.py create mode 100644 sapl/protocoloadm/migrations/0025_auto_20190815_1539.py create mode 100644 sapl/protocoloadm/migrations/0026_auto_20190815_1737.py create mode 100644 sapl/protocoloadm/migrations/0027_merge_20190926_1250.py create mode 100644 sapl/protocoloadm/migrations/0028_merge_20191009_1814.py create mode 100644 sapl/templates/protocoloadm/documentoadministrativo_detail.html diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index fe6c27004..e3f46d595 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -179,7 +179,8 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm): 'anexadas', 'data_ultima_atualizacao'] widgets = { 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput() + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput() } def __init__(self, *args, **kwargs): @@ -463,9 +464,12 @@ class TramitacaoForm(ModelForm): 'data_fim_prazo', 'texto', 'user', - 'ip'] + 'ip', + 'ultima_edicao'] + widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput()} + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput()} def __init__(self, *args, **kwargs): super(TramitacaoForm, self).__init__(*args, **kwargs) @@ -578,7 +582,8 @@ class TramitacaoForm(ModelForm): texto=tramitacao.texto, data_fim_prazo=tramitacao.data_fim_prazo, user=tramitacao.user, - ip=tramitacao.ip + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao )) Tramitacao.objects.bulk_create(lista_tramitacao) @@ -620,14 +625,16 @@ class TramitacaoUpdateForm(TramitacaoForm): 'data_fim_prazo', 'texto', 'user', - 'ip' + 'ip', + 'ultima_edicao' ] widgets = { 'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'), 'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'), 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput() + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput() } def clean(self): @@ -658,6 +665,17 @@ class TramitacaoUpdateForm(TramitacaoForm): 'Você não pode mudar a Unidade de Destino desta ' 'tramitação, pois irá conflitar com a Unidade ' 'Local da tramitação seguinte') + + if not (cd['data_tramitacao'] != obj.data_tramitacao or \ + cd['unidade_tramitacao_destino'] != obj.unidade_tramitacao_destino or \ + cd['status'] != obj.status or cd['texto'] != obj.texto or \ + cd['data_encaminhamento'] != obj.data_encaminhamento or \ + cd['data_fim_prazo'] != obj.data_fim_prazo or cd['urgente'] != str(obj.urgente) or \ + cd['turno'] != obj.turno): + ### Se não ocorreram alterações, o usuário, ip, data e hora da última edição (real) são mantidos + cd['user'] = obj.user + cd['ip'] = obj.ip + cd['ultima_edicao'] = obj.ultima_edicao cd['data_tramitacao'] = obj.data_tramitacao cd['unidade_tramitacao_local'] = obj.unidade_tramitacao_local @@ -690,6 +708,7 @@ class TramitacaoUpdateForm(TramitacaoForm): tram_anexada.data_fim_prazo = nova_tram_principal.data_fim_prazo tram_anexada.user = nova_tram_principal.user tram_anexada.ip = nova_tram_principal.ip + tram_anexada.ultima_edicao = nova_tram_principal.ultima_edicao tram_anexada.save() ma.em_tramitacao = False if nova_tram_principal.status.indicador == "F" else True @@ -1614,9 +1633,13 @@ class TramitacaoEmLoteForm(ModelForm): 'data_fim_prazo', 'texto', 'user', - 'ip'] + 'ip', + 'ultima_edicao'] + widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput()} + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput()} + def __init__(self, *args, **kwargs): super(TramitacaoEmLoteForm, self).__init__(*args, **kwargs) @@ -1737,9 +1760,12 @@ class TramitacaoEmLoteForm(ModelForm): @transaction.atomic def save(self, commit=True): cd = self.cleaned_data + materias = self.initial['materias'] user = self.initial['user'] if 'user' in self.initial else None ip = self.initial['ip'] if 'ip' in self.initial else '' + ultima_edicao = self.initial['ultima_edicao'] if 'ultima_edicao' in self.initial else '' + tramitar_anexadas = AppConfig.attr('tramitacao_materia') for mat_id in materias: mat = MateriaLegislativa.objects.get(id=mat_id) @@ -1755,7 +1781,8 @@ class TramitacaoEmLoteForm(ModelForm): texto=cd['texto'], data_fim_prazo=cd['data_fim_prazo'], user=user, - ip=ip + ip=ip, + ultima_edicao=ultima_edicao ) mat.em_tramitacao = False if tramitacao.status.indicador == "F" else True mat.save() @@ -1781,7 +1808,8 @@ class TramitacaoEmLoteForm(ModelForm): texto=tramitacao.texto, data_fim_prazo=tramitacao.data_fim_prazo, user=tramitacao.user, - ip=tramitacao.ip + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao )) Tramitacao.objects.bulk_create(lista_tramitacao) diff --git a/sapl/materia/migrations/0056_auto_20190829_1206.py b/sapl/materia/migrations/0056_auto_20190829_1206.py new file mode 100644 index 000000000..965760412 --- /dev/null +++ b/sapl/materia/migrations/0056_auto_20190829_1206.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-08-29 15:06 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0055_auto_20190816_0943'), + ] + + operations = [ + migrations.AddField( + model_name='materialegislativa', + name='ultima_edicao', + field=models.DateTimeField(blank=True, null=True, verbose_name='Data e Hora da Edição'), + ), + migrations.AddField( + model_name='tramitacao', + name='ultima_edicao', + field=models.DateTimeField(blank=True, null=True, verbose_name='Data e Hora da Edição'), + ), + ] diff --git a/sapl/materia/migrations/0058_merge_20190926_1250.py b/sapl/materia/migrations/0058_merge_20190926_1250.py new file mode 100644 index 000000000..aae54b049 --- /dev/null +++ b/sapl/materia/migrations/0058_merge_20190926_1250.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-09-26 15:50 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0057_materiaemtramitacao'), + ('materia', '0056_auto_20190829_1206'), + ] + + operations = [ + ] diff --git a/sapl/materia/migrations/0061_merge_20191009_1814.py b/sapl/materia/migrations/0061_merge_20191009_1814.py new file mode 100644 index 000000000..96ce48366 --- /dev/null +++ b/sapl/materia/migrations/0061_merge_20191009_1814.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-10-09 21:14 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0060_auto_20190930_1136'), + ('materia', '0058_merge_20190926_1250'), + ] + + operations = [ + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index 97f5926d4..c373d98d6 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -295,6 +295,10 @@ class MateriaLegislativa(models.Model): blank=True, default='' ) + ultima_edicao = models.DateTimeField( + verbose_name=_('Data e Hora da Edição'), + blank=True, null=True + ) class Meta: verbose_name = _('Matéria Legislativa') @@ -1083,6 +1087,10 @@ class Tramitacao(models.Model): max_length=30, blank=True, default='') + ultima_edicao = models.DateTimeField( + verbose_name=_('Data e Hora da Edição'), + blank=True, null=True + ) class Meta: verbose_name = _('Tramitação') diff --git a/sapl/materia/views.py b/sapl/materia/views.py index bf5a36c81..4ae4b4042 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1235,6 +1235,10 @@ class TramitacaoCrud(MasterDetailCrud): initial['data_tramitacao'] = timezone.now().date() initial['ip'] = get_client_ip(self.request) initial['user'] = self.request.user + + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) + return initial def get_context_data(self, **kwargs): @@ -1301,28 +1305,20 @@ class TramitacaoCrud(MasterDetailCrud): layout_key = 'TramitacaoUpdate' - def form_valid(self, form): - dict_objeto_antigo = Tramitacao.objects.get( - pk=self.kwargs['pk']).__dict__ - - self.object = form.save() - dict_objeto_novo = self.object.__dict__ + def get_initial(self): + initial = super(UpdateView, self).get_initial() + + initial['ip'] = get_client_ip(self.request) + initial['user'] = self.request.user - user = self.request.user + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) - atributos = [ - 'data_tramitacao', 'unidade_tramitacao_destino_id', 'status_id', 'texto', - 'data_encaminhamento', 'data_fim_prazo', 'urgente', 'turno' - ] + return initial - # Se não houve qualquer alteração em um dos dados, mantém o usuário - # e ip - for atributo in atributos: - if dict_objeto_antigo[atributo] != dict_objeto_novo[atributo]: - self.object.user = user - self.object.ip = get_client_ip(self.request) - self.object.save() - break + def form_valid(self, form): + self.object = form.save() + user = self.request.user try: self.logger.debug("user=" + user.username + ". Tentando enviar Tramitacao (sender={}, post={}, request={}" @@ -1718,6 +1714,9 @@ class MateriaLegislativaCrud(Crud): initial['user'] = self.request.user initial['ip'] = get_client_ip(self.request) + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) + return initial @property @@ -1749,6 +1748,10 @@ class MateriaLegislativaCrud(Crud): if dict_objeto_antigo[atributo] != dict_objeto_novo[atributo]: self.object.user = self.request.user self.object.ip = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + self.object.ultima_edicao = tz.localize(datetime.now()) + self.object.save() break @@ -2398,6 +2401,9 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): def post(self, request, *args, **kwargs): user = request.user ip = get_client_ip(request) + + tz = timezone.get_current_timezone() + ultima_edicao = tz.localize(datetime.now()) materias_ids = request.POST.getlist('materias') if not materias_ids: @@ -2407,7 +2413,8 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): form = TramitacaoEmLoteForm(request.POST, initial= {'materias': materias_ids, - 'user': user, 'ip':ip}) + 'user': user, 'ip':ip, + 'ultima_edicao': ultima_edicao}) if form.is_valid(): form.save() diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index 3a651749d..2be8315a7 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -135,10 +135,13 @@ class NormaJuridicaForm(FileFieldCheckMixin, ModelForm): 'texto_integral', 'assuntos', 'user', - 'ip'] + 'ip', + 'ultima_edicao'] + widgets = {'assuntos': widgets.CheckboxSelectMultiple, 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput()} + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput()} def clean(self): diff --git a/sapl/norma/migrations/0027_normajuridica_ultima_edicao.py b/sapl/norma/migrations/0027_normajuridica_ultima_edicao.py new file mode 100644 index 000000000..c01ff22a5 --- /dev/null +++ b/sapl/norma/migrations/0027_normajuridica_ultima_edicao.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-08-29 14:41 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0026_auto_20190712_1053'), + ] + + operations = [ + migrations.AddField( + model_name='normajuridica', + name='ultima_edicao', + field=models.DateTimeField(blank=True, null=True, verbose_name='Data e Hora da Edição'), + ), + ] diff --git a/sapl/norma/migrations/0028_merge_20191009_1814.py b/sapl/norma/migrations/0028_merge_20191009_1814.py new file mode 100644 index 000000000..503e70b76 --- /dev/null +++ b/sapl/norma/migrations/0028_merge_20191009_1814.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-10-09 21:14 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0027_normajuridica_ultima_edicao'), + ('norma', '0027_auto_20191001_1115'), + ] + + operations = [ + ] diff --git a/sapl/norma/models.py b/sapl/norma/models.py index 7a7cfc509..62cb33120 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -156,6 +156,10 @@ class NormaJuridica(models.Model): blank=True, default='' ) + ultima_edicao = models.DateTimeField( + verbose_name=_('Data e Hora da Edição'), + blank=True, null=True + ) class Meta: verbose_name = _('Norma Jurídica') diff --git a/sapl/norma/views.py b/sapl/norma/views.py index cbe7005a3..44c2cfeac 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -1,3 +1,4 @@ +from datetime import datetime import logging import re @@ -222,6 +223,9 @@ class NormaCrud(Crud): initial['user'] = self.request.user initial['ip'] = get_client_ip(self.request) + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) + username = self.request.user.username try: self.logger.debug( @@ -286,6 +290,10 @@ class NormaCrud(Crud): if dict_objeto_antigo[atributo] != dict_objeto_novo[atributo]: self.object.user = self.request.user self.object.ip = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + self.object.ultima_edicao = tz.localize(datetime.now()) + self.object.save() break @@ -295,6 +303,10 @@ class NormaCrud(Crud): if assuntos_antigos != assuntos_novos: self.object.user = self.request.user self.object.ip = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + self.object.ultima_edicao = tz.localize(datetime.now()) + self.object.save() return super().form_valid(form) diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index d76c49e09..82bba2372 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -689,9 +689,12 @@ class TramitacaoAdmForm(ModelForm): 'data_fim_prazo', 'texto', 'user', - 'ip'] + 'ip', + 'ultima_edicao'] + widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput()} + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput()} def __init__(self, *args, **kwargs): @@ -806,7 +809,8 @@ class TramitacaoAdmForm(ModelForm): texto=tramitacao.texto, data_fim_prazo=tramitacao.data_fim_prazo, user=tramitacao.user, - ip=tramitacao.ip + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao )) TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao) @@ -820,7 +824,7 @@ def compara_tramitacoes_doc(tramitacao1, tramitacao2): if not tramitacao1 or not tramitacao2: return False - lst_items = ['id', 'documento_id', 'timestamp'] + lst_items = ['id', 'documento_id', 'timestamp', 'ultima_edicao'] values = [(k,v) for k,v in tramitacao1.__dict__.items() if ((k not in lst_items) and (k[0] != '_'))] other_values = [(k,v) for k,v in tramitacao2.__dict__.items() if (k not in lst_items and k[0] != '_')] return values == other_values @@ -847,9 +851,12 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): 'data_fim_prazo', 'texto', 'user', - 'ip'] + 'ip', + 'ultima_edicao'] + widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput()} + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput()} def clean(self): super(TramitacaoAdmEditForm, self).clean() @@ -886,6 +893,7 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): cd['data_fim_prazo'] != obj.data_fim_prazo): cd['user'] = obj.user cd['ip'] = obj.ip + cd['ultima_edicao'] = obj.ultima_edicao cd['data_tramitacao'] = obj.data_tramitacao cd['unidade_tramitacao_local'] = obj.unidade_tramitacao_local @@ -917,6 +925,7 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): tram_anexada.data_fim_prazo = nova_tram_principal.data_fim_prazo tram_anexada.user = nova_tram_principal.user tram_anexada.ip = nova_tram_principal.ip + tram_anexada.ultima_edicao = nova_tram_principal.ultima_edicao tram_anexada.save() da.tramitacao = False if nova_tram_principal.status.indicador == "F" else True @@ -1084,10 +1093,17 @@ class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm): 'observacao', 'texto_integral', 'protocolo', - 'restrito' + 'restrito', + 'user', + 'ip', + 'ultima_edicao' ] - widgets = {'protocolo': forms.HiddenInput()} + widgets = {'protocolo': forms.HiddenInput(), + 'user': forms.HiddenInput(), + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput() + } def clean(self): super(DocumentoAdministrativoForm, self).clean() @@ -1489,9 +1505,12 @@ class TramitacaoEmLoteAdmForm(ModelForm): 'data_fim_prazo', 'texto', 'user', - 'ip'] + 'ip', + 'ultima_edicao'] + widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput()} + 'ip': forms.HiddenInput(), + 'ultima_edicao': forms.HiddenInput()} def __init__(self, *args, **kwargs): @@ -1612,9 +1631,12 @@ class TramitacaoEmLoteAdmForm(ModelForm): @transaction.atomic def save(self, commit=True): cd = self.cleaned_data + documentos = self.initial['documentos'] user = self.initial['user'] if 'user' in self.initial else None ip = self.initial['ip'] if 'ip' in self.initial else '' + ultima_edicao = self.initial['ultima_edicao'] if 'ultima_edicao' in self.initial else '' + tramitar_anexados = AppConfig.attr('tramitacao_documento') for doc_id in documentos: doc = DocumentoAdministrativo.objects.get(id=doc_id) @@ -1629,7 +1651,8 @@ class TramitacaoEmLoteAdmForm(ModelForm): texto=cd['texto'], data_fim_prazo=cd['data_fim_prazo'], user=user, - ip=ip + ip=ip, + ultima_edicao=ultima_edicao ) doc.tramitacao = False if tramitacao.status.indicador == "F" else True doc.save() @@ -1654,7 +1677,8 @@ class TramitacaoEmLoteAdmForm(ModelForm): texto=tramitacao.texto, data_fim_prazo=tramitacao.data_fim_prazo, user=tramitacao.user, - ip=tramitacao.ip + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao )) TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao) diff --git a/sapl/protocoloadm/migrations/0024_tramitacaoadministrativo_ultima_edicao.py b/sapl/protocoloadm/migrations/0024_tramitacaoadministrativo_ultima_edicao.py new file mode 100644 index 000000000..f9df6704c --- /dev/null +++ b/sapl/protocoloadm/migrations/0024_tramitacaoadministrativo_ultima_edicao.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-08-08 21:14 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0023_merge_20190802_1112'), + ] + + operations = [ + migrations.AddField( + model_name='tramitacaoadministrativo', + name='ultima_edicao', + field=models.DateField(blank=True, null=True, verbose_name='Data e Hora da Edição'), + ), + ] diff --git a/sapl/protocoloadm/migrations/0025_auto_20190815_1539.py b/sapl/protocoloadm/migrations/0025_auto_20190815_1539.py new file mode 100644 index 000000000..d635e2c39 --- /dev/null +++ b/sapl/protocoloadm/migrations/0025_auto_20190815_1539.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.23 on 2019-08-15 18:39 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0024_tramitacaoadministrativo_ultima_edicao'), + ] + + operations = [ + migrations.AlterField( + model_name='tramitacaoadministrativo', + name='ultima_edicao', + field=models.DateTimeField(blank=True, null=True, verbose_name='Data e Hora da Edição'), + ), + ] diff --git a/sapl/protocoloadm/migrations/0026_auto_20190815_1737.py b/sapl/protocoloadm/migrations/0026_auto_20190815_1737.py new file mode 100644 index 000000000..ba6d53656 --- /dev/null +++ b/sapl/protocoloadm/migrations/0026_auto_20190815_1737.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.23 on 2019-08-15 20:37 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('protocoloadm', '0025_auto_20190815_1539'), + ] + + operations = [ + migrations.AddField( + model_name='documentoadministrativo', + name='ip', + field=models.CharField(blank=True, default='', max_length=30, verbose_name='IP'), + ), + migrations.AddField( + model_name='documentoadministrativo', + name='ultima_edicao', + field=models.DateTimeField(blank=True, null=True, verbose_name='Data e Hora da Edição'), + ), + migrations.AddField( + model_name='documentoadministrativo', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='Usuário'), + ), + ] diff --git a/sapl/protocoloadm/migrations/0027_merge_20190926_1250.py b/sapl/protocoloadm/migrations/0027_merge_20190926_1250.py new file mode 100644 index 000000000..236f0ce51 --- /dev/null +++ b/sapl/protocoloadm/migrations/0027_merge_20190926_1250.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-09-26 15:50 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0026_auto_20190815_1737'), + ('protocoloadm', '0024_merge_20190821_1418'), + ] + + operations = [ + ] diff --git a/sapl/protocoloadm/migrations/0028_merge_20191009_1814.py b/sapl/protocoloadm/migrations/0028_merge_20191009_1814.py new file mode 100644 index 000000000..497fe180a --- /dev/null +++ b/sapl/protocoloadm/migrations/0028_merge_20191009_1814.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-10-09 21:14 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0027_merge_20190926_1250'), + ('protocoloadm', '0025_auto_20191001_1115'), + ] + + operations = [ + ] diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index 9145dfdcc..b9582a204 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -186,6 +186,24 @@ class DocumentoAdministrativo(models.Model): ) ) + user = models.ForeignKey( + get_settings_auth_user_model(), + verbose_name=_('Usuário'), + on_delete=models.PROTECT, + null=True, + blank=True + ) + ip = models.CharField( + verbose_name=_('IP'), + max_length=30, + blank=True, + default='' + ) + ultima_edicao = models.DateTimeField( + verbose_name=_('Data e Hora da Edição'), + blank=True, null=True + ) + class Meta: verbose_name = _('Documento Administrativo') verbose_name_plural = _('Documentos Administrativos') @@ -340,6 +358,10 @@ class TramitacaoAdministrativo(models.Model): max_length=30, blank=True, default='') + ultima_edicao = models.DateTimeField( + verbose_name=_('Data e Hora da Edição'), + blank=True, null=True + ) class Meta: verbose_name = _('Tramitação de Documento Administrativo') diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index c954413f5..496c3fcaa 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -350,6 +350,17 @@ class DocumentoAdministrativoCrud(Crud): form_class = DocumentoAdministrativoForm layout_key = None + def get_initial(self): + initial = super().get_initial() + + initial['user'] = self.request.user + initial['ip'] = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) + + return initial + @property def cancel_url(self): return self.search_url @@ -358,6 +369,33 @@ class DocumentoAdministrativoCrud(Crud): form_class = DocumentoAdministrativoForm layout_key = None + def form_valid(self, form): + dict_objeto_antigo = DocumentoAdministrativo.objects.get( + pk=self.kwargs['pk'] + ).__dict__ + + self.object = form.save() + dict_objeto_novo = self.object.__dict__ + + atributos = [ + 'tipo_id', 'ano', 'numero', 'data', 'protocolo_id', 'assunto', + 'interessado', 'tramitacao', 'restrito', 'texto_integral','numero_externo', + 'dias_prazo', 'data_fim_prazo', 'observacao' + ] + + for atributo in atributos: + if dict_objeto_antigo[atributo] != dict_objeto_novo[atributo]: + self.object.user = self.request.user + self.object.ip = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + self.object.ultima_edicao = tz.localize(datetime.now()) + + self.object.save() + break + + return super().form_valid(form) + def get_initial(self): if self.object.protocolo: p = self.object.protocolo @@ -372,7 +410,17 @@ class DocumentoAdministrativoCrud(Crud): if documento.restrito and self.request.user.is_anonymous(): return redirect('/') return super(Crud.DetailView, self).get(args, kwargs) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context['user'] = self.request.user + context['documentoadministrativo'] = DocumentoAdministrativo.objects.get( + pk=self.kwargs['pk'] + ) + return context + def urlize(self, obj, fieldname): a = '%s' % ( reverse( @@ -645,6 +693,12 @@ class CriarDocumentoProtocolo(PermissionRequiredMixin, CreateView): doc['assunto'] = protocolo.assunto_ementa doc['interessado'] = protocolo.interessado doc['numero'] = numero_max + 1 if numero_max else 1 + doc['user'] = self.request.user + doc['ip'] = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + doc['ultima_edicao'] = tz.localize(datetime.now()) + return doc @@ -1165,6 +1219,10 @@ class TramitacaoAdmCrud(MasterDetailCrud): initial['data_tramitacao'] = timezone.now().date() initial['ip'] = get_client_ip(self.request) initial['user'] = self.request.user + + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) + return initial def get_context_data(self, **kwargs): @@ -1228,6 +1286,10 @@ class TramitacaoAdmCrud(MasterDetailCrud): initial = super(UpdateView, self).get_initial() initial['ip'] = get_client_ip(self.request) initial['user'] = self.request.user + + tz = timezone.get_current_timezone() + initial['ultima_edicao'] = tz.localize(datetime.now()) + return initial def form_valid(self, form): @@ -1381,6 +1443,13 @@ class DesvincularDocumentoView(PermissionRequiredMixin, CreateView): ano=form.cleaned_data['ano'], tipo=form.cleaned_data['tipo']) documento.protocolo = None + + documento.user = self.request.user + documento.ip = get_client_ip(self.request) + + tz = timezone.get_current_timezone() + documento.ultima_edicao = tz.localize(datetime.now()) + documento.save() return redirect(self.get_success_url()) @@ -1545,15 +1614,19 @@ class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView): user = request.user ip = get_client_ip(request) + tz = timezone.get_current_timezone() + ultima_edicao = tz.localize(datetime.now()) + documentos_ids = request.POST.getlist('documentos') if not documentos_ids: msg = _("Escolha algum Documento para ser tramitado.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - form = TramitacaoEmLoteAdmForm(request.POST, - initial={'documentos': documentos_ids, - 'user': user, 'ip': ip}) + form = TramitacaoEmLoteAdmForm(request.POST, + initial= {'documentos': documentos_ids, + 'user': user, 'ip':ip, + 'ultima_edicao': ultima_edicao}) if form.is_valid(): form.save() diff --git a/sapl/templates/materia/materialegislativa_detail.html b/sapl/templates/materia/materialegislativa_detail.html index 3396653c2..10749b765 100644 --- a/sapl/templates/materia/materialegislativa_detail.html +++ b/sapl/templates/materia/materialegislativa_detail.html @@ -1,5 +1,6 @@ {% extends "crud/detail.html" %} {% load i18n %} + {% block sub_actions %} {{ block.super }} {% if object.em_tramitacao and mail_service_configured %} @@ -8,6 +9,7 @@ {% endif %} {% endblock sub_actions %} + {% block detail_content %} {{ block.super }} {% if object.registrovotacao_set.exists %} @@ -46,13 +48,15 @@ {% if user.is_superuser %}
{% if materia.user %} -
+

Usuário

@@ -60,12 +64,28 @@
{% endif %} {% if materia.ip %} -
+

IP

-
{{materia.ip}}
+
+ {{ materia.ip }} +
+
+
+
+
+ {% endif %} + {% if materia.ultima_edicao %} +
+
+

Data e Hora da Edição

+
+
+
+ {{ materia.ultima_edicao }} +
diff --git a/sapl/templates/materia/tramitacao_detail.html b/sapl/templates/materia/tramitacao_detail.html index 2015ef513..df108ad13 100644 --- a/sapl/templates/materia/tramitacao_detail.html +++ b/sapl/templates/materia/tramitacao_detail.html @@ -6,13 +6,15 @@ {% if user.is_superuser %}
{% if tramitacao.user %} -
+

Usuário

@@ -20,13 +22,27 @@
{% endif %} {% if tramitacao.ip %} -
+

IP

- {{tramitacao.ip}} + {{ tramitacao.ip }} +
+
+
+
+
+ {% endif %} + {% if tramitacao.ultima_edicao %} +
+
+

Data e Hora da Edição

+
+
+
+ {{ tramitacao.ultima_edicao }}
@@ -35,4 +51,4 @@ {% endif %}
{% endif %} -{% endblock detail_content %} \ No newline at end of file +{% endblock detail_content %} diff --git a/sapl/templates/norma/normajuridica_detail.html b/sapl/templates/norma/normajuridica_detail.html index 00467a491..4d2026a4f 100644 --- a/sapl/templates/norma/normajuridica_detail.html +++ b/sapl/templates/norma/normajuridica_detail.html @@ -9,96 +9,93 @@ {% endif %} {% endblock %} - - {% block detail_content %} - {% for fieldset in view.layout_display %} -

{{ fieldset.legend }}

- {% for row in fieldset.rows %} -
- {% for column in row %} -
-
-

{{ column.verbose_name }}

-
- {% comment %}TODO Transformar os links em URLs diretamente no CRUD{% endcomment %} - - {% if column.text|url %} - - {% elif column.verbose_name == 'Matéria' %} - {% if object.materia.id %} - - {% else %} -
{{ column.text|safe|default:"" }}
- {% endif %} - {% else %} -
{{ column.text|safe|default:"" }}
- {% endif %} + {% for fieldset in view.layout_display %} +

{{ fieldset.legend }}

+ {% for row in fieldset.rows %} +
+ {% for column in row %} +
+
+

{{ column.verbose_name }}

+
+ {% comment %}TODO Transformar os links em URLs diretamente no CRUD{% endcomment %} + {% if column.text|url %} + -
+ {% elif column.verbose_name == 'Matéria' %} + {% if object.materia.id %} + + {% else %} +
{{ column.text|safe|default:"" }}
+ {% endif %} + {% else %} +
{{ column.text|safe|default:"" }}
+ {% endif %}
- {% endfor %} +
{% endfor %} - {% endfor %} - -
-
-
-

Normas Relacionadas

- - {% if object.get_normas_relacionadas.0|length > 0 %} - {% for p in object.get_normas_relacionadas.0 %} -
- {{ p.tipo_vinculo.descricao_ativa }}  - - {{ p.norma_relacionada.epigrafe }} - -
- {% endfor %} - {% endif %} - - {% if object.get_normas_relacionadas.1|length > 0 %} - {% for r in object.get_normas_relacionadas.1 %} -
- {{ r.tipo_vinculo.descricao_passiva }}  - - {{ r.norma_principal.epigrafe }} - -
- {% endfor %} - {% endif %} - -
-
-
-
-  

Anexos Norma Jurídica

+ {% endfor %} + {% endfor %} +
+
+
+

Normas Relacionadas

+ {% if object.get_normas_relacionadas.0|length > 0 %} + {% for p in object.get_normas_relacionadas.0 %} +
+ {{ p.tipo_vinculo.descricao_ativa }}  + + {{ p.norma_relacionada.epigrafe }} + +
+ {% endfor %} + {% endif %} + {% if object.get_normas_relacionadas.1|length > 0 %} + {% for r in object.get_normas_relacionadas.1 %} +
+ {{ r.tipo_vinculo.descricao_passiva }}  + + {{ r.norma_principal.epigrafe }} + +
+ {% endfor %} + {% endif %} +
+
+
+
+
+  

Anexos Norma Jurídica

{% if object.get_anexos_norma_juridica|length > 0 %} {% for p in object.get_anexos_norma_juridica %} {% endfor %} {% endif %}
-

- {% if user.is_superuser %}
{% if object.user %} -
+

Usuário

@@ -106,19 +103,35 @@
{% endif %} {% if object.ip %} -
+

IP

-
{{object.ip}}
+
+ {{ object.ip }} +
{% endif %} -
- {% endif %} + {% if object.ultima_edicao %} +
+
+

Data e Hora da Edição

+
+
+
+ {{ object.ultima_edicao }} +
+
+
+
+
+ {% endif %} +
+ {% endif %} {% if object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}
@@ -131,7 +144,6 @@ {% endif %} {% endblock detail_content %} - {% block webpack_loader_js %} {{ block.super }} {% if object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %} @@ -139,7 +151,6 @@ {% endif %} {% endblock %} - {% block extra_js %} {% if object.texto_articulado.exists and object.texto_articulado.first.has_view_permission %}