Browse Source

Merge branch '504-autorizacao-autor-proposicao' of github.com:interlegis/sapl into 103-autorizacao-final

pull/529/head
Eduardo Edson Batista Cordeiro Alves 8 years ago
parent
commit
f27cd1843f
  1. 9
      sapl/base/templatetags/common_tags.py
  2. 2
      sapl/base/urls.py
  3. 109
      sapl/materia/forms.py
  4. 37
      sapl/materia/migrations/0039_auto_20160628_1251.py
  5. 24
      sapl/materia/models.py
  6. 43
      sapl/materia/tests/test_materia.py
  7. 9
      sapl/materia/urls.py
  8. 123
      sapl/materia/views.py
  9. 6
      sapl/parlamentares/forms.py
  10. 22
      sapl/parlamentares/migrations/0022_auto_20160624_1124.py
  11. 21
      sapl/parlamentares/migrations/0023_auto_20160628_1247.py
  12. 6
      sapl/parlamentares/migrations/0024_merge.py
  13. 87
      sapl/protocoloadm/forms.py
  14. 114
      sapl/protocoloadm/migrations/0001_initial.py
  15. 59
      sapl/protocoloadm/migrations/0002_auto_20150729_1717.py
  16. 22
      sapl/protocoloadm/migrations/0003_documentoacessorioadministrativo_texto_integral.py
  17. 27
      sapl/protocoloadm/migrations/0004_auto_20151007_1035.py
  18. 22
      sapl/protocoloadm/migrations/0005_auto_20151008_0744.py
  19. 74
      sapl/protocoloadm/migrations/0006_auto_20160216_1015.py
  20. 19
      sapl/protocoloadm/migrations/0007_auto_20160218_1429.py
  21. 20
      sapl/protocoloadm/migrations/0008_auto_20160308_1436.py
  22. 20
      sapl/protocoloadm/migrations/0009_auto_20160309_1323.py
  23. 25
      sapl/protocoloadm/migrations/0010_auto_20160309_1407.py
  24. 20
      sapl/protocoloadm/migrations/0011_auto_20160318_1504.py
  25. 26
      sapl/protocoloadm/migrations/0012_auto_20160503_0926.py
  26. 26
      sapl/protocoloadm/migrations/0012_tipoinstituicao.py
  27. 7
      sapl/protocoloadm/models.py
  28. 22
      sapl/protocoloadm/urls.py
  29. 122
      sapl/protocoloadm/views.py
  30. 1
      sapl/settings.py
  31. 10
      sapl/templates/base.html
  32. 7
      sapl/templates/confirma_email.html
  33. 12
      sapl/templates/materia/layouts.yaml
  34. 4
      sapl/templates/materia/materialegislativa_filter.html
  35. 9
      sapl/templates/protocoloadm/documentoadministrativo_detail.html
  36. 26
      sapl/templates/protocoloadm/documentoadministrativo_filter.html
  37. 6
      sapl/templates/protocoloadm/protocolo_filter.html
  38. 9
      sapl/templates/protocoloadm/protocolo_pesquisa.html
  39. 6
      sapl/templates/protocoloadm/protocoloadm_detail.html
  40. 40
      sapl/templates/protocoloadm/tramitacao.html
  41. 15
      sapl/templates/protocoloadm/tramitacao_edit.html
  42. 14
      sapl/templates/protocoloadm/tramitacao_incluir.html
  43. 9
      sapl/templates/protocoloadm/tramitacaoadministrativo_detail.html
  44. 9
      sapl/utils.py

9
sapl/base/templatetags/common_tags.py

@ -45,7 +45,10 @@ def get_add_perm(value, arg):
perm = value
view = arg
try:
nome_app = view.__class__.model._meta.app_label
except AttributeError:
return None
nome_model = view.__class__.model.__name__.lower()
can_add = '.add_' + nome_model
@ -57,7 +60,10 @@ def get_change_perm(value, arg):
perm = value
view = arg
try:
nome_app = view.__class__.model._meta.app_label
except AttributeError:
return None
nome_model = view.__class__.model.__name__.lower()
can_change = '.change_' + nome_model
@ -69,7 +75,10 @@ def get_delete_perm(value, arg):
perm = value
view = arg
try:
nome_app = view.__class__.model._meta.app_label
except AttributeError:
return None
nome_model = view.__class__.model.__name__.lower()
can_delete = '.delete_' + nome_model

2
sapl/base/urls.py

@ -20,5 +20,5 @@ urlpatterns = [
url(r'^login/$', views.login, {
'template_name': 'base/login.html', 'authentication_form': LoginForm},
name='login'),
url(r'^logout/$', views.logout, {'next_page': '/login'}, name='logout')
url(r'^logout/$', views.logout, {'next_page': '/login'}, name='logout'),
]

109
sapl/materia/forms.py

@ -4,8 +4,10 @@ import django_filters
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout
from django import forms
from django.contrib.auth.models import Group, User
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import models
from django.db import models, transaction
from django.db.models import Max
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
@ -98,7 +100,8 @@ class ProposicaoForm(ModelForm):
class Meta:
model = Proposicao
fields = ['tipo', 'data_envio', 'descricao', 'texto_original']
fields = ['tipo', 'data_envio', 'descricao', 'texto_original', 'autor']
widgets = {'autor': forms.HiddenInput()}
class AcompanhamentoMateriaForm(ModelForm):
@ -542,3 +545,105 @@ class AutoriaForm(ModelForm):
raise ValidationError(msg)
return self.cleaned_data
class AutorForm(ModelForm):
senha = forms.CharField(
max_length=20,
label=_('Senha'),
required=True,
widget=forms.PasswordInput())
senha_confirma = forms.CharField(
max_length=20,
label=_('Confirmar Senha'),
required=True,
widget=forms.PasswordInput())
confirma_email = forms.EmailField(
required=True,
label=_('Confirmar Email'))
class Meta:
model = Autor
fields = ['username',
'senha',
'email',
'nome',
'tipo',
'cargo',
'parlamentar',
'comissao']
def valida_igualdade(self, texto1, texto2, msg):
if texto1 != texto2:
raise ValidationError(msg)
return True
def valida_email_existente(self):
return User.objects.filter(
email=self.cleaned_data['email']).exists()
def usuario_existente(self):
return User.objects.filter(
username=self.cleaned_data['username']).exists()
def clean(self):
if ('senha' not in self.cleaned_data or
'senha_confirma' not in self.cleaned_data):
raise ValidationError(_('Favor informar as senhas'))
msg = _('As senhas não conferem.')
self.valida_igualdade(
self.cleaned_data['senha'],
self.cleaned_data['senha_confirma'],
msg)
if ('email' not in self.cleaned_data or
'confirma_email' not in self.cleaned_data):
raise ValidationError(_('Favor informar endereços de email'))
msg = _('Os emails não conferem.')
self.valida_igualdade(
self.cleaned_data['email'],
self.cleaned_data['confirma_email'],
msg)
email_existente = self.valida_email_existente()
if email_existente:
msg = _('Este email já foi cadastrado.')
raise ValidationError(msg)
if self.usuario_existente():
msg = _('Este nome de usuario já foi cadastrado.')
raise ValidationError(msg)
try:
validate_password(self.cleaned_data['senha'])
except ValidationError as error:
raise ValidationError(error)
return self.cleaned_data
@transaction.atomic
def save(self, commit=False):
autor = super(AutorForm, self).save(commit)
u = User.objects.get_or_create(
username=autor.username,
email=autor.email)
u = u[0]
u.set_password(self.cleaned_data['senha'])
u.is_active = False
u.save()
autor.user = u
autor.save()
grupo = Group.objects.filter(name='Autor')[0]
u.groups.add(grupo)
return autor

37
sapl/materia/migrations/0039_auto_20160628_1251.py

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-06-28 15:51
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import sapl.materia.models
class Migration(migrations.Migration):
dependencies = [
('auth', '0007_alter_validators_add_error_messages'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('materia', '0038_auto_20160612_1506'),
]
operations = [
migrations.AddField(
model_name='autor',
name='email',
field=models.EmailField(default=' ', max_length=254, verbose_name='Email'),
preserve_default=False,
),
migrations.AddField(
model_name='autor',
name='grupo_usuario',
field=models.ForeignKey(default=sapl.materia.models.grupo_autor, on_delete=django.db.models.deletion.CASCADE, to='auth.Group'),
),
migrations.AddField(
model_name='autor',
name='user',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
]

24
sapl/materia/models.py

@ -1,3 +1,4 @@
from django.contrib.auth.models import Group, User
from django.db import models
from django.utils.translation import ugettext_lazy as _
from model_utils import Choices
@ -8,6 +9,14 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES,
restringe_tipos_de_arquivo_txt, xstr)
def grupo_autor():
try:
grupo = Group.objects.get(name='Autor')
except Group.DoesNotExist:
return None
return grupo.id
class TipoMateriaLegislativa(models.Model):
sigla = models.CharField(max_length=5, verbose_name=_('Sigla'))
descricao = models.CharField(max_length=50, verbose_name=_('Descrição '))
@ -199,6 +208,7 @@ class TipoAutor(models.Model):
class Autor(models.Model):
user = models.ForeignKey(User)
partido = models.ForeignKey(Partido, blank=True, null=True)
comissao = models.ForeignKey(Comissao, blank=True, null=True)
parlamentar = models.ForeignKey(Parlamentar, blank=True, null=True)
@ -206,18 +216,24 @@ class Autor(models.Model):
nome = models.CharField(
max_length=50, blank=True, verbose_name=_('Autor'))
cargo = models.CharField(max_length=50, blank=True)
username = models.CharField(max_length=50, blank=True)
username = models.CharField(
max_length=50,
blank=True,
verbose_name=_('Nome de Usuário'))
email = models.EmailField(
verbose_name=_('Email'))
grupo_usuario = models.ForeignKey(Group, default=grupo_autor)
class Meta:
verbose_name = _('Autor')
verbose_name_plural = _('Autores')
def __str__(self):
if str(self.tipo) == 'Parlamentar':
if str(self.tipo) == 'Parlamentar' and self.parlamentar:
return self.parlamentar.nome_parlamentar
elif str(self.tipo) == 'Comissao':
elif str(self.tipo) == 'Comissao' and self.comissao:
return str(self.comissao)
elif str(self.tipo) == 'Partido':
elif str(self.tipo) == 'Partido' and self.partido:
return str(self.partido)
else:
if str(self.cargo):

43
sapl/materia/tests/test_materia.py

@ -1,7 +1,9 @@
import pytest
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from model_mommy import mommy
from model_mommy import mommy
from sapl.comissoes.models import Comissao, TipoComissao
from sapl.materia.models import (Anexada, Autor, Autoria, DespachoInicial,
DocumentoAcessorio, MateriaLegislativa,
@ -118,12 +120,15 @@ def test_materia_anexada_submit(admin_client):
@pytest.mark.django_db(transaction=False)
def test_autoria_submit(admin_client):
materia_principal = make_materia_principal()
# Cria um tipo de Autor
tipo_autor = mommy.make(TipoAutor, descricao='Teste Tipo_Autor')
# Cria um Autor
autor = mommy.make(Autor, tipo=tipo_autor, nome='Autor Teste')
autor = mommy.make(
Autor,
tipo=tipo_autor,
nome='Autor Teste',
grupo_usuario_id=8)
# Testa POST
response = admin_client.post(reverse('sapl.materia:autoria_create',
@ -200,7 +205,11 @@ def test_documento_acessorio_submit(admin_client):
tipo_autor = mommy.make(TipoAutor, descricao='Teste Tipo_Autor')
# Cria um Autor
autor = mommy.make(Autor, tipo=tipo_autor, nome='Autor Teste')
autor = mommy.make(
Autor,
tipo=tipo_autor,
nome='Autor Teste',
grupo_usuario_id=8)
# Cria um tipo de documento
tipo = mommy.make(TipoDocumento,
@ -424,10 +433,22 @@ def test_form_errors_relatoria(admin_client):
@pytest.mark.django_db(transaction=False)
def test_proposicao_submit(admin_client):
tipo_autor = mommy.make(TipoAutor, descricao='Teste Tipo_Autor')
user = User.objects.filter(is_active=True)[0]
autor = mommy.make(
Autor,
user=user,
tipo=tipo_autor,
nome='Autor Teste',
grupo_usuario_id=8)
response = admin_client.post(reverse('sapl.materia:proposicao_create'),
{'tipo': mommy.make(TipoProposicao, pk=3).pk,
'descricao': 'Teste proposição',
'salvar': 'salvar'},
'autor': autor,
'salvar': 'salvar',
},
follow=True)
assert response.status_code == 200
@ -439,9 +460,19 @@ def test_proposicao_submit(admin_client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_proposicao(admin_client):
tipo_autor = mommy.make(TipoAutor, descricao='Teste Tipo_Autor')
user = User.objects.filter(is_active=True)[0]
autor = mommy.make(
Autor,
user=user,
tipo=tipo_autor,
nome='Autor Teste',
grupo_usuario_id=8)
response = admin_client.post(reverse('sapl.materia:proposicao_create'),
{'salvar': 'salvar'},
{'autor': autor,
'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])

9
sapl/materia/urls.py

@ -3,9 +3,9 @@ from django.conf.urls import include, url
from sapl.materia.views import (AcompanhamentoConfirmarView,
AcompanhamentoExcluirView,
AcompanhamentoMateriaView, AnexadaCrud,
AutorCrud, AutoriaCrud, DespachoInicialCrud,
DocumentoAcessorioCrud, LegislacaoCitadaCrud,
MateriaLegislativaCrud,
AutorCrud, AutoriaCrud, ConfirmarEmailView,
DespachoInicialCrud, DocumentoAcessorioCrud,
LegislacaoCitadaCrud, MateriaLegislativaCrud,
MateriaLegislativaPesquisaView, MateriaTaView,
NumeracaoCrud, OrgaoCrud, OrigemCrud,
ProposicaoCrud, ProposicaoTaView,
@ -30,6 +30,9 @@ urlpatterns = [
RelatoriaCrud.get_urls() +
DocumentoAcessorioCrud.get_urls())),
url(r'^confirmar/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})$',
ConfirmarEmailView.as_view(), name='confirmar_email'),
url(r'^proposicao/', include(ProposicaoCrud.get_urls())),
# Integração com Compilação

123
sapl/materia/views.py

@ -4,13 +4,19 @@ from string import ascii_letters, digits
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User
from django.contrib.auth.tokens import default_token_generator
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.http.response import HttpResponseRedirect
from django.shortcuts import redirect
from django.template import Context, loader
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.utils.translation import ugettext_lazy as _
from django.views.generic import CreateView, TemplateView, UpdateView
from django_filters.views import FilterView
@ -19,15 +25,15 @@ from sapl.base.models import CasaLegislativa
from sapl.compilacao.views import IntegracaoTaView
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView,
CrudDeleteView, CrudListView, CrudUpdateView,
make_pagination)
CrudDeleteView, CrudDetailView, CrudListView,
CrudUpdateView, make_pagination)
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.norma.models import LegislacaoCitada
from sapl.utils import (autor_label, autor_modal, get_base_url,
permissao_tb_aux, permissoes_materia)
permissao_tb_aux, permissoes_autor, permissoes_materia)
from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutoriaForm,
DespachoInicialForm, DocumentoAcessorioForm,
from .forms import (AcompanhamentoMateriaForm, AnexadaForm, AutorForm,
AutoriaForm, DespachoInicialForm, DocumentoAcessorioForm,
LegislacaoCitadaForm, MateriaLegislativaFilterSet,
NumeracaoForm, ProposicaoForm, RelatoriaForm,
TramitacaoForm, UnidadeTramitacaoForm,
@ -103,9 +109,55 @@ class AutorCrud(Crud):
help_path = 'autor'
class BaseMixin(PermissionRequiredMixin, CrudBaseMixin):
list_field_names = ['tipo', 'nome',
'username', 'cargo']
def has_permission(self):
return permissao_tb_aux(self)
class CreateView(CrudCreateView):
form_class = AutorForm
layout_key = 'AutorCreate'
def get_success_url(self):
pk_autor = Autor.objects.get(
email=self.request.POST.get('email')).id
kwargs = {}
user = User.objects.get(email=self.request.POST.get('email'))
kwargs['token'] = default_token_generator.make_token(user)
kwargs['uidb64'] = urlsafe_base64_encode(force_bytes(user.pk))
assunto = "SAPL - Confirmação de Conta"
full_url = self.request.get_raw_uri()
url_base = full_url[:full_url.find('sistema') - 1]
mensagem = ("Este e-mail foi utilizado para fazer cadastro no " +
"SAPL com o perfil de Autor. Agora você pode " +
"criar/editar/enviar Proposições.\n" +
"Seu nome de usuário é: " +
self.request.POST['username'] + "\n"
"Caso você não tenha feito este cadastro, por favor " +
"ignore esta mensagem. Caso tenha, clique " +
"no link abaixo\n" + url_base +
reverse('sapl.materia:confirmar_email', kwargs=kwargs))
remetente = settings.EMAIL_SEND_USER
destinatario = [self.request.POST.get('email')]
send_mail(assunto, mensagem, remetente, destinatario,
fail_silently=False)
return reverse('sapl.materia:autor_detail',
kwargs={'pk': pk_autor})
class ConfirmarEmailView(TemplateView):
template_name = "confirma_email.html"
def get(self, request, *args, **kwargs):
uid = urlsafe_base64_decode(self.kwargs['uidb64'])
user = User.objects.get(id=uid)
user.is_active = True
user.save()
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
class OrgaoCrud(Crud):
model = Orgao
@ -167,16 +219,66 @@ class ProposicaoCrud(Crud):
def layout_key(self):
return 'ProposicaoCreate'
def get_initial(self):
try:
autor_id = Autor.objects.get(user=self.request.user.id)
except MultipleObjectsReturned:
msg = _('Este usuário está relacionado a mais de um autor. ' +
'Operação cancelada')
messages.add_message(self.request, messages.ERROR, msg)
return redirect(self.get_success_url())
else:
return {'autor': autor_id}
class UpdateView(PermissionRequiredMixin, CrudUpdateView):
form_class = ProposicaoForm
permission_required = permissoes_materia()
permission_required = permissoes_autor()
@property
def layout_key(self):
return 'ProposicaoCreate'
class ListView(CrudListView):
def has_permission(self):
perms = self.get_permission_required()
if self.request.user.has_perms(perms):
if (Proposicao.objects.filter(
id=self.kwargs['pk'],
autor__user_id=self.request.user.id).exists()):
proposicao = Proposicao.objects.get(
id=self.kwargs['pk'],
autor__user_id=self.request.user.id)
if not proposicao.data_recebimento:
return True
else:
msg = _('Essa proposição já foi recebida. ' +
'Não pode mais ser editada')
messages.add_message(self.request, messages.ERROR, msg)
return False
else:
return False
class DetailView(PermissionRequiredMixin, CrudDetailView):
permission_required = permissoes_autor()
@property
def layout_key(self):
return 'ProposicaoCreate'
def has_permission(self):
perms = self.get_permission_required()
if self.request.user.has_perms(perms):
if (Proposicao.objects.filter(
id=self.kwargs['pk'],
autor__user_id=self.request.user.id).exists()):
return True
else:
return False
else:
return False
class ListView(PermissionRequiredMixin, CrudListView):
ordering = ['-data_envio', 'descricao']
permission_required = permissoes_autor()
def get_rows(self, object_list):
@ -186,6 +288,11 @@ class ProposicaoCrud(Crud):
return [self._as_row(obj) for obj in object_list]
def get_queryset(self):
lista = Proposicao.objects.filter(
autor__user_id=self.request.user.id)
return lista
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_materia()

6
sapl/parlamentares/forms.py

@ -29,9 +29,9 @@ class LegislaturaForm(ModelForm):
data_eleicao = cleaned_data['data_eleicao']
if data_inicio >= data_fim or data_eleicao >= data_inicio:
raise ValidationError(_('A data início deve ser menor que a data \
fim, e a data eleição deve ser menor que\
a data início'))
raise ValidationError(_('A data início deve ser menor que a ' +
'data fim, e a data eleição deve ser ' +
'menor que a data início'))
return cleaned_data

22
sapl/parlamentares/migrations/0022_auto_20160624_1124.py

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-06-24 14:24
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import sapl.parlamentares.models
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0021_merge'),
]
operations = [
migrations.AlterField(
model_name='sessaolegislativa',
name='legislatura',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parlamentares.Legislatura', verbose_name=sapl.parlamentares.models.Legislatura),
),
]

21
sapl/parlamentares/migrations/0023_auto_20160628_1247.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-06-28 15:47
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0022_auto_20160624_1124'),
]
operations = [
migrations.AlterField(
model_name='sessaolegislativa',
name='legislatura',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parlamentares.Legislatura', verbose_name='Legislatura'),
),
]

6
sapl/protocoloadm/migrations/0013_merge.py → sapl/parlamentares/migrations/0024_merge.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-05-19 17:03
# Generated by Django 1.9.7 on 2016-08-18 21:39
from __future__ import unicode_literals
from django.db import migrations
@ -8,8 +8,8 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0012_tipoinstituicao'),
('protocoloadm', '0012_auto_20160503_0926'),
('parlamentares', '0022_auto_20160702_1519'),
('parlamentares', '0023_auto_20160628_1247'),
]
operations = [

87
sapl/protocoloadm/forms.py

@ -1,16 +1,18 @@
from datetime import datetime
import django_filters
from crispy_forms.bootstrap import InlineRadios
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button, Field, Fieldset, Layout, Submit
from crispy_forms.layout import HTML, Button, Fieldset, Layout, Submit
from django import forms
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db import models
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
from sapl.crispy_layout_mixin import form_actions, to_row
from sapl.materia.forms import RangeWidgetOverride
from sapl.materia.models import Autor
from sapl.materia.models import Autor, UnidadeTramitacao
from sapl.utils import RANGE_ANOS, autor_label, autor_modal
from .models import (DocumentoAcessorioAdministrativo, DocumentoAdministrativo,
@ -523,7 +525,6 @@ class TramitacaoAdmForm(ModelForm):
'data_encaminhamento',
'data_fim_prazo',
'texto',
'documento',
]
widgets = {
@ -532,22 +533,78 @@ class TramitacaoAdmForm(ModelForm):
'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'),
}
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset(_('Incluir Tramitação'),
'data_tramitacao',
def clean(self):
data_enc_form = self.cleaned_data['data_encaminhamento']
data_prazo_form = self.cleaned_data['data_fim_prazo']
data_tram_form = self.cleaned_data['data_tramitacao']
if self.errors:
return self.errors
ultima_tramitacao = TramitacaoAdministrativo.objects.filter(
documento_id=self.instance.documento_id).exclude(
id=self.instance.id).last()
if not self.instance.data_tramitacao:
if ultima_tramitacao:
destino = ultima_tramitacao.unidade_tramitacao_destino
if (destino != self.cleaned_data['unidade_tramitacao_local']):
msg = _('A origem da nova tramitação deve ser igual ao '
'destino da última adicionada!')
raise ValidationError(msg)
if self.cleaned_data['data_tramitacao'] > datetime.now().date():
msg = _(
'A data de tramitação deve ser ' +
'menor ou igual a data de hoje!')
raise ValidationError(msg)
if (ultima_tramitacao and
data_tram_form < ultima_tramitacao.data_tramitacao):
msg = _('A data da nova tramitação deve ser ' +
'maior que a data da última tramitação!')
raise ValidationError(msg)
if data_enc_form < data_tram_form or data_prazo_form < data_tram_form:
msg = _('A data fim de prazo e encaminhamento devem ser ' +
'maiores que a data de tramitação!')
raise ValidationError(msg)
return self.cleaned_data
class TramitacaoAdmEditForm(TramitacaoAdmForm):
unidade_tramitacao_local = forms.ModelChoiceField(
queryset=UnidadeTramitacao.objects.all(),
widget=forms.HiddenInput())
data_tramitacao = forms.DateField(widget=forms.HiddenInput())
class Meta:
model = TramitacaoAdministrativo
fields = ['data_tramitacao',
'unidade_tramitacao_local',
'status',
'unidade_tramitacao_destino',
'data_encaminhamento',
'data_fim_prazo',
'texto'),
Field('documento', type="hidden"),
form_actions()
)
super(TramitacaoAdmForm, self).__init__(
*args, **kwargs)
'texto',
]
widgets = {
'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'),
'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'),
}
def clean(self):
local = self.instance.unidade_tramitacao_local
data_tram = self.instance.data_tramitacao
self.cleaned_data['data_tramitacao'] = data_tram
self.cleaned_data['unidade_tramitacao_local'] = local
return super(TramitacaoAdmEditForm, self).clean()
class DocumentoAdministrativoForm(ModelForm):

114
sapl/protocoloadm/migrations/0001_initial.py

@ -1,147 +1,163 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-06-24 14:31
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
import sapl.protocoloadm.models
class Migration(migrations.Migration):
initial = True
dependencies = [
('materia', '0001_initial'),
('materia', '0038_auto_20160612_1506'),
]
operations = [
migrations.CreateModel(
name='DocumentoAcessorioAdministrativo',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nome', models.CharField(max_length=30, verbose_name='Nome')),
('arquivo', models.CharField(max_length=100, verbose_name='Arquivo')),
('arquivo', models.FileField(blank=True, null=True, upload_to=sapl.protocoloadm.models.texto_upload_path, verbose_name='Arquivo')),
('data', models.DateField(blank=True, null=True, verbose_name='Data')),
('autor', models.CharField(blank=True, max_length=50, null=True, verbose_name='Autor')),
('assunto', models.TextField(blank=True, null=True, verbose_name='Assunto')),
('indexacao', models.TextField(blank=True, null=True)),
('autor', models.CharField(blank=True, max_length=50, verbose_name='Autor')),
('assunto', models.TextField(blank=True, verbose_name='Assunto')),
('indexacao', models.TextField(blank=True)),
],
options={
'verbose_name_plural': 'Documentos Acessórios',
'verbose_name': 'Documento Acessório',
'verbose_name_plural': 'Documentos Acessórios',
},
),
migrations.CreateModel(
name='DocumentoAdministrativo',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('numero', models.IntegerField(verbose_name='Número')),
('ano', models.SmallIntegerField(verbose_name='Ano')),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('numero', models.PositiveIntegerField(verbose_name='Número')),
('ano', models.PositiveSmallIntegerField(choices=[(2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano')),
('data', models.DateField(verbose_name='Data')),
('numero_protocolo', models.IntegerField(blank=True, null=True, verbose_name='Núm. Protocolo')),
('interessado', models.CharField(blank=True, max_length=50, null=True, verbose_name='Interessado')),
('dias_prazo', models.IntegerField(blank=True, null=True, verbose_name='Dias Prazo')),
('numero_protocolo', models.PositiveIntegerField(blank=True, null=True, verbose_name='Núm. Protocolo')),
('interessado', models.CharField(blank=True, max_length=50, verbose_name='Interessado')),
('dias_prazo', models.PositiveIntegerField(blank=True, null=True, verbose_name='Dias Prazo')),
('data_fim_prazo', models.DateField(blank=True, null=True, verbose_name='Data Fim Prazo')),
('tramitacao', models.BooleanField(verbose_name='Em Tramitação?')),
('tramitacao', models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], verbose_name='Em Tramitação?')),
('assunto', models.TextField(verbose_name='Assunto')),
('observacao', models.TextField(blank=True, null=True, verbose_name='Observação')),
('autor', models.ForeignKey(blank=True, null=True, to='materia.Autor')),
('observacao', models.TextField(blank=True, verbose_name='Observação')),
('texto_integral', models.FileField(blank=True, null=True, upload_to=sapl.protocoloadm.models.texto_upload_path, verbose_name='Texto Integral')),
('autor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='materia.Autor')),
],
options={
'verbose_name_plural': 'Documentos Administrativos',
'verbose_name': 'Documento Administrativo',
'verbose_name_plural': 'Documentos Administrativos',
},
),
migrations.CreateModel(
name='Protocolo',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('numero', models.IntegerField(blank=True, null=True, verbose_name='Número do Protocolo')),
('ano', models.SmallIntegerField()),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('numero', models.PositiveIntegerField(verbose_name='Número de Protocolo')),
('ano', models.PositiveSmallIntegerField(choices=[(2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano do Protocolo')),
('data', models.DateField()),
('hora', models.TimeField()),
('timestamp', models.DateTimeField()),
('tipo_protocolo', models.IntegerField(verbose_name='Tipo de Protocolo')),
('tipo_processo', models.IntegerField()),
('interessado', models.CharField(blank=True, max_length=60, null=True, verbose_name='Interessado')),
('assunto_ementa', models.TextField(blank=True, null=True)),
('numero_paginas', models.IntegerField(blank=True, null=True, verbose_name='Número de Páginas')),
('observacao', models.TextField(blank=True, null=True, verbose_name='Observação')),
('tipo_protocolo', models.PositiveIntegerField(verbose_name='Tipo de Protocolo')),
('tipo_processo', models.PositiveIntegerField()),
('interessado', models.CharField(blank=True, max_length=60, verbose_name='Interessado')),
('assunto_ementa', models.TextField(blank=True)),
('numero_paginas', models.PositiveIntegerField(blank=True, null=True, verbose_name='Número de Páginas')),
('observacao', models.TextField(blank=True, verbose_name='Observação')),
('anulado', models.BooleanField()),
('user_anulacao', models.CharField(blank=True, max_length=20, null=True)),
('ip_anulacao', models.CharField(blank=True, max_length=15, null=True)),
('justificativa_anulacao', models.CharField(blank=True, max_length=60, null=True)),
('user_anulacao', models.CharField(blank=True, max_length=20)),
('ip_anulacao', models.CharField(blank=True, max_length=15)),
('justificativa_anulacao', models.CharField(blank=True, max_length=60, verbose_name='Motivo')),
('timestamp_anulacao', models.DateTimeField(blank=True, null=True)),
('autor', models.ForeignKey(blank=True, null=True, to='materia.Autor')),
('autor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='materia.Autor')),
],
options={
'verbose_name_plural': 'Protocolos',
'verbose_name': 'Protocolo',
'verbose_name_plural': 'Protocolos',
},
),
migrations.CreateModel(
name='StatusTramitacaoAdministrativo',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sigla', models.CharField(max_length=10, verbose_name='Sigla')),
('descricao', models.CharField(max_length=60, verbose_name='Descrição')),
('indicador', models.CharField(choices=[('F', 'Fim'), ('R', 'Retorno')], max_length=1, verbose_name='Indicador da Tramitação')),
],
options={
'verbose_name_plural': 'Status de Tramitação',
'verbose_name': 'Status de Tramitação',
'verbose_name_plural': 'Status de Tramitação',
},
),
migrations.CreateModel(
name='TipoDocumentoAdministrativo',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('sigla', models.CharField(max_length=5, verbose_name='Sigla')),
('descricao', models.CharField(max_length=50, verbose_name='Descrição')),
],
options={
'verbose_name_plural': 'Tipos de Documento Administrativo',
'verbose_name': 'Tipo de Documento Administrativo',
'verbose_name_plural': 'Tipos de Documento Administrativo',
},
),
migrations.CreateModel(
name='TipoInstituicao',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('descricao', models.CharField(max_length=50, verbose_name='Descrição')),
],
options={
'verbose_name': 'Tipo de Instituição',
'verbose_name_plural': 'Tipos de Instituições',
},
),
migrations.CreateModel(
name='TramitacaoAdministrativo',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('data_tramitacao', models.DateField(blank=True, null=True, verbose_name='Data Tramitação')),
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('data_tramitacao', models.DateField(verbose_name='Data Tramitação')),
('data_encaminhamento', models.DateField(blank=True, null=True, verbose_name='Data Encaminhamento')),
('ultima', models.BooleanField()),
('texto', models.TextField(blank=True, null=True, verbose_name='Texto da Ação')),
('texto', models.TextField(blank=True, verbose_name='Texto da Ação')),
('data_fim_prazo', models.DateField(blank=True, null=True, verbose_name='Data Fim do Prazo')),
('documento', models.ForeignKey(to='protocoloadm.DocumentoAdministrativo')),
('status', models.ForeignKey(blank=True, null=True, to='protocoloadm.StatusTramitacaoAdministrativo', verbose_name='Status')),
('unidade_tramitacao_destino', models.ForeignKey(blank=True, null=True, to='materia.UnidadeTramitacao', verbose_name='Unidade Destino', related_name='+')),
('unidade_tramitacao_local', models.ForeignKey(blank=True, null=True, to='materia.UnidadeTramitacao', verbose_name='Unidade Local', related_name='+')),
('documento', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='protocoloadm.DocumentoAdministrativo')),
('status', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='protocoloadm.StatusTramitacaoAdministrativo', verbose_name='Status')),
('unidade_tramitacao_destino', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='adm_tramitacoes_destino', to='materia.UnidadeTramitacao', verbose_name='Unidade Destino')),
('unidade_tramitacao_local', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='adm_tramitacoes_origem', to='materia.UnidadeTramitacao', verbose_name='Unidade Local')),
],
options={
'verbose_name_plural': 'Tramitações de Documento Administrativo',
'verbose_name': 'Tramitação de Documento Administrativo',
'verbose_name_plural': 'Tramitações de Documento Administrativo',
},
),
migrations.AddField(
model_name='protocolo',
name='tipo_documento',
field=models.ForeignKey(blank=True, null=True, to='protocoloadm.TipoDocumentoAdministrativo', verbose_name='Tipo de documento'),
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='protocoloadm.TipoDocumentoAdministrativo', verbose_name='Tipo de documento'),
),
migrations.AddField(
model_name='protocolo',
name='tipo_materia',
field=models.ForeignKey(blank=True, null=True, to='materia.TipoMateriaLegislativa', verbose_name='Tipo Matéria'),
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='materia.TipoMateriaLegislativa', verbose_name='Tipo Matéria'),
),
migrations.AddField(
model_name='documentoadministrativo',
name='tipo',
field=models.ForeignKey(to='protocoloadm.TipoDocumentoAdministrativo', verbose_name='Tipo Documento'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='protocoloadm.TipoDocumentoAdministrativo', verbose_name='Tipo Documento'),
),
migrations.AddField(
model_name='documentoacessorioadministrativo',
name='documento',
field=models.ForeignKey(to='protocoloadm.DocumentoAdministrativo'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='protocoloadm.DocumentoAdministrativo'),
),
migrations.AddField(
model_name='documentoacessorioadministrativo',
name='tipo',
field=models.ForeignKey(to='protocoloadm.TipoDocumentoAdministrativo', verbose_name='Tipo'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='protocoloadm.TipoDocumentoAdministrativo', verbose_name='Tipo'),
),
]

59
sapl/protocoloadm/migrations/0002_auto_20150729_1717.py

@ -1,59 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='documentoadministrativo',
name='ano',
field=models.PositiveSmallIntegerField(verbose_name='Ano'),
),
migrations.AlterField(
model_name='documentoadministrativo',
name='dias_prazo',
field=models.PositiveIntegerField(blank=True, verbose_name='Dias Prazo', null=True),
),
migrations.AlterField(
model_name='documentoadministrativo',
name='numero',
field=models.PositiveIntegerField(verbose_name='Número'),
),
migrations.AlterField(
model_name='documentoadministrativo',
name='numero_protocolo',
field=models.PositiveIntegerField(blank=True, verbose_name='Núm. Protocolo', null=True),
),
migrations.AlterField(
model_name='protocolo',
name='ano',
field=models.PositiveSmallIntegerField(),
),
migrations.AlterField(
model_name='protocolo',
name='numero',
field=models.PositiveIntegerField(blank=True, verbose_name='Número do Protocolo', null=True),
),
migrations.AlterField(
model_name='protocolo',
name='numero_paginas',
field=models.PositiveIntegerField(blank=True, verbose_name='Número de Páginas', null=True),
),
migrations.AlterField(
model_name='protocolo',
name='tipo_processo',
field=models.PositiveIntegerField(),
),
migrations.AlterField(
model_name='protocolo',
name='tipo_protocolo',
field=models.PositiveIntegerField(verbose_name='Tipo de Protocolo'),
),
]

22
sapl/protocoloadm/migrations/0003_documentoacessorioadministrativo_texto_integral.py

@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import sapl.protocoloadm.models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0002_auto_20150729_1717'),
]
operations = [
migrations.AddField(
model_name='documentoacessorioadministrativo',
name='texto_integral',
field=models.FileField(verbose_name='Texto Integral', blank=True,
null=True, upload_to=sapl.protocoloadm.models.texto_upload_path),
),
]

27
sapl/protocoloadm/migrations/0004_auto_20151007_1035.py

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import sapl.protocoloadm.models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm',
'0003_documentoacessorioadministrativo_texto_integral'),
]
operations = [
migrations.RemoveField(
model_name='documentoacessorioadministrativo',
name='texto_integral',
),
migrations.AddField(
model_name='documentoadministrativo',
name='texto_integral',
field=models.FileField(
blank=True, null=True, upload_to=sapl.protocoloadm.models.texto_upload_path, verbose_name='Texto Integral'),
),
]

22
sapl/protocoloadm/migrations/0005_auto_20151008_0744.py

@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import sapl.protocoloadm.models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0004_auto_20151007_1035'),
]
operations = [
migrations.AlterField(
model_name='documentoacessorioadministrativo',
name='arquivo',
field=models.FileField(
blank=True, null=True, upload_to=sapl.protocoloadm.models.texto_upload_path, verbose_name='Arquivo'),
),
]

74
sapl/protocoloadm/migrations/0006_auto_20160216_1015.py

@ -1,74 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0005_auto_20151008_0744'),
]
operations = [
migrations.AlterField(
model_name='documentoacessorioadministrativo',
name='assunto',
field=models.TextField(verbose_name='Assunto', blank=True),
),
migrations.AlterField(
model_name='documentoacessorioadministrativo',
name='autor',
field=models.CharField(verbose_name='Autor', max_length=50, blank=True),
),
migrations.AlterField(
model_name='documentoacessorioadministrativo',
name='indexacao',
field=models.TextField(blank=True),
),
migrations.AlterField(
model_name='documentoadministrativo',
name='interessado',
field=models.CharField(verbose_name='Interessado', max_length=50, blank=True),
),
migrations.AlterField(
model_name='documentoadministrativo',
name='observacao',
field=models.TextField(verbose_name='Observação', blank=True),
),
migrations.AlterField(
model_name='protocolo',
name='assunto_ementa',
field=models.TextField(blank=True),
),
migrations.AlterField(
model_name='protocolo',
name='interessado',
field=models.CharField(verbose_name='Interessado', max_length=60, blank=True),
),
migrations.AlterField(
model_name='protocolo',
name='ip_anulacao',
field=models.CharField(max_length=15, blank=True),
),
migrations.AlterField(
model_name='protocolo',
name='justificativa_anulacao',
field=models.CharField(max_length=60, blank=True),
),
migrations.AlterField(
model_name='protocolo',
name='observacao',
field=models.TextField(verbose_name='Observação', blank=True),
),
migrations.AlterField(
model_name='protocolo',
name='user_anulacao',
field=models.CharField(max_length=20, blank=True),
),
migrations.AlterField(
model_name='tramitacaoadministrativo',
name='texto',
field=models.TextField(verbose_name='Texto da Ação', blank=True),
),
]

19
sapl/protocoloadm/migrations/0007_auto_20160218_1429.py

@ -1,19 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0006_auto_20160216_1015'),
]
operations = [
migrations.AlterField(
model_name='documentoadministrativo',
name='tramitacao',
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], verbose_name='Em Tramitação?'),
),
]

20
sapl/protocoloadm/migrations/0008_auto_20160308_1436.py

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-08 17:36
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0007_auto_20160218_1429'),
]
operations = [
migrations.AlterField(
model_name='protocolo',
name='ano',
field=models.PositiveSmallIntegerField(verbose_name='Ano do Protocolo'),
),
]

20
sapl/protocoloadm/migrations/0009_auto_20160309_1323.py

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-09 16:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0008_auto_20160308_1436'),
]
operations = [
migrations.AlterField(
model_name='protocolo',
name='numero',
field=models.PositiveIntegerField(verbose_name='Número de Protocolo'),
),
]

25
sapl/protocoloadm/migrations/0010_auto_20160309_1407.py

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-09 17:07
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0009_auto_20160309_1323'),
]
operations = [
migrations.AlterField(
model_name='documentoadministrativo',
name='ano',
field=models.PositiveSmallIntegerField(choices=[(2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'),
),
migrations.AlterField(
model_name='protocolo',
name='ano',
field=models.PositiveSmallIntegerField(choices=[(2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano do Protocolo'),
),
]

20
sapl/protocoloadm/migrations/0011_auto_20160318_1504.py

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2016-03-18 18:04
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0010_auto_20160309_1407'),
]
operations = [
migrations.AlterField(
model_name='protocolo',
name='justificativa_anulacao',
field=models.CharField(blank=True, max_length=60, verbose_name='Motivo'),
),
]

26
sapl/protocoloadm/migrations/0012_auto_20160503_0926.py

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-05-03 12:26
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0011_auto_20160318_1504'),
]
operations = [
migrations.AlterField(
model_name='tramitacaoadministrativo',
name='unidade_tramitacao_destino',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='adm_tramitacoes_destino', to='materia.UnidadeTramitacao', verbose_name='Unidade Destino'),
),
migrations.AlterField(
model_name='tramitacaoadministrativo',
name='unidade_tramitacao_local',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='adm_tramitacoes_origem', to='materia.UnidadeTramitacao', verbose_name='Unidade Local'),
),
]

26
sapl/protocoloadm/migrations/0012_tipoinstituicao.py

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-05-17 18:07
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0011_auto_20160318_1504'),
]
operations = [
migrations.CreateModel(
name='TipoInstituicao',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('descricao', models.CharField(max_length=50, verbose_name='Descrição')),
],
options={
'verbose_name': 'Tipo de Instituição',
'verbose_name_plural': 'Tipos de Instituições',
},
),
]

7
sapl/protocoloadm/models.py

@ -167,16 +167,12 @@ class StatusTramitacaoAdministrativo(models.Model):
class TramitacaoAdministrativo(models.Model):
status = models.ForeignKey(
StatusTramitacaoAdministrativo,
blank=True,
null=True,
verbose_name=_('Status'))
documento = models.ForeignKey(DocumentoAdministrativo)
data_tramitacao = models.DateField(
blank=True, null=True, verbose_name=_('Data Tramitação'))
verbose_name=_('Data Tramitação'))
unidade_tramitacao_local = models.ForeignKey(
UnidadeTramitacao,
blank=True,
null=True,
related_name='adm_tramitacoes_origem',
verbose_name=_('Unidade Local'))
data_encaminhamento = models.DateField(
@ -187,7 +183,6 @@ class TramitacaoAdministrativo(models.Model):
null=True,
related_name='adm_tramitacoes_destino',
verbose_name=_('Unidade Destino'))
ultima = models.BooleanField()
texto = models.TextField(
blank=True, verbose_name=_('Texto da Ação'))
data_fim_prazo = models.DateField(

22
sapl/protocoloadm/urls.py

@ -22,13 +22,8 @@ from sapl.protocoloadm.views import (AnularProtocoloAdmView,
ProtocoloPesquisaView,
StatusTramitacaoAdministrativoCrud,
TipoDocumentoAdministrativoCrud,
TipoInstituicaoCrud,
TramitacaoAdmDeleteView,
TramitacaoAdmEditView,
TramitacaoAdmIncluirView,
TramitacaoAdministrativoCrud,
TramitacaoAdmView, get_nome_autor,
pesquisa_autores)
TipoInstituicaoCrud, TramitacaoAdmCrud,
get_nome_autor, pesquisa_autores)
from .apps import AppConfig
@ -36,7 +31,8 @@ app_name = AppConfig.name
urlpatterns = [
url(r'^protocoloadm/docadm/',
include(DocumentoAdministrativoCrud.get_urls())),
include(DocumentoAdministrativoCrud.get_urls() +
TramitacaoAdmCrud.get_urls())),
url(r'^protocoloadm/tipo-documento-adm/',
include(TipoDocumentoAdministrativoCrud.get_urls())),
url(r'^protocoloadm/doc-acessorio/',
@ -45,8 +41,6 @@ urlpatterns = [
include(StatusTramitacaoAdministrativoCrud.get_urls())),
url(r'^protocoloadm/tipo-instituicao/',
include(TipoInstituicaoCrud.get_urls())),
url(r'^protocoloadm/tramitacao-adm/',
include(TramitacaoAdministrativoCrud.get_urls())),
url(r'^protocoloadm/protocolo-doc/',
include(ProtocoloDocumentoCrud.get_urls())),
url(r'^protocoloadm/protocolo-mat/',
@ -73,14 +67,6 @@ urlpatterns = [
DocumentoAcessorioAdministrativoEditView.as_view(),
name='doc_ace_adm_edit'),
url(r'^protocoloadm/(?P<pk>\d+)/tramitacao$',
TramitacaoAdmView.as_view(), name='tramitacao_adm'),
url(r'^protocoloadm/(?P<pk>\d+)/tramitacao_incluir',
TramitacaoAdmIncluirView.as_view(), name='tramitacao_incluir'),
url(r'^protocoloadm/(?P<pk>\d+)/tramitacao_edit',
TramitacaoAdmEditView.as_view(), name='tramitacao_edit'),
url(r'^protocoloadm/(?P<pk>\d+)/tramitacao_delete/(?P<oid>\d+)',
TramitacaoAdmDeleteView.as_view(), name='tramitacao_delete'),
url(r'^protocoloadm/(?P<pk>\d+)/(?P<ano>\d+)/comprovante$',
ComprovanteProtocoloView.as_view(), name='comprovante_protocolo'),

122
sapl/protocoloadm/views.py

@ -13,9 +13,11 @@ from django.views.generic import CreateView, DetailView, FormView, ListView
from django.views.generic.base import TemplateView
from django_filters.views import FilterView
import sapl.crud.base
from sapl.crud.base import (Crud, CrudBaseMixin, CrudCreateView,
CrudDeleteView, CrudListView, CrudUpdateView,
make_pagination)
from sapl.crud.masterdetail import MasterDetailCrud
from sapl.materia.models import Proposicao, TipoMateriaLegislativa
from sapl.utils import (create_barcode, get_client_ip, permissoes_adm,
permissoes_protocoloadm)
@ -24,7 +26,8 @@ from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm,
DocumentoAdministrativoFilterSet,
DocumentoAdministrativoForm, ProposicaoSimpleForm,
ProtocoloDocumentForm, ProtocoloFilterSet,
ProtocoloMateriaForm, TramitacaoAdmForm)
ProtocoloMateriaForm, TramitacaoAdmEditForm,
TramitacaoAdmForm)
from .models import (Autor, DocumentoAcessorioAdministrativo,
DocumentoAdministrativo, Protocolo,
StatusTramitacaoAdministrativo,
@ -32,16 +35,33 @@ from .models import (Autor, DocumentoAcessorioAdministrativo,
TramitacaoAdministrativo)
TipoDocumentoAdministrativoCrud = Crud.build(TipoDocumentoAdministrativo, '')
DocumentoAdministrativoCrud = Crud.build(DocumentoAdministrativo, '')
DocumentoAcessorioAdministrativoCrud = Crud.build(
DocumentoAcessorioAdministrativo, '')
TramitacaoAdministrativoCrud = Crud.build(TramitacaoAdministrativo, '')
ProtocoloDocumentoCrud = Crud.build(Protocolo, '')
# FIXME precisa de uma chave diferente para o layout
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):
permission_required = permissoes_adm()
class DeleteView(PermissionRequiredMixin, CrudDeleteView):
permission_required = permissoes_adm()
class StatusTramitacaoAdministrativoCrud(Crud):
model = StatusTramitacaoAdministrativo
help_path = ''
@ -582,94 +602,30 @@ class DocumentoAcessorioAdministrativoView(PermissionRequiredMixin, FormView):
return reverse('sapl.protocoloadm:doc_ace_adm', kwargs={'pk': pk})
class TramitacaoAdmView(PermissionRequiredMixin, FormView):
template_name = "protocoloadm/tramitacao.html"
permission_required = permissoes_adm()
def get(self, request, *args, **kwargs):
pk = kwargs['pk']
documento = DocumentoAdministrativo.objects.get(id=pk)
tramitacoes = TramitacaoAdministrativo.objects.filter(
documento=documento).order_by('-data_tramitacao')
return self.render_to_response({'documento': documento,
'tramitacoes': tramitacoes})
class TramitacaoAdmCrud(MasterDetailCrud):
model = TramitacaoAdministrativo
parent_field = 'documento'
help_path = ''
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['data_tramitacao', 'unidade_tramitacao_local',
'unidade_tramitacao_destino', 'status']
class TramitacaoAdmIncluirView(PermissionRequiredMixin, FormView):
template_name = "protocoloadm/tramitacao_incluir.html"
class CreateView(PermissionRequiredMixin, MasterDetailCrud.CreateView):
form_class = TramitacaoAdmForm
permission_required = permissoes_adm()
def get(self, request, *args, **kwargs):
pk = kwargs['pk']
documento = DocumentoAdministrativo.objects.get(id=pk)
data = {'documento': documento}
form = TramitacaoAdmForm(initial=data)
return self.render_to_response({'documento': documento, 'form': form})
def post(self, request, *args, **kwargs):
pk = kwargs['pk']
form = TramitacaoAdmForm(request.POST or None)
if form.is_valid():
tramitacao = form.save(commit=False)
tramitacao.ultima = False
tramitacao.save()
return HttpResponseRedirect(reverse(
'sapl.protocoloadm:tramitacao_adm', kwargs={'pk': pk}))
else:
return self.form_invalid(form)
class TramitacaoAdmEditView(PermissionRequiredMixin, FormView):
template_name = "protocoloadm/tramitacao_edit.html"
class UpdateView(PermissionRequiredMixin, MasterDetailCrud.UpdateView):
form_class = TramitacaoAdmEditForm
permission_required = permissoes_adm()
def get(self, request, *args, **kwargs):
pk = kwargs['pk']
tramitacao = TramitacaoAdministrativo.objects.get(id=pk)
documento = tramitacao.documento
form = TramitacaoAdmForm(instance=tramitacao)
return self.render_to_response({'documento': documento, 'form': form})
def post(self, request, *args, **kwargs):
pk = kwargs['pk']
tramitacao = TramitacaoAdministrativo.objects.get(id=pk)
form = TramitacaoAdmForm(request.POST, instance=tramitacao)
if form.is_valid():
tramitacao = form.save(commit=False)
tramitacao.ultima = False
tramitacao.save()
return HttpResponseRedirect(
reverse('sapl.protocoloadm:tramitacao_adm',
kwargs={'pk': tramitacao.documento.id}))
else:
return self.form_invalid(form)
class TramitacaoAdmDeleteView(PermissionRequiredMixin, DetailView):
template_name = "protocoloadm/tramitacao.html"
class ListView(PermissionRequiredMixin, MasterDetailCrud.ListView):
permission_required = permissoes_adm()
def get(self, request, *args, **kwargs):
pk = kwargs['pk']
oid = kwargs['oid']
documento = DocumentoAdministrativo.objects.get(id=pk)
tramitacao = TramitacaoAdministrativo.objects.get(id=oid)
tramitacao.delete()
tramitacoes = TramitacaoAdministrativo.objects.filter(
documento=documento)
return self.render_to_response({'documento': documento,
'tramitacoes': tramitacoes})
def get_queryset(self):
qs = super(MasterDetailCrud.ListView, self).get_queryset()
kwargs = {self.crud.parent_field: self.kwargs['pk']}
return qs.filter(**kwargs).order_by('-id')
def get_nome_autor(request):

1
sapl/settings.py

@ -130,6 +130,7 @@ EMAIL_PORT = config('EMAIL_PORT', cast=int, default=587)
EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='')
EMAIL_USE_TLS = config('EMAIL_USE_TLS', cast=bool, default=True)
EMAIL_SEND_USER = config('EMAIL_SEND_USER', cast=str, default='')
MAX_DOC_UPLOAD_SIZE = 5 * 1024 * 1024 # 5MB
MAX_IMAGE_UPLOAD_SIZE = 2 * 1024 * 1024 # 2MB

10
sapl/templates/base.html

@ -60,12 +60,20 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Protocolo <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:protocolo' %}">Pesquisar Protocolo</a></li>
<li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:pesq_doc_adm' %}">Pesquisar Documento Administrativo</a></li>
<!-- <li class="nav__sub-item"><a class="nav__sub-link" href="/materia">Protocolo Legislativo</a></li> -->
{# <li class="nav__sub-item"><a class="nav__sub-link" href="">Protocolo Geral</a></li> #}
{# <li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:proposicao' %}">Proposições</a></li> #}
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Documentos Administrativos <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="nav__sub-item"><a class="nav__sub-link" href="{% url 'sapl.protocoloadm:pesq_doc_adm' %}">Pesquisar Documento Administrativo</a></li>
</ul>
</li>
<li class="dropdown">
{% endif %}
<li class="dropdown">

7
sapl/templates/confirma_email.html

@ -0,0 +1,7 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block detail_content %}
Sua conta foi confirmada via e-mail. Clique <a href="{% url 'base:login' %}">aqui</a> para fazer seu login.
{% endblock %}

12
sapl/templates/materia/layouts.yaml

@ -54,7 +54,14 @@ TipoAutor:
Autor:
{% trans 'Autor' %}:
- tipo:3 nome
- username
- username:6 cargo
AutorCreate:
Autor:
- tipo:3 nome
- username:4 senha:4 senha_confirma:4
- email:6 confirma_email:6
- cargo:4 parlamentar:4 comissao:4
Autoria:
{% trans 'Autoria' %}:
@ -91,8 +98,7 @@ ProposicaoCreate:
{% trans 'Proposição' %}:
- tipo data_envio
- descricao
{% trans 'Materia' %}:
- tipo_materia numero_materia ano_materia
{% trans 'Complemento' %}:
- texto_original

4
sapl/templates/materia/materialegislativa_filter.html

@ -9,7 +9,7 @@
{% block detail_content %}
{% if filter_url %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'sapl.materia:pesquisar_materia' %}" class="btn btn-default">{% trans 'Fazer nova pesquisa' %}</a>
<a href="{% url 'materia:pesquisar_materia' %}" class="btn btn-default">{% trans 'Fazer nova pesquisa' %}</a>
</div>
{% endif %}
@ -33,7 +33,7 @@
{% for m in page_obj %}
<tr>
<td>
<strong><a href="{% url 'sapl.materia:materialegislativa_detail' m.id %}">{{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}}</strong></a></br>
<strong><a href="{% url 'materia:materialegislativa_detail' m.id %}">{{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}}</strong></a></br>
<strong>Autores:</strong>
{% for a in m.autoria_set.all %}
{% if not forloop.first %}

9
sapl/templates/protocoloadm/documentoadministrativo_detail.html

@ -0,0 +1,9 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block actions %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'protocoloadm:tramitacaoadministrativo_list' object.pk %}" class="btn btn-default">{% trans 'Tramitações' %}</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 %}

26
sapl/templates/protocoloadm/documentoadministrativo_filter.html

@ -1,16 +1,34 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block actions %}{% endblock %}
{% load common_tags %}
{% block sections_nav %} {% endblock %}
{% block actions %}
<h1><b>Documentos Administrativos</b></h1>
<div class="actions btn-group pull-right" role="group">
{% if perms|get_add_perm:view %}
<a href="docadm/create" class="btn btn-default">{% trans 'Adicionar Documento Administrativo' %}</a>
{% endif %}
</div>
{% if filter_url %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'protocoloadm:pesq_doc_adm' %}" class="btn btn-default">{% trans 'Fazer Nova Pesquisa' %}</a>
</div>
{% endif %}
{% endblock actions %}
{% block detail_content %}
<h1><b>Pesquisar Documento Administrativo</b></h1>
<br></br>
{% if not filter_url %}
{% crispy filter.form %}
{% endif %}
{% if filter_url %}
<p></p>
<table class="table table-striped table-bordered">
@ -28,7 +46,7 @@
<tr>
<td>
<strong><a href="{% url 'sapl.protocoloadm:documentoadministrativo_detail' d.id %}">{{d.tipo.sigla}} {{d.numero}}/{{d.ano}} - {{d.tipo}}</strong></a></br>
<strong><a href="{% url 'protocoloadm:documentoadministrativo_detail' d.id %}">{{d.tipo.sigla}} {{d.numero}}/{{d.ano}} - {{d.tipo}}</strong></a></br>
<strong>Interessado:</strong>&nbsp;{{ d.interessado|default_if_none:"Não Informado"}}</br>
<strong>Assunto:</strong>&nbsp;{{ d.assunto|safe }}</br>
<p></p>

6
sapl/templates/protocoloadm/protocolo_filter.html

@ -10,7 +10,7 @@
<br></br>
{% if filter_url %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'sapl.protocoloadm:protocolo' %}" class="btn btn-default">{% trans 'Fazer nova pesquisa' %}</a>
<a href="{% url 'protocoloadm:protocolo' %}" class="btn btn-default">{% trans 'Fazer nova pesquisa' %}</a>
</div>
{% endif %}
@ -37,12 +37,12 @@
<tr>
<td>
<strong>Protocolo:
<a href="{% url 'sapl.protocoloadm:protocolo_mostrar' p.numero p.ano %}">
<a href="{% url 'protocoloadm:protocolo_mostrar' p.numero p.ano %}">
{{ p.numero|stringformat:'06d' }}/{{ p.ano }}
</a></strong>
&nbsp;&nbsp;<strong>-</strong>&nbsp;&nbsp;
<a href="{% url 'sapl.relatorios:relatorio_etiqueta_protocolo' p.numero p.ano %}">
<a href="{% url 'relatorios:relatorio_etiqueta_protocolo' p.numero p.ano %}">
<img src="{% static 'img/etiqueta.png' %}" alt="Etiqueta Individual">
</a></br>

9
sapl/templates/protocoloadm/protocolo_pesquisa.html

@ -1,9 +0,0 @@
{% extends "protocoloadm/protocoloadm_detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
<legend>Pesquisa Avançada</legend>
{% crispy form %}
</fieldset>
{% endblock detail_content %}

6
sapl/templates/protocoloadm/protocoloadm_detail.html

@ -2,8 +2,8 @@
{% load i18n %}
{% block actions %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'sapl.protocoloadm:protocolar_doc' %}" class="btn btn-default">{% trans 'Protocolar Documento' %}</a>
<a href="{% url 'sapl.protocoloadm:protocolar_mat' %}" class="btn btn-default">{% trans 'Protocolar Matéria' %}</a>
<a href="{% url 'sapl.protocoloadm:anular_protocolo' %}" class="btn btn-default">{% trans 'Anular Protocolo' %}</a>
<a href="{% url 'protocoloadm:protocolar_doc' %}" class="btn btn-default">{% trans 'Protocolar Documento' %}</a>
<a href="{% url 'protocoloadm:protocolar_mat' %}" class="btn btn-default">{% trans 'Protocolar Matéria' %}</a>
<a href="{% url 'protocoloadm:anular_protocolo' %}" class="btn btn-default">{% trans 'Anular Protocolo' %}</a>
</div>
{% endblock actions %}

40
sapl/templates/protocoloadm/tramitacao.html

@ -1,40 +0,0 @@
{% extends "protocoloadm/protocoloadm_detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
<fieldset>
Tipo: {{documento.tipo.sigla}} Número: {{documento.numero}} Ano: {{documento.ano}}</br>
Assunto: {{documento.assunto}}
</fieldset>
<fieldset>
<h2>Tramitação</h2>
{% if tramitacoes %}
<table>
<tr>
<td>Data Ação</td>
<td>Origem</td>
<td>Destino</td>
<td>Status</td>
<td>Excluir</td>
</tr>
{% for t in tramitacoes %}
<tr>
<td><a href="{% url 'sapl.protocoloadm:tramitacao_edit' t.id %}">{{t.data_encaminhamento|date:"d/m/Y"}}</a></td>
<td>{{t.unidade_tramitacao_local}}</td>
<td>{{t.unidade_tramitacao_destino}}</td>
<td>{{t.status.sigla}}</td>
<td><a href="{% url 'sapl.protocoloadm:tramitacao_delete' documento.id t.id %}">Excluir</ad></td>
</tr>
{% endfor %}
</table>
{% else %}
<strong>Nenhuma tramitação cadastrada para este documento.</strong>
{% endif %}
</br>
<a href="{% url 'sapl.protocoloadm:tramitacao_incluir' documento.id %}" class="button primary">Incluir Tramitação</a>
</fieldset>
{% endblock detail_content %}

15
sapl/templates/protocoloadm/tramitacao_edit.html

@ -1,15 +0,0 @@
{% extends "protocoloadm/protocoloadm_detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
<fieldset>
Tipo: {{documento.tipo.sigla}} Número: {{documento.numero}} Ano: {{documento.ano}}</br>
Assunto: {{documento.assunto}}
</fieldset>
<h2>Tramitação Edit</h2>
{% crispy form %}
{% endblock detail_content %}

14
sapl/templates/protocoloadm/tramitacao_incluir.html

@ -1,14 +0,0 @@
{% extends "protocoloadm/protocoloadm_detail.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block detail_content %}
<fieldset>
Tipo: {{documento.tipo.sigla}} Número: {{documento.numero}} Ano: {{documento.ano}}</br>
Assunto: {{documento.assunto}}
</fieldset>
<h2>Tramitação</h2>
{% crispy form %}
{% endblock detail_content %}

9
sapl/templates/protocoloadm/tramitacaoadministrativo_detail.html

@ -0,0 +1,9 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block actions %}
<div class="actions btn-group pull-right" role="group">
<a href="{% url 'protocoloadm:documentoadministrativo_detail' root_pk %}" class="btn btn-default">{% trans 'Início' %}</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 %}

9
sapl/utils.py

@ -299,3 +299,12 @@ def permissao_tb_aux(self):
return True
else:
return False
def permissoes_autor():
lista_permissoes = []
perms_autor = list(Permission.objects.filter(
group__name='Autor'))
for p in perms_autor:
lista_permissoes.append('materia.' + p.codename)
return set(lista_permissoes)

Loading…
Cancel
Save