Browse Source

Merge

pull/736/merge
Eduardo Calil 8 years ago
parent
commit
99bff2bd18
  1. 23
      sapl/comissoes/views.py
  2. 117
      sapl/crud/base.py
  3. 26
      sapl/materia/views.py
  4. 62
      sapl/parlamentares/forms.py
  5. 27
      sapl/parlamentares/views.py
  6. 33
      sapl/templates/comissoes/composicao_detail.html
  7. 3
      sapl/templates/crud/detail_detail.html
  8. 2
      sapl/templates/parlamentares/layouts.yaml

23
sapl/comissoes/views.py

@ -3,7 +3,7 @@ from django.core.urlresolvers import reverse
from django.db.models import F from django.db.models import F
from django.views.generic import ListView from django.views.generic import ListView
from sapl.crud.base import Crud, CrudAux, MasterDetailCrud from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, RP_DETAIL, RP_LIST
from sapl.materia.models import MateriaLegislativa, Tramitacao from sapl.materia.models import MateriaLegislativa, Tramitacao
from .models import (CargoComissao, Comissao, Composicao, Participacao, from .models import (CargoComissao, Comissao, Composicao, Participacao,
@ -27,40 +27,31 @@ TipoComissaoCrud = CrudAux.build(
class ParticipacaoCrud(MasterDetailCrud): class ParticipacaoCrud(MasterDetailCrud):
model = Participacao model = Participacao
parent_field = 'composicao__comissao' parent_field = 'composicao__comissao'
public = [RP_DETAIL, ]
ListView = None
is_m2m = True
link_return_to_parent_field = True
class BaseMixin(MasterDetailCrud.BaseMixin): class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['composicao', 'parlamentar', 'cargo'] list_field_names = ['composicao', 'parlamentar', 'cargo']
class DetailView(MasterDetailCrud.DetailView):
permission_required = []
class ComposicaoCrud(MasterDetailCrud): class ComposicaoCrud(MasterDetailCrud):
model = Composicao model = Composicao
parent_field = 'comissao' parent_field = 'comissao'
model_set = 'participacao_set' model_set = 'participacao_set'
public = [RP_LIST, RP_DETAIL, ]
class ListView(MasterDetailCrud.ListView):
permission_required = []
class DetailView(MasterDetailCrud.DetailView):
permission_required = []
class ComissaoCrud(Crud): class ComissaoCrud(Crud):
model = Comissao model = Comissao
help_path = 'modulo_comissoes' help_path = 'modulo_comissoes'
public = [RP_LIST, RP_DETAIL, ]
class BaseMixin(Crud.BaseMixin): class BaseMixin(Crud.BaseMixin):
list_field_names = ['nome', 'sigla', 'tipo', 'data_criacao', 'ativa'] list_field_names = ['nome', 'sigla', 'tipo', 'data_criacao', 'ativa']
ordering = '-ativa', 'sigla' ordering = '-ativa', 'sigla'
class ListView(Crud.ListView):
permission_required = []
class DetailView(Crud.DetailView):
permission_required = []
class MateriasTramitacaoListView(ListView): class MateriasTramitacaoListView(ListView):
template_name = "comissoes/materias_em_tramitacao.html" template_name = "comissoes/materias_em_tramitacao.html"

117
sapl/crud/base.py

@ -94,6 +94,7 @@ variáveis do crud:
ordered_list = False desativa os clicks e controles de ord da listagem ordered_list = False desativa os clicks e controles de ord da listagem
parent_field = parentesco reverso separado por '__' parent_field = parentesco reverso separado por '__'
namespace namespace
return_parent_field_url
""" """
@ -918,6 +919,7 @@ class CrudAux(Crud):
class MasterDetailCrud(Crud): class MasterDetailCrud(Crud):
is_m2m = False is_m2m = False
link_return_to_parent_field = False
class BaseMixin(Crud.BaseMixin): class BaseMixin(Crud.BaseMixin):
@ -978,20 +980,23 @@ class MasterDetailCrud(Crud):
parent_object = getattr(parent_object, field) parent_object = getattr(parent_object, field)
else: else:
parent_object = getattr(self.object, obj.parent_field) parent_object = getattr(self.object, obj.parent_field)
if not isinstance(parent_object, models.Model): if not isinstance(parent_object, models.Model):
if parent_object.count() > 1: if parent_object.count() > 1:
if 'pkk' not in self.request.GET: if 'pkk' not in self.request.GET:
raise Http404 raise Http404()
root_pk = self.request.GET['pkk'] root_pk = self.request.GET['pkk']
parent_object = parent_object.filter(id=root_pk) parent_object = parent_object.filter(id=root_pk)
parent_object = parent_object.first() parent_object = parent_object.first()
if not parent_object: if not parent_object:
raise Http404 raise Http404()
root_pk = parent_object.pk root_pk = parent_object.pk
else: else:
root_pk = self.kwargs['pk'] # in list and create root_pk = self.kwargs['pk'] if 'pkk' not in self.request.GET\
else self.request.GET['pkk']
kwargs.setdefault('root_pk', root_pk) kwargs.setdefault('root_pk', root_pk)
context = super(CrudBaseMixin, self).get_context_data(**kwargs) context = super(CrudBaseMixin, self).get_context_data(**kwargs)
@ -1066,11 +1071,11 @@ class MasterDetailCrud(Crud):
obj = self.crud if hasattr(self, 'crud') else self obj = self.crud if hasattr(self, 'crud') else self
form = super(MasterDetailCrud.CreateView, self).get_form( form = super(MasterDetailCrud.CreateView, self).get_form(
self.form_class) self.form_class)
if not obj.is_m2m: parent_field = obj.parent_field.split('__')
parent_field = obj.parent_field.split('__')[0] if not obj.is_m2m or len(parent_field) > 1:
field = self.model._meta.get_field(parent_field) field = self.model._meta.get_field(parent_field[0])
parent = field.related_model.objects.get(pk=self.kwargs['pk']) parent = field.related_model.objects.get(pk=self.kwargs['pk'])
setattr(form.instance, parent_field, parent) setattr(form.instance, parent_field[0], parent)
return form return form
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -1118,8 +1123,14 @@ class MasterDetailCrud(Crud):
def get_success_url(self): def get_success_url(self):
obj = self.crud if hasattr(self, 'crud') else self obj = self.crud if hasattr(self, 'crud') else self
parent_object = getattr( if '__' in obj.parent_field:
self.get_object(), obj.parent_field) fields = obj.parent_field.split('__')
parent_object = self.object
for field in fields:
parent_object = getattr(parent_object, field)
break
else:
parent_object = getattr(self.object, obj.parent_field)
if not isinstance(parent_object, models.Model): if not isinstance(parent_object, models.Model):
if parent_object.count() > 1: if parent_object.count() > 1:
if 'pkk' not in self.request.GET: if 'pkk' not in self.request.GET:
@ -1134,7 +1145,15 @@ class MasterDetailCrud(Crud):
root_pk = parent_object.pk root_pk = parent_object.pk
pk = root_pk pk = root_pk
return self.resolve_url(ACTION_LIST, args=(pk,))
if obj.is_m2m:
namespace = parent_object._meta.app_config.name
return reverse('%s:%s' % (
namespace,
'%s_%s' % (parent_object._meta.model_name, ACTION_DETAIL)),
args=(pk,))
else:
return self.resolve_url(ACTION_LIST, args=(pk,))
class DetailView(Crud.DetailView): class DetailView(Crud.DetailView):
permission_required = RP_DETAIL, permission_required = RP_DETAIL,
@ -1147,7 +1166,11 @@ class MasterDetailCrud(Crud):
@property @property
def detail_list_url(self): def detail_list_url(self):
obj = self.crud if hasattr(self, 'crud') else self obj = self.crud if hasattr(self, 'crud') else self
if not obj.ListView.permission_required or\
if not obj.ListView:
return ''
if obj.ListView.permission_required not in obj.public or\
self.request.user.has_perm(self.permission(RP_LIST)): self.request.user.has_perm(self.permission(RP_LIST)):
if '__' in obj.parent_field: if '__' in obj.parent_field:
fields = obj.parent_field.split('__') fields = obj.parent_field.split('__')
@ -1197,8 +1220,20 @@ class MasterDetailCrud(Crud):
if not parent_object: if not parent_object:
raise Http404 raise Http404
root_pk = parent_object.pk root_pk = parent_object.pk
pk = root_pk
return self.resolve_url(ACTION_CREATE, args=(pk,)) url = self.resolve_url(ACTION_CREATE, args=(root_pk,))
if not obj.is_m2m:
return url
else:
if '__' in obj.parent_field:
fields = obj.parent_field.split('__')
parent_object = self.object
for field in fields:
parent_object = getattr(parent_object, field)
else:
parent_object = getattr(self.object, obj.parent_field)
return url + '?pkk=' + str(parent_object.pk)
else: else:
return '' return ''
@ -1208,29 +1243,61 @@ class MasterDetailCrud(Crud):
if hasattr(obj, 'model_set') and obj.model_set\ if hasattr(obj, 'model_set') and obj.model_set\
and self.request.user.has_perm( and self.request.user.has_perm(
self.permission_set(RP_ADD)): self.permission_set(RP_ADD)):
root_pk = self.object .pk root_pk = self.object.pk
pk = root_pk pk = root_pk
return self.resolve_url_set(ACTION_CREATE, args=(pk,))
url = self.resolve_url_set(ACTION_CREATE, args=(pk,))
if not obj.is_m2m:
return url
else:
if '__' in obj.parent_field:
fields = obj.parent_field.split('__')
parent_object = self.object
for field in fields:
parent_object = getattr(parent_object, field)
else:
parent_object = getattr(self.object, obj.parent_field)
return url + '?pkk=' + str(parent_object.pk)
else: else:
return '' return ''
@property @property
def detail_root_detail_url(self): def detail_root_detail_url(self):
""" obj = self.crud if hasattr(self, 'crud') else self
Implementar retorno para o parent_field imediato no caso de if not obj.link_return_to_parent_field:
edição em cascata de MasterDetailDetail... return ''
""" if hasattr(obj, 'parent_field'):
parent_field = obj.parent_field.split('__')
if not obj.is_m2m or len(parent_field) > 1:
field = self.model._meta.get_field(parent_field[0])
if isinstance(getattr(
self.object, parent_field[0]), models.Model):
parent_object = getattr(self.object, parent_field[0])
root_pk = parent_object.pk
pk = root_pk
namespace = parent_object._meta.app_config.name
return reverse('%s:%s' % (
namespace,
'%s_%s' % (parent_object._meta.model_name,
ACTION_DETAIL)),
args=(pk,))
return '' return ''
@property
def detail_root_detail_verbose_name(self):
obj = self.crud if hasattr(self, 'crud') else self obj = self.crud if hasattr(self, 'crud') else self
if hasattr(obj, 'parent_field'): if hasattr(obj, 'parent_field'):
# parent_field = obj.parent_field.split('__')[0] parent_field = obj.parent_field.split('__')
if not obj.is_m2m or len(parent_field) > 1:
field = self.model._meta.get_field(parent_field[0])
root_pk = self.object .pk return field.verbose_name
pk = root_pk return ''
return self.resolve_url(ACTION_DELETE, args=(pk,))
else:
return ''
@classonlymethod @classonlymethod
def build(cls, model, parent_field, help_path, def build(cls, model, parent_field, help_path,

26
sapl/materia/views.py

@ -757,7 +757,28 @@ class LegislacaoCitadaCrud(MasterDetailCrud):
args=args) args=args)
def has_permission(self): def has_permission(self):
return self.request.user.has_module_perms('materia') perms = self.get_permission_required()
# Torna a view pública se não possuir conteudo
# no atributo permission_required
return self.request.user.has_module_perms('materia')\
if len(perms) else True
def permission(self, rad):
return '%s%s%s' % ('norma' if rad.endswith('_') else '',
rad,
self.model_name if rad.endswith('_') else '')
@property
def detail_create_url(self):
obj = self.crud if hasattr(self, 'crud') else self
if self.request.user.has_module_perms('materia'):
parent_field = obj.parent_field.split('__')[0]
parent_object = getattr(self.object, parent_field)
root_pk = parent_object.pk
return self.resolve_url(ACTION_CREATE, args=(root_pk,))
return ''
@property @property
def list_url(self): def list_url(self):
@ -802,6 +823,9 @@ class LegislacaoCitadaCrud(MasterDetailCrud):
def layout_key(self): def layout_key(self):
return 'LegislacaoCitadaDetail' return 'LegislacaoCitadaDetail'
class DeleteView(MasterDetailCrud.DeleteView):
pass
class NumeracaoCrud(MasterDetailCrud): class NumeracaoCrud(MasterDetailCrud):
model = Numeracao model = Numeracao

62
sapl/parlamentares/forms.py

@ -16,27 +16,65 @@ class ImageThumbnailFileInput(ClearableFileInput):
template_name = 'floppyforms/image_thumbnail.html' template_name = 'floppyforms/image_thumbnail.html'
def validar_datas_legislatura(eleicao, inicio, fim, pk=None):
# Verifica se data de eleição < inicio < fim
if inicio >= fim or eleicao >= inicio:
msg_error = _('A data início deve ser menor que a ' +
'data fim, e a data eleição deve ser ' +
'menor que a data início')
return [False, msg_error]
# Verifica se há alguma data cadastrada no intervalo de tempo desejado
if Legislatura.objects.filter(
data_inicio__range=[inicio, fim]).exclude(pk=pk).exists()\
or Legislatura.objects.filter(
data_fim__range=[inicio, fim]).exclude(pk=pk).exists():
msg_error = _('Já existe uma legislatura neste intervalo de datas')
return [False, msg_error]
# Verifica se há alguma outra data de eleição cadastrada
if Legislatura.objects.filter(
data_eleicao=eleicao).exclude(pk=pk).exists():
msg_error = _('Esta data de eleição já foi cadastrada')
return [False, msg_error]
return [True, '']
class LegislaturaForm(ModelForm): class LegislaturaForm(ModelForm):
class Meta: class Meta:
model = Legislatura model = Legislatura
exclude = [] exclude = []
class LegislaturaCreateForm(LegislaturaForm):
def clean(self): def clean(self):
cleaned_data = self.cleaned_data cleaned_data = self.cleaned_data
numero = cleaned_data['numero'] eleicao = cleaned_data['data_eleicao']
data_inicio = cleaned_data['data_inicio'] inicio = cleaned_data['data_inicio']
data_fim = cleaned_data['data_fim'] fim = cleaned_data['data_fim']
data_eleicao = cleaned_data['data_eleicao']
if data_inicio >= data_fim or data_eleicao >= data_inicio:
raise ValidationError(_('A data início deve ser menor que a ' +
'data fim, e a data eleição deve ser ' +
'menor que a data início'))
if Legislatura.objects.filter(numero=numero).exists():
raise ValidationError(
_('Já cadastrada uma legislatura com este número'))
valida_datas = validar_datas_legislatura(eleicao, inicio, fim)
if not valida_datas[0]:
raise ValidationError(valida_datas[1])
return cleaned_data
class LegislaturaUpdateForm(LegislaturaCreateForm):
def clean(self):
cleaned_data = super(LegislaturaCreateForm, self).clean()
eleicao = cleaned_data['data_eleicao']
inicio = cleaned_data['data_inicio']
fim = cleaned_data['data_fim']
valida_datas = validar_datas_legislatura(
eleicao, inicio, fim, pk=self.instance.pk)
if not valida_datas[0]:
raise ValidationError(valida_datas[1])
return cleaned_data return cleaned_data

27
sapl/parlamentares/views.py

@ -11,7 +11,8 @@ from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux,
from sapl.materia.models import Proposicao, Relatoria from sapl.materia.models import Proposicao, Relatoria
from sapl.parlamentares.apps import AppConfig from sapl.parlamentares.apps import AppConfig
from .forms import (FiliacaoForm, LegislaturaForm, ParlamentarCreateForm, from .forms import (FiliacaoForm, LegislaturaCreateForm,
LegislaturaUpdateForm, ParlamentarCreateForm,
ParlamentarForm) ParlamentarForm)
from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa,
Dependente, Filiacao, Frente, Legislatura, Mandato, Dependente, Filiacao, Frente, Legislatura, Mandato,
@ -149,8 +150,19 @@ class LegislaturaCrud(CrudAux):
model = Legislatura model = Legislatura
help_path = 'tabelas_auxiliares#legislatura' help_path = 'tabelas_auxiliares#legislatura'
class BaseMixin(CrudAux.BaseMixin): class CreateView(CrudAux.CreateView):
form_class = LegislaturaForm form_class = LegislaturaCreateForm
def get_initial(self):
try:
ultima_legislatura = Legislatura.objects.latest('numero')
numero = ultima_legislatura.numero + 1
except Legislatura.DoesNotExist:
numero = 1
return {'numero': numero}
class UpdateView(CrudAux.UpdateView):
form_class = LegislaturaUpdateForm
class FiliacaoCrud(MasterDetailCrud): class FiliacaoCrud(MasterDetailCrud):
@ -267,9 +279,14 @@ class MesaDiretoraView(FormView):
not SessaoLegislativa.objects.exists()): not SessaoLegislativa.objects.exists()):
return self.validation(request) return self.validation(request)
mesa = SessaoLegislativa.objects.filter( sessao = SessaoLegislativa.objects.filter(
legislatura=Legislatura.objects.first()).first( legislatura=Legislatura.objects.first()).first(
).composicaomesa_set.all() )
if sessao:
mesa = sessao.composicaomesa_set.all()
else:
mesa = []
cargos_ocupados = [m.cargo for m in mesa] cargos_ocupados = [m.cargo for m in mesa]
cargos = CargoMesa.objects.all() cargos = CargoMesa.objects.all()

33
sapl/templates/comissoes/composicao_detail.html

@ -1,33 +0,0 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
<table class="table table-striped">
<thead class="thead-default">
<tr>
<th>Nome</th>
<th>Cargo</th>
<th>Titular</th>
<th>Designação</th>
<th>Desligamento</th>
<th>Motivo</th>
<th>Observação</th>
</tr>
</thead>
{% for participacao in participacoes %}
<tr>
<td><a href="{% url 'sapl.comissoes:participacao_detail' participacao.pk %}">{{participacao.parlamentar.nome_parlamentar}}</a></td>
<td>{{participacao.cargo}}</td>
<td>{{participacao.titular|yesno:"Sim,Não"}}</td>
<td>{{participacao.data_designacao|date:"d/m/Y"}}</td>
<td>{{participacao.data_desligamento|date:"d/m/Y"|default:"-"}}</td>
<td>{{participacao.motivo_desligamento|default:"-"}}</td>
<td>{{participacao.observacao|default:"-"}}</td>
</tr>
{% endfor %}
</table>
{% if user.is_authenticated %}
<a href="{% url 'sapl.comissoes:participacao_create' composicao.pk %}" class="btn btn-primary">Incluir Parlamentar</a>
{% endif %}
{% endblock detail_content %}

3
sapl/templates/crud/detail_detail.html

@ -6,6 +6,9 @@
<div class="context-actions clearfix"> <div class="context-actions clearfix">
{% block actions %} {% block actions %}
<div class="actions btn-group btn-group-sm" role="group"> <div class="actions btn-group btn-group-sm" role="group">
{% if view.detail_root_detail_url %}
<a href="{{ view.detail_root_detail_url }}" class="btn btn-default">{% trans 'Retornar para' %} {{view.detail_root_detail_verbose_name}}</a>
{% endif %}
{% if view.detail_list_url %} {% if view.detail_list_url %}
<a href="{{ view.detail_list_url }}" class="btn btn-default">{% trans 'Listar' %} {{view.verbose_name_plural}}</a> <a href="{{ view.detail_list_url }}" class="btn btn-default">{% trans 'Listar' %} {{view.verbose_name_plural}}</a>
{% endif %} {% endif %}

2
sapl/templates/parlamentares/layouts.yaml

@ -5,7 +5,7 @@ CargoMesa:
Legislatura: Legislatura:
{% trans 'Legislatura' %}: {% trans 'Legislatura' %}:
- numero:2 data_inicio data_fim data_eleicao - numero data_eleicao data_inicio data_fim
Coligacao: Coligacao:
{% trans 'Coligação' %}: {% trans 'Coligação' %}:

Loading…
Cancel
Save