Repository: interlegis/sapl

Issue:
Impressos - Adicionar etiqueta
Em Bento Gonçalves, no 2.5 usamos a etiqueta gerada pelo seguinte: impresso/ficha/selecionada

O perfil dela é o seguinte:
http://repositorio.interlegis.gov.br/ILSAPL/branches/2.5/skins/sk_sapl/generico/impressos/materia_ficha_selec_proc.dtml

Ela gera a seguinte etiqueta:

![image](https://user-images.githubusercontent.com/13314947/29840116-3932c2d4-8cd7-11e7-8c28-e83f97638f52.png)

Usamos para as capas dos processos
![image](https://user-images.githubusercontent.com/13314947/29840130-4ac973f8-8cd7-11e7-8580-21db934337e6.png)

![image](https://user-images.githubusercontent.com/13314947/29840137-520df490-8cd7-11e7-95de-de0641c1c137.png)


Ela contem os seguintes campos:
O número do Processo
tipo da matéria numero e ano
Data da entrada:
Autor:
Ementa:
Despacho Inicial:

e tem um espaço para anotações 
<strong></strong><br>
<strong>________________NORMA JURÍDICA_________________</strong><br><br>
<strong>_________________________________________________</strong>
   </div>  
Impressos - Adicionar etiqueta
Em Bento Gonçalves, no 2.5 usamos a etiqueta gerada pelo seguinte: impresso/ficha/selecionada

O perfil dela é o seguinte:
http://repositorio.interlegis.gov.br/ILSAPL/branches/2.5/skins/sk_sapl/generico/impressos/materia_ficha_selec_proc.dtml

Ela gera a seguinte etiqueta:

![image](https://user-images.githubusercontent.com/13314947/29840116-3932c2d4-8cd7-11e7-8c28-e83f97638f52.png)

Usamos para as capas dos processos
![image](https://user-images.githubusercontent.com/13314947/29840130-4ac973f8-8cd7-11e7-8580-21db934337e6.png)

![image](https://user-images.githubusercontent.com/13314947/29840137-520df490-8cd7-11e7-95de-de0641c1c137.png)


Ela contem os seguintes campos:
O número do Processo
tipo da matéria numero e ano
Data da entrada:
Autor:
Ementa:
Despacho Inicial:

e tem um espaço para anotações 
<strong></strong><br>
<strong>________________NORMA JURÍDICA_________________</strong><br><br>
<strong>_________________________________________________</strong>
   </div>  


Discussion:
para pesquisa após clicar no menu os campos são
![image](https://user-images.githubusercontent.com/13314947/29840632-0e3c8996-8cd9-11e7-9e09-ce8b17a31220.png)

posterior tem uma tela de seleção
![image](https://user-images.githubusercontent.com/13314947/29840672-301e44d2-8cd9-11e7-99f5-21d41346b7b4.png)

para pesquisa após clicar no menu os campos são
![image](https://user-images.githubusercontent.com/13314947/29840632-0e3c8996-8cd9-11e7-9e09-ce8b17a31220.png)

posterior tem uma tela de seleção
![image](https://user-images.githubusercontent.com/13314947/29840672-301e44d2-8cd9-11e7-99f5-21d41346b7b4.png)


Resolving patch:
diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py
--- a/sapl/materia/forms.py
+++ b/sapl/materia/forms.py
@@ -1678,3 +1678,71 @@ def clean(self):
                     'O processo final não pode ser menor que o inicial'))
 
         return cleaned_data
+
+
+class FichaPesquisaForm(forms.Form):
+    tipo_materia = forms.ModelChoiceField(
+        label=TipoMateriaLegislativa._meta.verbose_name,
+        queryset=TipoMateriaLegislativa.objects.all(),
+        empty_label='Selecione')
+
+    data_inicial = forms.DateField(
+        label='Data Inicial',
+        widget=forms.DateInput(format='%d/%m/%Y')
+    )
+
+    data_final = forms.DateField(
+        label='Data Final',
+        widget=forms.DateInput(format='%d/%m/%Y')
+    )
+
+    def __init__(self, *args, **kwargs):
+        super(FichaPesquisaForm, self).__init__(*args, **kwargs)
+
+        row1 = to_row(
+            [('tipo_materia', 6),
+             ('data_inicial', 3),
+             ('data_final', 3)])
+
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Fieldset(
+                ('Formulário de Ficha'),
+                row1,
+                form_actions(save_label='Pesquisar')
+            )
+        )
+
+    def clean(self):
+        cleaned_data = super(FichaPesquisaForm, self).clean()
+
+        if not self.is_valid():
+            return cleaned_data
+
+        if cleaned_data['data_final'] < cleaned_data['data_inicial']:
+            raise ValidationError(_(
+                'A Data Final não pode ser menor que a Data Inicial'))
+
+        return cleaned_data
+
+
+class FichaSelecionaForm(forms.Form):
+    materia = forms.ModelChoiceField(
+        widget=forms.RadioSelect,
+        queryset=MateriaLegislativa.objects.all(),
+        label='')
+
+    def __init__(self, *args, **kwargs):
+        super(FichaSelecionaForm, self).__init__(*args, **kwargs)
+
+        row1 = to_row(
+            [('materia', 12)])
+
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Fieldset(
+                ('Selecione a ficha que deseja imprimir'),
+                row1,
+                form_actions(save_label='Gerar Impresso')
+            )
+        )
diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py
--- a/sapl/materia/urls.py
+++ b/sapl/materia/urls.py
@@ -8,7 +8,8 @@
                                 CriarProtocoloMateriaView, DespachoInicialCrud,
                                 DocumentoAcessorioCrud,
                                 DocumentoAcessorioEmLoteView,
-                                EtiquetaPesquisaView, ImpressosView,
+                                ImpressosView, EtiquetaPesquisaView,
+                                FichaPesquisaView, FichaSelecionaView,
                                 LegislacaoCitadaCrud, MateriaAssuntoCrud,
                                 MateriaLegislativaCrud,
                                 MateriaLegislativaPesquisaView, MateriaTaView,
@@ -35,6 +36,12 @@
     url(r'^materia/impressos/etiqueta-pesquisa/$',
         EtiquetaPesquisaView.as_view(),
         name='impressos_etiqueta'),
+    url(r'^materia/impressos/ficha-pesquisa/$',
+        FichaPesquisaView.as_view(),
+        name='impressos_ficha_pesquisa'),
+    url(r'^materia/impressos/ficha-seleciona/$',
+        FichaSelecionaView.as_view(),
+        name='impressos_ficha_seleciona'),
 ]
 
 urlpatterns_materia = [
diff --git a/sapl/materia/views.py b/sapl/materia/views.py
--- a/sapl/materia/views.py
+++ b/sapl/materia/views.py
@@ -1,3 +1,4 @@
+import datetime as dt_generator
 from datetime import datetime
 from random import choice
 from string import ascii_letters, digits
@@ -13,7 +14,7 @@
 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 RequestContext, loader
+from django.template import loader, RequestContext
 from django.utils import formats
 from django.utils.translation import ugettext_lazy as _
 from django.views.generic import CreateView, ListView, TemplateView, UpdateView
@@ -47,10 +48,11 @@
 from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm,
                     AdicionarVariasAutoriasFilterSet, DespachoInicialForm,
                     DocumentoAcessorioForm, EtiquetaPesquisaForm,
-                    MateriaAssuntoForm, MateriaLegislativaFilterSet,
-                    MateriaSimplificadaForm, PrimeiraTramitacaoEmLoteFilterSet,
-                    ReceberProposicaoForm, RelatoriaForm,
-                    TramitacaoEmLoteFilterSet, filtra_tramitacao_destino,
+                    FichaPesquisaForm, FichaSelecionaForm, MateriaAssuntoForm,
+                    MateriaLegislativaFilterSet, MateriaSimplificadaForm,
+                    PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm,
+                    RelatoriaForm, TramitacaoEmLoteFilterSet,
+                    filtra_tramitacao_destino,
                     filtra_tramitacao_destino_and_status,
                     filtra_tramitacao_status)
 from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria,
@@ -1750,8 +1752,8 @@ class ImpressosView(PermissionRequiredMixin, TemplateView):
     permission_required = ('materia.can_access_impressos', )
 
 
-def gerar_pdf_impressos(request, context):
-    template = loader.get_template('materia/impressos/pdf.html')
+def gerar_pdf_impressos(request, context, template_name):
+    template = loader.get_template(template_name)
     html = template.render(RequestContext(request, context))
     response = HttpResponse(content_type="application/pdf")
     weasyprint.HTML(
@@ -1795,4 +1797,77 @@ def form_valid(self, form):
 
         context['materias'] = materias
 
-        return gerar_pdf_impressos(self.request, context)
+        return gerar_pdf_impressos(self.request, context,
+                                   'materia/impressos/etiqueta_pdf.html')
+
+
+class FichaPesquisaView(PermissionRequiredMixin, FormView):
+    form_class = FichaPesquisaForm
+    template_name = 'materia/impressos/ficha.html'
+    permission_required = ('materia.can_access_impressos', )
+
+    def form_valid(self, form):
+        tipo_materia = form.data['tipo_materia']
+        data_inicial = form.data['data_inicial']
+        data_final = form.data['data_final']
+
+        url = reverse('sapl.materia:impressos_ficha_seleciona')
+        url = url + '?tipo=%s&data_inicial=%s&data_final=%s' % (
+            tipo_materia, data_inicial, data_final)
+
+        return HttpResponseRedirect(url)
+
+class FichaSelecionaView(PermissionRequiredMixin, FormView):
+    form_class = FichaSelecionaForm
+    template_name = 'materia/impressos/ficha_seleciona.html'
+    permission_required = ('materia.can_access_impressos', )
+
+    def get_context_data(self, **kwargs):
+        if ('tipo' not in self.request.GET or
+            'data_inicial' not in self.request.GET or
+            'data_final' not in self.request.GET):
+            return HttpResponseRedirect(reverse(
+                'sapl.materia:impressos_ficha_pesquisa'))
+
+        context = super(FichaSelecionaView, self).get_context_data(
+            **kwargs)
+
+        tipo = self.request.GET['tipo']
+        data_inicial = datetime.strptime(
+            self.request.GET['data_inicial'], "%d/%m/%Y").date()
+        data_final = datetime.strptime(
+            self.request.GET['data_final'], "%d/%m/%Y").date()
+
+        materia_list = MateriaLegislativa.objects.filter(
+            tipo=tipo,
+            data_apresentacao__range=(data_inicial, data_final))
+        context['quantidade'] = len(materia_list)
+        materia_list = materia_list[:20]
+
+        context['form'].fields['materia'].choices = [(m.id, str(m)) for m in materia_list]
+
+        if context['quantidade'] > 20:
+            messages.info(self.request, _('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'))
+
+        return context
+
+    def form_valid(self, form):
+        context = {}
+
+        try:
+            materia = MateriaLegislativa.objects.get(
+                id=form.data['materia'])
+        except ObjectDoesNotExist:
+            mensagem = _('Esta Máteria não existe!')
+            self.messages.add_message(request, messages.INFO, mensagem)
+
+            return self.render_to_response(context)
+
+        context['materia'] = materia
+        context['despachos'] = materia.despachoinicial_set.all().values_list(
+                            'comissao__nome', flat=True)
+
+        return gerar_pdf_impressos(self.request, context, 'materia/impressos/ficha_pdf.html')


Test patch:
diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py
--- a/sapl/materia/tests/test_materia.py
+++ b/sapl/materia/tests/test_materia.py
@@ -17,7 +17,7 @@
                                TipoNormaJuridica)
 from sapl.utils import models_with_gr_for_model
 
-
+@pytest.mark.django_db(transaction=False)
 def make_unidade_tramitacao(descricao):
     # Cria uma comissão para ser a unidade de tramitação
     tipo_comissao = mommy.make(TipoComissao)
diff --git a/sapl/materia/tests/test_materia_form.py b/sapl/materia/tests/test_materia_form.py
new file mode 100644
--- /dev/null
+++ b/sapl/materia/tests/test_materia_form.py
@@ -0,0 +1,66 @@
+import pytest
+from django.utils.translation import ugettext as _
+from model_mommy import mommy
+
+from sapl.materia import forms
+from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa)
+
+@pytest.mark.django_db(transaction=False)
+def test_valida_campos_obrigatorios_ficha_pesquisa_form():
+    form = forms.FichaPesquisaForm(data={})
+
+    assert not form.is_valid()
+
+    errors = form.errors
+
+    assert errors['tipo_materia'] == [_('Este campo é obrigatório.')]
+    assert errors['data_inicial'] == [_('Este campo é obrigatório.')]
+    assert errors['data_final'] == [_('Este campo é obrigatório.')]
+
+    assert len(errors) == 3
+
+@pytest.mark.django_db(transaction=False)
+def test_ficha_pesquisa_form_datas_invalidas():
+    tipo = mommy.make(TipoMateriaLegislativa)
+
+    form = forms.FichaPesquisaForm(data={'tipo_materia': str(tipo.pk),
+                                         'data_inicial': '10/11/2017',
+                                         'data_final': '09/11/2017'
+                                         })
+    assert not form.is_valid()
+    assert form.errors['__all__'] == [_('A Data Final não pode ser menor que '
+                                                            'a Data Inicial')]
+
+
+@pytest.mark.django_db(transaction=False)
+def test_ficha_pesquisa_form_invalido():
+    tipo = mommy.make(TipoMateriaLegislativa)
+
+    form = forms.FichaPesquisaForm(data={'tipo_materia': str(tipo.pk),
+                                         'data_inicial': '10/11/2017',
+                                         'data_final': '09/11/2017'
+                                         })
+
+    assert not form.is_valid()
+
+
+@pytest.mark.django_db(transaction=False)
+def test_valida_campos_obrigatorios_ficha_seleciona_form():
+    form = forms.FichaSelecionaForm(data={})
+
+    assert not form.is_valid()
+
+    errors = form.errors
+
+    assert errors['materia'] == [_('Este campo é obrigatório.')]
+
+    assert len(errors) == 1
+
+
+@pytest.mark.django_db(transaction=False)
+def test_ficha_seleciona_form_valido():
+    materia = mommy.make(MateriaLegislativa)
+
+    form = forms.FichaSelecionaForm(data={'materia': str(materia.pk)})
+
+    assert form.is_valid()