Repository: interlegis/sapl

Issue:
Impressos - Capa de Processo para Documentos Administrativos
A função imprime o resumo "Despacho" apenas para Matérias Legislativas. A AL Alagoas nos solicitou implementar também para Documentos Administrativos.

Adicionar  tipos dos documentos administrativos, pois existe a função. Coloca-se um título de identificação: matérias legislativas e documentos administrativos. Isso implica buscar os dados administrativos em outro local. 
Caso a opção seja duplicar a função, sugiro criar uma nova linha no menu de opções: Impressos - matérias administrativas, Impressos - Documentos Administrativos.




Discussion:
>  A AL Alagoas nos solicitou 

@morale Nos solicitou como? Não vi nenhum ticket aberto no OSTicket e vc que está abrindo aqui no github.
![image](https://user-images.githubusercontent.com/19825887/47854109-a023e880-ddbf-11e8-9811-213914039faa.png)
Seria essa tela para Documento Administrativo?
Acrescida do número e ano do protocolo e sem essa parte inferior sobre norma jurídica.
O Despacho Processo - quando a ementa da matéria é mais extensa, ela fica sobrepondo o texto "Despacho Inicial:" que suponho estar em posição fixa quando, nesse caso, deveria ser impressa mais abaixo.
Outra questão é a impossibilidade de seleção de mais de uma matéria para impressão dessa etiqueta sem que seja necessária nova pesquisa.
Fechada por descrição inválida
@morale Quando se abre uma issue não é pra apagar todo aquele texto e digitar um simples parágrafo. Siga o formulário e preencha os campos que achar necessário. **A diretriz é fechar toda issue que não siga o template para colocar um pouco de estrutura no report de bugs e sugestões, agiliza na solução de problemas, além de ficart melhor registrado.**

Resolving patch:
diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py
--- a/sapl/materia/urls.py
+++ b/sapl/materia/urls.py
@@ -26,6 +26,7 @@
                                 proposicao_texto, recuperar_materia,
                                 ExcluirTramitacaoEmLoteView, RetornarProposicao)
 from sapl.norma.views import NormaPesquisaSimplesView
+from sapl.protocoloadm.views import (FichaPesquisaAdmView, FichaSelecionaAdmView)
 
 from .apps import AppConfig
 
@@ -47,6 +48,12 @@
     url(r'^materia/impressos/norma-pesquisa/$',
         NormaPesquisaSimplesView.as_view(),
         name='impressos_norma_pesquisa'),
+    url(r'^materia/impressos/ficha-pesquisa-adm/$',
+        FichaPesquisaAdmView.as_view(),
+        name= 'impressos_ficha_pesquisa_adm'),
+    url(r'^materia/impressos/ficha-seleciona-adm/$',
+        FichaSelecionaAdmView.as_view(),
+        name= 'impressos_ficha_seleciona_adm'),
 ]
 
 urlpatterns_materia = [
diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py
--- a/sapl/protocoloadm/forms.py
+++ b/sapl/protocoloadm/forms.py
@@ -1000,3 +1000,80 @@ def filtra_tramitacao_adm_destino_and_status(status, destino):
         status=status,
         unidade_tramitacao_destino=destino).distinct().values_list(
             'documento_id', flat=True)
+
+class FichaPesquisaAdmForm(forms.Form):
+
+    logger = logging.getLogger(__name__)
+
+    tipo_documento = forms.ModelChoiceField(
+        label=TipoDocumentoAdministrativo._meta.verbose_name,
+        queryset=TipoDocumentoAdministrativo.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(FichaPesquisaAdmForm, self).__init__(*args, **kwargs)
+
+        row1 = to_row(
+            [('tipo_documento', 6),
+             ('data_inicial', 3),
+             ('data_final', 3)])
+
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Fieldset(
+                ('Formulário de Ficha'),
+                row1,
+                form_actions(label='Pesquisar')
+            )
+        )
+
+    def clean(self):
+        super(FichaPesquisaAdmForm, self).clean()
+
+        if not self.is_valid():
+            return self.cleaned_data
+
+        cleaned_data = self.cleaned_data
+
+        if not self.is_valid():
+            return cleaned_data
+
+        if cleaned_data['data_final'] < cleaned_data['data_inicial']:
+            self.logger.error("A Data Final ({}) não pode ser menor que a Data Inicial ({})."
+                              .format(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 FichaSelecionaAdmForm(forms.Form):
+    documento = forms.ModelChoiceField(
+        widget=forms.RadioSelect,
+        queryset=DocumentoAdministrativo.objects.all(),
+        label='')
+
+    def __init__(self, *args, **kwargs):
+        super(FichaSelecionaAdmForm, self).__init__(*args, **kwargs)
+
+        row1 = to_row(
+            [('documento', 12)])
+
+        self.helper = FormHelper()
+        self.helper.layout = Layout(
+            Fieldset(
+                ('Selecione a ficha que deseja imprimir'),
+                row1,
+                form_actions(label='Gerar Impresso')
+            )
+        )
\ No newline at end of file
diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py
--- a/sapl/protocoloadm/views.py
+++ b/sapl/protocoloadm/views.py
@@ -29,6 +29,7 @@
 from sapl.comissoes.models import Comissao
 from sapl.crud.base import Crud, CrudAux, MasterDetailCrud, make_pagination
 from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa
+from sapl.materia.views import gerar_pdf_impressos
 from sapl.parlamentares.models import Legislatura, Parlamentar
 from sapl.protocoloadm.models import Protocolo
 from sapl.utils import (create_barcode, get_base_url, get_client_ip,
@@ -38,7 +39,7 @@
 from .forms import (AcompanhamentoDocumentoForm, AnularProcoloAdmForm,
                     DocumentoAcessorioAdministrativoForm,
                     DocumentoAdministrativoFilterSet,
-                    DocumentoAdministrativoForm, ProtocoloDocumentForm,
+                    DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm, ProtocoloDocumentForm,
                     ProtocoloFilterSet, ProtocoloMateriaForm,
                     TramitacaoAdmEditForm, TramitacaoAdmForm,
                     DesvincularDocumentoForm, DesvincularMateriaForm,
@@ -1073,3 +1074,98 @@ def form_valid(self, form):
         materia.numero_protocolo = None
         materia.save()
         return redirect(self.get_success_url())
+
+
+class ImpressosView(PermissionRequiredMixin, TemplateView):
+    template_name = 'materia/impressos/impressos.html'
+    permission_required = ('materia.can_access_impressos', )
+
+
+class FichaPesquisaAdmView(PermissionRequiredMixin, FormView):
+    form_class = FichaPesquisaAdmForm
+    template_name = 'materia/impressos/ficha.html'
+    permission_required = ('materia.can_access_impressos', )
+
+    def form_valid(self, form):
+        tipo_documento = form.data['tipo_documento']
+        data_inicial = form.data['data_inicial']
+        data_final = form.data['data_final']
+
+        url = reverse('sapl.materia:impressos_ficha_seleciona_adm')
+        url = url + '?tipo=%s&data_inicial=%s&data_final=%s' % (
+            tipo_documento, data_inicial, data_final)
+
+        return HttpResponseRedirect(url)
+
+
+class FichaSelecionaAdmView(PermissionRequiredMixin, FormView):
+    logger = logging.getLogger(__name__)
+    form_class = FichaSelecionaAdmForm
+    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_adm'))
+
+        context = super(FichaSelecionaAdmView, 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()
+
+        documento_list = DocumentoAdministrativo.objects.filter(
+            tipo=tipo,
+            data__range=(data_inicial, data_final))
+        context['quantidade'] = len(documento_list)
+        documento_list = documento_list[:100]
+
+        context['form'].fields['documento'].choices = [
+            (d.id, str(d)) for d in documento_list]
+
+        username = self.request.user.username
+
+        if context['quantidade'] > 100:
+            self.logger.info('user=' + username + '. Sua pesquisa (tipo={}, data_inicial={}, data_final={}) retornou mais do que '
+                             '100 impressos. Por questões de '
+                             'performance, foram retornados '
+                             'apenas os 100 primeiros. Caso '
+                             'queira outros, tente fazer uma '
+                             'pesquisa mais específica'.format(tipo, data_inicial, data_final))
+            messages.info(self.request, _('Sua pesquisa retornou mais do que '
+                                          '100 impressos. Por questões de '
+                                          'performance, foram retornados '
+                                          'apenas os 100 primeiros. Caso '
+                                          'queira outros, tente fazer uma '
+                                          'pesquisa mais específica'))
+
+        return context
+
+    def form_valid(self, form):
+        context = {}
+        username = self.request.user.username
+
+        try:
+            self.logger.debug(
+                "user=" + username + ". Tentando obter objeto DocumentoAdministrativo com id={}".format(form.data['documento']))
+            documento = DocumentoAdministrativo.objects.get(
+                id=form.data['documento'])
+        except ObjectDoesNotExist:
+            self.logger.error(
+                "user=" + username + ". Este DocumentoAdministrativo não existe (id={}).".format(form.data['documento']))
+            mensagem = _('Este Documento Administrativo não existe.')
+            self.messages.add_message(self.request, messages.INFO, mensagem)
+
+            return self.render_to_response(context)
+        if len(documento.assunto) > 301:
+            documento.assunto = documento.assunto[0:300] + '[...]'
+        context['documento'] = documento
+
+        return gerar_pdf_impressos(self.request, context,
+                                   'materia/impressos/ficha_adm_pdf.html')
\ No newline at end of file


Test patch: