diff --git a/sapl/comissoes/forms.py b/sapl/comissoes/forms.py index 11ba22291..5e903caa9 100644 --- a/sapl/comissoes/forms.py +++ b/sapl/comissoes/forms.py @@ -7,7 +7,8 @@ from django.forms import ModelForm from django.utils.translation import ugettext_lazy as _ from sapl.base.models import Autor, TipoAutor -from sapl.comissoes.models import Comissao, Composicao, Participacao, Reuniao +from sapl.comissoes.models import (Comissao, Composicao, DocumentoAcessorio, + Participacao, Reuniao) from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar @@ -168,3 +169,43 @@ class ReuniaoForm(ModelForm): msg = _('A hora de término da reunião não pode ser menor que a de início') raise ValidationError(msg) return self.cleaned_data + +class DocumentoAcessorioCreateForm(forms.ModelForm): + + parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) + + class Meta: + model = DocumentoAcessorio + exclude = ['reuniao'] + + def __init__(self, user=None, **kwargs): + super(DocumentoAcessorioCreateForm, self).__init__(**kwargs) + + if self.instance: + comissao = kwargs['initial'] + comissao_pk = int(comissao['parent_pk']) + reuniao = Reuniao.objects.get(id=reuniao_pk) + documentos = reuniao.documentoacessorio_set.all() + return self.create_documentoacessorio() + + + def create_documentoacessorio(self): + reuniao = reuniao.objects.get(id=self.initial['parent_pk']) + + def clean(self): + super(DocumentoAcessorioCreateForm, self).clean() + return self.cleaned_data + + +class DocumentoAcessorioEditForm(forms.ModelForm): + + parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) + + class Meta: + model = DocumentoAcessorio + fields = ['nome', 'data', 'autor', 'ementa', + 'indexacao', 'arquivo'] + + def __init__(self, user=None, **kwargs): + super(DocumentoAcessorioEditForm, self).__init__(**kwargs) + diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index fa12a36e0..d4b6e5345 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -281,3 +281,66 @@ class Reuniao(models.Model): force_update=force_update, using=using, update_fields=update_fields) + + +@reversion.register() +class DocumentoAcessorio(models.Model): + reuniao = models.ForeignKey(Reuniao, + related_name='documentoacessorio_set', + on_delete=models.PROTECT) + nome = models.CharField(max_length=50, verbose_name=_('Nome')) + + data = models.DateField(blank=True, null=True, default=None, verbose_name=_('Data')) + autor = models.CharField( + max_length=50, blank=True, verbose_name=_('Autor')) + ementa = models.TextField(blank=True, verbose_name=_('Ementa')) + indexacao = models.TextField(blank=True) + arquivo = models.FileField( + blank=True, + null=True, + upload_to=anexo_upload_path, + verbose_name=_('Texto Integral'), + validators=[restringe_tipos_de_arquivo_txt]) + + data_ultima_atualizacao = models.DateTimeField( + blank=True, null=True, + auto_now=True, + verbose_name=_('Data')) + + class Meta: + verbose_name = _('Documento Acessório') + verbose_name_plural = _('Documentos Acessórios') + + def __str__(self): + return _('%(nome)s de %(data)s por %(autor)s') % { + 'nome': self.nome, + 'data': self.data, + 'autor': self.autor} + + def delete(self, using=None, keep_parents=False): + if self.arquivo: + self.arquivo.delete() + + for p in self.proposicao.all(): + p.conteudo_gerado_related = None + p.save() + + return models.Model.delete( + self, using=using, keep_parents=keep_parents) + + def save(self, force_insert=False, force_update=False, using=None, + update_fields=None): + + if not self.pk and self.arquivo: + arquivo = self.arquivo + self.arquivo = None + models.Model.save(self, force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields) + self.arquivo = arquivo + + return models.Model.save(self, force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields) diff --git a/sapl/comissoes/urls.py b/sapl/comissoes/urls.py index 4bf1904aa..72886f1f1 100644 --- a/sapl/comissoes/urls.py +++ b/sapl/comissoes/urls.py @@ -1,9 +1,7 @@ from django.conf.urls import include, url - from sapl.comissoes.views import (CargoCrud, ComissaoCrud, ComposicaoCrud, - MateriasTramitacaoListView, ParticipacaoCrud, - PeriodoComposicaoCrud, ReuniaoCrud, - TipoComissaoCrud) + DocumentoAcessorioCrud, MateriasTramitacaoListView, ParticipacaoCrud, + PeriodoComposicaoCrud, ReuniaoCrud, TipoComissaoCrud) from .apps import AppConfig @@ -13,7 +11,8 @@ urlpatterns = [ url(r'^comissao/', include(ComissaoCrud.get_urls() + ComposicaoCrud.get_urls() + ReuniaoCrud.get_urls() + - ParticipacaoCrud.get_urls())), + ParticipacaoCrud.get_urls() + + DocumentoAcessorioCrud.get_urls())), url(r'^comissao/(?P\d+)/materias-em-tramitacao$', MateriasTramitacaoListView.as_view(), name='materias_em_tramitacao'), diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index 8324f4b6a..428f2bdab 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -1,23 +1,27 @@ from django.core.urlresolvers import reverse from django.db.models import F +from django.http.response import HttpResponseRedirect from django.views.decorators.clickjacking import xframe_options_exempt from django.views.generic import ListView from django.views.generic.base import RedirectView from django.views.generic.detail import DetailView from django.views.generic.edit import FormMixin + from sapl.base.models import AppConfig as AppsAppConfig -from sapl.comissoes.apps import AppConfig -from sapl.comissoes.forms import ParticipacaoCreateForm, ParticipacaoEditForm -from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, - MasterDetailCrud, - PermissionRequiredForAppCrudMixin) +from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, + CrudAux, MasterDetailCrud, + PermissionRequiredForAppCrudMixin) +from sapl.comissoes.forms import (ComissaoForm, DocumentoAcessorioCreateForm, + DocumentoAcessorioEditForm, ParticipacaoCreateForm, + ParticipacaoEditForm, ReuniaoForm) from sapl.materia.models import MateriaLegislativa, Tramitacao -from .forms import ComissaoForm, ReuniaoForm -from .models import (CargoComissao, Comissao, Composicao, Participacao, - Periodo, Reuniao, TipoComissao) + +from .models import (CargoComissao, Comissao, Composicao, DocumentoAcessorio, + Participacao, Periodo, TipoComissao, Reuniao) +from sapl.comissoes.apps import AppConfig def pegar_url_composicao(pk): @@ -26,6 +30,11 @@ def pegar_url_composicao(pk): url = reverse('sapl.comissoes:composicao_detail', kwargs={'pk': comp_pk}) return url +def pegar_url_reuniao(pk): + documentoacessorio = DocumentoAcessorio.objects.get(id=pk) + r_pk = documentoacessorio.reuniao.pk + url = reverse('sapl.comissoes:reuniao_detail', kwargs={'pk': r_pk}) + return url CargoCrud = CrudAux.build(CargoComissao, 'cargo_comissao') PeriodoComposicaoCrud = CrudAux.build(Periodo, 'periodo_composicao_comissao') @@ -58,7 +67,6 @@ class ParticipacaoCrud(MasterDetailCrud): form_class = ParticipacaoEditForm class DeleteView(MasterDetailCrud.DeleteView): - def get_success_url(self): composicao_comissao_pk = self.object.composicao.comissao.pk composicao_pk = self.object.composicao.pk @@ -146,22 +154,44 @@ class MateriasTramitacaoListView(ListView): context['object'] = Comissao.objects.get(id=self.kwargs['pk']) return context - class ReuniaoCrud(MasterDetailCrud): model = Reuniao parent_field = 'comissao' + model_set = 'documentoacessorio_set' public = [RP_LIST, RP_DETAIL, ] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['nome', 'tema', 'comissao'] - - @property - def list_url(self): - return '' + list_field_names = [ 'nome', 'tema', 'data'] class ListView(MasterDetailCrud.ListView): paginate_by = 10 + def take_reuniao_pk(self): + try: + return int(self.request.GET['pk']) + except: + return 0 + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + reuniao_pk = self.take_reuniao_pk() + + if reuniao_pk == 0: + ultima_reuniao = list(context['reuniao_list']) + if len(ultima_reuniao) > 0: + ultimo = ultima_reuniao[-1] + context['reuniao_pk'] = ultimo.pk + else: + context['reuniao_pk'] = 0 + else: + context['reuniao_pk'] = reuniao_pk + + context['documentoacessorio_set'] = DocumentoAcessorio.objects.filter( + reuniao__pk=context['reuniao_pk'] + ).order_by('id') + return context + class UpdateView(MasterDetailCrud.UpdateView): form_class = ReuniaoForm @@ -172,15 +202,37 @@ class ReuniaoCrud(MasterDetailCrud): form_class = ReuniaoForm def get_initial(self): - comissao = Comissao.objects.get(id=self.kwargs['pk']) + comissao = Comissao.objects.get(id=self.kwargs['pk']) - return {'comissao': comissao} + return {'comissao': comissao} - class DeleteView(MasterDetailCrud.DeleteView): - pass - class DetailView(MasterDetailCrud.DetailView): +class DocumentoAcessorioCrud(MasterDetailCrud): + model = DocumentoAcessorio + parent_field = 'reuniao__comissao' + public = [RP_DETAIL, ] + ListView = None + link_return_to_parent_field = True + + class BaseMixin(MasterDetailCrud.BaseMixin): + list_field_names = ['nome', 'tipo', 'data', 'autor', 'arquivo'] - @xframe_options_exempt - def get(self, request, *args, **kwargs): - return super().get(request, *args, **kwargs) + class CreateView(MasterDetailCrud.CreateView): + form_class = DocumentoAcessorioCreateForm + + def get_initial(self): + initial = super().get_initial() + initial['parent_pk'] = self.kwargs['pk'] + return initial + + class UpdateView(MasterDetailCrud.UpdateView): + layout_key = 'DocumentoAcessorioEdit' + form_class = DocumentoAcessorioEditForm + + class DeleteView(MasterDetailCrud.DeleteView): + def delete(self, *args, **kwargs): + obj = self.get_object() + obj.delete() + return HttpResponseRedirect( + reverse('sapl.comissoes:reuniao_detail', + kwargs={'pk': obj.reuniao.pk})) \ No newline at end of file diff --git a/sapl/templates/comissoes/reuniao_list.html b/sapl/templates/comissoes/reuniao_list.html new file mode 100644 index 000000000..d9739ab9e --- /dev/null +++ b/sapl/templates/comissoes/reuniao_list.html @@ -0,0 +1,31 @@ +{% extends "crud/list.html" %} +{% load i18n common_tags crispy_forms_tags%} + +{% block base_content %} + {% if user.is_authenticated and perms.comissoes.add_reuniao %} +
+ {% block actions %} +
+ {% if view.create_url %} + + {% blocktrans with verbose_name=view.verbose_name %} Adicionar {{ verbose_name }} {% endblocktrans %} + + {% endif %} + {% block more_buttons %}{% endblock more_buttons %} +
+ {% endblock actions %} +
+ {% endif %} + + +
+ {% if user.is_authenticated and perms.comissoes.add_documentoacessorio %} +
+ + Adicionar Participação em Comissão + +
+ {% endif %} +
+ +{% endblock base_content %}