from datetime import date, datetime from re import sub from django import forms from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse from django.db.models import Max from django.http import HttpResponseRedirect from django.shortcuts import redirect from django.utils.html import strip_tags from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, DetailView, ListView from django.views.generic.base import TemplateView from django.views.generic.edit import FormMixin from vanilla import GenericView from crud import Crud, make_pagination from materia.models import Proposicao, TipoMateriaLegislativa from sapl.utils import create_barcode from .forms import (AnularProcoloAdmForm, DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoForm, ProposicaoSimpleForm, ProtocoloDocumentForm, ProtocoloForm, ProtocoloMateriaForm, TramitacaoAdmForm) from .models import (Autor, DocumentoAcessorioAdministrativo, DocumentoAdministrativo, Protocolo, StatusTramitacaoAdministrativo, TipoDocumentoAdministrativo, TramitacaoAdministrativo) tipo_documento_administrativo_crud = Crud(TipoDocumentoAdministrativo, '') documento_administrativo_crud = Crud(DocumentoAdministrativo, '') documento_acessorio_administrativo_crud = Crud( DocumentoAcessorioAdministrativo, '') status_tramitacao_administrativo_crud = Crud( StatusTramitacaoAdministrativo, '') tramitacao_administrativo_crud = Crud(TramitacaoAdministrativo, '') protocolo_documento_crud = Crud(Protocolo, '') # FIXME precisa de uma chave diferente para o layout protocolo_materia_crud = Crud(Protocolo, '') class ProtocoloListView(FormMixin, ListView): template_name = 'protocoloadm/protocolo_list.html' context_object_name = 'protocolos' model = Protocolo paginate_by = 10 def get_queryset(self): kwargs = self.request.session['kwargs'] return Protocolo.objects.filter( **kwargs) def get_context_data(self, **kwargs): context = super(ProtocoloListView, self).get_context_data( **kwargs) paginator = context['paginator'] page_obj = context['page_obj'] context['page_range'] = make_pagination( page_obj.number, paginator.num_pages) return context class ProtocoloPesquisaView(FormMixin, GenericView): template_name = 'protocoloadm/protocolo_pesquisa.html' form_class = ProtocoloForm() context_object_name = 'protocolos' paginate_by = 10 extra_context = {} def get_success_url(self): return reverse('protocolo') def get(self, request, *args, **kwargs): form = ProtocoloForm() return self.render_to_response({'form': form}) def get_form(self, data=None, files=None, **kwargs): return ProtocoloForm() def get_context_data(self, **kwargs): context = super(ProtocoloPesquisaView, self).get_context_data(**kwargs) context.update(self.extra_context) return context def post(self, request, *args, **kwargs): form = ProtocoloForm(request.POST or None) if form.is_valid(): kwargs = {} # format = '%Y-%m-%d' if request.POST['tipo_protocolo']: kwargs['tipo_protocolo'] = request.POST['tipo_protocolo'] if request.POST['numero_protocolo']: kwargs['numero'] = request.POST['numero_protocolo'] if request.POST['ano']: kwargs['ano'] = request.POST['ano'] if request.POST['inicial']: kwargs['data'] = datetime.strptime( request.POST['inicial'], '%d/%m/%Y').strftime('%Y-%m-%d') # if request.POST['final']: # kwargs['final'] = request.POST['final'] if request.POST['natureza_processo']: kwargs['tipo_protocolo'] = request.POST['natureza_processo'] if request.POST['tipo_documento']: kwargs['tipo_documento'] = request.POST['tipo_documento'] if request.POST['interessado']: kwargs['interessado__icontains'] = request.POST['interessado'] if request.POST['tipo_materia']: kwargs['tipo_materia'] = request.POST['tipo_materia'] if request.POST['autor']: kwargs['autor'] = request.POST['autor'] if request.POST['assunto']: kwargs['assunto_ementa__icontains'] = request.POST['assunto'] request.session['kwargs'] = kwargs return redirect('protocolo_list') else: return self.form_invalid(form) def get_client_ip(request): x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') return ip class AnularProtocoloAdmView(FormMixin, GenericView): template_name = 'protocoloadm/anular_protocoloadm.html' def get_success_url(self): return reverse('anular_protocolo') def get(self, request, *args, **kwargs): form = AnularProcoloAdmForm() return self.render_to_response({'form': form}) def post(self, request, *args, **kwargs): form = AnularProcoloAdmForm(request.POST) if form.is_valid(): numero = request.POST['numero_protocolo'] ano = request.POST['ano_protocolo'] justificativa_anulacao = sub(' ', ' ', strip_tags( request.POST['justificativa_anulacao'])) user_anulacao = request.user.username ip_addr = get_client_ip(request) try: protocolo = Protocolo.objects.get(numero=numero, ano=ano) if protocolo.anulado: errors = form._errors.setdefault( forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList()) errors.append(_("Procolo %s/%s já está anulado") % (numero, ano)) return self.form_invalid(form) protocolo.anulado = True protocolo.justificativa_anulacao = justificativa_anulacao protocolo.user_anulacao = user_anulacao protocolo.ip_anulacao = ip_addr protocolo.save() return self.form_valid(form) except ObjectDoesNotExist: errors = form._errors.setdefault( forms.forms.NON_FIELD_ERRORS, forms.util.ErrorList()) errors.append(_("Procolo %s/%s não existe") % (numero, ano)) return self.form_invalid(form) else: return self.form_invalid(form) class ProtocoloDocumentoView(FormMixin, GenericView): template_name = "protocoloadm/protocolar_documento.html" model = Protocolo def get_success_url(self): return reverse('protocolo') def get(self, request, *args, **kwargs): form = ProtocoloDocumentForm() return self.render_to_response({'form': form}) def post(self, request, *args, **kwargs): form = ProtocoloDocumentForm(request.POST) if form.is_valid(): if request.POST['numeracao'] == '1': numeracao = Protocolo.objects.filter( ano=date.today().year).aggregate(Max('numero')) else: numeracao = Protocolo.objects.all().aggregate(Max('numero')) if numeracao['numero__max'] is None: numeracao['numero__max'] = 0 protocolo = Protocolo() protocolo.numero = numeracao['numero__max'] + 1 protocolo.ano = datetime.now().year protocolo.data = datetime.now().strftime("%Y-%m-%d") protocolo.hora = datetime.now().strftime("%H:%M") protocolo.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M") protocolo.tipo_protocolo = request.POST['tipo_protocolo'] protocolo.tipo_processo = '0' # TODO validar o significado protocolo.interessado = request.POST['interessado'] protocolo.anulado = False protocolo.tipo_documento = TipoDocumentoAdministrativo.objects.get( id=request.POST['tipo_documento']) protocolo.assunto_ementa = sub( ' ', ' ', strip_tags(request.POST['assunto'])) protocolo.numero_paginas = request.POST['num_paginas'] protocolo.observacao = sub( ' ', ' ', strip_tags(request.POST['observacao'])) return self.form_valid(form) else: return self.form_invalid(form) def criar_documento(protocolo): doc = {} numero = Protocolo.objects.filter( tipo_documento=protocolo.tipo_documento, ano=protocolo.ano, anulado=False).aggregate(Max('numero')) doc['tipo'] = protocolo.tipo_documento doc['ano'] = protocolo.ano doc['data'] = protocolo.data doc['numero_protocolo'] = protocolo.numero doc['assunto'] = protocolo.assunto_ementa doc['interessado'] = protocolo.interessado doc['numero'] = numero['numero__max'] if doc['numero'] is None: doc['numero'] = 1 return doc class CriarDocumentoProtocolo(CreateView): template_name = "protocoloadm/criar_documento.html" form_class = DocumentoAdministrativoForm def get_initial(self): numero = self.kwargs['pk'] ano = self.kwargs['ano'] protocolo = Protocolo.objects.get(ano=ano, numero=numero) return criar_documento(protocolo) def get_success_url(self): return reverse('detail_doc_adm', kwargs={'pk': self.object.pk}) class ProtocoloMostrarView(TemplateView): template_name = "protocoloadm/protocolo_mostrar.html" def get(self, request, *args, **kwargs): numero = self.kwargs['pk'] ano = self.kwargs['ano'] protocolo = Protocolo.objects.get(ano=ano, numero=numero) return self.render_to_response({"protocolo": protocolo}) class ComprovanteProtocoloView(TemplateView): template_name = "protocoloadm/comprovante.html" def get(self, request, *args, **kwargs): numero = self.kwargs['pk'] ano = self.kwargs['ano'] protocolo = Protocolo.objects.get(ano=ano, numero=numero) # numero is string, padd with zeros left via .zfill() base64_data = create_barcode(numero.zfill(6)) barcode = 'data:image/png;base64,{0}'.format(base64_data) autenticacao = _("** NULO **") if not protocolo.anulado: autenticacao = str(protocolo.tipo_processo) + \ protocolo.data.strftime("%Y/%m/%d") + \ str(protocolo.numero).zfill(6) return self.render_to_response({"protocolo": protocolo, "barcode": barcode, "autenticacao": autenticacao}) class ProtocoloMateriaView(FormMixin, GenericView): template_name = "protocoloadm/protocolar_materia.html" model = Protocolo def get(self, request, *args, **kwargs): form = ProtocoloMateriaForm() return self.render_to_response({'form': form}) def post(self, request, *args, **kwargs): form = ProtocoloMateriaForm(request.POST) if form.is_valid(): if request.POST['numeracao'] == '1': numeracao = Protocolo.objects.filter( ano=date.today().year).aggregate(Max('numero')) else: numeracao = Protocolo.objects.all().aggregate(Max('numero')) if numeracao is None: numeracao['numero__max'] = 0 protocolo = Protocolo() protocolo.numero = numeracao['numero__max'] + 1 protocolo.ano = datetime.now().year protocolo.data = datetime.now().strftime("%Y-%m-%d") protocolo.hora = datetime.now().strftime("%H:%M") protocolo.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M") protocolo.tipo_protocolo = request.POST['tipo_protocolo'] protocolo.tipo_processo = '0' # TODO validar o significado protocolo.autor = Autor.objects.get(id=request.POST['autor']) protocolo.anulado = False protocolo.tipo_materia = TipoMateriaLegislativa.objects.get( id=request.POST['tipo_materia']) protocolo.numero_paginas = request.POST['num_paginas'] protocolo.observacao = sub( ' ', ' ', strip_tags(request.POST['observacao'])) protocolo.save() return self.form_valid(form) else: return self.form_invalid(form) # TODO: move to Proposicao app class ProposicaoReceberView(TemplateView): template_name = "protocoloadm/proposicao_receber.html" class ProposicoesNaoRecebidasView(ListView): template_name = "protocoloadm/proposicoes_naorecebidas.html" model = Proposicao paginate_by = 10 def get_queryset(self): return Proposicao.objects.filter(data_envio__isnull=False, status='E') class ProposicoesNaoIncorporadasView(ListView): template_name = "protocoloadm/proposicoes_naoincorporadas.html" model = Proposicao paginate_by = 10 def get_queryset(self): return Proposicao.objects.filter(data_envio__isnull=False, data_devolucao__isnull=False, status='D') class ProposicoesIncorporadasView(ListView): template_name = "protocoloadm/proposicoes_incorporadas.html" model = Proposicao paginate_by = 10 def get_queryset(self): return Proposicao.objects.filter(data_envio__isnull=False, data_recebimento__isnull=False, status='I') class ProposicaoView(TemplateView): template_name = "protocoloadm/proposicoes.html" class ProposicaoDetailView(DetailView): template_name = "protocoloadm/proposicao_view.html" model = Proposicao def get(self, request, *args, **kwargs): proposicao = Proposicao.objects.get(id=kwargs['pk']) data = { # 'ano': proposicao.ano, # TODO: FIX 'tipo': proposicao.tipo.descricao, # TODO: FIX 'materia': proposicao.materia, 'numero_proposicao': proposicao.numero_proposicao, 'data_envio': proposicao.data_envio, 'data_recebimento': proposicao.data_recebimento, 'descricao': proposicao.descricao} form = ProposicaoSimpleForm(initial=data) return self.render_to_response({'form': form}) def get_context_data(self, **kwargs): context = super(ProposicaoView, self).get_context_data(**kwargs) context['form'] = ProposicaoSimpleForm return context class PesquisarDocumentoAdministrativo(TemplateView): template_name = "protocoloadm/pesquisa_doc_adm.html" def get_tipos_doc(self): return TipoDocumentoAdministrativo.objects.all() def get(self, request, *args, **kwargs): return self.render_to_response( {"tipos_doc": TipoDocumentoAdministrativo.objects.all()} ) def post(self, request, *args, **kwargs): if request.POST['tipo_documento']: kwargs['tipo_id'] = request.POST['tipo_documento'] if request.POST['numero']: kwargs['numero'] = request.POST['numero'] if request.POST['ano']: kwargs['ano'] = request.POST['ano'] if request.POST['numero_protocolo']: kwargs['numero_protocolo'] = request.POST['numero_protocolo'] if request.POST['periodo_inicial']: kwargs['periodo_inicial'] = request.POST['periodo_inicial'] if request.POST['periodo_final']: kwargs['periodo_final'] = request.POST['periodo_final'] if request.POST['interessado']: kwargs['interessado'] = request.POST['interessado'] if request.POST['assunto']: kwargs['assunto_ementa__icontains'] = request.POST['assunto'] if request.POST['tramitacao']: if request.POST['tramitacao'] == 1: kwargs['tramitacao'] = True elif request.POST['tramitacao'] == 0: kwargs['tramitacao'] = False else: kwargs['tramitacao'] = request.POST['tramitacao'] # TODO # if request.POST['localizacao']: # kwargs['localizacao'] = request.POST['localizacao'] # if request.POST['situacao']: # kwargs['situacao'] = request.POST['situacao'] doc = DocumentoAdministrativo.objects.filter(**kwargs) if len(doc) == 0: return self.render_to_response( {'error': _('Nenhum resultado encontrado!'), "tipos_doc": TipoDocumentoAdministrativo.objects.all()} ) else: return self.render_to_response( {'documentos': doc} ) class DetailDocumentoAdministrativo(DetailView): template_name = "protocoloadm/detail_doc_adm.html" def get(self, request, *args, **kwargs): documento = DocumentoAdministrativo.objects.get( id=self.kwargs['pk']) form = DocumentoAdministrativoForm( instance=documento) return self.render_to_response({ 'form': form, 'pk': kwargs['pk']}) def post(self, request, *args, **kwargs): if 'Salvar' in request.POST: form = DocumentoAdministrativoForm(request.POST) if form.is_valid(): doc = form.save(commit=False) if 'texto_integral' in request.FILES: doc.texto_integral = request.FILES['texto_integral'] doc.save() return self.form_valid(form) else: return self.render_to_response({'form': form}) elif 'Excluir' in request.POST: DocumentoAdministrativo.objects.get( id=kwargs['pk']).delete() return HttpResponseRedirect(self.get_success_delete()) return HttpResponseRedirect(self.get_success_url()) def get_success_delete(self): return reverse('pesq_doc_adm') def get_success_url(self): return reverse('detail_doc_adm', kwargs={ 'pk': self.kwargs['pk']}) class DocumentoAcessorioAdministrativoEditView(FormMixin, GenericView): template_name = "protocoloadm/documento_acessorio_administrativo_edit.html" def get(self, request, *args, **kwargs): doc = DocumentoAdministrativo.objects.get( id=kwargs['pk']) doc_ace = DocumentoAcessorioAdministrativo.objects.get( id=kwargs['ano']) form = DocumentoAcessorioAdministrativoForm(instance=doc_ace, excluir=True) return self.render_to_response({'pk': self.kwargs['pk'], 'doc': doc, 'doc_ace': doc_ace, 'form': form}) def post(self, request, *args, **kwargs): form = DocumentoAcessorioAdministrativoForm(request.POST, excluir=True) doc_ace = DocumentoAcessorioAdministrativo.objects.get( id=kwargs['ano']) if form.is_valid(): if 'Salvar' in request.POST: if 'arquivo' in request.FILES: doc_ace.arquivo = request.FILES['arquivo'] doc_ace.documento = DocumentoAdministrativo.objects.get( id=kwargs['pk']) doc_ace.tipo = TipoDocumentoAdministrativo.objects.get( id=form.data['tipo']) doc_ace.nome = form.data['nome'] doc_ace.autor = form.data['autor'] doc_ace.data = datetime.strptime( form.data['data'], '%d/%m/%Y') doc_ace.assunto = form.data['assunto'] doc_ace.save() elif 'Excluir' in request.POST: doc_ace.delete() return self.form_valid(form) else: return self.form_invalid(form) def get_success_url(self): pk = self.kwargs['pk'] return reverse('doc_ace_adm', kwargs={'pk': pk}) class DocumentoAcessorioAdministrativoView(FormMixin, GenericView): template_name = "protocoloadm/documento_acessorio_administrativo.html" def get(self, request, *args, **kwargs): form = DocumentoAcessorioAdministrativoForm() doc = DocumentoAdministrativo.objects.get( id=kwargs['pk']) doc_ace_null = '' doc_acessorio = DocumentoAcessorioAdministrativo.objects.filter( documento_id=kwargs['pk']) if not doc_acessorio: doc_ace_null = _('Nenhum documento acessório \ cadastrado para este processo.') return self.render_to_response({'pk': kwargs['pk'], 'doc': doc, 'doc_ace': doc_acessorio, 'doc_ace_null': doc_ace_null, 'form': form}) def post(self, request, *args, **kwargs): form = DocumentoAcessorioAdministrativoForm(request.POST) if form.is_valid(): doc_ace = form.save(commit=False) if 'arquivo' in request.FILES: doc_ace.arquivo = request.FILES['arquivo'] doc = DocumentoAdministrativo.objects.get( id=kwargs['pk']) doc_ace.documento = doc doc_ace.save() return self.form_valid(form) else: return self.form_invalid(form) def get_success_url(self): pk = self.kwargs['pk'] return reverse('doc_ace_adm', kwargs={'pk': pk}) class TramitacaoAdmView(FormMixin, GenericView): template_name = "protocoloadm/tramitacao.html" def get(self, request, *args, **kwargs): pk = kwargs['pk'] documento = DocumentoAdministrativo.objects.get(id=pk) tramitacoes = TramitacaoAdministrativo.objects.filter( documento=documento).order_by('-data_tramitacao') return self.render_to_response({'documento': documento, 'tramitacoes': tramitacoes}) class TramitacaoAdmIncluirView(FormMixin, GenericView): template_name = "protocoloadm/tramitacao_incluir.html" def get(self, request, *args, **kwargs): pk = kwargs['pk'] documento = DocumentoAdministrativo.objects.get(id=pk) data = {'documento': documento} form = TramitacaoAdmForm(initial=data) return self.render_to_response({'documento': documento, 'form': form}) def post(self, request, *args, **kwargs): pk = kwargs['pk'] form = TramitacaoAdmForm(request.POST or None) if form.is_valid(): tramitacao = form.save(commit=False) tramitacao.ultima = False tramitacao.save() return HttpResponseRedirect( reverse('tramitacao', kwargs={'pk': pk})) else: return self.form_invalid(form) class TramitacaoAdmEditView(FormMixin, GenericView): template_name = "protocoloadm/tramitacao_edit.html" def get(self, request, *args, **kwargs): pk = kwargs['pk'] tramitacao = TramitacaoAdministrativo.objects.get(id=pk) documento = tramitacao.documento form = TramitacaoAdmForm(instance=tramitacao) return self.render_to_response({'documento': documento, 'form': form}) def post(self, request, *args, **kwargs): pk = kwargs['pk'] tramitacao = TramitacaoAdministrativo.objects.get(id=pk) form = TramitacaoAdmForm(request.POST, instance=tramitacao) if form.is_valid(): tramitacao = form.save(commit=False) tramitacao.ultima = False tramitacao.save() return HttpResponseRedirect( reverse('tramitacao', kwargs={'pk': tramitacao.documento.id})) else: return self.form_invalid(form) class TramitacaoAdmDeleteView(FormMixin, GenericView): template_name = "protocoloadm/tramitacao.html" def get(self, request, *args, **kwargs): pk = kwargs['pk'] oid = kwargs['oid'] documento = DocumentoAdministrativo.objects.get(id=pk) tramitacao = TramitacaoAdministrativo.objects.get(id=oid) tramitacao.delete() tramitacoes = TramitacaoAdministrativo.objects.filter( documento=documento) return self.render_to_response({'documento': documento, 'tramitacoes': tramitacoes})