From d65bcffb140b43dc89bfb8cc96d0dead357bdc22 Mon Sep 17 00:00:00 2001 From: Eduardo Calil Date: Tue, 22 Aug 2017 17:45:38 -0300 Subject: [PATCH] Implementa Impressos de Etiquetas --- requirements/requirements.txt | 1 + sapl/materia/forms.py | 84 +++++++++++++++++++ sapl/materia/urls.py | 12 ++- sapl/materia/views.py | 59 ++++++++++++- .../templates/materia/impressos/etiqueta.html | 7 ++ .../materia/impressos/impressos.html | 33 ++++++++ sapl/templates/materia/impressos/pdf.html | 82 ++++++++++++++++++ 7 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 sapl/templates/materia/impressos/etiqueta.html create mode 100644 sapl/templates/materia/impressos/impressos.html create mode 100644 sapl/templates/materia/impressos/pdf.html diff --git a/requirements/requirements.txt b/requirements/requirements.txt index fb70f9368..e64eb97dc 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -32,4 +32,5 @@ pysolr==3.6.0 python-magic==0.4.12 gunicorn==19.6.0 django-reversion==2.0.8 +WeasyPrint==0.30 whoosh==2.7.4 diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index f8aa30ea5..e2ff7f535 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1595,3 +1595,87 @@ class MateriaAssuntoForm(ModelForm): fields = ['materia', 'assunto'] 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 + diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index e91505c24..e803f18e0 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -8,6 +8,7 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, CriarProtocoloMateriaView, DespachoInicialCrud, DocumentoAcessorioCrud, DocumentoAcessorioEmLoteView, + ImpressosView, EtiquetaPesquisaView, LegislacaoCitadaCrud, MateriaAssuntoCrud, MateriaLegislativaCrud, MateriaLegislativaPesquisaView, MateriaTaView, @@ -27,6 +28,15 @@ from .apps import AppConfig 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 = [ url(r'^materia/', include(MateriaLegislativaCrud.get_urls() + AnexadaCrud.get_urls() + @@ -118,5 +128,5 @@ urlpatterns_sistema = [ url(r'^sistema/materia/orgao/', include(OrgaoCrud.get_urls())), ] -urlpatterns = urlpatterns_materia + \ +urlpatterns = urlpatterns_impressos + urlpatterns_materia + \ urlpatterns_proposicao + urlpatterns_sistema diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 9e9b63e45..0a0650fdb 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect +from django.template import Context, loader, RequestContext from django.utils import formats from django.utils.translation import ugettext_lazy as _ 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 .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, AdicionarVariasAutoriasFilterSet, DespachoInicialForm, - DocumentoAcessorioForm, MateriaAssuntoForm, + DocumentoAcessorioForm, EtiquetaPesquisaForm, + MateriaAssuntoForm, MateriaLegislativaFilterSet, MateriaSimplificadaForm, PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm, RelatoriaForm, TramitacaoEmLoteFilterSet, @@ -59,6 +61,8 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, TipoProposicao, Tramitacao, UnidadeTramitacao) from .signals import tramitacao_signal +import weasyprint + AssuntoMateriaCrud = Crud.build(AssuntoMateria, 'assunto_materia') OrigemCrud = Crud.build(Origem, '') @@ -1741,3 +1745,56 @@ class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView): id__in=lista).distinct() return context + + +class ImpressosView(TemplateView): + template_name = 'materia/impressos/impressos.html' + + +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(FormView): + form_class = EtiquetaPesquisaForm + template_name = 'materia/impressos/etiqueta.html' + + 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) + + diff --git a/sapl/templates/materia/impressos/etiqueta.html b/sapl/templates/materia/impressos/etiqueta.html new file mode 100644 index 000000000..03d1c8580 --- /dev/null +++ b/sapl/templates/materia/impressos/etiqueta.html @@ -0,0 +1,7 @@ +{% extends "crud/form.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} +

Impressos

+ {% crispy form %} +{% endblock base_content %} diff --git a/sapl/templates/materia/impressos/impressos.html b/sapl/templates/materia/impressos/impressos.html new file mode 100644 index 000000000..6f48dfddd --- /dev/null +++ b/sapl/templates/materia/impressos/impressos.html @@ -0,0 +1,33 @@ +{% extends "crud/detail.html" %} +{% load i18n %} + + +{% block actions %} +{% endblock %} + + +{% block detail_content %} + +

Impressos

+ +

Etiqueta

+ + +{#

Ficha

#} +{# #} +{##} +{#

Guia de Remessa

#} +{# #} +{##} +{#

Espelho

#} +{# #} + +{% endblock %} diff --git a/sapl/templates/materia/impressos/pdf.html b/sapl/templates/materia/impressos/pdf.html new file mode 100644 index 000000000..345835ba5 --- /dev/null +++ b/sapl/templates/materia/impressos/pdf.html @@ -0,0 +1,82 @@ + + + + + Impressos + + + + + + + +{% if quantidade > 30 %} +

Sua pesquisa retornou mais do que 20 impressos.

Por questões de performance, foram retornados apenas os 20 primeiros. Caso queira outros, tente fazer uma pesquisa mais específica

+


+{% endif %} + +{% for m in materias %} +
+ + + {% if m.numeracao_set.first %} + PROCESSO: {{ m.numeracao_set.first.numero_materia }} +   + {% else %} + PROCESSO: {{ m.numero }} +   + {% endif %} + + + {{m.tipo.sigla}}: {{m.numero}}/{{m.ano}}   + + + Pref: + {% if m.numeracao_set.first %} + {{ m.numeracao_set.first.numero_materia }} + {% endif %}
+ DATA DE ENTRADA: {{m.data_apresentacao}}
+ + + {% if m.autoria_set.all %} + Autores: + {% for a in m.autoria_set.all %} + {% if not forloop.first %} + ,    {{a.autor}} + {% else %} +  {{a.autor}} + {% endif %} + {% endfor %} +
+ {% endif %} + + + EMENTA: {{m.ementa}} + +
+ +
+
+
+
+
+ +{% endfor %} + + \ No newline at end of file