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'),
('cargo', 'funcao', 'setor'),
('tempo_de_servico', 'ult_alteracao'),
('desativado', 'observacoes'),
)
}),)
readonly_fields = ('ult_alteracao',)
@ -63,44 +64,75 @@ class FuncionariosInline(admin.StackedInline):
inlines = (TelefonesInline,)
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
fieldsets = (
(None, {'fields': (('link_convenio', 'num_processo_sf', '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',),
('get_tramitacoes', 'get_anexos', 'get_equipamentos',),
)}
),
(None, {'fields': (
('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',),
('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
can_delete = False
def get_tramitacoes(self, obj):
return '<br/>'.join([t.__unicode__() for t in obj.tramitacao_set.all()])
get_tramitacoes.short_description = _(u'Tramitações')
get_tramitacoes.allow_tags = True
def get_anexos(self, obj):
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 has_add_permission(self, request):
return False
# def get_tramitacoes(self, obj):
# return '<br/>'.join([t.__unicode__() for t in obj.tramitacao_set.all()])
#
# get_tramitacoes.short_description = _(u'Tramitações')
# get_tramitacoes.allow_tags = True
#
# def get_anexos(self, obj):
# 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 '<br/>'.join([e.__unicode__() for e in obj.equipamentoprevisto_set.all()])
return u'<p class="label label-{label}">{status}</p>'.format(label=label, status=status)
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):
if obj.pk is None:
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 = url + '?_popup=1'
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.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):
model = Legislatura
@ -191,10 +231,10 @@ class OcorrenciaInline(admin.TabularInline):
link_editar.allow_tags = True
class GerentesContasFilter(admin.filters.RelatedFieldListFilter):
class GerentesInterlegisFilter(admin.filters.RelatedFieldListFilter):
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()
self.lookup_choices = [(x.id, x) for x in gerentes]
@ -259,29 +299,33 @@ class ServicoFilter(admin.SimpleListFilter):
class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin):
form = CasaLegislativaForm
actions = ['adicionar_casas', ]
inlines = (TelefonesInline, PresidenteInline, FuncionariosInline, ConveniosInline, LegislaturaInline,
DiagnosticoInline, BemInline, ServicoInline, PlanoDiretorInline, OcorrenciaInline,)
list_display = ('nome', 'get_uf', 'get_gerente_contas', 'get_convenios',
inlines = (TelefonesInline, PresidenteInline, FuncionariosInline,
ConveniosInline, LegislaturaInline, DiagnosticoInline, BemInline,
ServicoInline, PlanoDiretorInline, OcorrenciaInline,)
list_display = ('nome', 'get_uf', 'get_gerentes', 'get_convenios',
'get_servicos')
list_display_links = ('nome',)
list_filter = ('tipo', ('gerente_contas', GerentesContasFilter),
list_filter = ('tipo', ('gerentes_interlegis', GerentesInterlegisFilter),
'municipio__uf__nome', ConvenioFilter, ServicoFilter,
'inclusao_digital',)
ordering = ('municipio__uf__nome', 'nome')
queryset = queryset_ascii
fieldsets = (
(None, {
'fields': ('tipo', 'nome', 'cnpj', 'num_parlamentares', 'gerente_contas')
'fields': ('tipo', 'nome', 'cnpj', 'num_parlamentares',
'gerentes_interlegis')
}),
(_(u'Endereço'), {
'fields': ('data_instalacao', 'logradouro', 'bairro',
'municipio', 'cep', 'ult_alt_endereco'),
}),
(_(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'), {
'fields': ('observacoes', 'horario_funcionamento', 'foto', 'recorte'),
'fields': ('observacoes', 'horario_funcionamento', 'foto',
'recorte'),
}),
)
raw_id_fields = ('municipio',)
@ -289,6 +333,7 @@ class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin):
search_fields = ('search_text', 'cnpj', 'bairro', 'logradouro',
'cep', 'municipio__nome', 'municipio__uf__nome',
'municipio__codigo_ibge', 'pagina_web', 'observacoes')
filter_horizontal = ('gerentes_interlegis',)
def get_uf(self, obj):
return obj.municipio.uf.nome
@ -296,10 +341,10 @@ class CasaLegislativaAdmin(ImageCroppingMixin, BaseModelAdmin):
get_uf.short_description = _(u'Unidade da Federação')
get_uf.admin_order_field = 'municipio__uf__nome'
def get_gerente_contas(self, obj):
return obj.gerente_contas
get_gerente_contas.short_description = _(u'Gerente de contas')
def get_gerentes(self, obj):
return obj.lista_gerentes
get_gerentes.short_description = _(u'Gerente Interlegis')
get_gerentes.allow_tags = True
def get_convenios(self, obj):
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__'
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)
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):
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
for reg in reader:
try:
municipio = Municipio.objects.get(codigo_ibge=reg['cod_municipio'])
municipio = Municipio.objects.get(
codigo_ibge=reg['cod_municipio']
)
except Municipio.DoesNotExist:
self.stdout.write(u"(Linha %s): não existe Município com código IBGE '%s'" %
(reader.line_num, reg['cod_municipio'],))
self.stdout.write(u"{linha}: não existe Município com "
u"código IBGE {ibge}'".format(
linha=reader.line_num,
ibge=reg['cod_municipio'])
)
erros = erros + 1
continue
try:
gerente = Servidor.objects.get(user__username=reg['user_id'])
gerente = Servidor.objects.get(
user__username=reg['user_id']
)
except Servidor.DoesNotExist:
self.stdout.write(u"(Linha %s): não existe Servidor com userid '%s'" %
(reader.line_num, reg['user_id'],))
self.stdout.write(u"({linha}): não existe Servidor com "
u"userid {userid}".format(
linha=reader.line_num,
userid=reg['user_id'])
)
erros = erros + 1
continue
for casa in municipio.casalegislativa_set.filter(tipo__sigla__in=['AL', 'CM']):
casa.gerente_contas = gerente
for casa in municipio.casalegislativa_set.filter(
tipo__sigla__in=['AL', 'CM']):
casa.gerentes_interlegis.add(gerente)
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
from string import ascii_uppercase
from unicodedata import normalize
from django.utils.translation import ugettext as _
from django.contrib.contenttypes import generic
from django.db import models
from image_cropping import ImageRatioField
@ -20,12 +20,8 @@ class TipoCasaLegislativa(models.Model):
Câmara Distrital ou Legislativo Federal
"""
sigla = models.CharField(
max_length=5
)
nome = models.CharField(
max_length=100
)
sigla = models.CharField(_(u"Sigla"), max_length=5)
nome = models.CharField(_(u"Nome"), max_length=100)
def __unicode__(self):
return self.nome
@ -37,77 +33,125 @@ class CasaLegislativa(models.Model):
"""
INCLUSAO_DIGITAL_CHOICES = (
('NAO PESQUISADO', u'Não pesquisado'),
('NAO POSSUI PORTAL', u'Não possui portal'),
('PORTAL MODELO', u'Possui Portal Modelo'),
('OUTRO PORTAL', u'Possui outro portal'),
('NAO PESQUISADO', _(u'Não pesquisado')),
('NAO POSSUI PORTAL', _(u'Não possui portal')),
('PORTAL MODELO', _(u'Possui Portal Modelo')),
('OUTRO PORTAL', _(u'Possui outro portal')),
)
nome = models.CharField(
_(u"Nome"),
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
search_text = SearchField(field_names=['nome'])
# search_text.projeto_filter = True
tipo = models.ForeignKey(TipoCasaLegislativa, verbose_name="Tipo")
cnpj = models.CharField('CNPJ', max_length=32, blank=True)
observacoes = models.TextField(u'observações', blank=True)
tipo = models.ForeignKey(TipoCasaLegislativa, verbose_name=_(u"Tipo"))
cnpj = models.CharField(_(u"CNPJ"), max_length=32, blank=True)
observacoes = models.TextField(_(u'observações'), blank=True)
horario_funcionamento = models.CharField(
u"Horário de funcionamento da Casa Legislativa",
_(u"Horário de funcionamento da Casa Legislativa"),
max_length=100,
blank=True,
)
# 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
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
logradouro = models.CharField(
_(u"Logradouro"),
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(
'contatos.Municipio',
verbose_name='município'
verbose_name=_(u'Município')
)
# municipio.uf_filter = True
cep = models.CharField(max_length=32)
email = models.EmailField('e-mail', max_length=128, blank=True)
cep = models.CharField(_(u"CEP"), max_length=32)
email = models.EmailField(_(u'E-mail'), max_length=128, blank=True)
pagina_web = models.URLField(
u'página web',
help_text='Exemplo: <em>http://www.camarapains.mg.gov.br</em>.',
_(u'Página web'),
help_text=_(u'Exemplo: <em>http://www.camarapains.mg.gov.br</em>.'),
blank=True,
)
inclusao_digital = models.CharField(max_length=30, choices=INCLUSAO_DIGITAL_CHOICES, 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)
inclusao_digital = models.CharField(
_(u"Inclusão digital"),
max_length=30,
choices=INCLUSAO_DIGITAL_CHOICES,
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')
foto = models.ImageField(
_(u"Foto"),
upload_to='imagens/casas',
width_field='foto_largura',
height_field='foto_altura',
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_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:
ordering = ('nome',)
unique_together = ('municipio', 'tipo')
verbose_name = 'Casa Legislativa'
verbose_name_plural = 'Casas Legislativas'
verbose_name = _(u'Casa Legislativa')
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
def num_parlamentares(self):
@ -276,42 +320,79 @@ class Funcionario(models.Model):
"""
SETOR_CHOICES = [
("presidente", "Presidente"),
("contato_interlegis", "Contato Interlegis"),
("infraestrutura_fisica", "Infraestrutura Física"),
("estrutura_de_ti", "Estrutura de TI"),
("organizacao_do_processo_legislativo", "Organização do Processo Legislativo"),
("producao_legislativa", "Produção Legislativa"),
("estrutura_de_comunicacao_social", "Estrutura de Comunicação Social"),
("estrutura_de_recursos_humanos", "Estrutura de Recursos Humanos"),
("gestao", "Gestão"),
("outros", "Outros"),
("presidente", _(u"Presidente")),
("contato_interlegis", _(u"Contato Interlegis")),
("infraestrutura_fisica", _(u"Infraestrutura Física")),
("estrutura_de_ti", _(u"Estrutura de TI")),
("organizacao_do_processo_legislativo",
_(u"Organização do Processo Legislativo")),
("producao_legislativa", _(u"Produção Legislativa")),
("estrutura_de_comunicacao_social",
_(u"Estrutura de Comunicação Social")),
("estrutura_de_recursos_humanos", _(u"Estrutura de Recursos Humanos")),
("gestao", _(u"Gestão")),
("outros", _(u"Outros")),
]
SEXO_CHOICES = [
("M", "Masculino"),
("F", "Feminino")
("M", _(u"Masculino")),
("F", _(u"Feminino"))
]
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
sexo = models.CharField(max_length=1, choices=SEXO_CHOICES, default="M")
data_nascimento = models.DateField(u"Data de nascimento", blank=True,
null=True)
nota = models.CharField(max_length=70, null=True, blank=True)
email = models.CharField('e-mail', max_length=75, blank=True)
telefones = generic.GenericRelation('contatos.Telefone')
sexo = models.CharField(
_(u"Sexo"),
max_length=1,
choices=SEXO_CHOICES,
default="M"
)
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')
cargo = models.CharField(max_length=100, null=True, blank=True)
funcao = models.CharField(u'função', max_length=100, null=True, blank=True)
setor = models.CharField(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)
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
)
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:
ordering = ('nome',)
verbose_name = 'contato da Casa Legislativa'
verbose_name_plural = 'contatos da Casa Legislativa'
verbose_name = _(u'contato da Casa Legislativa')
verbose_name_plural = _(u'contatos da Casa Legislativa')
def __unicode__(self):
return self.nome

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

@ -5,6 +5,32 @@
{% block extrastyle %}
<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>
{{ block.super }}
{% endblock %}
@ -22,10 +48,18 @@
<div class="alert alert-danger">{{ e }}</div>
{% 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">
<ul class="object-tools pull-left nav nav-pills">
{% 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 %}
</ul>
</div>
@ -34,7 +68,7 @@
<div class="nav">
<ul class="object-tools pull-left nav nav-tabs">
{% 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 %}
</ul>
</div>
@ -44,7 +78,7 @@
<div class="nav">
<ul class="object-tools pull-left nav nav-pills">
{% 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 %}
</ul>
</div>
@ -54,7 +88,7 @@
<div class="nav">
<ul class="object-tools pull-left nav nav-pills">
{% 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 %}
</ul>
</div>
@ -64,7 +98,7 @@
<form action="" method="post" id="atribui_gerente_form">
{% csrf_token %}
{{ form }}
<input type="submit" name="_save" value="Atribuir" class="btn btn-default" />
<input type="submit" name="_save" class="btn btn-default"/>
</form>
{% endif %}
@ -85,7 +119,7 @@
<td>{{ casa.municipio.uf }}</td>
<td>{{ casa.municipio.microrregiao.mesorregiao }}</td>
<td>{{ casa.municipio.microrregiao.nome }}</td>
<td>{{ casa.gerente_contas }}</td>
<td>{{ casa.lista_gerentes|safe }}</td>
</tr>
{% endfor %}
</table>

2
sigi/apps/casas/test_casas.py

@ -14,4 +14,4 @@ def some_parliaments():
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 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,
CasasLegislativasLabelsSemPresidente)
from sigi.apps.contatos.models import UnidadeFederativa, Mesorregiao, Microrregiao
@ -421,6 +421,7 @@ def export_csv(request):
@login_required
def portfolio(request):
page = request.GET.get('page', 1)
tipo = request.GET.get('tipo', None)
regiao = request.GET.get('regiao', None)
uf_id = request.GET.get('uf', None)
meso_id = request.GET.get('meso', None)
@ -430,15 +431,12 @@ def portfolio(request):
data['errors'] = []
data['messages'] = []
data['regioes'] = UnidadeFederativa.REGIAO_CHOICES
data['tipos_casas'] = TipoCasaLegislativa.objects.all()
casas = None
gerente_contas = None
gerente = None
if request.method == 'POST':
form = PortfolioForm(data=request.POST)
if form.is_valid():
gerente_contas = form.cleaned_data['gerente_contas']
else:
data['errors'].append(_(u"Dados inválidos"))
if tipo:
data['tipo'] = tipo
if 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['mesorregioes'] = uf.mesorregiao_set.all()
data['microrregioes'] = mesorregiao.microrregiao_set.all()
data['form'] = PortfolioForm(_(u'Atribuir casas da microrregiao %s para') % (unicode(microrregiao),))
data['querystring'] = 'micro=%s' % (microrregiao.pk,)
casas = CasaLegislativa.objects.filter(municipio__microrregiao=microrregiao)
data['form'] = PortfolioForm(
_(u'Atribuir casas da microrregiao {name} para').format(
name=unicode(microrregiao))
)
data['querystring'] = 'micro={0}'.format(microrregiao.pk)
casas = CasaLegislativa.objects.filter(
municipio__microrregiao=microrregiao
)
elif meso_id:
mesorregiao = get_object_or_404(Mesorregiao, pk=meso_id)
uf = mesorregiao.uf
@ -463,38 +466,74 @@ def portfolio(request):
data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao)
data['mesorregioes'] = uf.mesorregiao_set.all()
data['microrregioes'] = mesorregiao.microrregiao_set.all()
data['form'] = PortfolioForm(_(u'Atribuir casas da mesorregiao %s para') % (unicode(mesorregiao),))
data['querystring'] = 'meso=%s' % (mesorregiao.pk,)
casas = CasaLegislativa.objects.filter(municipio__microrregiao__mesorregiao=mesorregiao)
data['form'] = PortfolioForm(
_(u'Atribuir casas da mesorregiao {name} para').format(
name=unicode(mesorregiao)))
data['querystring'] = 'meso={0}'.format(mesorregiao.pk)
casas = CasaLegislativa.objects.filter(
municipio__microrregiao__mesorregiao=mesorregiao
)
elif uf_id:
uf = get_object_or_404(UnidadeFederativa, pk=uf_id)
data['regiao'] = uf.regiao
data['uf_id'] = uf.pk
data['ufs'] = UnidadeFederativa.objects.filter(regiao=uf.regiao)
data['mesorregioes'] = uf.mesorregiao_set.all()
data['form'] = PortfolioForm(_(u'Atribuir casas do estado %s para') % (unicode(uf),))
data['querystring'] = 'uf=%s' % (uf.pk,)
data['form'] = PortfolioForm(
_(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)
elif regiao:
data['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['querystring'] = 'regiao=%s' % (regiao,)
data['form'] = PortfolioForm(
_(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)
if casas:
if gerente_contas:
count = casas.update(gerente_contas=gerente_contas)
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',
casas = casas.order_by('municipio__uf',
'municipio__microrregiao__mesorregiao',
'municipio__microrregiao', 'municipio')
casas.prefetch_related('municipio', 'municipio__uf', 'municipio__microrregiao',
'municipio__microrregiao__mesorregiao', 'gerente_contas')
casas.prefetch_related('municipio', 'municipio__uf',
'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)
try:
@ -635,7 +674,7 @@ def painel_relacionamento(request):
snippet = request.GET.get('snippet', '')
seletor = request.GET.get('s', None)
servidor = request.GET.get('servidor', None)
format = request.GET.get('f', 'html')
fmt = request.GET.get('f', 'html')
if servidor is None:
gerente = request.user.servidor
@ -648,7 +687,7 @@ def painel_relacionamento(request):
casas = gerente.casas_que_gerencia.all()
if gerente is None or not casas.exists():
casas = CasaLegislativa.objects.exclude(gerente_contas=None)
casas = CasaLegislativa.objects.exclude(gerentes_interlegis=None)
gerente = None
tipos_servico = TipoServico.objects.all()
@ -677,7 +716,7 @@ def painel_relacionamento(request):
context['page_obj'] = pagina
if snippet == 'lista':
if format == 'csv':
if fmt == 'csv':
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=casas.csv'
writer = csv.writer(response)
@ -687,7 +726,7 @@ def painel_relacionamento(request):
_(u"Estado").encode('utf8'),
_(u"Mesorregião").encode('utf8'),
_(u"Microrregião").encode('utf8'),
_(u"Gerente de relacionamento").encode('utf8'),
_(u"Gerentes Interlegis").encode('utf8'),
_(u"Serviços").encode('utf8'),
])
for c in casas:
@ -697,7 +736,7 @@ def painel_relacionamento(request):
c.municipio.uf.sigla.encode('utf8'),
c.municipio.microrregiao.mesorregiao.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'),
])
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')}
),
(_(u'Datas'),
{'fields': ('data_adesao', 'data_retorno_assinatura',
{'fields': ('data_adesao', 'data_retorno_assinatura', 'duracao',
'data_termo_aceite', 'data_pub_diario',
'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 -*-
from datetime import datetime
#-*- coding: utf-8 -*-
import re
from datetime import datetime, date
from django.db import models
from django.utils.translation import ugettext as _
from sigi.apps.utils import SearchField
@ -58,6 +58,12 @@ class Convenio(models.Model):
blank=True,
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(
_(u'data da publicação no Diário Oficial'),
null=True,
@ -100,6 +106,58 @@ class Convenio(models.Model):
conveniada = 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):
self.conveniada = self.data_retorno_assinatura is not None
self.equipada = self.data_termo_aceite is not None
@ -112,10 +170,11 @@ class Convenio(models.Model):
def __unicode__(self):
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,
project=self.projeto.sigla,
date=self.data_retorno_assinatura)
date=self.data_retorno_assinatura,
status=self.get_status()))
else:
return _(u"Adesão ao projeto %(project)s, em %(date)s") % dict(
project=self.projeto.sigla,

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

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

49
sigi/apps/home/views.py

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

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.settings import MEDIA_ROOT, STATIC_URL
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')
@ -75,11 +76,15 @@ def mapa(request):
[(x.sigla, x.sigla, x.nome, True)
for x in TipoServico.objects.all()]),
("convenios", _(u'Por Casas conveniadas'),
[(x.sigla, 'convenio_' + x.sigla, _(u'ao %(projeto)s') % {'projeto': x.sigla}, x.sigla == 'PML')
for x in projetos]), # Apenas o ultimo #hardcoded #fixme
[(x.sigla,
'convenio_' + x.sigla,
_(u'ao {projeto}').format(projeto=x.sigla),
x.sigla == 'PML') for x in projetos]),
("equipadas", _(u'Por Casas equipadas'),
[(x.sigla, 'equip_' + x.sigla, _(u'pelo %(projeto)s') % {'projeto': x.sigla}, False)
for x in projetos]),
[(x.sigla,
'equip_' + x.sigla,
_(u'pelo {projeto}').format(projeto=x.sigla),
False) for x in projetos]),
("diagnosticos", _(u'Por Diagnósticos'),
[('A', 'diagnostico_A', 'Em andamento', False),
('P', 'diagnostico_P', 'Publicados', True)]),
@ -91,10 +96,12 @@ def mapa(request):
for x in UnidadeFederativa.objects.all()]),
("gerente", _(u'Por gerente de relacionamento'),
[("", 'gerente_', _(u"Sem gerente"), False)] +
[(x.gerente_contas.id, 'gerente_%s' % (x.gerente_contas.id,),
"%s %s" % (x.gerente_contas.nome_completo.split()[0], x.gerente_contas.nome_completo.split()[-1]), False)
for x in CasaLegislativa.objects.exclude(gerente_contas=None).select_related(
'gerente_contas').distinct('gerente_contas__nome_completo').order_by('gerente_contas__nome_completo')]),
[(g.id, 'gerente_{0}'.format(g.id),
_(u"{firstname} {lastname}").format(
firstname=g.nome_completo.split()[0],
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})
@ -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 '''
qServico = Q(servico__tipo_servico__sigla__in=seit)
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)
qEstado = Q(municipio__uf__sigla__in=estados)
if gerentes:
qGerente = Q(gerente_contas_id__in=gerentes)
qGerente = Q(gerentes_interlegis__id__in=gerentes)
else:
qGerente = Q()
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:
qDiagnostico = Q()
@ -296,7 +306,8 @@ def filtrar_casas(seit, convenios, equipadas, regioes, estados, diagnosticos, ge
if seit or convenios or equipadas or diagnosticos:
casas = casas.filter(qServico | qConvenio | qEquipada | qDiagnostico)
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
@ -351,7 +362,7 @@ def parliament_summary(parliament):
'lng': str(parliament.municipio.longitude),
'estado': parliament.municipio.uf.sigla,
'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': [],
'seit': [],
'convenios': [],
@ -359,45 +370,61 @@ def parliament_summary(parliament):
'info': []
}
if parliament.gerente_contas:
summary['info'].append(_(u"Gerente de relacionamento: %s") % parliament.gerente_contas.nome_completo)
if parliament.gerentes_interlegis.exists():
summary['info'].append(_(u"Gerentes Interlegis: {lista}").format(
lista=parliament.lista_gerentes(fmt='lista')))
for sv in parliament.servico_set.filter(data_desativacao=None):
summary['info'].append(
_(u"%(name)s ativado em %(date)s") % dict(
_(u"{name} ativado em {date}").format(
name=sv.tipo_servico.nome,
date=sv.data_ativacao.strftime('%d/%m/%Y') if sv.data_ativacao else _(u'<sem data de ativação>')) +
" <a href='%s' target='_blank'><img src='%simg/link.gif' alt='link'></a>" % (sv.url, STATIC_URL))
date=sv.data_ativacao.strftime('%d/%m/%Y') if sv.data_ativacao
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)
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):
summary['info'].append(_(u"Equipada em %(date)s pelo %(project)s") % dict(
date=cv.data_termo_aceite.strftime('%d/%m/%Y'),
project=cv.projeto.sigla))
if ((cv.data_retorno_assinatura is None) and
(cv.equipada and cv.data_termo_aceite is not None)):
summary['info'].append(
_(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)
elif cv.data_retorno_assinatura is None:
summary['info'].append(_(u"Adesão ao projeto %(project)s, em %(date)s") % dict(
project=cv.projeto.sigla,
date=cv.data_adesao))
summary['info'].append(
_(u"Adesão ao projeto {project}, em {date}").format(
project=cv.projeto.sigla, date=cv.data_adesao))
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):
summary['info'].append(_(u"Conveniada ao %(project)s em %(date)s") % dict(
project=cv.projeto.sigla,
date=cv.data_retorno_assinatura.strftime('%d/%m/%Y')))
if ((cv.data_retorno_assinatura is not None) and not
(cv.equipada and cv.data_termo_aceite is not None)):
summary['info'].append(
_(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)
if (cv.data_retorno_assinatura is not None) and (cv.equipada and cv.data_termo_aceite is not None):
summary['info'].append(_(u"Conveniada ao %(project)s em %(date)s e equipada em %(equipped_date)s") % dict(
project=cv.projeto.sigla,
date=cv.data_retorno_assinatura.strftime('%d/%m/%Y'),
equipped_date=cv.data_termo_aceite.strftime('%d/%m/%Y')))
if ((cv.data_retorno_assinatura is not None) and
(cv.equipada and cv.data_termo_aceite is not None)):
summary['info'].append(
_(u"Conveniada ao {project} em {date} e equipada em "
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['convenios'].append(cv.projeto.sigla)
for dg in parliament.diagnostico_set.all():
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(
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>")))
summary['info'].append(
_(u"Diagnosticada no período de {initial_date} "
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

17
sigi/apps/ocorrencias/admin.py

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

4
sigi/apps/ocorrencias/filters.py

@ -24,4 +24,6 @@ class OcorrenciaListFilter(admin.SimpleListFilter):
elif self.value() == 'M':
return queryset.filter(servidor_registro=servidor)
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 %}
<p><a href="{{ ocorrencia.get_ticket_url }}" target="_blank">{% trans "Ticket no suporte #" %}{{ ocorrencia.ticket|safe }}</a></p>
{% endif %}
<p>{% trans "Gerente de contas:" %}
<a href="{{ url_painel }}?type=servidor&id={{ ocorrencia.casa_legislativa.gerente_contas_id|safe }}">
{{ ocorrencia.casa_legislativa.gerente_contas }}</a></p>
<p>{% trans "Gerentes Interlegis:" %}
{% for g in ocorrencia.casa_legislativa.gerentes_interlegis.all %}
<a href="{{ url_painel }}?type=servidor&id={{ g.id|safe }}">
{{ g.nome_completo }}</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% trans 'Prioridade' %}:
<div class="btn-group btn-group-xs" data-toggle="buttons" role="group" aria-label="...">
{% for id, name in PRIORITY_CHOICES %}

73
sigi/apps/ocorrencias/views.py

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

Loading…
Cancel
Save