Browse Source

Merge pull request #675 from interlegis/648-refatorar-crud-e-masterdetailcrud

648 refatorar crud e masterdetailcrud
pull/713/head
Leandro Roberto da Silva 8 years ago
committed by GitHub
parent
commit
1da282de38
  1. 19
      sapl/base/migrations/0019_auto_20160928_1951.py
  2. 109
      sapl/base/models.py
  3. 12
      sapl/base/templatetags/common_tags.py
  4. 5
      sapl/base/templatetags/menus.py
  5. 5
      sapl/base/urls.py
  6. 71
      sapl/base/views.py
  7. 21
      sapl/comissoes/migrations/0008_auto_20160929_1611.py
  8. 3
      sapl/comissoes/models.py
  9. 133
      sapl/comissoes/views.py
  10. 33
      sapl/crispy_layout_mixin.py
  11. 1042
      sapl/crud/base.py
  12. 81
      sapl/crud/masterdetail.py
  13. 1
      sapl/legacy/management/commands/migracao_25_31.py
  14. 6
      sapl/lexml/views.py
  15. 7
      sapl/materia/forms.py
  16. 19
      sapl/materia/migrations/0050_auto_20161003_0417.py
  17. 5
      sapl/materia/models.py
  18. 2
      sapl/materia/tests/test_materia.py
  19. 301
      sapl/materia/views.py
  20. 40
      sapl/norma/views.py
  21. 24
      sapl/parlamentares/migrations/0032_frenteproxymasterdetail.py
  22. 29
      sapl/parlamentares/migrations/0033_auto_20160930_1715.py
  23. 18
      sapl/parlamentares/migrations/0034_delete_frenteparlamentar.py
  24. 13
      sapl/parlamentares/models.py
  25. 5
      sapl/parlamentares/urls.py
  26. 475
      sapl/parlamentares/views.py
  27. 130
      sapl/protocoloadm/views.py
  28. 19
      sapl/sessao/migrations/0027_auto_20161003_0417.py
  29. 1
      sapl/sessao/models.py
  30. 12
      sapl/sessao/urls.py
  31. 224
      sapl/sessao/views.py
  32. 12
      sapl/static/styles/app.scss
  33. 4
      sapl/templates/base.html
  34. 2
      sapl/templates/crud/ajax_form.html
  35. 3
      sapl/templates/crud/confirm_delete.html
  36. 64
      sapl/templates/crud/detail.html
  37. 92
      sapl/templates/crud/detail_detail.html
  38. 2
      sapl/templates/crud/form.html
  39. 44
      sapl/templates/crud/list.html
  40. 10
      sapl/templates/parlamentares/coligacao_detail.html
  41. 4
      sapl/templates/parlamentares/composicaomesa_form.html
  42. 21
      sapl/templates/parlamentares/frentes.html
  43. 8
      sapl/templates/parlamentares/subnav.yaml
  44. 5
      sapl/templates/parlamentares/subnav_coligacao.yaml
  45. 2
      sapl/templates/sessao/mesa.html
  46. 6
      sapl/utils.py
  47. 59
      scripts/inicializa_grupos_autorizacoes.py
  48. 3
      scripts/test_inicializa_grupos_autorizacoes.py

19
sapl/base/migrations/0019_auto_20160928_1951.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-28 22:51
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('base', '0018_auto_20160919_1333'),
]
operations = [
migrations.AlterModelOptions(
name='appconfig',
options={'permissions': (('menu_sistemas', 'Renderizar Menu Sistemas'), ('view_tabelas_auxiliares', 'Visualizar Tabelas Auxiliares')), 'verbose_name': 'Configurações da Aplicação', 'verbose_name_plural': 'Configurações da Aplicação'},
),
]

109
sapl/base/models.py

@ -1,10 +1,18 @@
from builtins import LookupError
from django.apps import apps
from django.contrib.auth.management import _get_all_permissions
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models from django.core import exceptions
from django.db import models, router
from django.db.utils import DEFAULT_DB_ALIAS
from django.utils.translation import string_concat
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from sapl.utils import UF, YES_NO_CHOICES from sapl.utils import UF, YES_NO_CHOICES
TIPO_DOCUMENTO_ADMINISTRATIVO = (('O', _('Ostensivo')), TIPO_DOCUMENTO_ADMINISTRATIVO = (('O', _('Ostensivo')),
('R', _('Restritivo'))) ('R', _('Restritivo')))
@ -94,7 +102,106 @@ class AppConfig(models.Model):
class Meta: class Meta:
verbose_name = _('Configurações da Aplicação') verbose_name = _('Configurações da Aplicação')
verbose_name_plural = _('Configurações da Aplicação') verbose_name_plural = _('Configurações da Aplicação')
permissions = (
('menu_sistemas', _('Renderizar Menu Sistemas')),
('view_tabelas_auxiliares', _('Visualizar Tabelas Auxiliares')),
)
def __str__(self): def __str__(self):
return _('Configurações da Aplicação - %(id)s') % { return _('Configurações da Aplicação - %(id)s') % {
'id': self.id} 'id': self.id}
def create_proxy_permissions(
app_config, verbosity=2, interactive=True,
using=DEFAULT_DB_ALIAS, **kwargs):
if not app_config.models_module:
return
# print(app_config)
try:
Permission = apps.get_model('auth', 'Permission')
except LookupError:
return
if not router.allow_migrate_model(using, Permission):
return
from django.contrib.contenttypes.models import ContentType
permission_name_max_length = Permission._meta.get_field('name').max_length
# This will hold the permissions we're looking for as
# (content_type, (codename, name))
searched_perms = list()
# The codenames and ctypes that should exist.
ctypes = set()
for klass in list(app_config.get_models()):
opts = klass._meta
permissions = (
("list_" + opts.model_name,
string_concat(
_('Visualizaçao da lista de'), ' ',
opts.verbose_name_plural)),
("detail_" + opts.model_name,
string_concat(
_('Visualização dos detalhes de'), ' ',
opts.verbose_name_plural)),
)
opts.permissions = tuple(
set(list(permissions) + list(opts.permissions)))
if opts.proxy:
# Force looking up the content types in the current database
# before creating foreign keys to them.
app_label, model = opts.app_label, opts.model_name
try:
ctype = ContentType.objects.db_manager(
using).get_by_natural_key(app_label, model)
except:
ctype = ContentType.objects.db_manager(
using).create(app_label=app_label, model=model)
else:
ctype = ContentType.objects.db_manager(using).get_for_model(klass)
ctypes.add(ctype)
for perm in _get_all_permissions(klass._meta, ctype):
searched_perms.append((ctype, perm))
# Find all the Permissions that have a content_type for a model we're
# looking for. We don't need to check for codenames since we already have
# a list of the ones we're going to create.
all_perms = set(Permission.objects.using(using).filter(
content_type__in=ctypes,
).values_list(
"content_type", "codename"
))
perms = [
Permission(codename=codename, name=name, content_type=ct)
for ct, (codename, name) in searched_perms
if (ct.pk, codename) not in all_perms
]
# Validate the permissions before bulk_creation to avoid cryptic database
# error when the name is longer than 255 characters
for perm in perms:
if len(perm.name) > permission_name_max_length:
raise exceptions.ValidationError(
'The permission name %s of %s.%s '
'is longer than %s characters' % (
perm.name,
perm.content_type.app_label,
perm.content_type.model,
permission_name_max_length,
)
)
Permission.objects.using(using).bulk_create(perms)
if verbosity >= 2:
for perm in perms:
print("Adding permission '%s'" % perm)
models.signals.post_migrate.connect(
receiver=create_proxy_permissions,
dispatch_uid="django.contrib.auth.management.create_permissions")

12
sapl/base/templatetags/common_tags.py

@ -126,3 +126,15 @@ def get_config_not_exists(user):
return True return True
else: else:
return False return False
@register.filter
def str2intabs(value):
if not isinstance(value, str):
return ''
try:
v = int(value)
v = abs(v)
return v
except:
return ''

5
sapl/base/templatetags/menus.py

@ -32,8 +32,6 @@ def subnav(context, path=None):
execução deste subnav. Inicialmente, a maneira mais prática encontrada execução deste subnav. Inicialmente, a maneira mais prática encontrada
de isolar foi com o teste abaixo. de isolar foi com o teste abaixo.
""" """
if 'sistema' in request.path:
return
rm = request.resolver_match rm = request.resolver_match
app_template = rm.app_name.rsplit('.', 1)[-1] app_template = rm.app_name.rsplit('.', 1)[-1]
@ -45,6 +43,9 @@ def subnav(context, path=None):
else: else:
yaml_path = '%s/%s' % (app_template, 'subnav.yaml') yaml_path = '%s/%s' % (app_template, 'subnav.yaml')
if not yaml_path:
return
try: try:
""" """
Por padrão, são carragados dois Loaders, Por padrão, são carragados dois Loaders,

5
sapl/base/urls.py

@ -1,5 +1,6 @@
from django.conf.urls import include, url from django.conf.urls import include, url
from django.contrib.auth import views from django.contrib.auth import views
from django.contrib.auth.decorators import permission_required
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from .apps import AppConfig from .apps import AppConfig
@ -15,7 +16,9 @@ app_name = AppConfig.name
urlpatterns = [ urlpatterns = [
url(r'^sistema/', TemplateView.as_view(template_name='sistema.html')), url(r'^sistema/', permission_required('base.view_tabelas_auxiliares')
(TemplateView.as_view(template_name='sistema.html'))),
url(r'^ajuda/', TemplateView.as_view(template_name='ajuda.html')), url(r'^ajuda/', TemplateView.as_view(template_name='ajuda.html')),
url(r'^relatorios/', TemplateView.as_view( url(r'^relatorios/', TemplateView.as_view(
template_name='base/relatorios_list.html')), template_name='base/relatorios_list.html')),

71
sapl/base/views.py

@ -1,18 +1,16 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from braces.views import PermissionRequiredMixin
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db.models import Count, Q from django.db.models import Count, Q
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.views.generic.edit import BaseCreateView
from django_filters.views import FilterView from django_filters.views import FilterView
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import CrudAux
CrudDetailView, CrudUpdateView)
from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
from sapl.parlamentares.models import Parlamentar from sapl.parlamentares.models import Parlamentar
from sapl.sessao.models import OrdemDia, SessaoPlenaria from sapl.sessao.models import OrdemDia, SessaoPlenaria
from sapl.utils import permissao_tb_aux
from .forms import (CasaLegislativaForm, ConfiguracoesAppForm, from .forms import (CasaLegislativaForm, ConfiguracoesAppForm,
RelatorioAtasFilterSet, RelatorioAtasFilterSet,
@ -225,24 +223,14 @@ class RelatorioMateriasPorAutorView(FilterView):
return context return context
class CasaLegislativaCrud(Crud): class CasaLegislativaCrud(CrudAux):
model = CasaLegislativa model = CasaLegislativa
help_path = ''
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin): class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['codigo', 'nome', 'sigla'] list_field_names = ['codigo', 'nome', 'sigla']
def has_permission(self):
return permissao_tb_aux(self)
class CreateView(PermissionRequiredMixin, CrudCreateView):
form_class = CasaLegislativaForm form_class = CasaLegislativaForm
class UpdateView(PermissionRequiredMixin, CrudUpdateView): class DetailView(CrudAux.DetailView):
form_class = CasaLegislativaForm
class DetailView(CrudDetailView):
form_class = CasaLegislativaForm
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
return HttpResponseRedirect( return HttpResponseRedirect(
@ -257,28 +245,21 @@ class HelpView(PermissionRequiredMixin, TemplateView):
return ['ajuda/%s.html' % self.kwargs['topic']] return ['ajuda/%s.html' % self.kwargs['topic']]
class SistemaView(PermissionRequiredMixin, TemplateView): class AppConfigCrud(CrudAux):
template_name = 'sistema.html'
permission_required = ''
def has_permission(self):
return permissao_tb_aux(self)
class AppConfigCrud(Crud):
model = AppConfig model = AppConfig
help_path = ''
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin): class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['documentos_administrativos', form_class = ConfiguracoesAppForm
'sequencia_numeracao',
'painel_aberto']
def has_permission(self): @property
return permissao_tb_aux(self) def list_url(self):
return ''
class CreateView(PermissionRequiredMixin, CrudCreateView): @property
form_class = ConfiguracoesAppForm def create_url(self):
return ''
class CreateView(CrudAux.CreateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
app_config = AppConfig.objects.last() app_config = AppConfig.objects.last()
@ -288,8 +269,20 @@ class AppConfigCrud(Crud):
kwargs={'pk': app_config.pk})) kwargs={'pk': app_config.pk}))
else: else:
self.object = None self.object = None
return super(BaseCreateView, self).get( return super(CrudAux.CreateView, self).get(
request, *args, **kwargs) request, *args, **kwargs)
class UpdateView(PermissionRequiredMixin, CrudUpdateView): class ListView(CrudAux.ListView):
form_class = ConfiguracoesAppForm
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse('sapl.base:appconfig_create'))
class DetailView(CrudAux.DetailView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse('sapl.base:appconfig_create'))
class DeleteView(CrudAux.DeleteView):
def get(self, request, *args, **kwargs):
return HttpResponseRedirect(reverse('sapl.base:appconfig_create'))

21
sapl/comissoes/migrations/0008_auto_20160929_1611.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-29 19:11
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('comissoes', '0007_merge'),
]
operations = [
migrations.AlterField(
model_name='participacao',
name='composicao',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participacao_set', to='comissoes.Composicao'),
),
]

3
sapl/comissoes/models.py

@ -1,4 +1,3 @@
import datetime
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -131,7 +130,7 @@ class Composicao(models.Model): # IGNORE
class Participacao(models.Model): # ComposicaoComissao class Participacao(models.Model): # ComposicaoComissao
composicao = models.ForeignKey(Composicao) composicao = models.ForeignKey(Composicao, related_name='participacao_set')
parlamentar = models.ForeignKey(Parlamentar) parlamentar = models.ForeignKey(Parlamentar)
cargo = models.ForeignKey(CargoComissao) cargo = models.ForeignKey(CargoComissao)
titular = models.BooleanField(verbose_name=_('Titular')) titular = models.BooleanField(verbose_name=_('Titular'))

133
sapl/comissoes/views.py

@ -1,12 +1,9 @@
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.views.generic import ListView from django.views.generic import ListView
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import Crud, CrudAux, MasterDetailCrud
CrudDeleteView, CrudListView, CrudUpdateView) from sapl.materia.models import MateriaLegislativa
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.materia.models import MateriaLegislativa, Tramitacao
from sapl.utils import permissao_tb_aux, permissoes_comissoes
from .models import (CargoComissao, Comissao, Composicao, Participacao, from .models import (CargoComissao, Comissao, Composicao, Participacao,
Periodo, TipoComissao) Periodo, TipoComissao)
@ -18,130 +15,50 @@ def pegar_url_composicao(pk):
url = reverse('sapl.comissoes:composicao_detail', kwargs={'pk': comp_pk}) url = reverse('sapl.comissoes:composicao_detail', kwargs={'pk': comp_pk})
return url return url
CargoCrud = CrudAux.build(CargoComissao, 'cargo_comissao')
PeriodoComposicaoCrud = CrudAux.build(Periodo, 'periodo_composicao_comissao')
class CargoCrud(Crud): TipoComissaoCrud = CrudAux.build(
model = CargoComissao TipoComissao, 'tipo_comissao', list_field_names=[
help_path = 'cargo_comissao' 'sigla', 'nome', 'natureza', 'dispositivo_regimental'])
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
list_field_names = ['nome', 'unico']
def has_permission(self):
return permissao_tb_aux(self)
class PeriodoComposicaoCrud(Crud):
model = Periodo
help_path = 'periodo_composicao_comissao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
list_field_names = ['data_inicio', 'data_fim']
def has_permission(self):
return permissao_tb_aux(self)
class TipoComissaoCrud(Crud):
model = TipoComissao
help_path = 'tipo_comissao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
list_field_names = ['sigla', 'nome', 'natureza',
'dispositivo_regimental']
def has_permission(self):
return permissao_tb_aux(self)
class ParticipacaoCrud(MasterDetailCrud): class ParticipacaoCrud(MasterDetailCrud):
model = Participacao model = Participacao
parent_field = 'composicao' parent_field = 'composicao__comissao'
help_path = ''
class DetailView(MasterDetailCrud.DetailView):
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
context['root_pk'] = self.object.composicao.comissao.pk
return self.render_to_response(context)
class CreateView(MasterDetailCrud.CreateView):
def get_success_url(self):
return reverse(
'sapl.comissoes:composicao_detail',
kwargs={'pk': self.kwargs['pk']}
)
def cancel_url(self):
return reverse(
'sapl.comissoes:composicao_detail',
kwargs={'pk': self.kwargs['pk']}
)
class UpdateView(MasterDetailCrud.UpdateView):
def get_success_url(self): class BaseMixin(MasterDetailCrud.BaseMixin):
return pegar_url_composicao(self.kwargs['pk'])
def cancel_url(self):
return pegar_url_composicao(self.kwargs['pk'])
class DeleteView(MasterDetailCrud.DeleteView):
def get_success_url(self):
return pegar_url_composicao(self.kwargs['pk'])
def cancel_url(self):
return pegar_url_composicao(self.kwargs['pk'])
class BaseMixin(PermissionRequiredMixin, MasterDetailCrud.BaseMixin):
permission_required = permissoes_comissoes()
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'
help_path = '' model_set = 'participacao_set'
class DetailView(MasterDetailCrud.DetailView):
def get(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data(object=self.object)
composicao = Composicao.objects.get(id=self.kwargs['pk'])
context['participacoes'] = composicao.participacao_set.all()
return self.render_to_response(context)
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class ListView(MasterDetailCrud.ListView):
permission_required = permissoes_comissoes() permission_required = []
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): class DetailView(MasterDetailCrud.DetailView):
permission_required = permissoes_comissoes() permission_required = []
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_comissoes()
class ComissaoCrud(Crud): class ComissaoCrud(Crud):
model = Comissao model = Comissao
help_path = 'modulo_comissoes' help_path = 'modulo_comissoes'
class CreateView(PermissionRequiredMixin, CrudCreateView): class BaseMixin(Crud.BaseMixin):
permission_required = permissoes_comissoes() list_field_names = ['nome', 'sigla', 'tipo', 'data_criacao', 'ativa']
ordering = '-ativa', 'sigla'
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
permission_required = permissoes_comissoes()
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_comissoes()
class ListView(CrudListView): class ListView(Crud.ListView):
ordering = ['-ativa', 'sigla'] permission_required = []
class BaseMixin(CrudBaseMixin): class DetailView(Crud.DetailView):
list_field_names = ['nome', 'sigla', 'tipo', 'data_criacao', 'ativa'] permission_required = []
class MateriasTramitacaoListView(ListView): class MateriasTramitacaoListView(ListView):

33
sapl/crispy_layout_mixin.py

@ -49,7 +49,12 @@ class SaplFormLayout(Layout):
def get_field_display(obj, fieldname): def get_field_display(obj, fieldname):
field = ''
try:
field = obj._meta.get_field(fieldname) field = obj._meta.get_field(fieldname)
except:
value = getattr(obj, fieldname)
return '', value
verbose_name = str(field.verbose_name)\ verbose_name = str(field.verbose_name)\
if hasattr(field, 'verbose_name') else '' if hasattr(field, 'verbose_name') else ''
if hasattr(field, 'choices') and field.choices: if hasattr(field, 'choices') and field.choices:
@ -97,10 +102,25 @@ class CrispyLayoutFormMixin:
else: else:
return self.model.__name__ return self.model.__name__
@property
def layout_key_set(self):
if hasattr(super(CrispyLayoutFormMixin, self), 'layout_key_set'):
return super(CrispyLayoutFormMixin, self).layout_key_set
else:
obj = self.crud if hasattr(self, 'crud') else self
return getattr(obj.model,
obj.model_set).field.model.__name__
def get_layout(self): def get_layout(self):
yaml_layout = '%s/layouts.yaml' % self.model._meta.app_config.label yaml_layout = '%s/layouts.yaml' % self.model._meta.app_config.label
return read_layout_from_yaml(yaml_layout, self.layout_key) return read_layout_from_yaml(yaml_layout, self.layout_key)
def get_layout_set(self):
obj = self.crud if hasattr(self, 'crud') else self
yaml_layout = '%s/layouts.yaml' % getattr(
obj.model, obj.model_set).field.model._meta.app_config.label
return read_layout_from_yaml(yaml_layout, self.layout_key_set)
@property @property
def fields(self): def fields(self):
if hasattr(self, 'form_class') and self.form_class: if hasattr(self, 'form_class') and self.form_class:
@ -129,9 +149,22 @@ class CrispyLayoutFormMixin:
This base implementation returns the field names This base implementation returns the field names
in the first fieldset of the layout. in the first fieldset of the layout.
''' '''
obj = self.crud if hasattr(self, 'crud') else self
if hasattr(obj, 'list_field_names') and obj.list_field_names:
return obj.list_field_names
rows = self.get_layout()[0][1:] rows = self.get_layout()[0][1:]
return [fieldname for row in rows for fieldname, __ in row] return [fieldname for row in rows for fieldname, __ in row]
@property
def list_field_names_set(self):
'''The list of field names to display on table
This base implementation returns the field names
in the first fieldset of the layout.
'''
rows = self.get_layout_set()[0][1:]
return [fieldname for row in rows for fieldname, __ in row]
def get_column(self, fieldname, span): def get_column(self, fieldname, span):
obj = self.get_object() obj = self.get_object()
verbose_name, text = get_field_display(obj, fieldname) verbose_name, text = get_field_display(obj, fieldname)

1042
sapl/crud/base.py

File diff suppressed because it is too large

81
sapl/crud/masterdetail.py

@ -1,81 +0,0 @@
from django.utils.decorators import classonlymethod
from .base import (CREATE, LIST, Crud, CrudBaseMixin, CrudCreateView,
CrudDeleteView, CrudDetailView, CrudListView,
CrudUpdateView)
class MasterDetailCrud(Crud):
class BaseMixin(CrudBaseMixin):
@property
def list_url(self):
return self.resolve_url(LIST, args=(self.kwargs['pk'],))
@property
def create_url(self):
return self.resolve_url(CREATE, args=(self.kwargs['pk'],))
def get_context_data(self, **kwargs):
obj = getattr(self, 'object', None)
if obj:
root_pk = getattr(obj, self.crud.parent_field).pk
else:
root_pk = self.kwargs['pk'] # in list and create
kwargs.setdefault('root_pk', root_pk)
return super(MasterDetailCrud.BaseMixin,
self).get_context_data(**kwargs)
class ListView(CrudListView):
@classmethod
def get_url_regex(cls):
return r'^(?P<pk>\d+)/%s$' % cls.model._meta.model_name
def get_queryset(self):
qs = super(MasterDetailCrud.ListView, self).get_queryset()
kwargs = {self.crud.parent_field: self.kwargs['pk']}
return qs.filter(**kwargs)
class CreateView(CrudCreateView):
@classmethod
def get_url_regex(cls):
return r'^(?P<pk>\d+)/%s/create$' % cls.model._meta.model_name
def get_form(self, form_class=None):
form = super(MasterDetailCrud.CreateView,
self).get_form(self.form_class)
field = self.model._meta.get_field(self.crud.parent_field)
parent = field.related_model.objects.get(pk=self.kwargs['pk'])
setattr(form.instance, self.crud.parent_field, parent)
return form
class DetailView(CrudDetailView):
@classmethod
def get_url_regex(cls):
return r'^%s/(?P<pk>\d+)$' % cls.model._meta.model_name
class UpdateView(CrudUpdateView):
@classmethod
def get_url_regex(cls):
return r'^%s/(?P<pk>\d+)/edit$' % cls.model._meta.model_name
class DeleteView(CrudDeleteView):
@classmethod
def get_url_regex(cls):
return r'^%s/(?P<pk>\d+)/delete$' % cls.model._meta.model_name
def get_success_url(self):
pk = getattr(self.get_object(), self.crud.parent_field).pk
return self.resolve_url(LIST, args=(pk,))
@classonlymethod
def build(cls, model, parent_field, help_path):
crud = super(MasterDetailCrud, cls).build(model, help_path)
crud.parent_field = parent_field
return crud

1
sapl/legacy/management/commands/migracao_25_31.py

@ -1,4 +1,5 @@
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from sapl.legacy import migration from sapl.legacy import migration

6
sapl/lexml/views.py

@ -1,6 +1,6 @@
from sapl.crud.base import Crud from sapl.crud.base import CrudAux
from .models import LexmlProvedor, LexmlPublicador from .models import LexmlProvedor, LexmlPublicador
LexmlProvedorCrud = Crud.build(LexmlProvedor, 'lexml_provedor') LexmlProvedorCrud = CrudAux.build(LexmlProvedor, 'lexml_provedor')
LexmlPublicadorCrud = Crud.build(LexmlPublicador, 'lexml_publicador') LexmlPublicadorCrud = CrudAux.build(LexmlPublicador, 'lexml_publicador')

7
sapl/materia/forms.py

@ -1,6 +1,5 @@
from datetime import datetime from datetime import datetime
import django_filters
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout
from django import forms from django import forms
@ -12,6 +11,7 @@ from django.db import models, transaction
from django.db.models import Max from django.db.models import Max
from django.forms import ModelForm from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import django_filters
from sapl.comissoes.models import Comissao from sapl.comissoes.models import Comissao
from sapl.crispy_layout_mixin import form_actions, to_row from sapl.crispy_layout_mixin import form_actions, to_row
@ -27,6 +27,7 @@ from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria,
Numeracao, Proposicao, Relatoria, TipoMateriaLegislativa, Numeracao, Proposicao, Relatoria, TipoMateriaLegislativa,
Tramitacao, UnidadeTramitacao) Tramitacao, UnidadeTramitacao)
ANO_CHOICES = [('', '---------')] + RANGE_ANOS ANO_CHOICES = [('', '---------')] + RANGE_ANOS
@ -427,6 +428,10 @@ class AnexadaForm(ModelForm):
ano = forms.CharField(label='Ano', required=True) ano = forms.CharField(label='Ano', required=True)
def __init__(self, *args, **kwargs):
return super(AnexadaForm, self).__init__(*args, **kwargs)
def clean(self): def clean(self):
if self.errors: if self.errors:
return self.errors return self.errors

19
sapl/materia/migrations/0050_auto_20161003_0417.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-10-03 07:17
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('materia', '0049_remove_autoria_partido'),
]
operations = [
migrations.AlterModelOptions(
name='tramitacao',
options={'ordering': ('data_tramitacao',), 'verbose_name': 'Tramitação', 'verbose_name_plural': 'Tramitações'},
),
]

5
sapl/materia/models.py

@ -6,8 +6,8 @@ from model_utils import Choices
from sapl.comissoes.models import Comissao from sapl.comissoes.models import Comissao
from sapl.parlamentares.models import Parlamentar, Partido from sapl.parlamentares.models import Parlamentar, Partido
from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES,
restringe_tipos_de_arquivo_txt, xstr, get_settings_auth_user_model,
get_settings_auth_user_model) restringe_tipos_de_arquivo_txt, xstr)
def grupo_autor(): def grupo_autor():
@ -589,6 +589,7 @@ class Tramitacao(models.Model):
class Meta: class Meta:
verbose_name = _('Tramitação') verbose_name = _('Tramitação')
verbose_name_plural = _('Tramitações') verbose_name_plural = _('Tramitações')
ordering = 'data_tramitacao',
def __str__(self): def __str__(self):
return _('%(materia)s | %(status)s | %(data)s') % { return _('%(materia)s | %(status)s | %(data)s') % {

2
sapl/materia/tests/test_materia.py

@ -1,8 +1,8 @@
import pytest
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from model_mommy import mommy from model_mommy import mommy
import pytest
from sapl.comissoes.models import Comissao, TipoComissao from sapl.comissoes.models import Comissao, TipoComissao
from sapl.materia.models import (Anexada, Autor, Autoria, DespachoInicial, from sapl.materia.models import (Anexada, Autor, Autoria, DespachoInicial,

301
sapl/materia/views.py

@ -26,25 +26,20 @@ from django_filters.views import FilterView
from sapl.base.models import CasaLegislativa from sapl.base.models import CasaLegislativa
from sapl.compilacao.views import IntegracaoTaView from sapl.compilacao.views import IntegracaoTaView
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, CrudDetailView,
CrudDeleteView, CrudDetailView, CrudListView, MasterDetailCrud, make_pagination)
CrudUpdateView, make_pagination) from sapl.materia.forms import AnexadaForm
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.norma.models import LegislacaoCitada from sapl.norma.models import LegislacaoCitada
from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label, from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label,
autor_modal, gerar_hash_arquivo, get_base_url, autor_modal, gerar_hash_arquivo, get_base_url,
permissao_tb_aux, permissoes_autor, permissoes_materia, permissoes_autor, permissoes_materia,
permissoes_protocoloadm) permissoes_protocoloadm)
from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
AnexadaForm, AutorForm, AutoriaForm, AutorForm, ConfirmarProposicaoForm, DocumentoAcessorioForm,
ConfirmarProposicaoForm, DespachoInicialForm, MateriaLegislativaFilterSet,
DocumentoAcessorioForm, LegislacaoCitadaForm,
MateriaLegislativaFilterSet, NumeracaoForm,
PrimeiraTramitacaoEmLoteFilterSet, ProposicaoForm, PrimeiraTramitacaoEmLoteFilterSet, ProposicaoForm,
ReceberProposicaoForm, RelatoriaForm, ReceberProposicaoForm, TramitacaoEmLoteFilterSet,
TramitacaoEmLoteFilterSet, TramitacaoForm,
TramitacaoUpdateForm, UnidadeTramitacaoForm,
filtra_tramitacao_destino, filtra_tramitacao_destino,
filtra_tramitacao_destino_and_status, filtra_tramitacao_destino_and_status,
filtra_tramitacao_status) filtra_tramitacao_status)
@ -55,8 +50,26 @@ from .models import (AcompanhamentoMateria, Anexada, Autor, Autoria,
TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao, TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao,
Tramitacao, UnidadeTramitacao) Tramitacao, UnidadeTramitacao)
AnexadaCrud = Crud.build(Anexada, '') AnexadaCrud = Crud.build(Anexada, '')
OrigemCrud = Crud.build(Origem, '')
TipoMateriaCrud = CrudAux.build(
TipoMateriaLegislativa, 'tipo_materia_legislativa')
RegimeTramitacaoCrud = CrudAux.build(
RegimeTramitacao, 'regime_tramitacao')
TipoDocumentoCrud = CrudAux.build(
TipoDocumento, 'tipo_documento')
TipoFimRelatoriaCrud = CrudAux.build(
TipoFimRelatoria, 'fim_relatoria')
TipoAutorCrud = CrudAux.build(
TipoAutor, 'regime_tramitacao')
def recuperar_materia(request): def recuperar_materia(request):
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo']) tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo'])
@ -70,66 +83,6 @@ def recuperar_materia(request):
return response return response
class OrigemCrud(Crud):
model = Origem
help_path = 'origem'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoMateriaCrud(Crud):
model = TipoMateriaLegislativa
help_path = 'tipo_materia_legislativa'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class RegimeTramitacaoCrud(Crud):
model = RegimeTramitacao
help_path = 'regime_tramitacao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoDocumentoCrud(Crud):
model = TipoDocumento
help_path = 'tipo_documento'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoFimRelatoriaCrud(Crud):
model = TipoFimRelatoria
help_path = 'fim_relatoria'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoAutorCrud(Crud):
model = TipoAutor
help_path = 'tipo_autor'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
def montar_helper_autor(self): def montar_helper_autor(self):
autor_row = montar_row_autor('nome') autor_row = montar_row_autor('nome')
self.helper = FormHelper() self.helper = FormHelper()
@ -152,18 +105,14 @@ def montar_helper_autor(self):
' class="btn btn-inverse">Cancelar</a>')])) ' class="btn btn-inverse">Cancelar</a>')]))
class AutorCrud(Crud): class AutorCrud(CrudAux):
model = Autor model = Autor
help_path = 'autor' help_path = 'autor'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin): class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['tipo', 'nome'] list_field_names = ['tipo', 'nome']
def has_permission(self): class UpdateView(CrudAux.UpdateView):
return permissao_tb_aux(self)
class UpdateView(CrudUpdateView):
form_class = AutorForm
layout_key = 'AutorCreate' layout_key = 'AutorCreate'
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -175,7 +124,7 @@ class AutorCrud(Crud):
context['helper'] = self.helper context['helper'] = self.helper
return context return context
class CreateView(CrudCreateView): class CreateView(CrudAux.CreateView):
form_class = AutorForm form_class = AutorForm
layout_key = 'AutorCreate' layout_key = 'AutorCreate'
@ -229,34 +178,10 @@ class ConfirmarEmailView(TemplateView):
return self.render_to_response(context) return self.render_to_response(context)
class OrgaoCrud(Crud): OrgaoCrud = CrudAux.build(Orgao, 'orgao')
model = Orgao TipoProposicaoCrud = CrudAux.build(TipoProposicao, 'tipo_proposicao')
help_path = 'orgao' StatusTramitacaoCrud = CrudAux.build(StatusTramitacao, 'status_tramitacao')
UnidadeTramitacaoCrud = CrudAux.build(UnidadeTramitacao, 'unidade_tramitacao')
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoProposicaoCrud(Crud):
model = TipoProposicao
help_path = 'tipo_proposicao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class StatusTramitacaoCrud(Crud):
model = StatusTramitacao
help_path = 'status_tramitacao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
def criar_materia_proposicao(proposicao): def criar_materia_proposicao(proposicao):
@ -296,22 +221,6 @@ def criar_doc_proposicao(proposicao):
) )
class UnidadeTramitacaoCrud(Crud):
model = UnidadeTramitacao
help_path = 'unidade_tramitacao'
class CreateView(PermissionRequiredMixin, CrudCreateView):
permission_required = permissoes_materia()
form_class = UnidadeTramitacaoForm
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
permission_required = permissoes_materia()
form_class = UnidadeTramitacaoForm
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_materia()
class ProposicaoDevolvida(PermissionRequiredMixin, ListView): class ProposicaoDevolvida(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_devolvidas_list.html' template_name = 'materia/prop_devolvidas_list.html'
model = Proposicao model = Proposicao
@ -457,13 +366,12 @@ class ProposicaoCrud(Crud):
model = Proposicao model = Proposicao
help_path = '' help_path = ''
class BaseMixin(CrudBaseMixin): class BaseMixin(Crud.BaseMixin):
list_field_names = ['data_envio', 'descricao', list_field_names = ['data_envio', 'descricao',
'tipo', 'data_recebimento'] 'tipo', 'data_recebimento']
class CreateView(PermissionRequiredMixin, CrudCreateView): class CreateView(Crud.CreateView):
form_class = ProposicaoForm form_class = ProposicaoForm
permission_required = {'materia.add_proposicao'}
@property @property
def layout_key(self): def layout_key(self):
@ -489,9 +397,8 @@ class ProposicaoCrud(Crud):
else: else:
return {'autor': autor_id} return {'autor': autor_id}
class UpdateView(PermissionRequiredMixin, CrudUpdateView): class UpdateView(Crud.UpdateView):
form_class = ProposicaoForm form_class = ProposicaoForm
permission_required = permissoes_autor()
def get_initial(self): def get_initial(self):
initial = self.initial.copy() initial = self.initial.copy()
@ -525,8 +432,7 @@ class ProposicaoCrud(Crud):
messages.add_message(self.request, messages.ERROR, msg) messages.add_message(self.request, messages.ERROR, msg)
return False return False
class DetailView(PermissionRequiredMixin, CrudDetailView): class DetailView(Crud.DetailView):
permission_required = permissoes_autor()
def has_permission(self): def has_permission(self):
perms = self.get_permission_required() perms = self.get_permission_required()
@ -542,9 +448,8 @@ class ProposicaoCrud(Crud):
context['subnav_template_name'] = '' context['subnav_template_name'] = ''
return context return context
class ListView(PermissionRequiredMixin, CrudListView): class ListView(Crud.ListView):
ordering = ['-data_envio', 'descricao'] ordering = ['-data_envio', 'descricao']
permission_required = permissoes_autor()
def get_rows(self, object_list): def get_rows(self, object_list):
@ -572,8 +477,7 @@ class ProposicaoCrud(Crud):
return lista return lista
class DeleteView(PermissionRequiredMixin, CrudDeleteView): class DeleteView(Crud.DeleteView):
permission_required = {'materia.delete_proposicao'}
def has_permission(self): def has_permission(self):
perms = self.get_permission_required() perms = self.get_permission_required()
@ -636,10 +540,9 @@ class RelatoriaCrud(MasterDetailCrud):
model = Relatoria model = Relatoria
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
permission_required = permissoes_materia()
form_class = RelatoriaForm
def get_initial(self): def get_initial(self):
materia = MateriaLegislativa.objects.get(id=self.kwargs['pk']) materia = MateriaLegislativa.objects.get(id=self.kwargs['pk'])
@ -658,26 +561,20 @@ class RelatoriaCrud(MasterDetailCrud):
return {'comissao': localizacao} return {'comissao': localizacao}
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_materia()
form_class = RelatoriaForm
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class TramitacaoCrud(MasterDetailCrud): class TramitacaoCrud(MasterDetailCrud):
model = Tramitacao model = Tramitacao
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin): class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['data_tramitacao', 'unidade_tramitacao_local', list_field_names = ['data_tramitacao', 'unidade_tramitacao_local',
'unidade_tramitacao_destino', 'status'] 'unidade_tramitacao_destino', 'status']
ordered_list = False
ordering = '-data_tramitacao',
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = TramitacaoForm
permission_required = permissoes_materia()
def get_initial(self): def get_initial(self):
local = MateriaLegislativa.objects.get( local = MateriaLegislativa.objects.get(
@ -692,9 +589,7 @@ class TramitacaoCrud(MasterDetailCrud):
do_envia_email_tramitacao(request, materia) do_envia_email_tramitacao(request, materia)
return super(CreateView, self).post(request, *args, **kwargs) return super(CreateView, self).post(request, *args, **kwargs)
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = TramitacaoUpdateForm
permission_required = permissoes_materia()
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
materia = MateriaLegislativa.objects.get( materia = MateriaLegislativa.objects.get(
@ -713,8 +608,7 @@ class TramitacaoCrud(MasterDetailCrud):
kwargs = {self.crud.parent_field: self.kwargs['pk']} kwargs = {self.crud.parent_field: self.kwargs['pk']}
return qs.filter(**kwargs).order_by('-data_tramitacao', '-id') return qs.filter(**kwargs).order_by('-data_tramitacao', '-id')
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView): class DeleteView(MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
def delete(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs):
tramitacao = Tramitacao.objects.get(id=self.kwargs['pk']) tramitacao = Tramitacao.objects.get(id=self.kwargs['pk'])
@ -767,78 +661,56 @@ class DocumentoAcessorioCrud(MasterDetailCrud):
model = DocumentoAcessorio model = DocumentoAcessorio
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin): class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['nome', 'tipo', 'data', 'autor', 'arquivo'] list_field_names = ['nome', 'tipo', 'data', 'autor', 'arquivo']
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = DocumentoAcessorioForm form_class = DocumentoAcessorioForm
permission_required = permissoes_materia()
def __init__(self, *args, **kwargs): def __init__(self, **kwargs):
montar_helper_documento_acessorio(self) montar_helper_documento_acessorio(self)
super(CreateView, self).__init__(*args, **kwargs) super(MasterDetailCrud.CreateView, self).__init__(**kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(CreateView, self).get_context_data(**kwargs) context = super(
MasterDetailCrud.CreateView, self).get_context_data(**kwargs)
context['helper'] = self.helper context['helper'] = self.helper
return context return context
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = DocumentoAcessorioForm form_class = DocumentoAcessorioForm
permission_required = permissoes_materia()
def __init__(self, *args, **kwargs): def __init__(self, **kwargs):
montar_helper_documento_acessorio(self) montar_helper_documento_acessorio(self)
super(UpdateView, self).__init__(*args, **kwargs) super(MasterDetailCrud.UpdateView, self).__init__(**kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs) context = super(UpdateView, self).get_context_data(**kwargs)
context['helper'] = self.helper context['helper'] = self.helper
return context return context
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class AutoriaCrud(MasterDetailCrud): class AutoriaCrud(MasterDetailCrud):
model = Autoria model = Autoria
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
form_class = AutoriaForm
permission_required = permissoes_materia()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = AutoriaForm
permission_required = permissoes_materia()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class DespachoInicialCrud(MasterDetailCrud): class DespachoInicialCrud(MasterDetailCrud):
model = DespachoInicial model = DespachoInicial
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
form_class = DespachoInicialForm
permission_required = permissoes_materia()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = DespachoInicialForm
permission_required = permissoes_materia()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class LegislacaoCitadaCrud(MasterDetailCrud): class LegislacaoCitadaCrud(MasterDetailCrud):
model = LegislacaoCitada model = LegislacaoCitada
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin): class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['norma', 'disposicoes'] list_field_names = ['norma', 'disposicoes']
@ -848,13 +720,7 @@ class LegislacaoCitadaCrud(MasterDetailCrud):
return reverse('%s:%s' % (namespace, self.url_name(suffix)), return reverse('%s:%s' % (namespace, self.url_name(suffix)),
args=args) args=args)
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = LegislacaoCitadaForm
permission_required = permissoes_materia()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = LegislacaoCitadaForm
permission_required = permissoes_materia()
def get_initial(self): def get_initial(self):
self.initial['tipo'] = self.object.norma.tipo.id self.initial['tipo'] = self.object.norma.tipo.id
@ -862,9 +728,6 @@ class LegislacaoCitadaCrud(MasterDetailCrud):
self.initial['ano'] = self.object.norma.ano self.initial['ano'] = self.object.norma.ano
return self.initial return self.initial
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class DetailView(MasterDetailCrud.DetailView): class DetailView(MasterDetailCrud.DetailView):
@property @property
@ -876,69 +739,35 @@ class NumeracaoCrud(MasterDetailCrud):
model = Numeracao model = Numeracao
parent_field = 'materia' parent_field = 'materia'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
form_class = NumeracaoForm
permission_required = permissoes_materia()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = NumeracaoForm
permission_required = permissoes_materia()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class AnexadaCrud(MasterDetailCrud): class AnexadaCrud(MasterDetailCrud):
model = Anexada model = Anexada
parent_field = 'materia_principal' parent_field = 'materia_principal'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin): class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['materia_anexada', 'data_anexacao'] list_field_names = ['materia_anexada', 'data_anexacao']
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
form_class = AnexadaForm
permission_required = permissoes_materia()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = AnexadaForm
permission_required = permissoes_materia()
def get_initial(self):
self.initial['tipo'] = self.object.materia_anexada.tipo.id
self.initial['numero'] = self.object.materia_anexada.numero
self.initial['ano'] = self.object.materia_anexada.ano
return self.initial
class DetailView(MasterDetailCrud.DetailView): class DetailView(MasterDetailCrud.DetailView):
@property @property
def layout_key(self): def layout_key(self):
return 'AnexadaDetail' return 'AnexadaDetail'
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_materia()
class MateriaLegislativaCrud(Crud): class MateriaLegislativaCrud(Crud):
model = MateriaLegislativa model = MateriaLegislativa
help_path = 'materia_legislativa' help_path = 'materia_legislativa'
public = [RP_LIST, RP_DETAIL]
class BaseMixin(CrudBaseMixin): class BaseMixin(Crud.BaseMixin):
list_field_names = ['tipo', 'numero', 'ano', 'data_apresentacao'] list_field_names = ['tipo', 'numero', 'ano', 'data_apresentacao']
class CreateView(PermissionRequiredMixin, CrudCreateView):
permission_required = permissoes_materia()
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
permission_required = permissoes_materia()
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_materia()
# FIXME - qual a finalidade dessa classe??
class DocumentoAcessorioView(PermissionRequiredMixin, CreateView): class DocumentoAcessorioView(PermissionRequiredMixin, CreateView):
template_name = "materia/documento_acessorio.html" template_name = "materia/documento_acessorio.html"
form_class = DocumentoAcessorioForm form_class = DocumentoAcessorioForm

40
sapl/norma/views.py

@ -1,46 +1,33 @@
from datetime import datetime from datetime import datetime
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.shortcuts import redirect from django.shortcuts import redirect
from django.views.generic import FormView, ListView from django.views.generic import FormView, ListView
from sapl.compilacao.views import IntegracaoTaView from sapl.compilacao.views import IntegracaoTaView
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import RP_DETAIL, RP_LIST, Crud, CrudAux, make_pagination
CrudDeleteView, CrudUpdateView, make_pagination)
from sapl.utils import permissoes_norma
from .forms import NormaJuridicaForm, NormaJuridicaPesquisaForm from .forms import NormaJuridicaPesquisaForm
from .models import (AssuntoNorma, LegislacaoCitada, NormaJuridica, from .models import (AssuntoNorma, LegislacaoCitada, NormaJuridica,
TipoNormaJuridica) TipoNormaJuridica)
LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '') LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '')
class AssuntoNormaCrud(Crud): AssuntoNormaCrud = CrudAux.build(AssuntoNorma, 'assunto_norma_juridica',
model = AssuntoNorma list_field_names=['assunto', 'descricao'])
help_path = 'assunto_norma_juridica'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
permission_required = permissoes_norma()
list_field_names = ['assunto', 'descricao']
TipoNormaCrud = CrudAux.build(
class TipoNormaCrud(Crud): TipoNormaJuridica, 'tipo_norma_juridica',
model = TipoNormaJuridica list_field_names=['equivalente_lexml', 'sigla', 'descricao'])
help_path = 'tipo_norma_juridica'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
permission_required = permissoes_norma()
list_field_names = ['equivalente_lexml', 'sigla', 'descricao']
class NormaCrud(Crud): class NormaCrud(Crud):
model = NormaJuridica model = NormaJuridica
help_path = 'norma_juridica' help_path = 'norma_juridica'
public = [RP_LIST, RP_DETAIL]
class UpdateView(PermissionRequiredMixin, CrudUpdateView): class UpdateView(Crud.UpdateView):
form_class = NormaJuridicaForm
permission_required = permissoes_norma()
@property @property
def layout_key(self): def layout_key(self):
@ -54,18 +41,13 @@ class NormaCrud(Crud):
self.initial['numero_materia'] = norma.materia.numero self.initial['numero_materia'] = norma.materia.numero
return self.initial.copy() return self.initial.copy()
class CreateView(PermissionRequiredMixin, CrudCreateView): class CreateView(Crud.CreateView):
form_class = NormaJuridicaForm
permission_required = permissoes_norma()
@property @property
def layout_key(self): def layout_key(self):
return 'NormaJuridicaCreate' return 'NormaJuridicaCreate'
class DeleteView(PermissionRequiredMixin, CrudDeleteView): class BaseMixin(Crud.BaseMixin):
permission_required = permissoes_norma()
class BaseMixin(CrudBaseMixin):
list_field_names = ['tipo', 'numero', 'ano', 'ementa'] list_field_names = ['tipo', 'numero', 'ano', 'ementa']

24
sapl/parlamentares/migrations/0032_frenteproxymasterdetail.py

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-30 20:09
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0031_auto_20160929_1842'),
]
operations = [
migrations.CreateModel(
name='FrenteProxyMasterDetail',
fields=[
],
options={
'proxy': True,
},
bases=('parlamentares.frente',),
),
]

29
sapl/parlamentares/migrations/0033_auto_20160930_1715.py

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-30 20:15
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0032_frenteproxymasterdetail'),
]
operations = [
migrations.DeleteModel(
name='FrenteProxyMasterDetail',
),
migrations.CreateModel(
name='FrenteParlamentar',
fields=[
],
options={
'proxy': True,
'verbose_name': 'Frente',
'verbose_name_plural': 'Frentes',
},
bases=('parlamentares.frente',),
),
]

18
sapl/parlamentares/migrations/0034_delete_frenteparlamentar.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-30 21:43
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0033_auto_20160930_1715'),
]
operations = [
migrations.DeleteModel(
name='FrenteParlamentar',
),
]

13
sapl/parlamentares/models.py

@ -267,6 +267,19 @@ class Parlamentar(models.Model):
def __str__(self): def __str__(self):
return self.nome_completo return self.nome_completo
@property
def filiacao_atual(self):
ultima_filiacao = self.filiacao_set.order_by('-data').first()
if ultima_filiacao and not ultima_filiacao.data_desfiliacao:
return ultima_filiacao.partido.sigla
else:
return _('Sem Partido')
@property
def avatar_html(self):
return '<img class="avatar-parlamentar" src='\
+ self.fotografia.url + '/>'if self.fotografia else ''
class TipoDependente(models.Model): class TipoDependente(models.Model):
descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição'))

5
sapl/parlamentares/urls.py

@ -23,12 +23,9 @@ urlpatterns = [
FiliacaoCrud.get_urls() + MandatoCrud.get_urls() + FiliacaoCrud.get_urls() + MandatoCrud.get_urls() +
ParticipacaoParlamentarCrud.get_urls() + ParticipacaoParlamentarCrud.get_urls() +
ProposicaoParlamentarCrud.get_urls() + ProposicaoParlamentarCrud.get_urls() +
RelatoriaParlamentarCrud.get_urls() RelatoriaParlamentarCrud.get_urls() + FrenteList.get_urls()
)), )),
url(r'^parlamentar/(?P<pk>\d+)/frente$',
FrenteList.as_view(), name="frent_list"),
url(r'^sistema/coligacao/', url(r'^sistema/coligacao/',
include(ColigacaoCrud.get_urls() + include(ColigacaoCrud.get_urls() +
ComposicaoColigacaoCrud.get_urls())), ComposicaoColigacaoCrud.get_urls())),

475
sapl/parlamentares/views.py

@ -1,126 +1,88 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.shortcuts import redirect
from django.utils.datastructures import MultiValueDictKeyError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView, ListView from django.views.generic import FormView
from sapl.comissoes.models import Participacao from sapl.comissoes.models import Participacao
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux,
CrudDeleteView, CrudDetailView, CrudListView, CrudBaseForListAndDetailExternalAppView,
CrudUpdateView) MasterDetailCrud)
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.materia.models import Proposicao, Relatoria from sapl.materia.models import Proposicao, Relatoria
from sapl.utils import permissao_tb_aux, permissoes_parlamentares from sapl.parlamentares.apps import AppConfig
from .forms import (ComposicaoColigacaoForm, FiliacaoForm, FrenteForm, from .forms import LegislaturaForm, ParlamentarCreateForm, ParlamentarForm
LegislaturaForm, ParlamentarCreateForm, 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,
NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa,
SituacaoMilitar, TipoAfastamento, TipoDependente) SituacaoMilitar, TipoAfastamento, TipoDependente)
CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa')
PartidoCrud = CrudAux.build(Partido, 'partidos')
SessaoLegislativaCrud = CrudAux.build(SessaoLegislativa, 'sessao_legislativa')
TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente')
NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao')
TipoAfastamentoCrud = CrudAux.build(TipoAfastamento, 'tipo_afastamento')
TipoMilitarCrud = CrudAux.build(SituacaoMilitar, 'tipo_situa_militar')
class FrenteList(ListView): FrenteCrud = CrudAux.build(Frente, 'tipo_situa_militar', list_field_names=[
model = Frente 'nome', 'data_criacao', 'parlamentares'])
paginate_by = 10
template_name = 'parlamentares/frentes.html'
def get_queryset(self):
return Frente.objects.filter(parlamentares__in=[self.kwargs['pk']])
def get_context_data(self, **kwargs): DependenteCrud = MasterDetailCrud.build(
context = super(FrenteList, self).get_context_data(**kwargs) Dependente, 'parlamentar', 'dependente')
context['root_pk'] = self.kwargs['pk']
context['object_list'] = self.get_queryset()
return context
class FrenteCrud(Crud): class FrenteList(MasterDetailCrud):
model = Frente model = Frente
help_path = '' is_m2m = True
parent_field = 'parlamentares'
class BaseMixin(CrudBaseMixin): CreateView, UpdateView, DeleteView = None, None, None
list_field_names = ['nome', 'data_criacao', 'parlamentares']
def has_permission(self): class BaseMixin(Crud.PublicMixin, MasterDetailCrud.BaseMixin):
return permissao_tb_aux(self) list_field_names = ['nome', 'data_criacao']
class CreateView(PermissionRequiredMixin, CrudCreateView): @classmethod
form_class = FrenteForm def url_name(cls, suffix):
return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix)
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
form_class = FrenteForm
class RelatoriaParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
class RelatoriaParlamentarCrud(MasterDetailCrud):
model = Relatoria model = Relatoria
parent_field = 'parlamentar' parent_field = 'parlamentar'
help_path = '' help_path = 'relatoria_parlamentar'
namespace = AppConfig.name
class ListView(MasterDetailCrud.ListView):
permission_required = permissoes_parlamentares()
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
permission_required = permissoes_parlamentares()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): class ProposicaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
permission_required = permissoes_parlamentares()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_parlamentares()
class ProposicaoParlamentarCrud(MasterDetailCrud):
model = Proposicao model = Proposicao
parent_field = 'autor__parlamentar'
help_path = ''
class BaseMixin(CrudBaseMixin):
list_field_names = ['tipo', 'descricao'] list_field_names = ['tipo', 'descricao']
parent_field = 'autor__parlamentar'
namespace = AppConfig.name
class ListView(MasterDetailCrud.ListView): class ListView(CrudBaseForListAndDetailExternalAppView.ListView):
permission_required = permissoes_parlamentares()
def get_context_data(self, **kwargs):
context = super(ProposicaoParlamentarCrud.ListView, self
).get_context_data(**kwargs)
context['root_pk'] = self.kwargs['pk']
return context
def get_queryset(self): def get_queryset(self):
try: return super().get_queryset().filter(
proposicoes = Proposicao.objects.filter(
autor__parlamentar_id=self.kwargs['pk'], autor__parlamentar_id=self.kwargs['pk'],
data_envio__isnull=False) data_envio__isnull=False)
except ObjectDoesNotExist:
return []
else:
return proposicoes
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
permission_required = permissoes_parlamentares()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_parlamentares()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_parlamentares()
class ParticipacaoParlamentarCrud(MasterDetailCrud): class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView):
model = Participacao model = Participacao
parent_field = 'parlamentar' parent_field = 'parlamentar'
help_path = '' namespace = AppConfig.name
list_field_names = ['composicao__comissao__nome', 'cargo__nome', (
'composicao__periodo__data_inicio', 'composicao__periodo__data_fim')]
class ListView(MasterDetailCrud.ListView): class ListView(CrudBaseForListAndDetailExternalAppView.ListView):
ordering = ('-composicao__periodo') ordering = ('-composicao__periodo')
def get_rows(self, object_list): def get_rows(self, object_list):
"""
FIXME:
Este metodo não será necessário quando get_rows for refatorada
"""
comissoes = [] comissoes = []
for p in object_list: for p in object_list:
if p.cargo.nome != 'Relator': if p.cargo.nome != 'Relator':
@ -138,324 +100,141 @@ class ParticipacaoParlamentarCrud(MasterDetailCrud):
return comissoes return comissoes
def get_headers(self): def get_headers(self):
return ['Comissão', 'Cargo', 'Período'] return [_('Comissão'), _('Cargo'), _('Período de participação'), ]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
permission_required = permissoes_parlamentares()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_parlamentares()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_parlamentares()
class CargoMesaCrud(Crud):
model = CargoMesa
help_path = 'cargo_mesa'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class PartidoCrud(Crud):
model = Partido
help_path = 'partidos'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class SessaoLegislativaCrud(Crud):
model = SessaoLegislativa
help_path = 'sessao_legislativa'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoDependenteCrud(Crud):
model = TipoDependente
help_path = 'nivel_instrucao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class NivelInstrucaoCrud(Crud):
model = NivelInstrucao
help_path = 'tipo_dependente'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoAfastamentoCrud(Crud):
model = TipoAfastamento
help_path = 'tipo_afastamento'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoMilitarCrud(Crud):
model = SituacaoMilitar
help_path = 'tipo_situa_militar'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class DependenteCrud(MasterDetailCrud): class ColigacaoCrud(CrudAux):
model = Dependente model = Coligacao
parent_field = 'parlamentar' help_path = 'tabelas_auxiliares#coligacao'
help_path = ''
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
permission_required = permissoes_parlamentares()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_parlamentares()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_parlamentares()
class ListView(PermissionRequiredMixin, MasterDetailCrud.ListView): class ListView(CrudAux.ListView):
permission_required = permissoes_parlamentares() ordering = ('-numero_votos', 'nome')
class DetailView(PermissionRequiredMixin, MasterDetailCrud.DetailView): class BaseMixin(CrudAux.BaseMixin):
permission_required = permissoes_parlamentares() subnav_template_name = 'parlamentares/subnav_coligacao.yaml'
class MandatoCrud(MasterDetailCrud): class MandatoCrud(MasterDetailCrud):
model = Mandato model = Mandato
parent_field = 'parlamentar' parent_field = 'parlamentar'
help_path = '' public = [RP_DETAIL, RP_LIST]
class ListView(MasterDetailCrud.ListView): class ListView(MasterDetailCrud.ListView):
ordering = ('-legislatura__numero') ordering = ('-legislatura__numero')
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
permission_required = permissoes_parlamentares()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_parlamentares()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_parlamentares()
class ColigacaoCrud(Crud):
model = Coligacao
help_path = 'tabelas_auxiliares#coligacao'
class ListView(CrudListView):
ordering = ('-numero_votos', 'nome')
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class ComposicaoColigacaoCrud(MasterDetailCrud): class ComposicaoColigacaoCrud(MasterDetailCrud):
model = ComposicaoColigacao model = ComposicaoColigacao
parent_field = 'coligacao' parent_field = 'coligacao'
help_path = '' help_path = ''
class CreateView(MasterDetailCrud.CreateView): class BaseMixin(MasterDetailCrud.BaseMixin):
form_class = ComposicaoColigacaoForm
def get_initial(self): def get_context_data(self, **kwargs):
id = self.kwargs['pk'] context = super().get_context_data()
return {'coligacao_id': id} context['subnav_template_name'] = \
'parlamentares/subnav_coligacao.yaml'
class UpdateView(MasterDetailCrud.UpdateView): return context
form_class = ComposicaoColigacaoForm
def get_initial(self):
id = self.kwargs['pk']
return {'coligacao_id': id}
class ListView(MasterDetailCrud.ListView): class ListView(MasterDetailCrud.ListView):
ordering = '-partido__sigla' ordering = '-partido__sigla'
class BaseMixin(PermissionRequiredMixin, MasterDetailCrud.BaseMixin):
def has_permission(self): class LegislaturaCrud(CrudAux):
return permissao_tb_aux(self)
class LegislaturaCrud(Crud):
model = Legislatura model = Legislatura
help_path = 'tabelas_auxiliares#legislatura' help_path = 'tabelas_auxiliares#legislatura'
class CreateView(CrudCreateView): class BaseMixin(CrudAux.BaseMixin):
form_class = LegislaturaForm
class UpdateView(CrudUpdateView):
form_class = LegislaturaForm form_class = LegislaturaForm
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class FiliacaoCrud(MasterDetailCrud): class FiliacaoCrud(MasterDetailCrud):
model = Filiacao model = Filiacao
parent_field = 'parlamentar' parent_field = 'parlamentar'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class BaseMixin(MasterDetailCrud.BaseMixin):
form_class = FiliacaoForm
permission_required = permissoes_parlamentares()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = FiliacaoForm
permission_required = permissoes_parlamentares()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_parlamentares()
class ListView(MasterDetailCrud.ListView):
ordering = '-data' ordering = '-data'
def get_parlamentar_permissions():
lista_permissoes = []
cts = ContentType.objects.filter(app_label='parlamentares')
perms_parlamentares = list(Permission.objects.filter(
content_type__in=cts))
for p in perms_parlamentares:
lista_permissoes.append('parlamentares.' + p.codename)
return set(lista_permissoes)
class ParlamentarCrud(Crud): class ParlamentarCrud(Crud):
model = Parlamentar model = Parlamentar
help_path = '' public = [RP_LIST, RP_DETAIL]
class DetailView(CrudDetailView): class BaseMixin(Crud.BaseMixin):
form_class = ParlamentarCreateForm
def get_template_names(self): ordered_list = False
usuario = self.request.user list_field_names = [
lista_permissoes = get_parlamentar_permissions() 'avatar_html', 'nome_parlamentar', 'filiacao_atual', 'ativo']
if usuario.has_perms(lista_permissoes): class DetailView(Crud.DetailView):
return ['crud/detail.html']
else: def get_template_names(self):
return ['parlamentares/parlamentar_perfil_publico.html'] return ['crud/detail.html']\
if self.request.user.has_perm(self.permission(RP_CHANGE))\
else ['parlamentares/parlamentar_perfil_publico.html']
class UpdateView(PermissionRequiredMixin, CrudUpdateView): class UpdateView(Crud.UpdateView):
form_class = ParlamentarForm form_class = ParlamentarForm
permission_required = permissoes_parlamentares()
class CreateView(PermissionRequiredMixin, CrudCreateView): class CreateView(Crud.CreateView):
form_class = ParlamentarCreateForm
permission_required = permissoes_parlamentares()
@property @property
def layout_key(self): def layout_key(self):
return 'ParlamentarCreate' return 'ParlamentarCreate'
class DeleteView(PermissionRequiredMixin, CrudDeleteView): def form_valid(self, form):
form_class = ParlamentarCreateForm '''
permission_required = permissoes_parlamentares() Reimplementa form_valid devido ao save de ParlamentarCreateForm
ser específico, sendo necessário isolar padrão do crud que aciona
form.save(commit=False) para registrar dados de auditoria se
o model implementá-los, bem como de container se também implement.
'''
return super(Crud.CreateView, self).form_valid(form)
class ListView(CrudListView): class ListView(Crud.ListView):
template_name = "parlamentares/parlamentares_list.html" template_name = "parlamentares/parlamentares_list.html"
paginate_by = None paginate_by = None
ordering = '-nome_parlamentar'
def take_legislatura_id(self): def take_legislatura_id(self):
legislaturas = Legislatura.objects.all().order_by(
'-numero')
if legislaturas:
try: try:
legislatura_id = int(self.request.GET['periodo']) return int(self.request.GET['periodo'])
except MultiValueDictKeyError: except:
for l in Legislatura.objects.all(): for l in Legislatura.objects.all():
if l.atual(): if l.atual():
return l.id return l.id
return legislatura_id
else:
return 0 return 0
def get_queryset(self): def get_queryset(self):
if self.take_legislatura_id() != 0: queryset = super().get_queryset()
mandatos = Mandato.objects.filter(
legislatura_id=self.take_legislatura_id()).order_by(
'parlamentar__nome_parlamentar')
return mandatos
return []
def get_rows(self, object_list): legislatura_id = self.take_legislatura_id()
parlamentares = [] if legislatura_id != 0:
for m in object_list: queryset = queryset.filter(
ultima_filiacao = m.parlamentar.filiacao_set.order_by( mandato__legislatura_id=legislatura_id)
'-data').first() return queryset
if ultima_filiacao and not ultima_filiacao.data_desfiliacao:
partido = ultima_filiacao.partido.sigla
else:
partido = _('Sem Partido')
parlamentar = [
("<img src=" + m.parlamentar.fotografia.url + " \
height='42' width='42' />" if m.parlamentar.fotografia
else '', ''),
(m.parlamentar.nome_parlamentar, m.parlamentar.id),
(partido, None),
('Sim' if m.parlamentar.ativo else 'Não', None)
]
parlamentares.append(parlamentar)
return parlamentares
def get_headers(self): def get_headers(self):
return ['', 'Parlamentar', 'Partido', 'Ativo?'] return ['', _('Parlamentar'), _('Partido'), _('Ativo?')]
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ParlamentarCrud.ListView, self context = super().get_context_data(**kwargs)
).get_context_data(**kwargs)
context.setdefault('title', self.verbose_name_plural)
# Adiciona legislatura para filtrar parlamentares # Adiciona legislatura para filtrar parlamentares
legislaturas = Legislatura.objects.all().order_by( legislaturas = Legislatura.objects.all().order_by('-numero')
'-numero')
context['legislaturas'] = legislaturas context['legislaturas'] = legislaturas
context['legislatura_id'] = self.take_legislatura_id() context['legislatura_id'] = self.take_legislatura_id()
return context
# Tira Link do avatar_html e coloca no nome
def check_permission_mesa(request): for row in context['rows']:
lista_permissoes = [] row[1] = (row[1][0], row[0][1])
cts = ContentType.objects.filter(app_label='parlamentares') row[0] = (row[0][0], None)
cts = cts.filter(model__icontains='mesa') return context
perms = list(Permission.objects.filter(content_type__in=cts))
for p in perms:
lista_permissoes.append('parlamentares.' + p.codename)
return request.user.has_perms(set(lista_permissoes))
class MesaDiretoraView(FormView): class MesaDiretoraView(FormView):
template_name = "mesa_diretora/mesa_diretora.html" template_name = 'parlamentares/composicaomesa_form.html'
success_url = reverse_lazy('sapl.parlamentares:mesa_diretora') success_url = reverse_lazy('sapl.parlamentares:mesa_diretora')
# Essa função avisa quando se pode compor uma Mesa Legislativa # Essa função avisa quando se pode compor uma Mesa Legislativa
@ -474,18 +253,18 @@ class MesaDiretoraView(FormView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if (not Legislatura.objects.exists() or if (not Legislatura.objects.exists() or
not SessaoLegislativa.objects.all()): not SessaoLegislativa.objects.exists()):
return self.validation(request) return self.validation(request)
mesa = SessaoLegislativa.objects.filter( mesa = SessaoLegislativa.objects.filter(
legislatura=Legislatura.objects.last()).first( legislatura=Legislatura.objects.first()).first(
).composicaomesa_set.all() ).composicaomesa_set.all()
cargos_ocupados = [m.cargo for m in mesa] cargos_ocupados = [m.cargo for m in mesa]
cargos = CargoMesa.objects.all() cargos = CargoMesa.objects.all()
cargos_vagos = list(set(cargos) - set(cargos_ocupados)) cargos_vagos = list(set(cargos) - set(cargos_ocupados))
parlamentares = Legislatura.objects.last().mandato_set.all() parlamentares = Legislatura.objects.first().mandato_set.all()
parlamentares_ocupados = [m.parlamentar for m in mesa] parlamentares_ocupados = [m.parlamentar for m in mesa]
parlamentares_vagos = list( parlamentares_vagos = list(
set( set(
@ -495,23 +274,26 @@ class MesaDiretoraView(FormView):
return self.render_to_response( return self.render_to_response(
{'legislaturas': Legislatura.objects.all( {'legislaturas': Legislatura.objects.all(
).order_by('-numero'), ).order_by('-numero'),
'legislatura_selecionada': Legislatura.objects.last(), 'legislatura_selecionada': Legislatura.objects.first(),
'sessoes': SessaoLegislativa.objects.filter( 'sessoes': SessaoLegislativa.objects.filter(
legislatura=Legislatura.objects.last()), legislatura=Legislatura.objects.first()),
'sessao_selecionada': SessaoLegislativa.objects.filter( 'sessao_selecionada': SessaoLegislativa.objects.filter(
legislatura=Legislatura.objects.last()).first(), legislatura=Legislatura.objects.first()).first(),
'composicao_mesa': mesa, 'composicao_mesa': mesa,
'parlamentares': parlamentares_vagos, 'parlamentares': parlamentares_vagos,
'cargos_vagos': cargos_vagos 'cargos_vagos': cargos_vagos
}) })
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if 'Incluir' in request.POST and check_permission_mesa(request):
if (not Legislatura.objects.all() or if (not Legislatura.objects.exists() or
not SessaoLegislativa.objects.all()): not SessaoLegislativa.objects.exists()):
return self.validation(request) return self.validation(request)
if 'Incluir' in request.POST and request.user.has_perm(
'%s.add_%s' % (
AppConfig.label, ComposicaoMesa._meta.model_name)):
composicao = ComposicaoMesa() composicao = ComposicaoMesa()
composicao.sessao_legislativa = SessaoLegislativa.objects.get( composicao.sessao_legislativa = SessaoLegislativa.objects.get(
id=int(request.POST['sessao'])) id=int(request.POST['sessao']))
@ -521,13 +303,12 @@ class MesaDiretoraView(FormView):
id=int(request.POST['cargo'])) id=int(request.POST['cargo']))
composicao.save() composicao.save()
return redirect('sapl.parlamentares:mesa_diretora') messages.success(request, _(
'Parlamentar adicionado com sucesso!'))
elif 'Excluir' in request.POST and check_permission_mesa(request): elif 'Excluir' in request.POST and request.user.has_perm(
'%s.delete_%s' % (
if (not Legislatura.objects.all() or AppConfig.label, ComposicaoMesa._meta.model_name)):
not SessaoLegislativa.objects.all()):
return self.validation(request)
if 'composicao_mesa' in request.POST: if 'composicao_mesa' in request.POST:
ids = request.POST['composicao_mesa'].split(':') ids = request.POST['composicao_mesa'].split(':')
@ -537,8 +318,12 @@ class MesaDiretoraView(FormView):
cargo_id=int(ids[1]) cargo_id=int(ids[1])
) )
composicao.delete() composicao.delete()
return redirect('sapl.parlamentares:mesa_diretora') messages.success(request, _(
'Parlamentar excluido com sucesso!'))
else: else:
messages.error(request, _(
'Selecione um parlamentar para ser excluido!'))
mesa = ComposicaoMesa.objects.filter( mesa = ComposicaoMesa.objects.filter(
sessao_legislativa=request.POST['sessao']) sessao_legislativa=request.POST['sessao'])
@ -553,6 +338,13 @@ class MesaDiretoraView(FormView):
set( set(
[p.parlamentar for p in parlamentares]) - set( [p.parlamentar for p in parlamentares]) - set(
parlamentares_ocupados)) parlamentares_ocupados))
sessao_selecionada = SessaoLegislativa.objects.get(
id=int(request.POST['sessao']))
if str(sessao_selecionada.legislatura_id) != int(
request.POST['legislatura']):
sessao_selecionada = SessaoLegislativa.objects.filter(
legislatura=Legislatura.objects.first()).first()
return self.render_to_response( return self.render_to_response(
{'legislaturas': Legislatura.objects.all( {'legislaturas': Legislatura.objects.all(
).order_by('-numero'), ).order_by('-numero'),
@ -560,8 +352,7 @@ class MesaDiretoraView(FormView):
id=int(request.POST['legislatura'])), id=int(request.POST['legislatura'])),
'sessoes': SessaoLegislativa.objects.filter( 'sessoes': SessaoLegislativa.objects.filter(
legislatura_id=int(request.POST['legislatura'])), legislatura_id=int(request.POST['legislatura'])),
'sessao_selecionada': SessaoLegislativa.objects.get( 'sessao_selecionada': sessao_selecionada,
id=int(request.POST['sessao'])),
'composicao_mesa': mesa, 'composicao_mesa': mesa,
'parlamentares': parlamentares_vagos, 'parlamentares': parlamentares_vagos,
'cargos_vagos': cargos_vagos 'cargos_vagos': cargos_vagos

130
sapl/protocoloadm/views.py

@ -14,12 +14,9 @@ from django.views.generic import CreateView, DetailView, FormView, ListView
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django_filters.views import FilterView from django_filters.views import FilterView
import sapl.crud.base from sapl.base.apps import AppConfig as AppsAppConfig
from sapl.base.models import AppConfig from sapl.base.models import AppConfig
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, make_pagination
CrudDeleteView, CrudDetailView, CrudListView,
CrudUpdateView, make_pagination)
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.materia.models import TipoMateriaLegislativa from sapl.materia.models import TipoMateriaLegislativa
from sapl.utils import (create_barcode, get_client_ip, permissoes_adm, from sapl.utils import (create_barcode, get_client_ip, permissoes_adm,
permissoes_protocoloadm) permissoes_protocoloadm)
@ -35,79 +32,56 @@ from .models import (Autor, DocumentoAcessorioAdministrativo,
TipoDocumentoAdministrativo, TipoInstituicao, TipoDocumentoAdministrativo, TipoInstituicao,
TramitacaoAdministrativo) TramitacaoAdministrativo)
TipoDocumentoAdministrativoCrud = Crud.build(TipoDocumentoAdministrativo, '') TipoDocumentoAdministrativoCrud = CrudAux.build(
DocumentoAcessorioAdministrativoCrud = Crud.build( TipoDocumentoAdministrativo, '')
DocumentoAcessorioAdministrativo, '') TipoInstituicaoCrud = CrudAux.build(TipoInstituicao, '')
ProtocoloDocumentoCrud = Crud.build(Protocolo, '') ProtocoloDocumentoCrud = Crud.build(Protocolo, '')
# FIXME precisa de uma chave diferente para o layout # FIXME precisa de uma chave diferente para o layout
ProtocoloMateriaCrud = Crud.build(Protocolo, '') ProtocoloMateriaCrud = Crud.build(Protocolo, '')
TipoInstituicaoCrud = Crud.build(TipoInstituicao, '')
class DocumentoAdministrativoCrud(Crud):
model = DocumentoAdministrativo
help_path = ''
class BaseMixin(sapl.crud.base.CrudBaseMixin):
list_field_names = ['tipo', 'numero', 'ano', 'data',
'numero_protocolo', 'assunto',
'interessado', 'tramitacao', 'texto_integral']
class CreateView(PermissionRequiredMixin, CrudCreateView):
permission_required = permissoes_adm()
class UpdateView(PermissionRequiredMixin, CrudUpdateView): DocumentoAcessorioAdministrativoCrud = Crud.build(
permission_required = permissoes_adm() DocumentoAcessorioAdministrativo, '')
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_adm()
class ListView(PermissionRequiredMixin, CrudListView): class DocumentoAdministrativoMixin:
permission_required = permissoes_adm()
def has_permission(self): def has_permission(self):
app_config = AppConfig.objects.last() app_config = AppConfig.objects.last()
if app_config and app_config.documentos_administrativos == 'O':
if app_config:
if app_config.documentos_administrativos == 'O':
return True return True
perms = self.get_permission_required() return self.request.user.has_module_perms(AppsAppConfig.label)
return self.request.user.has_perms(perms)
class DetailView(PermissionRequiredMixin, CrudDetailView):
permission_required = permissoes_adm()
def has_permission(self): class DocumentoAdministrativoCrud(Crud):
app_config = AppConfig.objects.last() model = DocumentoAdministrativo
help_path = ''
if app_config: class BaseMixin(Crud.BaseMixin):
if app_config.documentos_administrativos == 'O': list_field_names = ['tipo', 'numero', 'ano', 'data',
return True 'numero_protocolo', 'assunto',
'interessado', 'tramitacao', 'texto_integral']
class ListView(Crud.ListView, DocumentoAdministrativoMixin):
pass
perms = self.get_permission_required() class DetailView(Crud.DetailView, DocumentoAdministrativoMixin):
return self.request.user.has_perms(perms) pass
class StatusTramitacaoAdministrativoCrud(Crud): class StatusTramitacaoAdministrativoCrud(CrudAux):
model = StatusTramitacaoAdministrativo model = StatusTramitacaoAdministrativo
help_path = '' help_path = ''
class BaseMixin(CrudBaseMixin): class BaseMixin(CrudAux.BaseMixin):
list_field_names = ['sigla', 'indicador', 'descricao'] list_field_names = ['sigla', 'indicador', 'descricao']
class ListView(CrudListView): class ListView(CrudAux.ListView):
ordering = 'sigla' ordering = 'sigla'
class CreateView(PermissionRequiredMixin, CrudCreateView):
permission_required = permissoes_adm()
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
permission_required = permissoes_adm()
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_adm()
class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView): class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView):
model = Protocolo model = Protocolo
@ -394,22 +368,13 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView):
class PesquisarDocumentoAdministrativoView(PermissionRequiredMixin, class PesquisarDocumentoAdministrativoView(PermissionRequiredMixin,
FilterView): FilterView,
DocumentoAdministrativoMixin):
model = DocumentoAdministrativo model = DocumentoAdministrativo
filterset_class = DocumentoAdministrativoFilterSet filterset_class = DocumentoAdministrativoFilterSet
paginate_by = 10 paginate_by = 10
permission_required = permissoes_adm() permission_required = permissoes_adm()
def has_permission(self):
app_config = AppConfig.objects.last()
if app_config:
if app_config.documentos_administrativos == 'O':
return True
perms = self.get_permission_required()
return self.request.user.has_perms(perms)
def get_filterset_kwargs(self, filterset_class): def get_filterset_kwargs(self, filterset_class):
super(PesquisarDocumentoAdministrativoView, super(PesquisarDocumentoAdministrativoView,
self).get_filterset_kwargs(filterset_class) self).get_filterset_kwargs(filterset_class)
@ -603,47 +568,22 @@ class TramitacaoAdmCrud(MasterDetailCrud):
list_field_names = ['data_tramitacao', 'unidade_tramitacao_local', list_field_names = ['data_tramitacao', 'unidade_tramitacao_local',
'unidade_tramitacao_destino', 'status'] 'unidade_tramitacao_destino', 'status']
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = TramitacaoAdmForm form_class = TramitacaoAdmForm
permission_required = permissoes_adm()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = TramitacaoAdmEditForm form_class = TramitacaoAdmEditForm
permission_required = permissoes_adm()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_adm()
class ListView(PermissionRequiredMixin, MasterDetailCrud.ListView): class ListView(MasterDetailCrud.ListView, DocumentoAdministrativoMixin):
permission_required = permissoes_adm()
def get_queryset(self): def get_queryset(self):
qs = super(MasterDetailCrud.ListView, self).get_queryset() qs = super(MasterDetailCrud.ListView, self).get_queryset()
kwargs = {self.crud.parent_field: self.kwargs['pk']} kwargs = {self.crud.parent_field: self.kwargs['pk']}
return qs.filter(**kwargs).order_by('-data_tramitacao', '-id') return qs.filter(**kwargs).order_by('-data_tramitacao', '-id')
def has_permission(self): class DetailView(MasterDetailCrud.DetailView,
app_config = AppConfig.objects.last() DocumentoAdministrativoMixin):
pass
if app_config:
if app_config.documentos_administrativos == 'O':
return True
perms = self.get_permission_required()
return self.request.user.has_perms(perms)
class DetailView(PermissionRequiredMixin, MasterDetailCrud.DetailView):
permission_required = permissoes_adm()
def has_permission(self):
app_config = AppConfig.objects.last()
if app_config:
if app_config.documentos_administrativos == 'O':
return True
perms = self.get_permission_required()
return self.request.user.has_perms(perms)
def get_nome_autor(request): def get_nome_autor(request):

19
sapl/sessao/migrations/0027_auto_20161003_0417.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-10-03 07:17
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('sessao', '0026_auto_20160926_1445'),
]
operations = [
migrations.AlterModelOptions(
name='bancada',
options={'ordering': ('-legislatura__numero',), 'verbose_name': 'Bancada', 'verbose_name_plural': 'Bancadas'},
),
]

1
sapl/sessao/models.py

@ -41,6 +41,7 @@ class Bancada(models.Model):
class Meta: class Meta:
verbose_name = _('Bancada') verbose_name = _('Bancada')
verbose_name_plural = _('Bancadas') verbose_name_plural = _('Bancadas')
ordering = ('-legislatura__numero', )
def __str__(self): def __str__(self):
return self.nome return self.nome

12
sapl/sessao/urls.py

@ -39,6 +39,7 @@ urlpatterns = [
ExpedienteMateriaCrud.get_urls() + ExpedienteMateriaCrud.get_urls() +
MateriaOrdemDiaCrud.get_urls())), MateriaOrdemDiaCrud.get_urls())),
url(r'^sessao/(?P<pk>\d+)/mesa$', MesaView.as_view(), name='mesa'),
url(r'^recuperar-materia/', recuperar_materia), url(r'^recuperar-materia/', recuperar_materia),
url(r'^recuperar-numero-sessao/', recuperar_numero_sessao), url(r'^recuperar-numero-sessao/', recuperar_numero_sessao),
@ -86,17 +87,16 @@ urlpatterns = [
PautaOrdemDetail.as_view(), name='pauta_ordem_detail'), PautaOrdemDetail.as_view(), name='pauta_ordem_detail'),
# Subnav sessão # Subnav sessão
url(r'^(?P<pk>\d+)/expediente$', url(r'^sessao/(?P<pk>\d+)/expediente$',
ExpedienteView.as_view(), name='expediente'), ExpedienteView.as_view(), name='expediente'),
url(r'^(?P<pk>\d+)/presenca$', url(r'^sessao/(?P<pk>\d+)/presenca$',
PresencaView.as_view(), name='presenca'), PresencaView.as_view(), name='presenca'),
url(r'^(?P<pk>\d+)/painel$', url(r'^sessao/(?P<pk>\d+)/painel$',
PainelView.as_view(), name='painel'), PainelView.as_view(), name='painel'),
url(r'^(?P<pk>\d+)/presencaordemdia$', url(r'^sessao/(?P<pk>\d+)/presencaordemdia$',
PresencaOrdemDiaView.as_view(), PresencaOrdemDiaView.as_view(),
name='presencaordemdia'), name='presencaordemdia'),
url(r'^(?P<pk>\d+)/mesa$', MesaView.as_view(), name='mesa'), url(r'^sessao/(?P<pk>\d+)/resumo$',
url(r'^(?P<pk>\d+)/resumo$',
ResumoView.as_view(), name='resumo'), ResumoView.as_view(), name='resumo'),
url(r'^sessao/pesquisar-sessao$', url(r'^sessao/pesquisar-sessao$',
PesquisarSessaoPlenariaView.as_view(), name='pesquisar_sessao'), PesquisarSessaoPlenariaView.as_view(), name='pesquisar_sessao'),

224
sapl/sessao/views.py

@ -1,41 +1,41 @@
from datetime import datetime from datetime import datetime
from re import sub from re import sub
from braces.views import PermissionRequiredMixin
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.decorators import permission_required
from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.forms.utils import ErrorList from django.forms.utils import ErrorList
from django.http import JsonResponse from django.http import JsonResponse
from django.http.response import HttpResponseRedirect from django.http.response import HttpResponseRedirect
from django.utils.datastructures import MultiValueDictKeyError from django.utils.datastructures import MultiValueDictKeyError
from django.utils.decorators import method_decorator
from django.utils.html import strip_tags from django.utils.html import strip_tags
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import ListView, TemplateView from django.views.generic import ListView, TemplateView
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
from django_filters.views import FilterView from django_filters.views import FilterView
from rest_framework import generics from rest_framework import generics
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView, from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux,
CrudDeleteView, CrudDetailView, CrudListView, MasterDetailCrud, make_pagination)
CrudUpdateView, make_pagination)
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.materia.forms import pega_ultima_tramitacao from sapl.materia.forms import pega_ultima_tramitacao
from sapl.materia.models import (Autoria, DocumentoAcessorio, from sapl.materia.models import (Autoria, DocumentoAcessorio,
TipoMateriaLegislativa, Tramitacao) TipoMateriaLegislativa, Tramitacao)
from sapl.materia.views import MateriaLegislativaPesquisaView from sapl.materia.views import MateriaLegislativaPesquisaView
from sapl.norma.models import NormaJuridica from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import (Parlamentar, SessaoLegislativa, from sapl.parlamentares.models import (Legislatura, Parlamentar,
Legislatura) SessaoLegislativa)
from sapl.sessao.apps import AppConfig
from sapl.sessao.serializers import SessaoPlenariaSerializer from sapl.sessao.serializers import SessaoPlenariaSerializer
from sapl.utils import permissao_tb_aux, permissoes_painel, permissoes_sessao from sapl.utils import permissoes_painel, permissoes_sessao
from .forms import (AdicionarVariasMateriasFilterSet, BancadaForm, from .forms import (AdicionarVariasMateriasFilterSet, ExpedienteForm,
ExpedienteForm, ExpedienteMateriaForm, ListMateriaForm, ListMateriaForm, MesaForm, PautaSessaoFilterSet,
MesaForm, OradorExpedienteForm, OradorForm, OrdemDiaForm, PresencaForm, SessaoPlenariaFilterSet, VotacaoEditForm,
PautaSessaoFilterSet, PresencaForm, VotacaoForm, VotacaoNominalForm)
SessaoPlenariaFilterSet, VotacaoEditForm, VotacaoForm,
VotacaoNominalForm)
from .models import (Bancada, Bloco, CargoBancada, CargoMesa, from .models import (Bancada, Bloco, CargoBancada, CargoMesa,
ExpedienteMateria, ExpedienteSessao, IntegranteMesa, ExpedienteMateria, ExpedienteSessao, IntegranteMesa,
MateriaLegislativa, Orador, OradorExpediente, OrdemDia, MateriaLegislativa, Orador, OradorExpediente, OrdemDia,
@ -46,6 +46,19 @@ from .models import (Bancada, Bloco, CargoBancada, CargoMesa,
OrdemDiaCrud = Crud.build(OrdemDia, '') OrdemDiaCrud = Crud.build(OrdemDia, '')
RegistroVotacaoCrud = Crud.build(RegistroVotacao, '') RegistroVotacaoCrud = Crud.build(RegistroVotacao, '')
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoExpedienteCrud = CrudAux.build(TipoExpediente, 'tipo_expediente')
CargoBancadaCrud = CrudAux.build(CargoBancada, '')
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
TipoSessaoCrud = CrudAux.build(TipoSessaoPlenaria, 'tipo_sessao_plenaria')
BlocoCrud = CrudAux.build(
Bloco, '', list_field_names=['nome', 'data_criacao', 'partidos'])
BancadaCrud = CrudAux.build(
Bancada, '', list_field_names=['nome', 'legislatura'])
TipoResultadoVotacaoCrud = CrudAux.build(
TipoResultadoVotacao, 'tipo_resultado_votacao')
def reordernar_materias_expediente(request, pk): def reordernar_materias_expediente(request, pk):
expedientes = ExpedienteMateria.objects.filter( expedientes = ExpedienteMateria.objects.filter(
@ -73,73 +86,6 @@ def reordernar_materias_ordem(request, pk):
reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk})) reverse('sapl.sessao:ordemdia_list', kwargs={'pk': pk}))
class BlocoCrud(Crud):
model = Bloco
help_path = ''
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
list_field_names = ['nome', 'data_criacao', 'partidos']
def has_permission(self):
return permissao_tb_aux(self)
class BancadaCrud(Crud):
model = Bancada
help_path = ''
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
list_field_names = ['nome', 'legislatura']
def has_permission(self):
return permissao_tb_aux(self)
class ListView(CrudListView):
ordering = 'legislatura'
class CreateView(CrudCreateView):
form_class = BancadaForm
class UpdateView(CrudUpdateView):
form_class = BancadaForm
class TipoSessaoCrud(Crud):
model = TipoSessaoPlenaria
help_path = 'tipo_sessao_plenaria'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoResultadoVotacaoCrud(Crud):
model = TipoResultadoVotacao
help_path = 'tipo_resultado_votacao'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class TipoExpedienteCrud(Crud):
model = TipoExpediente
help_path = 'tipo_expediente'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
class CargoBancadaCrud(Crud):
model = CargoBancada
help_path = ''
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
def has_permission(self):
return permissao_tb_aux(self)
def abrir_votacao_expediente_view(request, pk, spk): def abrir_votacao_expediente_view(request, pk, spk):
existe_votacao_aberta = ExpedienteMateria.objects.filter( existe_votacao_aberta = ExpedienteMateria.objects.filter(
sessao_plenaria_id=spk, votacao_aberta=True sessao_plenaria_id=spk, votacao_aberta=True
@ -182,14 +128,12 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
'resultado'] 'resultado']
class CreateView(MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = OrdemDiaForm
def get_success_url(self): def get_success_url(self):
return reverse('sapl.sessao:ordemdia_list', return reverse('sapl.sessao:ordemdia_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})
class UpdateView(MasterDetailCrud.UpdateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = OrdemDiaForm
def get_initial(self): def get_initial(self):
self.initial['tipo_materia'] = self.object.materia.tipo.id self.initial['tipo_materia'] = self.object.materia.tipo.id
@ -198,6 +142,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
return self.initial return self.initial
class DetailView(MasterDetailCrud.DetailView): class DetailView(MasterDetailCrud.DetailView):
@property @property
def layout_key(self): def layout_key(self):
return 'OrdemDiaDetail' return 'OrdemDiaDetail'
@ -241,7 +186,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
url = reverse('sapl.sessao:abrir_votacao', kwargs={ url = reverse('sapl.sessao:abrir_votacao', kwargs={
'pk': obj.pk, 'spk': obj.sessao_plenaria_id}) 'pk': obj.pk, 'spk': obj.sessao_plenaria_id})
if self.request.user.has_perms(permissoes_sessao()): if self.request.user.has_module_perms(AppConfig.label):
btn_abrir = ''' btn_abrir = '''
Matéria não votada<br /> Matéria não votada<br />
<a href="%s" <a href="%s"
@ -251,7 +196,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
else: else:
obj.resultado = '''Não há resultado''' obj.resultado = '''Não há resultado'''
else: else:
if self.request.user.has_perms(permissoes_sessao()): if self.request.user.has_module_perms(AppConfig.label):
url = '' url = ''
if obj.tipo_votacao == 1: if obj.tipo_votacao == 1:
url = reverse('sapl.sessao:votacaosimbolicaedit', url = reverse('sapl.sessao:votacaosimbolicaedit',
@ -305,7 +250,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
list_field_names = ['numero_ordem', 'materia', list_field_names = ['numero_ordem', 'materia',
'observacao', 'resultado'] 'observacao', 'resultado']
class ListView(MasterDetailCrud.ListView): class ListView(Crud.PublicMixin, MasterDetailCrud.ListView):
ordering = ['numero_ordem', 'materia', 'resultado'] ordering = ['numero_ordem', 'materia', 'resultado']
def get_rows(self, object_list): def get_rows(self, object_list):
@ -345,6 +290,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
<a href="%s" <a href="%s"
class="btn btn-primary" class="btn btn-primary"
role="button">Abrir Votação</a>''' % (url) role="button">Abrir Votação</a>''' % (url)
obj.resultado = btn_abrir obj.resultado = btn_abrir
else: else:
url = '' url = ''
@ -370,17 +316,13 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
obj.resultado) obj.resultado)
return [self._as_row(obj) for obj in object_list] return [self._as_row(obj) for obj in object_list]
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
form_class = ExpedienteMateriaForm
permission_required = permissoes_sessao()
def get_success_url(self): def get_success_url(self):
return reverse('sapl.sessao:expedientemateria_list', return reverse('sapl.sessao:expedientemateria_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView): class UpdateView(MasterDetailCrud.UpdateView):
form_class = ExpedienteMateriaForm
permission_required = permissoes_sessao()
def get_initial(self): def get_initial(self):
self.initial['tipo_materia'] = self.object.materia.tipo.id self.initial['tipo_materia'] = self.object.materia.tipo.id
@ -388,9 +330,6 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
self.initial['ano_materia'] = self.object.materia.ano self.initial['ano_materia'] = self.object.materia.ano
return self.initial return self.initial
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_sessao()
class DetailView(MasterDetailCrud.DetailView): class DetailView(MasterDetailCrud.DetailView):
@property @property
@ -402,57 +341,31 @@ class OradorCrud(MasterDetailCrud):
model = '' model = ''
parent_field = 'sessao_plenaria' parent_field = 'sessao_plenaria'
help_path = '' help_path = ''
public = [RP_LIST, RP_DETAIL]
class ListView(MasterDetailCrud.ListView): class ListView(MasterDetailCrud.ListView):
ordering = ['numero_ordem', 'parlamentar'] ordering = ['numero_ordem', 'parlamentar']
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
permission_required = permissoes_sessao()
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_sessao()
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_sessao()
class OradorExpedienteCrud(OradorCrud): class OradorExpedienteCrud(OradorCrud):
model = OradorExpediente model = OradorExpediente
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
permission_required = permissoes_sessao()
form_class = OradorExpedienteForm
def get_success_url(self): def get_success_url(self):
return reverse('sapl.sessao:oradorexpediente_list', return reverse('sapl.sessao:oradorexpediente_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_sessao()
form_class = OradorExpedienteForm
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_sessao()
class OradorCrud(OradorCrud): class OradorCrud(OradorCrud):
model = Orador model = Orador
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView): class CreateView(MasterDetailCrud.CreateView):
permission_required = permissoes_sessao()
form_class = OradorForm
def get_success_url(self): def get_success_url(self):
return reverse('sapl.sessao:orador_list', return reverse('sapl.sessao:orador_list',
kwargs={'pk': self.kwargs['pk']}) kwargs={'pk': self.kwargs['pk']})
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
permission_required = permissoes_sessao()
form_class = OradorForm
class DeleteView(PermissionRequiredMixin, MasterDetailCrud.DeleteView):
permission_required = permissoes_sessao()
def recuperar_numero_sessao(request): def recuperar_numero_sessao(request):
try: try:
@ -469,22 +382,19 @@ def recuperar_numero_sessao(request):
class SessaoCrud(Crud): class SessaoCrud(Crud):
model = SessaoPlenaria model = SessaoPlenaria
help_path = 'sessao_plenaria' help_path = 'sessao_plenaria'
public = [RP_DETAIL]
class BaseMixin(CrudBaseMixin): class BaseMixin(Crud.BaseMixin):
list_field_names = ['data_inicio', 'legislatura', 'sessao_legislativa', list_field_names = ['data_inicio', 'legislatura', 'sessao_legislativa',
'tipo'] 'tipo']
# FIXME!!!! corrigir referencias no codigo e remover isso!!!!! class CrudDetailView(DetailView):
# fazer com #230
class CrudDetailView(CrudDetailView):
model = SessaoPlenaria model = SessaoPlenaria
help_path = 'sessao_plenaria'
class ListView(CrudListView): class ListView(Crud.ListView):
ordering = ['-data_inicio'] ordering = ['-data_inicio']
class CreateView(PermissionRequiredMixin, CrudCreateView): class CreateView(Crud.CreateView):
permission_required = permissoes_sessao()
def get_initial(self): def get_initial(self):
legislatura = Legislatura.objects.order_by('-numero')[0] legislatura = Legislatura.objects.order_by('-numero')[0]
@ -493,12 +403,6 @@ class SessaoCrud(Crud):
return {'legislatura': legislatura, return {'legislatura': legislatura,
'sessao_legislativa': sessao_legislativa} 'sessao_legislativa': sessao_legislativa}
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
permission_required = permissoes_sessao()
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_sessao()
class PresencaMixin: class PresencaMixin:
@ -531,18 +435,24 @@ class PresencaMixin:
yield (parlamentar, False) yield (parlamentar, False)
class PresencaView(FormMixin, class PresencaView(FormMixin, PresencaMixin, DetailView):
PresencaMixin,
SessaoCrud.CrudDetailView):
template_name = 'sessao/presenca.html' template_name = 'sessao/presenca.html'
form_class = PresencaForm form_class = PresencaForm
model = SessaoPlenaria model = SessaoPlenaria
@method_decorator(permission_required((
'%s.add_%s' % (
AppConfig.label, SessaoPlenariaPresenca._meta.model_name),
'%s.change_%s' % (
AppConfig.label, SessaoPlenariaPresenca._meta.model_name),
'%s.delete_%s' % (
AppConfig.label, SessaoPlenariaPresenca._meta.model_name),
)))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
form = self.get_form() form = self.get_form()
if not self.request.user.has_perms(permissoes_sessao()): if not self.request.user.has_module_perms(AppConfig.label):
return self.form_invalid(form) return self.form_invalid(form)
if form.is_valid(): if form.is_valid():
@ -582,12 +492,16 @@ class PainelView(PermissionRequiredMixin, TemplateView):
permission_required = permissoes_painel() permission_required = permissoes_painel()
class PresencaOrdemDiaView(FormMixin, class PresencaOrdemDiaView(FormMixin, PresencaMixin, DetailView):
PresencaMixin,
SessaoCrud.CrudDetailView):
template_name = 'sessao/presenca_ordemdia.html' template_name = 'sessao/presenca_ordemdia.html'
form_class = PresencaForm form_class = PresencaForm
model = SessaoPlenaria
@method_decorator(permission_required((
'%s.add_%s' % (AppConfig.label, PresencaOrdemDia._meta.model_name),
'%s.change_%s' % (AppConfig.label, PresencaOrdemDia._meta.model_name),
'%s.delete_%s' % (AppConfig.label, PresencaOrdemDia._meta.model_name),
)))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
@ -630,9 +544,10 @@ class PresencaOrdemDiaView(FormMixin,
return reverse('sapl.sessao:presencaordemdia', kwargs={'pk': pk}) return reverse('sapl.sessao:presencaordemdia', kwargs={'pk': pk})
class ListMateriaOrdemDiaView(FormMixin, SessaoCrud.CrudDetailView): class ListMateriaOrdemDiaView(FormMixin, DetailView):
template_name = 'sessao/materia_ordemdia_list.html' template_name = 'sessao/materia_ordemdia_list.html'
form_class = ListMateriaForm form_class = ListMateriaForm
model = SessaoPlenaria
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
@ -669,6 +584,11 @@ class ListMateriaOrdemDiaView(FormMixin, SessaoCrud.CrudDetailView):
return self.render_to_response(context) return self.render_to_response(context)
@method_decorator(permission_required((
'%s.add_%s' % (AppConfig.label, OrdemDia._meta.model_name),
'%s.change_%s' % (AppConfig.label, OrdemDia._meta.model_name),
'%s.delete_%s' % (AppConfig.label, OrdemDia._meta.model_name),
)))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
context = self.get_context_data(object=self.object) context = self.get_context_data(object=self.object)
@ -733,12 +653,13 @@ class ListMateriaOrdemDiaView(FormMixin, SessaoCrud.CrudDetailView):
return self.get(self, request, args, kwargs) return self.get(self, request, args, kwargs)
class MesaView(PermissionRequiredMixin, FormMixin, SessaoCrud.CrudDetailView): class MesaView(FormMixin, DetailView):
template_name = 'sessao/mesa.html' template_name = 'sessao/mesa.html'
form_class = MesaForm form_class = MesaForm
permission_required = permissoes_sessao() model = SessaoPlenaria
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
context = self.get_context_data(object=self.object) context = self.get_context_data(object=self.object)
@ -758,6 +679,11 @@ class MesaView(PermissionRequiredMixin, FormMixin, SessaoCrud.CrudDetailView):
return self.render_to_response(context) return self.render_to_response(context)
@method_decorator(permission_required((
'%s.add_integrantemesa' % AppConfig.label,
'%s.change_integrantemesa' % AppConfig.label,
'%s.delete_integrantemesa' % AppConfig.label,
)))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
self.object = self.get_object() self.object = self.get_object()
form = MesaForm(request.POST) form = MesaForm(request.POST)

12
sapl/static/styles/app.scss

@ -70,6 +70,13 @@ h6, .h6 {
color: inherit; color: inherit;
} }
.caret {
/* Por padrão caret aponta para baixo*/
&.top {
transform: rotate(180deg);
}
}
// #### CRUD DETAIL ######################################## // #### CRUD DETAIL ########################################
p.control-label { p.control-label {
font-weight: bold; font-weight: bold;
@ -147,6 +154,11 @@ fieldset {
} }
} }
.avatar-parlamentar {
height: 42px;
width: 42px;
}
/* INDEX */ /* INDEX */
#conteudo { #conteudo {
position: relative; position: relative;

4
sapl/templates/base.html

@ -103,11 +103,11 @@
<!-- <li class="nav__sub-item"><a class="nav__sub-link" href="#">Índice de Assuntos</a></li> --> <!-- <li class="nav__sub-item"><a class="nav__sub-link" href="#">Índice de Assuntos</a></li> -->
</ul> </ul>
</li> </li>
{% if user|ver_menu_sistema_perm %} {% if perms.base.menu_sistemas %}
<li class="dropdown"> <li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Sistema <span class="caret"></span></a> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Sistema <span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li class="nav__sub-item"><a class="nav__sub-link" href="/sistema">Tabelas Auxiliares</a></li> {% if perms.base.view_tabelas_auxiliares %}<li class="nav__sub-item"><a class="nav__sub-link" href="/sistema">Tabelas Auxiliares</a></li>{%endif%}
<!-- <li class="nav__sub-item"><a class="nav__sub-link" href="#">Provedor LexML</a></li> <!-- <li class="nav__sub-item"><a class="nav__sub-link" href="#">Provedor LexML</a></li>
<li class="nav__sub-item"><a class="nav__sub-link" href="#">Publicador LexML</a></li> <li class="nav__sub-item"><a class="nav__sub-link" href="#">Publicador LexML</a></li>
<li class="nav__sub-item"><a class="nav__sub-link" href="#">Gerenciar Usuários</a></li> <li class="nav__sub-item"><a class="nav__sub-link" href="#">Gerenciar Usuários</a></li>

2
sapl/templates/crud/ajax_form.html

@ -0,0 +1,2 @@
{% load i18n crispy_forms_tags %}
{% crispy form %}

3
sapl/templates/crud/confirm_delete.html

@ -3,13 +3,12 @@
{% block base_content %} {% block base_content %}
<form action="" method="post">{% csrf_token %} <form action="" method="post">{% csrf_token %}
<br>
<div class="panel panel-danger"> <div class="panel panel-danger">
<div class="panel-heading text-center"> <div class="panel-heading text-center">
{% block msg %}
{% blocktrans %} {% blocktrans %}
Confirma exclusão de "{{ object }}"? Confirma exclusão de "{{ object }}"?
{% endblocktrans %} {% endblocktrans %}
{% endblock msg %}
</div> </div>
<div class="panel-body text-center"> <div class="panel-body text-center">
<a href="{{ view.cancel_url }}" class="btn btn-inverse">{% trans 'Cancelar' %}</a> <a href="{{ view.cancel_url }}" class="btn btn-inverse">{% trans 'Cancelar' %}</a>

64
sapl/templates/crud/detail.html

@ -1,23 +1,33 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n common_tags%}
{% load common_tags %}
{% block base_content %} {% block base_content %}
<div class="clearfix"> <div class="context-actions clearfix">
{% block actions %} {% block actions %}
<div class="actions btn-group btn-group-sm" role="group">
{% if view.list_url %}
<a href="{{ view.list_url }}" class="btn btn-default">{% trans 'Listar' %} {{view.verbose_name_plural}}</a>
{% endif %}
{% if view.create_url %}
<a href="{{ view.create_url }}" class="btn btn-default">
{% blocktrans with verbose_name=view.verbose_name %} Adicionar {{ verbose_name }} {% endblocktrans %}
</a>
{% endif %}
</div>
{% if view.update_url or view.delete_url %}
<div class="actions btn-group pull-right" role="group"> <div class="actions btn-group pull-right" role="group">
{% if perms|get_change_perm:view %} {% if view.update_url %}
<a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Editar' %}</a> <a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Editar' %}</a>
{% endif %} {% endif %}
{% if view.delete_url %}
{% if perms|get_delete_perm:view %} <a href="{{ view.delete_url }}" class="btn btn-danger">{% trans 'Excluir' %}</a>
<a href="{{ view.delete_url }}" class="btn btn-default">{% trans 'Excluir' %}</a>
{% endif %} {% endif %}
</div> </div>
{% endif %}
{% endblock actions %} {% endblock actions %}
</div> </div>
{% block extra_msg %}{% endblock extra_msg %}
{% block detail_content %} {% block detail_content %}
{% for fieldset in view.layout_display %} {% for fieldset in view.layout_display %}
<h2 class="legend">{{ fieldset.legend }}</h2> <h2 class="legend">{{ fieldset.legend }}</h2>
@ -28,11 +38,7 @@
<div id="div_id_{{ column.id }}" class="form-group"> <div id="div_id_{{ column.id }}" class="form-group">
<p class="control-label">{{ column.verbose_name }}</p> <p class="control-label">{{ column.verbose_name }}</p>
<div class="controls"> <div class="controls">
{% if column.text %} <div class="form-control-static">{{ column.text|safe }}</div>
<p class="form-control-static">{{ column.text|safe }}</p>
{% else %}
<p class="form-control-static">Não informado</p>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
@ -42,4 +48,36 @@
{% endfor %} {% endfor %}
{% endblock detail_content %} {% endblock detail_content %}
<div class="container-table">
{% if not rows %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<div class="result-count">{% blocktrans with verbose_name_plural=view.model_set_verbose_name_plural %}Total de {{ verbose_name_plural }}: <strong>{{count}}</strong>{% endblocktrans %}</div>
<table class="table table-striped table-hover">
<thead>
<tr>
{% for name in headers %}
<th>{{ name }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for value_list in rows %}
<tr>
{% for value, href in value_list %}
<td>
{% if href %}
<a href="{{ href }}">{{ value }}</a>
{% elif value != 'core.Cep.None' %}
{{ value|safe }}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
{% include "paginacao.html" %}
{% endblock base_content %} {% endblock base_content %}

92
sapl/templates/crud/detail_detail.html

@ -0,0 +1,92 @@
{% extends "base.html" %}
{% load i18n common_tags%}
{% block base_content %}
<div class="context-actions clearfix">
{% block actions %}
<div class="actions btn-group btn-group-sm" role="group">
{% if view.detail_list_url %}
<a href="{{ view.detail_list_url }}" class="btn btn-default">{% trans 'Listar' %} {{view.verbose_name_plural}}</a>
{% endif %}
{% if view.detail_create_url %}
<a href="{{ view.detail_create_url }}" class="btn btn-default">
{% blocktrans with verbose_name=view.verbose_name %} Adicionar {{ verbose_name }} {% endblocktrans %}
</a>
{% endif %}
</div>
{% if view.update_url or view.delete_url %}
<div class="actions btn-group pull-right " role="group">
{% if view.update_url %}
<a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Editar' %}</a>
{% endif %}
{% if view.delete_url %}
<a href="{{ view.delete_url }}" class="btn btn-danger btn-excluir">{% trans 'Excluir' %}</a>
{% endif %}
</div>
{% endif %}
{% endblock actions %}
</div>
{% block detail_content %}
{% for fieldset in view.layout_display %}
<h2 class="legend">{{ fieldset.legend }}</h2>
{% for row in fieldset.rows %}
<div class="row-fluid">
{% for column in row %}
<div class="col-sm-{{ column.span }}">
<div id="div_id_{{ column.id }}" class="form-group">
<p class="control-label">{{ column.verbose_name }}</p>
<div class="controls">
<div class="form-control-static">{{ column.text|safe }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
{% endfor %}
{% endblock detail_content %}
<div class="actions btn-group pull-right btn-group-lg" role="group">
{% if view.detail_set_create_url %}
<a href="{{ view.detail_set_create_url }}" class="btn btn-default">
{% blocktrans with verbose_name=view.verbose_name_set %} Adicionar {{ verbose_name }} {% endblocktrans %}
</a>
{% endif %}
{% block more_buttons %}{% endblock more_buttons %}
</div>
<div class="container-table">
{% if not rows %}
<p>{{ NO_ENTRIES_MSG }}</p>
{% else %}
<div class="result-count">{% blocktrans with verbose_name_plural=view.verbose_name_plural %}Total de Registros: <strong>{{count}}</strong>{% endblocktrans %}</div>
<table class="table table-striped table-hover">
<thead>
<tr>
{% for name in headers %}
<th>{{ name }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for value_list in rows %}
<tr>
{% for value, href in value_list %}
<td>
{% if href %}
<a href="{{ href }}">{{ value }}</a>
{% elif valu != 'core.Cep.None' %}
{{ value|safe }}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
{% include "paginacao.html" %}
{% endblock base_content %}

2
sapl/templates/crud/form.html

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n crispy_forms_tags %} {% load i18n crispy_forms_tags %}
{% block base_content %} {% block base_content %}
{% block extra_msg %}{% endblock %}
{% crispy form %} {% crispy form %}
{% endblock %} {% endblock %}

44
sapl/templates/crud/list.html

@ -1,29 +1,54 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n common_tags crispy_forms_tags%}
{% load common_tags %}
{% block base_content %} {% block base_content %}
<div class="actions btn-group pull-right" role="group"> <div class="context-actions clearfix">
{% if perms|get_add_perm:view %}
<div class="actions search pull-left">
{% if form %}
{% crispy form %}
{% endif %}
</div>
{% block actions %}
<div class="actions btn-group pull-right btn-group-lg" role="group">
{% if view.create_url %}
<a href="{{ view.create_url }}" class="btn btn-default"> <a href="{{ view.create_url }}" class="btn btn-default">
{% blocktrans with verbose_name=view.verbose_name %} Adicionar {{ verbose_name }} {% endblocktrans %} {% blocktrans with verbose_name=view.verbose_name %} Adicionar {{ verbose_name }} {% endblocktrans %}
</a> </a>
{% endif %} {% endif %}
{% block more_buttons %}{% endblock more_buttons %} {% block more_buttons %}{% endblock more_buttons %}
</div> </div>
{% endblock actions %}
</div>
<br/><br/>
{% block extra_content %} {% endblock %} {% block extra_content %} {% endblock %}
{% if not rows %} {% if not rows %}
<p>{{ NO_ENTRIES_MSG }}</p> <p>{{ NO_ENTRIES_MSG }}</p>
{% else %} {% else %}
<table class="table table-striped table-hover"> <div class="container-table">
<div class="result-count">{% blocktrans with verbose_name_plural=view.verbose_name_plural %}Total de {{ verbose_name_plural }}: <strong>{{count}}</strong>{% endblocktrans %}</div>
<table class="table table-striped table-hover table-link-ordering">
<thead> <thead>
<tr> <tr>
{% for name in headers %} {% for name in headers %}
<th>{{ name }}</th> <th>
{% if view.ordered_list %}
<a title="{% trans 'Clique para alterar a ordem a listagem'%}" href="?o={% if 'o' not in request.GET and forloop.counter == 1 or 'o' in request.GET and forloop.counter|safe == request.GET.o %}-{%endif%}{{forloop.counter}}{{ordering_url}}">
{{ name }}
{% if 'o' in request.GET or not view.ordering %}
{% if 'o' not in request.GET and forloop.counter == 1 or 'o' in request.GET and forloop.counter|safe == request.GET.o %}
<span class="caret top" title="{% trans 'Listado na Ordem Ascendente'%}"></span>
{% elif 'o' in request.GET and forloop.counter == request.GET.o|str2intabs %}
<span class="caret" title="{% trans 'Listado na Ordem Descendente'%}"></span>
{%endif%}
{%endif%}
</a>
{% else %}
{{ name }}
{% endif %}
</th>
{% endfor %} {% endfor %}
</tr> </tr>
</thead> </thead>
@ -33,8 +58,8 @@
{% for value, href in value_list %} {% for value, href in value_list %}
<td> <td>
{% if href %} {% if href %}
<a href="{{ href }}">{{ value }}</a> <a href="{{ href }}">{{ value|safe }}</a>
{% else %} {% elif valu != 'core.Cep.None' %}
{{ value|safe }} {{ value|safe }}
{% endif %} {% endif %}
</td> </td>
@ -43,6 +68,7 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div>
{% endif %} {% endif %}
{% include "paginacao.html" %} {% include "paginacao.html" %}

10
sapl/templates/parlamentares/coligacao_detail.html

@ -1,10 +0,0 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block actions %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'sapl.parlamentares:composicaocoligacao_list' object.pk %}" class="btn btn-default">{% trans 'Ver Composição' %}</a>
<a href="{{ view.update_url }}" class="btn btn-default">{% trans 'Editar' %}</a>
<a href="{{ view.delete_url }}" class="btn btn-default">{% trans 'Excluir' %}</a>
</div>
{% endblock actions %}

4
sapl/templates/mesa_diretora/mesa_diretora.html → sapl/templates/parlamentares/composicaomesa_form.html

@ -48,13 +48,13 @@
<div class="col-md-4" align="center"> <div class="col-md-4" align="center">
<br /><br /> <br /><br />
{% if cargos_vagos %} {% if cargos_vagos %}
{% if perms.parlamentares.add_cargomesa or perms.parlamentares.add_composicaomesa %} {% if perms.parlamentares.add_cargomesa %}
<input type="submit" name="Incluir" Value="Incluir" class="btn btn-primary" /> <input type="submit" name="Incluir" Value="Incluir" class="btn btn-primary" />
{% endif %} {% endif %}
{% endif %} {% endif %}
<br /> <br />
<br /> <br />
{% if perms.parlamentares.add_cargomesa or perms.parlamentares.add_composicaomesa %} {% if perms.parlamentares.add_composicaomesa %}
<input type="submit" name="Excluir" Value="Excluir" class="btn btn-danger" /> <input type="submit" name="Excluir" Value="Excluir" class="btn btn-danger" />
{% endif %} {% endif %}
</div> </div>

21
sapl/templates/parlamentares/frentes.html

@ -1,21 +0,0 @@
{% extends "crud/list.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block base_content %}
{% if object_list|length == 0 %}
<p>Nenhuma frente encontrada.</p>
{% else %}
<table class="table table-striped table-hover">
<thead>
<tr><th>Frentes</th></tr>
</thead>
<tbody>
{% for frente in object_list %}
<tr><td><a href="{% url 'sapl.parlamentares:frente_detail' frente.pk %}">{{ frente.nome }}</a></td></tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% include "paginacao.html" %}
{% endblock %}

8
sapl/templates/parlamentares/subnav.yaml

@ -8,10 +8,10 @@
- title: {% trans 'Dependentes' %} - title: {% trans 'Dependentes' %}
url: dependente_list url: dependente_list
- title: {% trans 'Comissões' %} - title: {% trans 'Comissões' %}
url: participacao_list url: participacao_parlamentar_list
- title: {% trans 'Proposições' %} - title: {% trans 'Proposições' %}
url: proposicao_list url: proposicao_parlamentar_list
- title: {% trans 'Relatorias' %} - title: {% trans 'Relatorias' %}
url: relatoria_list url: relatoria_parlamentar_list
- title: {% trans 'Frentes' %} - title: {% trans 'Frentes' %}
url: frent_list url: frente_parlamentar_list

5
sapl/templates/parlamentares/subnav_coligacao.yaml

@ -0,0 +1,5 @@
{% load i18n %}
- title: {% trans 'Início' %}
url: coligacao_detail
- title: {% trans 'Composição da Coligação' %}
url: composicaocoligacao_list

2
sapl/templates/sessao/mesa.html

@ -20,10 +20,12 @@
</div> </div>
<div class="col-md-4" align="center"> <div class="col-md-4" align="center">
{% if perms.sessao %}
<br /><br /> <br /><br />
{% if view.get_cargos_mesa %}<input type="submit" name="Incluir" Value="Incluir" class="btn btn-primary" />{% endif %} {% if view.get_cargos_mesa %}<input type="submit" name="Incluir" Value="Incluir" class="btn btn-primary" />{% endif %}
<br /><br /> <br /><br />
<input type="submit" name="Excluir" Value="Excluir" class="btn btn-danger" /> <input type="submit" name="Excluir" Value="Excluir" class="btn btn-danger" />
{% endif %}
</div> </div>
{% if view.get_cargos_mesa %} {% if view.get_cargos_mesa %}
<div class="col-md-4"> <div class="col-md-4">

6
sapl/utils.py

@ -1,6 +1,7 @@
import hashlib import hashlib
from datetime import date from datetime import date
from functools import wraps from functools import wraps
from unicodedata import normalize as unicodedata_normalize
import magic import magic
from django import forms from django import forms
@ -14,6 +15,11 @@ from django.utils.translation import ugettext_lazy as _
from floppyforms import ClearableFileInput from floppyforms import ClearableFileInput
def normalize(txt):
return unicodedata_normalize(
'NFKD', txt).encode('ASCII', 'ignore').decode('ASCII')
def get_settings_auth_user_model(): def get_settings_auth_user_model():
return getattr(settings, 'AUTH_USER_MODEL', 'auth.User') return getattr(settings, 'AUTH_USER_MODEL', 'auth.User')

59
scripts/inicializa_grupos_autorizacoes.py

@ -1,25 +1,34 @@
from django.apps import apps import os
from django.contrib.auth import get_user_model import django
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
def cria_ou_reseta_grupo(nome): os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings")
django.setup()
if True:
from django.apps import apps
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
class InicializaGruposAutorizacoes():
def cria_ou_reseta_grupo(self, nome):
grupo = Group.objects.get_or_create(name=nome)[0] grupo = Group.objects.get_or_create(name=nome)[0]
for p in list(grupo.permissions.all()): for p in list(grupo.permissions.all()):
grupo.permissions.remove(p) grupo.permissions.remove(p)
return grupo return grupo
def cria_usuario(self, nome, grupo):
def cria_usuario(nome, grupo):
nome_usuario = nome nome_usuario = nome
usuario = get_user_model().objects.get_or_create(username=nome_usuario)[0] usuario = get_user_model().objects.get_or_create(
username=nome_usuario)[0]
usuario.set_password('interlegis') usuario.set_password('interlegis')
usuario.save() usuario.save()
grupo.user_set.add(usuario) grupo.user_set.add(usuario)
def cria_grupos_permissoes(self):
def cria_grupos_permissoes():
nomes_apps = ['base', 'parlamentares', 'comissoes', nomes_apps = ['base', 'parlamentares', 'comissoes',
'materia', 'norma', 'sessao', 'painel'] 'materia', 'norma', 'sessao', 'painel']
@ -35,12 +44,12 @@ def cria_grupos_permissoes():
permissoes['documento_administrativo'] = list( permissoes['documento_administrativo'] = list(
Permission.objects.filter(content_type__in=cts)) Permission.objects.filter(content_type__in=cts))
nome_grupo = 'Operador Administrativo' nome_grupo = 'Operador Administrativo'
grupo = cria_ou_reseta_grupo(nome_grupo) grupo = self.cria_ou_reseta_grupo(nome_grupo)
for p in permissoes['documento_administrativo']: for p in permissoes['documento_administrativo']:
grupo.permissions.add(p) grupo.permissions.add(p)
nome_usuario = 'operador_administrativo' nome_usuario = 'operador_administrativo'
cria_usuario(nome_usuario, grupo) self.cria_usuario(nome_usuario, grupo)
# prolocolo administrativo # prolocolo administrativo
cts = cts.exclude(model__icontains='tramitacao').exclude( cts = cts.exclude(model__icontains='tramitacao').exclude(
@ -48,12 +57,12 @@ def cria_grupos_permissoes():
permissoes['protocoloadm'] = list( permissoes['protocoloadm'] = list(
Permission.objects.filter(content_type__in=cts)) Permission.objects.filter(content_type__in=cts))
nome_grupo = 'Operador de Protocolo Administrativo' nome_grupo = 'Operador de Protocolo Administrativo'
grupo = cria_ou_reseta_grupo(nome_grupo) grupo = self.cria_ou_reseta_grupo(nome_grupo)
for p in permissoes['protocoloadm']: for p in permissoes['protocoloadm']:
grupo.permissions.add(p) grupo.permissions.add(p)
nome_usuario = 'operador_protocoloadm' nome_usuario = 'operador_protocoloadm'
cria_usuario(nome_usuario, grupo) self.cria_usuario(nome_usuario, grupo)
# permissoes do base # permissoes do base
cts = ContentType.objects.filter(app_label='base') cts = ContentType.objects.filter(app_label='base')
@ -68,7 +77,7 @@ def cria_grupos_permissoes():
# Cria Grupo # Cria Grupo
nome_grupo = 'Operador de %s' % apps.get_app_config( nome_grupo = 'Operador de %s' % apps.get_app_config(
nome_app).verbose_name nome_app).verbose_name
grupo = cria_ou_reseta_grupo(nome_grupo) grupo = self.cria_ou_reseta_grupo(nome_grupo)
# Elimina o acesso a proposicoes pelo Operador de Matérias # Elimina o acesso a proposicoes pelo Operador de Matérias
if nome_app == 'materia': if nome_app == 'materia':
@ -90,28 +99,34 @@ def cria_grupos_permissoes():
grupo.user_set.add(usuario) grupo.user_set.add(usuario)
# Operador Geral # Operador Geral
grupo_geral = cria_ou_reseta_grupo('Operador Geral') grupo_geral = self.cria_ou_reseta_grupo('Operador Geral')
for lista in permissoes.values(): for lista in permissoes.values():
for p in lista: for p in lista:
grupo_geral.permissions.add(p) grupo_geral.permissions.add(p)
nome_usuario = 'operador_geral' nome_usuario = 'operador_geral'
cria_usuario(nome_usuario, grupo_geral) self.cria_usuario(nome_usuario, grupo_geral)
# Autor # Autor
perms_autor = [] perms_autor = []
perms_autor.append(Permission.objects.get(name='Can add Proposição')) perms_autor.append(Permission.objects.get(name='Can add Proposição'))
perms_autor.append(Permission.objects.get(name='Can change Proposição')) perms_autor.append(
perms_autor.append(Permission.objects.get(name='Can delete Proposição')) Permission.objects.get(name='Can change Proposição'))
perms_autor.append(
Permission.objects.get(name='Can delete Proposição'))
# Configura Permissoes Autor # Configura Permissoes Autor
grupo = cria_ou_reseta_grupo('Autor') grupo = self.cria_ou_reseta_grupo('Autor')
for p in perms_autor: for p in perms_autor:
grupo.permissions.add(p) grupo.permissions.add(p)
nome_usuario = 'operador_autor' nome_usuario = 'operador_autor'
cria_usuario(nome_usuario, grupo) self.cria_usuario(nome_usuario, grupo)
def __call__(self):
self.cria_grupos_permissoes()
cria_grupos_permissoes = InicializaGruposAutorizacoes()
if __name__ == '__main__': if __name__ == '__main__':
cria_grupos_permissoes() cria_grupos_permissoes.cria_grupos_permissoes()

3
scripts/test_inicializa_grupos_autorizacoes.py

@ -1,10 +1,11 @@
import pytest
from django.apps import apps from django.apps import apps
from django.contrib.auth.models import Group, Permission from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
import pytest
from inicializa_grupos_autorizacoes import cria_grupos_permissoes from inicializa_grupos_autorizacoes import cria_grupos_permissoes
pytestmark = pytest.mark.django_db pytestmark = pytest.mark.django_db
apps_com_permissao_padrao = [ apps_com_permissao_padrao = [

Loading…
Cancel
Save