From c4daa0de4724ce611f2c346e05cb1406e0f34177 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Tue, 22 Jun 2021 09:24:41 -0300 Subject: [PATCH 01/73] Fix #47 --- sigi/apps/convenios/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index ce5a6fe..dd7f4c1 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -78,7 +78,7 @@ class ConvenioAdmin(BaseModelAdmin): ordering = ('casa_legislativa__tipo__sigla', 'casa_legislativa__municipio__uf', 'casa_legislativa') raw_id_fields = ('casa_legislativa',) get_queryset = queryset_ascii - search_fields = ('id', 'search_text', # 'casa_legislativa__nome', + search_fields = ('id', 'search_text', 'casa_legislativa__sigla', 'num_processo_sf', 'num_convenio') def get_uf(self, obj): From 38009f7a9455d83914e8139e011101890f69c5e6 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 24 Jun 2021 14:53:31 -0300 Subject: [PATCH 02/73] Fix #35 --- sigi/apps/home/templatetags/menu_conf.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index 0c51f7e..c441946 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -65,6 +65,8 @@ main_menu: url: convenios/statusconvenio/ - title: Tipos de serviço SEIT url: servicos/tiposervico/ + - title: Tipos de projeto + url: convenios/projeto/ - title: Categorias de ocorrências url: ocorrencias/categoria/ - title: Tipos de contato From 430ce91d5163ec1b82cf9b35fe48e512aa7e6db6 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 22 Jul 2021 09:16:02 -0300 Subject: [PATCH 03/73] Fix #61 e #39 alterando relatorio de parcerias --- sigi/apps/convenios/reports.py | 92 ++++++++++++---------------------- 1 file changed, 32 insertions(+), 60 deletions(-) diff --git a/sigi/apps/convenios/reports.py b/sigi/apps/convenios/reports.py index 15f68a8..86295cd 100644 --- a/sigi/apps/convenios/reports.py +++ b/sigi/apps/convenios/reports.py @@ -26,12 +26,12 @@ class SemEquipamentosReport(object): class ConvenioReport(ReportDefault): - title = _(u'Relatório de Convênios') + title = _(u'Relatório de Parcerias') class band_page_header(ReportDefault.band_page_header): label_top = ReportDefault.band_page_header.label_top - label_left = [0, 1.5, 7, 9, 11, 13, 15, 17] + label_left = [0, 2.5, 6, 8, 10, 12, 14, 16] elements = list(ReportDefault.band_page_header.elements) height = 4.7 * cm @@ -47,38 +47,32 @@ class ConvenioReport(ReportDefault): top=label_top + 0.4 * cm, ), Label( - text=_(u"Data de Adesão"), + text=_(u"Número do Convênio"), left=label_left[2] * cm, top=label_top, width=2 * cm, ), Label( - text=_(u"Número do Convênio"), + text=_(u"Data do Convênio"), left=label_left[3] * cm, top=label_top, width=2 * cm, ), Label( - text=_(u"Data do Convênio"), + text=_(u"Data de Publicação"), left=label_left[4] * cm, top=label_top, width=2 * cm, ), Label( - text=_(u"Data de Publicação"), + text=_(u"Projeto"), left=label_left[5] * cm, - top=label_top, + top=label_top + 0.4 * cm, width=2 * cm, ), Label( - text=_(u"Data de Aceite"), + text=_(u"Orgão"), left=label_left[6] * cm, - top=label_top, - width=2 * cm, - ), - Label( - text=_(u"Projeto"), - left=label_left[7] * cm, top=label_top + 0.4 * cm, width=2 * cm, ), @@ -89,7 +83,7 @@ class ConvenioReport(ReportDefault): class band_detail(ReportDefault.band_detail): - label_left = [0, 1.5, 7, 9, 11, 13, 15, 17] + label_left = [0, 2.5, 6, 8, 10, 12, 14, 16] elements = [ ObjectValue( @@ -100,37 +94,29 @@ class ConvenioReport(ReportDefault): attribute_name='casa_legislativa.municipio.nome', left=label_left[1] * cm ), - ObjectValue( - attribute_name='data_adesao', - left=label_left[2] * cm, - get_value=lambda instance: - instance.data_adesao.strftime('%d/%m/%Y') if instance.data_adesao is not None else '-' - ), ObjectValue( attribute_name='num_convenio', - left=label_left[3] * cm + left=label_left[2] * cm ), ObjectValue( attribute_name='data_retorno_assinatura', - left=label_left[4] * cm, + left=label_left[3] * 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[5] * cm, + left=label_left[4] * cm, get_value=lambda instance: instance.data_pub_diario.strftime('%d/%m/%Y') if instance.data_pub_diario is not None else '-' ), ObjectValue( - attribute_name='data_termo_aceite', - left=label_left[6] * cm, - get_value=lambda instance: - instance.data_termo_aceite.strftime('%d/%m/%Y') if instance.data_termo_aceite is not None else '-' + attribute_name='projeto.sigla', + left=label_left[5] * cm ), ObjectValue( - attribute_name='projeto.sigla', - left=label_left[7] * cm + attribute_name='casa_legislativa.nome', + left=label_left[6] * cm ), ] @@ -154,7 +140,7 @@ class ConvenioReportSemAceite(ConvenioReport): class band_page_header(ReportDefault.band_page_header): label_top = ReportDefault.band_page_header.label_top - label_left = [0, 1.5, 7, 9, 11, 13, 15, 17] + label_left = [0, 2.5, 6, 8, 10, 12, 14, 16] elements = list(ReportDefault.band_page_header.elements) height = 4.7 * cm @@ -169,33 +155,27 @@ class ConvenioReportSemAceite(ConvenioReport): left=label_left[1] * cm, top=label_top + 0.4 * cm, ), - Label( - text=_(u"Data de Adesão"), - left=label_left[3] * cm, - top=label_top, - width=2 * cm, - ), Label( text=_(u"Número do Convênio"), - left=label_left[4] * cm, + left=label_left[2] * cm, top=label_top, width=2 * cm, ), Label( text=_(u"Data do Convênio"), - left=label_left[5] * cm, + left=label_left[3] * cm, top=label_top, width=2 * cm, - ), + ), Label( - text=_(u"Data de Publicação"), - left=label_left[6] * cm, + text=_(u"Projeto"), + left=label_left[4] * cm, top=label_top, width=2 * cm, ), Label( - text=_(u"Projeto"), - left=label_left[7] * cm, + text=_(u"Orgão"), + left=label_left[5] * cm, top=label_top + 0.4 * cm, width=2 * cm, ), @@ -203,7 +183,7 @@ class ConvenioReportSemAceite(ConvenioReport): class band_detail(ReportDefault.band_detail): - label_left = [0, 1.5, 7, 9, 11, 13, 15, 17] + label_left = [0, 2.5, 6, 8, 10, 12, 14, 16] elements = [ ObjectValue( @@ -214,31 +194,23 @@ class ConvenioReportSemAceite(ConvenioReport): attribute_name='casa_legislativa.municipio.nome', left=label_left[1] * cm ), - ObjectValue( - attribute_name='data_adesao', - left=label_left[3] * cm, - get_value=lambda instance: - instance.data_adesao.strftime('%d/%m/%Y') if instance.data_adesao is not None else '-' - ), ObjectValue( attribute_name='num_convenio', - left=label_left[4] * cm + left=label_left[2] * cm ), ObjectValue( attribute_name='data_retorno_assinatura', - left=label_left[5] * cm, + left=label_left[3] * 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[6] * cm, - get_value=lambda instance: - instance.data_pub_diario.strftime('%d/%m/%Y') if instance.data_pub_diario is not None else '-' + attribute_name='projeto.sigla', + left=label_left[4], ), ObjectValue( - attribute_name='projeto.sigla', - left=label_left[7] * cm + attribute_name='casa_legislativa.nome', + left=label_left[5] * cm ), ] @@ -247,7 +219,7 @@ float_duas_casas = lambda instance: '%.2f' % (instance) class ConvenioReportRegiao(ReportDefault): - title = _(u'Relatório de Convênios por Região') + title = _(u'Relatório de Parcerias por Região') class band_page_header(ReportDefault.band_page_header): label_top = ReportDefault.band_page_header.label_top From 6f32784a99d07151166cbff8a1eeba2f0bb23671 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 22 Jul 2021 15:45:31 -0300 Subject: [PATCH 04/73] Tirando o nome das UFs deixando so siglas --- sigi/apps/convenios/reports.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sigi/apps/convenios/reports.py b/sigi/apps/convenios/reports.py index 86295cd..983edee 100644 --- a/sigi/apps/convenios/reports.py +++ b/sigi/apps/convenios/reports.py @@ -120,19 +120,19 @@ class ConvenioReport(ReportDefault): ), ] - groups = [ - ReportGroup(attribute_name='casa_legislativa.municipio.uf', - band_header=ReportBand( - height=0.7 * cm, - elements=[ - ObjectValue(attribute_name='casa_legislativa.municipio.uf', - get_Value=lambda instance: '%s: %s' % (_(u'Casa Legislativa'), instance.casa_legislativa.uf) - ) - ], - borders={'top': True}, - ) - ) - ] + #groups = [ + # ReportGroup(attribute_name='casa_legislativa.municipio.uf', + # band_header=ReportBand( + # height=0.7 * cm, + # elements=[ + # ObjectValue(attribute_name='casa_legislativa.municipio.uf', + # get_Value=lambda instance: '%s: %s' % (_(u'Casa Legislativa'), instance.casa_legislativa.uf) + # ) + # ], + # borders={'top': True}, + # ) + # ) + #] class ConvenioReportSemAceite(ConvenioReport): From 579643a249742136a371ad4f55fdb1a52c8c41c0 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Tue, 3 Aug 2021 09:31:52 -0300 Subject: [PATCH 05/73] =?UTF-8?q?Mudando=20a=20ordenacao=20no=20relat?= =?UTF-8?q?=C3=B3rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/reports.py | 10 +++++----- sigi/apps/convenios/views.py | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sigi/apps/convenios/reports.py b/sigi/apps/convenios/reports.py index 983edee..0cb0474 100644 --- a/sigi/apps/convenios/reports.py +++ b/sigi/apps/convenios/reports.py @@ -27,7 +27,7 @@ class SemEquipamentosReport(object): class ConvenioReport(ReportDefault): title = _(u'Relatório de Parcerias') - + class band_page_header(ReportDefault.band_page_header): label_top = ReportDefault.band_page_header.label_top @@ -270,16 +270,16 @@ class ConvenioReportRegiao(ReportDefault): class ConvenioPorCMReport(ConvenioReport): - title = _(u'Relatório de Convênios por Câmara Municipal') + title = _(u'Relatório de Parcerias por Câmara Municipal') class ConvenioPorALReport(ConvenioReport): - title = _(u'Relatório de Convênios por Assembléia Legislativa') + title = _(u'Relatório de Parcerias por Assembléia Legislativa') class ConvenioReportSemAceiteCM(ConvenioReportSemAceite): - title = _(u'Relatório de Convênios por Câmara Municipal') + title = _(u'Relatório de Parcerias por Câmara Municipal') class ConvenioReportSemAceiteAL(ConvenioReportSemAceite): - title = _(u'Relatório de Convênios por Assembléia Legislativa') + title = _(u'Relatório de Parcerias por Assembléia Legislativa') diff --git a/sigi/apps/convenios/views.py b/sigi/apps/convenios/views.py index d9ae58f..6760828 100644 --- a/sigi/apps/convenios/views.py +++ b/sigi/apps/convenios/views.py @@ -86,6 +86,8 @@ def carrinhoOrGet_for_qs(request): if 'carrinho_convenios' in request.session: ids = request.session['carrinho_convenios'] qs = Convenio.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 = Convenio.objects.all() if request.GET: From 9dae4e056c45aeb0649b6f7b9ab5b486e7e92f52 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Mon, 9 Aug 2021 09:57:29 -0300 Subject: [PATCH 06/73] =?UTF-8?q?Mudando=20a=20ordenacao=20no=20relat?= =?UTF-8?q?=C3=B3rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/admin.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index dd7f4c1..4a46d57 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -51,8 +51,7 @@ class ConvenioAdmin(BaseModelAdmin): 'projeto', 'data_sigi',)} ), (_(u"Acompanhamento no gabinete"), - {'fields': ('data_solicitacao', 'data_sigad', 'tipo_solicitacao', - 'status', 'acompanha', 'observacao',)} + {'fields': ('data_solicitacao', 'data_sigad', 'observacao',)} ), (_(u"Gestão do convênio"), {'fields': ('servico_gestao', 'servidor_gestao',)} @@ -67,10 +66,9 @@ class ConvenioAdmin(BaseModelAdmin): inlines = (AnexosInline,) list_display = ('num_convenio', 'casa_legislativa', 'get_uf', 'status_convenio', 'link_sigad', 'data_retorno_assinatura', - 'duracao', 'projeto', 'status', 'acompanha',) + 'duracao', 'projeto',) list_display_links = ('num_convenio', 'casa_legislativa',) - list_filter = ('status', ('acompanha', AcompanhaFilter), - ('casa_legislativa__gerentes_interlegis', + list_filter = (('casa_legislativa__gerentes_interlegis', GerentesInterlegisFilter), 'projeto', 'casa_legislativa__tipo', 'conveniada','equipada', 'casa_legislativa__municipio__uf',) From 37f2071fe3675976a96e098a3afd11f92f641c8f Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 13 Aug 2021 09:18:37 -0300 Subject: [PATCH 07/73] Reordenando os contatos pela ultDataAlteracao --- sigi/apps/casas/admin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index c09d079..19d5ebb 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -77,7 +77,9 @@ class FuncionariosInline(admin.StackedInline): def get_queryset(self, request): return (self.model.objects.exclude( - cargo='Presidente').exclude(desativado=True) + cargo='Presidente').exclude(desativado=True).order_by('-ult_alteracao') + .extra(select={'ult_null': 'ult_alteracao is null'}).extra(order_by=['ult_null']) + # 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 ) From c9cbf0bddccfe9c0d06354bbd52049b8589bb7d7 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 19 Aug 2021 09:12:24 -0300 Subject: [PATCH 08/73] Alterando de acordo com #77 --- sigi/apps/casas/admin.py | 9 ++++++--- sigi/apps/convenios/models.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 19d5ebb..7f542dc 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -89,9 +89,7 @@ class ConveniosInline(admin.TabularInline): (None, {'fields': ( ('link_sigad', 'status_convenio', 'num_convenio', 'projeto', 'observacao'), - ('data_adesao', 'data_retorno_assinatura', 'data_termo_aceite', - 'data_pub_diario', 'data_devolucao_via', 'data_postagem_correio'), - ('data_devolucao_sem_assinatura', 'data_retorno_sem_assinatura',), + ('data_retorno_assinatura', 'data_pub_diario',), ('get_anexos',), ('link_convenio',), )}), @@ -105,6 +103,7 @@ class ConveniosInline(admin.TabularInline): extra = 0 can_delete = False template = 'admin/casas/convenios_inline.html' + ordering = ('-data_retorno_assinatura',) def has_add_permission(self, request): return False @@ -227,6 +226,8 @@ class ServicoInline(admin.TabularInline): link_url.short_description = _(u'URL do serviço') link_url.allow_tags = True + ordering = ('-data_alteracao',) + # class PlanoDiretorInline(admin.TabularInline): # model = PlanoDiretor @@ -239,6 +240,8 @@ class OcorrenciaInline(admin.TabularInline): can_delete = False template = 'admin/casas/ocorrencia_inline.html' + ordering = ('-data_modificacao',) + def link_editar(self, obj): if obj.pk is None: return "" diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 775f066..a0dff36 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -130,7 +130,7 @@ class Convenio(models.Model): blank=True, ) data_retorno_assinatura = models.DateField( - _(u'conveniadas'), + _(u'data início vigência'), null=True, blank=True, help_text=_(u'Convênio firmado.') From 8e761bfd3b4e0e4de5848e97b3f250499c4af2d0 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 19 Aug 2021 10:37:40 -0300 Subject: [PATCH 09/73] finalizando o tkt #77 --- .../migrations/0010_auto_20210819_0833.py | 20 +++++++++++++++++++ sigi/apps/ocorrencias/admin.py | 14 ++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 sigi/apps/convenios/migrations/0010_auto_20210819_0833.py diff --git a/sigi/apps/convenios/migrations/0010_auto_20210819_0833.py b/sigi/apps/convenios/migrations/0010_auto_20210819_0833.py new file mode 100644 index 0000000..e1827de --- /dev/null +++ b/sigi/apps/convenios/migrations/0010_auto_20210819_0833.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', '0009_auto_20210611_0946'), + ] + + operations = [ + migrations.AlterField( + model_name='convenio', + name='data_retorno_assinatura', + field=models.DateField(help_text='Conv\xeanio firmado.', null=True, verbose_name='data in\xedcio vig\xeancia', blank=True), + preserve_default=True, + ), + ] diff --git a/sigi/apps/ocorrencias/admin.py b/sigi/apps/ocorrencias/admin.py index 2c55cc9..4f873b87 100644 --- a/sigi/apps/ocorrencias/admin.py +++ b/sigi/apps/ocorrencias/admin.py @@ -85,13 +85,13 @@ class OcorrenciaAdmin(BaseModelAdmin): def get_changelist(self, request, **kwargs): return OcorrenciaChangeList - def get_readonly_fields(self, request, obj=None): - fields = list(self.readonly_fields) - if obj is not None: - fields.extend(['casa_legislativa', 'categoria', 'tipo_contato', 'assunto', 'status', 'descricao', ]) - if obj.status in [Ocorrencia.STATUS_RESOLVIDO, Ocorrencia.STATUS_FECHADO, Ocorrencia.STATUS_DUPLICADO]: # Fechados - fields.append('prioridade') - return fields + # def get_readonly_fields(self, request, obj=None): + # fields = list(self.readonly_fields) + # if obj is not None: + # fields.extend(['casa_legislativa', 'categoria', 'tipo_contato', 'assunto', 'status', 'descricao', ]) + # if obj.status in [Ocorrencia.STATUS_RESOLVIDO, Ocorrencia.STATUS_FECHADO, Ocorrencia.STATUS_DUPLICADO]: # Fechados + # fields.append('prioridade') + # return fields def get_fieldsets(self, request, obj=None): if obj is None: From 62fb8d013c36ae63b7812a3366a9d51b7939fcaf Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 26 Aug 2021 09:36:49 -0300 Subject: [PATCH 10/73] Fix #72 --- sigi/apps/convenios/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index 4a46d57..55b5841 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -73,7 +73,7 @@ class ConvenioAdmin(BaseModelAdmin): 'casa_legislativa__tipo', 'conveniada','equipada', 'casa_legislativa__municipio__uf',) #date_hierarchy = 'data_adesao' - ordering = ('casa_legislativa__tipo__sigla', 'casa_legislativa__municipio__uf', 'casa_legislativa') + ordering = ('casa_legislativa', '-data_retorno_assinatura') raw_id_fields = ('casa_legislativa',) get_queryset = queryset_ascii search_fields = ('id', 'search_text', 'casa_legislativa__sigla', From 0e6f0aff043f6ba33d09b1d0f2e4b668d1290fe5 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 27 Aug 2021 09:17:56 -0300 Subject: [PATCH 11/73] Ordenando corretamente os Contatos --- sigi/apps/casas/admin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 7f542dc..d448df0 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -76,9 +76,9 @@ class FuncionariosInline(admin.StackedInline): inlines = (TelefonesInline,) def get_queryset(self, request): - return (self.model.objects.exclude( - cargo='Presidente').exclude(desativado=True).order_by('-ult_alteracao') - .extra(select={'ult_null': 'ult_alteracao is null'}).extra(order_by=['ult_null']) + return (self.model.objects.exclude(cargo='Presidente') + .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 ) From d634aeb55f0c407155187ccb15c5111b01b561ee Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Mon, 30 Aug 2021 09:35:34 -0300 Subject: [PATCH 12/73] =?UTF-8?q?Concluindo=20a=20ordena=C3=A7=C3=A3o=20do?= =?UTF-8?q?s=20presidentes=20por=20ult=5Falteracao?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/casas/admin.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index d448df0..1a925d5 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -50,6 +50,12 @@ class PresidenteInline(admin.StackedInline): extra = 1 max_num = 1 verbose_name_plural = _(u'Presidente') + def get_queryset(self, request): + 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 + ) class FuncionariosInline(admin.StackedInline): From a0a45d10ac1adaa2ba40911dfc82d7a233bf3ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Tue, 31 Aug 2021 16:48:40 -0300 Subject: [PATCH 13/73] =?UTF-8?q?Remodelagem=20convenios=20-=20elima=20dur?= =?UTF-8?q?a=C3=A7=C3=A3o=20e=20adiciona=20t=C3=A9rmino=20vig=C3=AAncia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/admin.py | 4 +- .../management/commands/duracao_act.py | 43 ------------------- .../0011_convenio_data_termino_vigencia.py | 20 +++++++++ .../migrations/0012_auto_20210831_0844.py | 38 ++++++++++++++++ .../0013_remove_convenio_duracao.py | 18 ++++++++ sigi/apps/convenios/models.py | 37 ++++------------ 6 files changed, 86 insertions(+), 74 deletions(-) delete mode 100644 sigi/apps/convenios/management/commands/duracao_act.py create mode 100644 sigi/apps/convenios/migrations/0011_convenio_data_termino_vigencia.py create mode 100644 sigi/apps/convenios/migrations/0012_auto_20210831_0844.py create mode 100644 sigi/apps/convenios/migrations/0013_remove_convenio_duracao.py diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index 55b5841..dcaa156 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -57,7 +57,7 @@ class ConvenioAdmin(BaseModelAdmin): {'fields': ('servico_gestao', 'servidor_gestao',)} ), (_(u'Datas'), - {'fields': ('data_retorno_assinatura', 'duracao', + {'fields': ('data_retorno_assinatura', 'data_termino_vigencia', 'data_pub_diario',)} ), ) @@ -66,7 +66,7 @@ class ConvenioAdmin(BaseModelAdmin): inlines = (AnexosInline,) list_display = ('num_convenio', 'casa_legislativa', 'get_uf', 'status_convenio', 'link_sigad', 'data_retorno_assinatura', - 'duracao', 'projeto',) + 'data_termino_vigencia', 'projeto',) list_display_links = ('num_convenio', 'casa_legislativa',) list_filter = (('casa_legislativa__gerentes_interlegis', GerentesInterlegisFilter), 'projeto', diff --git a/sigi/apps/convenios/management/commands/duracao_act.py b/sigi/apps/convenios/management/commands/duracao_act.py deleted file mode 100644 index 2144582..0000000 --- a/sigi/apps/convenios/management/commands/duracao_act.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# sigi.apps.casas.management.commands.importa_gerentes -# -# Copyright (c) 2015 by Interlegis -# -# GNU General Public License (GPL) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. -# - -from django.core.management.base import BaseCommand, CommandError -from sigi.apps.convenios.models import Projeto, Convenio - -class Command(BaseCommand): - help = u"""Define a duração de todos os ACT para 60 meses. - * A sigla do Projeto precisa ser ACT; - * O campo duracao precisa estar em branco. - """ - - def handle(self, *args, **options): - self.stdout.write(u"Atualizando ACTs... ") - act = Projeto.objects.get(sigla='ACT') - for conv in Convenio.objects.filter(projeto=act, duracao=None): - conv.duracao = 60 - conv.save() - self.stdout.write(u"\tACT {sigad} da Casa {casa} atualizado".format( - sigad=conv.num_processo_sf, casa=conv.casa_legislativa.nome - )) - self.stdout.write(u"Pronto!") diff --git a/sigi/apps/convenios/migrations/0011_convenio_data_termino_vigencia.py b/sigi/apps/convenios/migrations/0011_convenio_data_termino_vigencia.py new file mode 100644 index 0000000..c5065c1 --- /dev/null +++ b/sigi/apps/convenios/migrations/0011_convenio_data_termino_vigencia.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', '0010_auto_20210819_0833'), + ] + + operations = [ + migrations.AddField( + model_name='convenio', + name='data_termino_vigencia', + field=models.DateField(help_text='T\xe9rmino da vig\xeancia do conv\xeanio.', null=True, verbose_name='Data t\xe9rmino vig\xeancia', blank=True), + preserve_default=True, + ), + ] diff --git a/sigi/apps/convenios/migrations/0012_auto_20210831_0844.py b/sigi/apps/convenios/migrations/0012_auto_20210831_0844.py new file mode 100644 index 0000000..b4e2692 --- /dev/null +++ b/sigi/apps/convenios/migrations/0012_auto_20210831_0844.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from datetime import date +from django.db import models, migrations + +def migra_data_termino_vigencia(apps, schema_editor): + Convenio = apps.get_model('convenios', 'Convenio') + + for c in Convenio.objects.all(): + if (c.data_retorno_assinatura is None or c.duracao is None): + continue + + ano = c.data_retorno_assinatura.year + int(c.duracao / 12) + mes = int(c.data_retorno_assinatura.month + int(c.duracao % 12)) + if mes > 12: + ano = ano + 1 + mes = mes - 12 + dia = c.data_retorno_assinatura.day + + while True: + try: + data_fim = date(year=ano, month=mes,day=dia) + break + except: + dia = dia - 1 + + c.data_termino_vigencia = data_fim + c.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('convenios', '0011_convenio_data_termino_vigencia'), + ] + + operations = [ + migrations.RunPython(migra_data_termino_vigencia), + ] diff --git a/sigi/apps/convenios/migrations/0013_remove_convenio_duracao.py b/sigi/apps/convenios/migrations/0013_remove_convenio_duracao.py new file mode 100644 index 0000000..bcc66bc --- /dev/null +++ b/sigi/apps/convenios/migrations/0013_remove_convenio_duracao.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', '0012_auto_20210831_0844'), + ] + + operations = [ + migrations.RemoveField( + model_name='convenio', + name='duracao', + ), + ] diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index a0dff36..59f00fa 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -15,10 +15,10 @@ class Projeto(models.Model): def __unicode__(self): return self.sigla - + class Meta: ordering = ('nome',) - + class StatusConvenio(models.Model): nome = models.CharField(max_length=100) cancela = models.BooleanField(_(u"Cancela o convênio"), default=False) @@ -135,12 +135,12 @@ class Convenio(models.Model): blank=True, help_text=_(u'Convênio firmado.') ) - duracao = models.PositiveIntegerField( - _(u"duração (meses)"), + data_termino_vigencia = models.DateField( + _(u'Data término vigência'), null=True, blank=True, - help_text=_(u"Deixar em branco caso a duração seja indefinida") - ) + help_text=_(u'Término da vigência do convênio.') + ) data_pub_diario = models.DateField( _(u'data da publicação no Diário Oficial'), null=True, @@ -178,34 +178,13 @@ class Convenio(models.Model): conveniada = models.BooleanField(default=False) equipada = models.BooleanField(default=False) - def get_termino_convenio(self): - if (self.data_retorno_assinatura is None or - self.duracao is None): - return None - - ano = self.data_retorno_assinatura.year + int(self.duracao / 12) - mes = int(self.data_retorno_assinatura.month + int(self.duracao % 12)) - if mes > 12: - ano = ano + 1 - mes = mes - 12 - dia = self.data_retorno_assinatura.day - - while True: - try: - data_fim = date(year=ano, month=mes,day=dia) - break - except: - dia = dia - 1 - - return data_fim - def get_status(self): if self.status and self.status.cancela: return _(u"Cancelado") if self.data_retorno_assinatura is not None: - if self.duracao is not None: - if date.today() >= self.get_termino_convenio(): + if self.data_termino_vigencia is not None: + if date.today() >= self.data_termino_vigencia: return _(u"Vencido") return _(u"Vigente") From b41d4ea4cccf57495b5358798fab1cb6e7c5ffa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 1 Sep 2021 12:04:56 -0300 Subject: [PATCH 14/73] =?UTF-8?q?Adicionar=20municipio,=20UF=20e=20regi?= =?UTF-8?q?=C3=A3o=20da=20Casa=20no=20CSV=20dos=20eventos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/eventos/views.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index ec68f43..464d392 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -315,7 +315,12 @@ def export_csv(request): max_equipe = max([e.equipe_set.count() for e in eventos]) + mun_casa = u'Município da Casa Anfitriã'.encode('utf8') + uf_casa = u'UF da Casa Anfitriã'.encode('utf8') + reg_casa = u'Região da Casa Anfitriã'.encode('utf8') + head = [f.verbose_name.encode('utf8') for f in Evento._meta.fields] + head.extend([mun_casa, uf_casa, reg_casa]) head.extend([f.verbose_name.encode('utf8')+"_{0}".format(i+1) for i in range(max_equipe) for f in Equipe._meta.fields if f.name not in ('id', 'evento')]) @@ -331,6 +336,17 @@ def export_csv(request): for evento in eventos: reg = {f.verbose_name.encode('utf8'): serialize(evento, f) for f in Evento._meta.fields} + if evento.casa_anfitria is None: + reg[mun_casa] = "" + reg[uf_casa] = "" + reg[reg_casa] = "" + else: + reg[mun_casa] = evento.casa_anfitria.municipio.nome.encode('utf8') + reg[uf_casa] = evento.casa_anfitria.municipio.uf.sigla.\ + encode('utf8') + reg[reg_casa] = evento.casa_anfitria.municipio.uf.\ + get_regiao_display().encode('utf8') + idx = 1 for membro in evento.equipe_set.all(): reg.update( From 5a24039aa87f859f13cd6aa81b7b9586704a3f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Thu, 2 Sep 2021 10:33:29 -0300 Subject: [PATCH 15/73] =?UTF-8?q?Importa=C3=A7=C3=A3o=20de=20convenios=20d?= =?UTF-8?q?o=20Gescon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/admin.py | 10 +- sigi/apps/convenios/migrations/0014_gescon.py | 30 ++ sigi/apps/convenios/models.py | 387 +++++++++++++++++- .../templates/convenios/importar_gescon.html | 18 + sigi/apps/convenios/urls.py | 1 + sigi/apps/convenios/views.py | 11 +- templates/admin/base_site.html | 1 + 7 files changed, 454 insertions(+), 4 deletions(-) create mode 100644 sigi/apps/convenios/migrations/0014_gescon.py create mode 100644 sigi/apps/convenios/templates/convenios/importar_gescon.html diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index dcaa156..2f5435f 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 @@ -170,8 +171,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/models.py b/sigi/apps/convenios/models.py index 59f00fa..4982a5f 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): @@ -360,3 +365,383 @@ 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 + verificados = 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 == 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'] + ) + convenio.save() + novos += 1 + elif chk == 1: + convenio = convenios.get() + 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'] + ) + ) + erros += 1 + continue + + if convenio.num_processo_sf != sigad: + sigi_nums = filter( + type(convenio.num_processo_sf).isdigit, + convenio.num_processo_sf + ).zfill(17) + gesc_nums = filter(type(sigad).isdigit, sigad).zfill(17) + if ( sigi_nums == gesc_nums or + convenio.num_processo_sf == ""): + # Número SIGAD incorreto no SIGI, podemos corrigir + convenio.num_processso_sf = sigad + convenio.save() + else: + 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})").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 + ) + ) + erros += 1 + continue + + if convenio.num_convenio != numero: + sigi_nums = filter(type(convenio.num_convenio).isdigit, + convenio.num_convenio).zfill(8) + gesc_nums = filter(type(numero).isdigit, + numero).zfill(8) + if (sigi_nums == gesc_nums or + convenio.num_convenio == ""): + # Número gescon errado no SIGI mas podemos corrigir + convenio.num_convenio = numero + else: + 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})").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 + ) + ) + erros += 1 + continue + + if contrato['objeto'] not in convenio.observacao: + convenio.observacao += "\n" + contrato['objeto'] + + 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: + import ipdb; ipdb.set_trace() + print contrato + raise + + atualizados += 1 + verificados += 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, {verificados} confirmados e " + u"{erros} reportados com erro.").format( + novos=novos, + atualizados=atualizados, + verificados=verificados, + 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 %} + + +{% 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..61aa3bf 100644 --- a/sigi/apps/convenios/views.py +++ b/sigi/apps/convenios/views.py @@ -13,7 +13,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 +372,12 @@ def export_csv(request): csv_writer.writerow(lista) return response + +def importar_gescon(request): + 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/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 %} From 90de878876c1ca62aaf3d82d21f2845c766c740f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Thu, 2 Sep 2021 10:34:03 -0300 Subject: [PATCH 16/73] =?UTF-8?q?Pequena=20corre=C3=A7=C3=A3o=20de=20bug?= =?UTF-8?q?=20na=20gera=C3=A7=C3=A3o=20de=20relat=C3=B3rios=20em=20PDF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/shortcuts.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) 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 From 0be87faf133b60ece0cccda32836b183225f337c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Thu, 2 Sep 2021 12:46:51 -0300 Subject: [PATCH 17/73] =?UTF-8?q?Elimina=20campo=20search=5Ftext=20de=20co?= =?UTF-8?q?nv=C3=AAnio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/admin.py | 5 +++-- .../0015_remove_convenio_search_text.py | 18 ++++++++++++++++++ sigi/apps/convenios/models.py | 1 - 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 sigi/apps/convenios/migrations/0015_remove_convenio_search_text.py diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index 2f5435f..b744c13 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -77,8 +77,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 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/models.py b/sigi/apps/convenios/models.py index 4982a5f..d2aea00 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -54,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, From 46f2d6e3c30bcb41d380d25aefa84d472d92d251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 8 Sep 2021 14:53:50 -0300 Subject: [PATCH 18/73] =?UTF-8?q?Aprimoramentos=20importa=C3=A7=C3=A3o=20G?= =?UTF-8?q?escon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/models.py | 131 ++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index d2aea00..65e5b56 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -523,7 +523,7 @@ class Gescon(models.Model): novos = 0 erros = 0 - verificados = 0 + alertas = 0 atualizados = 0 for contrato in nossos: @@ -607,6 +607,15 @@ class Gescon(models.Model): 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( @@ -623,6 +632,7 @@ class Gescon(models.Model): ) convenio.save() novos += 1 + continue elif chk == 1: convenio = convenios.get() if convenio.casa_legislativa != orgao: @@ -641,79 +651,74 @@ class Gescon(models.Model): continue if convenio.num_processo_sf != sigad: - sigi_nums = filter( - type(convenio.num_processo_sf).isdigit, - convenio.num_processo_sf - ).zfill(17) - gesc_nums = filter(type(sigad).isdigit, sigad).zfill(17) - if ( sigi_nums == gesc_nums or - convenio.num_processo_sf == ""): - # Número SIGAD incorreto no SIGI, podemos corrigir - convenio.num_processso_sf = sigad - convenio.save() - else: - 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})").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 + 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 ) ) - erros += 1 - continue + convenio.num_processo_sf = sigad + alertas += 1 if convenio.num_convenio != numero: - sigi_nums = filter(type(convenio.num_convenio).isdigit, - convenio.num_convenio).zfill(8) - gesc_nums = filter(type(numero).isdigit, - numero).zfill(8) - if (sigi_nums == gesc_nums or - convenio.num_convenio == ""): - # Número gescon errado no SIGI mas podemos corrigir - convenio.num_convenio = numero - else: - 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})").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 - ) - ) - erros += 1 - continue + 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 + alertas += 1 if contrato['objeto'] not in convenio.observacao: convenio.observacao += "\n" + contrato['objeto'] - convenio.data_sigad=contrato['assinatura'] - convenio.data_retorno_assinatura=contrato['inicioVigencia'] - convenio.data_termino_vigencia=contrato['terminoVigencia'] - convenio.data_pub_diario=contrato['publicacao'] + 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: - import ipdb; ipdb.set_trace() - print contrato - raise + 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 - verificados += 1 else: self.add_message(_(u"\tExistem {count} convênios no SIGI " u"que correspondem ao mesmo contrato no " @@ -729,11 +734,11 @@ class Gescon(models.Model): self.add_message( _(u"\t{novos} novos convenios adicionados ao SIGI, " - u"{atualizados} atualizados, {verificados} confirmados e " + u"{atualizados} atualizados, sendo {alertas} com alertas, e " u"{erros} reportados com erro.").format( novos=novos, atualizados=atualizados, - verificados=verificados, + alertas=alertas, erros=erros ) ) From 72ee63fc364b0a1239af0646395d891781200fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Thu, 9 Sep 2021 10:15:23 -0300 Subject: [PATCH 19/73] =?UTF-8?q?Adiciona=20informa=C3=A7=C3=B5es=20de=20i?= =?UTF-8?q?mporta=C3=A7=C3=A3o=20no=20Conv=C3=AAnio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/admin.py | 9 ++++-- .../migrations/0016_auto_20210909_0732.py | 26 +++++++++++++++++ sigi/apps/convenios/models.py | 29 ++++++++++++++++++- sigi/apps/convenios/views.py | 5 ++++ 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 sigi/apps/convenios/migrations/0016_auto_20210909_0732.py diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index b744c13..328f46f 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -58,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', 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 65e5b56..b4dfc79 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -181,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: @@ -628,13 +637,18 @@ class Gescon(models.Model): observacao=contrato['objeto'], data_retorno_assinatura=contrato['inicioVigencia'], data_termino_vigencia=contrato['terminoVigencia'], - data_pub_diario=contrato['publicacao'] + 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 " @@ -647,6 +661,10 @@ class Gescon(models.Model): nome=contrato['nomeFornecedor'] ) ) + convenio.observacao_gescon = _( + u'ERRO: Órgão diverge do Gescon. Não atualizado!' + ) + convenio.save() erros += 1 continue @@ -666,6 +684,9 @@ class Gescon(models.Model): ) ) convenio.num_processo_sf = sigad + convenio.observacao_gescon += _( + u"Número do SIGAD atualizado.\n" + ) alertas += 1 if convenio.num_convenio != numero: @@ -685,10 +706,16 @@ class Gescon(models.Model): ) ) 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[ diff --git a/sigi/apps/convenios/views.py b/sigi/apps/convenios/views.py index 61aa3bf..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 @@ -373,7 +374,11 @@ def export_csv(request): return response +@login_required def importar_gescon(request): + if not request.user.is_superuser: + return HttpResponseForbidden() + action = request.GET.get('action', "") gescon = Gescon.load() From 912d3120adb17f61386c914be6c193ce20b9ff38 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Wed, 15 Sep 2021 12:35:19 -0300 Subject: [PATCH 20/73] =?UTF-8?q?Adicionando=20bot=C3=A3o=20de=20edicao=20?= =?UTF-8?q?para=20servicos=20no=20form=20de=20Casas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/casas/admin.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 1a925d5..2fe3928 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -217,10 +217,10 @@ class ServicoInline(admin.TabularInline): model = Servico fields = ('link_url', 'contato_tecnico', 'contato_administrativo', 'hospedagem_interlegis', 'data_ativacao', 'data_alteracao', - 'data_desativacao') + 'data_desativacao', 'link_servico') readonly_fields = ['link_url', 'contato_tecnico', 'contato_administrativo', 'hospedagem_interlegis', 'data_ativacao', - 'data_alteracao', 'data_desativacao'] + 'data_alteracao', 'data_desativacao', 'link_servico'] extra = 0 max_num = 0 can_delete = False @@ -234,6 +234,22 @@ class ServicoInline(admin.TabularInline): 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 """ + + Editar + """ % (obj.pk, obj.pk, url) + + link_servico.short_description = _(u'Editar Serviço') + link_servico.allow_tags = True + + def has_add_permission(self, request): + return False + # class PlanoDiretorInline(admin.TabularInline): # model = PlanoDiretor From 0c56c9ad55cb7f3df8a0b2f6b215243e53a5ef6e Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Wed, 15 Sep 2021 12:36:13 -0300 Subject: [PATCH 21/73] Alterando a ordem dos Contatos no form de Servicos --- sigi/apps/servicos/admin.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sigi/apps/servicos/admin.py b/sigi/apps/servicos/admin.py index 8826b7b..3fb2d4c 100644 --- a/sigi/apps/servicos/admin.py +++ b/sigi/apps/servicos/admin.py @@ -226,6 +226,13 @@ class ContatosInline(FuncionariosInline): def get_queryset(self, request): return self.model.objects.all() + def get_queryset(self, request): + 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 + ) + class CasaAtendidaAdmin(BaseModelAdmin): actions = None list_display = ('codigo_interlegis', 'nome', 'get_servicos',) From ff9ed195ea90f2f85a717ac1dcebd338bfc58bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Sat, 18 Sep 2021 10:16:39 -0300 Subject: [PATCH 22/73] =?UTF-8?q?Usar=20search=5Ftext=20em=20vez=20de=20no?= =?UTF-8?q?me=20na=20busca=20para=20importa=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/casas/views.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sigi/apps/casas/views.py b/sigi/apps/casas/views.py index 694e84b..8aa29d4 100644 --- a/sigi/apps/casas/views.py +++ b/sigi/apps/casas/views.py @@ -2,6 +2,7 @@ import csv from datetime import datetime from functools import reduce +from sigi.apps.utils import to_ascii from geraldo.generators import PDFGenerator from django.conf import settings @@ -257,9 +258,10 @@ class importa_casas(View): for reg in reader: self.total_registros += 1 reg[self.ERROS] = [] + nome_orgao = to_ascii(reg[self.MUNICIPIO]) orgao = Orgao.objects.filter( tipo__sigla=reg[self.TIPO], - municipio__nome=reg[self.MUNICIPIO], + municipio__search_text__icontains=nome_orgao, municipio__uf__sigla=reg[self.UF] ) if orgao.count() == 0: From 642ef92fec4178981fdc891ddbc029bc7dc60864 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 30 Sep 2021 11:00:22 -0300 Subject: [PATCH 23/73] Ordenando contatos SEIT --- sigi/apps/servicos/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sigi/apps/servicos/admin.py b/sigi/apps/servicos/admin.py index 3fb2d4c..75cd0c3 100644 --- a/sigi/apps/servicos/admin.py +++ b/sigi/apps/servicos/admin.py @@ -233,6 +233,7 @@ class ContatosInline(FuncionariosInline): # 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 CasaAtendidaAdmin(BaseModelAdmin): actions = None list_display = ('codigo_interlegis', 'nome', 'get_servicos',) From aaf2851459107f0fdd957504919cb8dbc2a00bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Thu, 14 Oct 2021 09:33:51 -0300 Subject: [PATCH 24/73] =?UTF-8?q?Ignorar=20certificados=20inv=C3=A1lidos?= =?UTF-8?q?=20ao=20importar=20do=20Gescon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/convenios/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index b4dfc79..84e683d 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -490,7 +490,7 @@ class Gescon(models.Model): projeto = Projeto.objects.get(sigla=sigla_sigi) try: - response = requests.get(url) + response = requests.get(url, verify=False) except Exception as e: self.add_message( _(u"\tErro ao acessar {url}: {errmsg}").format( @@ -775,4 +775,4 @@ class Gescon(models.Model): @classmethod def load(cls): obj, created = cls.objects.get_or_create(pk=1) - return obj \ No newline at end of file + return obj From 7fa37d9d0d1d9191eb30e40213bee75bf73d7492 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 15 Oct 2021 10:06:24 -0300 Subject: [PATCH 25/73] Acionando filtro de exclusao de convenios --- sigi/apps/casas/admin.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 2fe3928..48615f0 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -291,7 +291,7 @@ class ConvenioFilter(admin.SimpleListFilter): def lookups(self, request, model_admin): return ( ('SC', _(u"Sem nenhum convênio")), - ('CC', _(u"Com algum convênio")) + ('CC', _(u"Com algum convênio")), ) + tuple([(p.pk, p.sigla) for p in Projeto.objects.all()]) def queryset(self, request, queryset): @@ -305,6 +305,16 @@ class ConvenioFilter(admin.SimpleListFilter): return queryset.distinct('municipio__uf__nome', 'nome') +class ExcluirConvenioFilter(admin.SimpleListFilter): + title=_(u"Excluir convênio da pesquisa") + parameter_name = 'convenio_excluir' + + def lookups(self, request, model_admin): + return tuple([(p.pk, p.sigla) for p in Projeto.objects.all()]) + + def queryset(self, request, queryset): + queryset = queryset.exclude(convenio__projeto_id=self.value()) + return queryset.distinct('municipio__uf__nome', 'nome') class ServicoFilter(admin.SimpleListFilter): title = _(u"Serviço") @@ -350,7 +360,7 @@ class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin): 'get_servicos') list_display_links = ('sigla', 'nome',) list_filter = ('tipo', ('gerentes_interlegis', GerentesInterlegisFilter), - 'municipio__uf__nome', ConvenioFilter, ServicoFilter, + 'municipio__uf__nome', ConvenioFilter, ExcluirConvenioFilter, ServicoFilter, 'inclusao_digital',) ordering = ('municipio__uf__nome', 'nome') queryset = queryset_ascii From d99e98c1b24fe0974ac73009604e5d0f51ec3472 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 15 Oct 2021 12:00:55 -0300 Subject: [PATCH 26/73] Fix #75 --- sigi/apps/casas/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 48615f0..19b67f8 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -307,7 +307,7 @@ class ConvenioFilter(admin.SimpleListFilter): class ExcluirConvenioFilter(admin.SimpleListFilter): title=_(u"Excluir convênio da pesquisa") - parameter_name = 'convenio_excluir' + parameter_name = 'excluir_convenio' def lookups(self, request, model_admin): return tuple([(p.pk, p.sigla) for p in Projeto.objects.all()]) From 9ff7f420bdd172827939773f127ee746bfc04c1a Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Wed, 20 Oct 2021 11:14:36 -0300 Subject: [PATCH 27/73] Atualizando campo Processo no Senado no form de Casas e Orgaos --- sigi/apps/convenios/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 84e683d..b8e35ac 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -249,18 +249,18 @@ class Convenio(models.Model): if ((self.data_retorno_assinatura is None) and (self.equipada and self.data_termo_aceite is not None)): - return _(u"Convênio nº {number} - equipada em {date} pelo {project}" + return _(u"{project} nº {number} - equipada em {date}" ).format(number=self.num_convenio, date=self.data_termo_aceite.strftime('%d/%m/%Y'), project=self.projeto.sigla) elif self.data_retorno_assinatura is None: - return _(u"Convênio nº {number} - adesão ao projeto {project}, " + return _(u"{project}, nº {number}, início " u"em {date}").format(number=self.num_convenio, project=self.projeto.sigla, date=self.data_adesao) if ((self.data_retorno_assinatura is not None) and not (self.equipada and self.data_termo_aceite is not None)): - return _(u"Convênio nº {number} - conveniada ao {project} em " + return _(u"{project}, nº {number}, inicio em " u"{date}. Status: {status}").format( number=self.num_convenio, project=self.projeto.sigla, @@ -268,7 +268,7 @@ class Convenio(models.Model): status=self.get_status()) if ((self.data_retorno_assinatura is not None) and (self.equipada and self.data_termo_aceite is not None)): - return _(u"Convẽnio nº {number} - conveniada ao {project} em {date}" + return _(u"{project}, nº {number}, início em {date}" u" e equipada em {equipped_date}. Status: {status}" ).format(number=self.num_convenio, project=self.projeto.sigla, From 87de2c9ceec17973229e774ea0344a1c29124105 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Tue, 26 Oct 2021 12:12:24 -0300 Subject: [PATCH 28/73] Fix #98 --- sigi/apps/casas/admin.py | 27 ++++++++++++++++++++++++--- sigi/apps/convenios/models.py | 3 ++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 19b67f8..263b881 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -1,11 +1,13 @@ # -*- 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.http import HttpResponseRedirect from django.shortcuts import render from django.utils.translation import ugettext as _ +#from geraldo.site.newsite.django_1_0.django.forms import extras from image_cropping import ImageCroppingMixin from sigi.apps.casas.forms import OrgaoForm @@ -57,6 +59,24 @@ class PresidenteInline(admin.StackedInline): # 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): + model = Funcionario + fields = ('nome', 'sexo', 'data_nascimento', 'nota', 'email', 'cargo', + 'funcao', 'setor', 'tempo_de_servico', 'ult_alteracao', + 'endereco', 'municipio', 'bairro', 'cep', 'redes_sociais', + 'desativado', 'observacoes') + raw_id_fields = ('municipio',) + readonly_fields = ('ult_alteracao',) + extra = 1 + inlines = (TelefonesInline,) + verbose_name_plural = _(u'Contato Interlegis Vigente') + 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') + ) + def get_extra(self, request, obj=None , **kwargs): + extra = 0 + return extra class FuncionariosInline(admin.StackedInline): model = Funcionario @@ -65,6 +85,7 @@ class FuncionariosInline(admin.StackedInline): 'endereco', 'municipio', 'bairro', 'cep', 'redes_sociais', 'desativado', 'observacoes') raw_id_fields = ('municipio',) + # fieldsets = ((None, { # 'fields': ( # ('nome', 'sexo', 'data_nascimento'), @@ -80,15 +101,15 @@ class FuncionariosInline(admin.StackedInline): readonly_fields = ('ult_alteracao',) extra = 1 inlines = (TelefonesInline,) + verbose_name_plural = _(u'Outros Contatos da Casa') def get_queryset(self, request): - return (self.model.objects.exclude(cargo='Presidente') + return (self.model.objects.exclude(cargo='Presidente',) .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 ) - class ConveniosInline(admin.TabularInline): model = Convenio fieldsets = ( @@ -354,7 +375,7 @@ class ServicoFilter(admin.SimpleListFilter): class OrgaoAdmin(ImageCroppingMixin, BaseModelAdmin): form = OrgaoForm actions = ['adicionar_casas', ] - inlines = (TelefonesInline, PresidenteInline, FuncionariosInline, + inlines = (TelefonesInline, PresidenteInline, ContatoInterlegisInline, FuncionariosInline, ConveniosInline, ServicoInline, OcorrenciaInline,) list_display = ('id', 'sigla', 'nome', 'get_uf', 'get_gerentes', 'get_convenios', 'get_servicos') diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index b8e35ac..3e9aafb 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -3,7 +3,7 @@ import re import requests from datetime import datetime, date from django.db import models -from django.db.models import Q +from django.db.models import Q, fields from django.core.mail import send_mail from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ @@ -65,6 +65,7 @@ class Convenio(models.Model): blank=True, help_text=_(u'Formatos:
    Antigo: XXXXXX/XX-X.
    SIGAD: XXXXX.XXXXXX/XXXX-XX') ) + fieldsets = ({'fields':('num_processo_sf',)}) num_convenio = models.CharField( _(u'número do convênio'), max_length=10, From ade62d8cdbcad02caa76e8c8310c504e4b7fdddb Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Wed, 27 Oct 2021 12:26:12 -0300 Subject: [PATCH 29/73] Fix #100 e Resolvendo problema da busca --- sigi/apps/casas/admin.py | 7 +++++-- sigi/apps/convenios/models.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index 263b881..d5562de 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -334,8 +334,11 @@ class ExcluirConvenioFilter(admin.SimpleListFilter): return tuple([(p.pk, p.sigla) for p in Projeto.objects.all()]) def queryset(self, request, queryset): - queryset = queryset.exclude(convenio__projeto_id=self.value()) - return queryset.distinct('municipio__uf__nome', 'nome') + 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 = _(u"Serviço") diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 3e9aafb..5ab575e 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -10,6 +10,7 @@ from django.utils.translation import ugettext as _ from sigi.apps.utils import SearchField, to_ascii from sigi.apps.casas.models import Orgao from sigi.apps.servidores.models import Servidor, Servico +#from sigi.apps.convenios.admin import ConvenioAdmin class Projeto(models.Model): """ Modelo para representar os projetos do programa @@ -65,7 +66,6 @@ class Convenio(models.Model): blank=True, help_text=_(u'Formatos:
    Antigo: XXXXXX/XX-X.
    SIGAD: XXXXX.XXXXXX/XXXX-XX') ) - fieldsets = ({'fields':('num_processo_sf',)}) num_convenio = models.CharField( _(u'número do convênio'), max_length=10, From 18a3959aa806afd47a971a5737089ca337ee4a65 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 28 Oct 2021 11:14:06 -0300 Subject: [PATCH 30/73] Arrumando o erro de portugues no tkt #98 --- sigi/apps/casas/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/casas/admin.py b/sigi/apps/casas/admin.py index d5562de..a5eb2f7 100644 --- a/sigi/apps/casas/admin.py +++ b/sigi/apps/casas/admin.py @@ -69,7 +69,7 @@ class ContatoInterlegisInline(admin.StackedInline): readonly_fields = ('ult_alteracao',) extra = 1 inlines = (TelefonesInline,) - verbose_name_plural = _(u'Contato Interlegis Vigente') + verbose_name_plural = _(u'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') From f65e302a579c0929d6a1f7aef268f0ba8d6bbad6 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 4 Nov 2021 15:10:33 -0300 Subject: [PATCH 31/73] Alterando campos do form de Eventos de Date para DateField --- .../migrations/0008_auto_20211104_1253.py | 26 +++++++++++++++++++ sigi/apps/eventos/models.py | 16 +++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 sigi/apps/eventos/migrations/0008_auto_20211104_1253.py diff --git a/sigi/apps/eventos/migrations/0008_auto_20211104_1253.py b/sigi/apps/eventos/migrations/0008_auto_20211104_1253.py new file mode 100644 index 0000000..2231f84 --- /dev/null +++ b/sigi/apps/eventos/migrations/0008_auto_20211104_1253.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('eventos', '0007_auto_20210417_0744'), + ] + + operations = [ + migrations.AlterField( + model_name='evento', + name='data_inicio', + field=models.DateTimeField(null=True, verbose_name='Data/hora do In\xedcio', blank=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='evento', + name='data_termino', + field=models.DateTimeField(null=True, verbose_name='Data/hora do Termino', blank=True), + preserve_default=True, + ), + ] diff --git a/sigi/apps/eventos/models.py b/sigi/apps/eventos/models.py index 3fcb85f..964997c 100644 --- a/sigi/apps/eventos/models.py +++ b/sigi/apps/eventos/models.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- - +from datetime import datetime +import random from django.db import models from django.utils.functional import lazy from django.utils.translation import ugettext as _ +from django.contrib.contenttypes import generic from sigi.apps.casas.models import Orgao from sigi.apps.contatos.models import Municipio from sigi.apps.servidores.models import Servidor @@ -35,8 +37,16 @@ class Evento(models.Model): descricao = models.TextField(_(u"Descrição do evento")) virtual = models.BooleanField(_("Virtual"), default=False) solicitante = models.CharField(_(u"Solicitante"), max_length=100) - data_inicio = models.DateField(_(u"Data de início")) - data_termino = models.DateField(_(u"Data de término")) + data_inicio = models.DateTimeField( + _(u"Data/hora do Início"), + null=True, + blank=True + ) + data_termino = models.DateTimeField( + _(u"Data/hora do Termino"), + null=True, + blank=True + ) carga_horaria = models.PositiveIntegerField( _(u"carga horária"), default=0 From eebbe378ff27305b148f39f9e2c4829ec7a88a3e Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 11 Nov 2021 10:10:40 -0300 Subject: [PATCH 32/73] Adcionando submenu de Visitas Interlegis --- sigi/apps/eventos/admin.py | 4 ++++ sigi/apps/home/templatetags/menu_conf.yaml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py index e82717e..4879618 100644 --- a/sigi/apps/eventos/admin.py +++ b/sigi/apps/eventos/admin.py @@ -91,3 +91,7 @@ class EventoAdmin(admin.ModelAdmin): return HttpResponseRedirect('.') adicionar_eventos.short_description = _(u"Armazenar eventos no carrinho " u"para exportar") + + def lookup_allowed(self, lookup, value): + return (super(EventoAdmin, self).lookup_allowed(lookup, value) or + lookup in ['tipo_evento__nome__exact',]) diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index c441946..bb86084 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -47,6 +47,8 @@ main_menu: children: - title: Eventos url: eventos/evento/ + - title: Visitas Interlegis + url: eventos/evento/?tipo_evento__nome__exact=Visita Interlegis - title: Calendário mensal url: eventos/calendario - title: Alocação de equipe From 3fe686a929f8f9f9a9f4b8330c14b29c9e21f2cc Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 11 Nov 2021 13:49:35 -0300 Subject: [PATCH 33/73] =?UTF-8?q?Desabilitando=20o=20submenu=20de=20Oficin?= =?UTF-8?q?as=20enquanto=20n=C3=A3o=20funciona?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/home/templatetags/menu_conf.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index bb86084..5852305 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -47,6 +47,8 @@ main_menu: children: - title: Eventos url: eventos/evento/ +# - title: Oficinas +# url: eventos/evento/?tipo_evento__nome__exact=Oficina - title: Visitas Interlegis url: eventos/evento/?tipo_evento__nome__exact=Visita Interlegis - title: Calendário mensal From 7469023db5c461bab5dd6c6bd6d727fe851935aa Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 12 Nov 2021 12:43:23 -0300 Subject: [PATCH 34/73] Habilitando devidamente o submenu de oficinas --- sigi/apps/eventos/admin.py | 3 ++- sigi/apps/home/templatetags/menu_conf.yaml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py index 4879618..82fb986 100644 --- a/sigi/apps/eventos/admin.py +++ b/sigi/apps/eventos/admin.py @@ -94,4 +94,5 @@ class EventoAdmin(admin.ModelAdmin): def lookup_allowed(self, lookup, value): return (super(EventoAdmin, self).lookup_allowed(lookup, value) or - lookup in ['tipo_evento__nome__exact',]) + lookup in ['tipo_evento__nome__exact', + 'tipo_evento__nome__contains']) diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index 5852305..5be956b 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -47,8 +47,8 @@ main_menu: children: - title: Eventos url: eventos/evento/ -# - title: Oficinas -# url: eventos/evento/?tipo_evento__nome__exact=Oficina + - title: Oficinas + url: eventos/evento/?tipo_evento__nome__contains=Oficina - title: Visitas Interlegis url: eventos/evento/?tipo_evento__nome__exact=Visita Interlegis - title: Calendário mensal From b7001b3823918c5824168f19cead2ec687021d6c Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Tue, 16 Nov 2021 11:41:15 -0300 Subject: [PATCH 35/73] Alterando o submenu de Visitas --- sigi/apps/convenios/models.py | 10 +++++++++- sigi/apps/home/templatetags/menu_conf.yaml | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 5ab575e..636d237 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -10,7 +10,6 @@ from django.utils.translation import ugettext as _ from sigi.apps.utils import SearchField, to_ascii from sigi.apps.casas.models import Orgao from sigi.apps.servidores.models import Servidor, Servico -#from sigi.apps.convenios.admin import ConvenioAdmin class Projeto(models.Model): """ Modelo para representar os projetos do programa @@ -66,6 +65,7 @@ class Convenio(models.Model): blank=True, help_text=_(u'Formatos:
    Antigo: XXXXXX/XX-X.
    SIGAD: XXXXX.XXXXXX/XXXX-XX') ) + link_processo_stf = ('get_sigad_url') num_convenio = models.CharField( _(u'número do convênio'), max_length=10, @@ -212,6 +212,14 @@ class Convenio(models.Model): return _(u"Indefinido") + 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 + def get_sigad_url(self): m = re.match( r'(?P00100|00200)\.(?P\d{6})/(?P\d{4})-\d{2}', diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index 5be956b..8ef31b9 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -50,7 +50,7 @@ main_menu: - title: Oficinas url: eventos/evento/?tipo_evento__nome__contains=Oficina - title: Visitas Interlegis - url: eventos/evento/?tipo_evento__nome__exact=Visita Interlegis + url: eventos/evento/?tipo_evento__nome__contains=Visita - title: Calendário mensal url: eventos/calendario - title: Alocação de equipe From 19d93daa257e99d1fd211fdce23965521e481767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Tue, 16 Nov 2021 13:12:44 -0300 Subject: [PATCH 36/73] Fix #106 --- sigi/apps/eventos/admin.py | 4 ++-- .../migrations/0009_tipoevento_categoria.py | 20 +++++++++++++++++++ sigi/apps/eventos/models.py | 14 ++++++++++++- sigi/apps/home/templatetags/menu_conf.yaml | 12 ++++++++--- 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 sigi/apps/eventos/migrations/0009_tipoevento_categoria.py diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py index 82fb986..271c713 100644 --- a/sigi/apps/eventos/admin.py +++ b/sigi/apps/eventos/admin.py @@ -66,8 +66,8 @@ class EventoAdmin(admin.ModelAdmin): date_hierarchy = 'data_inicio' list_display = ('nome', 'tipo_evento', 'status', 'data_inicio', 'data_termino', 'municipio', 'solicitante') - list_filter = ('status', 'tipo_evento', 'virtual', 'municipio__uf', - 'solicitante') + list_filter = ('status', 'tipo_evento', 'tipo_evento__categoria', 'virtual', + 'municipio__uf', 'solicitante') raw_id_fields = ('casa_anfitria', 'municipio',) search_fields = ('nome', 'tipo_evento__nome', 'casa_anfitria__search_text', 'municipio__search_text', 'solicitante') diff --git a/sigi/apps/eventos/migrations/0009_tipoevento_categoria.py b/sigi/apps/eventos/migrations/0009_tipoevento_categoria.py new file mode 100644 index 0000000..a81069b --- /dev/null +++ b/sigi/apps/eventos/migrations/0009_tipoevento_categoria.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('eventos', '0008_auto_20211104_1253'), + ] + + operations = [ + migrations.AddField( + model_name='tipoevento', + name='categoria', + field=models.CharField(default='E', max_length=1, verbose_name='Categoaria', choices=[(b'C', 'Curso'), (b'E', 'Encontro'), (b'O', 'Oficina'), (b'S', 'Semin\xe1rio'), (b'V', 'Visita')]), + preserve_default=False, + ), + ] diff --git a/sigi/apps/eventos/models.py b/sigi/apps/eventos/models.py index 964997c..2eb1eed 100644 --- a/sigi/apps/eventos/models.py +++ b/sigi/apps/eventos/models.py @@ -11,8 +11,20 @@ from sigi.apps.servidores.models import Servidor from django.core.exceptions import ValidationError class TipoEvento(models.Model): - nome = models.CharField(_(u"Nome"), max_length=100) + CATEGORIA_CHOICES = ( + ('C', _(u'Curso')), + ('E', _(u'Encontro')), + ('O', _(u'Oficina')), + ('S', _(u'Seminário')), + ('V', _(u'Visita')), + ) + nome = models.CharField(_(u"Nome"), max_length=100) + categoria = models.CharField( + _(u'Categoaria'), + max_length=1, + choices=CATEGORIA_CHOICES + ) class Meta: ordering = ("nome",) verbose_name, verbose_name_plural = _(u"Tipo de evento"), _(u"Tipos de evento") diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index 5be956b..4d3f9f0 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -45,12 +45,18 @@ main_menu: url: ocorrencias/ocorrencia/?minhas=S&status__in=1,2 - title: Eventos children: - - title: Eventos + - title: Todos os eventos url: eventos/evento/ + - title: Cursos + url: eventos/evento/?tipo_evento__categoria__exact=C + - title: Encontros + url: eventos/evento/?tipo_evento__categoria__exact=E - title: Oficinas - url: eventos/evento/?tipo_evento__nome__contains=Oficina + url: eventos/evento/?tipo_evento__categoria__exact=O + - title: Seminários + url: eventos/evento/?tipo_evento__categoria__exact=S - title: Visitas Interlegis - url: eventos/evento/?tipo_evento__nome__exact=Visita Interlegis + url: eventos/evento/?tipo_evento__categoria__exact=V - title: Calendário mensal url: eventos/calendario - title: Alocação de equipe From 5546baa76e548701245c2e7b0088d146f49604af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 17 Nov 2021 16:09:35 -0300 Subject: [PATCH 37/73] Fix #106 --- sigi/apps/eventos/admin.py | 14 +++- sigi/apps/eventos/migrations/0010_modulo.py | 37 +++++++++ .../migrations/0011_auto_20211117_0633.py | 24 ++++++ .../migrations/0012_auto_20211117_0657.py | 28 +++++++ sigi/apps/eventos/models.py | 77 ++++++++++++++++++- 5 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 sigi/apps/eventos/migrations/0010_modulo.py create mode 100644 sigi/apps/eventos/migrations/0011_auto_20211117_0633.py create mode 100644 sigi/apps/eventos/migrations/0012_auto_20211117_0657.py diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py index 271c713..63ded3e 100644 --- a/sigi/apps/eventos/admin.py +++ b/sigi/apps/eventos/admin.py @@ -20,9 +20,10 @@ from django import forms 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 TipoEvento, Funcao, Evento, Equipe, Convite +from sigi.apps.eventos.models import Modulo, TipoEvento, Funcao, Evento, Equipe, Convite from sigi.apps.eventos.views import adicionar_eventos_carrinho class EventoAdminForm(forms.ModelForm): @@ -31,7 +32,8 @@ class EventoAdminForm(forms.ModelForm): fields = ('tipo_evento', 'nome', 'descricao', 'virtual', 'solicitante', 'data_inicio', 'data_termino', 'carga_horaria', 'casa_anfitria', 'municipio', 'local', 'publico_alvo', - 'status', 'data_cancelamento', 'motivo_cancelamento', ) + 'total_participantes', 'status', 'data_cancelamento', + 'motivo_cancelamento', ) def clean(self): cleaned_data = super(EventoAdminForm, self).clean() @@ -60,18 +62,22 @@ class ConviteInline(admin.TabularInline): model = Convite raw_id_fields = ('casa',) +class ModuloInline(admin.TabularInline): + model = Modulo + @admin.register(Evento) class EventoAdmin(admin.ModelAdmin): form = EventoAdminForm date_hierarchy = 'data_inicio' list_display = ('nome', 'tipo_evento', 'status', 'data_inicio', - 'data_termino', 'municipio', 'solicitante') + 'data_termino', 'municipio', 'solicitante', + 'total_participantes',) list_filter = ('status', 'tipo_evento', 'tipo_evento__categoria', 'virtual', 'municipio__uf', 'solicitante') raw_id_fields = ('casa_anfitria', 'municipio',) search_fields = ('nome', 'tipo_evento__nome', 'casa_anfitria__search_text', 'municipio__search_text', 'solicitante') - inlines = (EquipeInline, ConviteInline) + inlines = (EquipeInline, ConviteInline, ModuloInline) actions = ['adicionar_eventos', ] def adicionar_eventos(self, request, queryset): diff --git a/sigi/apps/eventos/migrations/0010_modulo.py b/sigi/apps/eventos/migrations/0010_modulo.py new file mode 100644 index 0000000..a03ce5a --- /dev/null +++ b/sigi/apps/eventos/migrations/0010_modulo.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('servidores', '0007_auto_20210430_0735'), + ('eventos', '0009_tipoevento_categoria'), + ] + + operations = [ + migrations.CreateModel( + name='Modulo', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('nome', models.CharField(max_length=100, verbose_name='Nome')), + ('descricao', models.TextField(verbose_name='Descri\xe7\xe3o do m\xf3dulo')), + ('tipo', models.CharField(max_length=1, verbose_name='Tipo', choices=[(b'A', 'Aula'), (b'P', 'Palestra'), (b'R', 'Apresenta\xe7\xe3o')])), + ('inicio', models.DateTimeField(null=True, verbose_name='Data/hora de in\xedcio', blank=True)), + ('termino', models.DateTimeField(null=True, verbose_name='Data/hora de t\xe9rmino', blank=True)), + ('carga_horaria', models.PositiveIntegerField(default=0, verbose_name='carga hor\xe1ria')), + ('qtde_participantes', models.PositiveIntegerField(default=0, help_text='Deixar Zero significa que todos os participantes do evento participaram do m\xf3dulo', verbose_name='n\xfamero de participantes')), + ('apresentador', models.ForeignKey(related_name='modulo_apresentador', on_delete=django.db.models.deletion.PROTECT, verbose_name='Apresentador', blank=True, to='servidores.Servidor', null=True)), + ('evento', models.ForeignKey(verbose_name='Evento', to='eventos.Evento')), + ('monitor', models.ForeignKey(related_name='modulo_monitor', on_delete=django.db.models.deletion.PROTECT, blank=True, to='servidores.Servidor', help_text='Monitor, mediador, auxiliar, etc.', null=True, verbose_name='Monitor')), + ], + options={ + 'verbose_name': 'M\xf3dulo do evento', + 'verbose_name_plural': 'M\xf3dulos do evento', + }, + bases=(models.Model,), + ), + ] diff --git a/sigi/apps/eventos/migrations/0011_auto_20211117_0633.py b/sigi/apps/eventos/migrations/0011_auto_20211117_0633.py new file mode 100644 index 0000000..4b09869 --- /dev/null +++ b/sigi/apps/eventos/migrations/0011_auto_20211117_0633.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('eventos', '0010_modulo'), + ] + + operations = [ + migrations.AlterModelOptions( + name='modulo', + options={'ordering': ('inicio',), 'verbose_name': 'M\xf3dulo do evento', 'verbose_name_plural': 'M\xf3dulos do evento'}, + ), + migrations.AddField( + model_name='evento', + name='total_participantes', + field=models.PositiveIntegerField(default=0, help_text='Se informar quantidade de participantes na aba de convites, este campo ser\xe1 ajustado com a somat\xf3ria dos participantes naquela aba.', verbose_name='Total de participantes'), + preserve_default=True, + ), + ] diff --git a/sigi/apps/eventos/migrations/0012_auto_20211117_0657.py b/sigi/apps/eventos/migrations/0012_auto_20211117_0657.py new file mode 100644 index 0000000..662c4d1 --- /dev/null +++ b/sigi/apps/eventos/migrations/0012_auto_20211117_0657.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.db.models import Sum + +def atualiza_participantes(apps, schema_editor): + if schema_editor.connection.alias != 'default': + return + + Evento = apps.get_model('eventos', 'Evento') + + for e in Evento.objects.all(): + total = e.convite_set.aggregate(total=Sum('qtde_participantes')) + total = total['total'] + if (total is not None) or (total > 0): + e.total_participantes = total + e.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('eventos', '0011_auto_20211117_0633'), + ] + + operations = [ + migrations.RunPython(atualiza_participantes), + ] diff --git a/sigi/apps/eventos/models.py b/sigi/apps/eventos/models.py index 2eb1eed..f9acacd 100644 --- a/sigi/apps/eventos/models.py +++ b/sigi/apps/eventos/models.py @@ -2,6 +2,7 @@ from datetime import datetime import random from django.db import models +from django.db.models import Sum from django.utils.functional import lazy from django.utils.translation import ugettext as _ from django.contrib.contenttypes import generic @@ -76,6 +77,13 @@ class Evento(models.Model): ) local = models.TextField(_(u"Local do evento"), blank=True) publico_alvo = models.TextField(_(u"Público alvo"), blank=True) + total_participantes = models.PositiveIntegerField( + _(u"Total de participantes"), + default=0, + help_text=_(u"Se informar quantidade de participantes na aba de " + u"convites, este campo será ajustado com a somatória " + u"dos participantes naquela aba.") + ) status = models.CharField(_(u"Status"), max_length=1, choices=STATUS_CHOICES) data_cancelamento = models.DateField(_(u"Data de cancelamento"), blank=True, null=True) motivo_cancelamento = models.TextField(_(u"Motivo do cancelamento"), blank=True) @@ -96,7 +104,12 @@ class Evento(models.Model): self.data_cancelamento = None self.motivo_cancelamento = "" if self.data_inicio > self.data_termino: - raise ValidationError(_(u"Data de término deve ser posterior à data de início")) + raise ValidationError(_(u"Data de término deve ser posterior à " + u"data de início")) + total = self.convite_set.aggregate(total=Sum('qtde_participantes')) + total = total['total'] + if (total is not None) or (total > 0): + self.total_participantes = total return super(Evento, self).save(*args, **kwargs) class Funcao(models.Model): @@ -165,4 +178,64 @@ class Convite(models.Model): class Meta: ordering = ('evento', 'casa', '-data_convite') unique_together = ('evento', 'casa') - verbose_name, verbose_name_plural = _(u"Casa convidada"), _(u"Casas convidadas") \ No newline at end of file + verbose_name = _(u"Casa convidada") + verbose_name_plural = _(u"Casas convidadas") + +class Modulo(models.Model): + TIPO_CHOICES = ( + ('A', _(u'Aula')), + ('P', _(u'Palestra')), + ('R', _(u'Apresentação')), + ) + evento = models.ForeignKey(Evento, verbose_name=_(u"Evento")) + nome = models.CharField(_(u"Nome"), max_length=100) + descricao = models.TextField(_(u"Descrição do módulo")) + tipo = models.CharField(_(u'Tipo'), max_length=1, choices=TIPO_CHOICES) + inicio = models.DateTimeField( + _(u"Data/hora de início"), + null=True, + blank=True + ) + termino = models.DateTimeField( + _(u"Data/hora de término"), + null=True, + blank=True + ) + carga_horaria = models.PositiveIntegerField( + _(u"carga horária"), + default=0 + ) + apresentador = models.ForeignKey( + Servidor, + on_delete=models.PROTECT, + related_name="modulo_apresentador", + null=True, + blank=True, + verbose_name=_(u"Apresentador"), + ) + monitor = models.ForeignKey( + Servidor, + on_delete=models.PROTECT, + related_name="modulo_monitor", + null=True, + blank=True, + verbose_name=_(u"Monitor"), + help_text=_(u"Monitor, mediador, auxiliar, etc.") + ) + qtde_participantes = models.PositiveIntegerField( + _(u"número de participantes"), + default=0, + help_text=_(u"Deixar Zero significa que todos os participantes " + u"do evento participaram do módulo"), + ) + + class Meta: + ordering = ('inicio',) + verbose_name = _(u"Módulo do evento") + verbose_name_plural = _(u"Módulos do evento") + + def __unicode__(self): + return _(u"{nome} ({tipo})").format( + nome=self.nome, + tipo=self.get_tipo_display() + ) From fb15e1f9a34b8199cf7d8e73456339ffed7fb0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 17 Nov 2021 17:54:17 -0300 Subject: [PATCH 38/73] Fix #112 --- sigi/apps/servicos/admin.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/sigi/apps/servicos/admin.py b/sigi/apps/servicos/admin.py index 75cd0c3..5d38565 100644 --- a/sigi/apps/servicos/admin.py +++ b/sigi/apps/servicos/admin.py @@ -90,10 +90,25 @@ class DataUtimoUsoFilter(admin.SimpleListFilter): timedelta(days=0) ) queryset = queryset.filter(data_ultimo_uso__range=(de, ate)) - print (de, ate, queryset.count()) - return queryset +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(data_desativacao__isnull=True) + else: + queryset = queryset.filter(data_desativacao__isnull=False) + return queryset class ServicoAdmin(BaseModelAdmin): form = ServicoFormAdmin @@ -116,6 +131,7 @@ class ServicoAdmin(BaseModelAdmin): list_filter = ( 'tipo_servico', 'hospedagem_interlegis', + ServicoAtivoFilter, DataUtimoUsoFilter, ('casa_legislativa__gerentes_interlegis', GerentesInterlegisFilter), 'casa_legislativa__municipio__uf', From 5a81b896848311eb930d40dafa78efbd3c05e1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 17 Nov 2021 21:12:14 -0300 Subject: [PATCH 39/73] Fix #110 --- sigi/apps/eventos/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index 464d392..dc530e5 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -62,17 +62,17 @@ def calendario(request): for evento in Evento.objects.filter(data_inicio__year=ano_pesquisa, data_inicio__month=mes_pesquisa).order_by('data_inicio'): - start = dates.index(evento.data_inicio) - if not evento.data_termino in dates: + start = dates.index(evento.data_inicio.date()) + if not evento.data_termino.date() in dates: lastday = dates[-1] - while lastday < evento.data_termino: + while lastday < evento.data_termino.date(): lastday = lastday + datetime.timedelta(days=1) dates.append(lastday) eventos.append({'evento': evento, 'start': start}) # Calcula a distância dos eventos para as bordas do calendário for evento in eventos: - end = dates.index(evento['evento'].data_termino) + end = dates.index(evento['evento'].data_termino.date()) evento['duration'] = end-evento['start']+1 evento['close'] = len(dates)-end-1 From de27ee206f168cf9d7e60eaef20cec1f1cb5daef Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 18 Nov 2021 10:30:29 -0300 Subject: [PATCH 40/73] Fix #105 --- sigi/apps/convenios/reports.py | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/sigi/apps/convenios/reports.py b/sigi/apps/convenios/reports.py index 0cb0474..f873f2e 100644 --- a/sigi/apps/convenios/reports.py +++ b/sigi/apps/convenios/reports.py @@ -52,6 +52,12 @@ class ConvenioReport(ReportDefault): top=label_top, width=2 * cm, ), + Label( + text=_(u"Projeto"), + left=label_left[5] * cm, + top=label_top + 0.4 * cm, + width=2 * cm, + ), Label( text=_(u"Data do Convênio"), left=label_left[3] * cm, @@ -64,12 +70,6 @@ class ConvenioReport(ReportDefault): top=label_top, width=2 * cm, ), - Label( - text=_(u"Projeto"), - left=label_left[5] * cm, - top=label_top + 0.4 * cm, - width=2 * cm, - ), Label( text=_(u"Orgão"), left=label_left[6] * cm, @@ -98,6 +98,10 @@ class ConvenioReport(ReportDefault): attribute_name='num_convenio', left=label_left[2] * cm ), + ObjectValue( + attribute_name='projeto.sigla', + left=label_left[5] * cm + ), ObjectValue( attribute_name='data_retorno_assinatura', left=label_left[3] * cm, @@ -110,10 +114,6 @@ class ConvenioReport(ReportDefault): get_value=lambda instance: instance.data_pub_diario.strftime('%d/%m/%Y') if instance.data_pub_diario is not None else '-' ), - ObjectValue( - attribute_name='projeto.sigla', - left=label_left[5] * cm - ), ObjectValue( attribute_name='casa_legislativa.nome', left=label_left[6] * cm @@ -160,12 +160,6 @@ class ConvenioReportSemAceite(ConvenioReport): left=label_left[2] * cm, top=label_top, width=2 * cm, - ), - Label( - text=_(u"Data do Convênio"), - left=label_left[3] * cm, - top=label_top, - width=2 * cm, ), Label( text=_(u"Projeto"), @@ -173,6 +167,12 @@ class ConvenioReportSemAceite(ConvenioReport): top=label_top, width=2 * cm, ), + Label( + text=_(u"Data do Convênio"), + left=label_left[3] * cm, + top=label_top, + width=2 * cm, + ), Label( text=_(u"Orgão"), left=label_left[5] * cm, @@ -198,16 +198,16 @@ class ConvenioReportSemAceite(ConvenioReport): attribute_name='num_convenio', left=label_left[2] * cm ), + ObjectValue( + attribute_name='projeto.sigla', + left=label_left[4], + ), ObjectValue( attribute_name='data_retorno_assinatura', left=label_left[3] * 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='projeto.sigla', - left=label_left[4], - ), ObjectValue( attribute_name='casa_legislativa.nome', left=label_left[5] * cm From 0682c015e664882111345083ad6f3284e1a452f0 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 18 Nov 2021 11:03:49 -0300 Subject: [PATCH 41/73] Fix #99 --- sigi/apps/casas/views.py | 5 ++++- sigi/apps/convenios/views.py | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sigi/apps/casas/views.py b/sigi/apps/casas/views.py index 8aa29d4..741786d 100644 --- a/sigi/apps/casas/views.py +++ b/sigi/apps/casas/views.py @@ -2,6 +2,8 @@ import csv from datetime import datetime from functools import reduce + +from django.contrib import messages from sigi.apps.utils import to_ascii from geraldo.generators import PDFGenerator @@ -446,7 +448,8 @@ def visualizar_carrinho(request): def excluir_carrinho(request): if 'carrinho_casas' in request.session: del request.session['carrinho_casas'] - return HttpResponseRedirect('.') + messages.info(request, u'O carrinho foi esvaziado') + return HttpResponseRedirect('../../') @login_required diff --git a/sigi/apps/convenios/views.py b/sigi/apps/convenios/views.py index dd21f0e..e829d09 100644 --- a/sigi/apps/convenios/views.py +++ b/sigi/apps/convenios/views.py @@ -2,6 +2,7 @@ import csv import datetime +from django.contrib import messages from django.http.response import HttpResponseForbidden import ho.pisa as pisa from django.conf import settings @@ -114,7 +115,8 @@ def adicionar_convenios_carrinho(request, queryset=None, id=None): def excluir_carrinho(request): if 'carrinho_convenios' in request.session: del request.session['carrinho_convenios'] - return HttpResponseRedirect('.') + messages.info(request, u'O carrinho foi esvaziado') + return HttpResponseRedirect('../../') @login_required def deleta_itens_carrinho(request): From c652a2b2f77d0a529db4ace2686726900265a7d6 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 18 Nov 2021 12:16:23 -0300 Subject: [PATCH 42/73] Update models.py --- sigi/apps/convenios/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 636d237..adb5021 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -59,7 +59,7 @@ class Convenio(models.Model): on_delete=models.PROTECT, ) # numero designado pelo Senado Federal para o convênio - num_processo_sf = models.CharField( + # num_processo_sf = models.CharField( _(u'número do processo SF (Senado Federal)'), max_length=20, blank=True, From 0272d492540fc46b8a3341e09082c9e17bb22eab Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Thu, 18 Nov 2021 12:17:09 -0300 Subject: [PATCH 43/73] Update models.py --- sigi/apps/convenios/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index adb5021..cabc724 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -59,13 +59,13 @@ class Convenio(models.Model): on_delete=models.PROTECT, ) # numero designado pelo Senado Federal para o convênio - # num_processo_sf = models.CharField( + num_processo_sf = models.CharField( _(u'número do processo SF (Senado Federal)'), max_length=20, blank=True, help_text=_(u'Formatos:
    Antigo: XXXXXX/XX-X.
    SIGAD: XXXXX.XXXXXX/XXXX-XX') ) - link_processo_stf = ('get_sigad_url') + # link_processo_stf = ('get_sigad_url') num_convenio = models.CharField( _(u'número do convênio'), max_length=10, From 40d5bea5bde172f14d76526c4be3d91b747ecaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Sat, 20 Nov 2021 21:43:20 -0300 Subject: [PATCH 44/73] Fixes #104 --- requirements/requirements.txt | 1 + sigi/apps/eventos/admin.py | 6 ++- sigi/apps/eventos/forms.py | 12 +++++ .../migrations/0013_modelodeclaracao.py | 30 +++++++++++++ sigi/apps/eventos/models.py | 43 ++++++++++++++++++ .../admin/eventos/evento/change_form.html | 10 +++++ .../eventos/{ => evento}/change_list.html | 0 .../templates/eventos/declaracao_pdf.html | 24 ++++++++++ .../templates/eventos/seleciona_modelo.html | 25 +++++++++++ sigi/apps/eventos/urls.py | 3 ++ sigi/apps/eventos/views.py | 44 +++++++++++++++++-- sigi/apps/home/templatetags/menu_conf.yaml | 2 + sigi/settings/base.py | 10 ++++- sigi/shortcuts.py | 14 +++--- sigi/urls.py | 1 + templates/base_report.html | 14 +++--- 16 files changed, 219 insertions(+), 20 deletions(-) create mode 100644 sigi/apps/eventos/forms.py create mode 100644 sigi/apps/eventos/migrations/0013_modelodeclaracao.py create mode 100644 sigi/apps/eventos/templates/admin/eventos/evento/change_form.html rename sigi/apps/eventos/templates/admin/eventos/{ => evento}/change_list.html (100%) create mode 100644 sigi/apps/eventos/templates/eventos/declaracao_pdf.html create mode 100644 sigi/apps/eventos/templates/eventos/seleciona_modelo.html diff --git a/requirements/requirements.txt b/requirements/requirements.txt index abfd1d4..ab6351f 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -21,3 +21,4 @@ requests==2.8.1 six==1.10.0 djangorestframework==2.4.8 django-ipware==1.1.6 +django-tinymce==2.6.0 \ No newline at end of file diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py index 63ded3e..d6d9d03 100644 --- a/sigi/apps/eventos/admin.py +++ b/sigi/apps/eventos/admin.py @@ -23,7 +23,7 @@ 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 Modulo, TipoEvento, Funcao, Evento, Equipe, Convite +from sigi.apps.eventos.models import ModeloDeclaracao, Modulo, TipoEvento, Funcao, Evento, Equipe, Convite from sigi.apps.eventos.views import adicionar_eventos_carrinho class EventoAdminForm(forms.ModelForm): @@ -55,6 +55,10 @@ class FuncaoAdmin(admin.ModelAdmin): list_display = ('nome', 'descricao',) search_fields = ('nome', 'descricao',) +@admin.register(ModeloDeclaracao) +class ModeloDeclaracaoAdmin(admin.ModelAdmin): + list_display = ('nome', 'formato') + class EquipeInline(admin.TabularInline): model = Equipe diff --git a/sigi/apps/eventos/forms.py b/sigi/apps/eventos/forms.py new file mode 100644 index 0000000..5804aa0 --- /dev/null +++ b/sigi/apps/eventos/forms.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +from django import forms +from django.utils.translation import ugettext as _ +from sigi.apps.eventos.models import ModeloDeclaracao + +class SelecionaModeloForm(forms.Form): + modelo = forms.ModelChoiceField( + queryset=ModeloDeclaracao.objects.all(), + required=True, + label=_(u"Modelo de declaração"), + ) \ No newline at end of file diff --git a/sigi/apps/eventos/migrations/0013_modelodeclaracao.py b/sigi/apps/eventos/migrations/0013_modelodeclaracao.py new file mode 100644 index 0000000..a8d9e4b --- /dev/null +++ b/sigi/apps/eventos/migrations/0013_modelodeclaracao.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import tinymce.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('eventos', '0012_auto_20211117_0657'), + ] + + operations = [ + migrations.CreateModel( + name='ModeloDeclaracao', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('nome', models.CharField(max_length=100, verbose_name='Nome do modelo')), + ('formato', models.CharField(default=b'A4 portrait', max_length=30, verbose_name='Formato da p\xe1gina', choices=[(b'A4 portrait', 'A4 retrato'), (b'A4 landscape', 'A4 paisagem'), (b'letter portrait', 'Carta retrato'), (b'letter landscape', 'Carta paisagem')])), + ('margem', models.PositiveIntegerField(default=4, help_text='Margem da p\xe1gina em cent\xedmetros', verbose_name='Margem')), + ('texto', tinymce.models.HTMLField(help_text='Use as seguintes marca\xe7\xf5es:
    • {{ casa }} para o nome da Casa Legislativa / \xf3rg\xe3o
    • {{ 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')), + ], + options={ + 'verbose_name': 'modelo de declara\xe7\xe3o', + 'verbose_name_plural': 'modelos de declara\xe7\xe3o', + }, + bases=(models.Model,), + ), + ] diff --git a/sigi/apps/eventos/models.py b/sigi/apps/eventos/models.py index f9acacd..9a11315 100644 --- a/sigi/apps/eventos/models.py +++ b/sigi/apps/eventos/models.py @@ -10,6 +10,7 @@ from sigi.apps.casas.models import Orgao from sigi.apps.contatos.models import Municipio from sigi.apps.servidores.models import Servidor from django.core.exceptions import ValidationError +from tinymce.models import HTMLField class TipoEvento(models.Model): CATEGORIA_CHOICES = ( @@ -239,3 +240,45 @@ class Modulo(models.Model): nome=self.nome, tipo=self.get_tipo_display() ) + +class ModeloDeclaracao(models.Model): + FORMATO_CHOICES = ( + ('A4 portrait', _(u"A4 retrato")), + ('A4 landscape', _(u"A4 paisagem")), + ('letter portrait', _(u"Carta retrato")), + ('letter landscape', _(u"Carta paisagem")) + ) + nome = models.CharField(_(u"Nome do modelo"), max_length=100) + formato = models.CharField( + _(u"Formato da página"), + max_length=30, + choices=FORMATO_CHOICES, + default=FORMATO_CHOICES[0][0] + ) + margem = models.PositiveIntegerField( + _(u"Margem"), + help_text=_(u"Margem da página em centímetros"), + default=4 + ) + 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 }} " + 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
    • " + u"
    • {{ evento.data_termino }} para a data/hora do " + u"término da visita
    • {{ evento.nome }} para o nome " + u"do evento
    • {{ evento.descricao }} para a descrição" + u" do evento
    ") + ) + + class Meta: + verbose_name = _(u"modelo de declaração") + verbose_name_plural = _(u"modelos de declaração") + + def __unicode__(self): + return _(u"{nome} ({formato})").format( + nome=self.nome, + formato=self.get_formato_display() + ) diff --git a/sigi/apps/eventos/templates/admin/eventos/evento/change_form.html b/sigi/apps/eventos/templates/admin/eventos/evento/change_form.html new file mode 100644 index 0000000..5dc8236 --- /dev/null +++ b/sigi/apps/eventos/templates/admin/eventos/evento/change_form.html @@ -0,0 +1,10 @@ +{% extends "base_change_form.html" %} +{% load i18n %} + +{% block object-tools-items %} +
  • + + {% trans 'Declaração' %} +
  • + {{ block.super }} +{% endblock %} diff --git a/sigi/apps/eventos/templates/admin/eventos/change_list.html b/sigi/apps/eventos/templates/admin/eventos/evento/change_list.html similarity index 100% rename from sigi/apps/eventos/templates/admin/eventos/change_list.html rename to sigi/apps/eventos/templates/admin/eventos/evento/change_list.html diff --git a/sigi/apps/eventos/templates/eventos/declaracao_pdf.html b/sigi/apps/eventos/templates/eventos/declaracao_pdf.html new file mode 100644 index 0000000..ec00d5d --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/declaracao_pdf.html @@ -0,0 +1,24 @@ +{% extends 'base_report.html' %} +{% load i18n %} + +{% block pagesize %}{{ pagesize }}{% endblock pagesize %} +{% block pagemargin %}4cm {{ pagemargin }}cm {{ pagemargin }}cm 2cm{% endblock pagemargin %} + +{% block report %} + {% for convite in evento.convite_set.all %} + {% with convite.casa.nome as casa %} + {% for nome in convite.nomes_participantes.splitlines %} + {% block text_body %}{% endblock %} + + {% endfor %} + {% endwith %} + {% endfor %} +{% endblock %} + +{%block page_foot%} + + + + +
    +{% endblock %} diff --git a/sigi/apps/eventos/templates/eventos/seleciona_modelo.html b/sigi/apps/eventos/templates/eventos/seleciona_modelo.html new file mode 100644 index 0000000..c3180f0 --- /dev/null +++ b/sigi/apps/eventos/templates/eventos/seleciona_modelo.html @@ -0,0 +1,25 @@ +{% extends "admin/base_site.html" %} +{% load i18n bootstrap3 %} + +{% block content_title %} +

    {% trans 'Emitir declaração de comparecimento' %}

    +{% endblock %} + +{% block content %} +{% if error %} + +{% endif %} +
    +
    {% csrf_token %} + {% csrf_token %} +
    + {% bootstrap_form form %} +
    + + {% trans "Voltar" %} +
    +
    +{% endblock %} + diff --git a/sigi/apps/eventos/urls.py b/sigi/apps/eventos/urls.py index 05af590..2d0a8f3 100644 --- a/sigi/apps/eventos/urls.py +++ b/sigi/apps/eventos/urls.py @@ -15,5 +15,8 @@ urlpatterns = patterns( url(r'^evento/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho', name='deleta-itens-carrinho-evento'), # Error url(r'^evento/csv/$', 'export_csv', name='evento-export-csv'), # Error + url(r'^evento/(?P\w+)/declaracao/$', 'declaracao', + name='evento-declaracao'), + ) diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index dc530e5..a7f3184 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -21,18 +21,21 @@ import calendar import datetime import locale +import csv +from django import template from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden from django.core.paginator import Paginator, InvalidPage, EmptyPage from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.shortcuts import render +from django.shortcuts import get_object_or_404, render from django.utils import translation from django.utils.translation import ungettext, ugettext as _ +from django.http.response import JsonResponse, HttpResponse +from django.template import Template, Context from sigi.apps.eventos.models import Evento, Equipe, Convite +from sigi.apps.eventos.forms import SelecionaModeloForm from sigi.apps.servidores.models import Servidor -from sigi.shortcuts import render_to_pdf -import csv -from django.http.response import JsonResponse, HttpResponse +from sigi.shortcuts import render_to_pdf, pdf_renderer @login_required def calendario(request): @@ -369,3 +372,36 @@ def export_csv(request): return response +@login_required +def declaracao(request, id): + if request.method == 'POST': + form = SelecionaModeloForm(request.POST) + if form.is_valid(): + evento = get_object_or_404(Evento, id=id) + modelo = form.cleaned_data['modelo'] + template_string = ( + """ + {% extends "eventos/declaracao_pdf.html" %} + {% block text_body %}""" + + modelo.texto + """ + {% endblock %} + """ + ) + context = Context( + {'pagesize': modelo.formato, + 'pagemargin': modelo.margem, + 'evento': evento, + 'data': datetime.date.today(), + } + ) + template = Template(template_string) + # return HttpResponse(template.render(context)) + return pdf_renderer(template, context, 'declaracao.pdf') + else: + form = SelecionaModeloForm() + + return render( + request, + 'eventos/seleciona_modelo.html', + {'form': form, 'evento_id': id} + ) \ No newline at end of file diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml index 4d3f9f0..a230afd 100644 --- a/sigi/apps/home/templatetags/menu_conf.yaml +++ b/sigi/apps/home/templatetags/menu_conf.yaml @@ -85,6 +85,8 @@ main_menu: url: eventos/tipoevento/ - title: Funções na equipe de eventos url: eventos/funcao/ + - title: Modelos de declaração + url: eventos/modelodeclaracao/ # Removidos diff --git a/sigi/settings/base.py b/sigi/settings/base.py index e123cbc..cd57c67 100644 --- a/sigi/settings/base.py +++ b/sigi/settings/base.py @@ -74,7 +74,7 @@ INSTALLED_APPS = ( 'easy_thumbnails', 'image_cropping', 'rest_framework', - + 'tinymce', ) MIDDLEWARE_CLASSES = ( @@ -188,3 +188,11 @@ REST_FRAMEWORK = { WHOIS_WHITELIST = [ '127.0.0.1', ] + +# TinyMCE configuration +TINYMCE_SPELLCHECKER = True +TINYMCE_COMPRESSOR = True +TINYMCE_DEFAULT_CONFIG = { + 'theme': "advanced", + "height": 500, +} \ No newline at end of file diff --git a/sigi/shortcuts.py b/sigi/shortcuts.py index d27986c..4f31978 100644 --- a/sigi/shortcuts.py +++ b/sigi/shortcuts.py @@ -24,12 +24,7 @@ def fetch_resources(uri, rel): uri.replace(settings.MEDIA_URL, "")) return path - -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) - +def pdf_renderer(template, context, filename='report.pdf'): html = template.render(context) response = HttpResponse(content_type='application/pdf') @@ -41,3 +36,10 @@ def render_to_pdf(template_src, context_dict): if pdf.err: return HttpResponse(_(u'We had some errors
    %s
    ') % escape(html)) return response + +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) + + return pdf_renderer(template, context,filename) \ No newline at end of file diff --git a/sigi/urls.py b/sigi/urls.py index 7998344..d269737 100644 --- a/sigi/urls.py +++ b/sigi/urls.py @@ -20,6 +20,7 @@ urlpatterns = patterns( url(r'^ocorrencias/', include('sigi.apps.ocorrencias.urls')), url(r'^eventos/', include('sigi.apps.eventos.urls')), url(r'^whois/', include('sigi.apps.whois.urls')), + url(r'^tinymce/', include('tinymce.urls')), url(r'^', include('sigi.apps.home.urls')), url(r'^', include(admin.site.urls)), diff --git a/templates/base_report.html b/templates/base_report.html index c5cc6e5..96e4495 100644 --- a/templates/base_report.html +++ b/templates/base_report.html @@ -11,11 +11,9 @@ text-align: center; } td.header_text p { - margin: 0px; - font-size: 1.4em; - } - td.header_text { - width: 550px; + margin: 5px; + font-size: 1.2em; + text-align: center; } h1 { font-size: 2em; @@ -58,12 +56,12 @@ } @page { size: {% block pagesize %}{{ pagesize }}{% endblock pagesize %}; - margin: 4cm 1cm 1cm 2cm; + margin: {% block pagemargin %}4cm 1cm 1cm 2cm{% endblock pagemargin %}; font-family: "Helvetica, Arial, sans-serif"; font-size: 2em; @frame header { -pdf-frame-content: header; - top: 1cm; + {% block header-settings %}top: 1cm;{% endblock header-settings %} } @frame footer { -pdf-frame-content: footer; @@ -84,7 +82,7 @@

    {% trans 'SENADO FEDERAL' %}

    -

    {% trans 'ILB - PROGRAMA INTERLEGIS' %}

    +

    {% trans 'INSTITUTO LEGISLATIVO BRASILEIRO - ILB / INTERLEGIS' %}

    {% block subsecretaria %}{% endblock %}

    From 76fe971d3e01cb14be4450f9d318493b4651d0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Sun, 21 Nov 2021 11:52:54 -0300 Subject: [PATCH 45/73] Move form de admin.py para forms.py --- sigi/apps/eventos/admin.py | 21 +-------------------- sigi/apps/eventos/forms.py | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py index d6d9d03..048ce57 100644 --- a/sigi/apps/eventos/admin.py +++ b/sigi/apps/eventos/admin.py @@ -25,26 +25,7 @@ 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.views import adicionar_eventos_carrinho - -class EventoAdminForm(forms.ModelForm): - class Meta: - model = Evento - fields = ('tipo_evento', 'nome', 'descricao', 'virtual', 'solicitante', - 'data_inicio', 'data_termino', 'carga_horaria', - 'casa_anfitria', 'municipio', 'local', 'publico_alvo', - 'total_participantes', 'status', 'data_cancelamento', - 'motivo_cancelamento', ) - - def clean(self): - cleaned_data = super(EventoAdminForm, self).clean() - data_inicio = cleaned_data.get("data_inicio") - data_termino = cleaned_data.get("data_termino") - - if data_inicio > data_termino: - raise forms.ValidationError( - _(u"Data término deve ser posterior à data inicio"), - code="invalid_period" - ) +from sigi.apps.eventos.forms import EventoAdminForm @admin.register(TipoEvento) class TipoEventAdmin(admin.ModelAdmin): diff --git a/sigi/apps/eventos/forms.py b/sigi/apps/eventos/forms.py index 5804aa0..7ec8869 100644 --- a/sigi/apps/eventos/forms.py +++ b/sigi/apps/eventos/forms.py @@ -2,7 +2,27 @@ from django import forms from django.utils.translation import ugettext as _ -from sigi.apps.eventos.models import ModeloDeclaracao +from sigi.apps.eventos.models import ModeloDeclaracao, Evento + +class EventoAdminForm(forms.ModelForm): + class Meta: + model = Evento + fields = ('tipo_evento', 'nome', 'descricao', 'virtual', 'solicitante', + 'data_inicio', 'data_termino', 'carga_horaria', + 'casa_anfitria', 'municipio', 'local', 'publico_alvo', + 'total_participantes', 'status', 'data_cancelamento', + 'motivo_cancelamento', ) + + def clean(self): + cleaned_data = super(EventoAdminForm, self).clean() + data_inicio = cleaned_data.get("data_inicio") + data_termino = cleaned_data.get("data_termino") + + if data_inicio > data_termino: + raise forms.ValidationError( + _(u"Data término deve ser posterior à data inicio"), + code="invalid_period" + ) class SelecionaModeloForm(forms.Form): modelo = forms.ModelChoiceField( From 671ccd0595f1624bfb8337b75a583771fb5dbc31 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Mon, 22 Nov 2021 10:16:40 -0300 Subject: [PATCH 46/73] Atualizando para fazer pull --- sigi/apps/eventos/views.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index dc530e5..379e7c2 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -297,6 +297,11 @@ def deleta_itens_carrinho(request): @login_required def export_csv(request): + # response = HttpResponse(content_type='text/csv') + # response['Content-Disposition'] = 'attachment; filename=eventos.csv' + + # csv_writer = csv.writer(response) + # eventos = carrinhoOrGet_for_qs(request) def serialize(r, field): value = (getattr(r, 'get_{0}_display'.format(field.name), None) or getattr(r, field.name, "")) @@ -366,6 +371,8 @@ def export_csv(request): writer.writerow(reg) if evento.convite_set.count() == 0: writer.writerow(reg) + + # csv_writer.writerow(reg) return response From 6f7fa20950b715ee63fb8a154b1c2c45652abdbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Mon, 22 Nov 2021 10:17:50 -0300 Subject: [PATCH 47/73] Fixes #114 --- sigi/apps/eventos/views.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index a7f3184..8a3adb5 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -87,10 +87,10 @@ def calendario(request): for linha in linhas: sobrepoe = False for e in linha: - if (((evento['evento'].data_inicio >= e['evento'].data_inicio) and - (evento['evento'].data_inicio <= e['evento'].data_termino)) or - ((evento['evento'].data_termino >= e['evento'].data_inicio) and - (evento['evento'].data_termino <= e['evento'].data_termino))): + if (((evento['evento'].data_inicio.date() >= e['evento'].data_inicio.date()) and + (evento['evento'].data_inicio.date() <= e['evento'].data_termino.date())) or + ((evento['evento'].data_termino.date() >= e['evento'].data_inicio.date()) and + (evento['evento'].data_termino.date() <= e['evento'].data_termino.date()))): sobrepoe = True break if not sobrepoe: @@ -109,7 +109,7 @@ def calendario(request): if anterior is None: anterior = evento continue - anterior['close'] = (evento['evento'].data_inicio - anterior['evento'].data_termino).days-1 + anterior['close'] = (evento['evento'].data_inicio.date() - anterior['evento'].data_termino.date()).days-1 evento['start'] = 0 anterior = evento From 3a62fde379e89d3363b1fa39f426b6f51c54fd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Mon, 22 Nov 2021 18:56:48 -0300 Subject: [PATCH 48/73] =?UTF-8?q?Hack=20horroroso=20para=20resolver=20inte?= =?UTF-8?q?gra=C3=A7=C3=A3o=20com=20LDAP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/servidores/models.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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 From d9d293ea475676aa73f12d915624b489499589f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 24 Nov 2021 10:26:17 -0300 Subject: [PATCH 49/73] =?UTF-8?q?Ajuste=20no=20cabe=C3=A7aho=20de=20relat?= =?UTF-8?q?=C3=B3rios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/base_report.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 @@

    {% trans 'SENADO FEDERAL' %}

    -

    {% trans 'INSTITUTO LEGISLATIVO BRASILEIRO - ILB / INTERLEGIS' %}

    +

    {% trans 'Instituto Legislativo Brasileiro' %}

    +

    {% trans "ILB / Interlegis" %}

    {% block subsecretaria %}{% endblock %}

    From 26e4a85ee90cb14601db45a82b7a9b1d1ca1496e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 24 Nov 2021 10:37:55 -0300 Subject: [PATCH 50/73] =?UTF-8?q?Dar=20acesso=20a=20mais=20campos=20da=20C?= =?UTF-8?q?asa=20no=20template=20de=20declara=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/0014_auto_20211124_0736.py | 21 +++++++++++++++++++ sigi/apps/eventos/models.py | 6 ++++-- .../templates/eventos/declaracao_pdf.html | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 sigi/apps/eventos/migrations/0014_auto_20211124_0736.py 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/models.py b/sigi/apps/eventos/models.py index 9a11315..220dff8 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
      • " 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 %} From 009580927c66f3d0006e8932e90ba364b2f3075f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 24 Nov 2021 15:22:34 -0300 Subject: [PATCH 51/73] Adicionar time_zone nos settings --- sigi/settings/base.py | 1 + 1 file changed, 1 insertion(+) 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 = ( From 95492729f62754cec663366a77b5fd08155eed18 Mon Sep 17 00:00:00 2001 From: Davi Galati Date: Mon, 6 Dec 2021 11:42:12 -0300 Subject: [PATCH 52/73] Fix #120 --- sigi/apps/convenios/admin.py | 4 ++-- sigi/apps/convenios/models.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index 328f46f..8296c2c 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -68,9 +68,9 @@ class ConvenioAdmin(BaseModelAdmin): readonly_fields = ('data_sigi', 'atualizacao_gescon', 'observacao_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', diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index cabc724..8c7f8d7 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( From 07df2908aacc988097fa6f3114b205b767fd54fe Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Mon, 6 Dec 2021 12:25:51 -0300 Subject: [PATCH 53/73] Alterando a ordem no form de Convenios --- sigi/apps/convenios/reports.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 '-' ), From b1d7e5034679b41ee9c92e3eb2d2a70a41a8072e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Mon, 6 Dec 2021 12:37:33 -0300 Subject: [PATCH 54/73] Fixes #94 --- sigi/apps/convenios/admin.py | 14 +++++++++++-- .../0017_convenio_id_contrato_gescon.py | 20 +++++++++++++++++++ sigi/apps/convenios/models.py | 17 ++++++++++++++-- 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 sigi/apps/convenios/migrations/0017_convenio_id_contrato_gescon.py diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index 328f46f..368f8f8 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -62,10 +62,10 @@ 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', @@ -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 PDF 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/models.py b/sigi/apps/convenios/models.py index cabc724..39eeeac 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -71,6 +71,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 +511,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 +741,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 +761,7 @@ class Gescon(models.Model): convenio._meta.model_name), args=[convenio.id] ), - errmsg=str(e) + errmsg=e.message.decode("utf8") ) ) erros += 1 From 6dc4fa2a279b6802af796c9ed92cc46669aa2c4b Mon Sep 17 00:00:00 2001 From: Davi Galati Date: Tue, 7 Dec 2021 11:20:53 -0300 Subject: [PATCH 55/73] Fix #118 --- sigi/apps/metas/templatetags/mapa_tags.py | 4 ++-- sigi/apps/metas/views.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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) From 025b81c4e1d2bbc82dadf810d406cd6d24b06bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 8 Dec 2021 12:58:35 -0300 Subject: [PATCH 56/73] Adicionado migrate de convenios --- .../migrations/0018_auto_20211208_1256.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 sigi/apps/convenios/migrations/0018_auto_20211208_1256.py 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, + ), + ] From b61bd74201b3fdd4651ce0c10b8716d2738eb81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Wed, 8 Dec 2021 13:04:19 -0300 Subject: [PATCH 57/73] Fixes #121 --- sigi/apps/eventos/admin.py | 9 +++++-- sigi/apps/eventos/migrations/0015_anexo.py | 29 ++++++++++++++++++++++ sigi/apps/eventos/models.py | 20 +++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 sigi/apps/eventos/migrations/0015_anexo.py 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/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 220dff8..041fb0e 100644 --- a/sigi/apps/eventos/models.py +++ b/sigi/apps/eventos/models.py @@ -284,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)) From d0f431e41237e1a2dc179a95878862b45c6f9078 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Wed, 8 Dec 2021 13:10:19 -0300 Subject: [PATCH 58/73] Fix #125 --- sigi/apps/convenios/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/convenios/admin.py b/sigi/apps/convenios/admin.py index 16de30e..971dd1e 100644 --- a/sigi/apps/convenios/admin.py +++ b/sigi/apps/convenios/admin.py @@ -122,7 +122,7 @@ class ConvenioAdmin(BaseModelAdmin): u"https://adm.senado.gov.br/" u"gestao-contratos/api/{id}").format(id=obj.id_contrato_gescon) - link_gescon.short_description = _("Download PDF do Gescon") + link_gescon.short_description = _("Download MINUTA ASSINADA do Gescon") link_gescon.allow_tags = True def changelist_view(self, request, extra_context=None): From 6541dadbc8d3410e47bc5698d75dde76799be77e Mon Sep 17 00:00:00 2001 From: Davi Galati Date: Thu, 9 Dec 2021 11:13:18 -0300 Subject: [PATCH 59/73] 124 --- sigi/apps/metas/templates/metas/openmap.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 @@ -
        +
        From 44b2214910770e9ff8681d535c3a0329b8d54d9f Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 13:26:45 -0300 Subject: [PATCH 60/73] =?UTF-8?q?Adicionando=20csv=20de=20servi=C3=A7os=20?= =?UTF-8?q?de=20acordo=20com=20o=20tkt=20#119?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/casas/models.py | 13 ++ sigi/apps/servicos/admin.py | 49 ++++- .../admin/servicos/servico/change_list.html | 4 - sigi/apps/servicos/urls.py | 4 + sigi/apps/servicos/views.py | 190 +++++++++++++++++- 5 files changed, 253 insertions(+), 7 deletions(-) delete mode 100644 sigi/apps/servicos/templates/admin/servicos/servico/change_list.html 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/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/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..ed3d97a 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,183 @@ 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) + lista.append(servico.casa_legislativa.telefone) + elif _(u"Contato Interlegis") == atributo: + lista.append(servico.casa_legislativa.contato_interlegis) + if servico.casa_legislativa.contato_interlegis is not None: + lista.append(servico.casa_legislativa.contato_interlegis.email) + else: + 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 From 4bfee27af0de39df87197d9223f98793c40d5a27 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 13:37:00 -0300 Subject: [PATCH 61/73] Subindo templates esquecidos --- .../templates/servico/change_list.html | 33 ++++++ .../servicos/templates/servicos/carrinho.html | 100 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 sigi/apps/servicos/templates/servico/change_list.html create mode 100644 sigi/apps/servicos/templates/servicos/carrinho.html 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 %} + + + + {%if not carIsEmpty%} + + {% endif %} + + + + + + + + + + + {% for servico in paginas.object_list %} + + {%if not carIsEmpty%} + + {% endif %} + + + + + + + + + {% endfor %} + +
        + {% trans 'Casa Legislativa' %}{% trans 'UF' %}{% trans 'Email' %}{% trans 'Telefone' %}{% trans 'Contato Interlegis' %}{% trans 'Tipo de Serviço' %}{% trans 'Data Ativação' %}
        {{servico.casa_legislativa}}{{servico.casa_legislativa.municipio.uf.sigla}}{{servico.casa_legislativa.email}}{{servico.casa_legislativa.telefone}}{{servico.casa_legislativa.contato_interlegis}}{{servico.casa_legislativa.contato_interlegis.email}}{{servico.tipo_servico}}{{servico.data_ativacao}}
        +{% endblock %} + +{% block botoes %} + +
        +
        +
        {% csrf_token %} +
        + {% trans 'Escolha os atributos para exportar' %} +
          +
        • + + + +
        • +
        • + + + +
        • +
        • + + + +
        • +
        • + + + +
        • +
        +
        + +
        +
        +
        + {% endblock %} From d683ae6f40a24e13e23d1d2b3e572203dea5e209 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 13:48:44 -0300 Subject: [PATCH 62/73] Adicionando encode nas strings --- sigi/apps/servicos/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py index ed3d97a..3844876 100644 --- a/sigi/apps/servicos/views.py +++ b/sigi/apps/servicos/views.py @@ -309,12 +309,12 @@ def export_csv(request): 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) - lista.append(servico.casa_legislativa.telefone) + lista.append(servico.casa_legislativa.email.encode("utf-8")) + lista.append(servico.casa_legislativa.telefone.encode("utf-8")) elif _(u"Contato Interlegis") == atributo: - lista.append(servico.casa_legislativa.contato_interlegis) + lista.append(servico.casa_legislativa.contato_interlegis.encode("utf-8")) if servico.casa_legislativa.contato_interlegis is not None: - lista.append(servico.casa_legislativa.contato_interlegis.email) + lista.append(servico.casa_legislativa.contato_interlegis.email.encode("utf-8")) else: lista.append("") elif _(u"Produto") == atributo: From f1822938ef42658a1bba1018c44a51d1f6288b67 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 13:56:36 -0300 Subject: [PATCH 63/73] tratando telefone --- sigi/apps/servicos/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py index 3844876..489a199 100644 --- a/sigi/apps/servicos/views.py +++ b/sigi/apps/servicos/views.py @@ -309,7 +309,10 @@ def export_csv(request): 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.contato_interlegis is not None: + lista.append(servico.casa_legislativa.email.encode("utf-8")) + else: + lista.append("") lista.append(servico.casa_legislativa.telefone.encode("utf-8")) elif _(u"Contato Interlegis") == atributo: lista.append(servico.casa_legislativa.contato_interlegis.encode("utf-8")) From 3cabd881b5511150d1a4b2e31890a1b094dbd6dd Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 14:00:29 -0300 Subject: [PATCH 64/73] tratando telefone --- sigi/apps/servicos/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py index 489a199..04ec597 100644 --- a/sigi/apps/servicos/views.py +++ b/sigi/apps/servicos/views.py @@ -309,11 +309,11 @@ def export_csv(request): 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")) - if servico.casa_legislativa.contato_interlegis is not None: - lista.append(servico.casa_legislativa.email.encode("utf-8")) - else: + lista.append(servico.casa_legislativa.email.encode("utf-8")) + if servico.casa_legislativa.telefone is not None: + lista.append(servico.casa_legislativa.telefone.encode("utf-8")) + else lista.append("") - lista.append(servico.casa_legislativa.telefone.encode("utf-8")) elif _(u"Contato Interlegis") == atributo: lista.append(servico.casa_legislativa.contato_interlegis.encode("utf-8")) if servico.casa_legislativa.contato_interlegis is not None: From 9066b716d55b094b2bbe1e20636f07b787d6225f Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 14:02:41 -0300 Subject: [PATCH 65/73] tratando telefone --- sigi/apps/servicos/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py index 04ec597..3b41d65 100644 --- a/sigi/apps/servicos/views.py +++ b/sigi/apps/servicos/views.py @@ -312,7 +312,7 @@ def export_csv(request): lista.append(servico.casa_legislativa.email.encode("utf-8")) if servico.casa_legislativa.telefone is not None: lista.append(servico.casa_legislativa.telefone.encode("utf-8")) - else + else: lista.append("") elif _(u"Contato Interlegis") == atributo: lista.append(servico.casa_legislativa.contato_interlegis.encode("utf-8")) From e0d241d940250b4e8f9583c839b3698030a5c004 Mon Sep 17 00:00:00 2001 From: Lude Ribeiro Date: Fri, 10 Dec 2021 14:09:27 -0300 Subject: [PATCH 66/73] tratando telefone --- sigi/apps/servicos/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sigi/apps/servicos/views.py b/sigi/apps/servicos/views.py index 3b41d65..c5b5be7 100644 --- a/sigi/apps/servicos/views.py +++ b/sigi/apps/servicos/views.py @@ -311,15 +311,16 @@ def export_csv(request): 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.encode("utf-8")) + lista.append(servico.casa_legislativa.telefone) else: lista.append("") elif _(u"Contato Interlegis") == atributo: - lista.append(servico.casa_legislativa.contato_interlegis.encode("utf-8")) 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: From a0df60685457f1f7cbf0885386c1ef1c6577812c Mon Sep 17 00:00:00 2001 From: Davi Galati Date: Mon, 13 Dec 2021 10:11:50 -0300 Subject: [PATCH 67/73] Fix #128 --- .../templates/convenios/change_list.html | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sigi/apps/convenios/templates/convenios/change_list.html b/sigi/apps/convenios/templates/convenios/change_list.html index f9aae7b..d8856f7 100644 --- a/sigi/apps/convenios/templates/convenios/change_list.html +++ b/sigi/apps/convenios/templates/convenios/change_list.html @@ -14,6 +14,7 @@ Filtro de datas
        +