diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py
index dcaa156..328f46f 100644
--- a/sigi/apps/convenios/admin.py
+++ b/sigi/apps/convenios/admin.py
@@ -6,7 +6,8 @@ from geraldo.generators import PDFGenerator
from sigi.apps.convenios.models import (Projeto, StatusConvenio,
TipoSolicitacao, Convenio,
- EquipamentoPrevisto, Anexo, Tramitacao)
+ EquipamentoPrevisto, Anexo, Tramitacao,
+ Gescon)
from sigi.apps.convenios.reports import ConvenioReport
from sigi.apps.convenios.views import adicionar_convenios_carrinho
from sigi.apps.utils import queryset_ascii
@@ -57,11 +58,14 @@ class ConvenioAdmin(BaseModelAdmin):
{'fields': ('servico_gestao', 'servidor_gestao',)}
),
(_(u'Datas'),
- {'fields': ('data_retorno_assinatura', 'data_termino_vigencia',
- 'data_pub_diario',)}
+ {'fields': ('data_retorno_assinatura', 'data_termino_vigencia',
+ 'data_pub_diario',)}
),
+ (_(u'Gescon'),
+ {'fields': ('atualizacao_gescon', 'observacao_gescon',)}
+ ),
)
- readonly_fields = ('data_sigi',)
+ readonly_fields = ('data_sigi', 'atualizacao_gescon', 'observacao_gescon',)
actions = ['adicionar_convenios']
inlines = (AnexosInline,)
list_display = ('num_convenio', 'casa_legislativa', 'get_uf',
@@ -76,8 +80,9 @@ class ConvenioAdmin(BaseModelAdmin):
ordering = ('casa_legislativa', '-data_retorno_assinatura')
raw_id_fields = ('casa_legislativa',)
get_queryset = queryset_ascii
- search_fields = ('id', 'search_text', 'casa_legislativa__sigla',
- 'num_processo_sf', 'num_convenio')
+ search_fields = ('id', 'casa_legislativa__search_text',
+ 'casa_legislativa__sigla', 'num_processo_sf',
+ 'num_convenio')
def get_uf(self, obj):
return obj.casa_legislativa.municipio.uf.sigla
@@ -170,8 +175,13 @@ class EquipamentoPrevistoAdmin(BaseModelAdmin):
search_fields = ('convenio__id', 'equipamento__fabricante__nome',
'equipamento__modelo__modelo', 'equipamento__modelo__tipo__tipo')
+@admin.register(Gescon)
+class GesconAdmin(admin.ModelAdmin):
+ list_display = ('url_gescon', 'email', 'ultima_importacao')
+ readonly_fields = ('ultima_importacao',)
+
admin.site.register(Projeto)
admin.site.register(StatusConvenio)
admin.site.register(TipoSolicitacao)
admin.site.register(Convenio, ConvenioAdmin)
-admin.site.register(EquipamentoPrevisto, EquipamentoPrevistoAdmin)
+admin.site.register(EquipamentoPrevisto, EquipamentoPrevistoAdmin)
\ No newline at end of file
diff --git a/sigi/apps/convenios/migrations/0014_gescon.py b/sigi/apps/convenios/migrations/0014_gescon.py
new file mode 100644
index 0000000..7fe216c
--- /dev/null
+++ b/sigi/apps/convenios/migrations/0014_gescon.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('convenios', '0013_remove_convenio_duracao'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Gescon',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('url_gescon', models.URLField(default='https://adm.senado.gov.br/gestao-contratos/api/contratos/busca?especie={s}', help_text='Informe o ponto de consulta do webservice do Gescon, inclusive com a querystring. No ponto onde deve ser inserida a sigla da subespecie do contrato, use a marca\xe7\xe3o {s}.
Por exemplo: https://adm.senado.gov.br/gestao-contratos/api/contratos/busca?especie={s}', verbose_name='Webservice Gescon')),
+ ('subespecies', models.TextField(default='AC=ACT\nPI=PI\nCN=PML\nTA=PML', help_text='Informe as siglas das subesp\xe9cies de contratos que devem ser pesquisados no Gescon com a sigla correspondente do projeto no SIGI. Coloque um par de siglas por linha, no formato SIGLA_GESTON=SIGLA_SIGI. As siglas n\xe3o encontradas ser\xe3o ignoradas.', verbose_name='Subesp\xe9cies')),
+ ('palavras', models.TextField(default='ILB\nINTERLEGIS', help_text='Palavras que devem aparecer no campo OBJETO dos dados do Gescon para identificar se o contrato pertence ao ILB.
- Informe uma palavra por linha.
- Ocorrendo qualquer uma das palavras, o contrato ser\xe1 importado.
', verbose_name='Palavras de filtro')),
+ ('email', models.EmailField(help_text='Caixa de e-mail para onde o relat\xf3rio di\xe1rio de importa\xe7\xe3o ser\xe1 enviado.', max_length=75, verbose_name='E-mail')),
+ ('ultima_importacao', models.TextField(verbose_name='Resultado da \xfaltima importa\xe7\xe3o', blank=True)),
+ ],
+ options={
+ 'verbose_name': 'Configura\xe7\xe3o do Gescon',
+ 'verbose_name_plural': 'Configura\xe7\xf5es do Gescon',
+ },
+ bases=(models.Model,),
+ ),
+ ]
diff --git a/sigi/apps/convenios/migrations/0015_remove_convenio_search_text.py b/sigi/apps/convenios/migrations/0015_remove_convenio_search_text.py
new file mode 100644
index 0000000..c187381
--- /dev/null
+++ b/sigi/apps/convenios/migrations/0015_remove_convenio_search_text.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('convenios', '0014_gescon'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='convenio',
+ name='search_text',
+ ),
+ ]
diff --git a/sigi/apps/convenios/migrations/0016_auto_20210909_0732.py b/sigi/apps/convenios/migrations/0016_auto_20210909_0732.py
new file mode 100644
index 0000000..9c98cbc
--- /dev/null
+++ b/sigi/apps/convenios/migrations/0016_auto_20210909_0732.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('convenios', '0015_remove_convenio_search_text'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='convenio',
+ name='atualizacao_gescon',
+ field=models.DateTimeField(null=True, verbose_name='Data de atualiza\xe7\xe3o pelo Gescon', blank=True),
+ preserve_default=True,
+ ),
+ migrations.AddField(
+ model_name='convenio',
+ name='observacao_gescon',
+ field=models.TextField(verbose_name='Observa\xe7\xf5es da atualiza\xe7\xe3o do Gescon', blank=True),
+ preserve_default=True,
+ ),
+ ]
diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py
index 59f00fa..b4dfc79 100644
--- a/sigi/apps/convenios/models.py
+++ b/sigi/apps/convenios/models.py
@@ -1,9 +1,14 @@
#-*- coding: utf-8 -*-
import re
+import requests
from datetime import datetime, date
from django.db import models
+from django.db.models import Q
+from django.core.mail import send_mail
+from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
-from sigi.apps.utils import SearchField
+from sigi.apps.utils import SearchField, to_ascii
+from sigi.apps.casas.models import Orgao
from sigi.apps.servidores.models import Servidor, Servico
class Projeto(models.Model):
@@ -49,7 +54,6 @@ class Convenio(models.Model):
verbose_name=_(u'órgão conveniado')
)
# campo de busca em caixa baixa e sem acentos
- search_text = SearchField(field_names=['casa_legislativa'])
projeto = models.ForeignKey(
Projeto,
on_delete=models.PROTECT,
@@ -177,6 +181,15 @@ class Convenio(models.Model):
)
conveniada = models.BooleanField(default=False)
equipada = models.BooleanField(default=False)
+ atualizacao_gescon = models.DateTimeField(
+ _(u"Data de atualização pelo Gescon"),
+ blank=True,
+ null=True
+ )
+ observacao_gescon = models.TextField(
+ _(u"Observações da atualização do Gescon"),
+ blank=True
+ )
def get_status(self):
if self.status and self.status.cancela:
@@ -360,3 +373,406 @@ class Tramitacao(models.Model):
if self.observacao:
result = result + u" (%s)" % (self.observacao)
return unicode(result) # XXX is this unicode(...) really necessary???
+
+class Gescon(models.Model):
+ url_gescon = models.URLField(
+ _(u"Webservice Gescon"),
+ default=(u"https://adm.senado.gov.br/gestao-contratos/api/contratos"
+ u"/busca?especie={s}"),
+ help_text=_(u"Informe o ponto de consulta do webservice do Gescon, "
+ u"inclusive com a querystring. No ponto onde deve ser "
+ u"inserida a sigla da subespecie do contrato, use a "
+ u"marcação {s}.
Por exemplo: "
+ u"https://adm.senado.gov.br/gestao-contratos/api/contratos"
+ u"/busca?especie={s}")
+ )
+ subespecies = models.TextField(
+ _(u"Subespécies"),
+ default=u"AC=ACT\nPI=PI\nCN=PML\nTA=PML",
+ help_text=_(u"Informe as siglas das subespécies de contratos que "
+ u"devem ser pesquisados no Gescon com a sigla "
+ u"correspondente do projeto no SIGI. Coloque um par de "
+ u"siglas por linha, no formato SIGLA_GESTON=SIGLA_SIGI. "
+ u"As siglas não encontradas serão ignoradas.")
+ )
+ palavras = models.TextField(
+ _(u"Palavras de filtro"),
+ default=u"ILB\nINTERLEGIS",
+ help_text=_(u"Palavras que devem aparecer no campo OBJETO dos dados do "
+ u"Gescon para identificar se o contrato pertence ao ILB. "
+ u"- Informe uma palavra por linha.
"
+ u"- Ocorrendo qualquer uma das palavras, o contrato será "
+ u"importado.
")
+ )
+ email = models.EmailField(
+ _(u"E-mail"),
+ help_text=_(u"Caixa de e-mail para onde o relatório diário de "
+ u"importação será enviado.")
+ )
+ ultima_importacao = models.TextField(
+ _(u"Resultado da última importação"),
+ blank=True
+ )
+
+ class Meta:
+ verbose_name = _(u"Configuração do Gescon")
+ verbose_name_plural = _(u"Configurações do Gescon")
+
+ def __unicode__(self):
+ return self.url_gescon
+
+ def save(self, *args, **kwargs):
+ self.pk = 1 # Highlander (singleton pattern)
+ return super(Gescon, self).save(*args, **kwargs)
+
+ def delete(self, *args, **kwargs):
+ pass # Highlander is immortal
+
+ def add_message(self, msg, save=False):
+ self.ultima_importacao += msg + "\n"
+ if save:
+ self.save()
+ self.email_report()
+
+ def email_report(self):
+ if self.email:
+ send_mail(
+ subject=_(u"Relatório de importação GESCON"),
+ message=self.ultima_importacao,
+ recipient_list=self.email,
+ fail_silently=True
+ )
+ else:
+ self.ultima_importacao += _(
+ u"\n\n*Não foi definida uma caixa de e-mail nas configurações "
+ u"do Gescon*"
+ )
+ self.save()
+
+ def importa_contratos(self):
+ self.ultima_importacao = ""
+ self.add_message(
+ _(u"Importação iniciada em {:%d/%m/%Y %H:%M:%S}\n"
+ u"==========================================\n").format(
+ datetime.now()
+ )
+ )
+
+ if self.palavras == "":
+ self.add_message(_(u"Nenhuma palavra de pesquisa definida - "
+ u"processo abortado."), True)
+ return
+
+ if self.subespecies == "":
+ self.add_message(_(u"Nenhuma subespécie definida - processo "
+ u"abortado."), True)
+ return
+
+ if "{s}" not in self.url_gescon:
+ self.add_message(
+ _(
+ u"Falta a marcação {s} na URL para indicar o local onde "
+ u"inserir a sigla da subespécia na consulta ao webservice "
+ u"- processo abortado."
+ ),
+ True
+ )
+ return
+
+ palavras = self.palavras.split()
+ subespecies = {tuple(s.split("=")) for s in self.subespecies.split()}
+
+ for sigla_gescon, sigla_sigi in subespecies:
+ self.add_message(_(u"\nImportando subespécie {s}".format(
+ s=sigla_gescon)))
+ url = self.url_gescon.format(s=sigla_gescon)
+
+ projeto = Projeto.objects.get(sigla=sigla_sigi)
+
+ try:
+ response = requests.get(url)
+ except Exception as e:
+ self.add_message(
+ _(u"\tErro ao acessar {url}: {errmsg}").format(
+ url=url,
+ errmsg=str(e)
+ )
+ )
+ continue
+
+ if not response.ok:
+ self.add_message(
+ _(u"\tErro ao acessar {url}: {reason}").format(
+ url=url,
+ reason=response.reason
+ )
+ )
+ continue
+
+ if not 'application/json' in response.headers.get('Content-Type'):
+ self.add_message(_(u"\tResultado da consulta à {url} não "
+ u"retornou dados em formato json").format(
+ url=url
+ )
+ )
+ continue
+
+ contratos = response.json()
+
+ # Pegar só os contratos que possuem alguma das palavras-chave
+
+ nossos = [c for c in contratos
+ if any(palavra in c['objeto'] for palavra in palavras)]
+
+ self.add_message(
+ _(u"\t{count} contratos encontrados no Gescon").format(
+ count=len(nossos)
+ )
+ )
+
+ novos = 0
+ erros = 0
+ alertas = 0
+ atualizados = 0
+
+ for contrato in nossos:
+ numero = contrato['numero'].zfill(8)
+ numero = "{}/{}".format(numero[:4], numero[4:])
+ sigad = contrato['processo'].zfill(17)
+ sigad = "{}.{}/{}-{}".format(sigad[:5], sigad[5:11],
+ sigad[11:15], sigad[15:])
+
+
+ if contrato['cnpjCpfFornecedor']:
+ cnpj = contrato['cnpjCpfFornecedor'].zfill(14)
+ cnpj = "{}.{}.{}/{}-{}".format(cnpj[:2], cnpj[2:5],
+ cnpj[5:8], cnpj[8:12],
+ cnpj[12:])
+ else:
+ cnpj = None
+
+ if contrato['nomeFornecedor']:
+ nome = contrato['nomeFornecedor']
+ nome = nome.replace(u'VEREADORES DE', '')
+ nome = nome.split('-')[0]
+ nome = nome.split('/')[0]
+ nome = nome.strip()
+ nome = nome.replace(" ", " ")
+ nome = to_ascii(nome)
+ else:
+ nome = None
+
+ if (cnpj is None) and (nome is None):
+ self.add_message(
+ _(u"\tO contrato {numero} no Gescon não informa o CNPJ "
+ u"nem o nome do órgão.").format(numero=numero)
+ )
+ erros += 1
+ continue
+
+ orgao = None
+
+ if cnpj is not None:
+ try:
+ orgao = Orgao.objects.get(cnpj=cnpj)
+ except (
+ Orgao.DoesNotExist,
+ Orgao.MultipleObjectsReturned) as e:
+ orgao = None
+ pass
+
+ if (orgao is None) and (nome is not None):
+ try:
+ orgao = Orgao.objects.get(search_text__iexact=nome)
+ except (
+ Orgao.DoesNotExist,
+ Orgao.MultipleObjectsReturned) as e:
+ orgao = None
+ pass
+
+ if orgao is None:
+ self.add_message(
+ _(u"\tÓrgão não encontrado no SIGI ou mais de um órgão"
+ u"encontrado com o mesmo CNPJ ou nome. Favor "
+ u"regularizar o cadastro: CNPJ: {cnpj}, "
+ u"Nome: {nome}".format(
+ cnpj=contrato['cnpjCpfFornecedor'],
+ nome=contrato['nomeFornecedor']
+ )
+ )
+ )
+ erros += 1
+ continue
+
+ # O mais seguro é o NUP sigad
+ convenios = Convenio.objects.filter(num_processo_sf=sigad)
+ chk = convenios.count()
+
+ if chk == 0:
+ # NUP não encontrado, talvez exista apenas com o número
+ # do GESCON
+ convenios = Convenio.objects.filter(
+ Q(num_convenio=numero) |
+ Q(num_processo_sf=numero)
+ )
+ chk = convenios.count()
+ if chk > 1:
+ # Pode ser que existam vários contratos de subespécies
+ # diferentes com o mesmo número Gescon. Neste caso, o
+ # ideal é filtrar pelo tipo de projeto. Existindo, é
+ # ele mesmo. Se não existir, então segue com os
+ # múltiplos para registrar o problema mais adiante
+ if convenios.filter(projeto=projeto).count() == 1:
+ convenios = convenios.filter(projeto=projeto)
+ chk = 1
+
+ if chk == 0:
+ convenio = Convenio(
+ casa_legislativa=orgao,
+ projeto=projeto,
+ num_processo_sf=sigad,
+ num_convenio=numero,
+ data_sigi=date.today(),
+ data_sigad=contrato['assinatura'],
+ observacao=contrato['objeto'],
+ data_retorno_assinatura=contrato['inicioVigencia'],
+ data_termino_vigencia=contrato['terminoVigencia'],
+ data_pub_diario=contrato['publicacao'],
+ atualizacao_gescon=datetime.now(),
+ observacao_gescon=_(u"Importado integralmente do"
+ u"Gescon")
+ )
+ convenio.save()
+ novos += 1
+ continue
+ elif chk == 1:
+ convenio = convenios.get()
+ convenio.atualizacao_gescon = datetime.now()
+ convenio.observacao_gescon = ''
+ if convenio.casa_legislativa != orgao:
+ self.add_message(
+ _(u"\tO órgao no convênio {url} diverge do que "
+ u"consta no Gescon ({cnpj}, {nome})").format(
+ url=reverse('admin:%s_%s_change' % (
+ convenio._meta.app_label,
+ convenio._meta.model_name),
+ args=[convenio.id]),
+ cnpj=cnpj,
+ nome=contrato['nomeFornecedor']
+ )
+ )
+ convenio.observacao_gescon = _(
+ u'ERRO: Órgão diverge do Gescon. Não atualizado!'
+ )
+ convenio.save()
+ erros += 1
+ continue
+
+ if convenio.num_processo_sf != sigad:
+ self.add_message(
+ _(u"\tO contrato Gescon nº {numero} corresponde"
+ u" ao convênio SIGI {url}, mas o NUP sigad "
+ u"diverge (Gescon: {sigad_gescon}, "
+ u"SIGI: {sigad_sigi}). CORRIGIDO!").format(
+ numero=numero,
+ url=reverse('admin:%s_%s_change' % (
+ convenio._meta.app_label,
+ convenio._meta.model_name),
+ args=[convenio.id]),
+ sigad_gescon=sigad,
+ sigad_sigi=convenio.num_processo_sf
+ )
+ )
+ convenio.num_processo_sf = sigad
+ convenio.observacao_gescon += _(
+ u"Número do SIGAD atualizado.\n"
+ )
+ alertas += 1
+
+ if convenio.num_convenio != numero:
+ self.add_message(
+ _(u"\tO contrato Gescon ID {id} corresponde ao "
+ u"convênio SIGI {url}, mas o número do convênio"
+ u" diverge (Gescon: {numero_gescon}, SIGI: "
+ u"{numero_sigi}). CORRIGIDO!").format(
+ id=contrato['id'],
+ url=reverse('admin:%s_%s_change' % (
+ convenio._meta.app_label,
+ convenio._meta.model_name),
+ args=[convenio.id]
+ ),
+ numero_gescon=numero,
+ numero_sigi=convenio.num_convenio
+ )
+ )
+ convenio.num_convenio = numero
+ convenio.observacao_gescon += _(
+ u"Número do convênio atualizado.\n"
+ )
+ alertas += 1
+
+ if contrato['objeto'] not in convenio.observacao:
+ convenio.observacao += "\n" + contrato['objeto']
+ convenio.observacao_gescon += _(
+ u"Observação atualizada.\n"
+ )
+
+ convenio.data_sigad = contrato['assinatura']
+ convenio.data_retorno_assinatura = contrato[
+ 'inicioVigencia'
+ ]
+ convenio.data_termino_vigencia = contrato[
+ 'terminoVigencia'
+ ]
+ convenio.data_pub_diario = contrato['publicacao']
+
+ try:
+ convenio.save()
+ except Exception as e:
+ self.add_message(
+ _(u"Ocorreu um erro ao salvar o convênio {url} no "
+ u"SIGI. Alguma informação do Gescon pode ter "
+ u"quebrado o sistema. Informe ao suporte. Erro:"
+ u"{errmsg}").format(
+ url=reverse('admin:%s_%s_change' % (
+ convenio._meta.app_label,
+ convenio._meta.model_name),
+ args=[convenio.id]
+ ),
+ errmsg=str(e)
+ )
+ )
+ erros += 1
+ continue
+
+ atualizados += 1
+ else:
+ self.add_message(_(u"\tExistem {count} convênios no SIGI "
+ u"que correspondem ao mesmo contrato no "
+ u"Gescon (contrato {numero}, sigad "
+ u"{sigad})").format(
+ count=chk,
+ numero=numero,
+ sigad=sigad
+ )
+ )
+ erros += 1
+ continue
+
+ self.add_message(
+ _(u"\t{novos} novos convenios adicionados ao SIGI, "
+ u"{atualizados} atualizados, sendo {alertas} com alertas, e "
+ u"{erros} reportados com erro.").format(
+ novos=novos,
+ atualizados=atualizados,
+ alertas=alertas,
+ erros=erros
+ )
+ )
+
+ self.save()
+
+ @classmethod
+ def load(cls):
+ obj, created = cls.objects.get_or_create(pk=1)
+ return obj
\ No newline at end of file
diff --git a/sigi/apps/convenios/templates/convenios/importar_gescon.html b/sigi/apps/convenios/templates/convenios/importar_gescon.html
new file mode 100644
index 0000000..49f068a
--- /dev/null
+++ b/sigi/apps/convenios/templates/convenios/importar_gescon.html
@@ -0,0 +1,18 @@
+{% extends 'admin/base_site.html' %}
+{% load i18n %}
+
+{% block content_title %}{% trans 'Importar dados do Gescon' %}
{% endblock %}
+{% block object-tools-items %}
+Importar
+Configurações
+{% endblock %}
+{% block content %}
+ {% if gescon.ultima_importacao %}
+ {{ gescon.ultima_importacao }}
+ {% else %}
+ {% blocktrans %}
+ Nenhuma importação anterior foi realizada!
+ Configure a conexão com o Gescon para realizar a primeira importação.
+ {% endblocktrans %}
+ {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/sigi/apps/convenios/urls.py b/sigi/apps/convenios/urls.py
index d3b753a..1986ecc 100644
--- a/sigi/apps/convenios/urls.py
+++ b/sigi/apps/convenios/urls.py
@@ -11,4 +11,5 @@ urlpatterns = patterns(
url(r'^convenio/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho', name='deleta-itens-carrinho'), # tagerror
url(r'^convenio/csv/$', 'export_csv', name='convenios-csv'),
url(r'^reportsRegiao/(?P\w+)/$', 'report_regiao', name='convenios-report_regiao_pdf'),
+ url(r'^importar/$', 'importar_gescon', name='importar-gescon'),
)
diff --git a/sigi/apps/convenios/views.py b/sigi/apps/convenios/views.py
index 6760828..dd21f0e 100644
--- a/sigi/apps/convenios/views.py
+++ b/sigi/apps/convenios/views.py
@@ -2,6 +2,7 @@
import csv
import datetime
+from django.http.response import HttpResponseForbidden
import ho.pisa as pisa
from django.conf import settings
from django.core.paginator import Paginator, InvalidPage, EmptyPage
@@ -13,7 +14,7 @@ from geraldo.generators import PDFGenerator
from sigi.apps.casas.models import Orgao
from sigi.apps.contatos.models import UnidadeFederativa
-from sigi.apps.convenios.models import Convenio, Projeto
+from sigi.apps.convenios.models import Convenio, Gescon, Projeto
from sigi.apps.convenios.reports import (ConvenioReport,
ConvenioReportSemAceite,
ConvenioPorCMReport,
@@ -372,3 +373,16 @@ def export_csv(request):
csv_writer.writerow(lista)
return response
+
+@login_required
+def importar_gescon(request):
+ if not request.user.is_superuser:
+ return HttpResponseForbidden()
+
+ action = request.GET.get('action', "")
+ gescon = Gescon.load()
+
+ if action == 'importar':
+ gescon.importa_contratos()
+
+ return render(request, "convenios/importar_gescon.html", {'gescon': gescon})
\ No newline at end of file
diff --git a/sigi/shortcuts.py b/sigi/shortcuts.py
index f5f0fff..d27986c 100644
--- a/sigi/shortcuts.py
+++ b/sigi/shortcuts.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from cgi import escape
+from datetime import datetime
import os
from django.conf import settings
@@ -28,12 +29,15 @@ def render_to_pdf(template_src, context_dict):
filename = template_src.replace('.html', '').replace('_pdf', '.pdf')
template = get_template(template_src)
context = Context(context_dict)
+
html = template.render(context)
- result = StringIO.StringIO()
-
- pdf = pisa.pisaDocument(StringIO.StringIO(html.encode('utf-8')), result, link_callback=fetch_resources)
- if not pdf.err:
- response = HttpResponse(result.getvalue(), content_type='application/pdf')
- response['Content-Disposition'] = 'attachment; filename=' + filename
- return response
- return HttpResponse(_(u'We had some errors%s
') % escape(html))
+
+ response = HttpResponse(content_type='application/pdf')
+ response['Content-Disposition'] = 'attachment; filename=' + filename
+
+ pdf = pisa.CreatePDF(html, dest=response,
+ link_callback=fetch_resources)
+
+ if pdf.err:
+ return HttpResponse(_(u'We had some errors%s
') % escape(html))
+ return response
diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html
index 6f61a15..f7d3120 100644
--- a/templates/admin/base_site.html
+++ b/templates/admin/base_site.html
@@ -41,6 +41,7 @@
{% trans 'Sites' %}
{% trans 'Diagnósticos' %}
{% trans 'Importar dados de Casas' %}
+ {% trans 'Importar convênios do Gescon' %}
{% endif %}