Browse Source

Prepara app Casas para migração - Vários TODOs

revisaoSidenav
Sesostris Vieira 3 years ago
parent
commit
97f98c9d0b
  1. 4
      requirements/requirements.txt
  2. 611
      sigi/apps/casas/admin.py
  3. 6
      sigi/apps/casas/apps.py
  4. 97
      sigi/apps/casas/filters.py
  5. 1
      sigi/apps/casas/forms.py
  6. 12
      sigi/apps/casas/migrations/0001_initial.py
  7. 5
      sigi/apps/casas/migrations/0002_auto_20150710_1247.py
  8. 1
      sigi/apps/casas/migrations/0003_auto_20200207_0919.py
  9. 3
      sigi/apps/casas/migrations/0004_auto_20201015_0810.py
  10. 1
      sigi/apps/casas/migrations/0005_casalegislativa_gerentes_interlegis.py
  11. 1
      sigi/apps/casas/migrations/0006_remove_casalegislativa_gerente_contas.py
  12. 3
      sigi/apps/casas/migrations/0007_auto_20201016_1632.py
  13. 3
      sigi/apps/casas/migrations/0008_auto_20210218_1007.py
  14. 3
      sigi/apps/casas/migrations/0009_auto_20210406_1055.py
  15. 1
      sigi/apps/casas/migrations/0010_auto_20210406_1101.py
  16. 1
      sigi/apps/casas/migrations/0011_auto_20210406_1135.py
  17. 1
      sigi/apps/casas/migrations/0012_auto_20210406_1420.py
  18. 1
      sigi/apps/casas/migrations/0013_auto_20210406_1428.py
  19. 4
      sigi/apps/casas/migrations/0014_auto_20210406_1945.py
  20. 1
      sigi/apps/casas/migrations/0015_auto_20210407_0801.py
  21. 1
      sigi/apps/casas/migrations/0016_auto_20210407_1559.py
  22. 3
      sigi/apps/casas/migrations/0017_auto_20210416_0841.py
  23. 1
      sigi/apps/casas/migrations/0018_orgao_sigla.py
  24. 1
      sigi/apps/casas/migrations/0019_auto_20210501_1058.py
  25. 1
      sigi/apps/casas/migrations/0020_auto_20210611_0946.py
  26. 200
      sigi/apps/casas/migrations/0021_alter_orgao_options_remove_orgao_recorte_and_more.py
  27. 137
      sigi/apps/casas/models.py
  28. 37
      sigi/apps/casas/templates/casas/casas_sem_convenio_pdf.html
  29. 132
      sigi/apps/casas/templates/casas/report_pdf.html
  30. 3
      sigi/apps/casas/tests.py
  31. 12
      sigi/apps/casas/urls.py
  32. 2163
      sigi/apps/casas/views.py
  33. 4
      sigi/settings/base.py
  34. 5
      sigi/settings/development.py
  35. BIN
      sigi/static/img/logo-interlegis.png
  36. BIN
      sigi/static/img/logo-senado.png
  37. 2
      sigi/templates/change_list_with_cart.html
  38. 45
      sigi/templates/pdf/base.html
  39. 59
      sigi/templates/pdf/base_report.html
  40. 1
      sigi/urls.py
  41. BIN
      sigiStatic/img/logo-interlegis.png
  42. BIN
      sigiStatic/img/logo-senado.png

4
requirements/requirements.txt

@ -1,6 +1,10 @@
ipython==7.30.1
weasyprint==54.0
Django==4.0.1
django-localflavor==3.1
django-extensions==3.1.5
django-weasyprint==2.1.0
psycopg2==2.9.3
django-bootstrap5==21.3
Pillow==9.0.0
django-localflavor==3.1

611
sigi/apps/casas/admin.py

@ -1,53 +1,35 @@
# -*- coding: utf-8 -*-
from unicodedata import name
from django.contrib import admin
from django.contrib.contenttypes import generic
from django.core.urlresolvers import reverse
from django.contrib.admin.options import ModelAdmin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.http import HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.utils.translation import gettext as _
#from geraldo.site.newsite.django_1_0.django.forms import extras
from image_cropping import ImageCroppingMixin
from sigi.apps.casas.forms import OrgaoForm
from sigi.apps.casas.models import Orgao, Presidente, Funcionario, TipoOrgao
from sigi.apps.casas.views import report_complete, labels_report, export_csv, \
labels_report_sem_presidente, report, \
adicionar_casas_carrinho
# from sigi.apps.casas.views import report_complete, labels_report, export_csv, \
# labels_report_sem_presidente, report, \
# adicionar_casas_carrinho
from sigi.apps.casas.filters import GerentesInterlegisFilter
from sigi.apps.contatos.models import Telefone
from sigi.apps.convenios.models import Convenio, Projeto
# from sigi.apps.diagnosticos.models import Diagnostico
# from sigi.apps.inventario.models import Bem
from sigi.apps.metas.models import PlanoDiretor
from sigi.apps.ocorrencias.models import Ocorrencia
# from sigi.apps.parlamentares.models import Legislatura
from sigi.apps.servicos.models import Servico, TipoServico
from sigi.apps.servidores.models import Servidor
# from sigi.apps.convenios.models import Convenio, Projeto
# from sigi.apps.ocorrencias.models import Ocorrencia
# from sigi.apps.servicos.models import Servico, TipoServico
from sigi.apps.utils import queryset_ascii
from sigi.apps.utils.base_admin import BaseModelAdmin
class TelefonesInline(generic.GenericTabularInline):
class TelefonesInline(GenericTabularInline):
model = Telefone
readonly_fields = ('ult_alteracao',)
extra = 1
class PresidenteInline(admin.StackedInline):
model = Presidente
fields = ('nome', 'sexo', 'data_nascimento', 'nota', 'email',
'tempo_de_servico', 'ult_alteracao', 'endereco', 'municipio',
'bairro', 'cep', 'redes_sociais',)
raw_id_fields = ('municipio',)
# fieldsets = ((None, {
# 'fields': (
# ('nome', 'sexo', 'data_nascimento'),
# ('nota', 'email', 'tempo_de_servico'),
# ('ult_alteracao',),
# )
# }),)
# exclude = ['setor', 'cargo', 'funcao']
readonly_fields = ('ult_alteracao',)
extra = 1
max_num = 1
@ -56,7 +38,8 @@ class PresidenteInline(admin.StackedInline):
return (self.model.objects.exclude(desativado=True)
.extra(select={'ult_null': 'ult_alteracao is null'})
.order_by('ult_null', '-ult_alteracao')
# A função extra foi usada para quando existir um registro com o campo igual a null não aparecer na frente dos mais novos
# A função extra foi usada para quando existir um registro com o
# campo igual a null não aparecer na frente dos mais novos
)
class ContatoInterlegisInline(admin.StackedInline):
@ -72,7 +55,8 @@ class ContatoInterlegisInline(admin.StackedInline):
verbose_name_plural = _('Contato(s) Interlegis Vigente(s)')
def get_queryset(self, request):
return (self.model.objects.filter(setor='contato_interlegis')
.extra(select={'ult_null': 'ult_alteracao is null'}).order_by('-ult_alteracao')
.extra(select={'ult_null': 'ult_alteracao is null'}).order_by(
'-ult_alteracao')
)
def get_extra(self, request, obj=None , **kwargs):
extra = 0
@ -85,19 +69,6 @@ class FuncionariosInline(admin.StackedInline):
'endereco', 'municipio', 'bairro', 'cep', 'redes_sociais',
'desativado', 'observacoes')
raw_id_fields = ('municipio',)
# fieldsets = ((None, {
# 'fields': (
# ('nome', 'sexo', 'data_nascimento'),
# ('nota', 'email'),
# ('cargo', 'funcao', 'setor'),
# ('tempo_de_servico', 'ult_alteracao'),
# ('endereco', 'municipio'),
# ('bairro', 'cep'),
# ('redes_sociais'),
# ('desativado', 'observacoes'),
# )
# }),)
readonly_fields = ('ult_alteracao',)
extra = 1
inlines = (TelefonesInline,)
@ -105,304 +76,167 @@ class FuncionariosInline(admin.StackedInline):
def get_queryset(self, request):
return (self.model.objects.exclude(cargo='Presidente',)
.exclude(desativado=True).extra(select={'ult_null': 'ult_alteracao is null'})
.exclude(desativado=True).extra(
select={'ult_null': 'ult_alteracao is null'})
.order_by('ult_null', '-ult_alteracao')
# A função extra foi usada para quando existir um registro com o campo igual a null não aparecer na frente dos mais novos
# A função extra foi usada para quando existir um registro com
# o campo igual a null não aparecer na frente dos mais novos
)
class ConveniosInline(admin.TabularInline):
model = Convenio
fieldsets = (
(None, {'fields': (
('link_sigad', 'status_convenio', 'num_convenio',
'projeto', 'observacao'),
('data_retorno_assinatura', 'data_pub_diario',),
('get_anexos',),
('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', 'get_anexos']
extra = 0
can_delete = False
template = 'admin/casas/convenios_inline.html'
ordering = ('-data_retorno_assinatura',)
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 = _('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 = _('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 = _('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 ["Vencido", "Desistência", "Cancelado"]:
label = r"danger"
elif status == "Vigente":
label = r"success"
elif status == "Pendente":
label = r"warning"
else:
label = r"info"
return '<p class="label label-{label}">{status}</p>'.format(label=label, status=status)
status_convenio.short_description = _("Status do convênio")
status_convenio.allow_tags = True
def link_convenio(self, obj):
if obj.pk is None:
return ""
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"/>
<a id="lookup_edit_convenio-%s" href="%s" class="changelink" onclick="return showRelatedObjectLookupPopup(this)">
Editar
</a>""" % (obj.pk, obj.pk, url)
link_convenio.short_description = _('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
# fields = ['numero', 'data_inicio', 'data_fim', 'data_eleicao', 'total_parlamentares', 'link_parlamentares', ]
# readonly_fields = ['link_parlamentares', ]
# def link_parlamentares(self, obj):
# class ConveniosInline(admin.TabularInline):
# model = Convenio
# fieldsets = (
# (None, {'fields': (
# ('link_sigad', 'status_convenio', 'num_convenio',
# 'projeto', 'observacao'),
# ('data_retorno_assinatura', 'data_pub_diario',),
# ('get_anexos',),
# ('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', 'get_anexos']
# extra = 0
# can_delete = False
# template = 'admin/casas/convenios_inline.html'
# ordering = ('-data_retorno_assinatura',)
# def has_add_permission(self, request):
# return False
# def get_anexos(self, obj):
# return mark_safe('<br/>'.join(
# [f'<a href="{a.arquivo.url}" target="_blank">{a}</a>'
# for a in obj.anexo_set.all()])
# )
# get_anexos.short_description = _('Anexos')
# def status_convenio(self, obj):
# if obj.pk is None:
# return ""
# status = obj.get_status()
# if status in ["Vencido", "Desistência", "Cancelado"]:
# label = r"danger"
# elif status == "Vigente":
# label = r"success"
# elif status == "Pendente":
# label = r"warning"
# else:
# label = r"info"
# return mark_safe(f'<p class="label label-{label}">{status}</p>')
# status_convenio.short_description = _("Status do convênio")
# def link_convenio(self, obj):
# if obj.pk is None:
# return ""
# url = reverse(
# f'admin:{obj._meta.app_label}_{obj._meta.module_name}_change',
# args=[obj.pk]
# ) + '?_popup=1'
# return mark_safe(
# f'<input id="edit_convenio-{obj.pk}" type="hidden"/>'
# f'<a id="lookup_edit_convenio-{obj.pk}" href="{url}"'
# 'class="changelink" '
# 'onclick="return showRelatedObjectLookupPopup(this)">'
# f'{_("Editar")}</a>'
# )
# link_convenio.short_description = _('Editar convenio')
# def link_sigad(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_legislatura-%s" type="hidden"/>
# <a id="lookup_edit_legislatura-%s" href="%s" class="changelink" onclick="return showRelatedObjectLookupPopup(this)">
# Editar
# </a>""" % (obj.pk, obj.pk, url)
# link_parlamentares.short_description = _('Parlamentares')
# link_parlamentares.allow_tags = True
# class DiagnosticoInline(admin.TabularInline):
# model = Diagnostico
# fields = ['data_visita_inicio', 'data_visita_fim', 'publicado', 'data_publicacao', 'responsavel', 'link_diagnostico', ]
# readonly_fields = ['data_visita_inicio', 'data_visita_fim', 'publicado', 'data_publicacao', 'responsavel', 'link_diagnostico', ]
# return mark_safe(obj.get_sigad_url())
# link_sigad.short_description = _("Processo no Senado")
# class ServicoInline(admin.TabularInline):
# model = Servico
# fields = ('link_url', 'contato_tecnico', 'contato_administrativo',
# 'hospedagem_interlegis', 'data_ativacao', 'data_alteracao',
# 'data_desativacao', 'link_servico')
# readonly_fields = ['link_url', 'contato_tecnico', 'contato_administrativo',
# 'hospedagem_interlegis', 'data_ativacao',
# 'data_alteracao', 'data_desativacao', 'link_servico']
# extra = 0
# max_num = 0
# can_delete = False
# ordering = ('-data_alteracao',)
# def link_diagnostico(self, obj):
# def link_url(self, servico):
# if servico.data_desativacao is not None:
# return servico.url
# return mark_safe(
# f'<a href="{servico.url}" target="_blank">{servico.url}</a>'
# )
# link_url.short_description = _('URL do serviço')
# def link_servico(self, obj):
# if obj.pk is None:
# return ""
# url = reverse('admin:%s_%s_change' % (obj._meta.app_label, obj._meta.module_name), args=["%s.pdf" % obj.pk])
# return """<input id="edit_diagnostico-%s" type="hidden"/>
# <a id="lookup_edit_diagnostico-%s" href="%s" class="button" target="_blank">
# Abrir PDF
# </a>""" % (obj.pk, obj.pk, url)
# link_diagnostico.short_description = _('Ver PDF')
# link_diagnostico.allow_tags = True
# class BemInline(admin.TabularInline):
# model = Bem
class ServicoInline(admin.TabularInline):
model = Servico
fields = ('link_url', 'contato_tecnico', 'contato_administrativo',
'hospedagem_interlegis', 'data_ativacao', 'data_alteracao',
'data_desativacao', 'link_servico')
readonly_fields = ['link_url', 'contato_tecnico', 'contato_administrativo',
'hospedagem_interlegis', 'data_ativacao',
'data_alteracao', 'data_desativacao', 'link_servico']
extra = 0
max_num = 0
can_delete = False
def link_url(self, servico):
if servico.data_desativacao is not None:
return servico.url
return '<a href="{url}" target="_blank">{url}</a>'.format(url=servico.url)
link_url.short_description = _('URL do serviço')
link_url.allow_tags = True
ordering = ('-data_alteracao',)
def link_servico(self, obj):
if obj.pk is None:
return ""
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"/>
<a id="lookup_edit_convenio-%s" href="%s" class="changelink" onclick="return showRelatedObjectLookupPopup(this)">
Editar
</a>""" % (obj.pk, obj.pk, url)
link_servico.short_description = _('Editar Serviço')
link_servico.allow_tags = True
def has_add_permission(self, request):
return False
# class PlanoDiretorInline(admin.TabularInline):
# model = PlanoDiretor
class OcorrenciaInline(admin.TabularInline):
model = Ocorrencia
fields = ('data_criacao', 'assunto', 'prioridade', 'status', 'data_modificacao', 'setor_responsavel', 'link_editar',)
readonly_fields = ('data_criacao', 'assunto', 'prioridade', 'status', 'data_modificacao', 'setor_responsavel', 'link_editar',)
extra = 0
max_num = 0
can_delete = False
template = 'admin/casas/ocorrencia_inline.html'
ordering = ('-data_modificacao',)
def link_editar(self, obj):
if obj.pk is None:
return ""
url = reverse('admin:%s_%s_change' % (obj._meta.app_label, obj._meta.module_name), args=[obj.pk])
return """<input id="edit_ocorrencia-%s" type="hidden"/>
<a id="lookup_edit_ocorrencia-%s" href="%s" class="button" target="_blank"
onclick="return showRelatedObjectLookupPopup(this);">%s</a>""" % (obj.pk, obj.pk, url, _('Editar'))
link_editar.short_description = _('Editar')
link_editar.allow_tags = True
class GerentesInterlegisFilter(admin.filters.RelatedFieldListFilter):
def __init__(self, *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]
class ConvenioFilter(admin.SimpleListFilter):
title = _("Tipo de convênio")
parameter_name = 'convenio'
def lookups(self, request, model_admin):
return (
('SC', _("Sem nenhum convênio")),
('CC', _("Com algum convênio")),
) + tuple([(p.pk, p.sigla) for p in Projeto.objects.all()])
def queryset(self, request, queryset):
if self.value() is not None:
if self.value() == 'SC':
queryset = queryset.filter(convenio=None)
elif self.value() == 'CC':
queryset = queryset.exclude(convenio=None)
else:
queryset = queryset.filter(convenio__projeto_id=self.value())
return queryset.distinct('municipio__uf__nome', 'nome')
class ExcluirConvenioFilter(admin.SimpleListFilter):
title=_("Excluir convênio da pesquisa")
parameter_name = 'excluir_convenio'
def lookups(self, request, model_admin):
return tuple([(p.pk, p.sigla) for p in Projeto.objects.all()])
def queryset(self, request, queryset):
if (self.value() is None):
return queryset
else:
queryset = queryset.exclude(convenio__projeto_id=self.value()).distinct('municipio__uf__nome', 'nome')
return queryset
class ServicoFilter(admin.SimpleListFilter):
title = _("Serviço")
parameter_name = 'servico'
def lookups(self, request, model_admin):
return (
('SS', _("Sem nenhum serviço")),
('CS', _("Com algum serviço")),
('CH', _("Com algum serviço de hospedagem")),
('CR', _("Apenas serviço de registro")),
) + tuple([(p.pk, p.nome) for p in TipoServico.objects.all()])
def queryset(self, request, queryset):
if self.value() is not None:
if self.value() == 'SS':
queryset = queryset.filter(servico=None)
elif self.value() == 'CS':
queryset = queryset.exclude(servico=None).filter(
servico__data_desativacao__isnull=True)
elif self.value() == 'CR':
queryset = queryset.exclude(servico__tipo_servico__modo='H') \
.exclude(servico=None)
elif self.value() == 'CH':
queryset = queryset.filter(
servico__tipo_servico__modo='H',
servico__data_desativacao__isnull=True
)
else:
queryset = queryset.filter(
servico__tipo_servico_id=self.value()
)
return queryset.distinct('municipio__uf__nome', 'nome')
class ServicoAtivoFilter(admin.SimpleListFilter):
title = _("Serviço ativo")
parameter_name = 'ativo'
def lookups(self, request, model_admin):
return (
('ativo', _("Ativo")),
('desativado', _("Desativado")),
)
# url = reverse(
# f'admin:{obj._meta.app_label}_{obj._meta.module_name_change}',
# args=[obj.pk]
# ) + '?_popup=1'
# return mark_safe(
# f'<input id="edit_convenio-{obj.pk}" type="hidden"/>'
# f'<a id="lookup_edit_convenio-{obj.pk}" href="{url}" '
# 'class="changelink" '
# 'onclick="return showRelatedObjectLookupPopup(this)">Editar</a>'
# )
# link_servico.short_description = _('Editar Serviço')
# def has_add_permission(self, request):
# return False
# class OcorrenciaInline(admin.TabularInline):
# model = Ocorrencia
# fields = ('data_criacao', 'assunto', 'prioridade', 'status',
# 'data_modificacao', 'setor_responsavel', 'link_editar',)
# readonly_fields = ('data_criacao', 'assunto', 'prioridade', 'status',
# 'data_modificacao', 'setor_responsavel', 'link_editar',)
# extra = 0
# max_num = 0
# can_delete = False
# template = 'admin/casas/ocorrencia_inline.html'
# ordering = ('-data_modificacao',)
# def link_editar(self, obj):
# if obj.pk is None:
# return ""
# url = reverse(
# f'admin:{obj._meta.app_label}_{obj._meta.module_name}_change',
# args=[obj.pk]
# )
# return mark_safe(
# f'<input id="edit_ocorrencia-{obj.pk}" type="hidden"/>'
# f'<a id="lookup_edit_ocorrencia-{obj.pk}" href="{url}" '
# 'class="button" target="_blank" '
# 'onclick="return showRelatedObjectLookupPopup(this);">'
# f'{_("Editar")}</a>'
# )
# link_editar.short_description = _('Editar')
def queryset(self, request, queryset):
if self.value() is not None:
if self.value() == 'ativo':
queryset = queryset.filter(servico__data_desativacao__isnull=True)
else:
queryset = queryset.filter(servico__data_desativacao__isnull=False)
return queryset
@admin.register(Orgao)
class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin):
class OrgaoAdmin(admin.ModelAdmin):
form = OrgaoForm
actions = ['adicionar_casas', ]
inlines = (TelefonesInline, PresidenteInline, ContatoInterlegisInline, FuncionariosInline,
ConveniosInline, ServicoInline, OcorrenciaInline,)
list_display = ('id', 'sigla', 'nome', 'get_uf', 'get_gerentes', 'get_convenios',
'get_servicos')
# actions = ['adicionar_casas', ]
inlines = (TelefonesInline, PresidenteInline, ContatoInterlegisInline,
FuncionariosInline, ) #ConveniosInline, ServicoInline,
# OcorrenciaInline,)
list_display = ('id', 'sigla', 'nome', 'get_uf', 'get_gerentes',
'get_convenios', 'get_servicos')
list_display_links = ('sigla', 'nome',)
# list_filter = ('tipo', ('gerentes_interlegis', GerentesInterlegisFilter),
# 'municipio__uf__nome', ConvenioFilter, ServicoAtivoFilter,
# ExcluirConvenioFilter, ServicoFilter, 'inclusao_digital',)
list_filter = ('tipo', ('gerentes_interlegis', GerentesInterlegisFilter),
'municipio__uf__nome', ConvenioFilter, ServicoAtivoFilter, ExcluirConvenioFilter, ServicoFilter,
'inclusao_digital',)
'municipio__uf__nome', 'inclusao_digital',)
ordering = ('municipio__uf__nome', 'nome')
queryset = queryset_ascii
fieldsets = (
@ -435,23 +269,33 @@ class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin):
get_uf.admin_order_field = 'municipio__uf__nome'
def get_gerentes(self, obj):
return obj.lista_gerentes()
return mark_safe(obj.lista_gerentes())
get_gerentes.short_description = _('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>'
#TODO: Descomentar após migração da app Convênios
# return mark_safe(
# '<ul>' +
# ''.join([f'<li>{c}</li>' for c in obj.convenio_set.all()]) +
# '</ul>'
# )
return "TODO: Descomentar após migração da app Convênios"
get_convenios.short_description = _('Convênios')
get_convenios.allow_tags = True
def get_servicos(self, obj):
return '<ul>' + ''.join(
['<li><a href="{url}" target="_blank">{servico}</a></li>'.format(
url=s.url, servico=s.__unicode__()) for s in
obj.servico_set.filter(data_desativacao__isnull=True)]) + '</ul>'
#TODO: Descomentar após migrar a app Servicos
# return mark_safe(
# '<ul>' +
# ''.join(
# [f'<li><a href="{s.url}" target="_blank">{s}</a></li>'
# for s in obj.servico_set.filter(
# data_desativacao__isnull=True)
# ]
# ) +
# '</ul>'
# )
return "TODO: Descomentar após migrar a app Servicos"
get_servicos.short_description = _('Serviços')
get_servicos.allow_tags = True
def changelist_view(self, request, extra_context=None):
return super(OrgaoAdmin, self).changelist_view(
@ -466,56 +310,55 @@ class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin):
'municipio__uf__codigo_ibge__exact',
'convenio__projeto__id__exact'])
def etiqueta(self, request, queryset):
return labels_report(request, queryset=queryset)
etiqueta.short_description = _("Gerar etiqueta(s) da(s) casa(s) "
"selecionada(s)")
def etiqueta_sem_presidente(self, request, queryset):
return labels_report_sem_presidente(request, queryset=queryset)
etiqueta_sem_presidente.short_description = _("Gerar etiqueta(s) sem "
"presidente da(s) casa(s) "
"selecionada(s)")
def relatorio(self, request, queryset):
return report(request, queryset=queryset)
relatorio.short_description = _("Exportar a(s) casa(s) selecionada(s) "
"para PDF")
def relatorio_completo(self, request, queryset):
return report_complete(request, queryset=queryset)
relatorio_completo.short_description = _("Gerar relatório completo da(s) "
"casa(s) selecionada(s)")
def relatorio_csv(self, request, queryset):
return export_csv(request)
relatorio_csv.short_description = _("Exportar casa(s) selecionada(s) "
"para CSV")
def adicionar_casas(self, request, queryset):
if 'carrinho_casas' in request.session:
# if request.session.has_key('carrinho_casas'):
q1 = len(request.session['carrinho_casas'])
else:
q1 = 0
response = adicionar_casas_carrinho(request, queryset=queryset)
q2 = len(request.session['carrinho_casas'])
quant = q2 - q1
if quant:
self.message_user(request, str(q2 - q1) + " " +
_("Casas Legislativas adicionadas no carrinho"))
else:
self.message_user(request, _("As Casas Legislativas selecionadas "
"já foram adicionadas anteriormente"))
return HttpResponseRedirect('.')
adicionar_casas.short_description = _("Armazenar casas no carrinho para "
"exportar")
#TODO: Resolver depois - sigi-boys???
# def etiqueta(self, request, queryset):
# return labels_report(request, queryset=queryset)
# etiqueta.short_description = _("Gerar etiqueta(s) da(s) casa(s) "
# "selecionada(s)")
# def etiqueta_sem_presidente(self, request, queryset):
# return labels_report_sem_presidente(request, queryset=queryset)
# etiqueta_sem_presidente.short_description = _("Gerar etiqueta(s) sem "
# "presidente da(s) casa(s) "
# "selecionada(s)")
# def relatorio(self, request, queryset):
# return report(request, queryset=queryset)
# relatorio.short_description = _("Exportar a(s) casa(s) selecionada(s) "
# "para PDF")
# def relatorio_completo(self, request, queryset):
# return report_complete(request, queryset=queryset)
# relatorio_completo.short_description = _("Gerar relatório completo da(s) "
# "casa(s) selecionada(s)")
# def relatorio_csv(self, request, queryset):
# return export_csv(request)
# relatorio_csv.short_description = _("Exportar casa(s) selecionada(s) "
# "para CSV")
# def adicionar_casas(self, request, queryset):
# if 'carrinho_casas' in request.session:
# # if request.session.has_key('carrinho_casas'):
# q1 = len(request.session['carrinho_casas'])
# else:
# q1 = 0
# response = adicionar_casas_carrinho(request, queryset=queryset)
# q2 = len(request.session['carrinho_casas'])
# quant = q2 - q1
# if quant:
# self.message_user(request, str(q2 - q1) + " " +
# _("Casas Legislativas adicionadas no carrinho"))
# else:
# self.message_user(request, _("As Casas Legislativas selecionadas "
# "já foram adicionadas anteriormente"))
# return HttpResponseRedirect('.')
# adicionar_casas.short_description = _("Armazenar casas no carrinho para "
# "exportar")
def get_actions(self, request):
actions = super(OrgaoAdmin, self).get_actions(request)
if 'delete_selected' in actions:
del actions['delete_selected']
return actions
admin.site.register(TipoOrgao)

6
sigi/apps/casas/apps.py

@ -0,0 +1,6 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class CasasConfig(AppConfig):
name = 'sigi.apps.casas'
verbose_name = _('casas legislativas')

97
sigi/apps/casas/filters.py

@ -0,0 +1,97 @@
from django.contrib import admin
from sigi.apps.servidores.models import Servidor
class GerentesInterlegisFilter(admin.filters.RelatedFieldListFilter):
def __init__(self, *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]
# class ConvenioFilter(admin.SimpleListFilter):
# title = _("Tipo de convênio")
# parameter_name = 'convenio'
# def lookups(self, request, model_admin):
# return (
# ('SC', _("Sem nenhum convênio")),
# ('CC', _("Com algum convênio")),
# ) + tuple([(p.pk, p.sigla) for p in Projeto.objects.all()])
# def queryset(self, request, queryset):
# if self.value() is not None:
# if self.value() == 'SC':
# queryset = queryset.filter(convenio=None)
# elif self.value() == 'CC':
# queryset = queryset.exclude(convenio=None)
# else:
# queryset = queryset.filter(convenio__projeto_id=self.value())
# return queryset.distinct('municipio__uf__nome', 'nome')
# class ExcluirConvenioFilter(admin.SimpleListFilter):
# title=_("Excluir convênio da pesquisa")
# parameter_name = 'excluir_convenio'
# def lookups(self, request, model_admin):
# return tuple([(p.pk, p.sigla) for p in Projeto.objects.all()])
# def queryset(self, request, queryset):
# if (self.value() is None):
# return queryset
# else:
# queryset = queryset.exclude(convenio__projeto_id=self.value()).distinct('municipio__uf__nome', 'nome')
# return queryset
# class ServicoFilter(admin.SimpleListFilter):
# title = _("Serviço")
# parameter_name = 'servico'
# def lookups(self, request, model_admin):
# return (
# ('SS', _("Sem nenhum serviço")),
# ('CS', _("Com algum serviço")),
# ('CH', _("Com algum serviço de hospedagem")),
# ('CR', _("Apenas serviço de registro")),
# ) + tuple([(p.pk, p.nome) for p in TipoServico.objects.all()])
# def queryset(self, request, queryset):
# if self.value() is not None:
# if self.value() == 'SS':
# queryset = queryset.filter(servico=None)
# elif self.value() == 'CS':
# queryset = queryset.exclude(servico=None).filter(
# servico__data_desativacao__isnull=True)
# elif self.value() == 'CR':
# queryset = queryset.exclude(servico__tipo_servico__modo='H') \
# .exclude(servico=None)
# elif self.value() == 'CH':
# queryset = queryset.filter(
# servico__tipo_servico__modo='H',
# servico__data_desativacao__isnull=True
# )
# else:
# queryset = queryset.filter(
# servico__tipo_servico_id=self.value()
# )
# return queryset.distinct('municipio__uf__nome', 'nome')
# class ServicoAtivoFilter(admin.SimpleListFilter):
# title = _("Serviço ativo")
# parameter_name = 'ativo'
# def lookups(self, request, model_admin):
# return (
# ('ativo', _("Ativo")),
# ('desativado', _("Desativado")),
# )
# def queryset(self, request, queryset):
# if self.value() is not None:
# if self.value() == 'ativo':
# queryset = queryset.filter(servico__data_desativacao__isnull=True)
# else:
# queryset = queryset.filter(servico__data_desativacao__isnull=False)
# return queryset

1
sigi/apps/casas/forms.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from django import forms
from django.utils.translation import gettext as _
from localflavor.br.forms import BRZipCodeField

12
sigi/apps/casas/migrations/0001_initial.py

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import image_cropping.fields
import sigi.apps.utils
@ -30,12 +28,12 @@ class Migration(migrations.Migration):
('pagina_web', models.URLField(help_text=b'Exemplo: <em>http://www.camarapains.mg.gov.br</em>.', verbose_name='p\xe1gina web', blank=True)),
('ult_alt_endereco', models.DateTimeField(null=True, verbose_name='\xdaltima altera\xe7\xe3o do endere\xe7o', blank=True)),
('foto', models.ImageField(height_field=b'foto_altura', width_field=b'foto_largura', upload_to=b'imagens/casas', blank=True)),
(b'recorte', image_cropping.fields.ImageRatioField(b'foto', '400x300', hide_image_field=False, size_warning=True, allow_fullsize=False, free_crop=False, adapt_rotation=False, help_text=None, verbose_name=b'Recorte')),
('recorte', models.CharField('foto', max_length=255)),
('foto_largura', models.SmallIntegerField(null=True, editable=False)),
('foto_altura', models.SmallIntegerField(null=True, editable=False)),
('data_instalacao', models.DateField(null=True, verbose_name='Data de instala\xe7\xe3o da Casa Legislativa', blank=True)),
('gerente_contas', models.ForeignKey(verbose_name=b'Gerente de contas', blank=True, to='servidores.Servidor', null=True)),
('municipio', models.ForeignKey(verbose_name=b'munic\xc3\xadpio', to='contatos.Municipio')),
('gerente_contas', models.ForeignKey(verbose_name=b'Gerente de contas', blank=True, to='servidores.Servidor', null=True, on_delete=models.CASCADE)),
('municipio', models.ForeignKey(verbose_name=b'munic\xc3\xadpio', to='contatos.Municipio', on_delete=models.CASCADE)),
],
options={
'ordering': ('nome',),
@ -57,7 +55,7 @@ class Migration(migrations.Migration):
('setor', models.CharField(default=b'outros', max_length=100, choices=[(b'presidente', b'Presidente'), (b'contato_interlegis', b'Contato Interlegis'), (b'infraestrutura_fisica', b'Infraestrutura F\xc3\xadsica'), (b'estrutura_de_ti', b'Estrutura de TI'), (b'organizacao_do_processo_legislativo', b'Organiza\xc3\xa7\xc3\xa3o do Processo Legislativo'), (b'producao_legislativa', b'Produ\xc3\xa7\xc3\xa3o Legislativa'), (b'estrutura_de_comunicacao_social', b'Estrutura de Comunica\xc3\xa7\xc3\xa3o Social'), (b'estrutura_de_recursos_humanos', b'Estrutura de Recursos Humanos'), (b'gestao', b'Gest\xc3\xa3o'), (b'outros', b'Outros')])),
('tempo_de_servico', models.CharField(max_length=50, null=True, verbose_name='tempo de servi\xe7o', blank=True)),
('ult_alteracao', models.DateTimeField(null=True, verbose_name='\xdaltima altera\xe7\xe3o', blank=True)),
('casa_legislativa', models.ForeignKey(to='casas.CasaLegislativa')),
('casa_legislativa', models.ForeignKey(to='casas.CasaLegislativa', on_delete=models.CASCADE)),
],
options={
'ordering': ('nome',),
@ -80,7 +78,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='casalegislativa',
name='tipo',
field=models.ForeignKey(verbose_name=b'Tipo', to='casas.TipoCasaLegislativa'),
field=models.ForeignKey(verbose_name=b'Tipo', to='casas.TipoCasaLegislativa', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterUniqueTogether(

5
sigi/apps/casas/migrations/0002_auto_20150710_1247.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@ -33,13 +32,13 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='casalegislativa',
name='pesquisador',
field=models.ForeignKey(verbose_name='Pesquisador', blank=True, to='servidores.Servidor', null=True),
field=models.ForeignKey(verbose_name='Pesquisador', blank=True, to='servidores.Servidor', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterField(
model_name='casalegislativa',
name='gerente_contas',
field=models.ForeignKey(related_name='casas_que_gerencia', verbose_name=b'Gerente de contas', blank=True, to='servidores.Servidor', null=True),
field=models.ForeignKey(related_name='casas_que_gerencia', verbose_name=b'Gerente de contas', blank=True, to='servidores.Servidor', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterField(

1
sigi/apps/casas/migrations/0003_auto_20200207_0919.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

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

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@ -14,7 +13,7 @@ class Migration(migrations.Migration):
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),
field=models.ForeignKey(related_name='casas_que_gerencia_old', verbose_name=b'Gerente de contas', blank=True, to='servidores.Servidor', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
]

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

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

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

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

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

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@ -68,7 +67,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='casalegislativa',
name='municipio',
field=models.ForeignKey(verbose_name='Munic\xedpio', to='contatos.Municipio'),
field=models.ForeignKey(verbose_name='Munic\xedpio', to='contatos.Municipio', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterField(

3
sigi/apps/casas/migrations/0008_auto_20210218_1007.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@ -33,7 +32,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='funcionario',
name='municipio',
field=models.ForeignKey(verbose_name='Municipio', to='contatos.Municipio', null=True),
field=models.ForeignKey(verbose_name='Municipio', to='contatos.Municipio', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AddField(

3
sigi/apps/casas/migrations/0009_auto_20210406_1055.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@ -14,7 +13,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='funcionario',
name='municipio',
field=models.ForeignKey(verbose_name='Municipio', blank=True, to='contatos.Municipio', null=True),
field=models.ForeignKey(verbose_name='Municipio', blank=True, to='contatos.Municipio', null=True, on_delete=models.CASCADE),
preserve_default=True,
),
]

1
sigi/apps/casas/migrations/0010_auto_20210406_1101.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

1
sigi/apps/casas/migrations/0011_auto_20210406_1135.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

1
sigi/apps/casas/migrations/0012_auto_20210406_1420.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

1
sigi/apps/casas/migrations/0013_auto_20210406_1428.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

4
sigi/apps/casas/migrations/0014_auto_20210406_1945.py

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import image_cropping.fields
import sigi.apps.utils
@ -14,7 +12,7 @@ class Migration(migrations.Migration):
('servidores', '0001_initial'),
# ('parlamentares', '0002_auto_20210406_1945'),
# ('servicos', '0005_auto_20210406_1945'),
('servicos', '0004_delete_casaatendida'),
# ('servicos', '0004_delete_casaatendida'),
# ('inventario', '0002_auto_20210406_1945'),
# ('convenios', '0003_auto_20210406_1945'),
# ('ocorrencias', '0003_auto_20210406_1945'),

1
sigi/apps/casas/migrations/0015_auto_20210407_0801.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

1
sigi/apps/casas/migrations/0016_auto_20210407_1559.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

3
sigi/apps/casas/migrations/0017_auto_20210416_0841.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
@ -15,7 +14,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='funcionario',
name='casa_legislativa',
field=models.ForeignKey(verbose_name='\xf3rg\xe3o', to='casas.Orgao'),
field=models.ForeignKey(verbose_name='\xf3rg\xe3o', to='casas.Orgao', on_delete=models.CASCADE),
preserve_default=True,
),
migrations.AlterField(

1
sigi/apps/casas/migrations/0018_orgao_sigla.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

1
sigi/apps/casas/migrations/0019_auto_20210501_1058.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

1
sigi/apps/casas/migrations/0020_auto_20210611_0946.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations

200
sigi/apps/casas/migrations/0021_alter_orgao_options_remove_orgao_recorte_and_more.py

@ -0,0 +1,200 @@
# Generated by Django 4.0.1 on 2022-01-11 18:44
from django.db import migrations, models
import django.db.models.deletion
import sigi.apps.utils
class Migration(migrations.Migration):
dependencies = [
('servidores', '0008_alter_servico_id_alter_servidor_foto_and_more'),
('contatos', '0005_alter_mesorregiao_options_alter_microrregiao_options_and_more'),
('casas', '0020_auto_20210611_0946'),
]
operations = [
migrations.AlterModelOptions(
name='orgao',
options={'ordering': ('nome',), 'verbose_name': 'órgão', 'verbose_name_plural': 'órgãos'},
),
migrations.RemoveField(
model_name='orgao',
name='recorte',
),
migrations.AlterField(
model_name='funcionario',
name='bairro',
field=models.CharField(blank=True, max_length=100, verbose_name='bairro'),
),
migrations.AlterField(
model_name='funcionario',
name='cargo',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='cargo'),
),
migrations.AlterField(
model_name='funcionario',
name='data_nascimento',
field=models.DateField(blank=True, null=True, verbose_name='data de nascimento'),
),
migrations.AlterField(
model_name='funcionario',
name='desativado',
field=models.BooleanField(default=False, verbose_name='desativado'),
),
migrations.AlterField(
model_name='funcionario',
name='endereco',
field=models.CharField(blank=True, max_length=100, verbose_name='endereço'),
),
migrations.AlterField(
model_name='funcionario',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='funcionario',
name='municipio',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contatos.municipio', verbose_name='municipio'),
),
migrations.AlterField(
model_name='funcionario',
name='nome',
field=models.CharField(max_length=60, verbose_name='nome completo'),
),
migrations.AlterField(
model_name='funcionario',
name='nota',
field=models.CharField(blank=True, max_length=250, null=True, verbose_name='telefones'),
),
migrations.AlterField(
model_name='funcionario',
name='observacoes',
field=models.TextField(blank=True, verbose_name='observações'),
),
migrations.AlterField(
model_name='funcionario',
name='redes_sociais',
field=models.TextField(blank=True, help_text='Colocar um por linha', verbose_name='redes sociais'),
),
migrations.AlterField(
model_name='funcionario',
name='setor',
field=models.CharField(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')], default='outros', max_length=100, verbose_name='setor'),
),
migrations.AlterField(
model_name='funcionario',
name='sexo',
field=models.CharField(choices=[('M', 'Masculino'), ('F', 'Feminino')], default='M', max_length=1, verbose_name='sexo'),
),
migrations.AlterField(
model_name='funcionario',
name='tempo_de_servico',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='tempo de serviço'),
),
migrations.AlterField(
model_name='funcionario',
name='ult_alteracao',
field=models.DateTimeField(auto_now=True, null=True, verbose_name='última alteração'),
),
migrations.AlterField(
model_name='orgao',
name='bairro',
field=models.CharField(blank=True, max_length=100, verbose_name='bairro'),
),
migrations.AlterField(
model_name='orgao',
name='cnpj',
field=models.CharField(blank=True, max_length=32, verbose_name='CNPJ'),
),
migrations.AlterField(
model_name='orgao',
name='codigo_interlegis',
field=models.CharField(blank=True, max_length=3, verbose_name='código Interlegis'),
),
migrations.AlterField(
model_name='orgao',
name='data_instalacao',
field=models.DateField(blank=True, null=True, verbose_name='data de instalação da Casa Legislativa'),
),
migrations.AlterField(
model_name='orgao',
name='data_levantamento',
field=models.DateTimeField(blank=True, null=True, verbose_name='data/hora da pesquisa'),
),
migrations.AlterField(
model_name='orgao',
name='email',
field=models.EmailField(blank=True, max_length=128, verbose_name='e-mail'),
),
migrations.AlterField(
model_name='orgao',
name='foto',
field=models.ImageField(blank=True, height_field='foto_altura', upload_to='imagens/casas', verbose_name='foto', width_field='foto_largura'),
),
migrations.AlterField(
model_name='orgao',
name='horario_funcionamento',
field=models.CharField(blank=True, max_length=100, verbose_name='horário de funcionamento da Casa Legislativa'),
),
migrations.AlterField(
model_name='orgao',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='orgao',
name='inclusao_digital',
field=models.CharField(choices=[('NAO PESQUISADO', 'Não pesquisado'), ('NAO POSSUI PORTAL', 'Não possui portal'), ('PORTAL MODELO', 'Possui Portal Modelo'), ('OUTRO PORTAL', 'Possui outro portal')], default='NAO PESQUISADO', max_length=30, verbose_name='inclusão digital'),
),
migrations.AlterField(
model_name='orgao',
name='logradouro',
field=models.CharField(help_text='Avenida, rua, praça, jardim, parque...', max_length=100, verbose_name='logradouro'),
),
migrations.AlterField(
model_name='orgao',
name='municipio',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contatos.municipio', verbose_name='município'),
),
migrations.AlterField(
model_name='orgao',
name='nome',
field=models.CharField(help_text='Exemplo: <em>Câmara Municipal de Pains</em>.', max_length=60, verbose_name='nome'),
),
migrations.AlterField(
model_name='orgao',
name='obs_pesquisa',
field=models.TextField(blank=True, verbose_name='observações do pesquisador'),
),
migrations.AlterField(
model_name='orgao',
name='pagina_web',
field=models.URLField(blank=True, help_text='Exemplo: <em>http://www.camarapains.mg.gov.br</em>.', verbose_name='página web'),
),
migrations.AlterField(
model_name='orgao',
name='pesquisador',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='servidores.servidor', verbose_name='pesquisador'),
),
migrations.AlterField(
model_name='orgao',
name='search_text',
field=sigi.apps.utils.SearchField(editable=False, field_names=['nome']),
),
migrations.AlterField(
model_name='orgao',
name='tipo',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='casas.tipoorgao', verbose_name='tipo'),
),
migrations.AlterField(
model_name='orgao',
name='ult_alt_endereco',
field=models.DateTimeField(blank=True, null=True, verbose_name='última alteração do endereço'),
),
migrations.AlterField(
model_name='tipoorgao',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
]

137
sigi/apps/casas/models.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from datetime import datetime
import random
from string import ascii_uppercase
@ -7,19 +6,12 @@ from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from image_cropping import ImageRatioField
from sigi.apps.contatos.models import Municipio
from sigi.apps.servidores.models import Servidor
from sigi.apps.utils import SearchField
class TipoOrgao(models.Model):
""" Modelo para representar o tipo da Casa Legislativa
Geralmente: Câmara Municipal, Assembléia Legislativa,
Câmara Distrital ou Legislativo Federal
"""
sigla = models.CharField(_("Sigla"), max_length=5)
nome = models.CharField(_("Nome"), max_length=100)
legislativo = models.BooleanField(_("Poder legislativo"), default=False)
@ -29,13 +21,10 @@ class TipoOrgao(models.Model):
verbose_name = _("Tipo de órgão")
verbose_name_plural = _("Tipos de órgão")
def __unicode__(self):
def __str__(self):
return self.nome
class Orgao(models.Model):
""" Modelo para representar uma Casa Legislativa
"""
INCLUSAO_DIGITAL_CHOICES = (
('NAO PESQUISADO', _('Não pesquisado')),
('NAO POSSUI PORTAL', _('Não possui portal')),
@ -44,7 +33,7 @@ class Orgao(models.Model):
)
nome = models.CharField(
_("Nome"),
_("nome"),
max_length=60,
help_text=_('Exemplo: <em>Câmara Municipal de Pains</em>.')
)
@ -58,102 +47,93 @@ class Orgao(models.Model):
tipo = models.ForeignKey(
TipoOrgao,
on_delete=models.PROTECT,
verbose_name=_("Tipo")
verbose_name=_("tipo")
)
cnpj = models.CharField(_("CNPJ"), max_length=32, blank=True)
observacoes = models.TextField(_('observações'), blank=True)
horario_funcionamento = models.CharField(
_("Horário de funcionamento da Casa Legislativa"),
_("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'),
_('código Interlegis'),
max_length=3,
blank=True
)
# codigo_interlegis.ts_filter = True
gerentes_interlegis = models.ManyToManyField(
Servidor,
verbose_name=_("Gerentes Interlegis"),
related_name='casas_que_gerencia',
blank=True,
)
# Informações de contato
logradouro = models.CharField(
_("Logradouro"),
_("logradouro"),
max_length=100,
help_text=_('Avenida, rua, praça, jardim, parque...')
)
bairro = models.CharField(_("Bairro"), max_length=100, blank=True)
bairro = models.CharField(_("bairro"), max_length=100, blank=True)
municipio = models.ForeignKey(
'contatos.Municipio',
on_delete=models.PROTECT,
verbose_name=_('Município')
verbose_name=_('município')
)
# municipio.uf_filter = True
cep = models.CharField(_("CEP"), max_length=32)
email = models.EmailField(_('E-mail'), max_length=128, blank=True)
email = models.EmailField(_('e-mail'), max_length=128, blank=True)
pagina_web = models.URLField(
_('Página web'),
_('página web'),
help_text=_('Exemplo: <em>http://www.camarapains.mg.gov.br</em>.'),
blank=True,
)
inclusao_digital = models.CharField(
_("Inclusão digital"),
_("inclusão digital"),
max_length=30,
choices=INCLUSAO_DIGITAL_CHOICES,
default=INCLUSAO_DIGITAL_CHOICES[0][0]
)
data_levantamento = models.DateTimeField(
_("Data/hora da pesquisa"),
_("data/hora da pesquisa"),
null=True,
blank=True
)
pesquisador = models.ForeignKey(
Servidor,
on_delete=models.SET_NULL,
verbose_name=_("Pesquisador"),
verbose_name=_("pesquisador"),
null=True,
blank=True
)
obs_pesquisa = models.TextField(
_("Observações do pesquisador"),
_("observações do pesquisador"),
blank=True
)
ult_alt_endereco = models.DateTimeField(
_('Última alteração do endereço'),
_('última alteração do endereço'),
null=True,
blank=True,
editable=True
)
telefones = GenericRelation('contatos.Telefone')
foto = models.ImageField(
_("Foto"),
_("foto"),
upload_to='imagens/casas',
width_field='foto_largura',
height_field='foto_altura',
blank=True
)
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(
_('Data de instalação da Casa Legislativa'),
_('data de instalação da Casa Legislativa'),
null=True,
blank=True
)
class Meta:
ordering = ('nome',)
verbose_name = _('Órgão')
verbose_name_plural = _('Órgãos')
verbose_name = _('órgão')
verbose_name_plural = _('órgãos')
def lista_gerentes(self, fmt='html'):
if not self.gerentes_interlegis.exists():
@ -168,15 +148,14 @@ class Orgao(models.Model):
@property
def num_parlamentares(self):
if not self.legislatura_set.exists():
return 0
return self.legislatura_set.latest('data_inicio').total_parlamentares
# TODO: Descomentar assim que a app Parlamentares for migrada
# if not self.legislatura_set.exists():
# return 0
# return self.legislatura_set.latest('data_inicio').total_parlamentares
return 0
@property
def telefone(self):
""" Link para acessar diretamente o primeiro telefone cadastrado da casa
Util para relatorios antigos
"""
telefones = self.telefones.all()
if telefones:
return telefones[0]
@ -184,9 +163,6 @@ class Orgao(models.Model):
@property
def presidente(self):
""" Link para acessar diretamente o contato do presidente da casa
Util para relatorios antigos
"""
try:
if self.funcionario_set.filter(setor='presidente').count() > 1:
return self.funcionario_set.filter(setor='presidente')[0]
@ -197,9 +173,6 @@ class Orgao(models.Model):
@property
def contato_interlegis(self):
""" Link para acessar diretamente o contato do presidente da casa
Util para relatorios antigos
"""
try:
if self.funcionario_set.filter(setor='contato_interlegis').count() > 1:
return self.funcionario_set.filter(setor='contato_interlegis')[0]
@ -208,23 +181,6 @@ class Orgao(models.Model):
except Funcionario.DoesNotExist:
return None
@property
def total_parlamentares(self):
"""
Calcula o total de parlamentares atual da Casa:
- O total de parlamentares da legislatura mais recente, ou
- num_parlamentares ou
- 0 se não tiver nenhuma das informações
"""
if self.legislatura_set.exists():
return self.legislatura_set.all()[0].total_parlamentares
if self.num_parlamentares is not None:
return self.num_parlamentares
return 0
def gerarCodigoInterlegis(self):
codigo = self.codigo_interlegis
@ -238,7 +194,8 @@ class Orgao(models.Model):
return codigo
# Se já existe, então trata a Assembleia como uma Casa qualquer.
cityName = normalize('NFKD', unicode(self.municipio.nome)).encode('ascii', 'ignore')
cityName = normalize('NFKD', self.municipio.nome).encode(
'ascii', 'ignore')
cityName = cityName.upper().strip()
cityName = cityName.replace(' DA ', ' ')
cityName = cityName.replace(' DE ', ' ')
@ -315,7 +272,7 @@ class Orgao(models.Model):
return codigo
def __unicode__(self):
def __str__(self):
return self.nome
def clean(self):
@ -347,13 +304,7 @@ class Orgao(models.Model):
return super(Orgao, self).save(*args, **kwargs)
class Funcionario(models.Model):
""" Modelo para registrar contatos vinculados às
Casas Legislativas
"""
SETOR_CHOICES = [
("presidente", _("Presidente")),
("contato_interlegis", _("Contato Interlegis")),
@ -379,42 +330,40 @@ class Funcionario(models.Model):
verbose_name=_("órgão"),
)
nome = models.CharField(_('nome completo'), max_length=60, blank=False)
# nome.alphabetic_filter = True
sexo = models.CharField(
_("Sexo"),
_("sexo"),
max_length=1,
choices=SEXO_CHOICES,
default="M"
)
data_nascimento = models.DateField(
_("Data de nascimento"),
_("data de nascimento"),
blank=True,
null=True
)
nota = models.CharField(
_("Telefones"),
_("telefones"),
max_length=250,
null=True,
blank=True
)
email = models.CharField(_('e-mail'), max_length=250, blank=True)
# endereco = generic.GenericRelation('contatos.Endereco')
endereco = models.CharField(_('Endereço'), max_length=100, blank=True)
endereco = models.CharField(_('endereço'), max_length=100, blank=True)
municipio = models.ForeignKey(
Municipio,
on_delete=models.SET_NULL,
verbose_name=_('Municipio'),
verbose_name=_('municipio'),
null=True,
blank=True,
)
bairro = models.CharField(_('Bairro'), max_length=100, blank=True)
bairro = models.CharField(_('bairro'), max_length=100, blank=True)
cep = models.CharField(_('CEP'), max_length=10, blank=True)
redes_sociais = models.TextField(
_('Redes sociais'),
_('redes sociais'),
help_text=_('Colocar um por linha'),
blank=True
)
cargo = models.CharField(_("Cargo"), max_length=100, null=True, blank=True)
cargo = models.CharField(_("cargo"), max_length=100, null=True, blank=True)
funcao = models.CharField(
_('função'),
max_length=100,
@ -422,46 +371,42 @@ class Funcionario(models.Model):
blank=True
)
setor = models.CharField(
_("Setor"),
_("setor"),
max_length=100,
choices=SETOR_CHOICES,
default="outros"
)
tempo_de_servico = models.CharField(
_('Tempo de serviço'),
_('tempo de serviço'),
max_length=50,
null=True,
blank=True
)
ult_alteracao = models.DateTimeField(
_('Última alteração'),
_('última alteração'),
null=True,
blank=True,
editable=True,
auto_now=True
)
desativado = models.BooleanField(_("Desativado"), default=False)
observacoes = models.TextField(_("Observações"), blank=True)
desativado = models.BooleanField(_("desativado"), default=False)
observacoes = models.TextField(_("observações"), blank=True)
class Meta:
ordering = ('nome',)
verbose_name = _('contato da Casa Legislativa')
verbose_name_plural = _('contatos da Casa Legislativa')
def __unicode__(self):
def __str__(self):
return self.nome
class PresidenteManager(models.Manager):
def get_queryset(self):
qs = super(PresidenteManager, self).get_queryset()
qs = qs.filter(setor='presidente')
return qs
class Presidente(Funcionario):
class Meta:
proxy = True

37
sigi/apps/casas/templates/casas/casas_sem_convenio_pdf.html

@ -0,0 +1,37 @@
{% extends 'pdf/base_report.html' %}
{% load static i18n %}
{% block page_size %}A4 landscape{% endblock %}
{% block main_content %}
<table repeat="1">
<thead>
<tr>
<th style="width: 22.5%;">{% trans 'Casa' %}</th>
<th style="width: 12.5%;">{% trans 'Presidente' %}</th>
<th style="width: 5%;">{% trans 'Tipo' %}</th>
<th style="width: 18%;">{% trans 'Endereço' %}</th>
<th style="width: 10%;">{% trans 'Bairro' %}</th>
<th style="width: 7%;">{% trans 'CEP' %}</th>
<th style="width: 12.5%;">{% trans 'Telefone' %}</th>
<th style="width: 12.5%;">{% trans 'E-mail' %}</th>
</tr>
</thead>
{% for casa in casas %}
{% ifchanged casa.municipio.uf %}
<tr class="title_row"><td colspan="8"><h1>{{ casa.municipio.uf.nome }}</h1></td></tr>
{% endifchanged %}
<tr>
<td>{{ casa.nome }}</td>
<td>{{ casa.presidente }}</td>
<td>{{ casa.tipo.sigla }}</td>
<td>{{ casa.logradouro }}</td>
<td>{{ casa.bairro }}</td>
<td>{{ casa.cep }}</td>
<td>{{ casa.telefone }}</td>
<td>{{ casa.email }}</td>
</tr>
{% endfor %}
</table>
{% endblock main_content %}

132
sigi/apps/casas/templates/casas/report_pdf.html

@ -1,132 +0,0 @@
{% load smart_if %}
{% load static from staticfiles %}
{% load i18n %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Casa Legislativa</title>
<style type="text/css">
table {
padding: 3px;
line-height: 1em;
-fs-table-paginate: paginate;
}
thead {
display: table-header-group;
}
th {
font-weight: bold;
text-align: left;
}
th, td {
border-bottom: 1px solid #ddd;
}
td.logo {
text-align: center;
}
td.header_text p {
margin: 0px;
font-size: 1.4em;
}
td.header_text {
width: 550px;
}
h1 {
font-size: 2em;
text-align: center;
}
h2 {
font-size: 1.7em;
}
h3 {
margin-top: 10px;
margin-bottom: 0px;
}
body {
font-family: "Helvetica, Arial, sans-serif";
font-size: 1.3em;
line-height: 1em;
}
#footer {
text-align: center;
}
@page {
size: a4 landscape;
margin: 3.5cm 2cm 2cm 2cm;
font-family: "Helvetica, Arial, sans-serif";
font-size: 2em;
@frame header {
-pdf-frame-content: header;
top: 1cm;
}
@frame footer {
-pdf-frame-content: footer;
bottom: 0cm;
margin-left: 2cm;
margin-right: 2cm;
height: 1cm;
}
}
</style>
</head>
<body>
<div id="header">
<table>
<tr>
<td class="logo"><img src="{% static 'img/logo-senado.jpg' %}"/></td>
<td class="header_text">
<p><strong>{% trans 'SENADO FEDERAL' %}</strong></p>
<p><strong>{% trans 'ILB - Interlegis' %}</strong></p>
<p>{{ title }}</p>
</td>
<td class="logo"><img src="{% static 'img/logo-interlegis.jpg' %}"/></td>
</tr>
</table>
</div>
<table repeat="1">
<thead>
<tr>
<th style="width: 22.5%;">{% trans 'Casa' %}</th>
<th style="width: 12.5%;">{% trans 'Presidente' %}</th>
<th style="width: 5%;">{% trans 'Tipo' %}</th>
<th style="width: 18%;">{% trans 'Endereço' %}</th>
<th style="width: 10%;">{% trans 'Bairro' %}</th>
<th style="width: 7%;">{% trans 'CEP' %}</th>
<th style="width: 12.5%;">{% trans 'Telefone' %}</th>
<th style="width: 12.5%;">{% trans 'E-mail' %}</th>
</tr>
</thead>
{% for casa in casas %}
{% ifchanged casa.municipio.uf %}
<tr><td colspan="8"><h3>{{ casa.municipio.uf.nome }}</h3></td></tr>
{% endifchanged %}
<tr>
<td>{{ casa.nome }}</td>
<td>{{ casa.presidente }}</td>
<td>{{ casa.tipo.sigla }}</td>
<td>{{ casa.logradouro }}</td>
<td>{{ casa.bairro }}</td>
<td>{{ casa.cep }}</td>
<td>{{ casa.telefone }}</td>
<td>{{ casa.email }}</td>
</tr>
{% endfor %}
</table>
<div id="footer">
{%block page_foot%}
{% trans 'Página' %} <pdf:pagenumber>
{%endblock%}
</div>
</body>
</html>

3
sigi/apps/casas/tests.py

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

12
sigi/apps/casas/urls.py

@ -1,4 +1,13 @@
# coding: utf-8
from django.urls import path, include
from sigi.apps.casas.views import CasasSemConvenioReport
urlpatterns = [
path('orgao/casas_sem_convenio_report/', CasasSemConvenioReport.as_view(),
name='casas-sem-convenio-report'),
]
"""
from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required
from sigi.apps.casas.views import importa_casas
@ -55,3 +64,4 @@ urlpatterns = patterns(
url(r'^gerentes/$', 'gerentes_interlegis',
name='gerentes_interlegis'),
)
"""

2163
sigi/apps/casas/views.py

File diff suppressed because it is too large

4
sigi/settings/base.py

@ -21,7 +21,9 @@ BASE_DIR = Path(__file__).resolve().parent.parent
INSTALLED_APPS = [
'sigi.apps.servidores',
'sigi.apps.contatos',
'sigi.apps.casas',
'django_bootstrap5',
'localflavor',
'django.forms',
'django.contrib.admin',
'django.contrib.auth',
@ -85,6 +87,8 @@ USE_THOUSAND_SEPARATOR = True
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / "static",]
STATIC_ROOT = '/var/www/sigi/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

5
sigi/settings/development.py

@ -50,3 +50,8 @@ AUTH_PASSWORD_VALIDATORS = [
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_ROOT = BASE_DIR / '../static/'

BIN
sigi/static/img/logo-interlegis.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
sigi/static/img/logo-senado.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

2
templates/change_list_with_cart.html → sigi/templates/change_list_with_cart.html

@ -1,5 +1,5 @@
{% extends "admin/change_list.html" %}
{% load admin_list i18n reporting_tags %}
{% load admin_list i18n %}
{% block object-tools-items %}
<li><a class="btn" href="carrinho/{{query_str}}">

45
sigi/templates/pdf/base.html

@ -0,0 +1,45 @@
{% load static i18n %}
<!DOCTYPE HTML>
<html lang="pt-BR">
<head>
<meta charset="utf-8"/>
<meta name="description" content="SIGI reports">
<meta name="author" content="Interlegis">
<style type="text/css">
@page {
size: {% block page_size %}A4 portrait{% endblock page_size %};
margin: {% block page_margin %}3cm 2cm 2cm 2cm{% endblock page_margin %};
font-family: "Helvetica, Arial, sans-serif";
font-size: 10px;
@top-right { content: url("{% static 'img/logo-interlegis.png' %}");}
@top-left {content: url("{% static 'img/logo-senado.png' %}");}
@top-center { content: element(header); }
@bottom-center { content: element(footer); }
@bottom-right { content: "{% trans "Página: " %}" counter(page); }
{% block extra_page_settings %}{% endblock extra_page_settings %}
}
h1 { bookmark-level: 1 }
h2 { bookmark-level: 2 }
h3 { bookmark-level: 3 }
h4 { bookmark-level: 4 }
h5 { bookmark-level: 5 }
h6 { bookmark-level: 6 }
@media print {
header {position: running(header);}
footer {position: running(footer);}
}
@media print {
}
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 10px;
}
{% block extra_style %}{% endblock extra_style %}
</style>
{% block extra_head %}{% endblock extra_head %}
<title>{% block title %}{% endblock title %}</title>
</head>
<body class="{% block body_class %}{% endblock body_class %}">
{% block body_content %}{% endblock body_content %}
</body>
</html>

59
sigi/templates/pdf/base_report.html

@ -0,0 +1,59 @@
{% extends 'pdf/base.html' %}
{% load static i18n %}
{% block title %}{{ title }}{% endblock title %}
{% block extra_style %}
h1, h2, h3, h4, h5, h6 {
margin: 0;
}
h1 {font-size: 1.6em;}
h2 {font-size: 1.5em;}
h3 {font-size: 1.4em;}
h4 {font-size: 1.3em;}
h5 {font-size: 1.2em;}
h6 {font-size: 1.1em;}
header {
font-size: 1.4em;
font-weight: bold;
text-align: center;
}
header p {
margin: 5px;
}
.report_name {
font-size: 1.6em;
}
table {
border: 2px white;
width: 100%;
}
th,td {
padding: 4px;
}
th {
background-color: #007433;
color: white;
}
tr:nth-child(even) {
background-color: #d2d2d2;
}
.title_row {
background-color: #b2b2b2;
}
{% endblock extra_style %}
{% block body_content %}
<header>{% block header %}
<p>{% trans 'SENADO FEDERAL' %}</p>
<p>{% trans 'Instituto Legislativo Brasileiro - ILB' %}</p>
<p>{% trans "INTERLEGIS" %}</p>
<p class="report_name">{{ title|upper }}</p>{% endblock header %}
</header>
<footer>{% block footer %}
<p>{% trans 'Emitido em ' %}{% now "DATETIME_FORMAT" %}</p>{% endblock footer %}
</footer>
{% block main_content %}{% endblock main_content %}
{% endblock body_content %}

1
sigi/urls.py

@ -18,6 +18,7 @@ from django.urls import path, include
from django.conf import settings
urlpatterns = [
path('admin/casas/', include('sigi.apps.casas.urls')),
path('admin/', admin.site.urls),
]

BIN
sigiStatic/img/logo-interlegis.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

BIN
sigiStatic/img/logo-senado.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Loading…
Cancel
Save