diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py
index a5eb2f7..3685f93 100644
--- a/sigi/apps/casas/admin.py
+++ b/sigi/apps/casas/admin.py
@@ -374,6 +374,23 @@ class ServicoFilter(admin.SimpleListFilter):
return queryset.distinct('municipio__uf__nome', 'nome')
+class ServicoAtivoFilter(admin.SimpleListFilter):
+ title = _(u"Serviço ativo")
+ parameter_name = 'ativo'
+
+ def lookups(self, request, model_admin):
+ return (
+ ('ativo', _(u"Ativo")),
+ ('desativado', _(u"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
@admin.register(Orgao)
class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin):
form = OrgaoForm
@@ -384,7 +401,7 @@ class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin):
'get_servicos')
list_display_links = ('sigla', 'nome',)
list_filter = ('tipo', ('gerentes_interlegis', GerentesInterlegisFilter),
- 'municipio__uf__nome', ConvenioFilter, ExcluirConvenioFilter, ServicoFilter,
+ 'municipio__uf__nome', ConvenioFilter, ServicoAtivoFilter, ExcluirConvenioFilter, ServicoFilter,
'inclusao_digital',)
ordering = ('municipio__uf__nome', 'nome')
queryset = queryset_ascii
diff --git a/sigi/apps/casas/models.py b/sigi/apps/casas/models.py
index 29c93e8..1ca27b7 100644
--- a/sigi/apps/casas/models.py
+++ b/sigi/apps/casas/models.py
@@ -194,6 +194,19 @@ class Orgao(models.Model):
return self.funcionario_set.get(setor='presidente')
except Funcionario.DoesNotExist:
return None
+
+ @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]
+ else:
+ return self.funcionario_set.get(setor='contato_interlegis')
+ except Funcionario.DoesNotExist:
+ return None
@property
def total_parlamentares(self):
diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py
index 328f46f..971dd1e 100644
--- a/sigi/apps/convenios/admin.py
+++ b/sigi/apps/convenios/admin.py
@@ -62,15 +62,15 @@ class ConvenioAdmin(BaseModelAdmin):
'data_pub_diario',)}
),
(_(u'Gescon'),
- {'fields': ('atualizacao_gescon', 'observacao_gescon',)}
+ {'fields': ('atualizacao_gescon', 'observacao_gescon', 'link_gescon')}
),
)
- readonly_fields = ('data_sigi', 'atualizacao_gescon', 'observacao_gescon',)
+ readonly_fields = ('data_sigi', 'atualizacao_gescon', 'observacao_gescon', 'link_gescon')
actions = ['adicionar_convenios']
inlines = (AnexosInline,)
- list_display = ('num_convenio', 'casa_legislativa', 'get_uf',
+ list_display = ('num_convenio', 'projeto','casa_legislativa', 'get_uf',
'status_convenio', 'link_sigad', 'data_retorno_assinatura',
- 'data_termino_vigencia', 'projeto',)
+ 'data_termino_vigencia',)
list_display_links = ('num_convenio', 'casa_legislativa',)
list_filter = (('casa_legislativa__gerentes_interlegis',
GerentesInterlegisFilter), 'projeto',
@@ -115,6 +115,16 @@ class ConvenioAdmin(BaseModelAdmin):
link_sigad.short_description = _("Processo no Senado")
link_sigad.allow_tags = True
+ def link_gescon(self, obj):
+ if not obj.id_contrato_gescon:
+ return u""
+ return (
+ u"https://adm.senado.gov.br/"
+ u"gestao-contratos/api/{id}").format(id=obj.id_contrato_gescon)
+ link_gescon.short_description = _("Download MINUTA ASSINADA do Gescon")
+ link_gescon.allow_tags = True
+
def changelist_view(self, request, extra_context=None):
from sigi.apps.convenios.views import normaliza_data
request.GET._mutable = True
diff --git a/sigi/apps/convenios/migrations/0017_convenio_id_contrato_gescon.py b/sigi/apps/convenios/migrations/0017_convenio_id_contrato_gescon.py
new file mode 100644
index 0000000..83bddab
--- /dev/null
+++ b/sigi/apps/convenios/migrations/0017_convenio_id_contrato_gescon.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', '0016_auto_20210909_0732'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='convenio',
+ name='id_contrato_gescon',
+ field=models.CharField(default=b'', verbose_name='ID do contrato no Gescon', max_length=20, editable=False, blank=True),
+ preserve_default=True,
+ ),
+ ]
diff --git a/sigi/apps/convenios/migrations/0018_auto_20211208_1256.py b/sigi/apps/convenios/migrations/0018_auto_20211208_1256.py
new file mode 100644
index 0000000..ed6b3c2
--- /dev/null
+++ b/sigi/apps/convenios/migrations/0018_auto_20211208_1256.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('convenios', '0017_convenio_id_contrato_gescon'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='convenio',
+ name='projeto',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, verbose_name='Tipo de Convenio', to='convenios.Projeto'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py
index cabc724..7e69675 100644
--- a/sigi/apps/convenios/models.py
+++ b/sigi/apps/convenios/models.py
@@ -57,6 +57,7 @@ class Convenio(models.Model):
projeto = models.ForeignKey(
Projeto,
on_delete=models.PROTECT,
+ verbose_name=_(u'Tipo de Convenio')
)
# numero designado pelo Senado Federal para o convênio
num_processo_sf = models.CharField(
@@ -71,6 +72,13 @@ class Convenio(models.Model):
max_length=10,
blank=True
)
+ id_contrato_gescon = models.CharField(
+ _(u"ID do contrato no Gescon"),
+ max_length=20,
+ blank=True,
+ default="",
+ editable=False
+ )
data_sigi = models.DateField(
_(u"data de cadastro no SIGI"),
blank=True,
@@ -504,7 +512,7 @@ class Gescon(models.Model):
self.add_message(
_(u"\tErro ao acessar {url}: {errmsg}").format(
url=url,
- errmsg=str(e)
+ errmsg=e.message.decode("utf8")
)
)
continue
@@ -734,6 +742,12 @@ class Gescon(models.Model):
'terminoVigencia'
]
convenio.data_pub_diario = contrato['publicacao']
+ if contrato['codTextoContrato']:
+ convenio.id_contrato_gescon = contrato[
+ 'codTextoContrato'
+ ]
+ else:
+ convenio.id_contrato_gescon = ""
try:
convenio.save()
@@ -748,7 +762,7 @@ class Gescon(models.Model):
convenio._meta.model_name),
args=[convenio.id]
),
- errmsg=str(e)
+ errmsg=e.message.decode("utf8")
)
)
erros += 1
diff --git a/sigi/apps/convenios/reports.py b/sigi/apps/convenios/reports.py
index f873f2e..dea94fc 100644
--- a/sigi/apps/convenios/reports.py
+++ b/sigi/apps/convenios/reports.py
@@ -54,19 +54,19 @@ class ConvenioReport(ReportDefault):
),
Label(
text=_(u"Projeto"),
- left=label_left[5] * cm,
+ left=label_left[3] * cm,
top=label_top + 0.4 * cm,
width=2 * cm,
),
Label(
text=_(u"Data do Convênio"),
- left=label_left[3] * cm,
+ left=label_left[4] * cm,
top=label_top,
width=2 * cm,
),
Label(
text=_(u"Data de Publicação"),
- left=label_left[4] * cm,
+ left=label_left[5] * cm,
top=label_top,
width=2 * cm,
),
@@ -100,17 +100,17 @@ class ConvenioReport(ReportDefault):
),
ObjectValue(
attribute_name='projeto.sigla',
- left=label_left[5] * cm
+ left=label_left[3] * cm
),
ObjectValue(
attribute_name='data_retorno_assinatura',
- left=label_left[3] * cm,
+ left=label_left[4] * cm,
get_value=lambda instance:
instance.data_retorno_assinatura.strftime('%d/%m/%Y') if instance.data_retorno_assinatura is not None else '-'
),
ObjectValue(
attribute_name='data_pub_diario',
- left=label_left[4] * cm,
+ left=label_left[5] * cm,
get_value=lambda instance:
instance.data_pub_diario.strftime('%d/%m/%Y') if instance.data_pub_diario is not None else '-'
),
@@ -163,13 +163,13 @@ class ConvenioReportSemAceite(ConvenioReport):
),
Label(
text=_(u"Projeto"),
- left=label_left[4] * cm,
+ left=label_left[3] * cm,
top=label_top,
width=2 * cm,
),
Label(
text=_(u"Data do Convênio"),
- left=label_left[3] * cm,
+ left=label_left[4] * cm,
top=label_top,
width=2 * cm,
),
@@ -200,11 +200,11 @@ class ConvenioReportSemAceite(ConvenioReport):
),
ObjectValue(
attribute_name='projeto.sigla',
- left=label_left[4],
+ left=label_left[3],
),
ObjectValue(
attribute_name='data_retorno_assinatura',
- left=label_left[3] * cm,
+ left=label_left[4] * cm,
get_value=lambda instance:
instance.data_retorno_assinatura.strftime('%d/%m/%Y') if instance.data_retorno_assinatura is not None else '-'
),
diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py
index 048ce57..198ef32 100644
--- a/sigi/apps/eventos/admin.py
+++ b/sigi/apps/eventos/admin.py
@@ -23,7 +23,8 @@ from django.contrib import admin
from django.db import models
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _
-from sigi.apps.eventos.models import ModeloDeclaracao, Modulo, TipoEvento, Funcao, Evento, Equipe, Convite
+from sigi.apps.eventos.models import (ModeloDeclaracao, Modulo, TipoEvento,
+ Funcao, Evento, Equipe, Convite, Anexo)
from sigi.apps.eventos.views import adicionar_eventos_carrinho
from sigi.apps.eventos.forms import EventoAdminForm
@@ -50,6 +51,10 @@ class ConviteInline(admin.TabularInline):
class ModuloInline(admin.TabularInline):
model = Modulo
+class AnexoInline(admin.TabularInline):
+ model = Anexo
+ exclude = ('data_pub',)
+
@admin.register(Evento)
class EventoAdmin(admin.ModelAdmin):
form = EventoAdminForm
@@ -62,7 +67,7 @@ class EventoAdmin(admin.ModelAdmin):
raw_id_fields = ('casa_anfitria', 'municipio',)
search_fields = ('nome', 'tipo_evento__nome', 'casa_anfitria__search_text',
'municipio__search_text', 'solicitante')
- inlines = (EquipeInline, ConviteInline, ModuloInline)
+ inlines = (EquipeInline, ConviteInline, ModuloInline, AnexoInline)
actions = ['adicionar_eventos', ]
def adicionar_eventos(self, request, queryset):
diff --git a/sigi/apps/eventos/migrations/0014_auto_20211124_0736.py b/sigi/apps/eventos/migrations/0014_auto_20211124_0736.py
new file mode 100644
index 0000000..8c5619d
--- /dev/null
+++ b/sigi/apps/eventos/migrations/0014_auto_20211124_0736.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import tinymce.models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('eventos', '0013_modelodeclaracao'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='modelodeclaracao',
+ name='texto',
+ field=tinymce.models.HTMLField(help_text='Use as seguintes marca\xe7\xf5es:
- {{ casa.nome }} para o nome da Casa Legislativa / \xf3rg\xe3o
- {{ casa.municipio.uf.sigla }} para a sigla da UF da Casa legislativa
- {{ nome }} para o nome do visitante
- {{ data }} para a data de emiss\xe3o da declara\xe7\xe3o
- {{ evento.data_inicio }} para a data/hora do in\xedcio da visita
- {{ evento.data_termino }} para a data/hora do t\xe9rmino da visita
- {{ evento.nome }} para o nome do evento
- {{ evento.descricao }} para a descri\xe7\xe3o do evento
', verbose_name='Texto da declara\xe7\xe3o'),
+ preserve_default=True,
+ ),
+ ]
diff --git a/sigi/apps/eventos/migrations/0015_anexo.py b/sigi/apps/eventos/migrations/0015_anexo.py
new file mode 100644
index 0000000..8dab092
--- /dev/null
+++ b/sigi/apps/eventos/migrations/0015_anexo.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import datetime
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('eventos', '0014_auto_20211124_0736'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Anexo',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('arquivo', models.FileField(max_length=500, upload_to=b'apps/eventos/anexo/arquivo')),
+ ('descricao', models.CharField(max_length=b'70', verbose_name='descri\xe7\xe3o')),
+ ('data_pub', models.DateTimeField(default=datetime.datetime.now, verbose_name='data da publica\xe7\xe3o do anexo')),
+ ('evento', models.ForeignKey(verbose_name='evento', to='eventos.Evento')),
+ ],
+ options={
+ 'ordering': ('-data_pub',),
+ },
+ bases=(models.Model,),
+ ),
+ ]
diff --git a/sigi/apps/eventos/models.py b/sigi/apps/eventos/models.py
index 9a11315..041fb0e 100644
--- a/sigi/apps/eventos/models.py
+++ b/sigi/apps/eventos/models.py
@@ -262,8 +262,10 @@ class ModeloDeclaracao(models.Model):
)
texto = HTMLField(
_(u"Texto da declaração"),
- help_text=_(u"Use as seguintes marcações:- {{ casa }} para o "
- u"nome da Casa Legislativa / órgão
- {{ nome }} "
+ help_text=_(u"Use as seguintes marcações:
- {{ casa.nome }} para o"
+ u" nome da Casa Legislativa / órgão
"
+ u"- {{ casa.municipio.uf.sigla }} para a sigla da UF da "
+ u"Casa legislativa
- {{ nome }} "
u"para o nome do visitante
- {{ data }} para a data "
u"de emissão da declaração
- {{ evento.data_inicio }}"
u" para a data/hora do início da visita
"
@@ -282,3 +284,23 @@ class ModeloDeclaracao(models.Model):
nome=self.nome,
formato=self.get_formato_display()
)
+
+class Anexo(models.Model):
+ evento = models.ForeignKey(
+ Evento,
+ on_delete=models.CASCADE,
+ verbose_name=_(u'evento')
+ )
+ # caminho no sistema para o documento anexo
+ arquivo = models.FileField(upload_to='apps/eventos/anexo/arquivo', max_length=500)
+ descricao = models.CharField(_(u'descrição'), max_length='70')
+ data_pub = models.DateTimeField(
+ _(u'data da publicação do anexo'),
+ default=datetime.now
+ )
+
+ class Meta:
+ ordering = ('-data_pub',)
+
+ def __unicode__(self):
+ return unicode("%s publicado em %s" % (self.descricao, self.data_pub))
diff --git a/sigi/apps/eventos/templates/eventos/declaracao_pdf.html b/sigi/apps/eventos/templates/eventos/declaracao_pdf.html
index ec00d5d..d545fe4 100644
--- a/sigi/apps/eventos/templates/eventos/declaracao_pdf.html
+++ b/sigi/apps/eventos/templates/eventos/declaracao_pdf.html
@@ -6,7 +6,7 @@
{% block report %}
{% for convite in evento.convite_set.all %}
- {% with convite.casa.nome as casa %}
+ {% with convite.casa as casa %}
{% for nome in convite.nomes_participantes.splitlines %}
{% block text_body %}{% endblock %}
diff --git a/sigi/apps/metas/templates/metas/openmap.html b/sigi/apps/metas/templates/metas/openmap.html
index 067cbd1..20987d0 100644
--- a/sigi/apps/metas/templates/metas/openmap.html
+++ b/sigi/apps/metas/templates/metas/openmap.html
@@ -46,7 +46,7 @@
-
+
diff --git a/sigi/apps/metas/templatetags/mapa_tags.py b/sigi/apps/metas/templatetags/mapa_tags.py
index 273176a..bd71770 100644
--- a/sigi/apps/metas/templatetags/mapa_tags.py
+++ b/sigi/apps/metas/templatetags/mapa_tags.py
@@ -3,7 +3,7 @@ from django import template
from django.utils.safestring import mark_safe
from sigi.apps.casas.models import Orgao
-from sigi.apps.metas.views import parliament_summary
+from sigi.apps.metas.views import openmap
register = template.Library()
@@ -14,7 +14,7 @@ def descricao_servicos(casa):
if not isinstance(casa, Orgao):
return ""
- summary = parliament_summary(casa)
+ summary = openmap(casa)
result = ''.join('
- %s
' % info for info in summary['info'])
return mark_safe(result)
descricao_servicos.is_safe = True
diff --git a/sigi/apps/metas/views.py b/sigi/apps/metas/views.py
index 6a8f9c9..59b22f3 100644
--- a/sigi/apps/metas/views.py
+++ b/sigi/apps/metas/views.py
@@ -232,4 +232,4 @@ def openmapsearch(request):
'label': d['nome'],
'lat': d['municipio__latitude'],
'lng': d['municipio__longitude']} for d in dados]
- return JsonResponse(list(dados), safe=False)
\ No newline at end of file
+ return JsonResponse(list(dados), safe=False)
diff --git a/sigi/apps/servicos/admin.py b/sigi/apps/servicos/admin.py
index 5d38565..d1d9a29 100644
--- a/sigi/apps/servicos/admin.py
+++ b/sigi/apps/servicos/admin.py
@@ -11,6 +11,7 @@ from sigi.apps.casas.admin import FuncionariosInline, GerentesInterlegisFilter
from sigi.apps.casas.models import Orgao
from sigi.apps.servicos.models import (Servico, LogServico, CasaAtendida,
TipoServico)
+from sigi.apps.servicos.views import adicionar_servicos_carrinho
from sigi.apps.utils.base_admin import BaseModelAdmin
@@ -111,6 +112,7 @@ class ServicoAtivoFilter(admin.SimpleListFilter):
return queryset
class ServicoAdmin(BaseModelAdmin):
+ change_list_template = "servico/change_list.html"
form = ServicoFormAdmin
actions = ['calcular_data_uso', ]
list_display = ('casa_legislativa', 'get_codigo_interlegis', 'get_uf', 'tipo_servico', 'hospedagem_interlegis',
@@ -137,6 +139,7 @@ class ServicoAdmin(BaseModelAdmin):
'casa_legislativa__municipio__uf',
)
list_display_links = []
+ actions = ['adicionar_servicos']
ordering = ('casa_legislativa__municipio__uf', 'casa_legislativa', 'tipo_servico',)
inlines = (LogServicoInline,)
search_fields = ('casa_legislativa__search_text',)
@@ -169,6 +172,22 @@ class ServicoAdmin(BaseModelAdmin):
get_link_erro.short_description = _(u"Erro na atualização")
get_link_erro.admin_order_field = 'erro_atualizacao'
+ def adicionar_servicos(self, request, queryset):
+ if 'carrinho_servicos' in request.session:
+ q1 = len(request.session['carrinho_servicos'])
+ else:
+ q1 = 0
+ adicionar_servicos_carrinho(request, queryset=queryset)
+ q2 = len(request.session['carrinho_servicos'])
+ quant = q2 - q1
+ if quant:
+ self.message_user(request, str(q2 - q1) + _(u" Serviços adicionados no carrinho"))
+ else:
+ self.message_user(request, _(u"Os Serviços selecionados já foram adicionadas anteriormente"))
+ return HttpResponseRedirect('.')
+ adicionar_servicos.short_description = _(u"Armazenar serviços no carrinho para exportar")
+
+
def calcular_data_uso(self, request, queryset):
for servico in queryset:
servico.atualiza_data_uso()
@@ -186,7 +205,7 @@ class ServicoAdmin(BaseModelAdmin):
def lookup_allowed(self, lookup, value):
return super(ServicoAdmin, self).lookup_allowed(lookup, value) or \
- lookup in ['casa_legislativa__municipio__uf__codigo_ibge__exact']
+ lookup in ['casa_legislativa__municipio__uf__codigo_ibge__exact', ]
def add_view(self, request, form_url='', extra_context=None):
id_casa = request.GET.get('id_casa', None)
@@ -234,6 +253,34 @@ class ServicoAdmin(BaseModelAdmin):
obj.casa_legislativa = Orgao.objects.get(pk=id_casa)
return obj
+
+ def changelist_view(self, request, extra_context=None):
+ from sigi.apps.convenios.views import normaliza_data
+ request.GET._mutable = True
+ normaliza_data(request.GET, 'data_ativacao__gte')
+ normaliza_data(request.GET, 'data_ativacao__lte')
+ request.GET._mutable = False
+
+ return super(ServicoAdmin, self).changelist_view(
+ request,
+ extra_context={'query_str': '?' + request.META['QUERY_STRING']}
+ )
+
+ def adicionar_servicos(self, request, queryset):
+ if 'carrinho_servicos' in request.session:
+ q1 = len(request.session['carrinho_servicos'])
+ else:
+ q1 = 0
+ adicionar_servicos_carrinho(request, queryset=queryset)
+ q2 = len(request.session['carrinho_servicos'])
+ quant = q2 - q1
+ if quant:
+ self.message_user(request, str(q2 - q1) + _(u" Convênios adicionados no carrinho"))
+ else:
+ self.message_user(request, _(u"Os Convênios selecionados já foram adicionadas anteriormente"))
+ return HttpResponseRedirect('.')
+ adicionar_servicos.short_description = _(u"Armazenar Serviços no carrinho para exportar")
+
class ContatosInline(FuncionariosInline):
diff --git a/sigi/apps/servicos/templates/admin/servicos/servico/change_list.html b/sigi/apps/servicos/templates/admin/servicos/servico/change_list.html
deleted file mode 100644
index 9d35d68..0000000
--- a/sigi/apps/servicos/templates/admin/servicos/servico/change_list.html
+++ /dev/null
@@ -1,4 +0,0 @@
-{% extends "admin/change_list.html" %}
-
-{% block object-tools-items %}
-{% endblock %}
\ No newline at end of file
diff --git a/sigi/apps/servicos/templates/servico/change_list.html b/sigi/apps/servicos/templates/servico/change_list.html
new file mode 100644
index 0000000..cc44655
--- /dev/null
+++ b/sigi/apps/servicos/templates/servico/change_list.html
@@ -0,0 +1,33 @@
+{% extends "change_list_with_cart.html" %}
+{% load i18n %}
+
+
+{% block extra_search %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/sigi/apps/servicos/templates/servicos/carrinho.html b/sigi/apps/servicos/templates/servicos/carrinho.html
new file mode 100644
index 0000000..c3b6994
--- /dev/null
+++ b/sigi/apps/servicos/templates/servicos/carrinho.html
@@ -0,0 +1,100 @@
+{% extends "admin/carrinho.html" %}
+{% load admin_list i18n %}
+{% block extrastyle %}
+ {{ block.super }}
+ {% include "admin/tabs_style.html" %}
+{% endblock %}
+
+{% block title %}{% trans 'Serviços no Carrinho | SIGI' %}{% endblock %}
+{% block content_title %}
{% trans 'Serviços no Carrinho' %}
{% endblock %}
+
+{% block mensagem%}
+
+ {%if carIsEmpty%}
+ - {% trans 'O carrinho está vazio, sendo assim todos os Serviços entram na lista para exportação de acordo com os filtros aplicados.' %}
+ {%else%}
+ - {{paginas.paginator.count}} {% trans 'Serviços no carrinho' %}.
+ {%endif%}
+
+{% endblock %}
+
+{% block action %}deleta_itens_carrinho{% endblock %}
+
+{% block tabela %}
+
+{% endblock %}
+
+{% block botoes %}
+
+
+ {% endblock %}
diff --git a/sigi/apps/servicos/urls.py b/sigi/apps/servicos/urls.py
index 8c91807..fb40db4 100644
--- a/sigi/apps/servicos/urls.py
+++ b/sigi/apps/servicos/urls.py
@@ -9,6 +9,10 @@ urlpatterns = patterns(
'sigi.apps.servicos.views',
url(r'^manifesta/$', 'casa_manifesta_view', name="casa-manifesta-view"),
+ url(r'^servico/carrinho/$', 'visualizar_carrinho', name='visualizar-carrinho'),
+ url(r'^servico/carrinho/excluir_carrinho/$', 'excluir_carrinho', name='excluir-carrinho'), # tagerror
+ url(r'^servico/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho', name='deleta-itens-carrinho'), # tagerror
+ url(r'^servico/csv/$', 'export_csv', name='servicos-csv'),
url(r'^munatenjson/(?P
\w+)/$', 'municipios_atendidos', name="municipios-atendidos"),
url(r'^mapa/(?P\w+)/$', MapaView.as_view(), name="servicos-mapa"),
# url(r'^listacasas/(?P\w+)', 'casas_usam_servico', name="casas-usam-servico"),
diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py
index d49bcd9..c5b5be7 100644
--- a/sigi/apps/servicos/views.py
+++ b/sigi/apps/servicos/views.py
@@ -1,18 +1,24 @@
# -*- coding: utf-8 -*-
+import csv
import json as simplejson # XXX trocar isso por simplesmente import json e refatorar o codigo
from django import forms
+from django.contrib import messages
+from django.contrib.auth.decorators import login_required
+from django.core.paginator import EmptyPage, InvalidPage, Paginator
from django.db.models import Q
from django.forms.forms import BoundField
from django.http import HttpResponse
-from django.shortcuts import render_to_response, get_object_or_404
+from django.http.response import HttpResponseRedirect
+from django.shortcuts import render, render_to_response, get_object_or_404
from django.template.context import RequestContext
from django.utils.translation import ugettext as _
from django.views.generic.base import TemplateView
from sigi.apps.casas.models import Orgao
from sigi.apps.contatos.models import UnidadeFederativa
-from sigi.apps.servicos.models import (TipoServico, CasaManifesta, CasaAtendida,
+from sigi.apps.convenios.views import normaliza_data, query_ordena
+from sigi.apps.servicos.models import (Servico, TipoServico, CasaManifesta, CasaAtendida,
ServicoManifesto)
@@ -144,3 +150,187 @@ def casa_manifesta_view(request):
extra_context = {'uf_list': UnidadeFederativa.objects.all()}
return render_to_response('servicos/casa_manifesta.html', extra_context, context_instance=RequestContext(request))
+
+def adicionar_servicos_carrinho(request, queryset=None, id=None):
+ if request.method == 'POST':
+ ids_selecionados = request.POST.getlist('_selected_action')
+ if 'carrinho_servicos' not in request.session:
+ request.session['carrinho_servicos'] = ids_selecionados
+ else:
+ lista = request.session['carrinho_servicos']
+ # Verifica se id já não está adicionado
+ for id in ids_selecionados:
+ if id not in lista:
+ lista.append(id)
+ request.session['carrinho_servicos'] = lista
+
+def carrinhoOrGet_for_qs(request):
+ """
+ Verifica se existe convênios na sessão se não verifica get e retorna qs correspondente.
+ """
+ if 'carrinho_servicos' in request.session:
+ ids = request.session['carrinho_servicos']
+ qs = Servico.objects.filter(pk__in=ids)
+ qs = qs.order_by("casa_legislativa__municipio__uf", "casa_legislativa__municipio")
+ qs = get_for_qs(request.GET, qs)
+ else:
+ qs = Servico.objects.all()
+ if request.GET:
+ qs = qs.order_by("casa_legislativa__municipio__uf", "casa_legislativa__municipio")
+ qs = get_for_qs(request.GET, qs)
+ return qs
+
+
+def adicionar_servicos_carrinho(request, queryset=None, id=None):
+ if request.method == 'POST':
+ ids_selecionados = request.POST.getlist('_selected_action')
+ if 'carrinho_servicos' not in request.session:
+ request.session['carrinho_servicos'] = ids_selecionados
+ else:
+ lista = request.session['carrinho_servicos']
+ # Verifica se id já não está adicionado
+ for id in ids_selecionados:
+ if id not in lista:
+ lista.append(id)
+ request.session['carrinho_servicos'] = lista
+
+@login_required
+def excluir_carrinho(request):
+ if 'carrinho_servicos' in request.session:
+ del request.session['carrinho_servicos']
+ messages.info(request, u'O carrinho foi esvaziado')
+ return HttpResponseRedirect('../../')
+
+@login_required
+def deleta_itens_carrinho(request):
+ if request.method == 'POST':
+ ids_selecionados = request.POST.getlist('_selected_action')
+ if 'carrinho_servicos' in request.session:
+ lista = request.session['carrinho_servicos']
+ for item in ids_selecionados:
+ lista.remove(item)
+ if lista:
+ request.session['carrinho_servicos'] = lista
+ else:
+ del lista
+ del request.session['carrinho_servicos']
+
+ return HttpResponseRedirect('.')
+
+@login_required
+def visualizar_carrinho(request):
+
+ qs = carrinhoOrGet_for_qs(request)
+
+ paginator = Paginator(qs, 100)
+
+ # Make sure page request is an int. If not, deliver first page.
+ # Esteja certo de que o `page request` é um inteiro. Se não, mostre a primeira página.
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ # Se o page request (9999) está fora da lista, mostre a última página.
+ try:
+ paginas = paginator.page(page)
+ except (EmptyPage, InvalidPage):
+ paginas = paginator.page(paginator.num_pages)
+
+ carrinhoIsEmpty = not('carrinho_servicos' in request.session)
+
+ return render(
+ request,
+ 'servicos/carrinho.html',
+ {
+ 'carIsEmpty': carrinhoIsEmpty,
+ 'paginas': paginas,
+ 'query_str': '?' + request.META['QUERY_STRING']
+ }
+ )
+
+def get_for_qs(get, qs):
+ kwargs = {}
+ ids = 0
+ get._mutable = True
+ normaliza_data(get, 'data_ativacao__gte')
+ normaliza_data(get, 'data_ativacao__lte')
+ get._mutable = False
+ for k, v in get.iteritems():
+ if k not in ['page', 'pop', 'q', '_popup']:
+ if not k == 'o':
+ if k == "ot":
+ qs = query_ordena(qs, get["o"], get["ot"])
+ else:
+ kwargs[str(k)] = v
+ if(str(k) == 'ids'):
+ ids = 1
+ break
+ qs = qs.filter(**kwargs)
+ if ids:
+ query = 'id IN (' + kwargs['ids'].__str__() + ')'
+ qs = Servico.objects.extra(where=[query])
+ return qs
+
+@login_required
+def export_csv(request):
+ response = HttpResponse(content_type='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=servicos.csv'
+
+ csv_writer = csv.writer(response)
+ servicos = carrinhoOrGet_for_qs(request)
+ if not servicos:
+ return HttpResponseRedirect('../')
+
+ atributos = [_(u"Casa Legislativa"), _(u"Contato Interlegis"), _(u"Produto"),
+ _(u"Data de Ativação"), ]
+
+ if request.POST:
+ atributos = request.POST.getlist("itens_csv_selected")
+
+ col_titles = atributos
+ if _(u"Casa Legislativa") in col_titles:
+ pos = col_titles.index(_(u"Casa Legislativa")) + 1
+ col_titles.insert(pos, _(u"uf"))
+ pos+=1
+ col_titles.insert(pos, _(u"email"))
+ pos+=1
+ col_titles.insert(pos, _(u"telefone"))
+
+ if _(u"Contato Interlegis") in col_titles:
+ pos = col_titles.index(_(u"Contato Interlegis")) + 1
+ col_titles.insert(pos, _(u"Email do contato"))
+
+ csv_writer.writerow([s.encode("utf-8") for s in col_titles])
+
+ for servico in servicos:
+ lista = []
+ for atributo in atributos:
+ if _(u"Casa Legislativa") == atributo:
+ lista.append(servico.casa_legislativa.nome.encode("utf-8"))
+ lista.append(servico.casa_legislativa.municipio.uf.sigla.encode("utf-8"))
+ lista.append(servico.casa_legislativa.email.encode("utf-8"))
+ if servico.casa_legislativa.telefone is not None:
+ lista.append(servico.casa_legislativa.telefone)
+ else:
+ lista.append("")
+ elif _(u"Contato Interlegis") == atributo:
+ if servico.casa_legislativa.contato_interlegis is not None:
+ lista.append(servico.casa_legislativa.contato_interlegis)
+ lista.append(servico.casa_legislativa.contato_interlegis.email.encode("utf-8"))
+ else:
+ lista.append("")
+ lista.append("")
+ elif _(u"Produto") == atributo:
+ lista.append(servico.tipo_servico.nome.encode("utf-8"))
+ elif _(u"Data de Ativação") == atributo:
+ data = ''
+ if servico.data_ativacao:
+ data = servico.data_ativacao.strftime("%d/%m/%Y")
+ lista.append(data.encode("utf-8"))
+ else:
+ pass
+
+ csv_writer.writerow(lista)
+
+ return response
diff --git a/sigi/apps/servidores/models.py b/sigi/apps/servidores/models.py
index 0915855..3a05411 100644
--- a/sigi/apps/servidores/models.py
+++ b/sigi/apps/servidores/models.py
@@ -2,7 +2,7 @@
from django.contrib.auth.models import User
from django.contrib.contenttypes import generic
from django.db import models
-from django.db.models.signals import post_save
+from django.db.models.signals import post_save, pre_save
from django.utils.translation import ugettext as _
class Servico(models.Model):
@@ -89,4 +89,14 @@ def create_user_profile(sender, instance, created, **kwargs):
nome_completo="%s %s" % (instance.first_name, instance.last_name)
)
-post_save.connect(create_user_profile, sender=User)
\ No newline at end of file
+post_save.connect(create_user_profile, sender=User)
+
+# Hack horrível para ajustar o first_name e o last_name do User criado pelo
+# Django-ldap. Os campos first_name e last_name têm o tamanho máximo de
+# 30 caracteres, mas o LDAP não tem esse limite, e alguns usuários podem ter
+# nomes maiores que isso, o que provoca erro ao salvar o usuário.j
+def ajusta_nome_usuario(sender, instance, *args, **kwargs):
+ instance.first_name = instance.first_name[:30]
+ instance.last_name = instance.last_name[:30]
+
+pre_save.connect(ajusta_nome_usuario, sender=User)
\ No newline at end of file
diff --git a/sigi/settings/base.py b/sigi/settings/base.py
index cd57c67..322443d 100644
--- a/sigi/settings/base.py
+++ b/sigi/settings/base.py
@@ -95,6 +95,7 @@ LANGUAGE_CODE = 'pt-br'
USE_I18N = True
USE_L10N = True
USE_THOUSAND_SEPARATOR = True
+TIME_ZONE = "America/Sao_Paulo"
gettext_noop = lambda s: s # for gettext discovery
LANGUAGES = (
diff --git a/templates/base_report.html b/templates/base_report.html
index 96e4495..5eb5265 100644
--- a/templates/base_report.html
+++ b/templates/base_report.html
@@ -15,6 +15,11 @@
font-size: 1.2em;
text-align: center;
}
+ .orgao_name {
+ margin-bottom: 0px;
+ margin-top: 0px;
+ font-weight: bold;
+ }
h1 {
font-size: 2em;
text-align: center;
@@ -82,7 +87,8 @@
|
|