Browse Source

Fixes #3356

pull/3358/head
eribeiro 5 years ago
parent
commit
c0d3c9a1a9
  1. 29
      sapl/materia/forms.py
  2. 34
      sapl/materia/migrations/0078_historicoproposicao.py
  3. 45
      sapl/materia/models.py
  4. 4
      sapl/materia/urls.py
  5. 47
      sapl/materia/views.py
  6. 44
      sapl/templates/materia/historico_proposicao.html
  7. 12
      sapl/templates/materia/proposicao_list.html
  8. 2
      sapl/templates/materia/subnav_prop.yaml

29
sapl/materia/forms.py

@ -29,7 +29,7 @@ from sapl.materia.models import (AssuntoMateria, MateriaAssunto,
MateriaLegislativa, Orgao, MateriaLegislativa, Orgao,
RegimeTramitacao, StatusTramitacao, RegimeTramitacao, StatusTramitacao,
TipoDocumento, TipoProposicao, TipoDocumento, TipoProposicao,
ConfigEtiquetaMateriaLegislativa) ConfigEtiquetaMateriaLegislativa, HistoricoProposicao)
from sapl.norma.models import (LegislacaoCitada, NormaJuridica, from sapl.norma.models import (LegislacaoCitada, NormaJuridica,
TipoNormaJuridica) TipoNormaJuridica)
from sapl.parlamentares.models import Legislatura, Partido from sapl.parlamentares.models import Legislatura, Partido
@ -2084,7 +2084,13 @@ class DevolverProposicaoForm(forms.ModelForm):
fields = [ fields = [
'justificativa_devolucao', 'justificativa_devolucao',
'observacao', 'observacao',
'user',
'ip'
] ]
widgets = {
'user': forms.HiddenInput(),
'ip': forms.HiddenInput(),
}
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -2139,6 +2145,13 @@ class DevolverProposicaoForm(forms.ModelForm):
ta.editing_locked = False ta.editing_locked = False
ta.save() ta.save()
observacao = self.instance.justificativa_devolucao
HistoricoProposicao.objects.create(proposicao=self.instance,
status='D',
user=self.initial['user'],
ip=self.initial['ip'],
observacao=observacao)
self.instance.results = { self.instance.results = {
'messages': { 'messages': {
'success': [_('Devolução efetuada com sucesso.'), ] 'success': [_('Devolução efetuada com sucesso.'), ]
@ -2181,13 +2194,17 @@ class ConfirmarProposicaoForm(ProposicaoForm):
'observacao', 'observacao',
'gerar_protocolo', 'gerar_protocolo',
'numero_de_paginas', 'numero_de_paginas',
'numero_materia_futuro' 'numero_materia_futuro',
'user',
'ip'
] ]
widgets = { widgets = {
'descricao': widgets.Textarea( 'descricao': widgets.Textarea(
attrs={'readonly': 'readonly', 'rows': 4}), attrs={'readonly': 'readonly', 'rows': 4}),
'data_envio': widgets.DateTimeInput( 'data_envio': widgets.DateTimeInput(
attrs={'readonly': 'readonly'}), attrs={'readonly': 'readonly'}),
'user': forms.HiddenInput(),
'ip': forms.HiddenInput(),
} }
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -2395,6 +2412,12 @@ class ConfirmarProposicaoForm(ProposicaoForm):
proposicao = self.instance proposicao = self.instance
conteudo_gerado = None conteudo_gerado = None
HistoricoProposicao.objects.create(proposicao=proposicao,
status='R',
user=self.initial['user'],
ip=self.initial['ip'],
)
if self.instance.tipo.content_type.model_class( if self.instance.tipo.content_type.model_class(
) == TipoMateriaLegislativa: ) == TipoMateriaLegislativa:
@ -2591,6 +2614,8 @@ class ConfirmarProposicaoForm(ProposicaoForm):
protocolo.tipo_processo = '0' protocolo.tipo_processo = '0'
protocolo.save() protocolo.save()
HistoricoProposicao.objects.create(proposicao=proposicao,
status='E')
self.instance.results['messages']['success'].append(_( self.instance.results['messages']['success'].append(_(
'Protocolo realizado com sucesso')) 'Protocolo realizado com sucesso'))

34
sapl/materia/migrations/0078_historicoproposicao.py

@ -0,0 +1,34 @@
# Generated by Django 2.2.13 on 2021-03-02 17:17
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('materia', '0077_auto_20210209_1047'),
]
operations = [
migrations.CreateModel(
name='HistoricoProposicao',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('E', 'Enviada'), ('R', 'Recebida'), ('T', 'Retornada'), ('D', 'Devolvida')], db_index=True, max_length=1, verbose_name='Status de Proposição')),
('data_hora', models.DateTimeField(blank=True, db_index=True, default=django.utils.timezone.now, null=True, verbose_name='Data/Hora')),
('observacao', models.CharField(blank=True, max_length=200, verbose_name='Observação')),
('ip', models.CharField(blank=True, default='', max_length=60, verbose_name='IP')),
('proposicao', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='materia.Proposicao', verbose_name='Proposição')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL, verbose_name='Usuário')),
],
options={
'verbose_name': 'Histórico de Proposição',
'verbose_name_plural': 'Histórico de Proposições',
'ordering': ('-data_hora', '-proposicao'),
},
),
]

45
sapl/materia/models.py

@ -1025,6 +1025,51 @@ class Proposicao(models.Model):
update_fields=update_fields) update_fields=update_fields)
class HistoricoProposicao(models.Model):
STATUS_PROPOSICAO = Choices(('E', 'ENVIADA', _('Enviada')),
('R', 'RECEBIDA', _('Recebida')),
('T', 'RETORNADA', _('Retornada')),
('D', 'DEVOLVIDA', _('Devolvida')))
proposicao = models.ForeignKey(Proposicao,
verbose_name=_('Proposição'),
db_index=True,
on_delete=models.CASCADE)
status = models.CharField(max_length=1,
verbose_name=_('Status de Proposição'),
db_index=True,
choices=STATUS_PROPOSICAO)
data_hora = models.DateTimeField(null=True,
blank=True,
default=timezone.now,
db_index=True,
verbose_name=_('Data/Hora'))
observacao = models.CharField(max_length=200,
blank=True,
verbose_name=_('Observação'))
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=60,
blank=True,
default='')
@property
def status_descricao(self):
return self.STATUS_PROPOSICAO[self.status]
class Meta:
verbose_name = _('Histórico de Proposição')
verbose_name_plural = _('Histórico de Proposições')
ordering = ('-data_hora', '-proposicao')
def __str__(self):
return f'{self.data_hora} - {self.STATUS_PROPOSICAO[self.status]} - {str(self.proposicao)}'
@reversion.register() @reversion.register()
class StatusTramitacao(models.Model): class StatusTramitacao(models.Model):
INDICADOR_CHOICES = Choices(('F', 'fim', _('Fim')), INDICADOR_CHOICES = Choices(('F', 'fim', _('Fim')),

4
sapl/materia/urls.py

@ -31,7 +31,7 @@ from sapl.materia.views import (AcompanhamentoConfirmarView,
DespachoInicialMultiCreateView, DespachoInicialMultiCreateView,
get_zip_docacessorios, get_pdf_docacessorios, get_zip_docacessorios, get_pdf_docacessorios,
configEtiquetaMateriaLegislativaCrud, configEtiquetaMateriaLegislativaCrud,
PesquisarStatusTramitacaoView) PesquisarStatusTramitacaoView, HistoricoProposicaoView)
from sapl.norma.views import NormaPesquisaSimplesView from sapl.norma.views import NormaPesquisaSimplesView
from sapl.protocoloadm.views import ( from sapl.protocoloadm.views import (
FichaPesquisaAdmView, FichaSelecionaAdmView FichaPesquisaAdmView, FichaSelecionaAdmView
@ -156,6 +156,8 @@ urlpatterns_proposicao = [
name='proposicao_texto'), name='proposicao_texto'),
url(r'^proposicao/(?P<pk>\d+)/retornar', RetornarProposicao.as_view(), url(r'^proposicao/(?P<pk>\d+)/retornar', RetornarProposicao.as_view(),
name='retornar-proposicao'), name='retornar-proposicao'),
url(r'^proposicao/historico', HistoricoProposicaoView.as_view(),
name='historico-proposicao'),
] ]

47
sapl/materia/views.py

@ -75,7 +75,7 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, De
DocumentoAcessorio, MateriaAssunto, MateriaLegislativa, Numeracao, Orgao, DocumentoAcessorio, MateriaAssunto, MateriaLegislativa, Numeracao, Orgao,
Origem, Proposicao, RegimeTramitacao, Relatoria, StatusTramitacao, Origem, Proposicao, RegimeTramitacao, Relatoria, StatusTramitacao,
TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao, TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao,
Tramitacao, UnidadeTramitacao, ConfigEtiquetaMateriaLegislativa) Tramitacao, UnidadeTramitacao, ConfigEtiquetaMateriaLegislativa, HistoricoProposicao)
AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, 'assunto_materia') AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, 'assunto_materia')
@ -680,6 +680,12 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView):
form_class = ConfirmarProposicaoForm, DevolverProposicaoForm form_class = ConfirmarProposicaoForm, DevolverProposicaoForm
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_initial(self):
initial = super().get_initial()
initial['ip'] = get_client_ip(self.request)
initial['user'] = self.request.user
return initial
def get_success_url(self): def get_success_url(self):
msgs = self.object.results['messages'] msgs = self.object.results['messages']
@ -897,6 +903,11 @@ class ProposicaoCrud(Crud):
p.data_devolucao = None p.data_devolucao = None
p.data_envio = timezone.now() p.data_envio = timezone.now()
p.save() p.save()
HistoricoProposicao.objects.create(
proposicao=p,
status='E',
ip=get_client_ip(self.request),
user=self.request.user)
messages.success(request, _( messages.success(request, _(
'Proposição enviada com sucesso.')) 'Proposição enviada com sucesso.'))
@ -939,6 +950,12 @@ class ProposicaoCrud(Crud):
else: else:
p.data_envio = None p.data_envio = None
p.save() p.save()
HistoricoProposicao.objects.create(
proposicao=p,
status='T',
ip=get_client_ip(self.request),
user=self.request.user)
if p.texto_articulado.exists(): if p.texto_articulado.exists():
ta = p.texto_articulado.first() ta = p.texto_articulado.first()
ta.privacidade = STATUS_TA_PRIVATE ta.privacidade = STATUS_TA_PRIVATE
@ -1216,6 +1233,34 @@ class ReciboProposicaoView(TemplateView):
kwargs={'pk': proposicao.pk})) kwargs={'pk': proposicao.pk}))
class HistoricoProposicaoView(PermissionRequiredMixin, ListView):
logger = logging.getLogger(__name__)
template_name = "materia/historico_proposicao.html"
ordering = ['-data_hora']
paginate_by = 10
model = HistoricoProposicao
permission_required = ('materia.detail_proposicao', )
def get_queryset(self):
qs = super().get_queryset()
user = self.request.user
if not user.is_superuser:
autores = Autor.objects.filter(user=user)
qs = qs.filter(proposicao__autor__in=autores)
return qs
def get_context_data(self, **kwargs):
context = super(HistoricoProposicaoView, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['NO_ENTRIES_MSG'] = 'Nenhuma proposição'
if self.request.user.is_superuser:
context['subnav_template_name'] = 'materia/subnav_prop.yaml'
return context
class RelatoriaCrud(MasterDetailCrud): class RelatoriaCrud(MasterDetailCrud):
model = Relatoria model = Relatoria
parent_field = 'materia' parent_field = 'materia'

44
sapl/templates/materia/historico_proposicao.html

@ -0,0 +1,44 @@
{% extends "base.html" %}
{% load i18n %}
{% load tz %}
{% block base_content %}
<fieldset>
<legend>Histórico de Proposições</legend>
{% if not object_list %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Data/Hora</th>
<th>Status</th>
<th>Operador</th>
<th>Proposição</th>
<th>Descrição</th>
<th>Autor</th>
<th>Observação</th>
</tr>
</thead>
<tbody>
{% for hist in object_list %}
<tr>
<td>{{ hist.data_hora|localtime|date:"d/m/Y H:i:s" }}</td>
<td>{{ hist.status_descricao}}</td>
<td>{{ hist.user }}</td>
<td>
<a href="{% url 'sapl.materia:proposicao_detail' hist.proposicao.pk %}">
{{ hist.proposicao.numero_proposicao }}/{{ hist.proposicao.ano }}
</a>
</td>
<td>{{ hist.proposicao.descricao }}</td>
<td>{{ hist.proposicao.autor }}</td>
<td>{{ hist.observacao }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</fieldset>
{% include 'paginacao.html'%}
{% endblock %}

12
sapl/templates/materia/proposicao_list.html

@ -0,0 +1,12 @@
{% extends "crud/list.html" %}
{% load i18n %}
{% block base_content %}
{% block sub_actions %}
<div class="actions btn-group btn-group-sm" role="group">
<a href="{% url 'sapl.materia:historico-proposicao' %}" class="btn btn-outline-primary">
{% blocktrans with verbose_name=view.verbose_name %} Histórico de {{ verbose_name }} {% endblocktrans %}
</a>
</div>
{% endblock sub_actions %}
{{ block.super }}
{% endblock %}

2
sapl/templates/materia/subnav_prop.yaml

@ -7,3 +7,5 @@
url: proposicao-devolvida url: proposicao-devolvida
- title: {% trans 'Proposições Incorporadas' %} - title: {% trans 'Proposições Incorporadas' %}
url: proposicao-recebida url: proposicao-recebida
- title: {% trans 'Histórico Proposições' %}
url: historico-proposicao
Loading…
Cancel
Save