# -*- coding: utf-8 -*- # # sigi.apps.home.views # # Copyright (c) 2016 by Interlegis # # GNU General Public License (GPL) # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # import datetime import calendar from django.shortcuts import render, get_object_or_404 from django.utils.translation import gettext as _ from itertools import cycle from sigi.apps.casas.models import Orgao from sigi.apps.convenios.models import Convenio, Projeto from sigi.apps.diagnosticos.models import Diagnostico from sigi.apps.metas.models import Meta from sigi.apps.servicos.models import TipoServico from sigi.apps.servidores.models import Servidor from django.views.decorators.cache import never_cache from django.contrib.auth.decorators import login_required from django.http.response import JsonResponse, HttpResponse from django.core.urlresolvers import reverse from django.db.models import Q, Count from sigi.shortcuts import render_to_pdf import csv @never_cache @login_required def index(request): context = {'gerentes': Servidor.objects.exclude(casas_que_gerencia=None)} return render(request, 'index.html', context) @never_cache @login_required def resumo_convenios(request): context = {'tabela_resumo_camara': busca_informacoes_camara() } return render(request, 'snippets/modules/resumo_convenios.html', context) @never_cache @login_required def resumo_seit(request): mes = request.GET.get('mes', None) ano = request.GET.get('ano', None) try: mes = datetime.date(year=int(ano), month=int(mes), day=1) tabela_resumo_seit = busca_informacoes_seit(mes) except: tabela_resumo_seit = busca_informacoes_seit() context = {'tabela_resumo_seit': tabela_resumo_seit} return render(request, 'snippets/modules/resumo_seit.html', context) @never_cache @login_required def chart_seit(request): mes = request.GET.get('mes', None) ano = request.GET.get('ano', None) try: mes = datetime.date(year=int(ano), month=int(mes), day=1) tabela_resumo_seit = busca_informacoes_seit(mes) except: tabela_resumo_seit = busca_informacoes_seit() data = { 'type': 'line', 'prevlink': reverse('home_chartseit') + ('?ano=%s&mes=%s' % (tabela_resumo_seit['mes_anterior'].year, tabela_resumo_seit['mes_anterior'].month)), 'nextlink': reverse('home_chartseit') + ('?ano=%s&mes=%s' % (tabela_resumo_seit['proximo_mes'].year, tabela_resumo_seit['proximo_mes'].month)), 'options': {'bezierCurve': False, 'datasetFill': False, 'pointDot': False, 'responsive': True}, 'data': { 'labels': ['%02d/%s' % (mes.month, mes.year) for mes in reversed(tabela_resumo_seit['meses'])], 'datasets': [ { 'label': servico['nome'], 'strokeColor': servico['cor'], 'data': [mes['total'] for mes in reversed(servico['novos_por_mes'])] } for servico in tabela_resumo_seit['servicos']], } } return JsonResponse(data) @never_cache @login_required def chart_convenios(request): q = request.GET.get('q', 'all') convenios = Convenio.objects.all() if q == 'assinados': convenios = convenios.exclude(data_retorno_assinatura=None) data = { 'type': 'pie', 'options': {'responsive': False, 'maintainAspectRatio': False}, 'data': grafico_convenio_projeto(convenios), } return JsonResponse(data) @never_cache @login_required def chart_carteira(request): colors, highlights = color_palete() data = {'type': 'pie', 'options': {'responsive': True}, 'data': [{'value': r['total_casas'], 'color': colors.next(), 'highlight': highlights.next(), 'label': r['gerentes_interlegis__nome_completo'] } for r in Orgao.objects.exclude( gerentes_interlegis=None).values( 'gerentes_interlegis__nome_completo').annotate( total_casas=Count('pk')).order_by( 'gerentes_interlegis__nome_completo') ] } return JsonResponse(data) @never_cache @login_required def chart_performance(request): servidor = request.GET.get('servidor', None) if servidor is None: casas = Orgao.objects.exclude(gerentes_interlegis=None) else: gerente = get_object_or_404(Servidor, pk=servidor) casas = gerente.casas_que_gerencia data = { 'type': 'pie', 'options': {'responsive': True}, 'data': [ {'label': _(u"Utilizam serviços"), 'value': casas.exclude(servico=None).count(), 'color': '#91e8e1'}, {'label': _(u"Não utilizam serviços"), 'value': casas.filter(servico=None).count(), 'color': '#f7a35c'}, ] } return JsonResponse(data) @never_cache @login_required def report_sem_convenio(request): modo = request.GET.get('modo', None) fmt = request.GET.get('f', 'pdf') sc = sem_convenio() if modo == 'H': casas = sc['hospedagem'] titulo = _(u"Casas sem convenio que utilizam algum serviço de " u"hospedagem") elif modo == 'R': casas = sc['registro'] titulo = _(u"Casas sem convenio que utilizam somente serviço de " u"registro") else: casas = sc['total'] titulo = _(u"Casas sem convenio que utilizam algum serviço de registro " u"e/ou hospedagem") if fmt == 'csv': response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=casas.csv' writer = csv.writer(response) writer.writerow([titulo.encode('utf8')]) writer.writerow([u'']) writer.writerow([u'casa', u'uf', u'gerentes', u'serviços'.encode('utf8')]) for casa in casas: writer.writerow([ casa.nome.encode('utf8'), casa.municipio.uf.sigla.encode('utf8'), casa.lista_gerentes(fmt='lista').encode('utf8'), (u', '.join(casa.servico_set.filter( data_desativacao__isnull=True).values_list( 'tipo_servico__nome', flat=True))).encode('utf8'), ]) return response elif fmt == 'json': data = { 'titulo': titulo, 'casas': [ {'nome': casa.nome, 'uf': casa.municipio.uf.sigla, 'gerentes': list(casa.gerentes_interlegis.all().values_list( 'nome_completo', flat=True)), 'servicos': list(casa.servico_set.filter( data_desativacao__isnull=True).values_list( 'tipo_servico__nome', flat=True))} for casa in casas ] } return JsonResponse(data, safe=False) else: context = {'casas': casas, 'titulo': titulo} return render_to_pdf('home/sem_convenio.html', context) def busca_informacoes_camara(): """ Busca informacoes no banco para montar tabela de resumo de camaras por projeto Retorna um dicionario de listas """ camaras = Orgao.objects.filter(tipo__sigla='CM') convenios = Convenio.objects.filter(casa_legislativa__tipo__sigla='CM') projetos = Projeto.objects.all() convenios_assinados = convenios.exclude(data_retorno_assinatura=None) convenios_em_andamento = convenios.filter(data_retorno_assinatura=None) convenios_sem_adesao = convenios.filter(data_adesao=None) convenios_com_adesao = convenios.exclude(data_adesao=None) convenios_com_aceite = convenios.exclude(data_termo_aceite=None) camaras_sem_processo = camaras.filter(convenio=None) # Criacao das listas para o resumo de camaras por projeto cabecalho_topo = ['', ] # Cabecalho superior da tabela lista_total = [] lista_nao_aderidas = [] lista_aderidas = [] lista_convenios_assinados = [] lista_convenios_em_andamento = [] lista_camaras_equipadas = [] for projeto in projetos: conv_sem_adesao_proj = convenios_sem_adesao.filter(projeto=projeto) conv_com_adesao_proj = convenios_com_adesao.filter(projeto=projeto) conv_assinados_proj = convenios_assinados.filter(projeto=projeto) conv_em_andamento_proj = convenios_em_andamento.filter(projeto=projeto) conv_equipadas_proj = convenios_com_aceite.filter(projeto=projeto) cabecalho_topo.append(projeto.sigla) lista_total.append(camaras.filter(convenio__projeto=projeto).count()) lista_nao_aderidas.append(camaras.filter(convenio__in=conv_sem_adesao_proj).count()) lista_aderidas.append(camaras.filter(convenio__in=conv_com_adesao_proj).count()) lista_convenios_assinados.append(camaras.filter(convenio__in=conv_assinados_proj).count()) lista_convenios_em_andamento.append(camaras.filter(convenio__in=conv_em_andamento_proj).count()) lista_camaras_equipadas.append(camaras.filter(convenio__in=conv_equipadas_proj).count()) # Monta linhas de diagnosticos lista_diagnosticos_digitados = ['', '', Diagnostico.objects.count(), '', '', ''] lista_diagnosticos_publicados = ['', '', Diagnostico.objects.filter(publicado=True).count(), '', '', ''] # Cabecalho da esquerda na tabela cabecalho_esquerda = ( _(u'Câmaras municipais'), _(u'Câmaras municipais não aderidas'), _(u'Câmaras municipais aderidas'), _(u'Câmaras municipais com convênios assinados'), _(u'Câmaras municipais convênios em andamento'), _(u'Câmaras municipais equipadas'), _(u'Diagnósticos digitados'), _(u'Diagnósticos publicados') ) linhas = ( lista_total, lista_nao_aderidas, lista_aderidas, lista_convenios_assinados, lista_convenios_em_andamento, lista_camaras_equipadas, lista_diagnosticos_digitados, lista_diagnosticos_publicados ) # Unindo as duas listass para que o cabecalho da esquerda fique junto com sua # respectiva linha lista_zip = zip(cabecalho_esquerda, linhas) # Retornando listas em forma de dicionario return { 'cabecalho_topo': cabecalho_topo, 'lista_zip': lista_zip, 'total_camaras': camaras.count(), 'camaras_sem_processo': camaras_sem_processo.count(), 'sem_convenio': sem_convenio(), } def sem_convenio(): total = Orgao.objects.exclude(servico=None).filter(servico__data_desativacao=None, convenio=None).order_by('municipio__uf__sigla', 'nome').distinct('municipio__uf__sigla', 'nome') hospedagem = Orgao.objects.exclude(servico=None).filter(servico__data_desativacao=None, servico__tipo_servico__modo='H', convenio=None).order_by('municipio__uf__sigla', 'nome').distinct('municipio__uf__sigla', 'nome') reg_keys = set(total.values_list('pk', flat=True)).difference(set(hospedagem.values_list('pk', flat=True))) registro = Orgao.objects.filter(pk__in=reg_keys).order_by('municipio__uf__sigla', 'nome') return { 'total': total, 'hospedagem': hospedagem, 'registro': registro, } def grafico_convenio_projeto(convenios): colors, highlights = color_palete() projetos = Projeto.objects.all() lista_projetos = [{'label': projeto.sigla, 'value': convenios.filter(projeto=projeto).count(), 'color': colors.next(), 'highlight': highlights.next()} for projeto in projetos] # remove projetos sem convenio lista_projetos = [x for x in lista_projetos if x['value'] > 0] # print lista_projetos # total_convenios = "Total: " + str(convenios.count()) # lista_projetos.insert(0, total_convenios) return lista_projetos def busca_informacoes_seit(mes_atual=None): colors, highlights = color_palete() if mes_atual is None: mes_atual = datetime.date.today().replace(day=1) mes_anterior = mes_atual - datetime.timedelta(days=1) proximo_mes = mes_atual + datetime.timedelta(days=calendar.monthrange(mes_atual.year, mes_atual.month)[1]) meses = [] mes = mes_atual for i in range(1, 13): meses.append(mes) mes = (mes - datetime.timedelta(days=1)).replace(day=1) result = { 'mes_atual': mes_atual, 'mes_anterior': mes_anterior, 'proximo_mes': proximo_mes, 'meses': meses, 'titulos': [ '', 'Total de casas atendidas', 'Novas casas em %s/%s' % (mes_anterior.month, mes_anterior.year), 'Novas casas em %s/%s' % (mes_atual.month, mes_atual.year) ], 'servicos': [], } for tipo_servico in TipoServico.objects.all(): por_mes = [] for mes in meses: por_mes.append({'mes': '%02d/%s' % (mes.month, mes.year), 'total': tipo_servico.servico_set.filter(data_ativacao__year=mes.year, data_ativacao__month=mes.month).count()}) result['servicos'].append( {'nome': tipo_servico.nome, 'total': tipo_servico.servico_set.filter(Q(data_ativacao__lt=proximo_mes)&(Q(data_desativacao=None)|Q(data_desativacao__gt=proximo_mes))).count(), 'novos_mes_anterior': tipo_servico.servico_set.filter(data_ativacao__year=mes_anterior.year, data_ativacao__month=mes_anterior.month).count(), 'novos_mes_atual': tipo_servico.servico_set.filter(data_ativacao__year=mes_atual.year, data_ativacao__month=mes_atual.month).count(), 'novos_por_mes': por_mes, 'cor': colors.next(), } ) return result def busca_informacoes_diagnostico(): return [ {'title': _(u'Diagnósticos digitados'), 'count': Diagnostico.objects.count()}, {'title': _(u'Diagnósticos publicados'), 'count': Diagnostico.objects.filter(publicado=True).count()}, ] def color_palete(): colors = cycle(['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9', '#f15c80', '#e4d354', '#8085e8', '#8d4653', '#91e8e1', ]) highlights = cycle(['#B0D3F4', '#8E8E91', '#BCF4B1', '#FAC89D', '#B3B6F2', '#F79DB3', '#EFE598', '#B3B6F1', '#BB9098', '#BDF1ED', ]) return (colors, highlights)