Browse Source

Fix #2337 (#2448)

* impl data e hora manual no protocolo de matérias

* impl data e hora manual no protocolo de documentos

* ajustes de teste em protocoloadm
pull/2457/head
Leandro Roberto da Silva 6 years ago
committed by GitHub
parent
commit
ac91543b0f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 155
      sapl/protocoloadm/forms.py
  2. 35
      sapl/protocoloadm/migrations/0014_auto_20190110_1300.py
  3. 21
      sapl/protocoloadm/migrations/0015_protocolo_timestamp_data_hora_manual.py
  4. 21
      sapl/protocoloadm/migrations/0016_auto_20190110_1345.py
  5. 24
      sapl/protocoloadm/models.py
  6. 23
      sapl/protocoloadm/tests/test_protocoloadm.py
  7. 39
      sapl/protocoloadm/views.py
  8. 33
      sapl/relatorios/views.py
  9. 1
      sapl/static/js/app.js
  10. 6
      sapl/templates/protocoloadm/comprovante.html
  11. 14
      sapl/templates/protocoloadm/protocolar_documento.html
  12. 62
      sapl/templates/protocoloadm/protocolar_materia.html
  13. 10
      sapl/templates/protocoloadm/protocolo_mostrar.html
  14. 18
      sapl/utils.py

155
sapl/protocoloadm/forms.py

@ -1,9 +1,9 @@
import logging import logging
from crispy_forms.bootstrap import InlineRadios from crispy_forms.bootstrap import InlineRadios, Alert
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout, Div
from django import forms from django import forms
from django.core.exceptions import (MultipleObjectsReturned, from django.core.exceptions import (MultipleObjectsReturned,
ObjectDoesNotExist, ValidationError) ObjectDoesNotExist, ValidationError)
@ -18,11 +18,12 @@ from sapl.base.models import Autor, TipoAutor
from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row
from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa, from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa,
UnidadeTramitacao) UnidadeTramitacao)
from sapl.protocoloadm.models import Protocolo
from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, AnoNumeroOrderingFilter, from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, AnoNumeroOrderingFilter,
RangeWidgetOverride, autor_label, autor_modal, RangeWidgetOverride, autor_label, autor_modal,
choice_anos_com_protocolo, choice_force_optional, choice_anos_com_protocolo, choice_force_optional,
choice_anos_com_documentoadministrativo, choice_anos_com_documentoadministrativo,
FilterOverridesMetaMixin) FilterOverridesMetaMixin, choice_anos_com_materias)
from .models import (AcompanhamentoDocumento, DocumentoAcessorioAdministrativo, from .models import (AcompanhamentoDocumento, DocumentoAcessorioAdministrativo,
DocumentoAdministrativo, DocumentoAdministrativo,
@ -344,6 +345,12 @@ class ProtocoloDocumentForm(ModelForm):
numero = forms.IntegerField( numero = forms.IntegerField(
required=False, label=_('Número de Protocolo (opcional)')) required=False, label=_('Número de Protocolo (opcional)'))
data_hora_manual = forms.ChoiceField(
label=_('Informar data e hora manualmente?'),
widget=forms.RadioSelect(),
choices=YES_NO_CHOICES,
initial=False)
class Meta: class Meta:
model = Protocolo model = Protocolo
fields = ['tipo_protocolo', fields = ['tipo_protocolo',
@ -352,7 +359,9 @@ class ProtocoloDocumentForm(ModelForm):
'assunto', 'assunto',
'interessado', 'interessado',
'observacao', 'observacao',
'numero' 'numero',
'data',
'hora',
] ]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -360,30 +369,56 @@ class ProtocoloDocumentForm(ModelForm):
row1 = to_row( row1 = to_row(
[(InlineRadios('tipo_protocolo'), 12)]) [(InlineRadios('tipo_protocolo'), 12)])
row2 = to_row( row2 = to_row(
[('tipo_documento', 6), [('tipo_documento', 5),
('numero_paginas', 6)]) ('numero_paginas', 2),
row3 = to_row( (Div(), 1),
[('assunto', 12)]) (InlineRadios('data_hora_manual'), 4),
])
row3 = to_row([
(Div(), 2),
(Alert(
"""
Usuário: <strong>{}</strong> - {}<br>
IP: <strong>{}</strong> - {}<br>
""".format(
kwargs['initial']['user_data_hora_manual'],
Protocolo._meta.get_field(
'user_data_hora_manual').help_text,
kwargs['initial']['ip_data_hora_manual'],
Protocolo._meta.get_field(
'ip_data_hora_manual').help_text,
),
dismiss=False,
css_class='alert-info'), 6),
('data', 2),
('hora', 2),
])
row4 = to_row( row4 = to_row(
[('interessado', 12)]) [('assunto', 12)])
row5 = to_row( row5 = to_row(
[('observacao', 12)]) [('interessado', 12)])
row6 = to_row( row6 = to_row(
[('observacao', 12)])
row7 = to_row(
[('numero', 12)]) [('numero', 12)])
self.helper = FormHelper() self.helper = FormHelper()
self.helper.layout = Layout( self.helper.layout = Layout(
Fieldset(_('Identificação de Documento'), Fieldset(_('Identificação de Documento'),
row1, row1,
row2, row2),
Fieldset(_('Protocolo com data e hora informados manualmente'),
row3, row3,
row4, css_id='protocolo_data_hora_manual',
row5, css_class='hidden'),
HTML("&nbsp;"), row4,
), row5,
HTML("&nbsp;"),
Fieldset(_('Número do Protocolo (Apenas se quiser que a numeração comece ' Fieldset(_('Número do Protocolo (Apenas se quiser que a numeração comece '
'a partir do número a ser informado)'), 'a partir do número a ser informado)'),
row6, row7,
HTML("&nbsp;"), HTML("&nbsp;"),
form_actions(label=_('Protocolar Documento')) form_actions(label=_('Protocolar Documento'))
) )
@ -419,10 +454,11 @@ class ProtocoloMateriaForm(ModelForm):
ano_materia = forms.CharField( ano_materia = forms.CharField(
label=_('Ano matéria'), required=False) label=_('Ano matéria'), required=False)
vincular_materia = forms.ChoiceField(label=_('Vincular a matéria existente?'), vincular_materia = forms.ChoiceField(
widget=forms.RadioSelect(), label=_('Vincular a matéria existente?'),
choices=YES_NO_CHOICES, widget=forms.RadioSelect(),
initial=False) choices=YES_NO_CHOICES,
initial=False)
numero_paginas = forms.CharField(label=_('Núm. Páginas'), required=True) numero_paginas = forms.CharField(label=_('Núm. Páginas'), required=True)
@ -435,6 +471,12 @@ class ProtocoloMateriaForm(ModelForm):
numero = forms.IntegerField( numero = forms.IntegerField(
required=False, label=_('Número de Protocolo (opcional)')) required=False, label=_('Número de Protocolo (opcional)'))
data_hora_manual = forms.ChoiceField(
label=_('Informar data e hora manualmente?'),
widget=forms.RadioSelect(),
choices=YES_NO_CHOICES,
initial=False)
class Meta: class Meta:
model = Protocolo model = Protocolo
fields = ['tipo_materia', fields = ['tipo_materia',
@ -446,7 +488,9 @@ class ProtocoloMateriaForm(ModelForm):
'numero_materia', 'numero_materia',
'ano_materia', 'ano_materia',
'vincular_materia', 'vincular_materia',
'numero' 'numero',
'data',
'hora',
] ]
def clean_autor(self): def clean_autor(self):
@ -506,28 +550,55 @@ class ProtocoloMateriaForm(ModelForm):
('tipo_autor', 3), ('tipo_autor', 3),
('autor', 3)]) ('autor', 3)])
row2 = to_row( row2 = to_row(
[(InlineRadios('vincular_materia'), 4), [(InlineRadios('vincular_materia'), 3),
('numero_materia', 4), ('numero_materia', 2),
('ano_materia', 4), ]) ('ano_materia', 2),
row3 = to_row( (Div(), 1),
[('assunto_ementa', 12)]) (InlineRadios('data_hora_manual'), 4),
])
row3 = to_row([
(Div(), 2),
(Alert(
"""
Usuário: <strong>{}</strong> - {}<br>
IP: <strong>{}</strong> - {}<br>
""".format(
kwargs['initial']['user_data_hora_manual'],
Protocolo._meta.get_field(
'user_data_hora_manual').help_text,
kwargs['initial']['ip_data_hora_manual'],
Protocolo._meta.get_field(
'ip_data_hora_manual').help_text,
),
dismiss=False,
css_class='alert-info'), 6),
('data', 2),
('hora', 2),
])
row4 = to_row( row4 = to_row(
[('observacao', 12)]) [('assunto_ementa', 12)])
row5 = to_row( row5 = to_row(
[('observacao', 12)])
row6 = to_row(
[('numero', 12)]) [('numero', 12)])
self.helper = FormHelper() self.helper = FormHelper()
self.helper.layout = Layout( self.helper.layout = Layout(
Fieldset(_('Identificação da Matéria'), Fieldset(_('Identificação da Matéria'),
row1, row1,
row2, row2),
Fieldset(_('Protocolo com data e hora informados manualmente'),
row3, row3,
row4, css_id='protocolo_data_hora_manual',
HTML("&nbsp;"), css_class='hidden'),
), row4,
row5,
HTML("&nbsp;"),
Fieldset(_('Número do Protocolo (Apenas se quiser que a numeração comece' Fieldset(_('Número do Protocolo (Apenas se quiser que a numeração comece'
' a partir do número a ser informado)'), ' a partir do número a ser informado)'),
row5, row6,
HTML("&nbsp;"), HTML("&nbsp;"),
form_actions(label=_('Protocolar Matéria'))) form_actions(label=_('Protocolar Matéria')))
) )
@ -855,15 +926,15 @@ class DesvincularDocumentoForm(ModelForm):
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
numero = forms.CharField(required=True, numero = forms.CharField(
label=DocumentoAdministrativo._meta. required=True,
get_field('numero').verbose_name label=DocumentoAdministrativo._meta.get_field('numero').verbose_name)
)
ano = forms.ChoiceField(required=True, ano = forms.ChoiceField(
label=DocumentoAdministrativo._meta. required=True,
get_field('ano').verbose_name, label=DocumentoAdministrativo._meta.get_field('ano').verbose_name,
choices=RANGE_ANOS, choices=choice_anos_com_documentoadministrativo,
widget=forms.Select(attrs={'class': 'selector'})) widget=forms.Select(attrs={'class': 'selector'}))
def clean(self): def clean(self):
super(DesvincularDocumentoForm, self).clean() super(DesvincularDocumentoForm, self).clean()
@ -929,7 +1000,7 @@ class DesvincularMateriaForm(forms.Form):
label=_('Número da Matéria')) label=_('Número da Matéria'))
ano = forms.ChoiceField(required=True, ano = forms.ChoiceField(required=True,
label=_('Ano da Matéria'), label=_('Ano da Matéria'),
choices=RANGE_ANOS, choices=choice_anos_com_materias,
widget=forms.Select(attrs={'class': 'selector'})) widget=forms.Select(attrs={'class': 'selector'}))
tipo = forms.ModelChoiceField(label=_('Tipo de Matéria'), tipo = forms.ModelChoiceField(label=_('Tipo de Matéria'),
required=True, required=True,

35
sapl/protocoloadm/migrations/0014_auto_20190110_1300.py

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2019-01-10 15:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0013_auto_20190106_1336'),
]
operations = [
migrations.AddField(
model_name='protocolo',
name='ip_data_hora_manual',
field=models.CharField(blank=True, help_text='Endereço IP da estação de trabalho do usuário que está realizando Protocolo e informando data e hora manualmente.', max_length=15, verbose_name='IP'),
),
migrations.AddField(
model_name='protocolo',
name='user_data_hora_manual',
field=models.CharField(blank=True, help_text='Usuário que está realizando Protocolo e informando data e hora manualmente.', max_length=20, verbose_name='IP'),
),
migrations.AlterField(
model_name='protocolo',
name='data',
field=models.DateField(blank=True, help_text='Informado manualmente', null=True, verbose_name='Data do Protocolo'),
),
migrations.AlterField(
model_name='protocolo',
name='hora',
field=models.TimeField(blank=True, help_text='Informado manualmente', null=True, verbose_name='Hora do Protocolo'),
),
]

21
sapl/protocoloadm/migrations/0015_protocolo_timestamp_data_hora_manual.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2019-01-10 15:43
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0014_auto_20190110_1300'),
]
operations = [
migrations.AddField(
model_name='protocolo',
name='timestamp_data_hora_manual',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

21
sapl/protocoloadm/migrations/0016_auto_20190110_1345.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.8 on 2019-01-10 15:45
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('protocoloadm', '0015_protocolo_timestamp_data_hora_manual'),
]
operations = [
migrations.AlterField(
model_name='protocolo',
name='timestamp',
field=models.DateTimeField(blank=True, default=django.utils.timezone.now, null=True),
),
]

24
sapl/protocoloadm/models.py

@ -57,13 +57,29 @@ class Protocolo(models.Model):
choices=RANGE_ANOS, choices=RANGE_ANOS,
verbose_name=_('Ano do Protocolo')) verbose_name=_('Ano do Protocolo'))
# FIXME: https://github.com/interlegis/sapl/issues/2337 data = models.DateField(null=True, blank=True,
data = models.DateField(null=True, blank=True) verbose_name=_('Data do Protocolo'),
hora = models.TimeField(null=True, blank=True) help_text=_('Informado manualmente'))
hora = models.TimeField(null=True, blank=True,
verbose_name=_('Hora do Protocolo'),
help_text=_('Informado manualmente'))
timestamp_data_hora_manual = models.DateTimeField(default=timezone.now)
user_data_hora_manual = models.CharField(
max_length=20, blank=True,
verbose_name=_('IP'),
help_text=_('Usuário que está realizando Protocolo e informando '
'data e hora manualmente.'))
ip_data_hora_manual = models.CharField(
max_length=15, blank=True,
verbose_name=_('IP'),
help_text=_('Endereço IP da estação de trabalho '
'do usuário que está realizando Protocolo e informando '
'data e hora manualmente.'))
# Não foi utilizado auto_now_add=True em timestamp porque # Não foi utilizado auto_now_add=True em timestamp porque
# ele usa datetime.now que não é timezone aware. # ele usa datetime.now que não é timezone aware.
timestamp = models.DateTimeField(default=timezone.now) timestamp = models.DateTimeField(
default=timezone.now, null=True, blank=True)
tipo_protocolo = models.PositiveIntegerField( tipo_protocolo = models.PositiveIntegerField(
blank=True, null=True, verbose_name=_('Tipo de Protocolo')) blank=True, null=True, verbose_name=_('Tipo de Protocolo'))
tipo_processo = models.PositiveIntegerField() tipo_processo = models.PositiveIntegerField()

23
sapl/protocoloadm/tests/test_protocoloadm.py

@ -1,4 +1,4 @@
from datetime import date, timedelta from datetime import date, timedelta, datetime
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils import timezone from django.utils import timezone
@ -392,29 +392,42 @@ def test_documento_administrativo_protocolo_inexistente():
def test_protocolo_documento_form_invalido(): def test_protocolo_documento_form_invalido():
form = ProtocoloDocumentForm(data={}) form = ProtocoloDocumentForm(
data={},
initial={
'user_data_hora_manual': '',
'ip_data_hora_manual': '',
'data': timezone.localdate(timezone.now()),
'hora': timezone.localtime(timezone.now())})
assert not form.is_valid() assert not form.is_valid()
errors = form.errors errors = form.errors
assert errors['data_hora_manual'] == [_('Este campo é obrigatório.')]
assert errors['tipo_protocolo'] == [_('Este campo é obrigatório.')] assert errors['tipo_protocolo'] == [_('Este campo é obrigatório.')]
assert errors['interessado'] == [_('Este campo é obrigatório.')] assert errors['interessado'] == [_('Este campo é obrigatório.')]
assert errors['tipo_documento'] == [_('Este campo é obrigatório.')] assert errors['tipo_documento'] == [_('Este campo é obrigatório.')]
assert errors['numero_paginas'] == [_('Este campo é obrigatório.')] assert errors['numero_paginas'] == [_('Este campo é obrigatório.')]
assert errors['assunto'] == [_('Este campo é obrigatório.')] assert errors['assunto'] == [_('Este campo é obrigatório.')]
assert len(errors) == 5 assert len(errors) == 6
def test_protocolo_materia_invalido(): def test_protocolo_materia_invalido():
form = ProtocoloMateriaForm(data={}) form = ProtocoloMateriaForm(data={},
initial={
'user_data_hora_manual': '',
'ip_data_hora_manual': '',
'data': timezone.localdate(timezone.now()),
'hora': timezone.localtime(timezone.now())})
assert not form.is_valid() assert not form.is_valid()
errors = form.errors errors = form.errors
assert errors['data_hora_manual'] == [_('Este campo é obrigatório.')]
assert errors['assunto_ementa'] == [_('Este campo é obrigatório.')] assert errors['assunto_ementa'] == [_('Este campo é obrigatório.')]
assert errors['tipo_autor'] == [_('Este campo é obrigatório.')] assert errors['tipo_autor'] == [_('Este campo é obrigatório.')]
assert errors['tipo_materia'] == [_('Este campo é obrigatório.')] assert errors['tipo_materia'] == [_('Este campo é obrigatório.')]
@ -422,4 +435,4 @@ def test_protocolo_materia_invalido():
assert errors['autor'] == [_('Este campo é obrigatório.')] assert errors['autor'] == [_('Este campo é obrigatório.')]
assert errors['vincular_materia'] == [_('Este campo é obrigatório.')] assert errors['vincular_materia'] == [_('Este campo é obrigatório.')]
assert len(errors) == 6 assert len(errors) == 7

39
sapl/protocoloadm/views.py

@ -492,6 +492,15 @@ class ProtocoloDocumentoView(PermissionRequiredMixin,
return reverse('sapl.protocoloadm:protocolo_mostrar', return reverse('sapl.protocoloadm:protocolo_mostrar',
kwargs={'pk': self.object.id}) kwargs={'pk': self.object.id})
def get_initial(self):
initial = super().get_initial()
initial['user_data_hora_manual'] = self.request.user.username
initial['ip_data_hora_manual'] = get_client_ip(self.request)
initial['data'] = timezone.localdate(timezone.now())
initial['hora'] = timezone.localtime(timezone.now())
return initial
def form_valid(self, form): def form_valid(self, form):
protocolo = form.save(commit=False) protocolo = form.save(commit=False)
username = self.request.user.username username = self.request.user.username
@ -538,6 +547,17 @@ class ProtocoloDocumentoView(PermissionRequiredMixin,
return self.render_to_response(self.get_context_data()) return self.render_to_response(self.get_context_data())
protocolo.ano = timezone.now().year protocolo.ano = timezone.now().year
protocolo.assunto_ementa = self.request.POST['assunto'] protocolo.assunto_ementa = self.request.POST['assunto']
if form.cleaned_data['data_hora_manual'] == 'True':
protocolo.timestamp = None
protocolo.user_data_hora_manual = username
protocolo.ip_data_hora_manual = get_client_ip(self.request)
else:
protocolo.data = None
protocolo.hora = None
protocolo.user_data_hora_manual = ''
protocolo.ip_data_hora_manual = ''
protocolo.save() protocolo.save()
self.object = protocolo self.object = protocolo
return redirect(self.get_success_url()) return redirect(self.get_success_url())
@ -659,6 +679,15 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView):
return reverse('sapl.protocoloadm:materia_continuar', kwargs={ return reverse('sapl.protocoloadm:materia_continuar', kwargs={
'pk': protocolo.pk}) 'pk': protocolo.pk})
def get_initial(self):
initial = super().get_initial()
initial['user_data_hora_manual'] = self.request.user.username
initial['ip_data_hora_manual'] = get_client_ip(self.request)
initial['data'] = timezone.localdate(timezone.now())
initial['hora'] = timezone.localtime(timezone.now())
return initial
def form_valid(self, form): def form_valid(self, form):
protocolo = form.save(commit=False) protocolo = form.save(commit=False)
username = self.request.user.username username = self.request.user.username
@ -719,6 +748,16 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView):
protocolo.observacao = self.request.POST['observacao'] protocolo.observacao = self.request.POST['observacao']
protocolo.assunto_ementa = self.request.POST['assunto_ementa'] protocolo.assunto_ementa = self.request.POST['assunto_ementa']
if form.cleaned_data['data_hora_manual'] == 'True':
protocolo.timestamp = None
protocolo.user_data_hora_manual = username
protocolo.ip_data_hora_manual = get_client_ip(self.request)
else:
protocolo.data = None
protocolo.hora = None
protocolo.user_data_hora_manual = ''
protocolo.ip_data_hora_manual = ''
protocolo.save() protocolo.save()
data = form.cleaned_data data = form.cleaned_data
if data['vincular_materia'] == 'True': if data['vincular_materia'] == 'True':

33
sapl/relatorios/views.py

@ -1,7 +1,7 @@
from datetime import datetime as dt
import html import html
import re
import logging import logging
from datetime import datetime as dt import re
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
@ -581,7 +581,6 @@ def get_sessao_plenaria(sessao, casa):
if dic_expedientes: if dic_expedientes:
lst_expedientes.append(dic_expedientes) lst_expedientes.append(dic_expedientes)
# Lista das matérias do Expediente, incluindo o resultado das votacoes # Lista das matérias do Expediente, incluindo o resultado das votacoes
lst_expediente_materia = [] lst_expediente_materia = []
for expediente_materia in ExpedienteMateria.objects.filter( for expediente_materia in ExpedienteMateria.objects.filter(
@ -612,7 +611,8 @@ def get_sessao_plenaria(sessao, casa):
dic_expediente_materia["nom_autor"] = '' dic_expediente_materia["nom_autor"] = ''
autoria = materia.autoria_set.all() autoria = materia.autoria_set.all()
dic_expediente_materia['num_autores'] = 'Autores' if len(autoria) > 1 else 'Autor' dic_expediente_materia['num_autores'] = 'Autores' if len(
autoria) > 1 else 'Autor'
if autoria: if autoria:
for a in autoria: for a in autoria:
if a.autor.nome: if a.autor.nome:
@ -762,7 +762,6 @@ def get_sessao_plenaria(sessao, casa):
lst_ocorrencias.append(o) lst_ocorrencias.append(o)
return (inf_basicas_dic, return (inf_basicas_dic,
lst_mesa, lst_mesa,
lst_presenca_sessao, lst_presenca_sessao,
@ -810,10 +809,12 @@ def relatorio_sessao_plenaria(request, pk):
imagem = get_imagem(casa) imagem = get_imagem(casa)
try: try:
logger.debug("user=" + username + ". Tentando obter SessaoPlenaria com id={}.".format(pk)) logger.debug("user=" + username +
". Tentando obter SessaoPlenaria com id={}.".format(pk))
sessao = SessaoPlenaria.objects.get(id=pk) sessao = SessaoPlenaria.objects.get(id=pk)
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
logger.error("user=" + username + ". Essa SessaoPlenaria não existe (pk={}). ".format(pk) + str(e)) logger.error("user=" + username +
". Essa SessaoPlenaria não existe (pk={}). ".format(pk) + str(e))
raise Http404('Essa página não existe') raise Http404('Essa página não existe')
(inf_basicas_dic, (inf_basicas_dic,
@ -828,11 +829,10 @@ def relatorio_sessao_plenaria(request, pk):
lst_oradores, lst_oradores,
lst_ocorrencias) = get_sessao_plenaria(sessao, casa) lst_ocorrencias) = get_sessao_plenaria(sessao, casa)
for idx in range(len(lst_expedientes)): for idx in range(len(lst_expedientes)):
txt_expedientes = lst_expedientes[idx]['txt_expediente'] txt_expedientes = lst_expedientes[idx]['txt_expediente']
txt_expedientes = TrocaTag(txt_expedientes, '<table', 'table>', 6, 6, txt_expedientes = TrocaTag(txt_expedientes, '<table', 'table>', 6, 6,
'expedientes', '</para><blockTable style = "', 'blockTable><para>') 'expedientes', '</para><blockTable style = "', 'blockTable><para>')
lst_expedientes[idx]['txt_expediente'] = txt_expedientes lst_expedientes[idx]['txt_expediente'] = txt_expedientes
pdf = pdf_sessao_plenaria_gerar.principal( pdf = pdf_sessao_plenaria_gerar.principal(
@ -868,7 +868,7 @@ def get_protocolos(prots):
ts.strftime("%H:%m") ts.strftime("%H:%m")
else: else:
dic['data'] = protocolo.data.strftime("%d/%m/%Y") + ' - <b>Horário:</b>' \ dic['data'] = protocolo.data.strftime("%d/%m/%Y") + ' - <b>Horário:</b>' \
+ protocolo.hora.strftime("%H:%m") + protocolo.hora.strftime("%H:%m")
dic['txt_assunto'] = protocolo.assunto_ementa dic['txt_assunto'] = protocolo.assunto_ementa
@ -979,8 +979,8 @@ def get_etiqueta_protocolos(prots):
dic['titulo'] = str(p.numero) + '/' + str(p.ano) dic['titulo'] = str(p.numero) + '/' + str(p.ano)
tz_hora = timezone.localtime(p.timestamp)
if p.timestamp: if p.timestamp:
tz_hora = timezone.localtime(p.timestamp)
dic['data'] = '<b>Data: </b>' + tz_hora.strftime( dic['data'] = '<b>Data: </b>' + tz_hora.strftime(
"%d/%m/%Y") + ' - <b>Horário: </b>' + tz_hora.strftime("%H:%M") "%d/%m/%Y") + ' - <b>Horário: </b>' + tz_hora.strftime("%H:%M")
else: else:
@ -1072,7 +1072,8 @@ def get_pauta_sessao(sessao, casa):
id=expediente_materia.materia.id).first() id=expediente_materia.materia.id).first()
dic_expediente_materia = {} dic_expediente_materia = {}
dic_expediente_materia["tipo_materia"] = materia.tipo.sigla + ' - ' + materia.tipo.descricao dic_expediente_materia["tipo_materia"] = materia.tipo.sigla + \
' - ' + materia.tipo.descricao
dic_expediente_materia["num_ordem"] = str( dic_expediente_materia["num_ordem"] = str(
expediente_materia.numero_ordem) expediente_materia.numero_ordem)
dic_expediente_materia["id_materia"] = str( dic_expediente_materia["id_materia"] = str(
@ -1090,7 +1091,8 @@ def get_pauta_sessao(sessao, casa):
dic_expediente_materia["nom_autor"] = '' dic_expediente_materia["nom_autor"] = ''
autoria = materia.autoria_set.all() autoria = materia.autoria_set.all()
dic_expediente_materia['num_autores'] = 'Autores' if len(autoria) > 1 else 'Autor' dic_expediente_materia['num_autores'] = 'Autores' if len(
autoria) > 1 else 'Autor'
if autoria: if autoria:
for a in autoria: for a in autoria:
if a.autor.nome: if a.autor.nome:
@ -1112,7 +1114,8 @@ def get_pauta_sessao(sessao, casa):
materia = MateriaLegislativa.objects.filter( materia = MateriaLegislativa.objects.filter(
id=votacao.materia.id).first() id=votacao.materia.id).first()
dic_votacao = {} dic_votacao = {}
dic_votacao["tipo_materia"] = materia.tipo.sigla + ' - ' + materia.tipo.descricao dic_votacao["tipo_materia"] = materia.tipo.sigla + \
' - ' + materia.tipo.descricao
dic_votacao["num_ordem"] = votacao.numero_ordem dic_votacao["num_ordem"] = votacao.numero_ordem
dic_votacao["id_materia"] = str( dic_votacao["id_materia"] = str(
materia.numero) + "/" + str(materia.ano) materia.numero) + "/" + str(materia.ano)
@ -1124,7 +1127,7 @@ def get_pauta_sessao(sessao, casa):
numeracao = Numeracao.objects.filter(materia=votacao.materia).first() numeracao = Numeracao.objects.filter(materia=votacao.materia).first()
if numeracao: if numeracao:
dic_votacao["des_numeracao"] = str( dic_votacao["des_numeracao"] = str(
numeracao.numero_materia) + '/' + str(numeracao.ano_materia) numeracao.numero_materia) + '/' + str(numeracao.ano_materia)
turno, tramitacao = get_turno(materia) turno, tramitacao = get_turno(materia)
dic_votacao["des_turno"] = turno dic_votacao["des_turno"] = turno

1
sapl/static/js/app.js

@ -47,6 +47,7 @@ function refreshMask() {
$('.dateinput').mask('00/00/0000', {placeholder:"__/__/____"}); $('.dateinput').mask('00/00/0000', {placeholder:"__/__/____"});
$('.hora').mask("00:00", {placeholder:"hh:mm"}); $('.hora').mask("00:00", {placeholder:"hh:mm"});
$('.hora_hms').mask("00:00:00", {placeholder:"hh:mm:ss"}); $('.hora_hms').mask("00:00:00", {placeholder:"hh:mm:ss"});
$('.timeinput').mask("00:00:00", {placeholder:"hh:mm:ss"});
$('.cronometro').mask("00:00:00", {placeholder:"hh:mm:ss"}); $('.cronometro').mask("00:00:00", {placeholder:"hh:mm:ss"});
} }

6
sapl/templates/protocoloadm/comprovante.html

@ -65,7 +65,11 @@
</tr> </tr>
<tr> <tr>
<th>Data / Horário</th> <th>Data / Horário</th>
<td>{{ protocolo.timestamp|date:"d/m/Y" }} - {{ protocolo.timestamp|date:"H:i:s" }}</td> {% if protocolo.timestamp %}
<td>{{ protocolo.timestamp|date:"d/m/Y" }} - {{ protocolo.timestamp|date:"H:i:s" }}</td>
{% else %}
<td>{{ protocolo.data|date:"d/m/Y" }} - {{ protocolo.hora|date:"H:i:s" }}</td>
{% endif %}
</tr> </tr>
{% if protocolo.tipo_processo == 1 %} {% if protocolo.tipo_processo == 1 %}
<tr> <tr>

14
sapl/templates/protocoloadm/protocolar_documento.html

@ -14,3 +14,17 @@
{% block detail_content %} {% block detail_content %}
{% crispy form %} {% crispy form %}
{% endblock detail_content %} {% endblock detail_content %}
{% block extra_js %}
<script language="Javascript">
$(document).ready(function() {
$("input[name=data_hora_manual]").change(function(event) {
if (this.value === 'True' && this.checked)
$("#protocolo_data_hora_manual").removeClass('hidden');
else if (this.value === 'False' && this.checked)
$("#protocolo_data_hora_manual").addClass('hidden');
});
$("input[name=data_hora_manual]").trigger('change')
});
</script>
{% endblock %}

62
sapl/templates/protocoloadm/protocolar_materia.html

@ -26,35 +26,43 @@
} }
$(document).ready(function() { $(document).ready(function() {
function busca_ementa() { $("input[name=data_hora_manual]").change(function(event) {
var vincular_materia = $("#id_vincular_materia_1").prop("checked"); if (this.value === 'True' && this.checked)
var ano_materia = $("#id_ano_materia").val(); $("#protocolo_data_hora_manual").removeClass('hidden');
var numero_materia = $("#id_numero_materia").val(); else if (this.value === 'False' && this.checked)
var tipo_materia = $("#id_tipo_materia").val(); $("#protocolo_data_hora_manual").addClass('hidden');
var json_data = { });
ano : ano_materia, $("input[name=data_hora_manual]").trigger('change')
numero : numero_materia,
tipo : tipo_materia
}
if (vincular_materia === true && ano_materia !== undefined &&
numero_materia !== undefined && numero_materia !== "") {
$.getJSON("/protocoloadm/recuperar-materia", json_data, function(data){
if (data) {
if (data['error'] === undefined){
$('#id_assunto_ementa').val(data['ementa']);
if (data['autor'] !== undefined) {
$('#id_autor').val(data['autor']);
$('#id_tipo_autor').val(data['tipo_autor']);
} function busca_ementa() {
} var vincular_materia = $("#id_vincular_materia_1").prop("checked");
} var ano_materia = $("#id_ano_materia").val();
}) var numero_materia = $("#id_numero_materia").val();
} var tipo_materia = $("#id_tipo_materia").val();
var json_data = {
ano : ano_materia,
numero : numero_materia,
tipo : tipo_materia
}
if (vincular_materia === true && ano_materia !== undefined &&
numero_materia !== undefined && numero_materia !== "") {
$.getJSON("/protocoloadm/recuperar-materia", json_data, function(data){
if (data) {
if (data['error'] === undefined){
$('#id_assunto_ementa').val(data['ementa']);
if (data['autor'] !== undefined) {
$('#id_autor').val(data['autor']);
$('#id_tipo_autor').val(data['tipo_autor']);
}
}
}
})
}
}; };
$("#id_ano_materia").blur(busca_ementa); $("#id_ano_materia").blur(busca_ementa);
$("#id_numero_materia").blur(busca_ementa); $("#id_numero_materia").blur(busca_ementa);
$("#id_tipo_materia").change(busca_ementa); $("#id_tipo_materia").change(busca_ementa);
$("#id_tipo_autor").change(function() { $("#id_tipo_autor").change(function() {
var tipo_selecionado = $("#id_tipo_autor").val(); var tipo_selecionado = $("#id_tipo_autor").val();

10
sapl/templates/protocoloadm/protocolo_mostrar.html

@ -4,6 +4,14 @@
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% load static %} {% load static %}
{% block actions %}
{{ block.super }}
<div class="actions btn-group pull-right grid-gutter-width-right " role="group">
<a href="{% url 'sapl.protocoloadm:protocolo' %}" class="btn btn-default">{% trans 'Fazer nova pesquisa' %}</a>
</div>
{% endblock %}
{% block detail_content %} {% block detail_content %}
<strong>Protocolo: </strong>{{ protocolo.numero|stringformat:'06d' }}/{{ protocolo.ano }} - <strong>Protocolo: </strong>{{ protocolo.numero|stringformat:'06d' }}/{{ protocolo.ano }} -
<a href="{% url 'sapl.relatorios:relatorio_etiqueta_protocolo' protocolo.numero protocolo.ano %}"><img src="{% static 'img/etiqueta.png' %}" alt="Etiqueta Individual"></a></br> <a href="{% url 'sapl.relatorios:relatorio_etiqueta_protocolo' protocolo.numero protocolo.ano %}"><img src="{% static 'img/etiqueta.png' %}" alt="Etiqueta Individual"></a></br>
@ -12,7 +20,7 @@
{% if protocolo.timestamp %} {% if protocolo.timestamp %}
<strong>Data Protocolo:</strong> {{ protocolo.timestamp|localtime|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ protocolo.timestamp|localtime|date:"G:i:s" }}</br> <strong>Data Protocolo:</strong> {{ protocolo.timestamp|localtime|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ protocolo.timestamp|localtime|date:"G:i:s" }}</br>
{% else %} {% else %}
<strong>Data Protocolo:</strong> {{ protocolo.data|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ protocolo.hora|date:"G:i:s" }}</br> <strong>Data Protocolo:</strong> {{ protocolo.data|date:"d/m/Y"|default_if_none:"Não informado" }} - Horário: {{ protocolo.hora|date:"G:i:s" }} - {% if not protocolo.timestamp %} Informado Manualmente por: {{protocolo.user_data_hora_manual}}{% endif %}</br>
{% endif %} {% endif %}
{% if protocolo.tipo_processo == 0 %} {% if protocolo.tipo_processo == 0 %}

18
sapl/utils.py

@ -18,6 +18,7 @@ from django.core.exceptions import ValidationError
from django.core.mail import get_connection from django.core.mail import get_connection
from django.db import models from django.db import models
from django.db.models import Q from django.db.models import Q
from django.forms.widgets import SplitDateTimeWidget
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import django_filters import django_filters
@ -234,6 +235,23 @@ class RangeWidgetOverride(forms.MultiWidget):
return '<div class="row">%s</div>' % html return '<div class="row">%s</div>' % html
class CustomSplitDateTimeWidget(SplitDateTimeWidget):
def render(self, name, value, attrs=None, renderer=None):
rendered_widgets = []
for i, x in enumerate(self.widgets):
x.attrs['class'] += ' form-control'
rendered_widgets.append(
x.render(
'%s_%d' % (name, i), self.decompress(
value)[i] if value else ''
)
)
html = '<div class="col-6">%s</div><div class="col-6">%s</div>'\
% tuple(rendered_widgets)
return '<div class="row">%s</div>' % html
def register_all_models_in_admin(module_name, exclude_list=[]): def register_all_models_in_admin(module_name, exclude_list=[]):
appname = module_name.split('.') appname = module_name.split('.')
appname = appname[1] if appname[0] == 'sapl' else appname[0] appname = appname[1] if appname[0] == 'sapl' else appname[0]

Loading…
Cancel
Save