Browse Source

Fix #1566 (#1750)

* Adiciona a model, forms e views da reunião de comissão

* Adiciona a model, forms e views da reunião de comissão

* Adiciona a model, forms e views da reunião de comissão

* Adiciona telas de cadastro de reunião

* Adiciona telas de cadastro de reunião

* Adiciona layouts e legacy

* Adiciona template, modifica o subnav e o ListView

* Troca Crud por MasterCrudDetail

* Troca Crud por MasterCrudDetail

* Troca Crud por MasterCrudDetail

* Adiciona template de cadastro de reunião

* Corrige Createview e Listview

* Ajusta comissoes

* Corrige o deleteview e o detailview

* Muda o layout do create de reunião

* - Retira o campo tipo de cadastro de reunião
- Retira a obrigatoriedade do campo tema

* Corrige migração

* Adiciona Documento Acessorio em cadastro de reunião

* Adiciona migração

* Adiciona Documento Acessorio no Map Rules

* Corrige alguns erros e adiciona mais detalhes no template

* Pequena correção

* Fix #1566

* Adiciona migração e corrige list view

* Ajusta titulo de exibição do documento acessorio
pull/1759/head
Mariana Mendes 7 years ago
committed by Edward
parent
commit
29e94455e3
  1. 56
      sapl/comissoes/forms.py
  2. 1
      sapl/comissoes/legacy.yaml
  3. 29
      sapl/comissoes/migrations/0010_auto_20180307_1645.py
  4. 16
      sapl/comissoes/migrations/0011_merge.py
  5. 36
      sapl/comissoes/migrations/0012_documentoacessorio.py
  6. 20
      sapl/comissoes/migrations/0013_auto_20180312_1533.py
  7. 70
      sapl/comissoes/models.py
  8. 9
      sapl/comissoes/urls.py
  9. 98
      sapl/comissoes/views.py
  10. 1
      sapl/materia/forms.py
  11. 1
      sapl/rules/map_rules.py
  12. 7
      sapl/templates/comissoes/cadastro_reuniao.html
  13. 7
      sapl/templates/comissoes/cadastro_reuniao_edit.html
  14. 17
      sapl/templates/comissoes/layouts.yaml
  15. 1
      sapl/templates/comissoes/subnav.yaml

56
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
@ -155,20 +156,53 @@ class ReuniaoForm(ModelForm):
class Meta:
model = Reuniao
exclude = ['cod_andamento_reuniao']
widgets = {
'hora_fim': forms.TimeInput(format='%H:%M'),
'hora_inicio': forms.TimeInput(format='%H:%M'),
}
def clean(self):
super(ReuniaoForm, self).clean()
if self.errors:
return
if self.cleaned_data['hora_fim']:
if (self.cleaned_data['hora_fim'] <
self.cleaned_data['hora_inicio']):
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:
reuniao = Reuniao.objects.get(id=self.initial['parent_pk'])
comissao = reuniao.comissao
comissao_pk = comissao.id
documentos = reuniao.documentoacessorio_set.all()
return self.create_documentoacessorio()
if self.cleaned_data['hora_fim'] < self.cleaned_data['hora_inicio']:
msg = _('A hora de término da reunião não pode '
'ser menor que a de início')
raise ValidationError(msg)
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)

1
sapl/comissoes/legacy.yaml

@ -47,7 +47,6 @@ Participacao (ComposicaoComissao):
Reuniao:
periodo: periodo_reuniao
comissao: cod_comissao
tipo: tipo_comissao
numero: num_comissao
nome: nom_reuniao
tema: tem_reuniao

29
sapl/comissoes/migrations/0010_auto_20180307_1645.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-03-07 19:45
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('comissoes', '0009_auto_20180301_1011'),
]
operations = [
migrations.RemoveField(
model_name='reuniao',
name='tipo',
),
migrations.AlterField(
model_name='reuniao',
name='nome',
field=models.CharField(max_length=150, verbose_name='Nome da Reunião'),
),
migrations.AlterField(
model_name='reuniao',
name='tema',
field=models.CharField(blank=True, max_length=150, verbose_name='Tema da Reunião'),
),
]

16
sapl/comissoes/migrations/0011_merge.py

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-03-09 10:27
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('comissoes', '0010_auto_20180307_1645'),
('comissoes', '0010_auto_20180306_0918'),
]
operations = [
]

36
sapl/comissoes/migrations/0012_documentoacessorio.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-03-09 12:38
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import sapl.comissoes.models
import sapl.utils
class Migration(migrations.Migration):
dependencies = [
('comissoes', '0011_merge'),
]
operations = [
migrations.CreateModel(
name='DocumentoAcessorio',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nome', models.CharField(max_length=50, verbose_name='Nome')),
('data', models.DateField(blank=True, default=None, null=True, verbose_name='Data')),
('autor', models.CharField(blank=True, max_length=50, 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=sapl.comissoes.models.anexo_upload_path, validators=[sapl.utils.restringe_tipos_de_arquivo_txt], verbose_name='Texto Integral')),
('data_ultima_atualizacao', models.DateTimeField(auto_now=True, null=True, verbose_name='Data')),
('reuniao', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='documentoacessorio_set', to='comissoes.Reuniao')),
],
options={
'verbose_name': 'Documento Acessório',
'verbose_name_plural': 'Documentos Acessórios',
},
),
]

20
sapl/comissoes/migrations/0013_auto_20180312_1533.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-03-12 18:33
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('comissoes', '0012_documentoacessorio'),
]
operations = [
migrations.AlterField(
model_name='documentoacessorio',
name='autor',
field=models.CharField(max_length=100, verbose_name='Autor'),
),
]

70
sapl/comissoes/models.py

@ -182,15 +182,13 @@ class Participacao(models.Model): # ComposicaoComissao
def get_comissao_media_path(instance, subpath, filename):
return './sapl/comissao/%s/%s/%s' % (instance.numero, subpath, filename)
def pauta_upload_path(instance, filename):
return texto_upload_path(instance, filename, subpath='pauta', pk_first=True)
return texto_upload_path(instance, filename, subpath='pauta', pk_first=True)
def ata_upload_path(instance, filename):
return texto_upload_path(instance, filename, subpath='ata', pk_first=True)
def anexo_upload_path(instance, filename):
return texto_upload_path(instance, filename, subpath='anexo', pk_first=True)
@ -204,15 +202,11 @@ class Reuniao(models.Model):
Comissao,
on_delete=models.PROTECT,
verbose_name=_('Comissão'))
tipo = models.ForeignKey(
TipoComissao,
on_delete=models.PROTECT,
verbose_name=_('Tipo de Comissão'))
numero = models.PositiveIntegerField(verbose_name=_('Número'))
nome = models.CharField(
max_length=100, verbose_name=_('Nome da Reunião'))
max_length=150, verbose_name=_('Nome da Reunião'))
tema = models.CharField(
max_length=100, verbose_name=_('Tema da Reunião'))
max_length=150, blank=True, verbose_name=_('Tema da Reunião'))
data = models.DateField(verbose_name=_('Data'))
hora_inicio = models.TimeField(
verbose_name=_('Horário de Início (hh:mm)'))
@ -287,3 +281,61 @@ 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=100, 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 por %(autor)s') % {
'nome': self.nome,
'autor': self.autor}
def delete(self, using=None, keep_parents=False):
if self.arquivo:
self.arquivo.delete()
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)

9
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<pk>\d+)/materias-em-tramitacao$',
MateriasTramitacaoListView.as_view(), name='materias_em_tramitacao'),

98
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}))

1
sapl/materia/forms.py

@ -1266,6 +1266,7 @@ class ProposicaoForm(forms.ModelForm):
inst.texto_original.delete()
self.gerar_hash(inst, receber_recibo)
return super().save(commit)
inst.ano = timezone.now().year

1
sapl/rules/map_rules.py

@ -90,6 +90,7 @@ rules_group_comissoes = {
(comissoes.Participacao, __base__),
(materia.Relatoria, __base__),
(comissoes.Reuniao, __base__),
(comissoes.DocumentoAcessorio, __base__),
]
}

7
sapl/templates/comissoes/cadastro_reuniao.html

@ -0,0 +1,7 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block actions %}{% endblock %}
{% block detail_content %}
{% crispy form %}
{% endblock detail_content %}

7
sapl/templates/comissoes/cadastro_reuniao_edit.html

@ -0,0 +1,7 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block actions %}{% endblock %}
{% block detail_content %}
{% crispy form %}
{% endblock detail_content %}

17
sapl/templates/comissoes/layouts.yaml

@ -46,7 +46,7 @@ ParticipacaoEdit:
Reuniao:
{% trans 'Reunião' %}:
- periodo numero tipo
- periodo numero
- nome tema local_reuniao
- data hora_inicio hora_fim
- url_video url_audio
@ -54,3 +54,18 @@ Reuniao:
- upload_pauta upload_ata upload_anexo
- comissao
DocumentoAcessorio:
{% trans 'Documento Acessório' %}:
- nome data
- autor arquivo
- indexacao
- ementa
DocumentoAcessorioEdit:
{% trans 'Documento Acessório' %}:
- nome data
- autor arquivo
- indexacao
- ementa

1
sapl/templates/comissoes/subnav.yaml

@ -8,3 +8,4 @@
url: materias_em_tramitacao
- title: {% trans 'Reunião' %}
url: reuniao_list

Loading…
Cancel
Save