Browse Source

Fix #2764 - Tramitacao em lote para Doc Adm

pull/2773/head
Cesar Carvalho 7 years ago
parent
commit
7a360c9008
  1. 7
      sapl/materia/views.py
  2. 211
      sapl/protocoloadm/forms.py
  3. 9
      sapl/protocoloadm/urls.py
  4. 187
      sapl/protocoloadm/views.py
  5. 8
      sapl/templates/navbar.yaml
  6. 5
      sapl/templates/protocoloadm/em_lote/subnav_em_lote.yaml
  7. 46
      sapl/templates/protocoloadm/em_lote/tramitacaoadm.html

7
sapl/materia/views.py

@ -1317,12 +1317,19 @@ class TramitacaoCrud(MasterDetailCrud):
return HttpResponseRedirect(url)
else:
tramitacoes_deletar = [tramitacao.id]
if materia.tramitacao_set.count() == 0:
materia.em_tramitacao = False
materia.save()
mat_anexadas = lista_anexados(materia)
for ma in mat_anexadas:
tram_anexada = ma.tramitacao_set.last()
if compara_tramitacoes_mat(tram_anexada, tramitacao):
tramitacoes_deletar.append(tram_anexada.id)
if ma.tramitacao_set.count() == 0:
ma.em_tramitacao = False
ma.save()
Tramitacao.objects.filter(id__in=tramitacoes_deletar).delete()
return HttpResponseRedirect(url)
class DetailView(MasterDetailCrud.DetailView):

211
sapl/protocoloadm/forms.py

@ -1407,3 +1407,214 @@ class FichaSelecionaAdmForm(forms.Form):
form_actions(label='Gerar Impresso')
)
)
class PrimeiraTramitacaoEmLoteAdmFilterSet(django_filters.FilterSet):
class Meta(FilterOverridesMetaMixin):
model = DocumentoAdministrativo
fields = ['tipo', 'data']
def __init__(self, *args, **kwargs):
super(PrimeiraTramitacaoEmLoteAdmFilterSet, self).__init__(
*args, **kwargs)
self.filters['tipo'].label = 'Tipo de Documento'
self.filters['data'].label = 'Data (Inicial - Final)'
self.form.fields['tipo'].required = True
self.form.fields['data'].required = False
row1 = to_row([('tipo', 12)])
row2 = to_row([('data', 12)])
self.form.helper = SaplFormHelper()
self.form.helper.form_method = 'GET'
self.form.helper.layout = Layout(
Fieldset(_('Primeira Tramitação'),
row1, row2, form_actions(label='Pesquisar')))
class PrimeiraTramitacaoEmLoteAdmForm(ModelForm):
logger = logging.getLogger(__name__)
class Meta:
model = TramitacaoAdministrativo
fields = ['data_tramitacao',
'unidade_tramitacao_local',
'status',
'urgente',
'unidade_tramitacao_destino',
'data_encaminhamento',
'data_fim_prazo',
'texto',
'user',
'ip']
widgets = {'user': forms.HiddenInput(),
'ip': forms.HiddenInput()}
def __init__(self, *args, **kwargs):
super(PrimeiraTramitacaoEmLoteAdmForm, 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', 6),
('urgente', 6)
])
row4 = to_row([
('texto', 12)
])
documentos_checkbox_HTML = '''
<br\><br\><br\>
<fieldset>
<legend style="font-size: 24px;">Selecione os documentos para tramitação:</legend>
<table class="table table-striped table-hover">
<div class="controls">
<div class="checkbox">
<label for="id_check_all">
<input type="checkbox" id="id_check_all" onchange="checkAll(this)" /> Marcar/Desmarcar Todos
</label>
</div>
</div>
<thead>
<tr><th>Documento</th></tr>
</thead>
<tbody>
{% for documento in object_list %}
<tr>
<td>
<input type="checkbox" name="documentos" value="{{documento.id}}" {% if check %} checked {% endif %}/>
<a href="{% url 'sapl.protocoloadm:documentoadministrativo_detail' documento.id %}">
{{documento.tipo.sigla}} {{documento.tipo.descricao}} {{documento.numero}}/{{documento.ano}}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>
'''
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(PrimeiraTramitacaoEmLoteAdmForm, 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.is_valid():
return cleaned_data
if not self.instance.data_tramitacao:
if self.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(self.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)
return self.cleaned_data
@transaction.atomic
def save(self, commit=True):
cd = self.cleaned_data
documentos = self.initial['documentos']
user = self.initial['user']
ip = self.initial['ip']
for doc_id in documentos:
doc = DocumentoAdministrativo.objects.get(id=doc_id)
tramitacao = TramitacaoAdministrativo.objects.create(
status=cd['status'],
documento=doc,
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'],
texto=cd['texto'],
data_fim_prazo=cd['data_fim_prazo'],
user=user,
ip=ip
)
doc.tramitacao = False if tramitacao.status.indicador == "F" else True
doc.save()
lista_tramitacao = []
for da in doc.anexados.all():
if not da.tramitacaoadministrativo_set.all() \
or da.tramitacaoadministrativo_set.last() \
.unidade_tramitacao_destino == tramitacao.unidade_tramitacao_local:
da.tramitacao = False if tramitacao.status.indicador == "F" else True
da.save()
lista_tramitacao.append(TramitacaoAdministrativo(
status=tramitacao.status,
documento=da,
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,
texto=tramitacao.texto,
data_fim_prazo=tramitacao.data_fim_prazo,
user=tramitacao.user,
ip=tramitacao.ip
))
TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao)
return tramitacao

9
sapl/protocoloadm/urls.py

@ -22,7 +22,8 @@ from sapl.protocoloadm.views import (AcompanhamentoDocumentoView,
doc_texto_integral,
DesvincularDocumentoView,
DesvincularMateriaView,
AnexadoCrud, DocumentoAnexadoEmLoteView)
AnexadoCrud, DocumentoAnexadoEmLoteView,
PrimeiraTramitacaoEmLoteAdmView)
from .apps import AppConfig
@ -98,6 +99,12 @@ urlpatterns_protocolo = [
url(r'^protocoloadm/recuperar-materia',
recuperar_materia_protocolo, name='recuperar_materia_protocolo'),
url(r'^protocoloadm/primeira-tramitacao-em-lote',
PrimeiraTramitacaoEmLoteAdmView.as_view(),
name='primeira_tramitacao_em_lote_docadm'),
# url(r'^protocoloadm/tramitacao-em-lote', TramitacaoEmLoteAdmView.as_view(),
# name='tramitacao_em_lote_docadm'),
]

187
sapl/protocoloadm/views.py

@ -47,6 +47,8 @@ from .forms import (AcompanhamentoDocumentoForm, AnularProtocoloAdmForm,
filtra_tramitacao_adm_destino_and_status,
filtra_tramitacao_adm_destino, filtra_tramitacao_adm_status,
AnexadoForm, AnexadoEmLoteFilterSet,
PrimeiraTramitacaoEmLoteAdmFilterSet,
PrimeiraTramitacaoEmLoteAdmForm,
compara_tramitacoes_doc)
from .models import (AcompanhamentoDocumento, DocumentoAcessorioAdministrativo,
DocumentoAdministrativo, StatusTramitacaoAdministrativo,
@ -1251,12 +1253,19 @@ class TramitacaoAdmCrud(MasterDetailCrud):
return HttpResponseRedirect(url)
else:
tramitacoes_deletar = [tramitacao.id]
if documento.tramitacaoadministrativo_set.count() == 0:
documento.tramitacao = False
documento.save()
docs_anexados = lista_anexados(documento, False)
for da in docs_anexados:
tram_anexada = da.tramitacaoadministrativo_set.last()
if compara_tramitacoes_doc(tram_anexada, tramitacao):
tramitacoes_deletar.append(tram_anexada.id)
if da.tramitacaoadministrativo_set.count() == 0:
da.tramitacao = False
da.save()
TramitacaoAdministrativo.objects.filter(id__in=tramitacoes_deletar).delete()
return HttpResponseRedirect(url)
@ -1437,3 +1446,181 @@ class FichaSelecionaAdmView(PermissionRequiredMixin, FormView):
return gerar_pdf_impressos(self.request, context,
'materia/impressos/ficha_adm_pdf.html')
class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView):
filterset_class = PrimeiraTramitacaoEmLoteAdmFilterSet
template_name = 'protocoloadm/em_lote/tramitacaoadm.html'
permission_required = ('materia.add_tramitacao', )
primeira_tramitacao = True
logger = logging.getLogger(__name__)
def get_context_data(self, **kwargs):
context = super(PrimeiraTramitacaoEmLoteAdmView,
self).get_context_data(**kwargs)
context['subnav_template_name'] = 'protocoloadm/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['object_list'] = context['object_list'].order_by(
'ano', 'numero')
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.tramitacaoadministrativo_set.all().count() == 0]
else:
context['title'] = _('Tramitação em Lote')
# context['unidade_local'] = [UnidadeTramitacao.objects.get(
# id=qr['tramitacao__unidade_tramitacao_destino'])]
qr = self.request.GET.copy()
form = PrimeiraTramitacaoEmLoteAdmForm()
context['form'] = form
context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else ''
context['show_results'] = show_results_filter_set(qr)
return context
def post(self, request, *args, **kwargs):
user = request.user
ip = get_client_ip(request)
documentos_ids = request.POST.getlist('documentos')
form = PrimeiraTramitacaoEmLoteAdmForm(request.POST, initial=
{'documentos': documentos_ids,
'user': user, 'ip':ip})
if form.is_valid():
cd = form.clean()
form.save()
msg = _('Tramitação completa.')
self.logger.info('user=' + user.username + '. Tramitação completa.')
messages.add_message(request, messages.SUCCESS, msg)
return self.get(request, self.kwargs)
# 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.')
# 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)
# return self.get(request, self.kwargs)
# # issue https://github.com/interlegis/sapl/issues/1123
# # TODO: usar Form
# urgente = request.POST['urgente'] == 'True'
# flag_error = False
# materias_principais = [m for m in MateriaLegislativa.objects.filter(id__in=marcadas)]
# materias_anexadas = [m.anexadas.all() for m in MateriaLegislativa.objects.filter(id__in=marcadas) if m.anexadas.all()]
# import ipdb; ipdb.set_trace()
# materias_anexadas = list(itertools.chain.from_iterable(materias_anexadas))
# tramitacao_local = int(request.POST['unidade_tramitacao_local'])
# materias_anexadas = list(filter(lambda ma : not ma.tramitacao_set.all() or \
# ma.tramitacao_set.last().unidade_tramitacao_destino.id == tramitacao_local,
# materias_anexadas))
# materias = set(materias_principais + materias_anexadas)
# 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)
# 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()

8
sapl/templates/navbar.yaml

@ -29,8 +29,12 @@
url: sapl.materia:receber-proposicao
- title: {% trans 'Documentos Administrativos' %}
{% if 'documentos_administrativos'|get_config_attr == 'R' %}check_permission: protocoloadm.list_documentoadministrativo{%endif%}
url: sapl.protocoloadm:pesq_doc_adm
{% if 'documentos_administrativos'|get_config_attr == 'R' %}check_permission: protocoloadm.list_documentoadministrativo {% endif %}
children:
- title: {% trans 'Pesquisar Documentos Administrativos' %}
url: sapl.protocoloadm:pesq_doc_adm
- title: {% trans 'Tramitação em Lote' %}
url: sapl.protocoloadm:primeira_tramitacao_em_lote_docadm
- title: {% trans 'Atividade Legislativa' %}
children:

5
sapl/templates/protocoloadm/em_lote/subnav_em_lote.yaml

@ -0,0 +1,5 @@
{% load i18n common_tags %}
- title: {% trans 'Primeira Tramitação' %}
url: primeira_tramitacao_em_lote_docadm
- title: {% trans 'Tramitação em Lote' %}
url: primeira_tramitacao_em_lote_docadm

46
sapl/templates/protocoloadm/em_lote/tramitacaoadm.html

@ -0,0 +1,46 @@
{% extends "crud/detail.html" %}
{% load i18n crispy_forms_tags %}
{% block detail_content %}
{% if not show_results %}
{% crispy filter.form %}
{% else %}
{% if object_list|length > 0 %}
{% if object_list|length == 1 %}
<h3 style="text-align: right;">{% trans 'Pesquisa concluída com sucesso! Foi encontrado 1 documento.'%}</h3>
{% else %}
<h3 style="text-align: right;">Foram encontrados {{object_list|length}} documentos.</h3>
{% endif %}
{% crispy form %}
{% else %}
<tr><td><h3 style="text-align: right;">Nenhum documento encontrado.</h3></td></tr>
{% endif %}
{% endif%}
{% endblock detail_content %}
{% block extra_js %}
<script language="JavaScript">
function checkAll(elem) {
let checkboxes = document.getElementsByName('documentos');
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].type == 'checkbox')
checkboxes[i].checked = elem.checked;
}
}
$(document).ready(function(){
var primeira_tramitacao = {{primeira_tramitacao|yesno:"true,false"}}
if (primeira_tramitacao == false){
$('#id_unidade_tramitacao_local').prop('disabled', true);
}
// Reabilita o campo, no momento do Submit, para que seu dado seja enviado
$('input[type=submit]').click(function() {
$('#id_unidade_tramitacao_local').attr('disabled', false);
$('#id_unidade_tramitacao_local').parents('form').submit();
});
});
</script>
{% endblock %}
Loading…
Cancel
Save