Sistema de Apoio ao Processo Legislativo
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1718 lines
61 KiB

from datetime import datetime, date
from random import choice
from string import ascii_letters, digits
8 years ago
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML
from django import forms
from django.contrib import messages
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import (ObjectDoesNotExist,
MultipleObjectsReturned)
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.http import HttpResponse, JsonResponse
8 years ago
from django.http.response import Http404, HttpResponseRedirect
8 years ago
from django.shortcuts import get_object_or_404, redirect
8 years ago
from django.utils import formats
from django.utils.translation import ugettext_lazy as _
from django.views.generic import CreateView, ListView, TemplateView, UpdateView
from django.views.generic.base import RedirectView
from django.views.generic.edit import FormView
from django_filters.views import FilterView
8 years ago
from sapl.base.models import Autor, CasaLegislativa
from sapl.comissoes.models import Comissao
8 years ago
from sapl.comissoes.models import Comissao, Participacao
from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT,
8 years ago
STATUS_TA_PRIVATE)
from sapl.compilacao.views import IntegracaoTaView
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions
8 years ago
from sapl.crud.base import (ACTION_CREATE, ACTION_DELETE, ACTION_DETAIL,
ACTION_LIST, ACTION_UPDATE, RP_DETAIL, RP_LIST,
8 years ago
Crud, CrudAux, MasterDetailCrud,
PermissionRequiredForAppCrudMixin, make_pagination)
from sapl.materia.forms import (AnexadaForm, ConfirmarProposicaoForm,
LegislacaoCitadaForm, AutoriaForm, ProposicaoForm,
TipoProposicaoForm, TramitacaoForm,
TramitacaoUpdateForm)
from sapl.materia.models import Autor
from sapl.norma.models import LegislacaoCitada
from sapl.parlamentares.models import Parlamentar
from sapl.protocoloadm.models import Protocolo
from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label,
autor_modal, gerar_hash_arquivo, get_base_url,
montar_row_autor)
import sapl
from .email_utils import do_envia_email_confirmacao
from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
AdicionarVariasAutoriasFilterSet, DespachoInicialForm,
DocumentoAcessorioForm, MateriaAssuntoForm,
MateriaLegislativaFilterSet, MateriaSimplificadaForm,
PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm,
RelatoriaForm, TramitacaoEmLoteFilterSet,
filtra_tramitacao_destino,
filtra_tramitacao_destino_and_status,
filtra_tramitacao_status)
from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria,
DespachoInicial, DocumentoAcessorio, MateriaAssunto,
MateriaLegislativa, Numeracao, Orgao, Origem, Proposicao,
RegimeTramitacao, Relatoria, StatusTramitacao,
TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa,
TipoProposicao, Tramitacao, UnidadeTramitacao)
from .signals import tramitacao_signal
AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia')
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')
def autores_ja_adicionados(materia_pk):
autorias = Autoria.objects.filter(materia_id=materia_pk)
pks = [a.autor.pk for a in autorias]
return pks
def proposicao_texto(request, pk):
proposicao = Proposicao.objects.get(pk=pk)
if proposicao.texto_original:
if (not proposicao.data_recebimento and
proposicao.autor.user_id != request.user.id):
raise Http404
arquivo = proposicao.texto_original
ext = arquivo.name.split('.')[-1]
mime = ''
if ext == 'odt':
mime = 'application/vnd.oasis.opendocument.text'
else:
mime = "application/%s" % (ext,)
with open(arquivo.path, 'rb') as f:
data = f.read()
response = HttpResponse(data, content_type='%s' % mime)
response['Content-Disposition'] = (
'inline; filename="%s"' % arquivo.name.split('/')[-1])
return response
raise Http404
class AdicionarVariasAutorias(PermissionRequiredForAppCrudMixin, FilterView):
app_label = sapl.materia.apps.AppConfig.label
filterset_class = AdicionarVariasAutoriasFilterSet
template_name = 'materia/adicionar_varias_autorias.html'
model = Autor
def get_filterset_kwargs(self, filterset_class):
super(AdicionarVariasAutorias, self).get_filterset_kwargs(
filterset_class)
kwargs = {'data': self.request.GET or None}
qs = self.get_queryset()
qs = qs.exclude(
id__in=autores_ja_adicionados(self.kwargs['pk'])).distinct()
kwargs.update({'queryset': qs})
return kwargs
def get_context_data(self, **kwargs):
context = super(AdicionarVariasAutorias, self).get_context_data(
**kwargs)
context['title'] = _('Pesquisar Autores')
qr = self.request.GET.copy()
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['pk_materia'] = self.kwargs['pk']
return context
def post(self, request, *args, **kwargs):
8 years ago
marcados = request.POST.getlist('autor_id')
for m in marcados:
Autoria.objects.create(
materia_id=self.kwargs['pk'],
autor_id=m
)
return HttpResponseRedirect(
8 years ago
reverse('sapl.materia:autoria_list',
kwargs={'pk': self.kwargs['pk']}))
class CriarProtocoloMateriaView(CreateView):
template_name = "crud/form.html"
form_class = MateriaSimplificadaForm
form_valid_message = _('Matéria cadastrada com sucesso!')
def get_success_url(self, materia):
return reverse('sapl.materia:materialegislativa_detail', kwargs={
'pk': materia.pk})
def get_context_data(self, **kwargs):
context = super(
CriarProtocoloMateriaView, self).get_context_data(**kwargs)
8 years ago
try:
protocolo = Protocolo.objects.get(pk=self.kwargs['pk'])
except ObjectDoesNotExist:
raise Http404()
materias_ano = MateriaLegislativa.objects.filter(
ano=protocolo.ano,
tipo=protocolo.tipo_materia).order_by('-numero')
if materias_ano:
numero = materias_ano.first().numero + 1
else:
numero = 1
context['form'].fields['tipo'].initial = protocolo.tipo_materia
8 years ago
context['form'].fields['numero'].initial = numero
context['form'].fields['ano'].initial = protocolo.ano
context['form'].fields['data_apresentacao'].initial = protocolo.data
context['form'].fields['numero_protocolo'].initial = protocolo.numero
8 years ago
context['form'].fields['ementa'].initial = protocolo.assunto_ementa
return context
def form_valid(self, form):
materia = form.save()
8 years ago
try:
protocolo = Protocolo.objects.get(pk=self.kwargs['pk'])
except ObjectDoesNotExist:
raise Http404()
if protocolo.autor:
Autoria.objects.create(
materia=materia,
autor=protocolo.autor,
primeiro_autor=True)
return redirect(self.get_success_url(materia))
class MateriaTaView(IntegracaoTaView):
model = MateriaLegislativa
model_type_foreignkey = TipoMateriaLegislativa
map_fields = {
'data': 'data_apresentacao',
'ementa': 'ementa',
'observacao': None,
'numero': 'numero',
'ano': 'ano',
}
map_funcs = {
8 years ago
'publicacao_func': False,
}
ta_values = {
'editable_only_by_owners': False,
'editing_locked': False,
}
def get(self, request, *args, **kwargs):
"""
Para manter a app compilacao isolada das outras aplicações,
este get foi implementado para tratar uma prerrogativa externa
de usuário.
"""
if sapl.base.models.AppConfig.attr('texto_articulado_materia'):
return IntegracaoTaView.get(self, request, *args, **kwargs)
else:
return self.get_redirect_deactivated()
class ProposicaoTaView(IntegracaoTaView):
model = Proposicao
model_type_foreignkey = TipoProposicao
map_fields = {
8 years ago
'data': 'data_envio',
'ementa': 'descricao',
'observacao': None,
'numero': 'numero_proposicao',
'ano': 'ano',
}
map_funcs = {
'publicacao_func': False
}
8 years ago
ta_values = {
'editable_only_by_owners': True,
'editing_locked': False,
'privacidade': STATUS_TA_PRIVATE
}
def get(self, request, *args, **kwargs):
"""
Para manter a app compilacao isolada das outras aplicações,
este get foi implementado para tratar uma prerrogativa externa
de usuário.
"""
if sapl.base.models.AppConfig.attr('texto_articulado_proposicao'):
8 years ago
proposicao = get_object_or_404(self.model, pk=kwargs['pk'])
if not proposicao.data_envio and\
request.user != proposicao.autor.user:
raise Http404()
return IntegracaoTaView.get(self, request, *args, **kwargs)
else:
return self.get_redirect_deactivated()
@permission_required('materia.detail_materialegislativa')
8 years ago
def recuperar_materia(request):
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo'])
8 years ago
ano = request.GET.get('ano', '')
param = {'tipo': tipo}
param['data_apresentacao__year'] = ano if ano else datetime.now().year
materia = MateriaLegislativa.objects.filter(**param).order_by(
'tipo', 'ano', 'numero').values_list('numero', 'ano').last()
8 years ago
if materia:
8 years ago
response = JsonResponse({'numero': materia[0] + 1,
'ano': materia[1]})
8 years ago
else:
8 years ago
response = JsonResponse(
{'numero': 1, 'ano': ano if ano else datetime.now().year})
8 years ago
return response
OrgaoCrud = CrudAux.build(Orgao, 'orgao')
StatusTramitacaoCrud = CrudAux.build(StatusTramitacao, 'status_tramitacao')
class TipoProposicaoCrud(CrudAux):
model = TipoProposicao
help_text = 'tipo_proposicao'
class BaseMixin(CrudAux.BaseMixin):
8 years ago
list_field_names = [
"descricao", "content_type", 'tipo_conteudo_related']
class CreateView(CrudAux.CreateView):
form_class = TipoProposicaoForm
layout_key = None
class UpdateView(CrudAux.UpdateView):
form_class = TipoProposicaoForm
layout_key = None
def criar_materia_proposicao(proposicao):
tipo_materia = TipoMateriaLegislativa.objects.get(
descricao=proposicao.tipo.descricao)
numero = MateriaLegislativa.objects.filter(
ano=datetime.now().year).order_by('numero').last().numero + 1
regime = RegimeTramitacao.objects.get(descricao='Normal')
return MateriaLegislativa.objects.create(
tipo=tipo_materia,
ano=datetime.now().year,
numero=numero,
data_apresentacao=datetime.now(),
regime_tramitacao=regime,
em_tramitacao=True,
ementa=proposicao.descricao,
texto_original=proposicao.texto_original
)
def criar_doc_proposicao(proposicao):
tipo_doc = TipoDocumento.objects.get(
descricao=proposicao.tipo.descricao)
if proposicao.autor is None:
autor = 'Desconhecido'
else:
autor = proposicao.autor
return DocumentoAcessorio.objects.create(
materia=proposicao.materia,
tipo=tipo_doc,
arquivo=proposicao.texto_original,
nome=proposicao.descricao,
data=proposicao.data_envio,
autor=autor
)
class ProposicaoDevolvida(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_devolvidas_list.html'
model = Proposicao
ordering = ['data_envio']
paginate_by = 10
permission_required = ('materia.detail_proposicao_devolvida', )
def get_queryset(self):
return Proposicao.objects.filter(
data_envio__isnull=True,
data_recebimento__isnull=True,
data_devolucao__isnull=False)
def get_context_data(self, **kwargs):
context = super(ProposicaoDevolvida, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['NO_ENTRIES_MSG'] = 'Nenhuma proposição devolvida.'
context['subnav_template_name'] = 'materia/subnav_prop.yaml'
return context
class ProposicaoPendente(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_pendentes_list.html'
model = Proposicao
ordering = ['data_envio', 'autor', 'tipo', 'descricao']
paginate_by = 10
permission_required = ('materia.detail_proposicao_enviada', )
def get_queryset(self):
return Proposicao.objects.filter(
data_envio__isnull=False,
data_recebimento__isnull=True,
9 years ago
data_devolucao__isnull=True)
def get_context_data(self, **kwargs):
context = super(ProposicaoPendente, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['NO_ENTRIES_MSG'] = 'Nenhuma proposição pendente.'
context['subnav_template_name'] = 'materia/subnav_prop.yaml'
return context
class ProposicaoRecebida(PermissionRequiredMixin, ListView):
template_name = 'materia/prop_recebidas_list.html'
model = Proposicao
ordering = ['data_envio']
paginate_by = 10
permission_required = 'materia.detail_proposicao_incorporada'
def get_queryset(self):
return Proposicao.objects.filter(
data_envio__isnull=False,
data_recebimento__isnull=False,
9 years ago
data_devolucao__isnull=True)
def get_context_data(self, **kwargs):
context = super(ProposicaoRecebida, self).get_context_data(**kwargs)
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['NO_ENTRIES_MSG'] = 'Nenhuma proposição recebida.'
context['subnav_template_name'] = 'materia/subnav_prop.yaml'
return context
class ReceberProposicao(PermissionRequiredForAppCrudMixin, FormView):
app_label = sapl.protocoloadm.apps.AppConfig.label
template_name = "crud/form.html"
form_class = ReceberProposicaoForm
def post(self, request, *args, **kwargs):
form = ReceberProposicaoForm(request.POST)
if form.is_valid():
proposicoes = Proposicao.objects.filter(
data_envio__isnull=False, data_recebimento__isnull=True)
for proposicao in proposicoes:
8 years ago
if proposicao.texto_articulado.exists():
ta = proposicao.texto_articulado.first()
# FIXME hash para textos articulados
hasher = 'P' + ta.hash() + '/' + str(proposicao.id)
else:
hasher = gerar_hash_arquivo(
proposicao.texto_original.path,
str(proposicao.pk)) \
8 years ago
if proposicao.texto_original else None
if hasher == form.cleaned_data['cod_hash']:
return HttpResponseRedirect(
reverse('sapl.materia:proposicao-confirmar',
kwargs={
'hash': hasher.split('/')[0][1:],
'pk': proposicao.pk}))
messages.error(request, _('Proposição não encontrada!'))
return self.form_invalid(form)
def get_success_url(self):
return reverse('sapl.materia:receber-proposicao')
def get_context_data(self, **kwargs):
context = super(ReceberProposicao, self).get_context_data(**kwargs)
context['subnav_template_name'] = 'materia/subnav_prop.yaml'
return context
class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView):
app_label = sapl.protocoloadm.apps.AppConfig.label
template_name = "materia/confirmar_proposicao.html"
model = Proposicao
form_class = ConfirmarProposicaoForm
def get_success_url(self):
msgs = self.object.results['messages']
for key, value in msgs.items():
for item in value:
getattr(messages, key)(self.request, item)
return self.object.results['url']
def get_object(self, queryset=None):
try:
"""Não deve haver acesso na rotina de confirmação a proposições:
recebidas -> data_recebimento != None
não enviadas -> data_envio == None
"""
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'],
data_envio__isnull=False,
data_recebimento__isnull=True)
self.object = None
# FIXME implementar hash para texto eletrônico
8 years ago
if proposicao.texto_articulado.exists():
ta = proposicao.texto_articulado.first()
# FIXME hash para textos articulados
hasher = 'P' + ta.hash() + '/' + str(proposicao.id)
else:
hasher = gerar_hash_arquivo(
proposicao.texto_original.path,
str(proposicao.pk)) if proposicao.texto_original else None
if hasher == 'P%s/%s' % (self.kwargs['hash'], proposicao.pk):
self.object = proposicao
except:
raise Http404()
if not self.object:
raise Http404()
return self.object
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['subnav_template_name'] = ''
return context
8 years ago
class UnidadeTramitacaoCrud(CrudAux):
model = UnidadeTramitacao
help_path = 'unidade_tramitacao'
class BaseMixin(Crud.BaseMixin):
list_field_names = ['comissao', 'orgao', 'parlamentar']
class ListView(Crud.ListView):
template_name = "crud/list.html"
def get_headers(self):
return [_('Unidade de Tramitação')]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
for row in context['rows']:
if row[0][0]: # Comissão
pass
elif row[1][0]: # Órgão
row[0] = (row[1][0], row[0][1])
elif row[2][0]: # Parlamentar
row[0] = (row[2][0], row[0][1])
row[1], row[2] = ('', ''), ('', '')
return context
class ProposicaoCrud(Crud):
model = Proposicao
help_path = ''
container_field = 'autor__user'
class BaseMixin(Crud.BaseMixin):
list_field_names = ['data_envio', 'data_recebimento', 'descricao',
8 years ago
'tipo', 'conteudo_gerado_related']
class BaseLocalMixin:
form_class = ProposicaoForm
layout_key = None
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['subnav_template_name'] = ''
return context
def get(self, request, *args, **kwargs):
if not self._action_is_valid(request, *args, **kwargs):
return redirect(reverse('sapl.materia:proposicao_detail',
kwargs={'pk': kwargs['pk']}))
return super().get(self, request, *args, **kwargs)
def post(self, request, *args, **kwargs):
if not self._action_is_valid(request, *args, **kwargs):
return redirect(reverse('sapl.materia:proposicao_detail',
kwargs={'pk': kwargs['pk']}))
return super().post(self, request, *args, **kwargs)
class DetailView(Crud.DetailView):
layout_key = 'Proposicao'
permission_required = (RP_DETAIL, 'materia.detail_proposicao_enviada',
'materia.detail_proposicao_devolvida',
'materia.detail_proposicao_incorporada')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['subnav_template_name'] = ''
context['title'] = '%s <small>(%s)</small>' % (
self.object, self.object.autor)
return context
def get(self, request, *args, **kwargs):
action = request.GET.get('action', '')
if not action:
return Crud.DetailView.get(self, request, *args, **kwargs)
p = Proposicao.objects.get(id=kwargs['pk'])
msg_error = ''
if p:
if action == 'send':
if p.data_envio and p.data_recebimento:
msg_error = _('Proposição já foi enviada e recebida.')
elif p.data_envio:
msg_error = _('Proposição já foi enviada.')
elif not p.texto_original and\
not p.texto_articulado.exists():
msg_error = _('Proposição não possui nenhum tipo de '
'Texto associado.')
else:
p.data_devolucao = None
p.data_envio = datetime.now()
p.save()
8 years ago
if p.texto_articulado.exists():
ta = p.texto_articulado.first()
ta.privacidade = STATUS_TA_IMMUTABLE_RESTRICT
ta.editing_locked = True
ta.save()
messages.success(request, _(
'Proposição enviada com sucesso.'))
elif action == 'return':
if not p.data_envio:
msg_error = _('Proposição ainda não foi enviada.')
elif p.data_recebimento:
msg_error = _('Proposição já foi recebida, não é '
'possível retorná-la.')
else:
p.data_envio = None
p.save()
8 years ago
if p.texto_articulado.exists():
ta = p.texto_articulado.first()
ta.privacidade = STATUS_TA_PRIVATE
ta.editing_locked = False
ta.save()
messages.success(request, _(
'Proposição Retornada com sucesso.'))
if msg_error:
messages.error(request, msg_error)
# retornar redirecionando para limpar a variavel action
return redirect(reverse('sapl.materia:proposicao_detail',
kwargs={'pk': kwargs['pk']}))
def dispatch(self, request, *args, **kwargs):
try:
p = Proposicao.objects.get(id=kwargs['pk'])
except:
raise Http404()
if not self.has_permission():
return self.handle_no_permission()
if p.autor.user != request.user:
if not p.data_envio and not p.data_devolucao:
raise Http404()
if p.data_devolucao and not request.user.has_perm(
'materia.detail_proposicao_devolvida'):
raise Http404()
if p.data_envio and not p.data_recebimento\
and not request.user.has_perm(
'materia.detail_proposicao_enviada'):
raise Http404()
if p.data_envio and p.data_recebimento\
and not request.user.has_perm(
'materia.detail_proposicao_incorporada'):
raise Http404()
return super(PermissionRequiredMixin, self).dispatch(
request, *args, **kwargs)
class DeleteView(BaseLocalMixin, Crud.DeleteView):
def _action_is_valid(self, request, *args, **kwargs):
proposicao = Proposicao.objects.filter(
id=kwargs['pk']).values_list(
'data_envio', 'data_recebimento')
if proposicao:
if proposicao[0][0] and proposicao[0][1]:
msg = _('Proposição já foi enviada e recebida.'
'Não pode mais ser excluida.')
elif proposicao[0][0] and not proposicao[0][1]:
msg = _('Proposição já foi enviada mas ainda não recebida '
'pelo protocolo. Use a opção Recuperar Proposição '
'para depois excluí-la.')
if proposicao[0][0] or proposicao[0][1]:
messages.error(request, msg)
return False
return True
class UpdateView(BaseLocalMixin, Crud.UpdateView):
def _action_is_valid(self, request, *args, **kwargs):
proposicao = Proposicao.objects.filter(
id=kwargs['pk']).values_list(
'data_envio', 'data_recebimento')
if proposicao:
if proposicao[0][0] and proposicao[0][1]:
msg = _('Proposição já foi enviada e recebida.'
'Não pode mais ser editada')
elif proposicao[0][0] and not proposicao[0][1]:
msg = _('Proposição já foi enviada mas ainda não recebida '
'pelo protocolo. Use a opção Recuperar Proposição '
'para voltar para edição.')
if proposicao[0][0] or proposicao[0][1]:
messages.error(request, msg)
return False
return True
def get_success_url(self):
tipo_texto = self.request.POST.get('tipo_texto', '')
if tipo_texto == 'T':
messages.info(self.request,
_('Sempre que uma Proposição é inclusa ou '
'alterada e a opção "Texto Articulado " for '
8 years ago
'marcada, você será redirecionado para a '
'edição do Texto Eletrônico.'))
return reverse('sapl.materia:proposicao_ta',
kwargs={'pk': self.object.pk})
else:
return Crud.UpdateView.get_success_url(self)
class CreateView(Crud.CreateView):
form_class = ProposicaoForm
layout_key = None
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['subnav_template_name'] = ''
return context
def get_success_url(self):
tipo_texto = self.request.POST.get('tipo_texto', '')
if tipo_texto == 'T':
messages.info(self.request,
_('Sempre que uma Proposição é inclusa ou '
'alterada e a opção "Texto Articulado " for '
'marcada, você será redirecionado para o '
'Texto Eletrônico. Use a opção "Editar Texto" '
'para construir seu texto.'))
return reverse('sapl.materia:proposicao_ta',
kwargs={'pk': self.object.pk})
else:
return Crud.CreateView.get_success_url(self)
class ListView(Crud.ListView):
ordering = ['-data_envio', 'descricao']
def get_rows(self, object_list):
for obj in object_list:
8 years ago
if obj.data_recebimento is None:
obj.data_recebimento = 'Não recebida'\
if obj.data_envio else 'Não enviada'
else:
obj.data_recebimento = formats.date_format(
obj.data_recebimento, "DATETIME_FORMAT")
if obj.data_envio is None:
obj.data_envio = 'Em elaboração...'
else:
obj.data_envio = formats.date_format(
obj.data_envio, "DATETIME_FORMAT")
return [self._as_row(obj) for obj in object_list]
class ReciboProposicaoView(TemplateView):
template_name = "materia/recibo_proposicao.html"
permission_required = ('materia.detail_proposicao', )
def has_permission(self):
perms = self.get_permission_required()
if not self.request.user.has_perms(perms):
return False
return (Proposicao.objects.filter(
id=self.kwargs['pk'],
autor__user_id=self.request.user.id).exists())
def get_context_data(self, **kwargs):
context = super(ReciboProposicaoView, self).get_context_data(
**kwargs)
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'])
8 years ago
if proposicao.texto_original:
_hash = gerar_hash_arquivo(
proposicao.texto_original.path,
self.kwargs['pk'])
elif proposicao.texto_articulado.exists():
ta = proposicao.texto_articulado.first()
# FIXME hash para textos articulados
_hash = 'P' + ta.hash() + '/' + str(proposicao.id)
context.update({'proposicao': proposicao,
8 years ago
'hash': _hash})
return context
def get(self, request, *args, **kwargs):
proposicao = Proposicao.objects.get(pk=self.kwargs['pk'])
if proposicao.data_envio:
return TemplateView.get(self, request, *args, **kwargs)
if not proposicao.data_envio and not proposicao.data_devolucao:
8 years ago
messages.error(request, _('Não é possível gerar recibo para uma '
'Proposição ainda não enviada.'))
elif proposicao.data_devolucao:
messages.error(request, _('Não é possível gerar recibo.'))
return redirect(reverse('sapl.materia:proposicao_detail',
kwargs={'pk': proposicao.pk}))
class RelatoriaCrud(MasterDetailCrud):
model = Relatoria
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(MasterDetailCrud.CreateView):
8 years ago
form_class = RelatoriaForm
8 years ago
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
8 years ago
try:
comissao = Comissao.objects.get(
pk=context['form'].initial['comissao'])
except ObjectDoesNotExist:
pass
else:
composicao = comissao.composicao_set.last()
participacao = Participacao.objects.filter(
composicao=composicao)
parlamentares = []
parlamentares.append(['', '---------'])
8 years ago
for p in participacao:
if p.titular:
parlamentares.append(
[p.parlamentar.id, p.parlamentar.nome_parlamentar])
8 years ago
context['form'].fields['parlamentar'].choices = parlamentares
8 years ago
return context
def get_initial(self):
materia = MateriaLegislativa.objects.get(id=self.kwargs['pk'])
loc_atual = Tramitacao.objects.filter(
materia=materia).last()
if loc_atual is None:
localizacao = 0
else:
comissao = loc_atual.unidade_tramitacao_destino.comissao
if comissao:
localizacao = comissao.pk
else:
localizacao = 0
return {'comissao': localizacao}
8 years ago
class UpdateView(MasterDetailCrud.UpdateView):
form_class = RelatoriaForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
try:
comissao = Comissao.objects.get(
pk=context['form'].initial['comissao'])
except ObjectDoesNotExist:
pass
else:
composicao = comissao.composicao_set.last()
participacao = Participacao.objects.filter(
composicao=composicao)
parlamentares = []
for p in participacao:
if p.titular:
parlamentares.append(
[p.parlamentar.id, p.parlamentar.nome_parlamentar])
context['form'].fields['parlamentar'].choices = parlamentares
return context
class TramitacaoCrud(MasterDetailCrud):
model = Tramitacao
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['data_tramitacao', 'unidade_tramitacao_local',
'unidade_tramitacao_destino', 'status']
ordered_list = False
ordering = '-data_tramitacao',
class CreateView(MasterDetailCrud.CreateView):
form_class = TramitacaoForm
8 years ago
def get_success_url(self):
return reverse('sapl.materia:tramitacao_list', kwargs={
'pk': self.kwargs['pk']})
8 years ago
def get_initial(self):
local = MateriaLegislativa.objects.get(
pk=self.kwargs['pk']).tramitacao_set.order_by(
'-data_tramitacao').first()
8 years ago
if local:
self.initial['unidade_tramitacao_local'
] = local.unidade_tramitacao_destino.pk
else:
self.initial['unidade_tramitacao_local'] = ''
8 years ago
self.initial['data_tramitacao'] = datetime.now()
8 years ago
return self.initial
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
primeira_tramitacao = not(Tramitacao.objects.filter(
materia_id=int(kwargs['root_pk'])).exists())
# Se não for a primeira tramitação daquela matéria, o campo
# não pode ser modificado
if not primeira_tramitacao:
context['form'].fields[
'unidade_tramitacao_local'].widget.attrs['disabled'] = True
return context
def form_valid(self, form):
self.object = form.save()
if form.instance.status.indicador == 'F':
form.instance.materia.em_tramitacao = False
else:
form.instance.materia.em_tramitacao = True
form.instance.materia.save()
try:
tramitacao_signal.send(sender=Tramitacao,
post=self.object,
request=self.request)
except Exception:
# TODO log error
msg = _('Tramitação criada, mas e-mail de acompanhamento '
'de matéria não enviado. Há problemas na configuração '
'do e-mail.')
messages.add_message(self.request, messages.ERROR, msg)
return HttpResponseRedirect(self.get_success_url())
return super().form_valid(form)
class UpdateView(MasterDetailCrud.UpdateView):
form_class = TramitacaoUpdateForm
@property
def layout_key(self):
return 'TramitacaoUpdate'
def form_valid(self, form):
self.object = form.save()
if form.instance.status.indicador == 'F':
form.instance.materia.em_tramitacao = False
else:
form.instance.materia.em_tramitacao = True
form.instance.materia.save()
try:
tramitacao_signal.send(sender=Tramitacao,
post=self.object,
request=self.request)
except Exception:
# TODO log error
msg = _('Tramitação atualizada, mas e-mail de acompanhamento '
'de matéria não enviado. Há problemas na configuração '
'do e-mail.')
messages.add_message(self.request, messages.ERROR, msg)
return HttpResponseRedirect(self.get_success_url())
return super().form_valid(form)
class ListView(MasterDetailCrud.ListView):
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('-data_tramitacao', '-id')
class DeleteView(MasterDetailCrud.DeleteView):
9 years ago
def delete(self, request, *args, **kwargs):
tramitacao = Tramitacao.objects.get(id=self.kwargs['pk'])
9 years ago
materia = MateriaLegislativa.objects.get(id=tramitacao.materia.id)
url = reverse('sapl.materia:tramitacao_list',
kwargs={'pk': tramitacao.materia.id})
9 years ago
if tramitacao.pk != materia.tramitacao_set.last().pk:
msg = _('Somente a última tramitação pode ser deletada!')
messages.add_message(request, messages.ERROR, msg)
return HttpResponseRedirect(url)
9 years ago
else:
tramitacao.delete()
return HttpResponseRedirect(url)
9 years ago
def montar_helper_documento_acessorio(self):
8 years ago
autor_row = montar_row_autor('autor')
self.helper = FormHelper()
self.helper.layout = SaplFormLayout(*self.get_layout())
# Adiciona o novo campo 'autor' e mecanismo de busca
self.helper.layout[0][0].append(HTML(autor_label))
self.helper.layout[0][0].append(HTML(autor_modal))
self.helper.layout[0][1] = autor_row
# Remove botões que estão fora do form
self.helper.layout[1].pop()
# Adiciona novos botões dentro do form
self.helper.layout[0][3][0].insert(1, form_actions(more=[
HTML('<a href="{{ view.cancel_url }}"'
' class="btn btn-inverse">Cancelar</a>')]))
class DocumentoAcessorioCrud(MasterDetailCrud):
model = DocumentoAcessorio
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['nome', 'tipo', 'data', 'autor', 'arquivo']
class CreateView(MasterDetailCrud.CreateView):
form_class = DocumentoAcessorioForm
def __init__(self, **kwargs):
super(MasterDetailCrud.CreateView, self).__init__(**kwargs)
def get_context_data(self, **kwargs):
context = super(
MasterDetailCrud.CreateView, self).get_context_data(**kwargs)
return context
class UpdateView(MasterDetailCrud.UpdateView):
form_class = DocumentoAcessorioForm
def __init__(self, **kwargs):
super(MasterDetailCrud.UpdateView, self).__init__(**kwargs)
def get_context_data(self, **kwargs):
context = super(UpdateView, self).get_context_data(**kwargs)
return context
class AutoriaCrud(MasterDetailCrud):
model = Autoria
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class CreateView(MasterDetailCrud.CreateView):
form_class = AutoriaForm
@property
def layout_key(self):
return 'AutoriaCreate'
def get_initial(self):
initial = super().get_initial()
materia = MateriaLegislativa.objects.get(id=self.kwargs['pk'])
initial['data_relativa'] = materia.data_apresentacao
initial['autor'] = []
return initial
class UpdateView(MasterDetailCrud.UpdateView):
form_class = AutoriaForm
@property
def layout_key(self):
return 'AutoriaUpdate'
def get_initial(self):
initial = super().get_initial()
autoria = Autoria.objects.get(id=self.kwargs['pk'])
initial.update({
'data_relativa': autoria.materia.data_apresentacao,
'tipo_autor': self.object.autor.tipo.id,
'autor': self.object.autor.id,
'primeiro_autor': self.object.primeiro_autor
})
return initial
8 years ago
class ListView(MasterDetailCrud.ListView):
def get_queryset(self):
qs = super().get_queryset()
return qs.order_by('-primeiro_autor', 'autor__nome')
class DespachoInicialCrud(MasterDetailCrud):
model = DespachoInicial
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
9 years ago
class CreateView(MasterDetailCrud.CreateView):
form_class = DespachoInicialForm
class UpdateView(MasterDetailCrud.UpdateView):
form_class = DespachoInicialForm
class LegislacaoCitadaCrud(MasterDetailCrud):
model = LegislacaoCitada
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['norma', 'disposicoes']
def resolve_url(self, suffix, args=None):
namespace = 'sapl.materia'
return reverse('%s:%s' % (namespace, self.url_name(suffix)),
args=args)
def has_permission(self):
8 years ago
perms = self.get_permission_required()
# Torna a view pública se não possuir conteudo
# no atributo permission_required
return self.request.user.has_module_perms('materia')\
if len(perms) else True
def permission(self, rad):
return '%s%s%s' % ('norma' if rad.endswith('_') else '',
rad,
self.model_name if rad.endswith('_') else '')
@property
def detail_create_url(self):
obj = self.crud if hasattr(self, 'crud') else self
if self.request.user.has_module_perms('materia'):
parent_field = obj.parent_field.split('__')[0]
parent_object = getattr(self.object, parent_field)
root_pk = parent_object.pk
return self.resolve_url(ACTION_CREATE, args=(root_pk,))
return ''
@property
def list_url(self):
return self.resolve_url(ACTION_LIST, args=(self.kwargs['pk'],))\
if self.request.user.has_module_perms('materia') else ''
@property
def create_url(self):
return self.resolve_url(ACTION_CREATE, args=(self.kwargs['pk'],))\
if self.request.user.has_module_perms('materia') else ''
@property
def detail_url(self):
return self.resolve_url(ACTION_DETAIL, args=(self.object.id,))\
if self.request.user.has_module_perms('materia') else ''
@property
def update_url(self):
return self.resolve_url(ACTION_UPDATE, args=(self.kwargs['pk'],))\
if self.request.user.has_module_perms('materia') else ''
@property
def delete_url(self):
return self.resolve_url(ACTION_DELETE, args=(self.object.id,))\
if self.request.user.has_module_perms('materia') else ''
class CreateView(MasterDetailCrud.CreateView):
form_class = LegislacaoCitadaForm
class UpdateView(MasterDetailCrud.UpdateView):
form_class = LegislacaoCitadaForm
def get_initial(self):
self.initial['tipo'] = self.object.norma.tipo.id
self.initial['numero'] = self.object.norma.numero
self.initial['ano'] = self.object.norma.ano
return self.initial
class DetailView(MasterDetailCrud.DetailView):
@property
def layout_key(self):
return 'LegislacaoCitadaDetail'
8 years ago
class DeleteView(MasterDetailCrud.DeleteView):
pass
9 years ago
class NumeracaoCrud(MasterDetailCrud):
model = Numeracao
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
9 years ago
class AnexadaCrud(MasterDetailCrud):
model = Anexada
parent_field = 'materia_principal'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['materia_anexada', 'data_anexacao']
class CreateView(MasterDetailCrud.CreateView):
form_class = AnexadaForm
class UpdateView(MasterDetailCrud.UpdateView):
form_class = AnexadaForm
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):
@property
def layout_key(self):
return 'AnexadaDetail'
class MateriaAssuntoCrud(MasterDetailCrud):
model = MateriaAssunto
parent_field = 'materia'
help_path = ''
public = [RP_LIST, RP_DETAIL]
class BaseMixin(MasterDetailCrud.BaseMixin):
list_field_names = ['assunto', 'materia']
class CreateView(MasterDetailCrud.CreateView):
form_class = MateriaAssuntoForm
def get_initial(self):
self.initial['materia'] = self.kwargs['pk']
return self.initial
class UpdateView(MasterDetailCrud.UpdateView):
form_class = MateriaAssuntoForm
def get_initial(self):
self.initial['materia'] = self.get_object().materia
self.initial['assunto'] = self.get_object().assunto
return self.initial
class MateriaLegislativaCrud(Crud):
model = MateriaLegislativa
help_path = 'materia_legislativa'
public = [RP_LIST, RP_DETAIL]
class BaseMixin(Crud.BaseMixin):
list_field_names = ['tipo', 'numero', 'ano', 'data_apresentacao']
@property
def list_url(self):
return ''
@property
def search_url(self):
namespace = self.model._meta.app_config.name
return reverse('%s:%s' % (namespace, 'pesquisar_materia'))
class CreateView(Crud.CreateView):
@property
def cancel_url(self):
return self.search_url
8 years ago
class DeleteView(Crud.DeleteView):
def get_success_url(self):
return self.search_url
8 years ago
class DetailView(Crud.DetailView):
@property
def layout_key(self):
return 'MateriaLegislativaDetail'
class ListView(Crud.ListView, RedirectView):
def get_redirect_url(self, *args, **kwargs):
namespace = self.model._meta.app_config.name
return reverse('%s:%s' % (namespace, 'pesquisar_materia'))
def get(self, request, *args, **kwargs):
return RedirectView.get(self, request, *args, **kwargs)
# FIXME - qual a finalidade dessa classe??
class DocumentoAcessorioView(PermissionRequiredMixin, CreateView):
template_name = "materia/documento_acessorio.html"
form_class = DocumentoAcessorioForm
permission_required = ('materia.add_documentoacessorio', )
def get(self, request, *args, **kwargs):
materia = MateriaLegislativa.objects.get(id=kwargs['pk'])
docs = DocumentoAcessorio.objects.filter(
materia_id=kwargs['pk']).order_by('data')
form = DocumentoAcessorioForm()
return self.render_to_response(
{'object': materia,
'form': form,
'docs': docs})
def post(self, request, *args, **kwargs):
form = self.get_form()
materia = MateriaLegislativa.objects.get(id=kwargs['pk'])
docs_list = DocumentoAcessorio.objects.filter(
materia_id=kwargs['pk'])
if form.is_valid():
documento_acessorio = form.save(commit=False)
documento_acessorio.materia = materia
documento_acessorio.save()
return self.form_valid(form)
else:
return self.render_to_response({'form': form,
'object': materia,
'docs': docs_list})
def get_success_url(self):
pk = self.kwargs['pk']
return reverse('sapl.materia:documento_acessorio', kwargs={'pk': pk})
class AcompanhamentoConfirmarView(TemplateView):
def get_redirect_url(self, email):
msg = _('Esta matéria está sendo acompanhada pelo e-mail: %s') % (
email)
messages.add_message(self.request, messages.SUCCESS, msg)
return reverse('sapl.materia:materialegislativa_detail',
kwargs={'pk': self.kwargs['pk']})
def get(self, request, *args, **kwargs):
materia_id = kwargs['pk']
hash_txt = request.GET.get('hash_txt', '')
try:
acompanhar = AcompanhamentoMateria.objects.get(
materia_id=materia_id,
hash=hash_txt)
except ObjectDoesNotExist:
raise Http404()
# except MultipleObjectsReturned:
# A melhor solução deve ser permitir que a exceção
# (MultipleObjectsReturned) seja lançada e vá para o log,
# pois só poderá ser causada por um erro de desenvolvimente
acompanhar.confirmado = True
acompanhar.save()
return HttpResponseRedirect(self.get_redirect_url(acompanhar.email))
class AcompanhamentoExcluirView(TemplateView):
def get_success_url(self):
msg = _('Você parou de acompanhar esta matéria.')
messages.add_message(self.request, messages.INFO, msg)
return reverse('sapl.materia:materialegislativa_detail',
kwargs={'pk': self.kwargs['pk']})
def get(self, request, *args, **kwargs):
materia_id = kwargs['pk']
hash_txt = request.GET.get('hash_txt', '')
try:
AcompanhamentoMateria.objects.get(materia_id=materia_id,
hash=hash_txt).delete()
except ObjectDoesNotExist:
pass
return HttpResponseRedirect(self.get_success_url())
class MateriaLegislativaPesquisaView(FilterView):
model = MateriaLegislativa
filterset_class = MateriaLegislativaFilterSet
paginate_by = 10
def get_filterset_kwargs(self, filterset_class):
super(MateriaLegislativaPesquisaView,
self).get_filterset_kwargs(filterset_class)
kwargs = {'data': self.request.GET or None}
status_tramitacao = self.request.GET.get('tramitacao__status')
unidade_destino = self.request.GET.get(
'tramitacao__unidade_tramitacao_destino')
qs = self.get_queryset().distinct()
if status_tramitacao and unidade_destino:
lista = filtra_tramitacao_destino_and_status(status_tramitacao,
unidade_destino)
qs = qs.filter(id__in=lista).distinct()
elif status_tramitacao:
lista = filtra_tramitacao_status(status_tramitacao)
qs = qs.filter(id__in=lista).distinct()
elif unidade_destino:
lista = filtra_tramitacao_destino(unidade_destino)
qs = qs.filter(id__in=lista).distinct()
8 years ago
if 'o' in self.request.GET and not self.request.GET['o']:
qs = qs.order_by('-ano', 'tipo__sigla', '-numero')
8 years ago
kwargs.update({
'queryset': qs,
})
return kwargs
def get_context_data(self, **kwargs):
context = super(MateriaLegislativaPesquisaView,
self).get_context_data(**kwargs)
context['title'] = _('Pesquisar Matéria Legislativa')
self.filterset.form.fields['o'].label = _('Ordenação')
qr = self.request.GET.copy()
if 'page' in qr:
del qr['page']
paginator = context['paginator']
page_obj = context['page_obj']
context['page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
return context
class AcompanhamentoMateriaView(CreateView):
template_name = "materia/acompanhamento_materia.html"
def get_random_chars(self):
s = ascii_letters + digits
return ''.join(choice(s) for i in range(choice([6, 7])))
def get(self, request, *args, **kwargs):
pk = self.kwargs['pk']
materia = MateriaLegislativa.objects.get(id=pk)
return self.render_to_response(
{'form': AcompanhamentoMateriaForm(),
'materia': materia})
def post(self, request, *args, **kwargs):
form = AcompanhamentoMateriaForm(request.POST)
pk = self.kwargs['pk']
materia = MateriaLegislativa.objects.get(id=pk)
if form.is_valid():
email = form.cleaned_data['email']
usuario = request.user
hash_txt = self.get_random_chars()
acompanhar = AcompanhamentoMateria.objects.get_or_create(
materia=materia,
email=form.data['email'])
# Se o segundo elemento do retorno do get_or_create for True
# quer dizer que o elemento não existia
if acompanhar[1]:
acompanhar = acompanhar[0]
acompanhar.hash = hash_txt
acompanhar.usuario = usuario.username
acompanhar.confirmado = False
acompanhar.save()
base_url = get_base_url(request)
destinatario = AcompanhamentoMateria.objects.get(
materia=materia,
email=email,
confirmado=False)
casa = CasaLegislativa.objects.first()
do_envia_email_confirmacao(base_url,
casa,
materia,
destinatario)
msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \
de mensagens e clique no link que nós enviamos para \
confirmar o acompanhamento desta matéria.')
messages.add_message(request, messages.SUCCESS, msg)
# Caso esse Acompanhamento já exista
# avisa ao usuário que essa matéria já está sendo acompanhada
else:
msg = _('Este e-mail já está acompanhando essa matéria.')
messages.add_message(request, messages.INFO, msg)
return self.render_to_response(
{'form': form,
'materia': materia,
'error': _('Essa matéria já está\
sendo acompanhada por este e-mail.')})
return HttpResponseRedirect(self.get_success_url())
else:
return self.render_to_response(
{'form': form,
'materia': materia})
def get_success_url(self):
return reverse('sapl.materia:materialegislativa_detail',
kwargs={'pk': self.kwargs['pk']})
class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
filterset_class = AcessorioEmLoteFilterSet
template_name = 'materia/em_lote/acessorio.html'
permission_required = ('materia.add_documentoacessorio',)
def get_context_data(self, **kwargs):
context = super(DocumentoAcessorioEmLoteView,
self).get_context_data(**kwargs)
context['title'] = _('Documentos Acessórios em Lote')
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
qr = self.request.GET.copy()
context['tipos_docs'] = TipoDocumento.objects.all()
8 years ago
context['object_list'] = context['object_list'].order_by(
'ano', 'numero')
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
return context
def post(self, request, *args, **kwargs):
marcadas = request.POST.getlist('materia_id')
if len(marcadas) == 0:
msg = _('Nenhuma máteria foi selecionada.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
tipo = TipoDocumento.objects.get(descricao=request.POST['tipo'])
for materia_id in marcadas:
doc = DocumentoAcessorio()
doc.materia_id = materia_id
doc.tipo = tipo
doc.arquivo = request.FILES['arquivo']
doc.nome = request.POST['nome']
doc.data = datetime.strptime(request.POST['data'], "%d/%m/%Y")
doc.autor = request.POST['autor']
doc.ementa = request.POST['ementa']
doc.save()
msg = _('Documento(s) criado(s).')
messages.add_message(request, messages.SUCCESS, msg)
return self.get(request, self.kwargs)
class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView):
filterset_class = PrimeiraTramitacaoEmLoteFilterSet
template_name = 'materia/em_lote/tramitacao.html'
permission_required = ('materia.add_tramitacao', )
def get_context_data(self, **kwargs):
context = super(PrimeiraTramitacaoEmLoteView,
self).get_context_data(**kwargs)
context['subnav_template_name'] = 'materia/em_lote/subnav_em_lote.yaml'
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
9 years ago
context['title'] = _('Primeira Tramitação em Lote')
qr = self.request.GET.copy()
9 years ago
context['unidade_destino'] = UnidadeTramitacao.objects.all()
context['status_tramitacao'] = StatusTramitacao.objects.all()
context['turnos_tramitacao'] = TURNO_TRAMITACAO_CHOICES
context['urgente_tramitacao'] = YES_NO_CHOICES
context['unidade_local'] = UnidadeTramitacao.objects.all()
8 years ago
context['primeira_tramitacao'] = True
# Pega somente matéria que não possuem tramitação
9 years ago
if (type(self.__dict__['filterset']).__name__ ==
'PrimeiraTramitacaoEmLoteFilterSet'):
context['object_list'] = context['object_list'].filter(
tramitacao__isnull=True)
else:
context['title'] = _('Tramitação em Lote')
context['unidade_local'] = [UnidadeTramitacao.objects.get(
8 years ago
id=qr['tramitacao__unidade_tramitacao_destino'])]
8 years ago
context['object_list'] = context['object_list'].order_by(
'ano', 'numero')
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
return context
def post(self, request, *args, **kwargs):
marcadas = request.POST.getlist('materia_id')
if len(marcadas) == 0:
msg = _('Nenhuma máteria foi selecionada.')
messages.add_message(request, messages.ERROR, msg)
return self.get(request, self.kwargs)
if request.POST['data_encaminhamento']:
data_encaminhamento = datetime.strptime(
request.POST['data_encaminhamento'], "%d/%m/%Y")
else:
data_encaminhamento = None
if request.POST['data_fim_prazo']:
data_fim_prazo = datetime.strptime(
request.POST['data_fim_prazo'], "%d/%m/%Y")
else:
data_fim_prazo = None
8 years ago
# issue https://github.com/interlegis/sapl/issues/1123
# TODO: usar Form
urgente = request.POST['urgente'] == 'True'
for materia_id in marcadas:
8 years ago
t = Tramitacao(
materia_id=materia_id,
data_tramitacao=datetime.strptime(
request.POST['data_tramitacao'], "%d/%m/%Y"),
data_encaminhamento=data_encaminhamento,
data_fim_prazo=data_fim_prazo,
unidade_tramitacao_local_id=request.POST[
'unidade_tramitacao_local'],
unidade_tramitacao_destino_id=request.POST[
'unidade_tramitacao_destino'],
8 years ago
urgente=urgente,
status_id=request.POST['status'],
turno=request.POST['turno'],
texto=request.POST['texto']
)
8 years ago
t.save()
msg = _('Tramitação completa.')
messages.add_message(request, messages.SUCCESS, msg)
return self.get(request, self.kwargs)
class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView):
filterset_class = TramitacaoEmLoteFilterSet
8 years ago
def get_context_data(self, **kwargs):
context = super(TramitacaoEmLoteView,
self).get_context_data(**kwargs)
qr = self.request.GET.copy()
8 years ago
context['primeira_tramitacao'] = False
8 years ago
if ('tramitacao__status' in qr and
'tramitacao__unidade_tramitacao_destino' in qr and
qr['tramitacao__status'] and
qr['tramitacao__unidade_tramitacao_destino']
):
8 years ago
lista = filtra_tramitacao_destino_and_status(
qr['tramitacao__status'],
qr['tramitacao__unidade_tramitacao_destino'])
context['object_list'] = context['object_list'].filter(
id__in=lista).distinct()
8 years ago
return context