diff --git a/etc/migracao/migra.py b/etc/migracao/migra.py index 6e4fed3..aa6a23c 100755 --- a/etc/migracao/migra.py +++ b/etc/migracao/migra.py @@ -1,6 +1,5 @@ - #!/usr/bin/env python -# coding: utf-8 +# -*- coding: utf-8 -*- """ Script para fazer a migração dos dados do SIGI antigo (Access), exportados para @@ -38,29 +37,31 @@ ERROR_MSG_0 = (' %s[%s]: erro desconhecido! Possível erro de integridade 'necessário.') ERROR_MSG_1 = (' %s[%s]: erro ao inserir item, será necessário inserção ' 'manual.') +OBS_CONVENIO = ('Convênio sem termo de adesão') def migra_assembleias(filename): # identificação das colunas nos arquivo CSV UF_COL = 5 NOME_COL = 8 - ENDERECO_COL = 39 - CEP_COL = 40 - EMAIL_COL = 41 - PAGINA_COL = 43 - OBS_COL = 37 FONE_1_COL = 32 FONE_2_COL = 33 FAX_COL = 34 FONE_PREFEITURA = 35 + OBS_COL = 37 PRESIDENTE_COL = 38 + ENDERECO_COL = 39 + CEP_COL = 40 + EMAIL_COL = 41 EMAIL_PRESIDENTE_COL = 42 - REPRESENTANTE_COL = 86 + PAGINA_COL = 43 + #REPRESENTANTE_COL = 86 reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True) header = reader.next() for line in reader: - municipio = Municipio.objects.get(uf__sigla=line[UF_COL], is_capital=True) + uf = UnidadeFederativa.objects.get(sigla=line[UF_COL]) + municipio = Municipio.objects.get(uf=uf, is_capital=True) casa = CasaLegislativa( municipio=municipio, nome=line[NOME_COL], @@ -93,9 +94,9 @@ def migra_assembleias(filename): ) fone_prefeitura.save() - if line[REPRESENTANTE_COL]: - representante = Contato(nome=line[REPRESENTANTE_COL], content_object=casa) - representante.save() +# if line[REPRESENTANTE_COL]: +# representante = Contato(nome=line[REPRESENTANTE_COL], content_object=casa) +# representante.save() if line[PRESIDENTE_COL]: mesa = MesaDiretora(casa_legislativa=casa) @@ -134,15 +135,19 @@ def migra_casas(filename): linenum = 1 for line in reader: linenum += 1 - try: municipio = Municipio.objects.get(codigo_ibge=line[COD_IBGE_COL]) except Municipio.DoesNotExist: + print "Municipio não existe" print ERROR_MSG_1 % (filename, linenum) continue except ValueError: print ERROR_MSG_1 % (filename, linenum) continue + parlamentar=None + if(line[PRESIDENTE_COL]): + parlamentar = Parlamentar(nome_completo=line[PRESIDENTE_COL], email=line[EMAIL_PRESIDENTE_COL]) + parlamentar.save() casa = CasaLegislativa( municipio=municipio, nome='Câmara Municipal de ' + line[NOME_COL], @@ -152,10 +157,13 @@ def migra_casas(filename): email=line[EMAIL_COL], pagina_web=line[PAGINA_COL], observacoes=line[OBS_COL], + parlamentar=parlamentar, ) + try: casa.save() except: + print "Erro ao inserir casa..." print ERROR_MSG_0 % (filename, linenum) continue @@ -217,35 +225,67 @@ def migra_cnpj(filename): except ValueError: print ERROR_MSG_1 % (filename, linenum) continue - casa.cnpj = line[COD_CNPJ1_COL] if not 'BRANCO' in line[COD_CNPJ1_COL] else line[COD_CNPJ2_COL] + casa.cnpj = line[COD_CNPJ1_COL] if not 'EM BRANCO' in line[COD_CNPJ1_COL] else line[COD_CNPJ2_COL] casa.save() def migra_convenios_casas(filename): + """ + Será preciso cadastrar no banco os seguintes Projeto: + 1 - Projeto Interlegis + 2 - Programa Piloto de Modernização + """ def get_datetime_obj(data): ldata = data.split('-') if len(ldata) != 3: return None return datetime(int(ldata[0]), int(ldata[1]), int(ldata[2])) + projeto1 = Projeto(nome="Projeto Interlegis") + projeto1.save() + projeto2 = Projeto(nome="Projeto Piloto de Modernização") + projeto2.save() + + # identificação das colunas no arquivo CSV + # No arquivo CSV colunas que contém _100 são do Programa Interlegis COD_IBGE_COL = 1 - NUM_PROCESSO_SF_COL = 25 + DATA_ADESAO_COL = 10 DATA_TERMO_ACEITE_COL = 21 + NUM_CONVENIO_COL = 23 + DATA_POSTAGEM_CORREIO = 26 + NUM_PROCESSO_SF_COL = 27 DATA_RETORNO_ASSINATURA = 28 DATA_PUB_DIARIO = 30 DATA_DEV_VIA_CONV_CM = 32 - DATA_POSTAGEM_CORREIO = 26 + + + DATA_ADESAO_100_COL = 11 + DATA_TERMO_ACEITE_100_COL = 22 + NUM_CONVENIO_100_COL = 24 + NUM_PROCESSO_SF_100_COL = 25 + DATA_RETORNO_ASSINATURA_100_COL = 29 + DATA_PUB_DIARIO_100_COL = 31 + #DATA_DEV_VIA_CONV_CM_100 = 32 Não foi registrado para as 100 + #DATA_POSTAGEM_CORREIO_100 = 26 reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True) header = reader.next() linenum = 1 + ###Geração de arquivos para análise### + import codecs + f1 = codecs.open('file1.txt','w' , encoding="utf-8") + f1.write(u'Casas que não tem Número Processo Senado Federal\n') + f2 = codecs.open('file2.txt','w', encoding="utf-8") + f2.write(u'Casas que não tem data de adesão e não tem convênio mas recebeu equipamentos\n') + ###### for line in reader: linenum += 1 try: casa = CasaLegislativa.objects.get(municipio__codigo_ibge=line[COD_IBGE_COL]) except CasaLegislativa.DoesNotExist: + print "Erro ao inserir convênio. Casa não existe" print ERROR_MSG_1 % (filename, linenum) continue except CasaLegislativa.MultipleObjectsReturned: @@ -255,21 +295,68 @@ def migra_convenios_casas(filename): print ERROR_MSG_1 % (filename, linenum) continue - convenio = Convenio( + # Se o convênio não tiver data de adesão mas tiver data retorno assinatura copiar essa data para a data de adesão. + obs = '' + projeto = None + convenio1=None + convenio2=None + if line[DATA_ADESAO_COL]=='1001-01-01' and line[DATA_RETORNO_ASSINATURA].__len__()!=0: + line[DATA_ADESAO_COL] = line[DATA_RETORNO_ASSINATURA] + obs = OBS_CONVENIO + + if line[DATA_ADESAO_COL]!='1001-01-01': + projeto = Projeto.objects.get(id=1) + + if projeto: + convenio1 = Convenio( + casa_legislativa=casa, + projeto=projeto, + num_processo_sf=line[NUM_PROCESSO_SF_COL], + num_convenio=line[NUM_CONVENIO_COL], + data_adesao=get_datetime_obj(line[DATA_ADESAO_COL]), + data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_COL]), + data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA]), + data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO]), + data_devolucao_via=get_datetime_obj(line[DATA_DEV_VIA_CONV_CM]), + data_postagem_correio=get_datetime_obj(line[DATA_POSTAGEM_CORREIO]), + observacao=obs,) + + ###Relatório### + if( (projeto or line[DATA_TERMO_ACEITE_COL]) and line[NUM_PROCESSO_SF_COL].__len__()==0): + f1.write(casa.nome+","+casa.municipio.uf.sigla+"\n") + if(projeto==None and line[DATA_TERMO_ACEITE_COL].__len__()!=0): + f2.write(casa.nome+","+casa.municipio.uf.sigla+"\n") + ###### + projeto=None + obs = '' + if line[DATA_ADESAO_100_COL]=='1001-01-01' and line[DATA_RETORNO_ASSINATURA_100_COL].__len__()!=0: + line[DATA_ADESAO_100_COL] = line[DATA_RETORNO_ASSINATURA_100_COL] + obs = OBS_CONVENIO + if line[DATA_ADESAO_100_COL]!='1001-01-01': + projeto = Projeto.objects.get(id=2) + + if projeto: + convenio2 = Convenio( casa_legislativa=casa, - num_processo_sf=line[NUM_PROCESSO_SF_COL], - data_adesao=get_datetime_obj(line[DATA_ADESAO_COL]), - data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_COL]), - data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA]), - data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO]), - data_devolucao_via=get_datetime_obj(line[DATA_DEV_VIA_CONV_CM]), - data_postagem_correio=get_datetime_obj(line[DATA_POSTAGEM_CORREIO]), - ) + projeto=projeto, + num_processo_sf=line[NUM_PROCESSO_SF_100_COL], + num_convenio=line[NUM_CONVENIO_100_COL], + data_adesao=get_datetime_obj(line[DATA_ADESAO_100_COL]), + data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_100_COL]), + data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA_100_COL]), + data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO_100_COL]), + observacao=obs, + ) + try: - convenio.save() + if convenio1: convenio1.save() + if convenio2: convenio2.save() except: + print "Erro ao inserir convênio" print ERROR_MSG_0 % (filename, linenum) continue + f1.close() + f2.close() def migra_convenios_assembleias(filename): def get_datetime_obj(data): @@ -279,15 +366,14 @@ def migra_convenios_assembleias(filename): return datetime(int(ldata[0]), int(ldata[1]), int(ldata[2])) # identificação das colunas no arquivo CSV - COD_IBGE_COL = 1 - NUM_PROCESSO_SF_COL = 25 + SIGLA_COL = 5 DATA_ADESAO_COL = 10 DATA_TERMO_ACEITE_COL = 21 - DATA_RETORNO_ASSINATURA = 28 - DATA_PUB_DIARIO = 30 - DATA_DEV_VIA_CONV_CM = 32 - DATA_POSTAGEM_CORREIO = 26 - + NUM_CONVENIO_COL = 23 + NUM_PROCESSO_SF_COL = 26 + DATA_RETORNO_ASSINATURA = 27 + DATA_PUB_DIARIO = 29 + reader = csv.reader(open(filename, 'r'), delimiter='|', skipinitialspace=True) header = reader.next() linenum = 1 @@ -295,7 +381,7 @@ def migra_convenios_assembleias(filename): linenum += 1 try: - assembleia = CasaLegislativa.objects.get(municipio__codigo_ibge=line[COD_IBGE_COL]) + assembleia = CasaLegislativa.objects.get(municipio__uf__sigla=line[SIGLA_COL], tipo='AL') except CasaLegislativa.DoesNotExist: print ERROR_MSG_1 % (filename, linenum) continue @@ -304,16 +390,16 @@ def migra_convenios_assembleias(filename): except ValueError: print ERROR_MSG_1 % (filename, linenum) continue - + projeto = Projeto.objects.get(id=2) convenio = Convenio( casa_legislativa=assembleia, num_processo_sf=line[NUM_PROCESSO_SF_COL], + num_convenio=line[NUM_CONVENIO_COL], + projeto=projeto, data_adesao=get_datetime_obj(line[DATA_ADESAO_COL]), data_retorno_assinatura=get_datetime_obj(line[DATA_TERMO_ACEITE_COL]), data_pub_diario=get_datetime_obj(line[DATA_RETORNO_ASSINATURA]), data_termo_aceite=get_datetime_obj(line[DATA_PUB_DIARIO]), - data_devolucao_via=get_datetime_obj(line[DATA_DEV_VIA_CONV_CM]), - data_postagem_correio=get_datetime_obj(line[DATA_POSTAGEM_CORREIO]), ) try: convenio.save() @@ -323,13 +409,13 @@ def migra_convenios_assembleias(filename): if __name__ == '__main__': - print "" - migra_assembleias('assembleias.csv') - print "" - migra_casas('casas.csv') - print "" - migra_cnpj('cnpj.csv') +# print "" +# migra_assembleias('assembleias.csv') +# print "" +# migra_casas('casas.csv') +# print "" +# migra_cnpj('cnpj.csv') print "" migra_convenios_casas('casas.csv') print "" - migra_convenios_casas('assembleias.csv') + migra_convenios_assembleias('assembleias.csv') diff --git a/media/css/base_site.css b/media/css/base_site.css index 9d55a24..800207a 100644 --- a/media/css/base_site.css +++ b/media/css/base_site.css @@ -4,7 +4,7 @@ a:hover { color:#11488d; } /* HEADER */ -#header { background:#003351; } +#header { background:#003351 url(../images/default-bg2.jpg);} #site-name a:hover { text-decoration: none; } #nav-global { @@ -16,7 +16,8 @@ a:hover { color:#11488d; } font-weight:bold; } #nav-global ul { - background:#222; + /*background:#222;*/ + background:#efefef url("../../admin_media/img/admin/nav-bg.gif");/*#9C9C9C;*/ height:25px; margin:0; padding:0; @@ -27,7 +28,7 @@ a:hover { color:#11488d; } padding:0px; } #nav-global li a { - background:#222 url("../images/menu/seperator.gif") bottom right no-repeat; + /*background: url("../images/menu/seperator.gif") bottom right no-repeat;*/ color:#cccccc; display:block; font-weight:normal; @@ -36,7 +37,10 @@ a:hover { color:#11488d; } padding:0px 15px; text-align:center; text-decoration:none; + /*font-size: medium;*/ } +#nav-global li a:link,#nav-global li a:visited{ color: black;} + #nav-global li a:hover, #nav-global ul li:hover a { background-color:#333; color:#FFFFFF; @@ -52,7 +56,7 @@ a:hover { color:#11488d; } position:absolute; width:200px; z-index:200; - /*top:1em; + /*top:1em;*/ /*left:0;*/ } #nav-global li:hover ul { display:block; } diff --git a/media/images/default-bg2.jpg b/media/images/default-bg2.jpg new file mode 100644 index 0000000..075aec3 Binary files /dev/null and b/media/images/default-bg2.jpg differ diff --git a/media/images/logo-interlegis.jpg b/media/images/logo-interlegis.jpg new file mode 100644 index 0000000..619502e Binary files /dev/null and b/media/images/logo-interlegis.jpg differ diff --git a/media/images/logo-senado.png b/media/images/logo-senado.png new file mode 100644 index 0000000..bee0ada Binary files /dev/null and b/media/images/logo-senado.png differ diff --git a/sigi/admin/filterspecs.py b/sigi/admin/filterspecs.py index d926dab..57608ae 100644 --- a/sigi/admin/filterspecs.py +++ b/sigi/admin/filterspecs.py @@ -3,6 +3,7 @@ from django.utils.encoding import smart_unicode from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ from sigi.apps.contatos.models import UnidadeFederativa +from abc import ABCMeta class AlphabeticFilterSpec(ChoicesFilterSpec): """ @@ -39,13 +40,34 @@ class AlphabeticFilterSpec(ChoicesFilterSpec): FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'alphabetic_filter', False), AlphabeticFilterSpec)) -class MunicipioUFFilterSpec(ChoicesFilterSpec): +class UFFilterSpec(ChoicesFilterSpec): + """ + This is an abstract class and customs filters by 'Uf' have to extend this class. + """ + __metaclass__ = ABCMeta + def __init__(self, f, request, params, model, model_admin): + super(UFFilterSpec, self).__init__(f, request, params, model, + model_admin) + + def choices(self, cl): + yield {'selected': self.lookup_val is None, + 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), + 'display': _('All')} + for val in self.lookup_choices: + yield {'selected': smart_unicode(val.codigo_ibge) == self.lookup_val, + 'query_string': cl.get_query_string({self.lookup_kwarg: val.codigo_ibge}), + 'display': val.nome} + def title(self): + return _('UF') % \ + {'field_name': self.field.verbose_name} + +class MunicipioUFFilterSpec(UFFilterSpec): """ Usage: my_municipio_field.uf_filter = True - On Django 1.2 you will can specify a lookup on admin filters. Example: + On Django 1.3 you will can specify a lookup on admin filters. Example: list_filter = ('municipio__uf',) @@ -58,21 +80,30 @@ class MunicipioUFFilterSpec(ChoicesFilterSpec): self.lookup_val = request.GET.get(self.lookup_kwarg, None) self.lookup_choices = UnidadeFederativa.objects.all().order_by('nome') - def choices(self, cl): - yield {'selected': self.lookup_val is None, - 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), - 'display': _('All')} - for val in self.lookup_choices: - yield {'selected': smart_unicode(val.codigo_ibge) == self.lookup_val, - 'query_string': cl.get_query_string({self.lookup_kwarg: val.codigo_ibge}), - 'display': val.nome} - def title(self): - return _('UF') % \ - {'field_name': self.field.verbose_name} # registering the filter FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'uf_filter', False), - MunicipioUFFilterSpec)) + MunicipioUFFilterSpec)) + +class ConvenioUFFilterSpec(UFFilterSpec): + """ + Usage: + + my_casa_legislativa_field.convenio_uf_filter = True + + On Django 1.3 you will can specify a lookup on admin filters. Example: + + list_filter = ('casa_legislativa__municipio__uf',) + + """ + def __init__(self, f, request, params, model, model_admin): + super(ConvenioUFFilterSpec, self).__init__(f, request, params, model, model_admin) + self.lookup_kwarg = '%s__municipio__uf__codigo_ibge__exact' % f.name + self.lookup_val = request.GET.get(self.lookup_kwarg, None) + self.lookup_choices = UnidadeFederativa.objects.all().order_by('nome') + +FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'convenio_uf_filter', False), +ConvenioUFFilterSpec)) class RangeValuesFilterSpec(FilterSpec): """ diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 6d73979..f46e7b7 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -4,6 +4,10 @@ from django.contrib.contenttypes import generic from sigi.apps.casas.forms import CasaLegislativaForm from sigi.apps.casas.models import CasaLegislativa from sigi.apps.contatos.models import Contato, Telefone +from sigi.apps.convenios.models import Projeto, Convenio, EquipamentoPrevisto, Anexo +from django.http import HttpResponse, HttpResponseRedirect +from sigi.apps.casas.reports import CasasLegislativasLabels +from geraldo.generators import PDFGenerator class ContatosInline(generic.GenericTabularInline): model = Contato @@ -14,17 +18,23 @@ class TelefonesInline(generic.GenericTabularInline): model = Telefone extra = 2 +class ConveniosInline(admin.TabularInline): + model = Convenio + extra = 1 + class CasaLegislativaAdmin(admin.ModelAdmin): form = CasaLegislativaForm change_form_template = 'casas/change_form.html' change_list_template = 'casas/change_list.html' - inlines = (TelefonesInline, ContatosInline) + actions = ['delete_selected','etiqueta'] + inlines = (TelefonesInline, ContatosInline, ConveniosInline) list_display = ('nome', 'email', 'pagina_web', 'municipio') list_display_links = ('nome',) list_filter = ('tipo', 'municipio') fieldsets = ( (None, { - 'fields': ('nome', 'sigla', 'tipo', 'cnpj', 'observacoes'), + 'fields': ('nome', 'sigla', 'tipo', 'cnpj', 'observacoes', + 'parlamentar'), }), ('Endereço', { 'fields': ('logradouro', 'bairro', 'municipio', 'cep'), @@ -34,7 +44,7 @@ class CasaLegislativaAdmin(admin.ModelAdmin): 'fields': ('email', 'pagina_web', 'foto', 'historico'), }), ) - raw_id_fields = ('municipio',) + raw_id_fields = ('municipio','parlamentar') search_fields = ('nome', 'sigla', 'cnpj', 'logradouro', 'bairro', 'cep', 'municipio__nome', 'municipio__uf__nome', 'municipio__codigo_ibge', 'pagina_web', 'observacoes') @@ -45,4 +55,11 @@ class CasaLegislativaAdmin(admin.ModelAdmin): extra_context={'query_str': '?' + request.META['QUERY_STRING']} ) + def etiqueta(modelAdmin,request,queryset): + response = HttpResponse(mimetype='application/pdf') + report = CasasLegislativasLabels(queryset=queryset) + report.generate_by(PDFGenerator, filename=response) + return response + etiqueta.short_description = "Gerar etiqueta(s) da(s) casa(s) selecionada(s)" + admin.site.register(CasaLegislativa, CasaLegislativaAdmin) diff --git a/sigi/apps/casas/models.py b/sigi/apps/casas/models.py index bd84bd7..84f70b9 100644 --- a/sigi/apps/casas/models.py +++ b/sigi/apps/casas/models.py @@ -2,6 +2,7 @@ from django.db import models from django.contrib.contenttypes import generic from sigi.apps.mesas.models import MesaDiretora, MembroMesaDiretora +from sigi.apps.parlamentares.models import Parlamentar class CasaLegislativa(models.Model): CASA_CHOICES = ( @@ -24,6 +25,7 @@ class CasaLegislativa(models.Model): tipo = models.CharField(max_length=2, choices=CASA_CHOICES, default='CM') cnpj = models.CharField('CNPJ', max_length=32, blank=True) observacoes = models.TextField(u'observações', blank=True) + parlamentar = models.ForeignKey(Parlamentar, null=True, blank=True, verbose_name="Presidente") logradouro = models.CharField( max_length=100, diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index a4fe994..1ded868 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -1,7 +1,11 @@ # -*- coding: utf-8 -*- from django.contrib import admin -from sigi.apps.convenios.models import Convenio, EquipamentoPrevisto, Anexo +from sigi.apps.convenios.models import Projeto, Convenio, EquipamentoPrevisto, Anexo +from sigi.apps.casas.models import CasaLegislativa from sigi.apps.servicos.models import Servico +from django.http import HttpResponse, HttpResponseRedirect +from sigi.apps.convenios.reports import ConvenioReport +from geraldo.generators import PDFGenerator class AnexosInline(admin.TabularInline): model = Anexo @@ -25,7 +29,7 @@ class ConvenioAdmin(admin.ModelAdmin): change_list_template = 'convenios/change_list.html' fieldsets = ( (None, - {'fields': ('casa_legislativa', 'num_processo_sf')} + {'fields': ('casa_legislativa', 'num_processo_sf','num_convenio','projeto','observacao')} ), ('Datas', {'fields': ('data_adesao', 'data_retorno_assinatura', @@ -33,17 +37,34 @@ class ConvenioAdmin(admin.ModelAdmin): 'data_devolucao_via', 'data_postagem_correio')} ), ) + actions = ['delete_selected', 'relatorio'] inlines = (AnexosInline, EquipamentoPrevistoInline) list_display = ('id', 'casa_legislativa', - 'num_processo_sf', 'data_adesao') - list_filter = ('data_adesao', 'data_retorno_assinatura', - 'data_termo_aceite', 'data_devolucao_via', - 'data_postagem_correio') + 'num_processo_sf', 'data_adesao', 'projeto', + ) + list_filter = ('projeto','casa_legislativa','conveniada', 'equipada') + date_hierarchy = 'data_adesao' ordering = ('-id',) raw_id_fields = ('casa_legislativa',) search_fields = ('id', 'casa_legislativa__nome', - 'num_processo_sf', 'casa_legislativa__municipio__nome', - 'casa_legislativa__municipio__uf__nome') + 'num_processo_sf') + + def changelist_view(self, request, extra_context=None): + return super(ConvenioAdmin, self).changelist_view( + request, + extra_context={'query_str': '?' + request.META['QUERY_STRING']} + ) + def relatorio(modeladmin, request, queryset): + response = HttpResponse(mimetype='application/pdf') + report = ConvenioReport(queryset=queryset) + report.generate_by(PDFGenerator, filename=response) + return response + #selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME) + #print selected + #return HttpResponseRedirect("reports/?ids=%s"%(",".join(selected))) + #relatorio.short_description = 'Selecione para gerar relatorio' + relatorio.short_description = 'Gerar relatorio dos convenios selecionados' + class EquipamentoPrevistoAdmin(admin.ModelAdmin): list_display = ('convenio', 'equipamento', 'quantidade') @@ -53,6 +74,7 @@ class EquipamentoPrevistoAdmin(admin.ModelAdmin): search_fields = ('convenio__id', 'equipamento__fabricante__nome', 'equipamento__modelo__modelo', 'equipamento__modelo__tipo__tipo') +#admin.site.register(Projeto) admin.site.register(Convenio, ConvenioAdmin) +#admin.site.register(CasaLegislativa) admin.site.register(EquipamentoPrevisto, EquipamentoPrevistoAdmin) -admin.site.register(Anexo, AnexoAdmin) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index dc928c6..3488973 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -1,24 +1,40 @@ # -*- coding: utf-8 -*- from datetime import datetime from django.db import models +#from django.contrib.contenttypes import ContentType from django.contrib.contenttypes import generic -class Convenio(models.Model): +class Projeto(models.Model): + nome = models.CharField(max_length=50) + + def __unicode__(self): + return self.nome + +class Convenio(models.Model): casa_legislativa = models.ForeignKey( 'casas.CasaLegislativa', verbose_name='Casa Legislativa' ) + casa_legislativa.uf_filter = True num_processo_sf = models.CharField( 'número do processo SF', max_length=11, blank=True, help_text='Formato: XXXXXX/XX-X.' ) + num_convenio = models.CharField( + 'número do convênio', + max_length=10, + blank=True + ) data_adesao = models.DateField( 'data de adesão', null=True, blank=True, ) + projeto = models.ForeignKey( + Projeto + ) data_retorno_assinatura = models.DateField( 'data do retorno e assinatura', null=True, @@ -40,24 +56,37 @@ class Convenio(models.Model): 'data de devolução da via', null=True, blank=True, - help_text='Data de devolução da via do convênio à Câmara Municipal.' + help_text=u'Data de devolução da via do convênio à Câmara Municipal.' ) data_postagem_correio = models.DateField( 'data postagem correio', null=True, blank=True, ) + observacao = models.CharField( + null=True, + blank=True, + max_length=100, + ) + conveniada = models.BooleanField() + equipada = models.BooleanField() + + def save(self, *args, **kwargs): + self.conveniada = self.data_retorno_assinatura!=None + self.equipada = self.data_termo_aceite!=None + super(Convenio, self).save(*args, **kwargs) + class Meta: get_latest_by = 'id' ordering = ('id',) - verbose_name = 'convênio' + verbose_name = u'convênio' def __unicode__(self): return str(self.id) class EquipamentoPrevisto(models.Model): - convenio = models.ForeignKey(Convenio, verbose_name='convênio') + convenio = models.ForeignKey(Convenio, verbose_name=u'convênio') equipamento = models.ForeignKey('inventario.Equipamento') quantidade = models.PositiveSmallIntegerField(default=1) @@ -69,7 +98,7 @@ class EquipamentoPrevisto(models.Model): return '%s %s(s)' % (self.quantidade, self.equipamento) class Anexo(models.Model): - convenio = models.ForeignKey(Convenio, verbose_name='convênio') + convenio = models.ForeignKey(Convenio, verbose_name=u'convênio') arquivo = models.FileField(upload_to='apps/convenios/anexo/arquivo',) descricao = models.CharField('descrição', max_length='70') data_pub = models.DateTimeField( diff --git a/sigi/apps/convenios/reports.py b/sigi/apps/convenios/reports.py index 86eca5d..6b3f4ea 100644 --- a/sigi/apps/convenios/reports.py +++ b/sigi/apps/convenios/reports.py @@ -1,3 +1,14 @@ +# -*- coding: utf-8 -*- +from operator import attrgetter +from geraldo import Report, ReportBand, ObjectValue, DetailBand, Label, \ + landscape,SystemField, BAND_WIDTH,ReportGroup, \ + FIELD_ACTION_SUM, FIELD_ACTION_COUNT + + +from reportlab.lib.units import cm +from reportlab.lib.pagesizes import A4 +from reportlab.lib.enums import TA_CENTER, TA_RIGHT + class CasasAderidasReport(object): pass @@ -9,3 +20,114 @@ class CasasComEquipamentosReport(object): class SemEquipamentosReport(object): pass +class ConvenioReport(Report): + title = u'Relatórios dos Convênios' + #author = u'Interlegis' + print_if_empty = True + page_size = A4#landscape(A4) + + class band_page_header(ReportBand): + height = 1.3*cm + + elements = [ + SystemField( + expression='%(report_title)s',top=0.1*cm,left=0,width=BAND_WIDTH, + style={'fontName': 'Helvetica-Bold','fontSize':14, 'alignment': TA_CENTER} + ), + SystemField(expression=u'Página %(page_number)d de %(page_count)d', top=0.1*cm, + width=BAND_WIDTH, style={'alignment': TA_RIGHT} + ), + Label( + text="Nº Processo", left=0.5*cm, top=0.8*cm + ), + Label( + text="Nome", left=3*cm, top=0.8*cm + ), + Label( + text="Data Adesão", left=7*cm, top=0.8*cm + ), + Label( + text="Projeto", left=10*cm, top=0.8*cm + ), + ] + borders = {'bottom': True} + + class band_page_footer(ReportBand): + height = 0.5*cm + + elements = [ + Label(text='Interlegis', top=0.1*cm), + SystemField(expression=u'Impresso em %(now:%d/%m/%Y)s às %(now:%H:%M)s', top=0.1*cm, + width=BAND_WIDTH, style={'alignment': TA_RIGHT}), + ] + borders = {'top': True} + + class band_detail(DetailBand): + height = 0.5*cm + elements=[ + ObjectValue(attribute_name='num_processo_sf', left=0.5*cm), + ObjectValue(attribute_name='casa_legislativa', left=3*cm), + ObjectValue(attribute_name='data_adesao', left=7*cm), + ObjectValue(attribute_name='projeto', left=10*cm) + ] + #border = {'bottom': True} + + groups = [ + ReportGroup(attribute_name='casa_legislativa.municipio.uf', + band_header=ReportBand( + height=0.7*cm, + elements= [ + ObjectValue(attribute_name='casa_legislativa.municipio.uf', + get_Value= lambda instance: 'CasaLegislativa: '+ (instance.casa_legislativa.uf.regiao) + ) + ], + borders={'bottom': True}, + ) + ) + ] + + +class ConvenioReportRegiao(Report): + title = u'Relatório dos Convênios por Região' + author = u'Interlegis' + class band_page_header(ReportBand): + elements = [ + Label( + text="Região", left=0*cm + ), + Label( + text="Quantidade Casas", left=3*cm, + ), + Label( + text="Quantidade Casas Conveniadas", left=6*cm + ), + Label( + text="Porcentagem Casas Conveniadas", left=15*cm + ), + ] + class band_detail(DetailBand): + height = 0.5*cm + elements=[ + ObjectValue(attribute_name='regiao', left=0*cm, ), + ObjectValue(attribute_name='casas', left=3*cm,), + ObjectValue(attribute_name='casas_conveniadas', left=6*cm), + ObjectValue(attribute_name='porc_casas_conveniadas', left=15*cm), + ] + border = {'bottom': True} + + class band_summary(ReportBand): + elements = [ + Label(text="Total", top=0.1*cm, left=0), + ObjectValue(attribute_name='casas', action=FIELD_ACTION_SUM, left=3*cm, top=0.1*cm), + ObjectValue(attribute_name='casas_conveniadas', left=6*cm, action=FIELD_ACTION_SUM), + ] + borders = {'top':True} + child_bands = [ + ReportBand( + height = 0.6*cm, + elements = [ + Label(text="Total",), + ObjectValue(attribute_name='casas', action=FIELD_ACTION_COUNT,) + ] + ), + ] diff --git a/sigi/apps/convenios/views.py b/sigi/apps/convenios/views.py new file mode 100644 index 0000000..5bb0bbc --- /dev/null +++ b/sigi/apps/convenios/views.py @@ -0,0 +1,61 @@ +from django.http import HttpResponse, HttpResponseRedirect +from geraldo.generators import PDFGenerator +from sigi.apps.convenios.models import Convenio +from sigi.apps.convenios.reports import ConvenioReport, ConvenioReportRegiao +from sigi.apps.casas.models import CasaLegislativa + + +def report(request, id=None): + qs = Convenio.objects.all() + if id: + qs = qs.filter(pk=id) + elif request.GET: #Se tiver algum parametro de pesquisa + kwargs = {} + ids = 0 + for k, v in request.GET.iteritems(): + kwargs[str(k)] = v + if(str(k)=='ids'): + ids = 1 + break + qs = qs.filter(**kwargs) + if ids: + query = 'id IN ('+ kwargs['ids'].__str__()+')' + qs = Convenio.objects.extra(where=[query]) + if not qs: + return HttpResponseRedirect('../') + response = HttpResponse(mimetype='application/pdf') + report = ConvenioReport(queryset=qs.order_by('casa_legislativa')) + report.generate_by(PDFGenerator, filename=response) + return response + +class Relatorios(object): + def __init__(self, regiao, casas, casas_conveniadas): + self.regiao = regiao + self.casas = casas + self.casas_conveniadas = casas_conveniadas + if(casas_conveniadas!=0): + self.porc_casas_conveniadas = float(casas_conveniadas)/float(casas)*100 + else: + self.porc_casas_conveniadas = 0 + +def reportRegiao(request): + REGIAO_CHOICES = ( + ('SL', 'Sul'), + ('SD', 'Sudeste'), + ('CO', 'Centro-Oeste'), + ('NE', 'Nordeste'), + ('NO', 'Norte'), + ) + relatorio = [] + for casa in REGIAO_CHOICES: + casasSD = CasaLegislativa.objects.filter(municipio__uf__regiao=casa[0]) + casasConvSD = CasaLegislativa.objects.filter(convenio__casa_legislativa__municipio__uf__regiao=casa[0]).distinct() + + relatorio.append(Relatorios(casa[1], casasSD.count(), + casasConvSD.count())) + + response = HttpResponse(mimetype='application/pdf') + relatorio = ConvenioReportRegiao(queryset=relatorio) + relatorio.generate_by(PDFGenerator, filename=response) + return response + diff --git a/sigi/apps/parlamentares/admin.py b/sigi/apps/parlamentares/admin.py index b57b61d..a485074 100644 --- a/sigi/apps/parlamentares/admin.py +++ b/sigi/apps/parlamentares/admin.py @@ -27,27 +27,27 @@ class ParlamentarAdmin(admin.ModelAdmin): (None, { 'fields': ('nome_completo', 'nome_parlamentar', 'sexo'), }), - ('Endereço', { - 'fields': ('logradouro', 'bairro', 'municipio', 'cep'), - }), +# ('Endereço', { +# 'fields': ('logradouro', 'bairro', 'municipio', 'cep'), +# }), ('Outras informações', { 'fields': ('data_nascimento', 'email', 'pagina_web', 'foto'), }), ) radio_fields = {'sexo': admin.VERTICAL} - raw_id_fields = ('municipio',) +# raw_id_fields = ('municipio',) search_fields = ('nome_completo', 'nome_parlamentar', 'email', - 'pagina_web', 'municipio__nome') + 'pagina_web',) class MandatoAdmin(admin.ModelAdmin): list_display = ('parlamentar', 'legislatura', 'partido', 'inicio_mandato', 'fim_mandato', 'is_afastado') - list_filter = ('is_afastado', 'partido', 'suplencia') + list_filter = ('is_afastado', 'partido') search_fields = ('legislatura__numero', 'parlamentar__nome_completo', 'parlamentar__nome_parlamentar', 'partido__nome', 'partido__sigla') raw_id_fields = ('parlamentar', 'legislatura', 'partido') - radio_fields = {'suplencia': admin.VERTICAL} +# radio_fields = {'suplencia': admin.VERTICAL} admin.site.register(Partido, PartidoAdmin) admin.site.register(Parlamentar, ParlamentarAdmin) diff --git a/sigi/apps/parlamentares/models.py b/sigi/apps/parlamentares/models.py index 53eae15..a65de4a 100644 --- a/sigi/apps/parlamentares/models.py +++ b/sigi/apps/parlamentares/models.py @@ -37,21 +37,11 @@ class Parlamentar(models.Model): blank=True, null=True, ) - logradouro = models.CharField(max_length=100, blank=True) - bairro = models.CharField(max_length=40, blank=True) - municipio = models.ForeignKey('contatos.Municipio', blank=True, null=True) - cep = models.CharField( - 'CEP', - max_length=9, - blank=True, - help_text="Formato: XXXXX-XXX." - ) - telefones = generic.GenericRelation('contatos.Telefone') + email = models.EmailField('e-mail', blank=True) pagina_web = models.URLField( u'página web', blank=True, verify_exists=False ) - email = models.EmailField('e-mail', blank=True) class Meta: ordering = ('nome_completo',) @@ -62,6 +52,20 @@ class Parlamentar(models.Model): return self.nome_parlamentar return self.nome_completo + +# logradouro = models.CharField(max_length=100, blank=True) +# bairro = models.CharField(max_length=40, blank=True) +# municipio = models.ForeignKey('contatos.Municipio', blank=True, null=True) +# cep = models.CharField( +# 'CEP', +# max_length=9, +# blank=True, +# help_text="Formato: XXXXX-XXX." +# ) +# telefones = generic.GenericRelation('contatos.Telefone') + + + class Mandato(models.Model): SUPLENCIA_CHOICES = ( ('T', 'Titular'), @@ -77,11 +81,13 @@ class Mandato(models.Model): default=False, help_text=u'Marque caso parlamentar não esteja ativo.' ) - suplencia = models.CharField( - u'suplência', - max_length=1, - choices=SUPLENCIA_CHOICES, - ) + +# suplencia = models.CharField( +# u'suplência', +# max_length=1, +# choices=SUPLENCIA_CHOICES, +# ) + def __unicode__(self): return str(self.id) diff --git a/sigi/context_processors.py b/sigi/context_processors.py index 9e06722..fa454f7 100644 --- a/sigi/context_processors.py +++ b/sigi/context_processors.py @@ -1,15 +1,24 @@ from sigi.apps.casas.models import CasaLegislativa -from sigi.apps.convenios.models import Convenio +from sigi.apps.convenios.models import Convenio, Projeto +from sigi.apps.contatos.models import UnidadeFederativa def charts_data(request): casas = CasaLegislativa.objects.all() convenios = Convenio.objects.all() + projetos = Projeto.objects.all() + convenios_firmados = convenios.exclude(data_retorno_assinatura=None) num_convenios_firmados = convenios_firmados.count() num_convenios_nao_firmados = convenios.filter(data_retorno_assinatura=None).count() - num_casas_nao_aderidas = casas.count() - convenios.exclude(data_adesao=None).count() + #num_casas_nao_aderidas = CasaLegislativa.objects.filter(convenio=None).count() + #num_casas_nao_aderidas = casas.count() - convenios.exclude(data_adesao=None).count() + # Verifica quantidade de convenios por projeto + convenios_por_projeto = [] + for p in projetos: + convenios_por_projeto.append(convenios_firmados.filter(projeto=p).count()) + num_casas_regiao = [ casas.filter(municipio__uf__regiao='CO').count(), casas.filter(municipio__uf__regiao='NO').count(), @@ -17,20 +26,47 @@ def charts_data(request): casas.filter(municipio__uf__regiao='SD').count(), casas.filter(municipio__uf__regiao='SL').count() ] - num_convenios_firmados_regiao = [ - convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='CO').count(), - convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='NO').count(), - convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='NE').count(), - convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='SD').count(), - convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='SL').count() - ] + #num_convenios_firmados_regiao = [ + # convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='CO').count(), + # convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='NO').count(), + # convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='NE').count(), + # convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='SD').count(), + # convenios_firmados.filter(casa_legislativa__municipio__uf__regiao='SL').count() + #] + + REGIAO_CHOICES = ('CO','NO','NE','SD','SL') + + # Busca numero de casas conveniadas por regiao + num_casas_conveniadas_regiao = [] + for regiao in REGIAO_CHOICES: + num_casas_conveniadas_regiao.append( + CasaLegislativa.objects.filter( + convenio__casa_legislativa__municipio__uf__regiao=regiao + ).exclude( + convenio__data_retorno_assinatura=None + ).distinct().count() + ) + + # Busca numero de casas sem convenio por regiao + num_casas_sem_convenio_regiao = [] + for i in range(len(num_casas_regiao)): + num_casas_sem_convenio_regiao.append( + num_casas_regiao[i] - num_casas_conveniadas_regiao[i] + ) + + # Verifica qual regiao tem mais convenios e guarda valor para "axis left" do grafico de regioes + num_regiao_maior = 0 + for i in num_casas_regiao: + if num_regiao_maior - +

Copyright © 2008–2010 Interlegis. Todos os Direitos Reservados.
É proibido o uso das informações aqui fornecidas fora do âmbito do Interlegis. diff --git a/sigi/templates/snippets/modules/charts-convenios.html b/sigi/templates/snippets/modules/charts-convenios.html index 78042b2..e5f8ca2 100644 --- a/sigi/templates/snippets/modules/charts-convenios.html +++ b/sigi/templates/snippets/modules/charts-convenios.html @@ -1,29 +1,46 @@ {% load charts %} {% chart as convenios %} - {% chart-size 340 160 %} - {% chart-type "pie" %} - {% chart-labels "Conveniadas" "Não conveniadas" "Não aderidas" %} + {% chart-size 440 160 %} + {% chart-type "pie-3d" %} + {% chart-labels convenios_chart_data %} + {% chart-legend "Convênios firmados" "Convênios pendentes" %} {% chart-data convenios_chart_data %} + {% chart-colors "A2CD5A,FFB90F,6CA6CD" %} {% endchart %} {% chart as regioes %} - {% chart-size 320 160 %} + {% chart-size 440 160 %} {% chart-type "column-stacked" %} {% chart-bar-width "40" %} {% chart-labels "Centro-O" "Norte" "Nordeste" "Sudeste" "Sul" %} {% chart-data regioes_chart_data.0 regioes_chart_data.1 %} - {% chart-legend "Conveniadas" "Total" %} - {% chart-colors "ff9900,ffc266" %} + {% chart-legend "Conveniadas" "Total" %} + {% axis "left" %} + {% axis-range 0 regioes_chart_data.2 %} + {% endaxis %} + {% chart-colors "A2CD5A,FFB90F,6CA6CD" %} {% endchart %} {% chart as equipamentos %} - {% chart-size 340 160 %} - {% chart-type "pie" %} - {% chart-labels "Recebidos" "Não recebidos" %} + {% chart-size 440 160 %} + {% chart-type "pie-3d" %} + {% chart-labels equipamentos_chart_data %} {% chart-data equipamentos_chart_data %} + {% chart-legend "Recebidos" "Não recebidos" %} + {% chart-colors "A2CD5A,FFB90F,6CA6CD" %} {% endchart %} +{% chart as projetos %} + {% chart-size 440 160 %} + {% chart-type "pie-3d" %} + {% chart-labels convenios_por_projeto_chart_data %} + {% chart-data convenios_por_projeto_chart_data %} + {% chart-legend projetos_chart_data %} + {% chart-colors "A2CD5A,FFB90F,6CA6CD" %} +{% endchart %} + +

Convênios

Convênios com as Casas Legislativas

@@ -47,3 +64,12 @@

+ +
+

Convênios

+

Convênios por projeto

+

+ +

+
+ diff --git a/sigi/urls.py b/sigi/urls.py index 6eb1965..a4a82d0 100644 --- a/sigi/urls.py +++ b/sigi/urls.py @@ -8,11 +8,14 @@ import sigi.admin.filterspecs urlpatterns = patterns( '', - # reports + # reports labels (r'^casas/casalegislativa/labels/', 'sigi.apps.casas.views.labels_report'), (r'^casas/casalegislativa/(?P\w+)/labels/', 'sigi.apps.casas.views.labels_report'), + # reports + (r'^convenios/convenio/reports/', + 'sigi.apps.convenios.views.report'), # automatic interface based on admin (r'^(.*)', sites.default.root),