Browse Source

Remodelagem para Gerentes Interlegis e outras

pull/11/head
Sesostris Vieira 4 years ago
parent
commit
9db266f0ad
  1. 5592
      scripts/setgerentes/dados_gerentes.py
  2. 16
      scripts/setgerentes/set_gerentes.py
  3. 121
      sigi/apps/casas/admin.py
  4. 20
      sigi/apps/casas/forms.py
  5. 34
      sigi/apps/casas/management/commands/importa_gerentes.py
  6. 20
      sigi/apps/casas/migrations/0004_auto_20201015_0810.py
  7. 21
      sigi/apps/casas/migrations/0005_casalegislativa_gerentes_interlegis.py
  8. 18
      sigi/apps/casas/migrations/0006_remove_casalegislativa_gerente_contas.py
  9. 128
      sigi/apps/casas/migrations/0007_auto_20201016_1632.py
  10. 201
      sigi/apps/casas/models.py
  11. 46
      sigi/apps/casas/templates/casas/portfolio.html
  12. 2
      sigi/apps/casas/test_casas.py
  13. 105
      sigi/apps/casas/views.py
  14. 2
      sigi/apps/convenios/admin.py
  15. 20
      sigi/apps/convenios/migrations/0002_convenio_duracao.py
  16. 69
      sigi/apps/convenios/models.py
  17. 2
      sigi/apps/home/templates/home/sem_convenio.html
  18. 49
      sigi/apps/home/views.py
  19. 103
      sigi/apps/metas/views.py
  20. 17
      sigi/apps/ocorrencias/admin.py
  21. 4
      sigi/apps/ocorrencias/filters.py
  22. 10
      sigi/apps/ocorrencias/templates/ocorrencias/ocorrencia_snippet.html
  23. 73
      sigi/apps/ocorrencias/views.py

5592
scripts/setgerentes/dados_gerentes.py

File diff suppressed because it is too large

16
scripts/setgerentes/set_gerentes.py

@ -1,16 +0,0 @@
# -*- coding: utf-8 -*-
from dados_gerentes import atrib, gerentes
from sigi.apps.casas.models import CasaLegislativa
def salvar():
for cod, abrev_gerente in atrib:
casas = CasaLegislativa.objects.filter(municipio__codigo_ibge=cod, tipo__sigla='CM')
if not casas:
print '############################# SEM CASA: ', cod
elif len(casas) > 1:
print '############################# VÁRIAS CASAS: ', cod, casas
else:
[c] = casas
c.gerente_contas = gerentes[abrev_gerente]
c.save()

121
sigi/apps/casas/admin.py

@ -56,6 +56,7 @@ class FuncionariosInline(admin.StackedInline):
('nota', 'email'), ('nota', 'email'),
('cargo', 'funcao', 'setor'), ('cargo', 'funcao', 'setor'),
('tempo_de_servico', 'ult_alteracao'), ('tempo_de_servico', 'ult_alteracao'),
('desativado', 'observacoes'),
) )
}),) }),)
readonly_fields = ('ult_alteracao',) readonly_fields = ('ult_alteracao',)
@ -63,44 +64,75 @@ class FuncionariosInline(admin.StackedInline):
inlines = (TelefonesInline,) inlines = (TelefonesInline,)
def get_queryset(self, request): def get_queryset(self, request):
return self.model.objects.exclude(cargo=_(u"Presidente")) return (self.model.objects.exclude(
cargo='Presidente').exclude(desativado=True)
)
class ConveniosInline(admin.StackedInline): class ConveniosInline(admin.TabularInline):
model = Convenio model = Convenio
fieldsets = ( fieldsets = (
(None, {'fields': (('link_convenio', 'num_processo_sf', 'num_convenio', 'projeto', 'observacao'), (None, {'fields': (
('data_adesao', 'data_retorno_assinatura', 'data_termo_aceite', 'data_pub_diario', 'data_devolucao_via', 'data_postagem_correio'), ('link_sigad', 'status_convenio', 'num_convenio',
('data_devolucao_sem_assinatura', 'data_retorno_sem_assinatura',), 'projeto', 'observacao'),
('get_tramitacoes', 'get_anexos', 'get_equipamentos',), ('data_adesao', 'data_retorno_assinatura', 'data_termo_aceite',
)} 'data_pub_diario', 'data_devolucao_via', 'data_postagem_correio'),
), ('data_devolucao_sem_assinatura', 'data_retorno_sem_assinatura',),
('link_convenio',),
)}),
) )
readonly_fields = ['get_tramitacoes', 'get_anexos', 'get_equipamentos', 'link_convenio', ] readonly_fields = ['link_convenio', 'link_sigad', 'status_convenio',
'num_convenio', 'projeto', 'observacao', 'data_adesao',
'data_retorno_assinatura', 'data_termo_aceite',
'data_pub_diario', 'data_devolucao_via',
'data_postagem_correio', 'data_devolucao_sem_assinatura',
'data_retorno_sem_assinatura',]
extra = 0 extra = 0
can_delete = False
def get_tramitacoes(self, obj): def has_add_permission(self, request):
return '<br/>'.join([t.__unicode__() for t in obj.tramitacao_set.all()]) return False
get_tramitacoes.short_description = _(u'Tramitações') # def get_tramitacoes(self, obj):
get_tramitacoes.allow_tags = True # return '<br/>'.join([t.__unicode__() for t in obj.tramitacao_set.all()])
#
def get_anexos(self, obj): # get_tramitacoes.short_description = _(u'Tramitações')
return '<br/>'.join(['<a href="%s" target="_blank">%s</a>' % (a.arquivo.url, a.__unicode__()) for a in obj.anexo_set.all()]) # get_tramitacoes.allow_tags = True
#
get_anexos.short_description = _(u'Anexos') # def get_anexos(self, obj):
get_anexos.allow_tags = True # return '<br/>'.join(['<a href="%s" target="_blank">%s</a>' % (a.arquivo.url, a.__unicode__()) for a in obj.anexo_set.all()])
#
# get_anexos.short_description = _(u'Anexos')
# get_anexos.allow_tags = True
#
# def get_equipamentos(self, obj):
# return '<br/>'.join([e.__unicode__() for e in obj.equipamentoprevisto_set.all()])
#
# get_equipamentos.short_description = _(u'Equipamentos previstos')
# get_equipamentos.allow_tags = True
def status_convenio(self, obj):
if obj.pk is None:
return ""
status = obj.get_status()
if status in [u"Vencido", u"Desistência"]:
label = r"danger"
elif status == u"Vigente":
label = r"success"
elif status == u"Pendente":
label = r"warning"
else:
label = r"info"
def get_equipamentos(self, obj): return u'<p class="label label-{label}">{status}</p>'.format(label=label, status=status)
return '<br/>'.join([e.__unicode__() for e in obj.equipamentoprevisto_set.all()]) status_convenio.short_description = _(u"Status do convênio")
status_convenio.allow_tags = True
get_equipamentos.short_description = _(u'Equipamentos previstos')
get_equipamentos.allow_tags = True
def link_convenio(self, obj): def link_convenio(self, obj):
if obj.pk is None: if obj.pk is None:
return "" return ""
from django.core.urlresolvers import reverse
url = reverse('admin:%s_%s_change' % (obj._meta.app_label, obj._meta.module_name), args=[obj.pk]) url = reverse('admin:%s_%s_change' % (obj._meta.app_label, obj._meta.module_name), args=[obj.pk])
url = url + '?_popup=1' url = url + '?_popup=1'
return """<input id="edit_convenio-%s" type="hidden"/> return """<input id="edit_convenio-%s" type="hidden"/>
@ -111,6 +143,14 @@ class ConveniosInline(admin.StackedInline):
link_convenio.short_description = _(u'Editar convenio') link_convenio.short_description = _(u'Editar convenio')
link_convenio.allow_tags = True link_convenio.allow_tags = True
def link_sigad(self, obj):
if obj.pk is None:
return ""
return obj.get_sigad_url()
link_sigad.short_description = _("Processo no Senado")
link_sigad.allow_tags = True
class LegislaturaInline(admin.TabularInline): class LegislaturaInline(admin.TabularInline):
model = Legislatura model = Legislatura
@ -191,10 +231,10 @@ class OcorrenciaInline(admin.TabularInline):
link_editar.allow_tags = True link_editar.allow_tags = True
class GerentesContasFilter(admin.filters.RelatedFieldListFilter): class GerentesInterlegisFilter(admin.filters.RelatedFieldListFilter):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(GerentesContasFilter, self).__init__(*args, **kwargs) super(GerentesInterlegisFilter, self).__init__(*args, **kwargs)
gerentes = Servidor.objects.filter(casas_que_gerencia__isnull=False).order_by('nome_completo').distinct() gerentes = Servidor.objects.filter(casas_que_gerencia__isnull=False).order_by('nome_completo').distinct()
self.lookup_choices = [(x.id, x) for x in gerentes] self.lookup_choices = [(x.id, x) for x in gerentes]
@ -259,29 +299,33 @@ class ServicoFilter(admin.SimpleListFilter):
class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin): class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin):
form = CasaLegislativaForm form = CasaLegislativaForm
actions = ['adicionar_casas', ] actions = ['adicionar_casas', ]
inlines = (TelefonesInline, PresidenteInline, FuncionariosInline, ConveniosInline, LegislaturaInline, inlines = (TelefonesInline, PresidenteInline, FuncionariosInline,
DiagnosticoInline, BemInline, ServicoInline, PlanoDiretorInline, OcorrenciaInline,) ConveniosInline, LegislaturaInline, DiagnosticoInline, BemInline,
list_display = ('nome', 'get_uf', 'get_gerente_contas', 'get_convenios', ServicoInline, PlanoDiretorInline, OcorrenciaInline,)
list_display = ('nome', 'get_uf', 'get_gerentes', 'get_convenios',
'get_servicos') 'get_servicos')
list_display_links = ('nome',) list_display_links = ('nome',)
list_filter = ('tipo', ('gerente_contas', GerentesContasFilter), list_filter = ('tipo', ('gerentes_interlegis', GerentesInterlegisFilter),
'municipio__uf__nome', ConvenioFilter, ServicoFilter, 'municipio__uf__nome', ConvenioFilter, ServicoFilter,
'inclusao_digital',) 'inclusao_digital',)
ordering = ('municipio__uf__nome', 'nome') ordering = ('municipio__uf__nome', 'nome')
queryset = queryset_ascii queryset = queryset_ascii
fieldsets = ( fieldsets = (
(None, { (None, {
'fields': ('tipo', 'nome', 'cnpj', 'num_parlamentares', 'gerente_contas') 'fields': ('tipo', 'nome', 'cnpj', 'num_parlamentares',
'gerentes_interlegis')
}), }),
(_(u'Endereço'), { (_(u'Endereço'), {
'fields': ('data_instalacao', 'logradouro', 'bairro', 'fields': ('data_instalacao', 'logradouro', 'bairro',
'municipio', 'cep', 'ult_alt_endereco'), 'municipio', 'cep', 'ult_alt_endereco'),
}), }),
(_(u'Presença na Internet'), { (_(u'Presença na Internet'), {
'fields': ('inclusao_digital', 'data_levantamento', 'pesquisador', 'pagina_web', 'email', 'obs_pesquisa',) 'fields': ('inclusao_digital', 'data_levantamento', 'pesquisador',
'pagina_web', 'email', 'obs_pesquisa',)
}), }),
(_(u'Outras informações'), { (_(u'Outras informações'), {
'fields': ('observacoes', 'horario_funcionamento', 'foto', 'recorte'), 'fields': ('observacoes', 'horario_funcionamento', 'foto',
'recorte'),
}), }),
) )
raw_id_fields = ('municipio',) raw_id_fields = ('municipio',)
@ -289,6 +333,7 @@ class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin):
search_fields = ('search_text', 'cnpj', 'bairro', 'logradouro', search_fields = ('search_text', 'cnpj', 'bairro', 'logradouro',
'cep', 'municipio__nome', 'municipio__uf__nome', 'cep', 'municipio__nome', 'municipio__uf__nome',
'municipio__codigo_ibge', 'pagina_web', 'observacoes') 'municipio__codigo_ibge', 'pagina_web', 'observacoes')
filter_horizontal = ('gerentes_interlegis',)
def get_uf(self, obj): def get_uf(self, obj):
return obj.municipio.uf.nome return obj.municipio.uf.nome
@ -296,10 +341,10 @@ class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin):
get_uf.short_description = _(u'Unidade da Federação') get_uf.short_description = _(u'Unidade da Federação')
get_uf.admin_order_field = 'municipio__uf__nome' get_uf.admin_order_field = 'municipio__uf__nome'
def get_gerente_contas(self, obj): def get_gerentes(self, obj):
return obj.gerente_contas return obj.lista_gerentes
get_gerentes.short_description = _(u'Gerente Interlegis')
get_gerente_contas.short_description = _(u'Gerente de contas') get_gerentes.allow_tags = True
def get_convenios(self, obj): def get_convenios(self, obj):
return '<ul>' + ''.join(['<li>%s</li>' % c.__unicode__() for c in obj.convenio_set.all()]) + '</ul>' return '<ul>' + ''.join(['<li>%s</li>' % c.__unicode__() for c in obj.convenio_set.all()]) + '</ul>'

20
sigi/apps/casas/forms.py

@ -20,8 +20,22 @@ class CasaLegislativaForm(forms.ModelForm):
fields = '__all__' fields = '__all__'
class PortfolioForm(forms.Form): class PortfolioForm(forms.Form):
gerente_contas = forms.ModelChoiceField(queryset=Servidor.objects.all(), label=_(u"Atribuir casas para")) ACAO_CHOICES = (
('ADD', _(u"Adicionar")),
('DEL', _(u"Remover"))
)
acao = forms.ChoiceField(
label=_(u"Ação"),
choices=ACAO_CHOICES,
initial='ADD',
widget=forms.RadioSelect
)
gerente = forms.ModelChoiceField(
queryset=Servidor.objects.all(),
label=_(u"Atribuir para")
)
def __init__(self, label=_(u"Atribuir casas para"), *args, **kwargs): # O label precisa ser trocado dependendo da região que se está visualizando
def __init__(self, label=_(u"Atribuir para"), *args, **kwargs):
super(PortfolioForm, self).__init__(*args, **kwargs) super(PortfolioForm, self).__init__(*args, **kwargs)
self.fields['gerente_contas'].label = label self.fields['gerente'].label = label

34
sigi/apps/casas/management/commands/importa_gerentes.py

@ -56,29 +56,43 @@ class Command(BaseCommand):
if not self.campos.issubset(reader.fieldnames): if not self.campos.issubset(reader.fieldnames):
raise CommandError(u"O arquivo não possui todos os campos obrigatórios") raise CommandError(u"O arquivo não possui todos os campos obrigatórios")
CasaLegislativa.objects.update(gerente_contas=None) CasaLegislativa.gerentes_interlegis.through.objects.all().delete()
erros = 0 erros = 0
for reg in reader: for reg in reader:
try: try:
municipio = Municipio.objects.get(codigo_ibge=reg['cod_municipio']) municipio = Municipio.objects.get(
codigo_ibge=reg['cod_municipio']
)
except Municipio.DoesNotExist: except Municipio.DoesNotExist:
self.stdout.write(u"(Linha %s): não existe Município com código IBGE '%s'" % self.stdout.write(u"{linha}: não existe Município com "
(reader.line_num, reg['cod_municipio'],)) u"código IBGE {ibge}'".format(
linha=reader.line_num,
ibge=reg['cod_municipio'])
)
erros = erros + 1 erros = erros + 1
continue continue
try: try:
gerente = Servidor.objects.get(user__username=reg['user_id']) gerente = Servidor.objects.get(
user__username=reg['user_id']
)
except Servidor.DoesNotExist: except Servidor.DoesNotExist:
self.stdout.write(u"(Linha %s): não existe Servidor com userid '%s'" % self.stdout.write(u"({linha}): não existe Servidor com "
(reader.line_num, reg['user_id'],)) u"userid {userid}".format(
linha=reader.line_num,
userid=reg['user_id'])
)
erros = erros + 1 erros = erros + 1
continue continue
for casa in municipio.casalegislativa_set.filter(tipo__sigla__in=['AL', 'CM']): for casa in municipio.casalegislativa_set.filter(
casa.gerente_contas = gerente tipo__sigla__in=['AL', 'CM']):
casa.gerentes_interlegis.add(gerente)
casa.save() casa.save()
self.stdout.write(u"Importação concluída. %s erros em %s linhas" % (erros, reader.line_num,)) self.stdout.write(u"Importação concluída. {erros} erros em {linhas}"
u" linhas".format(erros=erros,
linhas=reader.line_num)
)

20
sigi/apps/casas/migrations/0004_auto_20201015_0810.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('casas', '0003_auto_20200207_0919'),
]
operations = [
migrations.AlterField(
model_name='casalegislativa',
name='gerente_contas',
field=models.ForeignKey(related_name='casas_que_gerencia_old', verbose_name=b'Gerente de contas', blank=True, to='servidores.Servidor', null=True),
preserve_default=True,
),
]

21
sigi/apps/casas/migrations/0005_casalegislativa_gerentes_interlegis.py

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('servidores', '0001_initial'),
('casas', '0004_auto_20201015_0810'),
]
operations = [
migrations.AddField(
model_name='casalegislativa',
name='gerentes_interlegis',
field=models.ManyToManyField(related_name='casas_que_gerencia', verbose_name=b'Gerentes Interlegis', to='servidores.Servidor'),
preserve_default=True,
),
]

18
sigi/apps/casas/migrations/0006_remove_casalegislativa_gerente_contas.py

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('casas', '0005_casalegislativa_gerentes_interlegis'),
]
operations = [
migrations.RemoveField(
model_name='casalegislativa',
name='gerente_contas',
),
]

128
sigi/apps/casas/migrations/0007_auto_20201016_1632.py

@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('casas', '0006_remove_casalegislativa_gerente_contas'),
]
operations = [
migrations.AddField(
model_name='funcionario',
name='desativado',
field=models.BooleanField(default=False, verbose_name='Desativado'),
preserve_default=True,
),
migrations.AddField(
model_name='funcionario',
name='observacoes',
field=models.TextField(verbose_name='Observa\xe7\xf5es', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='bairro',
field=models.CharField(max_length=100, verbose_name='Bairro', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='cep',
field=models.CharField(max_length=32, verbose_name='CEP'),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='codigo_interlegis',
field=models.CharField(max_length=3, verbose_name='C\xf3digo Interlegis', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='email',
field=models.EmailField(max_length=128, verbose_name='E-mail', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='foto',
field=models.ImageField(upload_to=b'imagens/casas', width_field=b'foto_largura', height_field=b'foto_altura', blank=True, verbose_name='Foto'),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='inclusao_digital',
field=models.CharField(default=b'NAO PESQUISADO', max_length=30, verbose_name='Inclus\xe3o digital', choices=[(b'NAO PESQUISADO', 'N\xe3o pesquisado'), (b'NAO POSSUI PORTAL', 'N\xe3o possui portal'), (b'PORTAL MODELO', 'Possui Portal Modelo'), (b'OUTRO PORTAL', 'Possui outro portal')]),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='logradouro',
field=models.CharField(help_text='Avenida, rua, pra\xe7a, jardim, parque...', max_length=100, verbose_name='Logradouro'),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='municipio',
field=models.ForeignKey(verbose_name='Munic\xedpio', to='contatos.Municipio'),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='nome',
field=models.CharField(help_text='Exemplo: <em>C\xe2mara Municipal de Pains</em>.', max_length=60, verbose_name='Nome'),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='pagina_web',
field=models.URLField(help_text='Exemplo: <em>http://www.camarapains.mg.gov.br</em>.', verbose_name='P\xe1gina web', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='funcionario',
name='cargo',
field=models.CharField(max_length=100, null=True, verbose_name='Cargo', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='funcionario',
name='nota',
field=models.CharField(max_length=70, null=True, verbose_name='Telefones', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='funcionario',
name='setor',
field=models.CharField(default=b'outros', max_length=100, verbose_name='Setor', choices=[(b'presidente', 'Presidente'), (b'contato_interlegis', 'Contato Interlegis'), (b'infraestrutura_fisica', 'Infraestrutura F\xedsica'), (b'estrutura_de_ti', 'Estrutura de TI'), (b'organizacao_do_processo_legislativo', 'Organiza\xe7\xe3o do Processo Legislativo'), (b'producao_legislativa', 'Produ\xe7\xe3o Legislativa'), (b'estrutura_de_comunicacao_social', 'Estrutura de Comunica\xe7\xe3o Social'), (b'estrutura_de_recursos_humanos', 'Estrutura de Recursos Humanos'), (b'gestao', 'Gest\xe3o'), (b'outros', 'Outros')]),
preserve_default=True,
),
migrations.AlterField(
model_name='funcionario',
name='sexo',
field=models.CharField(default=b'M', max_length=1, verbose_name='Sexo', choices=[(b'M', 'Masculino'), (b'F', 'Feminino')]),
preserve_default=True,
),
migrations.AlterField(
model_name='funcionario',
name='tempo_de_servico',
field=models.CharField(max_length=50, null=True, verbose_name='Tempo de servi\xe7o', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='tipocasalegislativa',
name='nome',
field=models.CharField(max_length=100, verbose_name='Nome'),
preserve_default=True,
),
migrations.AlterField(
model_name='tipocasalegislativa',
name='sigla',
field=models.CharField(max_length=5, verbose_name='Sigla'),
preserve_default=True,
),
]

201
sigi/apps/casas/models.py

@ -3,7 +3,7 @@ from datetime import datetime
import random import random
from string import ascii_uppercase from string import ascii_uppercase
from unicodedata import normalize from unicodedata import normalize
from django.utils.translation import ugettext as _
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from django.db import models from django.db import models
from image_cropping import ImageRatioField from image_cropping import ImageRatioField
@ -20,12 +20,8 @@ class TipoCasaLegislativa(models.Model):
Câmara Distrital ou Legislativo Federal Câmara Distrital ou Legislativo Federal
""" """
sigla = models.CharField( sigla = models.CharField(_(u"Sigla"), max_length=5)
max_length=5 nome = models.CharField(_(u"Nome"), max_length=100)
)
nome = models.CharField(
max_length=100
)
def __unicode__(self): def __unicode__(self):
return self.nome return self.nome
@ -37,77 +33,125 @@ class CasaLegislativa(models.Model):
""" """
INCLUSAO_DIGITAL_CHOICES = ( INCLUSAO_DIGITAL_CHOICES = (
('NAO PESQUISADO', u'Não pesquisado'), ('NAO PESQUISADO', _(u'Não pesquisado')),
('NAO POSSUI PORTAL', u'Não possui portal'), ('NAO POSSUI PORTAL', _(u'Não possui portal')),
('PORTAL MODELO', u'Possui Portal Modelo'), ('PORTAL MODELO', _(u'Possui Portal Modelo')),
('OUTRO PORTAL', u'Possui outro portal'), ('OUTRO PORTAL', _(u'Possui outro portal')),
) )
nome = models.CharField( nome = models.CharField(
_(u"Nome"),
max_length=60, max_length=60,
help_text='Exemplo: <em>Câmara Municipal de Pains</em>.' help_text=_(u'Exemplo: <em>Câmara Municipal de Pains</em>.')
) )
# Guarda um campo para ser usado em buscas em caixa baixa e sem acento # Guarda um campo para ser usado em buscas em caixa baixa e sem acento
search_text = SearchField(field_names=['nome']) search_text = SearchField(field_names=['nome'])
# search_text.projeto_filter = True # search_text.projeto_filter = True
tipo = models.ForeignKey(TipoCasaLegislativa, verbose_name="Tipo") tipo = models.ForeignKey(TipoCasaLegislativa, verbose_name=_(u"Tipo"))
cnpj = models.CharField('CNPJ', max_length=32, blank=True) cnpj = models.CharField(_(u"CNPJ"), max_length=32, blank=True)
observacoes = models.TextField(u'observações', blank=True) observacoes = models.TextField(_(u'observações'), blank=True)
horario_funcionamento = models.CharField( horario_funcionamento = models.CharField(
u"Horário de funcionamento da Casa Legislativa", _(u"Horário de funcionamento da Casa Legislativa"),
max_length=100, max_length=100,
blank=True, blank=True,
) )
# num_parlamentares = models.PositiveIntegerField('Número de parlamentares') # num_parlamentares = models.PositiveIntegerField('Número de parlamentares')
codigo_interlegis = models.CharField('Código Interlegis', max_length=3, blank=True) codigo_interlegis = models.CharField(
_(u'Código Interlegis'),
max_length=3,
blank=True
)
# codigo_interlegis.ts_filter = True # codigo_interlegis.ts_filter = True
gerente_contas = models.ForeignKey(Servidor, verbose_name="Gerente de contas", null=True, blank=True, related_name='casas_que_gerencia') gerentes_interlegis = models.ManyToManyField(
Servidor,
verbose_name=_(u"Gerentes Interlegis"),
related_name='casas_que_gerencia'
)
# Informações de contato # Informações de contato
logradouro = models.CharField( logradouro = models.CharField(
_(u"Logradouro"),
max_length=100, max_length=100,
help_text='Avenida, rua, praça, jardim, parque...' help_text=_(u'Avenida, rua, praça, jardim, parque...')
) )
bairro = models.CharField(max_length=100, blank=True) bairro = models.CharField(_(u"Bairro"), max_length=100, blank=True)
municipio = models.ForeignKey( municipio = models.ForeignKey(
'contatos.Municipio', 'contatos.Municipio',
verbose_name='município' verbose_name=_(u'Município')
) )
# municipio.uf_filter = True # municipio.uf_filter = True
cep = models.CharField(max_length=32) cep = models.CharField(_(u"CEP"), max_length=32)
email = models.EmailField('e-mail', max_length=128, blank=True) email = models.EmailField(_(u'E-mail'), max_length=128, blank=True)
pagina_web = models.URLField( pagina_web = models.URLField(
u'página web', _(u'Página web'),
help_text='Exemplo: <em>http://www.camarapains.mg.gov.br</em>.', help_text=_(u'Exemplo: <em>http://www.camarapains.mg.gov.br</em>.'),
blank=True, blank=True,
) )
inclusao_digital = models.CharField(max_length=30, choices=INCLUSAO_DIGITAL_CHOICES, default=INCLUSAO_DIGITAL_CHOICES[0][0]) inclusao_digital = models.CharField(
data_levantamento = models.DateTimeField(u"Data/hora da pesquisa", null=True, blank=True) _(u"Inclusão digital"),
pesquisador = models.ForeignKey(Servidor, verbose_name=u"Pesquisador", null=True, blank=True) max_length=30,
obs_pesquisa = models.TextField(u"Observações do pesquisador", blank=True) choices=INCLUSAO_DIGITAL_CHOICES,
ult_alt_endereco = models.DateTimeField(u'Última alteração do endereço', null=True, blank=True, editable=True) default=INCLUSAO_DIGITAL_CHOICES[0][0]
)
data_levantamento = models.DateTimeField(
_(u"Data/hora da pesquisa"),
null=True,
blank=True
)
pesquisador = models.ForeignKey(
Servidor,
verbose_name=_(u"Pesquisador"),
null=True,
blank=True
)
obs_pesquisa = models.TextField(
_(u"Observações do pesquisador"),
blank=True
)
ult_alt_endereco = models.DateTimeField(
_(u'Última alteração do endereço'),
null=True,
blank=True,
editable=True
)
telefones = generic.GenericRelation('contatos.Telefone') telefones = generic.GenericRelation('contatos.Telefone')
foto = models.ImageField( foto = models.ImageField(
_(u"Foto"),
upload_to='imagens/casas', upload_to='imagens/casas',
width_field='foto_largura', width_field='foto_largura',
height_field='foto_altura', height_field='foto_altura',
blank=True blank=True
) )
recorte = ImageRatioField('foto', '400x300', verbose_name="Recorte",) recorte = ImageRatioField('foto', '400x300', verbose_name=_("Recorte"))
foto_largura = models.SmallIntegerField(editable=False, null=True) foto_largura = models.SmallIntegerField(editable=False, null=True)
foto_altura = models.SmallIntegerField(editable=False, null=True) foto_altura = models.SmallIntegerField(editable=False, null=True)
data_instalacao = models.DateField(u'Data de instalação da Casa Legislativa', null=True, blank=True) data_instalacao = models.DateField(
_(u'Data de instalação da Casa Legislativa'),
null=True,
blank=True
)
class Meta: class Meta:
ordering = ('nome',) ordering = ('nome',)
unique_together = ('municipio', 'tipo') unique_together = ('municipio', 'tipo')
verbose_name = 'Casa Legislativa' verbose_name = _(u'Casa Legislativa')
verbose_name_plural = 'Casas Legislativas' verbose_name_plural = _(u'Casas Legislativas')
def lista_gerentes(self, fmt='html'):
if not self.gerentes_interlegis.exists():
return ""
if fmt == 'html':
return u"<ul><li>"+u"</li><li>".join(
[g.nome_completo for g in self.gerentes_interlegis.all()])+\
u"</li></ul>"
else:
return u", ".join([g.nome_completo for g in
self.gerentes_interlegis.all()])
@property @property
def num_parlamentares(self): def num_parlamentares(self):
@ -276,42 +320,79 @@ class Funcionario(models.Model):
""" """
SETOR_CHOICES = [ SETOR_CHOICES = [
("presidente", "Presidente"), ("presidente", _(u"Presidente")),
("contato_interlegis", "Contato Interlegis"), ("contato_interlegis", _(u"Contato Interlegis")),
("infraestrutura_fisica", "Infraestrutura Física"), ("infraestrutura_fisica", _(u"Infraestrutura Física")),
("estrutura_de_ti", "Estrutura de TI"), ("estrutura_de_ti", _(u"Estrutura de TI")),
("organizacao_do_processo_legislativo", "Organização do Processo Legislativo"), ("organizacao_do_processo_legislativo",
("producao_legislativa", "Produção Legislativa"), _(u"Organização do Processo Legislativo")),
("estrutura_de_comunicacao_social", "Estrutura de Comunicação Social"), ("producao_legislativa", _(u"Produção Legislativa")),
("estrutura_de_recursos_humanos", "Estrutura de Recursos Humanos"), ("estrutura_de_comunicacao_social",
("gestao", "Gestão"), _(u"Estrutura de Comunicação Social")),
("outros", "Outros"), ("estrutura_de_recursos_humanos", _(u"Estrutura de Recursos Humanos")),
("gestao", _(u"Gestão")),
("outros", _(u"Outros")),
] ]
SEXO_CHOICES = [ SEXO_CHOICES = [
("M", "Masculino"), ("M", _(u"Masculino")),
("F", "Feminino") ("F", _(u"Feminino"))
] ]
casa_legislativa = models.ForeignKey(CasaLegislativa) casa_legislativa = models.ForeignKey(CasaLegislativa)
nome = models.CharField('nome completo', max_length=60, blank=False) nome = models.CharField(_(u'nome completo'), max_length=60, blank=False)
# nome.alphabetic_filter = True # nome.alphabetic_filter = True
sexo = models.CharField(max_length=1, choices=SEXO_CHOICES, default="M") sexo = models.CharField(
data_nascimento = models.DateField(u"Data de nascimento", blank=True, _(u"Sexo"),
null=True) max_length=1,
nota = models.CharField(max_length=70, null=True, blank=True) choices=SEXO_CHOICES,
email = models.CharField('e-mail', max_length=75, blank=True) default="M"
telefones = generic.GenericRelation('contatos.Telefone') )
data_nascimento = models.DateField(
_(u"Data de nascimento"),
blank=True,
null=True
)
nota = models.CharField(
_(u"Telefones"),
max_length=70,
null=True,
blank=True
)
email = models.CharField(_(u'e-mail'), max_length=75, blank=True)
endereco = generic.GenericRelation('contatos.Endereco') endereco = generic.GenericRelation('contatos.Endereco')
cargo = models.CharField(max_length=100, null=True, blank=True) cargo = models.CharField(_(u"Cargo"), max_length=100, null=True, blank=True)
funcao = models.CharField(u'função', max_length=100, null=True, blank=True) funcao = models.CharField(
setor = models.CharField(max_length=100, choices=SETOR_CHOICES, default="outros") _(u'função'),
tempo_de_servico = models.CharField(u'tempo de serviço', max_length=50, null=True, blank=True) max_length=100,
ult_alteracao = models.DateTimeField(u'Última alteração', null=True, blank=True, editable=True, auto_now=True) null=True,
blank=True
)
setor = models.CharField(
_(u"Setor"),
max_length=100,
choices=SETOR_CHOICES,
default="outros"
)
tempo_de_servico = models.CharField(
_(u'Tempo de serviço'),
max_length=50,
null=True,
blank=True
)
ult_alteracao = models.DateTimeField(
_(u'Última alteração'),
null=True,
blank=True,
editable=True,
auto_now=True
)
desativado = models.BooleanField(_(u"Desativado"), default=False)
observacoes = models.TextField(_(u"Observações"), blank=True)
class Meta: class Meta:
ordering = ('nome',) ordering = ('nome',)
verbose_name = 'contato da Casa Legislativa' verbose_name = _(u'contato da Casa Legislativa')
verbose_name_plural = 'contatos da Casa Legislativa' verbose_name_plural = _(u'contatos da Casa Legislativa')
def __unicode__(self): def __unicode__(self):
return self.nome return self.nome

46
sigi/apps/casas/templates/casas/portfolio.html

@ -5,6 +5,32 @@
{% block extrastyle %} {% block extrastyle %}
<style type="text/css"> <style type="text/css">
/* Tooltip container */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
}
/* Tooltip text */
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px 0;
border-radius: 6px;
/* Position the tooltip text - see examples below! */
position: absolute;
z-index: 1;
}
/* Show the tooltip text when you mouse over the tooltip container */
.tooltip:hover .tooltiptext {
visibility: visible;
}
</style> </style>
{{ block.super }} {{ block.super }}
{% endblock %} {% endblock %}
@ -22,10 +48,18 @@
<div class="alert alert-danger">{{ e }}</div> <div class="alert alert-danger">{{ e }}</div>
{% endfor %} {% endfor %}
<div class="nav">
<ul class="object-tools pull-left nav nav-pills">
{% for t in tipos_casas %}
<li{% if tipo == t.sigla %} class="active"{% endif %}><a href="?tipo={{ t.sigla }}" data-toggle="tooltip" title="{{ t.nome }}">{{ t.sigla }}</a></li>
{% endfor %}
</ul>
</div>
<div class="nav"> <div class="nav">
<ul class="object-tools pull-left nav nav-pills"> <ul class="object-tools pull-left nav nav-pills">
{% for key, value in regioes %} {% for key, value in regioes %}
<li{% if regiao == key %} class="active"{% endif %}><a href="?regiao={{ key }}">{{ value }}</a></li> <li{% if regiao == key %} class="active"{% endif %}><a href="?regiao={{ key }}{% if tipo %}&tipo={{ tipo|safe }}{% endif %}">{{ value }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
@ -34,7 +68,7 @@
<div class="nav"> <div class="nav">
<ul class="object-tools pull-left nav nav-tabs"> <ul class="object-tools pull-left nav nav-tabs">
{% for uf in ufs %} {% for uf in ufs %}
<li{% if uf_id == uf.pk %} class="active"{% endif %}><a href="?uf={{ uf.pk|safe }}">{{ uf.nome }}</a></li> <li{% if uf_id == uf.pk %} class="active"{% endif %}><a href="?uf={{ uf.pk|safe }}{% if tipo %}&tipo={{ tipo|safe }}{% endif %}">{{ uf.nome }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
@ -44,7 +78,7 @@
<div class="nav"> <div class="nav">
<ul class="object-tools pull-left nav nav-pills"> <ul class="object-tools pull-left nav nav-pills">
{% for meso in mesorregioes %} {% for meso in mesorregioes %}
<li{% if meso_id == meso.pk %} class="active"{% endif %}><a href="?meso={{ meso.pk|safe }}">{{ meso.nome }}</a></li> <li{% if meso_id == meso.pk %} class="active"{% endif %}><a href="?meso={{ meso.pk|safe }}{% if tipo %}&tipo={{ tipo|safe }}{% endif %}">{{ meso.nome }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
@ -54,7 +88,7 @@
<div class="nav"> <div class="nav">
<ul class="object-tools pull-left nav nav-pills"> <ul class="object-tools pull-left nav nav-pills">
{% for micro in microrregioes %} {% for micro in microrregioes %}
<li{% if micro_id == micro.pk %} class="active"{% endif %}><a href="?micro={{ micro.pk|safe }}">{{ micro.nome }}</a></li> <li{% if micro_id == micro.pk %} class="active"{% endif %}><a href="?micro={{ micro.pk|safe }}{% if tipo %}&tipo={{ tipo|safe }}{% endif %}">{{ micro.nome }}</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
@ -64,7 +98,7 @@
<form action="" method="post" id="atribui_gerente_form"> <form action="" method="post" id="atribui_gerente_form">
{% csrf_token %} {% csrf_token %}
{{ form }} {{ form }}
<input type="submit" name="_save" value="Atribuir" class="btn btn-default" /> <input type="submit" name="_save" class="btn btn-default"/>
</form> </form>
{% endif %} {% endif %}
@ -85,7 +119,7 @@
<td>{{ casa.municipio.uf }}</td> <td>{{ casa.municipio.uf }}</td>
<td>{{ casa.municipio.microrregiao.mesorregiao }}</td> <td>{{ casa.municipio.microrregiao.mesorregiao }}</td>
<td>{{ casa.municipio.microrregiao.nome }}</td> <td>{{ casa.municipio.microrregiao.nome }}</td>
<td>{{ casa.gerente_contas }}</td> <td>{{ casa.lista_gerentes|safe }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

2
sigi/apps/casas/test_casas.py

@ -14,4 +14,4 @@ def some_parliaments():
def parliaments_from_names(names): def parliaments_from_names(names):
return [G(CasaLegislativa, nome=name, foto=None, gerente_contas=None,) for name in names] return [G(CasaLegislativa, nome=name, foto=None,) for name in names]

105
sigi/apps/casas/views.py

@ -11,7 +11,7 @@ from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext as _, ungettext from django.utils.translation import ugettext as _, ungettext
from sigi.apps.casas.forms import PortfolioForm from sigi.apps.casas.forms import PortfolioForm
from sigi.apps.casas.models import CasaLegislativa from sigi.apps.casas.models import CasaLegislativa, TipoCasaLegislativa
from sigi.apps.casas.reports import (CasasLegislativasLabels, from sigi.apps.casas.reports import (CasasLegislativasLabels,
CasasLegislativasLabelsSemPresidente) CasasLegislativasLabelsSemPresidente)
from sigi.apps.contatos.models import UnidadeFederativa, Mesorregiao, Microrregiao from sigi.apps.contatos.models import UnidadeFederativa, Mesorregiao, Microrregiao
@ -421,6 +421,7 @@ def export_csv(request):
@login_required @login_required
def portfolio(request): def portfolio(request):
page = request.GET.get('page', 1) page = request.GET.get('page', 1)
tipo = request.GET.get('tipo', None)
regiao = request.GET.get('regiao', None) regiao = request.GET.get('regiao', None)
uf_id = request.GET.get('uf', None) uf_id = request.GET.get('uf', None)
meso_id = request.GET.get('meso', None) meso_id = request.GET.get('meso', None)
@ -430,15 +431,12 @@ def portfolio(request):
data['errors'] = [] data['errors'] = []
data['messages'] = [] data['messages'] = []
data['regioes'] = UnidadeFederativa.REGIAO_CHOICES data['regioes'] = UnidadeFederativa.REGIAO_CHOICES
data['tipos_casas'] = TipoCasaLegislativa.objects.all()
casas = None casas = None
gerente_contas = None gerente = None
if request.method == 'POST': if tipo:
form = PortfolioForm(data=request.POST) data['tipo'] = tipo
if form.is_valid():
gerente_contas = form.cleaned_data['gerente_contas']
else:
data['errors'].append(_(u"Dados inválidos"))
if micro_id: if micro_id:
microrregiao = get_object_or_404(Microrregiao, pk=micro_id) microrregiao = get_object_or_404(Microrregiao, pk=micro_id)
@ -451,9 +449,14 @@ def portfolio(request):
data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao) data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao)
data['mesorregioes'] = uf.mesorregiao_set.all() data['mesorregioes'] = uf.mesorregiao_set.all()
data['microrregioes'] = mesorregiao.microrregiao_set.all() data['microrregioes'] = mesorregiao.microrregiao_set.all()
data['form'] = PortfolioForm(_(u'Atribuir casas da microrregiao %s para') % (unicode(microrregiao),)) data['form'] = PortfolioForm(
data['querystring'] = 'micro=%s' % (microrregiao.pk,) _(u'Atribuir casas da microrregiao {name} para').format(
casas = CasaLegislativa.objects.filter(municipio__microrregiao=microrregiao) name=unicode(microrregiao))
)
data['querystring'] = 'micro={0}'.format(microrregiao.pk)
casas = CasaLegislativa.objects.filter(
municipio__microrregiao=microrregiao
)
elif meso_id: elif meso_id:
mesorregiao = get_object_or_404(Mesorregiao, pk=meso_id) mesorregiao = get_object_or_404(Mesorregiao, pk=meso_id)
uf = mesorregiao.uf uf = mesorregiao.uf
@ -463,38 +466,74 @@ def portfolio(request):
data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao) data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao)
data['mesorregioes'] = uf.mesorregiao_set.all() data['mesorregioes'] = uf.mesorregiao_set.all()
data['microrregioes'] = mesorregiao.microrregiao_set.all() data['microrregioes'] = mesorregiao.microrregiao_set.all()
data['form'] = PortfolioForm(_(u'Atribuir casas da mesorregiao %s para') % (unicode(mesorregiao),)) data['form'] = PortfolioForm(
data['querystring'] = 'meso=%s' % (mesorregiao.pk,) _(u'Atribuir casas da mesorregiao {name} para').format(
casas = CasaLegislativa.objects.filter(municipio__microrregiao__mesorregiao=mesorregiao) name=unicode(mesorregiao)))
data['querystring'] = 'meso={0}'.format(mesorregiao.pk)
casas = CasaLegislativa.objects.filter(
municipio__microrregiao__mesorregiao=mesorregiao
)
elif uf_id: elif uf_id:
uf = get_object_or_404(UnidadeFederativa, pk=uf_id) uf = get_object_or_404(UnidadeFederativa, pk=uf_id)
data['regiao'] = uf.regiao data['regiao'] = uf.regiao
data['uf_id'] = uf.pk data['uf_id'] = uf.pk
data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao) data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao)
data['mesorregioes'] = uf.mesorregiao_set.all() data['mesorregioes'] = uf.mesorregiao_set.all()
data['form'] = PortfolioForm(_(u'Atribuir casas do estado %s para') % (unicode(uf),)) data['form'] = PortfolioForm(
data['querystring'] = 'uf=%s' % (uf.pk,) _(u'Atribuir casas do estado {name} para').format(
name=unicode(uf)))
data['querystring'] = 'uf={0}'.format(uf.pk)
casas = CasaLegislativa.objects.filter(municipio__uf=uf) casas = CasaLegislativa.objects.filter(municipio__uf=uf)
elif regiao: elif regiao:
data['regiao'] = regiao data['regiao'] = regiao
data['ufs'] = UnidadeFederativa.objects.filter(regiao=regiao) data['ufs'] = UnidadeFederativa.objects.filter(regiao=regiao)
data['form'] = PortfolioForm(_(u'Atribuir casas da região %s para') % [x[1] for x in UnidadeFederativa.REGIAO_CHOICES if x[0] == regiao][0]) data['form'] = PortfolioForm(
data['querystring'] = 'regiao=%s' % (regiao,) _(u'Atribuir casas da região {name} para').format(
name=[x[1] for x in UnidadeFederativa.REGIAO_CHOICES if
x[0] == regiao][0]))
data['querystring'] = 'regiao={0}'.format(regiao)
casas = CasaLegislativa.objects.filter(municipio__uf__regiao=regiao) casas = CasaLegislativa.objects.filter(municipio__uf__regiao=regiao)
if casas: if casas:
if gerente_contas: casas = casas.order_by('municipio__uf',
count = casas.update(gerente_contas=gerente_contas) 'municipio__microrregiao__mesorregiao',
data['messages'].append(ungettext(
u"%(count)s casa atribuída para %(name)s",
u"%(count)s casas atribuídas para %(name)s",
count) % {'count': count, 'name': unicode(gerente_contas)})
casas = casas.order_by('municipio__uf', 'municipio__microrregiao__mesorregiao',
'municipio__microrregiao', 'municipio') 'municipio__microrregiao', 'municipio')
casas.prefetch_related('municipio', 'municipio__uf', 'municipio__microrregiao', casas.prefetch_related('municipio', 'municipio__uf',
'municipio__microrregiao__mesorregiao', 'gerente_contas') 'municipio__microrregiao',
'municipio__microrregiao__mesorregiao',
'gerentes_interlegis')
if tipo:
casas = casas.filter(tipo__sigla=tipo)
data['querystring'] += "&tipo={0}".format(tipo)
if request.method == 'POST':
form = PortfolioForm(data=request.POST)
if form.is_valid():
gerente = form.cleaned_data['gerente']
acao = form.cleaned_data['acao']
count = casas.count()
if acao == 'ADD':
gerente.casas_que_gerencia.add(*casas)
data['messages'].append(ungettext(
u"{count} casa adicionada para {gerente}",
u"{count} casas adicionadas para {gerente}",
count).format(count=count,gerente=gerente.nome_completo)
)
elif acao == 'DEL':
gerente.casas_que_gerencia.remove(*casas)
data['messages'].append(ungettext(
u"{count} casa removida de {gerente}",
u"{count} casas removidas de {gerente}",
count).format(count=count,gerente=gerente.nome_completo)
)
else:
data['errors'].append(_(u"Ação não definida"))
else:
data['errors'].append(_(u"Dados inválidos"))
paginator = Paginator(casas, 30) paginator = Paginator(casas, 30)
try: try:
@ -635,7 +674,7 @@ def painel_relacionamento(request):
snippet = request.GET.get('snippet', '') snippet = request.GET.get('snippet', '')
seletor = request.GET.get('s', None) seletor = request.GET.get('s', None)
servidor = request.GET.get('servidor', None) servidor = request.GET.get('servidor', None)
format = request.GET.get('f', 'html') fmt = request.GET.get('f', 'html')
if servidor is None: if servidor is None:
gerente = request.user.servidor gerente = request.user.servidor
@ -648,7 +687,7 @@ def painel_relacionamento(request):
casas = gerente.casas_que_gerencia.all() casas = gerente.casas_que_gerencia.all()
if gerente is None or not casas.exists(): if gerente is None or not casas.exists():
casas = CasaLegislativa.objects.exclude(gerente_contas=None) casas = CasaLegislativa.objects.exclude(gerentes_interlegis=None)
gerente = None gerente = None
tipos_servico = TipoServico.objects.all() tipos_servico = TipoServico.objects.all()
@ -677,7 +716,7 @@ def painel_relacionamento(request):
context['page_obj'] = pagina context['page_obj'] = pagina
if snippet == 'lista': if snippet == 'lista':
if format == 'csv': if fmt == 'csv':
response = HttpResponse(content_type='text/csv') response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=casas.csv' response['Content-Disposition'] = 'attachment; filename=casas.csv'
writer = csv.writer(response) writer = csv.writer(response)
@ -687,7 +726,7 @@ def painel_relacionamento(request):
_(u"Estado").encode('utf8'), _(u"Estado").encode('utf8'),
_(u"Mesorregião").encode('utf8'), _(u"Mesorregião").encode('utf8'),
_(u"Microrregião").encode('utf8'), _(u"Microrregião").encode('utf8'),
_(u"Gerente de relacionamento").encode('utf8'), _(u"Gerentes Interlegis").encode('utf8'),
_(u"Serviços").encode('utf8'), _(u"Serviços").encode('utf8'),
]) ])
for c in casas: for c in casas:
@ -697,7 +736,7 @@ def painel_relacionamento(request):
c.municipio.uf.sigla.encode('utf8'), c.municipio.uf.sigla.encode('utf8'),
c.municipio.microrregiao.mesorregiao.nome.encode('utf8'), c.municipio.microrregiao.mesorregiao.nome.encode('utf8'),
c.municipio.microrregiao.nome.encode('utf8'), c.municipio.microrregiao.nome.encode('utf8'),
c.gerente_contas.nome_completo.encode('utf8'), c.lista_gerentes(fmt='lista').encode('utf8'),
(u", ".join([s.tipo_servico.nome for s in c.servico_set.filter(data_desativacao__isnull=True)])).encode('utf8'), (u", ".join([s.tipo_servico.nome for s in c.servico_set.filter(data_desativacao__isnull=True)])).encode('utf8'),
]) ])
return response return response

2
sigi/apps/convenios/admin.py

@ -44,7 +44,7 @@ class ConvenioAdmin(BaseModelAdmin):
{'fields': ('casa_legislativa', 'num_processo_sf', 'num_convenio', 'projeto', 'observacao')} {'fields': ('casa_legislativa', 'num_processo_sf', 'num_convenio', 'projeto', 'observacao')}
), ),
(_(u'Datas'), (_(u'Datas'),
{'fields': ('data_adesao', 'data_retorno_assinatura', {'fields': ('data_adesao', 'data_retorno_assinatura', 'duracao',
'data_termo_aceite', 'data_pub_diario', 'data_termo_aceite', 'data_pub_diario',
'data_devolucao_via', 'data_postagem_correio')} 'data_devolucao_via', 'data_postagem_correio')}
), ),

20
sigi/apps/convenios/migrations/0002_convenio_duracao.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('convenios', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='convenio',
name='duracao',
field=models.PositiveIntegerField(help_text='Deixar em branco caso a dura\xe7\xe3o seja indefinida', null=True, verbose_name='Dura\xe7\xe3o (meses)', blank=True),
preserve_default=True,
),
]

69
sigi/apps/convenios/models.py

@ -1,8 +1,8 @@
# style="list-style-type: noneo -*- coding: utf-8 -*- #-*- coding: utf-8 -*-
from datetime import datetime import re
from datetime import datetime, date
from django.db import models from django.db import models
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from sigi.apps.utils import SearchField from sigi.apps.utils import SearchField
@ -58,6 +58,12 @@ class Convenio(models.Model):
blank=True, blank=True,
help_text=_(u'Convênio firmado.') help_text=_(u'Convênio firmado.')
) )
duracao = models.PositiveIntegerField(
_(u"Duração (meses)"),
null=True,
blank=True,
help_text=_(u"Deixar em branco caso a duração seja indefinida")
)
data_pub_diario = models.DateField( data_pub_diario = models.DateField(
_(u'data da publicação no Diário Oficial'), _(u'data da publicação no Diário Oficial'),
null=True, null=True,
@ -100,6 +106,58 @@ class Convenio(models.Model):
conveniada = models.BooleanField(default=False) conveniada = models.BooleanField(default=False)
equipada = models.BooleanField(default=False) equipada = models.BooleanField(default=False)
def get_termino_convenio(self):
if (self.data_retorno_assinatura is None or
self.duracao is None):
return None
ano = self.data_retorno_assinatura.year + int(self.duracao / 12)
mes = int(self.data_retorno_assinatura.month + int(self.duracao % 12))
if mes > 12:
ano = ano + 1
mes = mes - 12
dia = self.data_retorno_assinatura.day
while True:
try:
data_fim = date(year=ano, month=mes,day=dia)
break
except:
dia = dia - 1
return data_fim
def get_status(self):
if self.data_retorno_assinatura is not None:
if self.duracao is not None:
if date.today() >= self.get_termino_convenio():
return _(u"Vencido")
return _(u"Vigente")
if (self.data_retorno_assinatura is None and
self.data_devolucao_sem_assinatura is None and
self.data_retorno_sem_assinatura is None):
return _(u"Pendente")
if (self.data_devolucao_sem_assinatura is not None or
self.data_retorno_sem_assinatura is not None):
return _(u"Desistência")
return _(u"Indefinido")
def get_sigad_url(self):
m = re.match(
r'(?P<orgao>00100|00200)\.(?P<sequencial>\d{6})/(?P<ano>\d{4})-\d{2}',
self.num_processo_sf
)
if m:
return (r'<a href="https://intra.senado.leg.br/'
r'sigad/novo/protocolo/impressao.asp?area=processo'
r'&txt_numero_orgao={orgao}'
r'&txt_numero_sequencial={sequencial}'
r'&txt_numero_ano={ano}"'
r' target="_blank">{processo}</a>').format(processo=self.num_processo_sf,**m.groupdict())
return self.num_processo_sf
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
self.conveniada = self.data_retorno_assinatura is not None self.conveniada = self.data_retorno_assinatura is not None
self.equipada = self.data_termo_aceite is not None self.equipada = self.data_termo_aceite is not None
@ -112,10 +170,11 @@ class Convenio(models.Model):
def __unicode__(self): def __unicode__(self):
if self.data_retorno_assinatura is not None: if self.data_retorno_assinatura is not None:
return _(u"Convênio %(number)s - projeto %(project)s, em %(date)s") % dict( return _(u"Convênio {project}{number} assinado em {date}. Status: {status}".format(
number=self.num_convenio, number=self.num_convenio,
project=self.projeto.sigla, project=self.projeto.sigla,
date=self.data_retorno_assinatura) date=self.data_retorno_assinatura,
status=self.get_status()))
else: else:
return _(u"Adesão ao projeto %(project)s, em %(date)s") % dict( return _(u"Adesão ao projeto %(project)s, em %(date)s") % dict(
project=self.projeto.sigla, project=self.projeto.sigla,

2
sigi/apps/home/templates/home/sem_convenio.html

@ -77,7 +77,7 @@
<tr> <tr>
<td>{{ casa.nome }}</td> <td>{{ casa.nome }}</td>
<td>{{ casa.municipio.uf.sigla }}</td> <td>{{ casa.municipio.uf.sigla }}</td>
<td>{{ casa.gerente_contas.nome_completo }}</td> <td>{{ casa.lista_gerentes }}</td>
<td> <td>
{% for s in casa.servico_set.all %} {% for s in casa.servico_set.all %}
{% if s.data_desativacao == None %} {% if s.data_desativacao == None %}

49
sigi/apps/home/views.py

@ -126,9 +126,13 @@ def chart_carteira(request):
'data': [{'value': r['total_casas'], 'data': [{'value': r['total_casas'],
'color': colors.next(), 'color': colors.next(),
'highlight': highlights.next(), 'highlight': highlights.next(),
'label': r['gerente_contas__nome_completo'] 'label': r['gerentes_interlegis__nome_completo']
} }
for r in CasaLegislativa.objects.all().values('gerente_contas__nome_completo').annotate(total_casas=Count('pk')).order_by('gerente_contas__nome_completo') for r in CasaLegislativa.objects.exclude(
gerentes_interlegis=None).values(
'gerentes_interlegis__nome_completo').annotate(
total_casas=Count('pk')).order_by(
'gerentes_interlegis__nome_completo')
] ]
} }
@ -140,7 +144,7 @@ def chart_performance(request):
servidor = request.GET.get('servidor', None) servidor = request.GET.get('servidor', None)
if servidor is None: if servidor is None:
casas = CasaLegislativa.objects.exclude(gerente_contas=None) casas = CasaLegislativa.objects.exclude(gerentes_interlegis=None)
else: else:
gerente = get_object_or_404(Servidor, pk=servidor) gerente = get_object_or_404(Servidor, pk=servidor)
casas = gerente.casas_que_gerencia casas = gerente.casas_que_gerencia
@ -149,8 +153,12 @@ def chart_performance(request):
'type': 'pie', 'type': 'pie',
'options': {'responsive': True}, 'options': {'responsive': True},
'data': [ 'data': [
{'label': _(u"Utilizam serviços"), 'value': casas.exclude(servico=None).count(), 'color': '#91e8e1'}, {'label': _(u"Utilizam serviços"),
{'label': _(u"Não utilizam serviços"), 'value': casas.filter(servico=None).count(), 'color': '#f7a35c'}, 'value': casas.exclude(servico=None).count(),
'color': '#91e8e1'},
{'label': _(u"Não utilizam serviços"),
'value': casas.filter(servico=None).count(),
'color': '#f7a35c'},
] ]
} }
@ -160,43 +168,52 @@ def chart_performance(request):
@login_required @login_required
def report_sem_convenio(request): def report_sem_convenio(request):
modo = request.GET.get('modo', None) modo = request.GET.get('modo', None)
format = request.GET.get('f', 'pdf') fmt = request.GET.get('f', 'pdf')
sc = sem_convenio() sc = sem_convenio()
if modo == 'H': if modo == 'H':
casas = sc['hospedagem'] casas = sc['hospedagem']
titulo = _(u"Casas sem convenio que utilizam algum serviço de hospedagem") titulo = _(u"Casas sem convenio que utilizam algum serviço de "
u"hospedagem")
elif modo == 'R': elif modo == 'R':
casas = sc['registro'] casas = sc['registro']
titulo = _(u"Casas sem convenio que utilizam somente serviço de registro") titulo = _(u"Casas sem convenio que utilizam somente serviço de "
u"registro")
else: else:
casas = sc['total'] casas = sc['total']
titulo = _(u"Casas sem convenio que utilizam algum serviço de registro e/ou hospedagem") titulo = _(u"Casas sem convenio que utilizam algum serviço de registro "
u"e/ou hospedagem")
if format == 'csv': if fmt == 'csv':
response = HttpResponse(content_type='text/csv') response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=casas.csv' response['Content-Disposition'] = 'attachment; filename=casas.csv'
writer = csv.writer(response) writer = csv.writer(response)
writer.writerow([titulo.encode('utf8')]) writer.writerow([titulo.encode('utf8')])
writer.writerow([u'']) writer.writerow([u''])
writer.writerow([u'casa', u'uf', u'gerente', u'serviços'.encode('utf8')]) writer.writerow([u'casa', u'uf', u'gerentes',
u'serviços'.encode('utf8')])
for casa in casas: for casa in casas:
writer.writerow([ writer.writerow([
casa.nome.encode('utf8'), casa.nome.encode('utf8'),
casa.municipio.uf.sigla.encode('utf8'), casa.municipio.uf.sigla.encode('utf8'),
casa.gerente_contas.nome_completo.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'), (u', '.join(casa.servico_set.filter(
data_desativacao__isnull=True).values_list(
'tipo_servico__nome', flat=True))).encode('utf8'),
]) ])
return response return response
elif format == 'json': elif fmt == 'json':
data = { data = {
'titulo': titulo, 'titulo': titulo,
'casas': [ 'casas': [
{'nome': casa.nome, {'nome': casa.nome,
'uf': casa.municipio.uf.sigla, 'uf': casa.municipio.uf.sigla,
'gerente': casa.gerente_contas.nome_completo, 'gerentes': list(casa.gerentes_interlegis.all().values_list(
'servicos': list(casa.servico_set.filter(data_desativacao__isnull=True).values_list('tipo_servico__nome', flat=True))} '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 for casa in casas
] ]
} }

103
sigi/apps/metas/views.py

@ -25,6 +25,7 @@ from sigi.apps.servicos.models import TipoServico
from sigi.apps.utils import to_ascii from sigi.apps.utils import to_ascii
from sigi.settings import MEDIA_ROOT, STATIC_URL from sigi.settings import MEDIA_ROOT, STATIC_URL
from sigi.shortcuts import render_to_pdf from sigi.shortcuts import render_to_pdf
from sigi.apps.servidores.models import Servidor
JSON_FILE_NAME = os.path.join(MEDIA_ROOT, 'apps/metas/map_data.json') JSON_FILE_NAME = os.path.join(MEDIA_ROOT, 'apps/metas/map_data.json')
@ -75,11 +76,15 @@ def mapa(request):
[(x.sigla, x.sigla, x.nome, True) [(x.sigla, x.sigla, x.nome, True)
for x in TipoServico.objects.all()]), for x in TipoServico.objects.all()]),
("convenios", _(u'Por Casas conveniadas'), ("convenios", _(u'Por Casas conveniadas'),
[(x.sigla, 'convenio_' + x.sigla, _(u'ao %(projeto)s') % {'projeto': x.sigla}, x.sigla == 'PML') [(x.sigla,
for x in projetos]), # Apenas o ultimo #hardcoded #fixme 'convenio_' + x.sigla,
_(u'ao {projeto}').format(projeto=x.sigla),
x.sigla == 'PML') for x in projetos]),
("equipadas", _(u'Por Casas equipadas'), ("equipadas", _(u'Por Casas equipadas'),
[(x.sigla, 'equip_' + x.sigla, _(u'pelo %(projeto)s') % {'projeto': x.sigla}, False) [(x.sigla,
for x in projetos]), 'equip_' + x.sigla,
_(u'pelo {projeto}').format(projeto=x.sigla),
False) for x in projetos]),
("diagnosticos", _(u'Por Diagnósticos'), ("diagnosticos", _(u'Por Diagnósticos'),
[('A', 'diagnostico_A', 'Em andamento', False), [('A', 'diagnostico_A', 'Em andamento', False),
('P', 'diagnostico_P', 'Publicados', True)]), ('P', 'diagnostico_P', 'Publicados', True)]),
@ -91,10 +96,12 @@ def mapa(request):
for x in UnidadeFederativa.objects.all()]), for x in UnidadeFederativa.objects.all()]),
("gerente", _(u'Por gerente de relacionamento'), ("gerente", _(u'Por gerente de relacionamento'),
[("", 'gerente_', _(u"Sem gerente"), False)] + [("", 'gerente_', _(u"Sem gerente"), False)] +
[(x.gerente_contas.id, 'gerente_%s' % (x.gerente_contas.id,), [(g.id, 'gerente_{0}'.format(g.id),
"%s %s" % (x.gerente_contas.nome_completo.split()[0], x.gerente_contas.nome_completo.split()[-1]), False) _(u"{firstname} {lastname}").format(
for x in CasaLegislativa.objects.exclude(gerente_contas=None).select_related( firstname=g.nome_completo.split()[0],
'gerente_contas').distinct('gerente_contas__nome_completo').order_by('gerente_contas__nome_completo')]), lastname=g.nome_completo.split()[-1])
, False) for g in Servidor.objects.exclude(
casas_que_gerencia=None).order_by('nome_completo')]),
) )
return render(request, 'metas/mapa.html', {'filters': filters}) return render(request, 'metas/mapa.html', {'filters': filters})
@ -271,23 +278,26 @@ def get_params(request):
} }
def filtrar_casas(seit, convenios, equipadas, regioes, estados, diagnosticos, gerentes): def filtrar_casas(seit, convenios, equipadas, regioes, estados, diagnosticos,
gerentes):
''' Filtrar Casas que atendem aos parâmetros de pesquisa ''' ''' Filtrar Casas que atendem aos parâmetros de pesquisa '''
qServico = Q(servico__tipo_servico__sigla__in=seit) qServico = Q(servico__tipo_servico__sigla__in=seit)
qConvenio = Q(convenio__projeto__sigla__in=convenios) qConvenio = Q(convenio__projeto__sigla__in=convenios)
qEquipada = Q(convenio__projeto__sigla__in=equipadas, convenio__equipada=True) qEquipada = Q(convenio__projeto__sigla__in=equipadas,
convenio__equipada=True)
qRegiao = Q(municipio__uf__regiao__in=regioes) qRegiao = Q(municipio__uf__regiao__in=regioes)
qEstado = Q(municipio__uf__sigla__in=estados) qEstado = Q(municipio__uf__sigla__in=estados)
if gerentes: if gerentes:
qGerente = Q(gerente_contas_id__in=gerentes) qGerente = Q(gerentes_interlegis__id__in=gerentes)
else: else:
qGerente = Q() qGerente = Q()
if diagnosticos: if diagnosticos:
qDiagnostico = Q(diagnostico__publicado__in=[p == 'P' for p in diagnosticos]) qDiagnostico = Q(diagnostico__publicado__in=[p == 'P'
for p in diagnosticos])
else: else:
qDiagnostico = Q() qDiagnostico = Q()
@ -296,7 +306,8 @@ def filtrar_casas(seit, convenios, equipadas, regioes, estados, diagnosticos, ge
if seit or convenios or equipadas or diagnosticos: if seit or convenios or equipadas or diagnosticos:
casas = casas.filter(qServico | qConvenio | qEquipada | qDiagnostico) casas = casas.filter(qServico | qConvenio | qEquipada | qDiagnostico)
else: else:
casas = casas.filter(Q(servico=None) & Q(convenio=None) & Q(diagnostico=None)) casas = casas.filter(Q(servico=None) & Q(convenio=None) &
Q(diagnostico=None))
return casas return casas
@ -351,7 +362,7 @@ def parliament_summary(parliament):
'lng': str(parliament.municipio.longitude), 'lng': str(parliament.municipio.longitude),
'estado': parliament.municipio.uf.sigla, 'estado': parliament.municipio.uf.sigla,
'regiao': parliament.municipio.uf.regiao, 'regiao': parliament.municipio.uf.regiao,
'gerente': (str(parliament.gerente_contas.id) if parliament.gerente_contas else ''), 'gerentes': [str(g.id) for g in parliament.gerentes_interlegis.all()],
'diagnosticos': [], 'diagnosticos': [],
'seit': [], 'seit': [],
'convenios': [], 'convenios': [],
@ -359,45 +370,61 @@ def parliament_summary(parliament):
'info': [] 'info': []
} }
if parliament.gerente_contas: if parliament.gerentes_interlegis.exists():
summary['info'].append(_(u"Gerente de relacionamento: %s") % parliament.gerente_contas.nome_completo) summary['info'].append(_(u"Gerentes Interlegis: {lista}").format(
lista=parliament.lista_gerentes(fmt='lista')))
for sv in parliament.servico_set.filter(data_desativacao=None): for sv in parliament.servico_set.filter(data_desativacao=None):
summary['info'].append( summary['info'].append(
_(u"%(name)s ativado em %(date)s") % dict( _(u"{name} ativado em {date}").format(
name=sv.tipo_servico.nome, name=sv.tipo_servico.nome,
date=sv.data_ativacao.strftime('%d/%m/%Y') if sv.data_ativacao else _(u'<sem data de ativação>')) + date=sv.data_ativacao.strftime('%d/%m/%Y') if sv.data_ativacao
" <a href='%s' target='_blank'><img src='%simg/link.gif' alt='link'></a>" % (sv.url, STATIC_URL)) else _(u'<sem data de ativação>')) +
(u" <a href='{0}' target='_blank'><img src='{1}img/link.gif' "
u"alt='link'></a>").format(sv.url, STATIC_URL))
summary['seit'].append(sv.tipo_servico.sigla) summary['seit'].append(sv.tipo_servico.sigla)
for cv in parliament.convenio_set.all(): for cv in parliament.convenio_set.all():
if (cv.data_retorno_assinatura is None) and (cv.equipada and cv.data_termo_aceite is not None): if ((cv.data_retorno_assinatura is None) and
summary['info'].append(_(u"Equipada em %(date)s pelo %(project)s") % dict( (cv.equipada and cv.data_termo_aceite is not None)):
date=cv.data_termo_aceite.strftime('%d/%m/%Y'), summary['info'].append(
project=cv.projeto.sigla)) _(u"Equipada em {date} pelo {project}").format(
date=cv.data_termo_aceite.strftime('%d/%m/%Y'),
project=cv.projeto.sigla))
summary['equipadas'].append(cv.projeto.sigla) summary['equipadas'].append(cv.projeto.sigla)
elif cv.data_retorno_assinatura is None: elif cv.data_retorno_assinatura is None:
summary['info'].append(_(u"Adesão ao projeto %(project)s, em %(date)s") % dict( summary['info'].append(
project=cv.projeto.sigla, _(u"Adesão ao projeto {project}, em {date}").format(
date=cv.data_adesao)) project=cv.projeto.sigla, date=cv.data_adesao))
summary['convenios'].append(cv.projeto.sigla) summary['convenios'].append(cv.projeto.sigla)
if (cv.data_retorno_assinatura is not None) and not (cv.equipada and cv.data_termo_aceite is not None): if ((cv.data_retorno_assinatura is not None) and not
summary['info'].append(_(u"Conveniada ao %(project)s em %(date)s") % dict( (cv.equipada and cv.data_termo_aceite is not None)):
project=cv.projeto.sigla, summary['info'].append(
date=cv.data_retorno_assinatura.strftime('%d/%m/%Y'))) _(u"Conveniada ao %(project)s em %(date)s").format(
project=cv.projeto.sigla,
date=cv.data_retorno_assinatura.strftime('%d/%m/%Y')))
summary['convenios'].append(cv.projeto.sigla) summary['convenios'].append(cv.projeto.sigla)
if (cv.data_retorno_assinatura is not None) and (cv.equipada and cv.data_termo_aceite is not None): if ((cv.data_retorno_assinatura is not None) and
summary['info'].append(_(u"Conveniada ao %(project)s em %(date)s e equipada em %(equipped_date)s") % dict( (cv.equipada and cv.data_termo_aceite is not None)):
project=cv.projeto.sigla, summary['info'].append(
date=cv.data_retorno_assinatura.strftime('%d/%m/%Y'), _(u"Conveniada ao {project} em {date} e equipada em "
equipped_date=cv.data_termo_aceite.strftime('%d/%m/%Y'))) u"{equipped_date}").format(
project=cv.projeto.sigla,
date=cv.data_retorno_assinatura.strftime('%d/%m/%Y'),
equipped_date=cv.data_termo_aceite.strftime('%d/%m/%Y')))
summary['equipadas'].append(cv.projeto.sigla) summary['equipadas'].append(cv.projeto.sigla)
summary['convenios'].append(cv.projeto.sigla) summary['convenios'].append(cv.projeto.sigla)
for dg in parliament.diagnostico_set.all(): for dg in parliament.diagnostico_set.all():
summary['diagnosticos'].append('P' if dg.publicado else 'A') summary['diagnosticos'].append('P' if dg.publicado else 'A')
summary['info'].append(_(u'Diagnosticada no período de %(initial_date)s a %(final_date)s') % dict( summary['info'].append(
initial_date=dg.data_visita_inicio.strftime('%d/%m/%Y') if dg.data_visita_inicio is not None else _(u"<sem data de início>"), _(u"Diagnosticada no período de {initial_date} "
final_date=dg.data_visita_fim.strftime('%d/%m/%Y') if dg.data_visita_fim else _(u"<sem data de término>"))) u"a {final_date}").format(
initial_date=dg.data_visita_inicio.strftime('%d/%m/%Y')
if dg.data_visita_inicio is not None
else _(u"<sem data de início>"),
final_date=dg.data_visita_fim.strftime('%d/%m/%Y')
if dg.data_visita_fim
else _(u"<sem data de término>")))
return summary return summary

17
sigi/apps/ocorrencias/admin.py

@ -63,12 +63,19 @@ class OcorrenciaChangeList(ChangeList):
class OcorrenciaAdmin(BaseModelAdmin): class OcorrenciaAdmin(BaseModelAdmin):
list_display = ('data_criacao', 'casa_legislativa', 'get_municipio', 'get_uf', 'assunto', 'prioridade', 'status', 'data_modificacao', 'setor_responsavel',) list_display = ('data_criacao', 'casa_legislativa', 'get_municipio',
list_filter = (OcorrenciaListFilter, 'status', 'prioridade', 'categoria__nome', 'setor_responsavel__nome', 'casa_legislativa__gerente_contas',) 'get_uf', 'assunto', 'prioridade', 'status',
search_fields = ('casa_legislativa__search_text', 'assunto', 'servidor_registro__nome_completo', 'descricao', 'resolucao', 'ticket',) 'data_modificacao', 'setor_responsavel',)
list_filter = (OcorrenciaListFilter, 'status', 'prioridade',
'categoria__nome', 'setor_responsavel__nome',
'casa_legislativa__gerentes_interlegis',)
search_fields = ('casa_legislativa__search_text', 'assunto',
'servidor_registro__nome_completo', 'descricao',
'resolucao', 'ticket',)
date_hierarchy = 'data_criacao' date_hierarchy = 'data_criacao'
fields = ('casa_legislativa', 'categoria', 'tipo_contato', 'assunto', 'status', 'prioridade', 'ticket', 'descricao', 'servidor_registro', fields = ('casa_legislativa', 'categoria', 'tipo_contato', 'assunto',
'setor_responsavel', 'resolucao', ) 'status', 'prioridade', 'ticket', 'descricao',
'servidor_registro', 'setor_responsavel', 'resolucao', )
readonly_fields = ('servidor_registro', 'setor_responsavel', ) readonly_fields = ('servidor_registro', 'setor_responsavel', )
inlines = (ComentarioViewInline, ComentarioInline, AnexosInline, ) inlines = (ComentarioViewInline, ComentarioInline, AnexosInline, )
raw_id_fields = ('casa_legislativa', ) raw_id_fields = ('casa_legislativa', )

4
sigi/apps/ocorrencias/filters.py

@ -24,4 +24,6 @@ class OcorrenciaListFilter(admin.SimpleListFilter):
elif self.value() == 'M': elif self.value() == 'M':
return queryset.filter(servidor_registro=servidor) return queryset.filter(servidor_registro=servidor)
elif self.value() == 'G': elif self.value() == 'G':
return queryset.filter(casa_legislativa__gerente_contas=servidor) return queryset.filter(
casa_legislativa__gerentes_interlegis=servidor
)

10
sigi/apps/ocorrencias/templates/ocorrencias/ocorrencia_snippet.html

@ -24,9 +24,13 @@
{% if ocorrencia.ticket %} {% if ocorrencia.ticket %}
<p><a href="{{ ocorrencia.get_ticket_url }}" target="_blank">{% trans "Ticket no suporte #" %}{{ ocorrencia.ticket|safe }}</a></p> <p><a href="{{ ocorrencia.get_ticket_url }}" target="_blank">{% trans "Ticket no suporte #" %}{{ ocorrencia.ticket|safe }}</a></p>
{% endif %} {% endif %}
<p>{% trans "Gerente de contas:" %} <p>{% trans "Gerentes Interlegis:" %}
<a href="{{ url_painel }}?type=servidor&id={{ ocorrencia.casa_legislativa.gerente_contas_id|safe }}"> {% for g in ocorrencia.casa_legislativa.gerentes_interlegis.all %}
{{ ocorrencia.casa_legislativa.gerente_contas }}</a></p> <a href="{{ url_painel }}?type=servidor&id={{ g.id|safe }}">
{{ g.nome_completo }}</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% trans 'Prioridade' %}: {% trans 'Prioridade' %}:
<div class="btn-group btn-group-xs" data-toggle="buttons" role="group" aria-label="..."> <div class="btn-group btn-group-xs" data-toggle="buttons" role="group" aria-label="...">
{% for id, name in PRIORITY_CHOICES %} {% for id, name in PRIORITY_CHOICES %}

73
sigi/apps/ocorrencias/views.py

@ -17,62 +17,85 @@ from django.utils.html import escape
@login_required @login_required
def painel_ocorrencias(request): def painel_ocorrencias(request):
type = request.GET.get('type', None) tipo = request.GET.get('type', None)
id = request.GET.get('id', None) id = request.GET.get('id', None)
painel = request.GET.get('painel', None) painel = request.GET.get('painel', None)
data = {} data = {}
if type is None or type == 'error': if tipo is None or tipo == 'error':
type = 'servidor' tipo = 'servidor'
u = get_object_or_404(Servidor, user=request.user) u = get_object_or_404(Servidor, user=request.user)
id = u.pk id = u.pk
if id is None: if id is None:
raise Http404("id não definido") raise Http404("id não definido")
if type == 'casa': if tipo == 'casa':
casa = get_object_or_404(CasaLegislativa, pk=id) casa = get_object_or_404(CasaLegislativa, pk=id)
ocorrencias = Ocorrencia.objects.filter(casa_legislativa=casa) ocorrencias = casa.ocorrencia_set.all()
panel_title = "%s, %s" % (casa.nome, casa.municipio.uf.sigla) panel_title = u"{casa}, {uf}".format(
elif type == 'servidor': casa=casa.nome,
uf=casa.municipio.uf.sigla
)
elif tipo == 'servidor':
servidor = get_object_or_404(Servidor, pk=id) servidor = get_object_or_404(Servidor, pk=id)
panel_title = servidor.nome_completo panel_title = servidor.nome_completo
paineis = {'gerente': 'Minhas casas', 'servico': 'Meu setor', 'timeline': 'Comentados por mim'} paineis = {'gerente': u"Minhas casas", 'servico': u"Meu setor",
'timeline': u"Comentados por mim"}
if painel is None: if painel is None:
if CasaLegislativa.objects.filter(gerente_contas=servidor).count() > 0: if CasaLegislativa.objects.filter(
gerentes_interlegis=servidor).count() > 0:
painel = 'gerente' painel = 'gerente'
elif Ocorrencia.objects.filter(setor_responsavel=servidor.servico).count() > 0: elif Ocorrencia.objects.filter(
setor_responsavel=servidor.servico).count() > 0:
painel = 'servico' painel = 'servico'
else: else:
painel = 'timeline' painel = 'timeline'
data.update({'paineis': paineis, 'painel': painel, 'servidor': servidor}) data.update({'paineis': paineis, 'painel': painel,
'servidor': servidor})
if painel == 'gerente': if painel == 'gerente':
ocorrencias = Ocorrencia.objects.filter(casa_legislativa__gerente_contas=servidor) ocorrencias = Ocorrencia.objects.filter(
casa_legislativa__gerentes_interlegis=servidor)
elif painel == 'servico': elif painel == 'servico':
ocorrencias = Ocorrencia.objects.filter(setor_responsavel_id=servidor.servico_id) ocorrencias = Ocorrencia.objects.filter(
setor_responsavel_id=servidor.servico_id)
else: else:
ocorrencias = (Ocorrencia.objects.filter(servidor_registro=servidor) | ocorrencias = (
Ocorrencia.objects.filter(comentarios__usuario=servidor)) Ocorrencia.objects.filter(servidor_registro=servidor) |
elif type == 'servico': Ocorrencia.objects.filter(comentarios__usuario=servidor)
)
elif tipo == 'servico':
servico = get_object_or_404(Servico, pk=id) servico = get_object_or_404(Servico, pk=id)
ocorrencias = Ocorrencia.objects.filter(setor_responsavel_id=id) ocorrencias = servico.ocorrencia_set.all()
panel_title = "%s - %s" % (servico.sigla, servico.nome) panel_title = _(u"{sigla} - {nome}").format(
sigla=servico.sigla, nome=servico.nome)
ocorrencias = ocorrencias.filter(status__in=[1,2]) ocorrencias = ocorrencias.filter(status__in=[1, 2])
ocorrencias = ocorrencias.order_by('prioridade', '-data_modificacao') ocorrencias = ocorrencias.order_by('prioridade', '-data_modificacao')
ocorrencias = ocorrencias.select_related('casa_legislativa', 'categoria', 'tipo_contato', 'servidor_registro', 'setor_responsavel', ocorrencias = ocorrencias.select_related(
'casa_legislativa__gerente_contas') 'casa_legislativa', 'categoria', 'tipo_contato', 'servidor_registro',
ocorrencias = ocorrencias.prefetch_related('comentarios', 'comentarios__usuario', 'comentarios__encaminhar_setor', 'setor_responsavel', 'casa_legislativa__gerentes_interlegis'
'casa_legislativa__municipio', 'casa_legislativa__municipio__uf', 'anexo_set') )
ocorrencias = ocorrencias.prefetch_related(
'comentarios', 'comentarios__usuario', 'comentarios__encaminhar_setor',
'casa_legislativa__municipio', 'casa_legislativa__municipio__uf',
'anexo_set'
)
ocorrencias = ocorrencias.annotate(total_anexos=Count('anexo')) ocorrencias = ocorrencias.annotate(total_anexos=Count('anexo'))
data.update({'ocorrencias': ocorrencias, 'panel_title': panel_title, 'comentario_form': ComentarioForm(), data.update(
'ocorrencia_form': OcorrenciaForm(), 'PRIORITY_CHOICES': Ocorrencia.PRIORITY_CHOICES}) {'ocorrencias': ocorrencias,
'panel_title': panel_title,
'comentario_form': ComentarioForm(),
'ocorrencia_form': OcorrenciaForm(),
'PRIORITY_CHOICES': Ocorrencia.PRIORITY_CHOICES
}
)
return render(request, 'ocorrencias/painel.html', data) return render(request, 'ocorrencias/painel.html', data)

Loading…
Cancel
Save