diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index 030e5386e..e446e6a64 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -26,6 +26,7 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, 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 @@ urlpatterns_impressos = [ 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 index a621754b7..0edd63a34 100644 --- 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 index 1d68dfce2..8dd7e9e47 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -29,6 +29,7 @@ from sapl.base.signals import tramitacao_signal 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 sapl.utils import (create_barcode, get_base_url, get_client_ip, from .forms import (AcompanhamentoDocumentoForm, AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, - DocumentoAdministrativoForm, ProtocoloDocumentForm, + DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm, ProtocoloDocumentForm, ProtocoloFilterSet, ProtocoloMateriaForm, TramitacaoAdmEditForm, TramitacaoAdmForm, DesvincularDocumentoForm, DesvincularMateriaForm, @@ -1073,3 +1074,98 @@ class DesvincularMateriaView(PermissionRequiredMixin, FormView): 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 diff --git a/sapl/templates/materia/impressos/ficha_adm_pdf.html b/sapl/templates/materia/impressos/ficha_adm_pdf.html new file mode 100644 index 000000000..b5de1e0a9 --- /dev/null +++ b/sapl/templates/materia/impressos/ficha_adm_pdf.html @@ -0,0 +1,107 @@ + +
+ + + + + + + + +
+
+ {{documento.tipo}}: {{documento.numero}} / {{documento.ano}} + |
+
+ + Data de entrada: {{documento.data}} + | +
+
+ Protocolo: {{materia.protocolo}} + |
+
+
+ Ementa: {{documento.assunto}}
+
+ |
+