Browse Source

Merge pull request #527 from interlegis/524-Proposição

Fix #524 proposição
pull/516/head
Edward 9 years ago
committed by GitHub
parent
commit
5d3cb556a9
  1. 2
      sapl/crispy_layout_mixin.py
  2. 58
      sapl/materia/forms.py
  3. 42
      sapl/materia/migrations/0039_auto_20160808_1753.py
  4. 35
      sapl/materia/migrations/0040_auto_20160810_1524.py
  5. 19
      sapl/materia/migrations/0041_remove_proposicao_data_incorporação.py
  6. 20
      sapl/materia/migrations/0042_proposicao_data_devolução.py
  7. 20
      sapl/materia/migrations/0043_auto_20160810_1738.py
  8. 28
      sapl/materia/models.py
  9. 35
      sapl/materia/tests/test_materia.py
  10. 33
      sapl/materia/urls.py
  11. 225
      sapl/materia/views.py
  12. 29
      sapl/protocoloadm/forms.py
  13. 30
      sapl/protocoloadm/urls.py
  14. 70
      sapl/protocoloadm/views.py
  15. 1
      sapl/templates/base.html
  16. 8
      sapl/templates/crud/confirm_delete.html
  17. 2
      sapl/templates/crud/detail.html
  18. 2
      sapl/templates/crud/form.html
  19. 32
      sapl/templates/materia/confirmar_proposicao.html
  20. 43
      sapl/templates/materia/prop_devolvidas_list.html
  21. 35
      sapl/templates/materia/prop_pendentes_list.html
  22. 43
      sapl/templates/materia/prop_recebidas_list.html
  23. 10
      sapl/templates/materia/proposicao_confirm_delete.html
  24. 12
      sapl/templates/materia/proposicao_detail.html
  25. 8
      sapl/templates/materia/proposicao_form.html
  26. 9
      sapl/templates/materia/receber_proposicao.html
  27. 70
      sapl/templates/materia/recibo_proposicao.html
  28. 6
      sapl/templates/materia/subnav_prop.html
  29. 12
      sapl/utils.py

2
sapl/crispy_layout_mixin.py

@ -1,12 +1,12 @@
from math import ceil from math import ceil
import rtyaml
from crispy_forms.bootstrap import FormActions from crispy_forms.bootstrap import FormActions
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit
from django import template from django import template
from django.utils import formats from django.utils import formats
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
import rtyaml
def heads_and_tails(list_of_lists): def heads_and_tails(list_of_lists):

58
sapl/materia/forms.py

@ -31,6 +31,31 @@ def em_tramitacao():
(False, 'Não')] (False, 'Não')]
class ConfirmarProposicaoForm(ModelForm):
class Meta:
model = Proposicao
exclude = ['texto_original', 'descricao', 'tipo']
class ReceberProposicaoForm(ModelForm):
cod_hash = forms.CharField(label='Código do Documento', required=True)
class Meta:
model = Proposicao
exclude = ['texto_original', 'descricao', 'tipo']
def __init__(self, *args, **kwargs):
row1 = to_row([('cod_hash', 12)])
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset(
_('Incorporar Proposição'), row1,
form_actions(save_label='Buscar Proposição')
)
)
super(ReceberProposicaoForm, self).__init__(*args, **kwargs)
class UnidadeTramitacaoForm(ModelForm): class UnidadeTramitacaoForm(ModelForm):
class Meta: class Meta:
@ -82,20 +107,33 @@ class ProposicaoForm(ModelForm):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
if 'tipo' in cleaned_data: if 'tipo' in cleaned_data:
if cleaned_data['tipo'].descricao == 'Parecer': if cleaned_data['tipo'].descricao == 'Parecer':
try: if self.instance.materia:
materia = MateriaLegislativa.objects.get( cleaned_data['materia'] = self.instance.materia
tipo_id=cleaned_data['tipo_materia'], cleaned_data['autor'] = (
ano=cleaned_data['ano_materia'], self.instance.materia.autoria_set.first().autor)
numero=cleaned_data['numero_materia'])
except ObjectDoesNotExist:
msg = _('Matéria adicionada não existe!')
raise ValidationError(msg)
else: else:
cleaned_data['materia'] = materia try:
cleaned_data['autor'] = materia.autoria_set.first().autor materia = MateriaLegislativa.objects.get(
tipo_id=cleaned_data['tipo_materia'],
ano=cleaned_data['ano_materia'],
numero=cleaned_data['numero_materia'])
except ObjectDoesNotExist:
msg = _('Matéria adicionada não existe!')
raise ValidationError(msg)
else:
cleaned_data['materia'] = materia
cleaned_data['autor'] = materia.autoria_set.first(
).autor
return cleaned_data return cleaned_data
def save(self, commit=False):
proposicao = super(ProposicaoForm, self).save(commit)
if 'materia' in self.cleaned_data:
proposicao.materia = self.cleaned_data['materia']
proposicao.save()
return proposicao
class Meta: class Meta:
model = Proposicao model = Proposicao
fields = ['tipo', 'data_envio', 'descricao', 'texto_original'] fields = ['tipo', 'data_envio', 'descricao', 'texto_original']

42
sapl/materia/migrations/0039_auto_20160808_1753.py

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-08-08 20:53
from __future__ import unicode_literals
from django.db import migrations, models
import sapl.materia.models
import sapl.utils
class Migration(migrations.Migration):
dependencies = [
('materia', '0038_auto_20160612_1506'),
]
operations = [
migrations.RemoveField(
model_name='proposicao',
name='data_devolucao',
),
migrations.AddField(
model_name='proposicao',
name='data_incorporação',
field=models.DateTimeField(blank=True, null=True, verbose_name='Data de Incorporação'),
),
migrations.AlterField(
model_name='proposicao',
name='data_recebimento',
field=models.DateTimeField(blank=True, null=True, verbose_name='Data de Recebimento'),
),
migrations.AlterField(
model_name='proposicao',
name='status',
field=models.CharField(blank=True, choices=[('E', 'Enviada'), ('R', 'Recebida'), ('I', 'Incorporada')], max_length=1, verbose_name='Status Proposição'),
),
migrations.AlterField(
model_name='proposicao',
name='texto_original',
field=models.FileField(default='', upload_to=sapl.materia.models.texto_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Original'),
preserve_default=False,
),
]

35
sapl/materia/migrations/0040_auto_20160810_1524.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-08-10 18:24
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('materia', '0039_auto_20160808_1753'),
]
operations = [
migrations.RemoveField(
model_name='proposicao',
name='documento',
),
migrations.AddField(
model_name='proposicao',
name='documento_gerado',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='materia.DocumentoAcessorio'),
),
migrations.AddField(
model_name='proposicao',
name='materia_gerada',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='materia_gerada', to='materia.MateriaLegislativa'),
),
migrations.AlterField(
model_name='proposicao',
name='materia',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='materia_vinculada', to='materia.MateriaLegislativa', verbose_name='Matéria'),
),
]

19
sapl/materia/migrations/0041_remove_proposicao_data_incorporação.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-08-10 20:02
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('materia', '0040_auto_20160810_1524'),
]
operations = [
migrations.RemoveField(
model_name='proposicao',
name='data_incorporação',
),
]

20
sapl/materia/migrations/0042_proposicao_data_devolução.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-08-10 20:37
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('materia', '0041_remove_proposicao_data_incorporação'),
]
operations = [
migrations.AddField(
model_name='proposicao',
name='data_devolução',
field=models.DateTimeField(blank=True, null=True, verbose_name='Data de Devolução'),
),
]

20
sapl/materia/migrations/0043_auto_20160810_1738.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-08-10 20:38
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('materia', '0042_proposicao_data_devolução'),
]
operations = [
migrations.RenameField(
model_name='proposicao',
old_name='data_devolução',
new_name='data_devolucao',
),
]

28
sapl/materia/models.py

@ -443,14 +443,16 @@ class TipoProposicao(models.Model):
class Proposicao(models.Model): class Proposicao(models.Model):
autor = models.ForeignKey(Autor, null=True, blank=True) autor = models.ForeignKey(Autor, null=True, blank=True)
tipo = models.ForeignKey(TipoProposicao, verbose_name=_('Tipo')) tipo = models.ForeignKey(TipoProposicao, verbose_name=_('Tipo'))
# XXX data_envio was not null, but actual data said otherwise!!! # XXX data_envio was not null, but actual data said otherwise!!!
data_envio = models.DateTimeField( data_envio = models.DateTimeField(
null=True, blank=True, verbose_name=_('Data de Envio')) blank=True, null=True, verbose_name=_('Data de Envio'))
data_recebimento = models.DateTimeField( data_recebimento = models.DateTimeField(
blank=True, null=True, verbose_name=_('Data de Incorporação')) blank=True, null=True, verbose_name=_('Data de Recebimento'))
descricao = models.TextField(max_length=100, verbose_name=_('Descrição'))
data_devolucao = models.DateTimeField( data_devolucao = models.DateTimeField(
blank=True, null=True, verbose_name=_('Data de devolução')) blank=True, null=True, verbose_name=_('Data de Devolução'))
descricao = models.TextField(max_length=100, verbose_name=_('Descrição'))
justificativa_devolucao = models.CharField( justificativa_devolucao = models.CharField(
max_length=200, max_length=200,
blank=True, blank=True,
@ -461,17 +463,23 @@ class Proposicao(models.Model):
status = models.CharField(blank=True, status = models.CharField(blank=True,
max_length=1, max_length=1,
choices=(('E', 'Enviada'), choices=(('E', 'Enviada'),
('D', 'Devolvida'), ('R', 'Recebida'),
('I', 'Incorporada')), ('I', 'Incorporada')),
verbose_name=_('Status Proposição')) verbose_name=_('Status Proposição'))
# mutually exclusive (depend on tipo.materia_ou_documento) # mutually exclusive (depend on tipo.materia_ou_documento)
materia = models.ForeignKey( materia = models.ForeignKey(
MateriaLegislativa, blank=True, null=True, verbose_name=_('Matéria')) MateriaLegislativa, blank=True, null=True, verbose_name=_('Matéria'),
documento = models.ForeignKey( related_name=_('materia_vinculada'))
DocumentoAcessorio, blank=True, null=True, verbose_name=_('Documento'))
# Ao ser recebida, irá gerar uma nova matéria ou um documento acessorio
# de uma já existente
materia_gerada = models.ForeignKey(
MateriaLegislativa, blank=True, null=True,
related_name=_('materia_gerada'))
documento_gerado = models.ForeignKey(
DocumentoAcessorio, blank=True, null=True)
texto_original = models.FileField( texto_original = models.FileField(
blank=True,
null=True,
upload_to=texto_upload_path, upload_to=texto_upload_path,
verbose_name=_('Texto Original'), verbose_name=_('Texto Original'),
validators=[restringe_tipos_de_arquivo_txt]) validators=[restringe_tipos_de_arquivo_txt])

35
sapl/materia/tests/test_materia.py

@ -5,10 +5,10 @@ from model_mommy import mommy
from sapl.comissoes.models import Comissao, TipoComissao from sapl.comissoes.models import Comissao, TipoComissao
from sapl.materia.models import (Anexada, Autor, Autoria, DespachoInicial, from sapl.materia.models import (Anexada, Autor, Autoria, DespachoInicial,
DocumentoAcessorio, MateriaLegislativa, DocumentoAcessorio, MateriaLegislativa,
Numeracao, Proposicao, RegimeTramitacao, Numeracao, RegimeTramitacao, StatusTramitacao,
StatusTramitacao, TipoAutor, TipoDocumento, TipoAutor, TipoDocumento,
TipoMateriaLegislativa, TipoProposicao, TipoMateriaLegislativa, Tramitacao,
Tramitacao, UnidadeTramitacao) UnidadeTramitacao)
from sapl.norma.models import (LegislacaoCitada, NormaJuridica, from sapl.norma.models import (LegislacaoCitada, NormaJuridica,
TipoNormaJuridica) TipoNormaJuridica)
@ -414,30 +414,3 @@ def test_form_errors_relatoria(client):
['Este campo é obrigatório.']) ['Este campo é obrigatório.'])
assert (response.context_data['form'].errors['parlamentar'] == assert (response.context_data['form'].errors['parlamentar'] ==
['Este campo é obrigatório.']) ['Este campo é obrigatório.'])
@pytest.mark.django_db(transaction=False)
def test_proposicao_submit(client):
response = client.post(reverse('sapl.materia:proposicao_create'),
{'tipo': mommy.make(TipoProposicao, pk=3).pk,
'descricao': 'Teste proposição',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
proposicao = Proposicao.objects.first()
assert proposicao.descricao == 'Teste proposição'
assert proposicao.tipo.pk == 3
@pytest.mark.django_db(transaction=False)
def test_form_errors_proposicao(client):
response = client.post(reverse('sapl.materia:proposicao_create'),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])
assert (response.context_data['form'].errors['descricao'] ==
['Este campo é obrigatório.'])

33
sapl/materia/urls.py

@ -3,17 +3,20 @@ from django.conf.urls import include, url
from sapl.materia.views import (AcompanhamentoConfirmarView, from sapl.materia.views import (AcompanhamentoConfirmarView,
AcompanhamentoExcluirView, AcompanhamentoExcluirView,
AcompanhamentoMateriaView, AnexadaCrud, AcompanhamentoMateriaView, AnexadaCrud,
AutorCrud, AutoriaCrud, DespachoInicialCrud, AutorCrud, AutoriaCrud, ConfirmarProposicao,
DocumentoAcessorioCrud, LegislacaoCitadaCrud, DespachoInicialCrud, DocumentoAcessorioCrud,
MateriaLegislativaCrud, LegislacaoCitadaCrud, MateriaLegislativaCrud,
MateriaLegislativaPesquisaView, MateriaTaView, MateriaLegislativaPesquisaView, MateriaTaView,
NumeracaoCrud, OrgaoCrud, OrigemCrud, NumeracaoCrud, OrgaoCrud, OrigemCrud,
ProposicaoCrud, ProposicaoTaView, ProposicaoCrud, ProposicaoDevolvida,
RegimeTramitacaoCrud, RelatoriaCrud, ProposicaoPendente, ProposicaoRecebida,
StatusTramitacaoCrud, TipoAutorCrud, ProposicaoTaView, ReceberProposicao,
TipoDocumentoCrud, TipoFimRelatoriaCrud, ReciboProposicaoView, RegimeTramitacaoCrud,
TipoMateriaCrud, TipoProposicaoCrud, RelatoriaCrud, StatusTramitacaoCrud,
TramitacaoCrud, UnidadeTramitacaoCrud) TipoAutorCrud, TipoDocumentoCrud,
TipoFimRelatoriaCrud, TipoMateriaCrud,
TipoProposicaoCrud, TramitacaoCrud,
UnidadeTramitacaoCrud)
from .apps import AppConfig from .apps import AppConfig
@ -31,6 +34,18 @@ urlpatterns = [
DocumentoAcessorioCrud.get_urls())), DocumentoAcessorioCrud.get_urls())),
url(r'^proposicao/', include(ProposicaoCrud.get_urls())), url(r'^proposicao/', include(ProposicaoCrud.get_urls())),
url(r'^proposicao/recibo/(?P<pk>\d+)', ReciboProposicaoView.as_view(),
name='recibo-proposicao'),
url(r'^proposicao/receber/', ReceberProposicao.as_view(),
name='receber-proposicao'),
url(r'^proposicao/pendente/', ProposicaoPendente.as_view(),
name='proposicao-pendente'),
url(r'^proposicao/recebida/', ProposicaoRecebida.as_view(),
name='proposicao-recebida'),
url(r'^proposicao/devolvida/', ProposicaoDevolvida.as_view(),
name='proposicao-devolvida'),
url(r'^proposicao/confirmar/(?P<pk>\d+)', ConfirmarProposicao.as_view(),
name='proposicao-confirmar'),
# Integração com Compilação # Integração com Compilação
url(r'^materia/(?P<pk>[0-9]+)/ta$', url(r'^materia/(?P<pk>[0-9]+)/ta$',

225
sapl/materia/views.py

@ -11,7 +11,7 @@ from django.core.urlresolvers import reverse
from django.http.response import HttpResponseRedirect from django.http.response import HttpResponseRedirect
from django.template import Context, loader from django.template import Context, loader
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import CreateView, TemplateView, UpdateView from django.views.generic import CreateView, ListView, TemplateView, UpdateView
from django_filters.views import FilterView from django_filters.views import FilterView
from sapl.base.models import CasaLegislativa from sapl.base.models import CasaLegislativa
@ -21,14 +21,15 @@ from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudListView,
CrudUpdateView, make_pagination) CrudUpdateView, make_pagination)
from sapl.crud.masterdetail import MasterDetailCrud from sapl.crud.masterdetail import MasterDetailCrud
from sapl.norma.models import LegislacaoCitada from sapl.norma.models import LegislacaoCitada
from sapl.utils import autor_label, autor_modal, get_base_url from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo,
get_base_url)
from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutoriaForm, from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutoriaForm,
DespachoInicialForm, DocumentoAcessorioForm, ConfirmarProposicaoForm, DespachoInicialForm,
LegislacaoCitadaForm, MateriaLegislativaFilterSet, DocumentoAcessorioForm, LegislacaoCitadaForm,
NumeracaoForm, ProposicaoForm, RelatoriaForm, MateriaLegislativaFilterSet, NumeracaoForm, ProposicaoForm,
TramitacaoForm, UnidadeTramitacaoForm, ReceberProposicaoForm, RelatoriaForm, TramitacaoForm,
filtra_tramitacao_destino, UnidadeTramitacaoForm, filtra_tramitacao_destino,
filtra_tramitacao_destino_and_status, filtra_tramitacao_destino_and_status,
filtra_tramitacao_status) filtra_tramitacao_status)
from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria, from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria,
@ -52,6 +53,43 @@ TipoProposicaoCrud = Crud.build(TipoProposicao, 'tipo_proposicao')
StatusTramitacaoCrud = Crud.build(StatusTramitacao, 'status_tramitacao') StatusTramitacaoCrud = Crud.build(StatusTramitacao, 'status_tramitacao')
def criar_materia_proposicao(proposicao):
tipo_materia = TipoMateriaLegislativa.objects.get(
descricao=proposicao.tipo.descricao)
numero = MateriaLegislativa.objects.filter(
ano=datetime.now().year).order_by('numero').last().numero + 1
regime = RegimeTramitacao.objects.get(descricao='Normal')
return MateriaLegislativa.objects.create(
tipo=tipo_materia,
ano=datetime.now().year,
numero=numero,
data_apresentacao=datetime.now(),
regime_tramitacao=regime,
em_tramitacao=True,
ementa=proposicao.descricao,
texto_original=proposicao.texto_original
)
def criar_doc_proposicao(proposicao):
tipo_doc = TipoDocumento.objects.get(
descricao=proposicao.tipo.descricao)
if proposicao.autor is None:
autor = 'Desconhecido'
else:
autor = proposicao.autor
return DocumentoAcessorio.objects.create(
materia=proposicao.materia,
tipo=tipo_doc,
arquivo=proposicao.texto_original,
nome=proposicao.descricao,
data=proposicao.data_envio,
autor=autor
)
class UnidadeTramitacaoCrud(Crud): class UnidadeTramitacaoCrud(Crud):
model = UnidadeTramitacao model = UnidadeTramitacao
help_path = 'unidade_tramitacao' help_path = 'unidade_tramitacao'
@ -63,12 +101,149 @@ class UnidadeTramitacaoCrud(Crud):
form_class = UnidadeTramitacaoForm form_class = UnidadeTramitacaoForm
class ProposicaoDevolvida(ListView):
template_name = 'materia/prop_devolvidas_list.html'
model = Proposicao
ordering = ['data_envio']
paginate_by = 10
def get_queryset(self):
return Proposicao.objects.filter(
data_envio__isnull=False,
data_recebimento__isnull=True,
data_devolucao__isnull=False)
def get_context_data(self, **kwargs):
context = super(ProposicaoDevolvida, 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 devolvida.'
return context
class ProposicaoPendente(ListView):
template_name = 'materia/prop_pendentes_list.html'
model = Proposicao
ordering = ['data_envio', 'autor', 'tipo', 'descricao']
paginate_by = 10
def get_queryset(self):
return Proposicao.objects.filter(
data_envio__isnull=False,
data_recebimento__isnull=True,
data_devolucao__isnull=True)
def get_context_data(self, **kwargs):
context = super(ProposicaoPendente, 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 pendente.'
return context
class ProposicaoRecebida(ListView):
template_name = 'materia/prop_recebidas_list.html'
model = Proposicao
ordering = ['data_envio']
paginate_by = 10
def get_queryset(self):
return Proposicao.objects.filter(
data_envio__isnull=False,
data_recebimento__isnull=False,
data_devolucao__isnull=True)
def get_context_data(self, **kwargs):
context = super(ProposicaoRecebida, 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 recebida.'
return context
class ReceberProposicao(CreateView):
template_name = "materia/receber_proposicao.html"
form_class = ReceberProposicaoForm
def get_context_data(self, **kwargs):
context = super(ReceberProposicao, self).get_context_data(**kwargs)
context.update({'form': self.get_form()})
return context
def post(self, request, *args, **kwargs):
form = ReceberProposicaoForm(request.POST)
if form.is_valid():
proposicoes = Proposicao.objects.filter(data_envio__isnull=False)
for proposicao in proposicoes:
hasher = gerar_hash_arquivo(proposicao.texto_original.path,
str(proposicao.pk))
if hasher == form.cleaned_data['cod_hash']:
return HttpResponseRedirect(
reverse('sapl.materia:proposicao-confirmar',
kwargs={'pk': proposicao.pk}))
msg = 'Proposição não encontrada!'
return self.render_to_response({'form': form, 'msg': msg})
else:
return self.render_to_response({'form': form})
def get_success_url(self):
return reverse('sapl.materia:receber-proposicao')
class ConfirmarProposicao(CreateView):
template_name = "materia/confirmar_proposicao.html"
form_class = ConfirmarProposicaoForm
def get_context_data(self, **kwargs):
context = super(ConfirmarProposicao, self).get_context_data(**kwargs)
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'])
context.update({'form': self.get_form(), 'proposicao': proposicao})
return context
def post(self, request, *args, **kwargs):
form = ConfirmarProposicaoForm(request.POST)
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'])
if form.is_valid():
if 'incorporar' in request.POST:
proposicao.data_recebimento = datetime.now()
if proposicao.tipo.descricao == 'Parecer':
documento = criar_doc_proposicao(proposicao)
proposicao.documento_gerado = documento
proposicao.save()
return HttpResponseRedirect(
reverse('sapl.materia:documentoacessorio_update',
kwargs={'pk': documento.pk}))
else:
materia = criar_materia_proposicao(proposicao)
proposicao.materia_gerada = materia
proposicao.save()
return HttpResponseRedirect(
reverse('sapl.materia:materialegislativa_update',
kwargs={'pk': materia.pk}))
else:
proposicao.data_devolucao = datetime.now()
proposicao.save()
return HttpResponseRedirect(
reverse('sapl.materia:proposicao-devolvida'))
class ProposicaoCrud(Crud): class ProposicaoCrud(Crud):
model = Proposicao model = Proposicao
help_path = '' help_path = ''
class BaseMixin(CrudBaseMixin): class BaseMixin(CrudBaseMixin):
list_field_names = ['data_envio', 'descricao', 'tipo'] list_field_names = ['data_envio', 'descricao',
'tipo', 'data_recebimento']
class CreateView(CrudCreateView): class CreateView(CrudCreateView):
form_class = ProposicaoForm form_class = ProposicaoForm
@ -80,18 +255,36 @@ class ProposicaoCrud(Crud):
class UpdateView(CrudUpdateView): class UpdateView(CrudUpdateView):
form_class = ProposicaoForm form_class = ProposicaoForm
def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs)
if self.object.materia:
context['form'].fields['tipo_materia'].initial = (
self.object.materia.tipo.id)
context['form'].fields['numero_materia'].initial = (
self.object.materia.numero)
context['form'].fields['ano_materia'].initial = (
self.object.materia.ano)
return context
@property @property
def layout_key(self): def layout_key(self):
return 'ProposicaoCreate' return 'ProposicaoCreate'
class ListView(CrudListView): class ListView(CrudListView):
ordering = ['-data_envio', 'descricao'] ordering = ['-data_envio', '-descricao']
def get_rows(self, object_list): def get_rows(self, object_list):
for obj in object_list: for obj in object_list:
if obj.data_envio is None: if obj.data_envio is None:
obj.data_envio = 'Em elaboração...' obj.data_envio = 'Em elaboração...'
else:
obj.data_envio = obj.data_envio.strftime("%d/%m/%Y %H:%M")
if obj.data_recebimento is None:
obj.data_recebimento = 'Não recebida'
else:
obj.data_recebimento = obj.data_recebimento.strftime(
"%d/%m/%Y %H:%M")
return [self._as_row(obj) for obj in object_list] return [self._as_row(obj) for obj in object_list]
@ -112,6 +305,20 @@ class ProposicaoCrud(Crud):
kwargs={'pk': proposicao.pk})) kwargs={'pk': proposicao.pk}))
class ReciboProposicaoView(TemplateView):
template_name = "materia/recibo_proposicao.html"
def get_context_data(self, **kwargs):
context = super(ReciboProposicaoView, self).get_context_data(
**kwargs)
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'])
context.update({'proposicao': proposicao,
'hash': gerar_hash_arquivo(
proposicao.texto_original.path,
self.kwargs['pk'])})
return context
class RelatoriaCrud(MasterDetailCrud): class RelatoriaCrud(MasterDetailCrud):
model = Relatoria model = Relatoria
parent_field = 'materia' parent_field = 'materia'

29
sapl/protocoloadm/forms.py

@ -439,35 +439,6 @@ class ProtocoloMateriaForm(ModelForm):
*args, **kwargs) *args, **kwargs)
class ProposicaoSimpleForm(forms.Form):
tipo = forms.CharField(label='Tipo',
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
materia = forms.CharField(label='Matéria',
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
data_envio = forms.DateField(label=_('Data Envio'),
widget=forms.DateInput(
format='%d/%m/%Y',
attrs={'readonly': 'readonly'}))
data_recebimento = forms.DateField(label=_('Data Recebimento'),
widget=forms.DateInput(
format='%d/%m/%Y',
attrs={'readonly': 'readonly'}))
descricao = forms.CharField(label='Descrição',
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
numero_proposicao = forms.CharField(label='Número',
widget=forms.TextInput(
attrs={'readonly': 'readonly'}))
# ano = forms.CharField(label='Ano',
# widget = forms.TextInput(
# attrs={'readonly':'readonly'}))
class DocumentoAcessorioAdministrativoForm(ModelForm): class DocumentoAcessorioAdministrativoForm(ModelForm):
class Meta: class Meta:

30
sapl/protocoloadm/urls.py

@ -9,11 +9,6 @@ from sapl.protocoloadm.views import (AnularProtocoloAdmView,
DocumentoAcessorioAdministrativoView, DocumentoAcessorioAdministrativoView,
DocumentoAdministrativoCrud, DocumentoAdministrativoCrud,
PesquisarDocumentoAdministrativoView, PesquisarDocumentoAdministrativoView,
ProposicaoDetailView,
ProposicaoReceberView, ProposicaoView,
ProposicoesIncorporadasView,
ProposicoesNaoIncorporadasView,
ProposicoesNaoRecebidasView,
ProtocoloDocumentoCrud, ProtocoloDocumentoCrud,
ProtocoloDocumentoView, ProtocoloListView, ProtocoloDocumentoView, ProtocoloListView,
ProtocoloMateriaCrud, ProtocoloMateriaCrud,
@ -27,8 +22,7 @@ from sapl.protocoloadm.views import (AnularProtocoloAdmView,
TramitacaoAdmEditView, TramitacaoAdmEditView,
TramitacaoAdmIncluirView, TramitacaoAdmIncluirView,
TramitacaoAdministrativoCrud, TramitacaoAdministrativoCrud,
TramitacaoAdmView, get_nome_autor, TramitacaoAdmView)
pesquisa_autores)
from .apps import AppConfig from .apps import AppConfig
@ -86,26 +80,4 @@ urlpatterns = [
ComprovanteProtocoloView.as_view(), name='comprovante_protocolo'), ComprovanteProtocoloView.as_view(), name='comprovante_protocolo'),
url(r'^protocoloadm/(?P<pk>\d+)/(?P<ano>\d+)/criar_documento$', url(r'^protocoloadm/(?P<pk>\d+)/(?P<ano>\d+)/criar_documento$',
CriarDocumentoProtocolo.as_view(), name='criar_documento'), CriarDocumentoProtocolo.as_view(), name='criar_documento'),
# TODO: move to Proposicoes app
url(r'^proposicao$',
ProposicaoView.as_view(), name='proposicao'),
url(r'^proposicao/proposicao-receber',
ProposicaoReceberView.as_view(), name='proposicao_receber'),
url(r'^proposicao/proposicao-naorecebidas',
ProposicoesNaoRecebidasView.as_view(),
name='proposicao_naorecebidas'),
url(r'^proposicao/proposicao-naoincorporadas',
ProposicoesNaoIncorporadasView.as_view(),
name='proposicao_naoincorporadas'),
url(r'^proposicao/proposicao-incorporadas',
ProposicoesIncorporadasView.as_view(),
name='proposicao_incorporadas'),
url(r'^proposicao/(?P<pk>\d+)/proposicao',
ProposicaoDetailView.as_view(), name='proposicao_view'),
url(r'^proposicao/pesquisar_autor',
pesquisa_autores, name='pesquisar_autor'),
url(r'^proposicao/get_nome_autor',
get_nome_autor, name='get_nome_autor')
] ]

70
sapl/protocoloadm/views.py

@ -13,14 +13,14 @@ from django.views.generic.base import TemplateView
from django_filters.views import FilterView from django_filters.views import FilterView
from sapl.crud.base import Crud, CrudBaseMixin, CrudListView, make_pagination from sapl.crud.base import Crud, CrudBaseMixin, CrudListView, make_pagination
from sapl.materia.models import Proposicao, TipoMateriaLegislativa from sapl.materia.models import TipoMateriaLegislativa
from sapl.utils import create_barcode, get_client_ip from sapl.utils import create_barcode, get_client_ip
from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm,
DocumentoAdministrativoFilterSet, DocumentoAdministrativoFilterSet,
DocumentoAdministrativoForm, ProposicaoSimpleForm, DocumentoAdministrativoForm, ProtocoloDocumentForm,
ProtocoloDocumentForm, ProtocoloFilterSet, ProtocoloFilterSet, ProtocoloMateriaForm,
ProtocoloMateriaForm, TramitacaoAdmForm) TramitacaoAdmForm)
from .models import (Autor, DocumentoAcessorioAdministrativo, from .models import (Autor, DocumentoAcessorioAdministrativo,
DocumentoAdministrativo, Protocolo, DocumentoAdministrativo, Protocolo,
StatusTramitacaoAdministrativo, StatusTramitacaoAdministrativo,
@ -306,68 +306,6 @@ class ProtocoloMateriaView(CreateView):
return redirect(self.get_success_url()) return redirect(self.get_success_url())
# TODO: move to Proposicao app
class ProposicaoReceberView(TemplateView):
template_name = "protocoloadm/proposicao_receber.html"
class ProposicoesNaoRecebidasView(ListView):
template_name = "protocoloadm/proposicao_naorecebidas.html"
model = Proposicao
paginate_by = 10
def get_queryset(self):
return Proposicao.objects.filter(data_envio__isnull=False, status='E')
class ProposicoesNaoIncorporadasView(ListView):
template_name = "protocoloadm/proposicao_naoincorporadas.html"
model = Proposicao
paginate_by = 10
def get_queryset(self):
return Proposicao.objects.filter(data_envio__isnull=False,
data_devolucao__isnull=False,
status='D')
class ProposicoesIncorporadasView(ListView):
template_name = "protocoloadm/proposicao_incorporadas.html"
model = Proposicao
paginate_by = 10
def get_queryset(self):
return Proposicao.objects.filter(data_envio__isnull=False,
data_recebimento__isnull=False,
status='I')
class ProposicaoView(TemplateView):
template_name = "protocoloadm/proposicoes.html"
class ProposicaoDetailView(DetailView):
template_name = "protocoloadm/proposicao_view.html"
model = Proposicao
def get(self, request, *args, **kwargs):
proposicao = Proposicao.objects.get(id=kwargs['pk'])
data = { # 'ano': proposicao.ano, # TODO: FIX
'tipo': proposicao.tipo.descricao, # TODO: FIX
'materia': proposicao.materia,
'numero_proposicao': proposicao.numero_proposicao,
'data_envio': proposicao.data_envio,
'data_recebimento': proposicao.data_recebimento,
'descricao': proposicao.descricao}
form = ProposicaoSimpleForm(initial=data)
return self.render_to_response({'form': form})
def get_context_data(self, **kwargs):
context = super(ProposicaoView, self).get_context_data(**kwargs)
context['form'] = ProposicaoSimpleForm
return context
class PesquisarDocumentoAdministrativoView(FilterView): class PesquisarDocumentoAdministrativoView(FilterView):
model = DocumentoAdministrativo model = DocumentoAdministrativo
filterset_class = DocumentoAdministrativoFilterSet filterset_class = DocumentoAdministrativoFilterSet

1
sapl/templates/base.html

@ -57,6 +57,7 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:protocolo' %}">Pesquisar Protocolo</a></li> <li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:protocolo' %}">Pesquisar Protocolo</a></li>
<li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:pesq_doc_adm' %}">Pesquisar Documento Administrativo</a></li> <li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:pesq_doc_adm' %}">Pesquisar Documento Administrativo</a></li>
<li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.materia:receber-proposicao' %}">Receber Proposições</a></li>
<!-- <li class="nav__sub-item"><a class="nav__sub-link" href="/materia">Protocolo Legislativo</a></li> --> <!-- <li class="nav__sub-item"><a class="nav__sub-link" href="/materia">Protocolo Legislativo</a></li> -->
{# <li class="nav__sub-item"><a class="nav__sub-link" href="">Protocolo Geral</a></li> #} {# <li class="nav__sub-item"><a class="nav__sub-link" href="">Protocolo Geral</a></li> #}
{# <li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:proposicao' %}">Proposições</a></li> #} {# <li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:proposicao' %}">Proposições</a></li> #}

8
sapl/templates/crud/confirm_delete.html

@ -5,9 +5,11 @@
<form action="" method="post">{% csrf_token %} <form action="" method="post">{% csrf_token %}
<div class="panel panel-danger"> <div class="panel panel-danger">
<div class="panel-heading text-center"> <div class="panel-heading text-center">
{% blocktrans %} {% block msg %}
Confirma exclusão de "{{ object }}"? {% blocktrans %}
{% endblocktrans %} Confirma exclusão de "{{ object }}"?
{% endblocktrans %}
{% endblock msg %}
</div> </div>
<div class="panel-body text-center"> <div class="panel-body text-center">
<a href="{{ view.cancel_url }}" class="btn btn-inverse">{% trans 'Cancelar' %}</a> <a href="{{ view.cancel_url }}" class="btn btn-inverse">{% trans 'Cancelar' %}</a>

2
sapl/templates/crud/detail.html

@ -11,7 +11,7 @@
</div> </div>
{% endblock actions %} {% endblock actions %}
</div> </div>
{% block extra_msg %}{% endblock extra_msg %}
{% block detail_content %} {% block detail_content %}
{% for fieldset in view.layout_display %} {% for fieldset in view.layout_display %}
<h2 class="legend">{{ fieldset.legend }}</h2> <h2 class="legend">{{ fieldset.legend }}</h2>

2
sapl/templates/crud/form.html

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n crispy_forms_tags %} {% load i18n crispy_forms_tags %}
{% block base_content %} {% block base_content %}
{% block extra_msg %}{% endblock %}
{% crispy form %} {% crispy form %}
{% endblock %} {% endblock %}

32
sapl/templates/materia/confirmar_proposicao.html

@ -0,0 +1,32 @@
{% extends "base.html" %}
{% load i18n crispy_forms_tags %}
{% block base_content %}
<style>
table {
border-collapse: collapse;
}
table, th, td {
border: 2px solid black;
}
</style>
<fieldset>
<legend>Confirmar recebimento de Proposição</legend>
<table class="table table-striped">
<tr><td><b>Tipo: </b>{{proposicao.tipo}}</td></tr>
<tr><td><b>Autor: </b>{{proposicao.autor}}</td></tr>
<tr><td><b>Descrição: </b>{{proposicao.descricao}}</td></tr>
<tr><td><b>Data de Envio: </b>{{proposicao.data_envio|date:'d/m/Y H:i:s'}}</td></tr>
</table>
<form method="POST">
{% csrf_token %}
<div align="center">
<input type="submit" value="Devolver ao autor" name="devolver" class="btn btn-danger">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type="submit" value="Incorporar" name="incorporar" class="btn btn-primary">
</div>
</form>
</fieldset>
{% endblock %}

43
sapl/templates/materia/prop_devolvidas_list.html

@ -0,0 +1,43 @@
{% extends "base.html" %}
{% load i18n %}
{% block sections_nav %} {% include 'materia/subnav_prop.html'%} {% endblock sections_nav %}
{% block base_content %}
<fieldset>
<legend>Proposições Não Incorporadas</legend>
{% if not object_list %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Data do Devolução</th>
<th>Tipo</th>
<th>Descrição</th>
<th>Autor</th>
<th>Vínculo</th>
</tr>
</thead>
<tbody>
{% for prop in object_list %}
<tr>
<td><a href="{% url 'sapl.materia:proposicao_detail' prop.pk %}">{{ prop.data_devolucao|date:"d/m/Y H:i:s" }}</a></td>
<td>{{ prop.tipo.descricao }}</td>
<td>{{ prop.descricao }}</td>
<td>{{ prop.autor }}</td>
<td>
{% if prop.materia_gerada %}
<a href="{% url 'sapl.materia:materialegislativa_detail' prop.materia_gerada.pk %}">{{ prop.materia_gerada.tipo.sigla }} {{ prop.materia_gerada.numero }}/{{ prop.materia_gerada.ano }}</a>
{% elif prop.documento_gerado %}
<a href="{% url 'sapl.materia:documentoacessorio_detail' prop.documento_gerado.pk %}">{{ prop.documento_gerado.materia.tipo.sigla }} {{ prop.documento_gerado.materia.numero }}/{{ prop.documento_gerado.materia.ano }}</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</fieldset>
{% include 'paginacao.html'%}
{% endblock %}

35
sapl/templates/materia/prop_pendentes_list.html

@ -0,0 +1,35 @@
{% extends "base.html" %}
{% load i18n %}
{% block sections_nav %} {% include 'materia/subnav_prop.html'%} {% endblock sections_nav %}
{% block base_content %}
<fieldset>
<legend>Proposições Não Recebidas</legend>
{% if not object_list %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Data de Envio</th>
<th>Tipo</th>
<th>Descrição</th>
<th>Autor</th>
</tr>
</thead>
<tbody>
{% for prop in object_list %}
<tr>
<td><a href="{% url 'sapl.materia:proposicao_detail' prop.pk %}">{{ prop.data_envio|date:"d/m/Y H:i:s" }}</a></td>
<td>{{ prop.tipo.descricao }}</td>
<td>{{ prop.descricao }}</td>
<td>{{ prop.autor }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</fieldset>
{% include 'paginacao.html'%}
{% endblock %}

43
sapl/templates/materia/prop_recebidas_list.html

@ -0,0 +1,43 @@
{% extends "base.html" %}
{% load i18n %}
{% block sections_nav %} {% include 'materia/subnav_prop.html'%} {% endblock sections_nav %}
{% block base_content %}
<fieldset>
<legend>Proposições Incorporadas</legend>
{% if not object_list %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Data do Recebimento</th>
<th>Tipo</th>
<th>Descrição</th>
<th>Autor</th>
<th>Vínculo</th>
</tr>
</thead>
<tbody>
{% for prop in object_list %}
<tr>
<td><a href="{% url 'sapl.materia:proposicao_detail' prop.pk %}">{{ prop.data_recebimento|date:"d/m/Y H:i:s" }}</a></td>
<td>{{ prop.tipo.descricao }}</td>
<td>{{ prop.descricao }}</td>
<td>{{ prop.autor }}</td>
<td>
{% if prop.materia_gerada %}
<a href="{% url 'sapl.materia:materialegislativa_detail' prop.materia_gerada.pk %}">{{ prop.materia_gerada.tipo.sigla }} {{ prop.materia_gerada.numero }}/{{ prop.materia_gerada.ano }}</a>
{% elif prop.documento_gerado %}
<a href="{% url 'sapl.materia:documentoacessorio_detail' prop.documento_gerado.pk %}">{{ prop.documento_gerado.materia.tipo.sigla }} {{ prop.documento_gerado.materia.numero }}/{{ prop.documento_gerado.materia.ano }}</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</fieldset>
{% include 'paginacao.html'%}
{% endblock %}

10
sapl/templates/materia/proposicao_confirm_delete.html

@ -0,0 +1,10 @@
{% extends "crud/confirm_delete.html" %}
{% load i18n %}
{% block msg %}
{% if proposicao.data_envio %}
Confirma o retorno de "{{ object }}"?
{% else %}
Confirma exclusão de "{{ object }}"?
{% endif %}
{% endblock msg %}

12
sapl/templates/materia/proposicao_detail.html

@ -3,12 +3,16 @@
{% block actions %} {% block actions %}
<div class="actions btn-group pull-right" role="group"> <div class="actions btn-group pull-right" role="group">
{% if proposicao.data_envio %} {% if proposicao.data_envio and not proposicao.data_recebimento %}
<a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Editar Proposição' %}</a>
<a href="{{ view.delete_url }}" class="btn btn-default">{% trans 'Retornar Proposição Enviada' %}</a> <a href="{{ view.delete_url }}" class="btn btn-default">{% trans 'Retornar Proposição Enviada' %}</a>
{% else %} {% elif not proposicao.data_envio %}
<a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Enviar/Editar Proposição' %}</a> <a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Enviar Proposição' %}</a>
<a href="{{ view.delete_url }}" class="btn btn-default">{% trans 'Excluir Proposição' %}</a> <a href="{{ view.delete_url }}" class="btn btn-default">{% trans 'Excluir Proposição' %}</a>
{% endif %} {% endif %}
</div> </div>
{% endblock actions %} {% endblock actions %}
{% block extra_msg %}
{% if proposicao.data_envio and not proposicao.data_recebimento %}
<b><p align="center"><a href="" onclick="window.open('{% url 'sapl.materia:recibo-proposicao' object.pk %}','Recibo','width=1100, height=600, scrollbars=yes')">[Imprimir Recibo]</a></p></b>
{% endif %}
{% endblock extra_msg %}

8
sapl/templates/materia/proposicao_form.html

@ -7,18 +7,12 @@
$(document).ready(function(){ $(document).ready(function(){
if($("#id_data_envio").val() != ''){ if($("#id_data_envio").val() != ''){
$("#submit-id-excluir").val('Retornar proposição enviada'); $("#submit-id-excluir").val('Retornar proposição enviada');
$("#submit-id-salvar").val('Salvar proposição');
}else{ }else{
$("#submit-id-excluir").val('Excluir proposição'); $("#submit-id-excluir").val('Excluir proposição');
$("#submit-id-salvar").val('Enviar proposição');
} }
}); });
function disable_fields() { function disable_fields() {
$("#id_tipo_materia").val("");
$("#id_numero_materia").val("");
$("#id_ano_materia").val("");
$("#id_tipo_materia").attr("disabled", "disabled"); $("#id_tipo_materia").attr("disabled", "disabled");
$("#id_numero_materia").attr("disabled", "disabled"); $("#id_numero_materia").attr("disabled", "disabled");
$("#id_ano_materia").attr("disabled", "disabled"); $("#id_ano_materia").attr("disabled", "disabled");
@ -34,7 +28,7 @@
$(function () { $(function () {
disable_fields(); disable_fields();
$("#id_tipo").change(function() { $("#id_tipo").change(function() {
if ($("#id_tipo").val() == 9) { // parecer if ($('#id_tipo option:selected').text() == 'Parecer') { // parecer
enable_fields(); enable_fields();
}else { }else {
disable_fields(); disable_fields();

9
sapl/templates/materia/receber_proposicao.html

@ -0,0 +1,9 @@
{% extends "crud/form.html" %}
{% load i18n %}
{% block sections_nav %} {% include 'materia/subnav_prop.html'%} {% endblock sections_nav %}
{% load crispy_forms_tags %}
{% block extra_msg %}
<p align="center"><font size="4" color="red"><b>{{msg}}</b></font></p>
{% endblock %}

70
sapl/templates/materia/recibo_proposicao.html

@ -0,0 +1,70 @@
{% load i18n %}
{% load crispy_forms_tags %}
{% load static %}
{% block detail_content %}
<style>
table {
width: 100%;
}
th, td {
padding: 5px;
}
</style>
<div align="center">
<input type="submit" value="Imprimir" onclick="window.print();" class="btn btn-success"/>
</div>
<br />
<table>
<tr>
<td>
<img height="100" width="100"
src="{% if logotipo %}{{ MEDIA_URL }}{{ logotipo }}{% else %}{% static 'img/logo.png' %}{% endif %}"
alt="Logotipo"
class="img-responsive visible-lg-inline-block vcenter">
<div>
</td>
<td>
{% if nome %}
<b>{{ nome }} {% trans 'de' %} {{ municipio }} - {{ uf }}</b>
{% else %}
<b>{% trans 'Sem Nome Cadastrado' %}</b>
{% endif %}
<br />
{% trans 'Sistema de Apoio ao Processo Legislativo' %}
</td>
</tr>
<tr> <td colspan="2" align="center"><b>RECIBO DE ENVIO DE PROPOSIÇÃO</b></td> </tr>
</table>
<br /><br />
<table frame="box">
<tr>
<td>Código do Documento: <b>{{hash}}</b></td>
<td>Tipo de Proposição: <b>{{proposicao.tipo.descricao}}</b></td>
</tr>
<tr>
<td>Autor: <b>{{proposicao.autor}}</b></td>
<td>Data de Envio: <b>{{proposicao.data_envio|date:"d/m/Y H:i:s"}}</b></td>
</tr>
<tr>
<td>Descrição: <b>{{proposicao.descricao}}</b></td>
</tr>
</table>
<br /><br />
<table>
<tr>
<td align="center">
Declaro que o conteúdo do texto impresso em anexo é idêntico ao conteúdo enviado eletronicamente por meio do sistema SAPL para esta proposição.
</td>
</tr>
<tr> <td align="center"><br /><br /><br /><b>________________________________________________________________</b></td> </tr>
<tr> <td align="center">{{proposicao.autor}}</td> </tr>
</table>
{% endblock detail_content %}

6
sapl/templates/materia/subnav_prop.html

@ -0,0 +1,6 @@
<ul class="nav nav-pills navbar-right">
<li class=""><a href="{% url 'sapl.materia:receber-proposicao' %}">Receber Proposição</a></li>
<li class=""><a href="{% url 'sapl.materia:proposicao-pendente' %}">Proposições Não Recebidas</a></li>
<li class=""><a href="{% url 'sapl.materia:proposicao-devolvida' %}">Proposições Não Incorporadas</a></li>
<li class=""><a href="{% url 'sapl.materia:proposicao-recebida' %}">Proposições Incorporadas</a></li>
</ul>

12
sapl/utils.py

@ -1,3 +1,4 @@
import hashlib
from datetime import date from datetime import date
from functools import wraps from functools import wraps
@ -218,3 +219,14 @@ def intervalos_tem_intersecao(a_inicio, a_fim, b_inicio, b_fim):
maior_inicio = max(a_inicio, b_inicio) maior_inicio = max(a_inicio, b_inicio)
menor_fim = min(a_fim, b_fim) menor_fim = min(a_fim, b_fim)
return maior_inicio <= menor_fim return maior_inicio <= menor_fim
def gerar_hash_arquivo(arquivo, pk, block_size=2**20):
md5 = hashlib.md5()
arq = open(arquivo, 'rb')
while True:
data = arq.read(block_size)
if not data:
break
md5.update(data)
return 'P' + md5.hexdigest() + '/' + pk

Loading…
Cancel
Save