Browse Source

Fix #542 impressos v2 (#1434)

* Implementa Impressos de Etiquetas

* Implementa Impressos de Etiquetas

* Insere permissões a tela de impressos
pull/1438/head
Eduardo Calil 7 years ago
committed by Edward
parent
commit
0219cbaeb3
  1. 1
      requirements/requirements.txt
  2. 84
      sapl/materia/forms.py
  3. 19
      sapl/materia/migrations/0012_auto_20170829_1321.py
  4. 2
      sapl/materia/models.py
  5. 12
      sapl/materia/urls.py
  6. 60
      sapl/materia/views.py
  7. 5
      sapl/rules/map_rules.py
  8. 7
      sapl/templates/materia/impressos/etiqueta.html
  9. 33
      sapl/templates/materia/impressos/impressos.html
  10. 82
      sapl/templates/materia/impressos/pdf.html
  11. 3
      sapl/templates/navbar.yaml

1
requirements/requirements.txt

@ -32,4 +32,5 @@ pysolr==3.6.0
python-magic==0.4.12 python-magic==0.4.12
gunicorn==19.6.0 gunicorn==19.6.0
django-reversion==2.0.8 django-reversion==2.0.8
WeasyPrint==0.30
whoosh==2.7.4 whoosh==2.7.4

84
sapl/materia/forms.py

@ -1595,3 +1595,87 @@ class MateriaAssuntoForm(ModelForm):
fields = ['materia', 'assunto'] fields = ['materia', 'assunto']
widgets = {'materia': forms.HiddenInput()} widgets = {'materia': forms.HiddenInput()}
class EtiquetaPesquisaForm(forms.Form):
tipo_materia = forms.ModelChoiceField(
label=TipoMateriaLegislativa._meta.verbose_name,
queryset=TipoMateriaLegislativa.objects.all(),
required=False,
empty_label='Selecione')
data_inicial = forms.DateField(
label='Data Inicial',
required=False,
widget=forms.DateInput(format='%d/%m/%Y')
)
data_final = forms.DateField(
label='Data Final',
required=False,
widget=forms.DateInput(format='%d/%m/%Y')
)
processo_inicial = forms.IntegerField(
label='Processo Inicial',
required=False)
processo_final = forms.IntegerField(
label='Processo Final',
required=False)
def __init__(self, *args, **kwargs):
super(EtiquetaPesquisaForm, self).__init__(*args, **kwargs)
row1 = to_row(
[('tipo_materia', 6),
('data_inicial', 3),
('data_final', 3)])
row2 = to_row(
[('processo_inicial', 6),
('processo_final', 6)])
self.helper = FormHelper()
self.helper.layout = Layout(
Fieldset(
('Formulário de Etiqueta'),
row1, row2,
form_actions(save_label='Pesquisar')
)
)
def clean(self):
cleaned_data = self.cleaned_data
# Verifica se algum campo de data foi preenchido
if cleaned_data['data_inicial'] or cleaned_data['data_final']:
# Então verifica se o usuário preencheu o Incial e mas não
# preencheu o Final, ou vice-versa
if (not cleaned_data['data_inicial'] or
not cleaned_data['data_final']):
raise ValidationError(_(
'Caso pesquise por data, os campos de Data Incial e ' +
'Data Final devem ser preenchidos obrigatoriamente'))
# Caso tenha preenchido, verifica se a data final é maior que
# a inicial
elif cleaned_data['data_final'] < cleaned_data['data_inicial']:
raise ValidationError(_(
'A Data Final não pode ser menor que a Data Inicial'))
# O mesmo processo anterior é feito com o processo
if (cleaned_data['processo_inicial'] or
cleaned_data['processo_final']):
if (not cleaned_data['processo_inicial'] or
not cleaned_data['processo_final']):
raise ValidationError(_(
'Caso pesquise por número de processo, os campos de ' +
'Processo Inicial e Processo Final ' +
'devem ser preenchidos obrigatoriamente'))
elif (cleaned_data['processo_final'] <
cleaned_data['processo_inicial']):
raise ValidationError(_(
'O processo final não pode ser menor que o inicial'))
return cleaned_data

19
sapl/materia/migrations/0012_auto_20170829_1321.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.3 on 2017-08-29 13:21
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('materia', '0011_auto_20170808_1034'),
]
operations = [
migrations.AlterModelOptions(
name='materialegislativa',
options={'permissions': (('can_access_impressos', 'Can access impressos'),), 'verbose_name': 'Matéria Legislativa', 'verbose_name_plural': 'Matérias Legislativas'},
),
]

2
sapl/materia/models.py

@ -234,6 +234,8 @@ class MateriaLegislativa(models.Model):
verbose_name_plural = _('Matérias Legislativas') verbose_name_plural = _('Matérias Legislativas')
unique_together = (("tipo", "numero", "ano"),) unique_together = (("tipo", "numero", "ano"),)
permissions = (("can_access_impressos", "Can access impressos"),)
def __str__(self): def __str__(self):
return _('%(tipo)s%(numero)s de %(ano)s') % { return _('%(tipo)s%(numero)s de %(ano)s') % {
'tipo': self.tipo, 'numero': self.numero, 'ano': self.ano} 'tipo': self.tipo, 'numero': self.numero, 'ano': self.ano}

12
sapl/materia/urls.py

@ -8,6 +8,7 @@ from sapl.materia.views import (AcompanhamentoConfirmarView,
CriarProtocoloMateriaView, DespachoInicialCrud, CriarProtocoloMateriaView, DespachoInicialCrud,
DocumentoAcessorioCrud, DocumentoAcessorioCrud,
DocumentoAcessorioEmLoteView, DocumentoAcessorioEmLoteView,
ImpressosView, EtiquetaPesquisaView,
LegislacaoCitadaCrud, MateriaAssuntoCrud, LegislacaoCitadaCrud, MateriaAssuntoCrud,
MateriaLegislativaCrud, MateriaLegislativaCrud,
MateriaLegislativaPesquisaView, MateriaTaView, MateriaLegislativaPesquisaView, MateriaTaView,
@ -27,6 +28,15 @@ from .apps import AppConfig
app_name = AppConfig.name app_name = AppConfig.name
urlpatterns_impressos = [
url(r'^materia/impressos/$',
ImpressosView.as_view(),
name='impressos'),
url(r'^materia/impressos/etiqueta-pesquisa/$',
EtiquetaPesquisaView.as_view(),
name='impressos_etiqueta'),
]
urlpatterns_materia = [ urlpatterns_materia = [
url(r'^materia/', include(MateriaLegislativaCrud.get_urls() + url(r'^materia/', include(MateriaLegislativaCrud.get_urls() +
AnexadaCrud.get_urls() + AnexadaCrud.get_urls() +
@ -118,5 +128,5 @@ urlpatterns_sistema = [
url(r'^sistema/materia/orgao/', include(OrgaoCrud.get_urls())), url(r'^sistema/materia/orgao/', include(OrgaoCrud.get_urls())),
] ]
urlpatterns = urlpatterns_materia + \ urlpatterns = urlpatterns_impressos + urlpatterns_materia + \
urlpatterns_proposicao + urlpatterns_sistema urlpatterns_proposicao + urlpatterns_sistema

60
sapl/materia/views.py

@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse
from django.http.response import Http404, HttpResponseRedirect from django.http.response import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.template import Context, loader, RequestContext
from django.utils import formats from django.utils import formats
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import CreateView, ListView, TemplateView, UpdateView from django.views.generic import CreateView, ListView, TemplateView, UpdateView
@ -44,7 +45,8 @@ from sapl.utils import (TURNO_TRAMITACAO_CHOICES, YES_NO_CHOICES, autor_label,
from .email_utils import do_envia_email_confirmacao from .email_utils import do_envia_email_confirmacao
from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
AdicionarVariasAutoriasFilterSet, DespachoInicialForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm,
DocumentoAcessorioForm, MateriaAssuntoForm, DocumentoAcessorioForm, EtiquetaPesquisaForm,
MateriaAssuntoForm,
MateriaLegislativaFilterSet, MateriaSimplificadaForm, MateriaLegislativaFilterSet, MateriaSimplificadaForm,
PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm, PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm,
RelatoriaForm, TramitacaoEmLoteFilterSet, RelatoriaForm, TramitacaoEmLoteFilterSet,
@ -59,6 +61,8 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria,
TipoProposicao, Tramitacao, UnidadeTramitacao) TipoProposicao, Tramitacao, UnidadeTramitacao)
from .signals import tramitacao_signal from .signals import tramitacao_signal
import weasyprint
AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia')
OrigemCrud = Crud.build(Origem, '') OrigemCrud = Crud.build(Origem, '')
@ -1741,3 +1745,57 @@ class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView):
id__in=lista).distinct() id__in=lista).distinct()
return context return context
class ImpressosView(PermissionRequiredMixin, TemplateView):
template_name = 'materia/impressos/impressos.html'
permission_required = ('materia.can_access_impressos', )
def gerar_pdf_impressos(request, context):
template = loader.get_template('materia/impressos/pdf.html')
html = template.render(RequestContext(request, context))
response = HttpResponse(content_type="application/pdf")
weasyprint.HTML(
string=html,
base_url=request.build_absolute_uri()).write_pdf(
response)
return response
class EtiquetaPesquisaView(PermissionRequiredMixin, FormView):
form_class = EtiquetaPesquisaForm
template_name = 'materia/impressos/etiqueta.html'
permission_required = ('materia.can_access_impressos', )
def form_valid(self, form):
context = {}
materias = MateriaLegislativa.objects.all().order_by(
'-data_apresentacao')
if form.cleaned_data['tipo_materia']:
materias = materias.filter(tipo=form.cleaned_data['tipo_materia'])
if form.cleaned_data['data_inicial']:
materias = materias.filter(
data_apresentacao__gte=form.cleaned_data['data_inicial'],
data_apresentacao__lte=form.cleaned_data['data_final'])
if form.cleaned_data['processo_inicial']:
materias = materias.filter(
numeracao__numero_materia__gte=form.cleaned_data[
'processo_inicial'],
numeracao__numero_materia__lte=form.cleaned_data[
'processo_final'])
context['quantidade'] = len(materias)
if context['quantidade'] > 20:
materias = materias[:20]
context['materias'] = materias
return gerar_pdf_impressos(self.request, context)

5
sapl/rules/map_rules.py

@ -53,6 +53,7 @@ __listdetailchange__ = [RP_LIST, RP_DETAIL, RP_CHANGE]
rules_group_administrativo = { rules_group_administrativo = {
'group': SAPL_GROUP_ADMINISTRATIVO, 'group': SAPL_GROUP_ADMINISTRATIVO,
'rules': [ 'rules': [
(materia.MateriaLegislativa, ['can_access_impressos']),
(protocoloadm.DocumentoAdministrativo, __base__), (protocoloadm.DocumentoAdministrativo, __base__),
(protocoloadm.DocumentoAcessorioAdministrativo, __base__), (protocoloadm.DocumentoAcessorioAdministrativo, __base__),
(protocoloadm.TramitacaoAdministrativo, __base__), (protocoloadm.TramitacaoAdministrativo, __base__),
@ -69,6 +70,7 @@ rules_group_protocolo = {
(protocoloadm.DocumentoAcessorioAdministrativo, __listdetailchange__), (protocoloadm.DocumentoAcessorioAdministrativo, __listdetailchange__),
(materia.MateriaLegislativa, __listdetailchange__), (materia.MateriaLegislativa, __listdetailchange__),
(materia.MateriaLegislativa, ['can_access_impressos']),
(materia.DocumentoAcessorio, __listdetailchange__), (materia.DocumentoAcessorio, __listdetailchange__),
(materia.Anexada, __base__), (materia.Anexada, __base__),
(materia.Autoria, __base__), (materia.Autoria, __base__),
@ -98,7 +100,7 @@ rules_group_materia = {
(materia.DespachoInicial, __base__), (materia.DespachoInicial, __base__),
(materia.DocumentoAcessorio, __base__), (materia.DocumentoAcessorio, __base__),
(materia.MateriaLegislativa, __base__), (materia.MateriaLegislativa, __base__ + ['can_access_impressos']),
(materia.Numeracao, __base__), (materia.Numeracao, __base__),
(materia.Tramitacao, __base__), (materia.Tramitacao, __base__),
(norma.LegislacaoCitada, __base__), (norma.LegislacaoCitada, __base__),
@ -209,6 +211,7 @@ rules_group_geral = {
(materia.AssuntoMateria, __base__), # não há implementação (materia.AssuntoMateria, __base__), # não há implementação
(materia.MateriaAssunto, __base__), # não há implementação (materia.MateriaAssunto, __base__), # não há implementação
(materia.MateriaLegislativa, ['can_access_impressos']),
(materia.TipoProposicao, __base__), (materia.TipoProposicao, __base__),
(materia.TipoMateriaLegislativa, __base__), (materia.TipoMateriaLegislativa, __base__),
(materia.RegimeTramitacao, __base__), (materia.RegimeTramitacao, __base__),

7
sapl/templates/materia/impressos/etiqueta.html

@ -0,0 +1,7 @@
{% extends "crud/form.html" %}
{% load i18n crispy_forms_tags %}
{% block base_content %}
<h1 class="page-header">Impressos</h1>
{% crispy form %}
{% endblock base_content %}

33
sapl/templates/materia/impressos/impressos.html

@ -0,0 +1,33 @@
{% extends "crud/detail.html" %}
{% load i18n %}
{% block actions %}
{% endblock %}
{% block detail_content %}
<h1 class="page-header">Impressos</h1>
<h2 class="legend">Etiqueta</h2>
<ul>
<li><a href="{% url 'sapl.materia:impressos_etiqueta' %}">Pesquisar</a></li>
</ul>
{#<h2 class="legend">Ficha</h2>#}
{# <ul>#}
{# <li><a href="{% url 'sapl.materia:impressos_ficha' %}">Pesquisar</a></li>#}
{# </ul>#}
{##}
{#<h2 class="legend">Guia de Remessa</h2>#}
{# <ul>#}
{# <li><a href="{% url 'sapl.materia:impressos_guiaremessa' %}">Pesquisar</a></li>#}
{# </ul>#}
{##}
{#<h2 class="legend">Espelho</h2>#}
{# <ul>#}
{# <li><a href="{% url 'sapl.materia:impressos_espelho' %}">Pesquisar</a></li>#}
{# </ul>#}
{% endblock %}

82
sapl/templates/materia/impressos/pdf.html

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<title>Impressos</title>
<meta charset="utf-8">
</head>
<style type="text/css">
.text_pdf{
font-family: verdana;
font-size: 77%;
}
.alert_message{
font-family: verdana;
font-size: 77%;
color: red;
@media print {
p {page-break-inside: avoid;}
}
}
</style>
<body style="margin-left:80px;margin-right:80px; margin-top: -50px">
{% if quantidade > 30 %}
<b><p class="alert_message">Sua pesquisa retornou mais do que 20 impressos.</p><p class="alert_message">Por questões de performance, foram retornados apenas os 20 primeiros. Caso queira outros, tente fazer uma pesquisa mais específica</p></b>
</br></br></br>
{% endif %}
{% for m in materias %}
<div style="page-break-inside: avoid;">
<justify>
<!-- Informa o processo -->
{% if m.numeracao_set.first %}
<strong class="text_pdf">PROCESSO: {{ m.numeracao_set.first.numero_materia }}</strong>
&nbsp;
{% else %}
<strong class="text_pdf">PROCESSO: {{ m.numero }}</strong>
&nbsp;
{% endif %}
<!-- Informa o tipo da matéria -->
<strong class="text_pdf">{{m.tipo.sigla}}:</strong> <span class="text_pdf"> {{m.numero}}/{{m.ano}} </span> &nbsp;
<!-- Informa o campo Pref ??? #TODO -->
<strong class="text_pdf">Pref:</strong>
{% if m.numeracao_set.first %}
<span class="text_pdf">{{ m.numeracao_set.first.numero_materia }}</span>
{% endif %} </br
<!-- Informa a Data de Entrada -->
<strong class="text_pdf">DATA DE ENTRADA:</strong> <span class="text_pdf"> {{m.data_apresentacao}}</span></br>
<!-- Lista os autores -->
{% if m.autoria_set.all %}
<strong class="text_pdf">Autores:</strong>
{% for a in m.autoria_set.all %}
{% if not forloop.first %}
, &nbsp;&nbsp; <span class="text_pdf">{{a.autor}}</span>
{% else %}
&nbsp;<span class="text_pdf">{{a.autor}}</span>
{% endif %}
{% endfor %}
</br>
{% endif %}
<!-- Ementa -->
<strong class="text_pdf">EMENTA:</strong> <span class="text_pdf">{{m.ementa}}</span>
</div>
</justify>
</br>
</br>
</br>
</br>
</br>
{% endfor %}
</body>

3
sapl/templates/navbar.yaml

@ -33,6 +33,9 @@
- title: {% trans 'Acessório em Lote' %} - title: {% trans 'Acessório em Lote' %}
url: sapl.materia:acessorio_em_lote url: sapl.materia:acessorio_em_lote
check_permission: materia.list_documentoacessorio {% comment %} FIXME transformar para checagens de menu_[funcionalidade]{% endcomment%} check_permission: materia.list_documentoacessorio {% comment %} FIXME transformar para checagens de menu_[funcionalidade]{% endcomment%}
- title: {% trans 'Impressos' %}
url: sapl.materia:impressos
check_permission: materia.can_access_impressos {% comment %} FIXME transformar para checagens de menu_[funcionalidade]{% endcomment%}
- title: {% trans 'Matérias Legislativas' %} - title: {% trans 'Matérias Legislativas' %}
url: sapl.materia:pesquisar_materia url: sapl.materia:pesquisar_materia
- title: {% trans 'Pautas das Sessões' %} - title: {% trans 'Pautas das Sessões' %}

Loading…
Cancel
Save