diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index 40f6b01e4..6ac4a2e22 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -1,12 +1,12 @@ from math import ceil +import rtyaml from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit from django import template from django.utils import formats from django.utils.translation import ugettext as _ -import rtyaml def heads_and_tails(list_of_lists): diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index de0ebf143..89892ba18 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -31,6 +31,31 @@ def em_tramitacao(): (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 Meta: @@ -82,20 +107,33 @@ class ProposicaoForm(ModelForm): cleaned_data = self.cleaned_data if 'tipo' in cleaned_data: if cleaned_data['tipo'].descricao == 'Parecer': - try: - 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) + if self.instance.materia: + cleaned_data['materia'] = self.instance.materia + cleaned_data['autor'] = ( + self.instance.materia.autoria_set.first().autor) else: - cleaned_data['materia'] = materia - cleaned_data['autor'] = materia.autoria_set.first().autor + try: + 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 + 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: model = Proposicao fields = ['tipo', 'data_envio', 'descricao', 'texto_original'] diff --git a/sapl/materia/migrations/0039_auto_20160808_1753.py b/sapl/materia/migrations/0039_auto_20160808_1753.py new file mode 100644 index 000000000..a7473aa59 --- /dev/null +++ b/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, + ), + ] diff --git a/sapl/materia/migrations/0040_auto_20160810_1524.py b/sapl/materia/migrations/0040_auto_20160810_1524.py new file mode 100644 index 000000000..798bd8a64 --- /dev/null +++ b/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'), + ), + ] diff --git a/sapl/materia/migrations/0041_remove_proposicao_data_incorporação.py b/sapl/materia/migrations/0041_remove_proposicao_data_incorporação.py new file mode 100644 index 000000000..126ef1687 --- /dev/null +++ b/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', + ), + ] diff --git a/sapl/materia/migrations/0042_proposicao_data_devolução.py b/sapl/materia/migrations/0042_proposicao_data_devolução.py new file mode 100644 index 000000000..cb17864d6 --- /dev/null +++ b/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'), + ), + ] diff --git a/sapl/materia/migrations/0043_auto_20160810_1738.py b/sapl/materia/migrations/0043_auto_20160810_1738.py new file mode 100644 index 000000000..4012d1162 --- /dev/null +++ b/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', + ), + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index ca433d7a6..2e56d6cad 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -443,14 +443,16 @@ class TipoProposicao(models.Model): class Proposicao(models.Model): autor = models.ForeignKey(Autor, null=True, blank=True) tipo = models.ForeignKey(TipoProposicao, verbose_name=_('Tipo')) + # XXX data_envio was not null, but actual data said otherwise!!! 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( - blank=True, null=True, verbose_name=_('Data de Incorporação')) - descricao = models.TextField(max_length=100, verbose_name=_('Descrição')) + blank=True, null=True, verbose_name=_('Data de Recebimento')) 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( max_length=200, blank=True, @@ -461,17 +463,23 @@ class Proposicao(models.Model): status = models.CharField(blank=True, max_length=1, choices=(('E', 'Enviada'), - ('D', 'Devolvida'), + ('R', 'Recebida'), ('I', 'Incorporada')), verbose_name=_('Status Proposição')) # mutually exclusive (depend on tipo.materia_ou_documento) materia = models.ForeignKey( - MateriaLegislativa, blank=True, null=True, verbose_name=_('Matéria')) - documento = models.ForeignKey( - DocumentoAcessorio, blank=True, null=True, verbose_name=_('Documento')) + MateriaLegislativa, blank=True, null=True, verbose_name=_('Matéria'), + related_name=_('materia_vinculada')) + + # 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( - blank=True, - null=True, upload_to=texto_upload_path, verbose_name=_('Texto Original'), validators=[restringe_tipos_de_arquivo_txt]) diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py index 1386e294a..6e82c51c5 100644 --- a/sapl/materia/tests/test_materia.py +++ b/sapl/materia/tests/test_materia.py @@ -5,10 +5,10 @@ from model_mommy import mommy from sapl.comissoes.models import Comissao, TipoComissao from sapl.materia.models import (Anexada, Autor, Autoria, DespachoInicial, DocumentoAcessorio, MateriaLegislativa, - Numeracao, Proposicao, RegimeTramitacao, - StatusTramitacao, TipoAutor, TipoDocumento, - TipoMateriaLegislativa, TipoProposicao, - Tramitacao, UnidadeTramitacao) + Numeracao, RegimeTramitacao, StatusTramitacao, + TipoAutor, TipoDocumento, + TipoMateriaLegislativa, Tramitacao, + UnidadeTramitacao) from sapl.norma.models import (LegislacaoCitada, NormaJuridica, TipoNormaJuridica) @@ -414,30 +414,3 @@ def test_form_errors_relatoria(client): ['Este campo é obrigatório.']) assert (response.context_data['form'].errors['parlamentar'] == ['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.']) diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index dbc6499fc..b831fbfae 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -3,17 +3,20 @@ from django.conf.urls import include, url from sapl.materia.views import (AcompanhamentoConfirmarView, AcompanhamentoExcluirView, AcompanhamentoMateriaView, AnexadaCrud, - AutorCrud, AutoriaCrud, DespachoInicialCrud, - DocumentoAcessorioCrud, LegislacaoCitadaCrud, - MateriaLegislativaCrud, + AutorCrud, AutoriaCrud, ConfirmarProposicao, + DespachoInicialCrud, DocumentoAcessorioCrud, + LegislacaoCitadaCrud, MateriaLegislativaCrud, MateriaLegislativaPesquisaView, MateriaTaView, NumeracaoCrud, OrgaoCrud, OrigemCrud, - ProposicaoCrud, ProposicaoTaView, - RegimeTramitacaoCrud, RelatoriaCrud, - StatusTramitacaoCrud, TipoAutorCrud, - TipoDocumentoCrud, TipoFimRelatoriaCrud, - TipoMateriaCrud, TipoProposicaoCrud, - TramitacaoCrud, UnidadeTramitacaoCrud) + ProposicaoCrud, ProposicaoDevolvida, + ProposicaoPendente, ProposicaoRecebida, + ProposicaoTaView, ReceberProposicao, + ReciboProposicaoView, RegimeTramitacaoCrud, + RelatoriaCrud, StatusTramitacaoCrud, + TipoAutorCrud, TipoDocumentoCrud, + TipoFimRelatoriaCrud, TipoMateriaCrud, + TipoProposicaoCrud, TramitacaoCrud, + UnidadeTramitacaoCrud) from .apps import AppConfig @@ -31,6 +34,18 @@ urlpatterns = [ DocumentoAcessorioCrud.get_urls())), url(r'^proposicao/', include(ProposicaoCrud.get_urls())), + url(r'^proposicao/recibo/(?P\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\d+)', ConfirmarProposicao.as_view(), + name='proposicao-confirmar'), # Integração com Compilação url(r'^materia/(?P[0-9]+)/ta$', diff --git a/sapl/materia/views.py b/sapl/materia/views.py index b63efc737..7648d1afd 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -11,7 +11,7 @@ from django.core.urlresolvers import reverse from django.http.response import HttpResponseRedirect from django.template import Context, loader 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 sapl.base.models import CasaLegislativa @@ -21,14 +21,15 @@ from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, CrudListView, CrudUpdateView, make_pagination) from sapl.crud.masterdetail import MasterDetailCrud 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, - DespachoInicialForm, DocumentoAcessorioForm, - LegislacaoCitadaForm, MateriaLegislativaFilterSet, - NumeracaoForm, ProposicaoForm, RelatoriaForm, - TramitacaoForm, UnidadeTramitacaoForm, - filtra_tramitacao_destino, + ConfirmarProposicaoForm, DespachoInicialForm, + DocumentoAcessorioForm, LegislacaoCitadaForm, + MateriaLegislativaFilterSet, NumeracaoForm, ProposicaoForm, + ReceberProposicaoForm, RelatoriaForm, TramitacaoForm, + UnidadeTramitacaoForm, filtra_tramitacao_destino, filtra_tramitacao_destino_and_status, filtra_tramitacao_status) from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria, @@ -52,6 +53,43 @@ TipoProposicaoCrud = Crud.build(TipoProposicao, 'tipo_proposicao') 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): model = UnidadeTramitacao help_path = 'unidade_tramitacao' @@ -63,12 +101,149 @@ class UnidadeTramitacaoCrud(Crud): 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): model = Proposicao help_path = '' class BaseMixin(CrudBaseMixin): - list_field_names = ['data_envio', 'descricao', 'tipo'] + list_field_names = ['data_envio', 'descricao', + 'tipo', 'data_recebimento'] class CreateView(CrudCreateView): form_class = ProposicaoForm @@ -80,18 +255,36 @@ class ProposicaoCrud(Crud): class UpdateView(CrudUpdateView): 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 def layout_key(self): return 'ProposicaoCreate' class ListView(CrudListView): - ordering = ['-data_envio', 'descricao'] + ordering = ['-data_envio', '-descricao'] def get_rows(self, object_list): for obj in object_list: if obj.data_envio is None: 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] @@ -112,6 +305,20 @@ class ProposicaoCrud(Crud): 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): model = Relatoria parent_field = 'materia' diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index 90d684a36..d791ab501 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -439,35 +439,6 @@ class ProtocoloMateriaForm(ModelForm): *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 Meta: diff --git a/sapl/protocoloadm/urls.py b/sapl/protocoloadm/urls.py index 5f6feb538..6108b7847 100644 --- a/sapl/protocoloadm/urls.py +++ b/sapl/protocoloadm/urls.py @@ -9,11 +9,6 @@ from sapl.protocoloadm.views import (AnularProtocoloAdmView, DocumentoAcessorioAdministrativoView, DocumentoAdministrativoCrud, PesquisarDocumentoAdministrativoView, - ProposicaoDetailView, - ProposicaoReceberView, ProposicaoView, - ProposicoesIncorporadasView, - ProposicoesNaoIncorporadasView, - ProposicoesNaoRecebidasView, ProtocoloDocumentoCrud, ProtocoloDocumentoView, ProtocoloListView, ProtocoloMateriaCrud, @@ -27,8 +22,7 @@ from sapl.protocoloadm.views import (AnularProtocoloAdmView, TramitacaoAdmEditView, TramitacaoAdmIncluirView, TramitacaoAdministrativoCrud, - TramitacaoAdmView, get_nome_autor, - pesquisa_autores) + TramitacaoAdmView) from .apps import AppConfig @@ -86,26 +80,4 @@ urlpatterns = [ ComprovanteProtocoloView.as_view(), name='comprovante_protocolo'), url(r'^protocoloadm/(?P\d+)/(?P\d+)/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\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') ] diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index 3eba8b729..9d86f0dde 100644 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -13,14 +13,14 @@ from django.views.generic.base import TemplateView from django_filters.views import FilterView 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 .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, - DocumentoAdministrativoForm, ProposicaoSimpleForm, - ProtocoloDocumentForm, ProtocoloFilterSet, - ProtocoloMateriaForm, TramitacaoAdmForm) + DocumentoAdministrativoForm, ProtocoloDocumentForm, + ProtocoloFilterSet, ProtocoloMateriaForm, + TramitacaoAdmForm) from .models import (Autor, DocumentoAcessorioAdministrativo, DocumentoAdministrativo, Protocolo, StatusTramitacaoAdministrativo, @@ -306,68 +306,6 @@ class ProtocoloMateriaView(CreateView): 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): model = DocumentoAdministrativo filterset_class = DocumentoAdministrativoFilterSet diff --git a/sapl/templates/base.html b/sapl/templates/base.html index 93dcc665f..5e0eabfe9 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -57,6 +57,7 @@