@ -1,13 +1,11 @@
from datetime import datetime
import itertools
import logging
import logging
import os
import os
import shutil
import tempfile
import weasyprint
import itertools
from datetime import datetime
from random import choice
from random import choice
import shutil
from string import ascii_letters , digits
from string import ascii_letters , digits
import tempfile
from crispy_forms . layout import HTML
from crispy_forms . layout import HTML
from django . conf import settings
from django . conf import settings
@ -28,6 +26,7 @@ from django.views.generic.base import RedirectView
from django . views . generic . edit import FormView
from django . views . generic . edit import FormView
from django_filters . views import FilterView
from django_filters . views import FilterView
import weasyprint
import weasyprint
import weasyprint
import sapl
import sapl
from sapl . base . email_utils import do_envia_email_confirmacao
from sapl . base . email_utils import do_envia_email_confirmacao
@ -47,11 +46,12 @@ from sapl.materia.forms import (AnexadaForm, AutoriaForm,
ConfirmarProposicaoForm ,
ConfirmarProposicaoForm ,
DevolverProposicaoForm , LegislacaoCitadaForm ,
DevolverProposicaoForm , LegislacaoCitadaForm ,
OrgaoForm , ProposicaoForm , TipoProposicaoForm ,
OrgaoForm , ProposicaoForm , TipoProposicaoForm ,
TramitacaoForm , TramitacaoUpdateForm , MateriaPesquisaSimplesForm )
TramitacaoForm , TramitacaoUpdateForm , MateriaPesquisaSimplesForm ,
DespachoInicialCreateForm )
from sapl . norma . models import LegislacaoCitada
from sapl . norma . models import LegislacaoCitada
from sapl . parlamentares . models import Legislatura
from sapl . parlamentares . models import Legislatura
from sapl . protocoloadm . models import Protocolo
from sapl . protocoloadm . models import Protocolo
from sapl . settings import MEDIA_ROOT
from sapl . settings import MEDIA_ROOT , MAX_DOC_UPLOAD_SIZE
from sapl . utils import ( YES_NO_CHOICES , autor_label , autor_modal , SEPARADOR_HASH_PROPOSICAO ,
from sapl . utils import ( YES_NO_CHOICES , autor_label , autor_modal , SEPARADOR_HASH_PROPOSICAO ,
gerar_hash_arquivo , get_base_url , get_client_ip ,
gerar_hash_arquivo , get_base_url , get_client_ip ,
get_mime_type_from_file_extension , montar_row_autor ,
get_mime_type_from_file_extension , montar_row_autor ,
@ -69,7 +69,8 @@ from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
filtra_tramitacao_destino ,
filtra_tramitacao_destino ,
filtra_tramitacao_destino_and_status ,
filtra_tramitacao_destino_and_status ,
filtra_tramitacao_status ,
filtra_tramitacao_status ,
ExcluirTramitacaoEmLote , compara_tramitacoes_mat )
ExcluirTramitacaoEmLote , compara_tramitacoes_mat ,
TramitacaoEmLoteForm )
from . models import ( AcompanhamentoMateria , Anexada , AssuntoMateria , Autoria ,
from . models import ( AcompanhamentoMateria , Anexada , AssuntoMateria , Autoria ,
DespachoInicial , DocumentoAcessorio , MateriaAssunto ,
DespachoInicial , DocumentoAcessorio , MateriaAssunto ,
MateriaLegislativa , Numeracao , Orgao , Origem , Proposicao ,
MateriaLegislativa , Numeracao , Orgao , Origem , Proposicao ,
@ -1203,7 +1204,8 @@ class TramitacaoCrud(MasterDetailCrud):
' -timestamp ' ,
' -timestamp ' ,
' -id ' ) . first ( )
' -id ' ) . first ( )
#TODO: Esta checagem foi inserida na issue #2027, mas é mesmo necessária?
# TODO: Esta checagem foi inserida na issue #2027, mas é mesmo
# necessária?
if ultima_tramitacao :
if ultima_tramitacao :
if ultima_tramitacao . unidade_tramitacao_destino :
if ultima_tramitacao . unidade_tramitacao_destino :
context [ ' form ' ] . fields [
context [ ' form ' ] . fields [
@ -1257,7 +1259,8 @@ class TramitacaoCrud(MasterDetailCrud):
layout_key = ' TramitacaoUpdate '
layout_key = ' TramitacaoUpdate '
def form_valid ( self , form ) :
def form_valid ( self , form ) :
dict_objeto_antigo = Tramitacao . objects . get ( pk = self . kwargs [ ' pk ' ] ) . __dict__
dict_objeto_antigo = Tramitacao . objects . get (
pk = self . kwargs [ ' pk ' ] ) . __dict__
self . object = form . save ( )
self . object = form . save ( )
dict_objeto_novo = self . object . __dict__
dict_objeto_novo = self . object . __dict__
@ -1269,7 +1272,8 @@ class TramitacaoCrud(MasterDetailCrud):
' data_encaminhamento ' , ' data_fim_prazo ' , ' urgente ' , ' turno '
' data_encaminhamento ' , ' data_fim_prazo ' , ' urgente ' , ' turno '
]
]
# Se não houve qualquer alteração em um dos dados, mantém o usuário e ip
# Se não houve qualquer alteração em um dos dados, mantém o usuário
# e ip
for atributo in atributos :
for atributo in atributos :
if dict_objeto_antigo [ atributo ] != dict_objeto_novo [ atributo ] :
if dict_objeto_antigo [ atributo ] != dict_objeto_novo [ atributo ] :
self . object . user = user
self . object . user = user
@ -1331,7 +1335,8 @@ class TramitacaoCrud(MasterDetailCrud):
if materia . tramitacao_set . count ( ) == 0 :
if materia . tramitacao_set . count ( ) == 0 :
materia . em_tramitacao = False
materia . em_tramitacao = False
materia . save ( )
materia . save ( )
tramitar_anexadas = sapl . base . models . AppConfig . attr ( ' tramitacao_materia ' )
tramitar_anexadas = sapl . base . models . AppConfig . attr (
' tramitacao_materia ' )
if tramitar_anexadas :
if tramitar_anexadas :
mat_anexadas = lista_anexados ( materia )
mat_anexadas = lista_anexados ( materia )
for ma in mat_anexadas :
for ma in mat_anexadas :
@ -1484,20 +1489,58 @@ class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView):
autores_selecionados = form . cleaned_data [ ' autor ' ]
autores_selecionados = form . cleaned_data [ ' autor ' ]
primeiro_autor = form . cleaned_data [ ' primeiro_autor ' ]
primeiro_autor = form . cleaned_data [ ' primeiro_autor ' ]
for autor in autores_selecionados :
for autor in autores_selecionados :
Autoria . objects . create ( materia = self . materia , autor = autor , primeiro_autor = primeiro_autor )
Autoria . objects . create ( materia = self . materia ,
autor = autor , primeiro_autor = primeiro_autor )
return FormView . form_valid ( self , form )
return FormView . form_valid ( self , form )
class DespachoInicialMultiCreateView ( PermissionRequiredForAppCrudMixin , FormView ) :
app_label = sapl . materia . apps . AppConfig . label
form_class = DespachoInicialCreateForm
template_name = ' materia/despachoinicial_multicreate_form.html '
def get_initial ( self ) :
initial = super ( ) . get_initial ( )
self . materia = MateriaLegislativa . objects . get ( id = self . kwargs [ ' pk ' ] )
initial [ ' materia ' ] = self . materia
return initial
def get_context_data ( self , * * kwargs ) :
context = super ( ) . get_context_data ( * * kwargs )
context [ ' title ' ] = ' %s <small>( %s )</small> ' % (
_ ( ' Adicionar Vários Despachos ' ) , self . materia )
context [ ' root_pk ' ] = self . kwargs [ ' pk ' ]
context [ ' subnav_template_name ' ] = ' materia/subnav.yaml '
return context
def get_success_url ( self ) :
messages . add_message (
self . request , messages . SUCCESS ,
_ ( ' Despachos adicionados com sucesso. ' ) )
return reverse (
' sapl.materia:despachoinicial_list ' , kwargs = { ' pk ' : self . materia . pk } )
def form_valid ( self , form ) :
comissoes_selecionadas = form . cleaned_data [ ' comissao ' ]
for comissao in comissoes_selecionadas :
DespachoInicial . objects . create (
materia = self . materia , comissao = comissao )
return FormView . form_valid ( self , form )
@property
def cancel_url ( self ) :
return reverse (
' sapl.materia:despachoinicial_list ' , kwargs = { ' pk ' : self . materia . pk } )
class DespachoInicialCrud ( MasterDetailCrud ) :
class DespachoInicialCrud ( MasterDetailCrud ) :
model = DespachoInicial
model = DespachoInicial
parent_field = ' materia '
parent_field = ' materia '
help_topic = ' despacho_autoria '
help_topic = ' despacho_autoria '
public = [ RP_LIST , RP_DETAIL ]
public = [ RP_LIST , RP_DETAIL ]
class CreateView ( MasterDetailCrud . CreateView ) :
form_class = DespachoInicialForm
class UpdateView ( MasterDetailCrud . UpdateView ) :
class UpdateView ( MasterDetailCrud . UpdateView ) :
form_class = DespachoInicialForm
form_class = DespachoInicialForm
@ -1620,7 +1663,7 @@ class MateriaLegislativaCrud(Crud):
form_class = MateriaLegislativaForm
form_class = MateriaLegislativaForm
def get_initial ( self ) :
def get_initial ( self ) :
initial = super ( CreateView , self ) . get_initial ( )
initial = super ( ) . get_initial ( )
initial [ ' user ' ] = self . request . user
initial [ ' user ' ] = self . request . user
initial [ ' ip ' ] = get_client_ip ( self . request )
initial [ ' ip ' ] = get_client_ip ( self . request )
@ -1686,7 +1729,8 @@ class MateriaLegislativaCrud(Crud):
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
context = super ( ) . get_context_data ( * * kwargs )
context = super ( ) . get_context_data ( * * kwargs )
context [ ' user ' ] = self . request . user
context [ ' user ' ] = self . request . user
context [ ' materia ' ] = MateriaLegislativa . objects . get ( pk = self . kwargs [ ' pk ' ] )
context [ ' materia ' ] = MateriaLegislativa . objects . get (
pk = self . kwargs [ ' pk ' ] )
return context
return context
class ListView ( Crud . ListView , RedirectView ) :
class ListView ( Crud . ListView , RedirectView ) :
@ -2074,6 +2118,13 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
messages . add_message ( request , messages . ERROR , msg )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
return self . get ( request , self . kwargs )
if request . FILES [ ' arquivo ' ] . size > MAX_DOC_UPLOAD_SIZE :
msg = _ ( " O arquivo Anexo de Texto Integral deve ser menor que {0:.1f} MB, \
o tamanho atual desse arquivo é { 1 : .1 f } MB " \
. format ( ( MAX_DOC_UPLOAD_SIZE / 1024 ) / 1024 , ( request . FILES [ ' arquivo ' ] . size / 1024 ) / 1024 ) )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
tmp_name = os . path . join ( MEDIA_ROOT , request . FILES [ ' arquivo ' ] . name )
tmp_name = os . path . join ( MEDIA_ROOT , request . FILES [ ' arquivo ' ] . name )
with open ( tmp_name , ' wb ' ) as destination :
with open ( tmp_name , ' wb ' ) as destination :
for chunk in request . FILES [ ' arquivo ' ] . chunks ( ) :
for chunk in request . FILES [ ' arquivo ' ] . chunks ( ) :
@ -2082,9 +2133,11 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
doc_data = tz . localize ( datetime . strptime (
doc_data = tz . localize ( datetime . strptime (
request . POST [ ' data ' ] , " %d / % m/ % Y " ) )
request . POST [ ' data ' ] , " %d / % m/ % Y " ) )
except Exception as e :
except Exception as e :
msg = _ ( ' Formato da data incorreto. O formato deve ser da forma dd/mm/aaaa. ' )
msg = _ (
' Formato da data incorreto. O formato deve ser da forma dd/mm/aaaa. ' )
messages . add_message ( request , messages . ERROR , msg )
messages . add_message ( request , messages . ERROR , msg )
self . logger . error ( " User= {} . {} . Data inserida: {} " . format ( username , str ( msg ) , request . POST [ ' data ' ] ) )
self . logger . error ( " User= {} . {} . Data inserida: {} " . format (
username , str ( msg ) , request . POST [ ' data ' ] ) )
os . remove ( tmp_name )
os . remove ( tmp_name )
return self . get ( request , self . kwargs )
return self . get ( request , self . kwargs )
@ -2100,12 +2153,13 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
try :
try :
doc . clean_fields ( )
doc . clean_fields ( )
except ValidationError as e :
except ValidationError as e :
for m in [ ' %s : %s ' % ( DocumentoAcessorio ( ) . _meta . get_field ( k ) . verbose_name , ' </br> ' . join ( v ) )
for m in [ ' %s : %s ' % ( DocumentoAcessorio ( ) . _meta . get_field ( k ) . verbose_name , ' </br> ' . join ( v ) )
for k , v in e . message_dict . items ( ) ] :
for k , v in e . message_dict . items ( ) ] :
# Insere as mensagens de erro no formato:
# Insere as mensagens de erro no formato:
# 'verbose_name do nome do campo': 'mensagem de erro'
# 'verbose_name do nome do campo': 'mensagem de erro'
messages . add_message ( request , messages . ERROR , m )
messages . add_message ( request , messages . ERROR , m )
self . logger . error ( " User= {} . {} . Nome do arquivo: {} . " . format ( username , str ( msg ) , request . FILES [ ' arquivo ' ] . name ) )
self . logger . error ( " User= {} . {} . Nome do arquivo: {} . " . format (
username , str ( msg ) , request . FILES [ ' arquivo ' ] . name ) )
os . remove ( tmp_name )
os . remove ( tmp_name )
return self . get ( request , self . kwargs )
return self . get ( request , self . kwargs )
doc . save ( )
doc . save ( )
@ -2118,7 +2172,8 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView):
file_path = os . path . join ( diretorio ,
file_path = os . path . join ( diretorio ,
request . FILES [ ' arquivo ' ] . name )
request . FILES [ ' arquivo ' ] . name )
shutil . copy2 ( tmp_name , file_path )
shutil . copy2 ( tmp_name , file_path )
doc . arquivo . name = file_path . split ( MEDIA_ROOT + " / " ) [ 1 ] # Retira MEDIA_ROOT do nome
doc . arquivo . name = file_path . split (
MEDIA_ROOT + " / " ) [ 1 ] # Retira MEDIA_ROOT do nome
doc . save ( )
doc . save ( )
os . remove ( tmp_name )
os . remove ( tmp_name )
@ -2144,17 +2199,17 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView):
# Verifica se os campos foram preenchidos
# Verifica se os campos foram preenchidos
if not self . request . GET . get ( ' tipo ' , " " ) :
if not self . request . GET . get ( ' tipo ' , " " ) :
msg = _ ( ' Por favor, selecione um tipo de matéria. ' )
msg = _ ( ' Por favor, selecione um tipo de matéria. ' )
messages . add_message ( self . request , messages . ERROR , msg )
messages . add_message ( self . request , messages . ERROR , msg )
if not self . request . GET . get ( ' data_apresentacao_0 ' , " " ) or not self . request . GET . get ( ' data_apresentacao_1 ' , " " ) :
if not self . request . GET . get ( ' data_apresentacao_0 ' , " " ) or not self . request . GET . get ( ' data_apresentacao_1 ' , " " ) :
msg = _ ( ' Por favor, preencha as datas. ' )
msg = _ ( ' Por favor, preencha as datas. ' )
messages . add_message ( self . request , messages . ERROR , msg )
messages . add_message ( self . request , messages . ERROR , msg )
return context
return context
if not self . request . GET . get ( ' data_apresentacao_0 ' , " " ) or not self . request . GET . get ( ' data_apresentacao_1 ' , " " ) :
if not self . request . GET . get ( ' data_apresentacao_0 ' , " " ) or not self . request . GET . get ( ' data_apresentacao_1 ' , " " ) :
msg = _ ( ' Por favor, preencha as datas. ' )
msg = _ ( ' Por favor, preencha as datas. ' )
messages . add_message ( self . request , messages . ERROR , msg )
messages . add_message ( self . request , messages . ERROR , msg )
return context
return context
@ -2163,8 +2218,10 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView):
' numero ' , ' -ano ' )
' numero ' , ' -ano ' )
principal = MateriaLegislativa . objects . get ( pk = self . kwargs [ ' pk ' ] )
principal = MateriaLegislativa . objects . get ( pk = self . kwargs [ ' pk ' ] )
not_list = [ self . kwargs [ ' pk ' ] ] + \
not_list = [ self . kwargs [ ' pk ' ] ] + \
[ m for m in principal . materia_principal_set . all ( ) . values_list ( ' materia_anexada_id ' , flat = True ) ]
[ m for m in principal . materia_principal_set . all (
context [ ' object_list ' ] = context [ ' object_list ' ] . exclude ( pk__in = not_list )
) . values_list ( ' materia_anexada_id ' , flat = True ) ]
context [ ' object_list ' ] = context [ ' object_list ' ] . exclude (
pk__in = not_list )
context [ ' temp_object_list ' ] = context [ ' object_list ' ]
context [ ' temp_object_list ' ] = context [ ' object_list ' ]
context [ ' object_list ' ] = [ ]
context [ ' object_list ' ] = [ ]
@ -2172,7 +2229,7 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView):
materia_anexada = obj
materia_anexada = obj
ciclico = False
ciclico = False
anexadas_anexada = Anexada . objects . filter (
anexadas_anexada = Anexada . objects . filter (
materia_principal = materia_anexada
materia_principal = materia_anexada
)
)
while anexadas_anexada and not ciclico :
while anexadas_anexada and not ciclico :
@ -2241,7 +2298,8 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView):
msg = _ ( ' Matéria(s) anexada(s). ' )
msg = _ ( ' Matéria(s) anexada(s). ' )
messages . add_message ( request , messages . SUCCESS , msg )
messages . add_message ( request , messages . SUCCESS , msg )
success_url = reverse ( ' sapl.materia:anexada_list ' , kwargs = { ' pk ' : kwargs [ ' pk ' ] } )
success_url = reverse ( ' sapl.materia:anexada_list ' ,
kwargs = { ' pk ' : kwargs [ ' pk ' ] } )
return HttpResponseRedirect ( success_url )
return HttpResponseRedirect ( success_url )
@ -2254,39 +2312,34 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView):
logger = logging . getLogger ( __name__ )
logger = logging . getLogger ( __name__ )
def get_context_data ( self , * * kwargs ) :
def get_context_data ( self , * * kwargs ) :
context = super ( PrimeiraTramitacaoEmLoteView ,
context = super ( PrimeiraTramitacaoEmLoteView ,
self ) . get_context_data ( * * kwargs )
self ) . get_context_data ( * * kwargs )
context [ ' subnav_template_name ' ] = ' materia/em_lote/subnav_em_lote.yaml '
context [ ' subnav_template_name ' ] = ' materia/em_lote/subnav_em_lote.yaml '
context [ ' primeira_tramitacao ' ] = self . primeira_tramitacao
# Verifica se os campos foram preenchidos
# Verifica se os campos foram preenchidos
if not self . filterset . form . is_valid ( ) :
if not self . filterset . form . is_valid ( ) :
return context
return context
context [ ' title ' ] = _ ( ' Primeira Tramitação em Lote ' )
context [ ' objec t_l is t' ] = context [ ' object_list ' ] . order_by (
' ano ' , ' numero ' )
qr = self . request . GET . copy ( )
qr = self . request . GET . copy ( )
context [ ' unidade_destino ' ] = UnidadeTramitacao . objects . all ( )
context [ ' status_tramitacao ' ] = StatusTramitacao . objects . all ( )
context [ ' turnos_tramitacao ' ] = Tramitacao . TURNO_CHOICES
context [ ' urgente_tramitacao ' ] = YES_NO_CHOICES
context [ ' unidade_local ' ] = UnidadeTramitacao . objects . all ( )
context [ ' primeira_tramitacao ' ] = True
form = TramitacaoEmLoteForm ( )
context [ ' form ' ] = form
# Pega somente matéria que não possuem tramitação
if self . primeira_tramitacao :
if ( type ( self . __dict__ [ ' filterset ' ] ) . __name__ ==
context [ ' title ' ] = _ ( ' Primeira Tramitação em Lote ' )
' PrimeiraTramitacaoEmLoteFilterSet ' ) :
# Pega somente documentos que não possuem tramitação
context [ ' object_list ' ] = context [ ' object_list ' ] . filter (
context [ ' object_list ' ] = [ obj for obj in context [ ' object_list ' ]
tramitacao__isnull = True )
if obj . tramitacao_set . all ( ) . count ( ) == 0 ]
else :
else :
context [ ' title ' ] = _ ( ' Tramitação em Lote ' )
context [ ' title ' ] = _ ( ' Tramitação em Lote ' )
context [ ' unidade_local ' ] = [ UnidadeTramitacao . objects . get (
context [ ' form ' ] . fields [ ' unidade_tramitacao_local ' ] . initial = UnidadeTramitacao . objects . get (
id = qr [ ' tramitacao__unidade_tramitacao_destino ' ] ) ]
id = qr [ ' tramitacao__unidade_tramitacao_destino ' ] )
context [ ' object_list ' ] = context [ ' object_list ' ] . order_by (
' ano ' , ' numero ' )
context [ ' filter_url ' ] = ( ' & ' + qr . urlencode ( ) ) if len ( qr ) > 0 else ' '
context [ ' filter_url ' ] = ( ' & ' + qr . urlencode ( ) ) if len ( qr ) > 0 else ' '
@ -2295,127 +2348,43 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView):
return context
return context
def post ( self , request , * args , * * kwargs ) :
def post ( self , request , * args , * * kwargs ) :
user = request . user
ip = get_client_ip ( request )
marcadas = request . POST . getlist ( ' materia_id ' )
materias_ids = request . POST . getlist ( ' materias ' )
if not materias_ids :
tz = timezone . get_current_timezone ( )
msg = _ ( " Escolha alguma matéria para ser tramitada. " )
username = request . user . username
if len ( marcadas ) == 0 :
msg = _ ( ' Nenhuma máteria foi selecionada. ' )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
obrigatorios = { ' data_tramitacao ' : ' Data da Tramitação ' ,
' unidade_tramitacao_local ' : ' Unidade Local ' ,
' unidade_tramitacao_destino ' : ' Unidade Destino ' ,
' status ' : ' Status ' ,
' urgente ' : ' Urgente ' ,
' texto ' : ' Texto da Ação ' }
for field , nome in obrigatorios . items ( ) :
if not request . POST [ field ] :
msg = _ ( ' Campo {} deve ser preenchido. ' . format ( nome ) )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
if not request . POST [ ' data_encaminhamento ' ] :
data_encaminhamento = None
else :
try :
data_encaminhamento = tz . localize ( datetime . strptime (
request . POST [ ' data_encaminhamento ' ] , " %d / % m/ % Y " ) )
except ValueError :
msg = _ ( ' Formato da data de encaminhamento incorreto. ' )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
if request . POST [ ' data_fim_prazo ' ] == ' ' :
data_fim_prazo = None
else :
try :
data_fim_prazo = tz . localize ( datetime . strptime (
request . POST [ ' data_fim_prazo ' ] , " %d / % m/ % Y " ) )
except ValueError :
msg = _ ( ' Formato da data fim do prazo incorreto. ' )
messages . add_message ( request , messages . ERROR , msg )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
return self . get ( request , self . kwargs )
# issue https://github.com/interlegis/sapl/issues/1123
form = TramitacaoEmLoteForm ( request . POST ,
# TODO: usar Form
initial = { ' materias ' : materias_ids ,
urgente = request . POST [ ' urgente ' ] == ' True '
' user ' : user , ' ip ' : ip } )
flag_error = False
materias_principais = [ m for m in MateriaLegislativa . objects . filter ( id__in = marcadas ) ]
if form . is_valid ( ) :
tramitar_anexadas = sapl . base . models . AppConfig . attr ( ' tramitacao_materia ' )
form . save ( )
materias_anexadas = [ ]
if tramitar_anexadas :
for materia in materias_principais :
materias_anexadas = materias_anexadas + lista_anexados ( materia )
materias = set ( materias_principais + materias_anexadas )
msg = _ ( ' Tramitação completa. ' )
self . logger . info ( ' user= ' + user . username + ' . Tramitação completa. ' )
messages . add_message ( request , messages . SUCCESS , msg )
return self . get_success_url ( )
for materia in materias :
return self . form_invalid ( form )
try :
data_tramitacao = tz . localize ( datetime . strptime (
request . POST [ ' data_tramitacao ' ] , " %d / % m/ % Y " ) )
except ValueError :
msg = _ ( ' Formato da data da tramitação incorreto. ' )
messages . add_message ( request , messages . ERROR , msg )
return self . get ( request , self . kwargs )
user = request . user
ip = get_client_ip ( request )
t = Tramitacao (
materia = materia ,
data_tramitacao = data_tramitacao ,
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 ' ] ,
urgente = urgente ,
status_id = request . POST [ ' status ' ] ,
turno = request . POST [ ' turno ' ] ,
texto = request . POST [ ' texto ' ] ,
user = user ,
ip = ip
)
t . save ( )
try :
self . logger . debug ( " user= " + username +
" . Tentando enviar tramitação. " )
tramitacao_signal . send ( sender = Tramitacao ,
post = t ,
request = self . request )
except Exception as e :
def get_success_url ( self ) :
self . logger . error ( ' user= ' + username + ' . Tramitação criada , mas e-mail de acompanhamento '
return HttpResponseRedirect ( reverse ( ' sapl.materia:primeira_tramitacao_em_lote ' ) )
' de matéria não enviado. Há problemas na configuração '
' do e-mail. ' + str ( e ) )
flag_error = True
if flag_error :
msg = _ ( ' Tramitação criada, mas e-mail de acompanhamento '
' de matéria não enviado. A não configuração do servidor de e-mail '
' impede o envio de aviso de tramitação ' )
messages . add_message ( self . request , messages . WARNING , msg )
status = StatusTramitacao . objects . get ( id = request . POST [ ' status ' ] )
for materia in materias :
def form_invalid ( self , form , * args , * * kwargs ) :
if status . indicador == ' F ' :
for key , erros in form . errors . items ( ) :
materia . em_tramitacao = False
if not key == ' __all__ ' :
elif self . primeira_tramitacao :
[ messages . add_message ( self . request , messages . ERROR , form . fields [ key ] . label + " : " + e ) for e in erros ]
materia . em_tramitacao = True
else :
materia . save ( )
[ messages . add_message ( self . request , messages . ERROR , e ) for e in erros ]
return self . get ( self . request , kwargs , { ' form ' : form } )
msg = _ ( ' Tramitação completa. ' + " Foram tramitadas " + str ( len ( materias ) ) + " matéria(s). " )
self . logger . info ( ' user= ' + username + ' . Tramitação completa. ' )
messages . add_message ( request , messages . SUCCESS , msg )
if self . primeira_tramitacao :
return HttpResponseRedirect ( reverse ( ' sapl.materia:primeira_tramitacao_em_lote ' ) )
return HttpResponseRedirect ( reverse ( ' sapl.materia:tramitacao_em_lote ' ) )
class TramitacaoEmLoteView ( PrimeiraTramitacaoEmLoteView ) :
class TramitacaoEmLoteView ( PrimeiraTramitacaoEmLoteView ) :
filterset_class = TramitacaoEmLoteFilterSet
filterset_class = TramitacaoEmLoteFilterSet
@ -2428,7 +2397,7 @@ class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView):
qr = self . request . GET . copy ( )
qr = self . request . GET . copy ( )
context [ ' primeira_tramitacao ' ] = False
context [ ' primeira_tramitacao ' ] = self . primeira_tramitacao
if ( ' tramitacao__status ' in qr and
if ( ' tramitacao__status ' in qr and
' tramitacao__unidade_tramitacao_destino ' in qr and
' tramitacao__unidade_tramitacao_destino ' in qr and