diff --git a/materia/forms.py b/materia/forms.py index 186c6ba09..9604ad6ca 100644 --- a/materia/forms.py +++ b/materia/forms.py @@ -1,6 +1,8 @@ +from datetime import datetime + import django_filters from crispy_forms.helper import FormHelper -from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout, Submit +from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import models @@ -52,43 +54,33 @@ class ProposicaoForm(ModelForm): raise ValidationError("Arquivo muito grande. ( > 5mb )") return texto_original - class Meta: - model = Proposicao - fields = ['tipo', 'data_envio', 'descricao', 'texto_original'] + def clean_data_envio(self): + data_envio = self.cleaned_data.get('data_envio') + if (not data_envio) and bool(self.initial): + data_envio = datetime.now() + return data_envio - def __init__(self, excluir=False, *args, **kwargs): - more = [] - if excluir: - more = [Submit('Excluir', 'Excluir')] + def clean(self): + 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) + else: + cleaned_data['materia'] = materia + cleaned_data['autor'] = materia.autoria_set.first().autor - row1 = crispy_layout_mixin.to_row( - [('tipo', 8), ('data_envio', 4)]) - row2 = crispy_layout_mixin.to_row( - [('descricao', 12)]) - row3 = crispy_layout_mixin.to_row( - [('tipo_materia', 4), ('numero_materia', 4), ('ano_materia', 4)]) - row4 = crispy_layout_mixin.to_row( - [('texto_original', 12)]) + return cleaned_data - self.helper = FormHelper() - self.helper.layout = Layout( - Fieldset(_('Incluir Proposição'), - row1, row2, row3, row4, - HTML(""" -
-

- -

- """, ), - form_actions(more=more)) - ) - super(ProposicaoForm, self).__init__( - *args, **kwargs) + class Meta: + model = Proposicao + fields = ['tipo', 'data_envio', 'descricao', 'texto_original'] class AcompanhamentoMateriaForm(ModelForm): @@ -121,8 +113,6 @@ class DocumentoAcessorioForm(ModelForm): fields = ['tipo', 'nome', 'data', 'autor', 'ementa', 'arquivo'] widgets = {'autor': forms.HiddenInput()} - widgets = {'autor': forms.HiddenInput()} - def clean_autor(self): autor_field = self.cleaned_data['autor'] try: diff --git a/materia/layouts.yaml b/materia/layouts.yaml index 272cb006e..b52311a37 100644 --- a/materia/layouts.yaml +++ b/materia/layouts.yaml @@ -87,12 +87,23 @@ TipoProposicao: - materia_ou_documento tipo_documento - modelo +ProposicaoCreate: + Proposição: + - tipo data_envio + - descricao + Materia: + - tipo_materia numero_materia ano_materia + Complemento: + - texto_original + Proposicao: Proposição: - - tipo dat_criacao_FIXME data_recebimento - - descricao_FIXME - - tip_id_basica_FIXME num_ident_basica_FIXME ano_ident_basica_FIXME - - nom_arquivo_FIXME modelo_FIXME + - tipo data_envio + - descricao + Materia: + - materia + Complemento: + - texto_original StatusTramitacao: Status Tramitação: diff --git a/materia/tests/test_materia.py b/materia/tests/test_materia.py index b4157f6d7..44f77a75f 100644 --- a/materia/tests/test_materia.py +++ b/materia/tests/test_materia.py @@ -416,7 +416,7 @@ def test_form_errors_relatoria(client): @pytest.mark.django_db(transaction=False) def test_proposicao_submit(client): - response = client.post(reverse('materia:adicionar_proposicao'), + response = client.post(reverse('materia:proposicao_create'), {'tipo': mommy.make(TipoProposicao, pk=3).pk, 'descricao': 'Teste proposição', 'salvar': 'salvar'}, @@ -432,10 +432,9 @@ def test_proposicao_submit(client): @pytest.mark.django_db(transaction=False) def test_form_errors_proposicao(client): - response = client.post(reverse('materia:adicionar_proposicao'), + response = client.post(reverse('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'] == diff --git a/materia/tests/test_materia_urls.py b/materia/tests/test_materia_urls.py index 27f350f1b..64e341c2d 100644 --- a/materia/tests/test_materia_urls.py +++ b/materia/tests/test_materia_urls.py @@ -9,11 +9,11 @@ from django.core.urlresolvers import reverse ('materia:tramitacao_update', {'pk': '8'}, '/materia/tramitacao/8/edit'), - ('materia:adicionar_proposicao', {}, '/materia/proposicao'), - ('materia:editar_proposicao', + ('materia:proposicao_create', {}, '/proposicao/create'), + ('materia:proposicao_update', {'pk': '3'}, - '/materia/proposicao/3/edit'), - ('materia:list_proposicao', {}, '/materia/proposicao_list'), + '/proposicao/3/edit'), + ('materia:proposicao_list', {}, '/proposicao/'), ]) def test_reverse(test_input, kwargs, expected): assert reverse(test_input, kwargs=kwargs) == expected diff --git a/materia/urls.py b/materia/urls.py index 332623881..e53f6940c 100644 --- a/materia/urls.py +++ b/materia/urls.py @@ -8,8 +8,7 @@ from materia.views import (AcompanhamentoConfirmarView, MateriaLegislativaCrud, MateriaLegislativaPesquisaView, MateriaTaView, NumeracaoCrud, OrgaoCrud, OrigemCrud, - ProposicaoEditView, ProposicaoListView, - ProposicaoTaView, ProposicaoView, + ProposicaoCrud, ProposicaoTaView, RegimeTramitacaoCrud, RelatoriaCrud, StatusTramitacaoCrud, TipoAutorCrud, TipoDocumentoCrud, TipoFimRelatoriaCrud, @@ -31,6 +30,8 @@ urlpatterns = [ RelatoriaCrud.get_urls() + DocumentoAcessorioCrud.get_urls())), + url(r'proposicao/', include(ProposicaoCrud.get_urls())), + # Integração com Compilação url(r'^materia/(?P[0-9]+)/ta$', MateriaTaView.as_view(), name='materia_ta'), @@ -55,12 +56,6 @@ urlpatterns = [ url(r'^sistema/materia/status-tramitacao/', include(StatusTramitacaoCrud.get_urls())), url(r'^sistema/materia/orgao/', include(OrgaoCrud.get_urls())), - url(r'^materia/proposicao$', - ProposicaoView.as_view(), name='adicionar_proposicao'), - url(r'^materia/proposicao_list$', - ProposicaoListView.as_view(), name='list_proposicao'), - url(r'^materia/proposicao/(?P[0-9]+)/edit$', - ProposicaoEditView.as_view(), name='editar_proposicao'), url(r'^materia/pesquisar-materia$', MateriaLegislativaPesquisaView.as_view(), name='pesquisar_materia'), url(r'^materia/(?P\d+)/acompanhar-materia/$', diff --git a/materia/views.py b/materia/views.py index 93c322221..1cdfada39 100644 --- a/materia/views.py +++ b/materia/views.py @@ -1,7 +1,7 @@ -import os from datetime import datetime from random import choice from string import ascii_letters, digits +from crispy_layout_mixin import form_actions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Button @@ -10,10 +10,9 @@ from django.core.exceptions import ObjectDoesNotExist from django.core.mail import send_mail from django.core.urlresolvers import reverse from django.http.response import HttpResponseRedirect -from django.shortcuts import redirect from django.template import Context, loader from django.utils.translation import ugettext_lazy as _ -from django.views.generic import CreateView, ListView, TemplateView, UpdateView +from django.views.generic import CreateView, TemplateView, UpdateView from django_filters.views import FilterView import crispy_layout_mixin @@ -53,11 +52,58 @@ TipoAutorCrud = Crud.build(TipoAutor, 'tipo_autor') AutorCrud = Crud.build(Autor, 'autor') OrgaoCrud = Crud.build(Orgao, 'orgao') TipoProposicaoCrud = Crud.build(TipoProposicao, 'tipo_proposicao') -ProposicaoCrud = Crud.build(Proposicao, '') StatusTramitacaoCrud = Crud.build(StatusTramitacao, 'status_tramitacao') UnidadeTramitacaoCrud = Crud.build(UnidadeTramitacao, 'unidade_tramitacao') +class ProposicaoCrud(Crud): + model = Proposicao + help_path = '' + + class BaseMixin(crud.base.CrudBaseMixin): + list_field_names = ['data_envio', 'descricao', 'tipo'] + + class CreateView(crud.base.CrudCreateView): + form_class = ProposicaoForm + + @property + def layout_key(self): + return 'ProposicaoCreate' + + class UpdateView(crud.base.CrudUpdateView): + form_class = ProposicaoForm + + @property + def layout_key(self): + return 'ProposicaoCreate' + + class ListView(crud.base.CrudListView): + 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...' + + return [self._as_row(obj) for obj in object_list] + + class DeleteView(MasterDetailCrud.DeleteView): + + def delete(self, request, *args, **kwargs): + proposicao = Proposicao.objects.get(id=self.kwargs['pk']) + + if not proposicao.data_envio: + proposicao.delete() + return HttpResponseRedirect(reverse('materia:proposicao_list')) + else: + proposicao.data_envio = None + proposicao.save() + return HttpResponseRedirect( + reverse('materia:proposicao_detail', + kwargs={'pk': proposicao.pk})) + + class RelatoriaCrud(MasterDetailCrud): model = Relatoria parent_field = 'materia' @@ -325,6 +371,42 @@ class MateriaLegislativaCrud(Crud): list_field_names = ['tipo', 'numero', 'ano', 'data_apresentacao'] +class DocumentoAcessorioView(CreateView): + template_name = "materia/documento_acessorio.html" + form_class = DocumentoAcessorioForm + + def get(self, request, *args, **kwargs): + materia = MateriaLegislativa.objects.get(id=kwargs['pk']) + docs = DocumentoAcessorio.objects.filter( + materia_id=kwargs['pk']).order_by('data') + form = DocumentoAcessorioForm() + + return self.render_to_response( + {'object': materia, + 'form': form, + 'docs': docs}) + + def post(self, request, *args, **kwargs): + form = self.get_form() + materia = MateriaLegislativa.objects.get(id=kwargs['pk']) + docs_list = DocumentoAcessorio.objects.filter( + materia_id=kwargs['pk']) + + if form.is_valid(): + documento_acessorio = form.save(commit=False) + documento_acessorio.materia = materia + documento_acessorio.save() + return self.form_valid(form) + else: + return self.render_to_response({'form': form, + 'object': materia, + 'docs': docs_list}) + + def get_success_url(self): + pk = self.kwargs['pk'] + return reverse('materia:documento_acessorio', kwargs={'pk': pk}) + + class AcompanhamentoConfirmarView(TemplateView): def get_redirect_url(self): @@ -556,27 +638,6 @@ def do_envia_email_tramitacao(request, materia): return None -class ProposicaoListView(ListView): - template_name = "materia/proposicao/proposicao_list.html" - paginate_by = 10 - model = Proposicao - - def get_queryset(self): - return Proposicao.objects.all().order_by('data_envio', - 'tipo', - 'descricao') - - def get_context_data(self, **kwargs): - context = super(ProposicaoListView, self).get_context_data(**kwargs) - - paginator = context['paginator'] - page_obj = context['page_obj'] - - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) - return context - - class MateriaLegislativaPesquisaView(FilterView): model = MateriaLegislativa filterset_class = MateriaLegislativaFilterSet @@ -651,99 +712,6 @@ class MateriaLegislativaPesquisaView(FilterView): return self.render_to_response(context) -class ProposicaoView(CreateView): - template_name = "materia/proposicao/proposicao.html" - form_class = ProposicaoForm - - def get_success_url(self): - return reverse('materia:list_proposicao') - - def get(self, request, *args, **kwargs): - return self.render_to_response({'form': self.get_form()}) - - def post(self, request, *args, **kwargs): - form = self.get_form() - - if form.is_valid(): - proposicao = form.save(commit=False) - tipo = TipoProposicao.objects.get(id=form.data['tipo']) - if tipo.descricao == 'Parecer': - try: - materia = MateriaLegislativa.objects.get( - tipo_id=int(form.data['tipo_materia']), - ano=int(form.data['ano_materia']), - numero=int(form.data['numero_materia'])) - except ObjectDoesNotExist: - msg = _('Matéria adicionada não existe!') - messages.add_message(request, messages.INFO, msg) - return self.render_to_response({'form': form}) - else: - proposicao.autor = materia.autoria_set.first().autor - proposicao.materia = materia - proposicao.save() - return redirect(self.get_success_url()) - else: - return self.render_to_response({'form': form}) - - -class ProposicaoEditView(CreateView): - template_name = "materia/proposicao/proposicao.html" - form_class = ProposicaoForm - - def get_success_url(self): - return reverse('materia:list_proposicao') - - def get(self, request, *args, **kwargs): - proposicao = Proposicao.objects.get(id=kwargs['pk']) - return self.render_to_response({'form': ProposicaoForm( - excluir=True, - instance=proposicao)}) - - def post(self, request, *args, **kwargs): - form = self.get_form() - proposicao = Proposicao.objects.get(id=kwargs['pk']) - if form.is_valid(): - if 'Excluir' in request.POST: - if proposicao.data_envio: - proposicao.data_envio = None - proposicao.save() - else: - proposicao.delete() - if 'salvar' or "remover-foto" in request.POST: - if 'texto_original' in request.FILES: - # if os.unlink(proposicao.texto_original.path): - # proposicao.texto_original = None - proposicao.texto_original = request.FILES['texto_original'] - tipo = TipoProposicao.objects.get(id=form.data['tipo']) - proposicao.tipo = tipo - proposicao.descricao = form.data['descricao'] - if tipo.descricao == 'Parecer': - try: - materia = MateriaLegislativa.objects.get( - tipo_id=int(form.data['tipo_materia']), - ano=int(form.data['ano_materia']), - numero=int(form.data['numero_materia'])) - except ObjectDoesNotExist: - msg = _('Matéria adicionada não existe!') - messages.add_message(request, messages.INFO, msg) - return self.render_to_response({'form': form}) - else: - proposicao.autor = materia.autoria_set.first().autor - proposicao.materia = materia - if not proposicao.data_envio: - proposicao.data_envio = datetime.now() - if "remover-texto" in request.POST: - try: - os.unlink(proposicao.texto_original.path) - except OSError: - pass # Should log this error!!!!! - proposicao.texto_original = None - proposicao.save() - return redirect(self.get_success_url()) - else: - return self.render_to_response({'form': form}) - - class MateriaTaView(IntegracaoTaView): model = MateriaLegislativa model_type_foreignkey = TipoMateriaLegislativa diff --git a/parlamentares/views.py b/parlamentares/views.py index 10fc9c1f9..89fd88615 100644 --- a/parlamentares/views.py +++ b/parlamentares/views.py @@ -88,8 +88,8 @@ class ParlamentarCrud(Crud): def get_rows(self, object_list): parlamentares = [] for m in object_list: - ultima_filiacao = m.parlamentar.filiacao_set.\ - order_by('-data').first() + ultima_filiacao = m.parlamentar.filiacao_set.order_by( + '-data').first() if ultima_filiacao and not ultima_filiacao.data_desfiliacao: partido = ultima_filiacao.partido.sigla else: diff --git a/templates/base.html b/templates/base.html index a2eacf6dc..4822ebc2d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -67,7 +67,7 @@