diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
index 417352b1d..38f3b0182 100644
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -1511,6 +1511,203 @@ class TipoProposicaoSelect(Select):
return option
+class TramitacaoEmLoteForm(ModelForm):
+ logger = logging.getLogger(__name__)
+
+ class Meta:
+ model = Tramitacao
+ fields = ['data_tramitacao',
+ 'unidade_tramitacao_local',
+ 'status',
+ 'urgente',
+ 'turno',
+ 'unidade_tramitacao_destino',
+ 'data_encaminhamento',
+ 'data_fim_prazo',
+ 'texto',
+ 'user',
+ 'ip']
+ widgets = {'user': forms.HiddenInput(),
+ 'ip': forms.HiddenInput()}
+
+
+ def __init__(self, *args, **kwargs):
+ super(TramitacaoEmLoteForm, self).__init__(*args, **kwargs)
+ self.fields['data_tramitacao'].initial = timezone.now().date()
+ ust = UnidadeTramitacao.objects.select_related().all()
+ unidade_tramitacao_destino = [('', '---------')] + [(ut.pk, ut)
+ for ut in ust if ut.comissao and ut.comissao.ativa]
+ unidade_tramitacao_destino.extend(
+ [(ut.pk, ut) for ut in ust if ut.orgao])
+ unidade_tramitacao_destino.extend(
+ [(ut.pk, ut) for ut in ust if ut.parlamentar])
+ self.fields['unidade_tramitacao_destino'].choices = unidade_tramitacao_destino
+ self.fields['urgente'].label = "Urgente? *"
+
+ row1 = to_row([
+ ('data_tramitacao', 4),
+ ('data_encaminhamento', 4),
+ ('data_fim_prazo', 4)
+ ])
+ row2 = to_row([
+ ('unidade_tramitacao_local', 6),
+ ('unidade_tramitacao_destino', 6),
+ ])
+ row3 = to_row([
+ ('status', 4),
+ ('urgente', 4),
+ ('turno', 4)
+ ])
+ row4 = to_row([
+ ('texto', 12)
+ ])
+
+ documentos_checkbox_HTML = '''
+
+
+ '''
+
+ self.helper = SaplFormHelper()
+ self.helper.layout = Layout(
+ Fieldset(
+ 'Detalhes da tramitação:',
+ row1, row2, row3, row4,
+ HTML(documentos_checkbox_HTML),
+ form_actions(label='Salvar')
+ )
+ )
+
+
+ def clean(self):
+ cleaned_data = super(TramitacaoEmLoteForm, self).clean()
+
+ if not self.is_valid():
+ return self.cleaned_data
+
+ if 'data_encaminhamento' in cleaned_data:
+ data_enc_form = cleaned_data['data_encaminhamento']
+ if 'data_fim_prazo' in cleaned_data:
+ data_prazo_form = cleaned_data['data_fim_prazo']
+ if 'data_tramitacao' in cleaned_data:
+ data_tram_form = cleaned_data['data_tramitacao']
+
+ if not self.instance.data_tramitacao:
+
+ if cleaned_data['data_tramitacao'] > timezone.now().date():
+ self.logger.error('A data de tramitação ({}) deve ser '
+ 'menor ou igual a data de hoje ({})!'
+ .format(cleaned_data['data_tramitacao'], timezone.now().date()))
+ msg = _(
+ 'A data de tramitação deve ser ' +
+ 'menor ou igual a data de hoje!')
+ raise ValidationError(msg)
+
+ if data_enc_form:
+ if data_enc_form < data_tram_form:
+ self.logger.error('A data de encaminhamento ({}) deve ser '
+ 'maior que a data de tramitação ({})!'
+ .format(data_enc_form, data_tram_form))
+ msg = _('A data de encaminhamento deve ser ' +
+ 'maior que a data de tramitação!')
+ raise ValidationError(msg)
+
+ if data_prazo_form:
+ if data_prazo_form < data_tram_form:
+ self.logger.error('A data fim de prazo ({}) deve ser '
+ 'maior que a data de tramitação ({})!'
+ .format(data_prazo_form, data_tram_form))
+ msg = _('A data fim de prazo deve ser ' +
+ 'maior que a data de tramitação!')
+ raise ValidationError(msg)
+
+ if cleaned_data['unidade_tramitacao_local'] == cleaned_data['unidade_tramitacao_destino']:
+ msg = _('Unidade tramitação local deve ser diferente da unidade tramitação destino.')
+ self.logger.error('Unidade tramitação local ({}) deve ser diferente da unidade tramitação destino'
+ .format(cleaned_data['unidade_tramitacao_local']))
+ raise ValidationError(msg)
+
+ return cleaned_data
+
+ @transaction.atomic
+ def save(self, commit=True):
+ cd = self.cleaned_data
+ materias = self.initial['materias']
+ user = self.initial['user'] if 'user' in self.initial else None
+ ip = self.initial['ip'] if 'ip' in self.initial else ''
+ tramitar_anexadas = AppConfig.attr('tramitacao_materia')
+ for mat_id in materias:
+ mat = MateriaLegislativa.objects.get(id=mat_id)
+ tramitacao = Tramitacao.objects.create(
+ status=cd['status'],
+ materia=mat,
+ data_tramitacao=cd['data_tramitacao'],
+ unidade_tramitacao_local=cd['unidade_tramitacao_local'],
+ unidade_tramitacao_destino=cd['unidade_tramitacao_destino'],
+ data_encaminhamento=cd['data_encaminhamento'],
+ urgente=cd['urgente'],
+ turno=cd['turno'],
+ texto=cd['texto'],
+ data_fim_prazo=cd['data_fim_prazo'],
+ user=user,
+ ip=ip
+ )
+ mat.em_tramitacao = False if tramitacao.status.indicador == "F" else True
+ mat.save()
+
+ if tramitar_anexadas:
+ lista_tramitacao = []
+ anexadas = lista_anexados(mat)
+ for ml in anexadas:
+ if not ml.tramitacao_set.all() \
+ or ml.tramitacao_set.last() \
+ .unidade_tramitacao_destino == tramitacao.unidade_tramitacao_local:
+ ml.em_tramitacao = False if tramitacao.status.indicador == "F" else True
+ ml.save()
+ lista_tramitacao.append(Tramitacao(
+ status=tramitacao.status,
+ materia=ml,
+ data_tramitacao=tramitacao.data_tramitacao,
+ unidade_tramitacao_local=tramitacao.unidade_tramitacao_local,
+ data_encaminhamento=tramitacao.data_encaminhamento,
+ unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino,
+ urgente=tramitacao.urgente,
+ turno=tramitacao.turno,
+ texto=tramitacao.texto,
+ data_fim_prazo=tramitacao.data_fim_prazo,
+ user=tramitacao.user,
+ ip=tramitacao.ip
+ ))
+ Tramitacao.objects.bulk_create(lista_tramitacao)
+
+ return tramitacao
+
+
class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm):
logger = logging.getLogger(__name__)
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
index 739f4c486..7e64c6dd0 100644
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -69,7 +69,8 @@ from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
filtra_tramitacao_destino,
filtra_tramitacao_destino_and_status,
filtra_tramitacao_status,
- ExcluirTramitacaoEmLote, compara_tramitacoes_mat)
+ ExcluirTramitacaoEmLote, compara_tramitacoes_mat,
+ TramitacaoEmLoteForm)
from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria,
DespachoInicial, DocumentoAcessorio, MateriaAssunto,
MateriaLegislativa, Numeracao, Orgao, Origem, Proposicao,
@@ -2254,39 +2255,34 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView):
logger = logging.getLogger(__name__)
+
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'
+ context['primeira_tramitacao'] = self.primeira_tramitacao
# Verifica se os campos foram preenchidos
if not self.filterset.form.is_valid():
return context
- context['title'] = _('Primeira Tramitação em Lote')
-
+ context['object_list'] = context['object_list'].order_by(
+ 'ano', 'numero')
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 (type(self.__dict__['filterset']).__name__ ==
- 'PrimeiraTramitacaoEmLoteFilterSet'):
- context['object_list'] = context['object_list'].filter(
- tramitacao__isnull=True)
+ if self.primeira_tramitacao:
+ context['title'] = _('Primeira Tramitação em Lote')
+ # Pega somente documentos que não possuem tramitação
+ context['object_list'] = [obj for obj in context['object_list']
+ if obj.tramitacao_set.all().count() == 0]
else:
context['title'] = _('Tramitação em Lote')
- context['unidade_local'] = [UnidadeTramitacao.objects.get(
- id=qr['tramitacao__unidade_tramitacao_destino'])]
-
- context['object_list'] = context['object_list'].order_by(
- 'ano', 'numero')
+ context['form'].fields['unidade_tramitacao_local'].initial = UnidadeTramitacao.objects.get(
+ id=qr['tramitacao__unidade_tramitacao_destino'])
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
@@ -2295,127 +2291,42 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView):
return context
def post(self, request, *args, **kwargs):
+ user = request.user
+ ip = get_client_ip(request)
- marcadas = request.POST.getlist('materia_id')
-
- tz = timezone.get_current_timezone()
-
- username = request.user.username
-
- if len(marcadas) == 0:
- msg = _('Nenhuma máteria foi selecionada.')
+ materias_ids = request.POST.getlist('materias')
+ if not materias_ids:
+ msg = _("Escolha alguma matéria para ser tramitada.")
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)
+ form = TramitacaoEmLoteForm(request.POST,
+ initial= {'materias': materias_ids,
+ 'user': user, 'ip':ip})
- 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)
- return self.get(request, self.kwargs)
+ if form.is_valid():
+ form.save()
- # issue https://github.com/interlegis/sapl/issues/1123
- # TODO: usar Form
- urgente = request.POST['urgente'] == 'True'
- flag_error = False
+ 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()
- materias_principais = [m for m in MateriaLegislativa.objects.filter(id__in=marcadas)]
- tramitar_anexadas = sapl.base.models.AppConfig.attr('tramitacao_materia')
- materias_anexadas = []
- if tramitar_anexadas:
- for materia in materias_principais:
- materias_anexadas = materias_anexadas + lista_anexados(materia)
+ return self.form_invalid(form)
- materias = set(materias_principais + materias_anexadas)
+
+ def get_success_url(self):
+ return HttpResponseRedirect(reverse('sapl.materia:primeira_tramitacao_em_lote'))
- for materia in materias:
- 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)
+ def form_invalid(self, form, *args, **kwargs):
+ for key, erros in form.errors.items():
+ if not key=='__all__':
+ [messages.add_message(self.request, messages.ERROR, form.fields[key].label + ": " + e) for e in erros]
+ else:
+ [messages.add_message(self.request, messages.ERROR, e) for e in erros]
+ return self.get(self.request, kwargs, {'form':form})
- except Exception as e:
- self.logger.error('user=' + username + '. Tramitação criada , mas e-mail de acompanhamento '
- '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:
- if status.indicador == 'F':
- materia.em_tramitacao = False
- elif self.primeira_tramitacao:
- materia.em_tramitacao = True
- materia.save()
-
- 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):
filterset_class = TramitacaoEmLoteFilterSet
@@ -2428,7 +2339,7 @@ class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView):
qr = self.request.GET.copy()
- context['primeira_tramitacao'] = False
+ context['primeira_tramitacao'] = self.primeira_tramitacao
if ('tramitacao__status' in qr and
'tramitacao__unidade_tramitacao_destino' in qr and
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
index 32f6748ad..e817fdcfc 100755
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -1545,7 +1545,7 @@ class TramitacaoEmLoteAdmView(PrimeiraTramitacaoEmLoteAdmView):
qr = self.request.GET.copy()
- context['primeira_tramitacao'] = False
+ context['primeira_tramitacao'] = self.primeira_tramitacao
if ('tramitacao__status' in qr and
'tramitacao__unidade_tramitacao_destino' in qr and
diff --git a/sapl/templates/materia/em_lote/tramitacao.html b/sapl/templates/materia/em_lote/tramitacao.html
index 5cc4a0b90..1c68274e6 100644
--- a/sapl/templates/materia/em_lote/tramitacao.html
+++ b/sapl/templates/materia/em_lote/tramitacao.html
@@ -1,134 +1,28 @@
{% extends "crud/detail.html" %}
{% load i18n crispy_forms_tags %}
-{% block actions %}{% endblock %}
{% block detail_content %}
- {% if not show_results %}
- {% crispy filter.form %}
- {% endif %}
-
- {% if show_results %}
- {% if object_list|length > 0 %}
- {% if object_list|length == 1 %}
- {% trans 'Pesquisa concluída com sucesso! Foi encontrada 1 matéria.'%}
- {% else %}
- Foram encontradas {{object_list|length}} matérias.
- {% endif %}
-
+ {% if not show_results %}
+ {% crispy filter.form %}
{% else %}
- Nenhuma matéria encontrada. |
- {% endif %}
- {% endif %}
+ {% if object_list|length > 0 %}
+ {% if object_list|length == 1 %}
+ {% trans 'Pesquisa concluída com sucesso! Foi encontrada 1 matéria.'%}
+ {% else %}
+ Foram encontradas {{object_list|length}} matérias.
+ {% endif %}
+ {% crispy form %}
+ {% else %}
+ Nenhuma matéria encontrada. |
+ {% endif %}
+
+ {% endif%}
{% endblock detail_content %}
+
{% block extra_js %}