From 9d2a8d4916cd6352806d36b6e94ab6575f2a7d0a Mon Sep 17 00:00:00 2001 From: rayane maria dos santos Date: Tue, 6 Jun 2023 13:48:20 -0300 Subject: [PATCH 01/11] =?UTF-8?q?feat(95819):=20Implementa=20m=C3=A9todos?= =?UTF-8?q?=20para=20retornar=20pendencias=20cadastrais=20da=20associacao?= =?UTF-8?q?=20e=20conciliacao=20bancaria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(95819): Implementa métodos para retornar pendencias cadastrais da associacao e conciliacao bancaria --- sme_ptrf_apps/conftest.py | 68 +++++++++ .../core/api/views/associacoes_viewset.py | 13 +- sme_ptrf_apps/core/models/associacao.py | 47 +++++- .../test_action_status_periodo.py | 138 +++++++++++++++++- 4 files changed, 262 insertions(+), 4 deletions(-) diff --git a/sme_ptrf_apps/conftest.py b/sme_ptrf_apps/conftest.py index 3998cb8cf..7b3d59e12 100644 --- a/sme_ptrf_apps/conftest.py +++ b/sme_ptrf_apps/conftest.py @@ -459,6 +459,21 @@ def associacao_com_presidente_ausente(unidade, periodo_anterior): cargo_substituto_presidente_ausente=MembroEnum.VICE_PRESIDENTE_DIRETORIA_EXECUTIVA.name ) +@pytest.fixture +def associacao_sem_nome(unidade, periodo_anterior): + return baker.make( + 'Associacao', + nome='', + cnpj='52.302.275/0001-83', + unidade=unidade, + periodo_inicial=periodo_anterior, + ccm='0.000.00-0', + email="ollyverottoboni@gmail.com", + processo_regularidade='123456', + status_presidente='AUSENTE', + cargo_substituto_presidente_ausente=MembroEnum.VICE_PRESIDENTE_DIRETORIA_EXECUTIVA.name + ) + @pytest.fixture def outra_associacao(unidade, periodo_anterior): @@ -504,6 +519,26 @@ def conta_associacao(associacao, tipo_conta): numero_cartao='534653264523' ) +@pytest.fixture +def conta_associacao_tipo_cheque(associacao, tipo_conta_cheque): + return baker.make( + 'ContaAssociacao', + associacao=associacao, + tipo_conta=tipo_conta_cheque, + banco_nome='Banco do Brasil', + agencia='12345', + numero_conta='123456-x', + numero_cartao='534653264523' + ) + +@pytest.fixture +def conta_associacao_incompleta(associacao_sem_nome, tipo_conta_cartao): + return baker.make( + 'ContaAssociacao', + associacao=associacao_sem_nome, + tipo_conta=tipo_conta_cartao, + ) + @pytest.fixture def conta_associacao_cheque(associacao, tipo_conta_cheque): @@ -2024,6 +2059,39 @@ def observacao_conciliacao(periodo, conta_associacao): saldo_extrato = 1000 ) +@pytest.fixture +def observacao_conciliacao_campos_nao_preenchidos(periodo_2020_1, conta_associacao): + return baker.make( + 'ObservacaoConciliacao', + periodo=periodo_2020_1, + associacao=conta_associacao.associacao, + conta_associacao=conta_associacao, + texto="Observação com campos não preenchidos.", + ) + +@pytest.fixture +def observacao_conciliacao_campos_nao_preenchidos_002(periodo_2020_1, conta_associacao_tipo_cheque): + return baker.make( + 'ObservacaoConciliacao', + periodo=periodo_2020_1, + associacao=conta_associacao_tipo_cheque.associacao, + conta_associacao=conta_associacao_tipo_cheque, + texto="Observação com campos não preenchidos 002.", + ) + +@pytest.fixture +def observacao_conciliacao_campos_preenchidos(periodo_2020_1, conta_associacao): + return baker.make( + 'ObservacaoConciliacao', + periodo=periodo_2020_1, + associacao=conta_associacao.associacao, + conta_associacao=conta_associacao, + texto="Observação com campos não preenchidos.", + data_extrato = date(2020, 7, 1), + saldo_extrato = 1000, + comprovante_extrato=None + ) + @pytest.fixture def devolucao_prestacao_conta_2020_1(prestacao_conta_2020_1_conciliada): return baker.make( diff --git a/sme_ptrf_apps/core/api/views/associacoes_viewset.py b/sme_ptrf_apps/core/api/views/associacoes_viewset.py index 5f0a1dfd3..d7e21398f 100644 --- a/sme_ptrf_apps/core/api/views/associacoes_viewset.py +++ b/sme_ptrf_apps/core/api/views/associacoes_viewset.py @@ -234,6 +234,16 @@ def status_periodo(self, request, uuid=None): if prestacao_conta: gerar_previas = pc_requer_geracao_documentos(prestacao_conta) + pendencias_dados = associacao.pendencias_dados_da_associacao_para_geracao_de_documentos() + pendencias_conciliacao = associacao.pendencias_conciliacao_bancaria_por_periodo_para_geracao_de_documentos(periodo) + if pendencias_dados or pendencias_conciliacao: + pendencias_cadastrais = { + 'dados_associacao': pendencias_dados, + 'conciliacao_bancaria': pendencias_conciliacao, + } + else: + pendencias_cadastrais = None + result = { 'associacao': f'{uuid}', 'periodo_referencia': periodo_referencia, @@ -243,6 +253,7 @@ def status_periodo(self, request, uuid=None): 'gerar_ou_editar_ata_apresentacao': gerar_ou_editar_ata_apresentacao, 'gerar_ou_editar_ata_retificacao': gerar_ou_editar_ata_retificacao, 'gerar_previas': gerar_previas, + 'pendencias_cadastrais': pendencias_cadastrais } return Response(result) @@ -707,7 +718,7 @@ def valida_data_de_encerramento(self, request, uuid=None): status_response = response.pop("status") return Response(response, status=status_response) - + @action(detail=False, url_path='tags-informacoes', permission_classes=[IsAuthenticated & PermissaoAPITodosComLeituraOuGravacao]) def tags_informacoes_list(self, request): diff --git a/sme_ptrf_apps/core/models/associacao.py b/sme_ptrf_apps/core/models/associacao.py index bef902e39..1dfe8156d 100644 --- a/sme_ptrf_apps/core/models/associacao.py +++ b/sme_ptrf_apps/core/models/associacao.py @@ -1,6 +1,6 @@ import datetime - from django.db import models +from sme_ptrf_apps.core.models.conta_associacao import ContaAssociacao from sme_ptrf_apps.core.models_abstracts import ModeloIdNome from .validators import cnpj_validation @@ -126,7 +126,7 @@ def tags_de_informacao(self): self.TAG_ENCERRADA, f"{self.tooltip_data_encerramento}" )) - + return tags def apaga_implantacoes_de_saldo(self): @@ -282,6 +282,49 @@ def pode_editar_dados_associacao_encerrada(self): return False return True + @property + def membros_diretoria_executiva_e_conselho_fiscal_cadastrados(self): + for key in MembroEnum: + cargo = self.cargos.filter(cargo_associacao=key.name) + if not cargo.exists(): + return False + return True + + def pendencias_dados_da_associacao_para_geracao_de_documentos(self): + pendencia_cadastro = not self.nome or not self.ccm or not self.unidade.email + pendencia_membros = not self.membros_diretoria_executiva_e_conselho_fiscal_cadastrados + pendencia_contas = self.contas.filter(Q(banco_nome__exact='') | Q(agencia__exact='') | Q(numero_conta__exact='', + status=ContaAssociacao.STATUS_ATIVA)).exists() + if pendencia_cadastro or pendencia_membros or pendencia_contas: + pendencias = { + 'pendencia_cadastro': pendencia_cadastro, + 'pendencia_membros': pendencia_membros, + 'pendencia_contas': pendencia_contas + } + else: + pendencias = None + + return pendencias + + def pendencias_conciliacao_bancaria_por_periodo_para_geracao_de_documentos(self, periodo): + pendencias = { + 'contas_pendentes': [] + } + + contas = self.contas.filter(status=ContaAssociacao.STATUS_ATIVA) + observacoes = self.observacoes_conciliacao_da_associacao.filter(periodo=periodo) + + for conta in contas: + observacao = observacoes.filter(conta_associacao=conta).first() + + if observacao is None or not all([observacao.data_extrato, observacao.saldo_extrato, observacao.comprovante_extrato]): + pendencias['contas_pendentes'].append(conta.uuid) + + if not pendencias['contas_pendentes']: + return None + + return pendencias + objects = models.Manager() # Manager Padrão ativas = AssociacoesAtivasManager() diff --git a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py index b5f8ea7de..11e10130c 100644 --- a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py +++ b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py @@ -37,7 +37,14 @@ def test_status_periodo_em_andamento(jwt_authenticated_client_a, associacao, per 'tem_acertos_pendentes': False, }, 'prestacao_conta': '', - + 'pendencias_cadastrais': { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } } assert response.status_code == status.HTTP_200_OK @@ -69,6 +76,14 @@ def test_status_periodo_pendente(jwt_authenticated_client_a, associacao, periodo 'tem_acertos_pendentes': False, }, 'prestacao_conta': '', + 'pendencias_cadastrais': { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } } @@ -104,6 +119,14 @@ def test_chamada_data_sem_periodo(jwt_authenticated_client_a, associacao, period 'aceita_alteracoes': True, 'prestacao_contas_status': {}, 'prestacao_conta': '', + 'pendencias_cadastrais': { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } } assert response.status_code == status.HTTP_200_OK @@ -137,6 +160,14 @@ def test_status_periodo_finalizado(jwt_authenticated_client_a, associacao, prest 'tem_acertos_pendentes': False, }, 'prestacao_conta': f'{prestacao_conta_2020_1_conciliada.uuid}', + 'pendencias_cadastrais': { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } } @@ -185,8 +216,113 @@ def test_status_periodo_devolvido_para_acertos(jwt_authenticated_client_a, assoc 'tem_acertos_pendentes': False, }, 'prestacao_conta': f'{_prestacao_conta_devolvida.uuid}', + 'pendencias_cadastrais': { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } } assert response.status_code == status.HTTP_200_OK assert result == esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_periodo_pendencias_cadastrais_com_contas_pendentes( + jwt_authenticated_client_a, associacao, + observacao_conciliacao_campos_nao_preenchidos, + observacao_conciliacao_campos_nao_preenchidos_002, + periodo_2020_1 +): + + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', + content_type='application/json') + result = json.loads(response.content) + + pendencias_cadastrais_esperado = { + 'conciliacao_bancaria': { + 'contas_pendentes': [f'{observacao_conciliacao_campos_nao_preenchidos.conta_associacao.uuid}', f'{observacao_conciliacao_campos_nao_preenchidos_002.conta_associacao.uuid}',], + }, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } + + assert response.status_code == status.HTTP_200_OK + assert result['pendencias_cadastrais'] == pendencias_cadastrais_esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_periodo_pendencias_cadastrais_sem_contas_pendentes( + jwt_authenticated_client_a, + associacao, + periodo_2020_1, +): + + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', + content_type='application/json') + result = json.loads(response.content) + + pendencias_cadastrais_esperado = { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } + + assert response.status_code == status.HTTP_200_OK + assert result['pendencias_cadastrais'] == pendencias_cadastrais_esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_periodo_pendencias_cadastrais_somente_dados_associacao_com_pendencia_cadastro_e_pendencia_membros( + jwt_authenticated_client_a, + associacao_sem_nome, + periodo_2020_1, +): + + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao_sem_nome.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', + content_type='application/json') + result = json.loads(response.content) + + pendencias_cadastrais_esperado = { + 'conciliacao_bancaria': None, + 'dados_associacao': { + 'pendencia_cadastro': True, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } + + assert response.status_code == status.HTTP_200_OK + assert result['pendencias_cadastrais'] == pendencias_cadastrais_esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_periodo_todas_as_pendencias_cadastrais( + jwt_authenticated_client_a, + conta_associacao_incompleta, + periodo_2020_1, +): + + response = jwt_authenticated_client_a.get(f'/api/associacoes/{conta_associacao_incompleta.associacao.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', + content_type='application/json') + result = json.loads(response.content) + + pendencias_cadastrais_esperado = { + 'dados_associacao': { + 'pendencia_cadastro': True, + 'pendencia_membros': True, + 'pendencia_contas': True, + }, + 'conciliacao_bancaria': { + 'contas_pendentes': [f'{conta_associacao_incompleta.uuid}'] + }, + } + + assert response.status_code == status.HTTP_200_OK + assert result['pendencias_cadastrais'] == pendencias_cadastrais_esperado From 2c1071342c971699dff829234966dde07394647b Mon Sep 17 00:00:00 2001 From: Matheus de Castro Diori <44413101+mdiori@users.noreply.github.com> Date: Mon, 12 Jun 2023 08:30:47 -0300 Subject: [PATCH 02/11] =?UTF-8?q?feat(94790):=20Adiciona=20op=C3=A7=C3=A3o?= =?UTF-8?q?=20membro=20ausente=20ata=20pc=20(#2096)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(9470): Adiciona a opcao de membro ausente na ata de PC * feat(94790): Modifica nome modelo PresentesAta para Participante --------- Co-authored-by: Matheus --- sme_ptrf_apps/conftest.py | 6 +++--- sme_ptrf_apps/core/admin.py | 10 ++++++---- .../serializers/presentes_ata_serializer.py | 10 +++++----- .../core/api/views/presentes_ata_viewset.py | 15 ++++++++------- .../migrations/0333_presenteata_presente.py | 18 ++++++++++++++++++ .../core/migrations/0334_auto_20230611_2044.py | 17 +++++++++++++++++ sme_ptrf_apps/core/models/__init__.py | 2 +- .../{presentes_ata.py => participante.py} | 5 +++-- .../core/services/ata_dados_service.py | 6 +++--- .../tests/tests_api_presentes_ata/conftest.py | 6 +++--- .../core/tests/tests_services/conftest.py | 4 ++-- 11 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 sme_ptrf_apps/core/migrations/0333_presenteata_presente.py create mode 100644 sme_ptrf_apps/core/migrations/0334_auto_20230611_2044.py rename sme_ptrf_apps/core/models/{presentes_ata.py => participante.py} (94%) diff --git a/sme_ptrf_apps/conftest.py b/sme_ptrf_apps/conftest.py index 7b3d59e12..1183420bb 100644 --- a/sme_ptrf_apps/conftest.py +++ b/sme_ptrf_apps/conftest.py @@ -1808,7 +1808,7 @@ def ata_2020_1_cheque_aprovada(prestacao_conta_2020_1_conciliada): @pytest.fixture def presente_ata_membro(ata_2020_1_cheque_aprovada): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2020_1_cheque_aprovada, identificacao="123", nome="membro", @@ -1833,7 +1833,7 @@ def membro_associacao_presidente_conselho_01(associacao): @pytest.fixture def presente_ata_membro_e_conselho_fiscal(ata_2020_1_cheque_aprovada): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2020_1_cheque_aprovada, identificacao="123", nome="membro", @@ -1845,7 +1845,7 @@ def presente_ata_membro_e_conselho_fiscal(ata_2020_1_cheque_aprovada): @pytest.fixture def presente_ata_nao_membro(ata_2020_1_cheque_aprovada): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2020_1_cheque_aprovada, identificacao="123", nome="membro", diff --git a/sme_ptrf_apps/core/admin.py b/sme_ptrf_apps/core/admin.py index b657e0c33..c9db97356 100644 --- a/sme_ptrf_apps/core/admin.py +++ b/sme_ptrf_apps/core/admin.py @@ -43,7 +43,7 @@ TipoAcertoDocumento, AnaliseDocumentoPrestacaoConta, SolicitacaoAcertoDocumento, - PresenteAta, + Participante, ValoresReprogramados, SolicitacaoDevolucaoAoTesouro, TransferenciaEol, @@ -1237,7 +1237,7 @@ def get_analise_pc(self, obj): autocomplete_fields = ['analise_documento', 'despesa_incluida', 'receita_incluida'] -@admin.register(PresenteAta) +@admin.register(Participante) class PresenteAtaAdmin(admin.ModelAdmin): def get_unidade(self, obj): return f'{obj.ata.associacao.unidade.codigo_eol} - {obj.ata.associacao.unidade.nome}' if obj and obj.ata and obj.ata.associacao and obj.ata.associacao.unidade else '' @@ -1259,12 +1259,14 @@ def get_periodo(self, obj): ] list_filter = [ 'ata__periodo__referencia', - 'ata__associacao__unidade', 'ata__associacao__unidade__tipo_unidade', 'ata__associacao__unidade__dre', 'cargo', - 'membro' + 'membro', + ('criado_em', DateRangeFilter), + ('alterado_em', DateRangeFilter), ] + readonly_fields = ('uuid', 'id', 'criado_em', 'alterado_em') @admin.register(ValoresReprogramados) diff --git a/sme_ptrf_apps/core/api/serializers/presentes_ata_serializer.py b/sme_ptrf_apps/core/api/serializers/presentes_ata_serializer.py index 88ce7163f..ff8ffbd47 100644 --- a/sme_ptrf_apps/core/api/serializers/presentes_ata_serializer.py +++ b/sme_ptrf_apps/core/api/serializers/presentes_ata_serializer.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from ...models import Ata, PresenteAta +from ...models import Ata, Participante class PresentesAtaSerializer(serializers.ModelSerializer): @@ -13,8 +13,8 @@ def editavel(self, obj): return obj.editavel class Meta: - model = PresenteAta - fields = ('ata', 'identificacao', 'nome', 'cargo', 'membro', 'editavel') + model = Participante + fields = ('ata', 'identificacao', 'nome', 'cargo', 'membro', 'editavel', 'presente') class PresentesAtaCreateSerializer(serializers.ModelSerializer): @@ -25,5 +25,5 @@ class PresentesAtaCreateSerializer(serializers.ModelSerializer): ) class Meta: - model = PresenteAta - fields = ('ata', 'identificacao', 'nome', 'cargo', 'membro') + model = Participante + fields = ('ata', 'identificacao', 'nome', 'cargo', 'membro', 'presente') diff --git a/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py b/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py index d387888d6..06392eb11 100644 --- a/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py +++ b/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py @@ -5,7 +5,7 @@ PermissaoApiUe ) from rest_framework.permissions import IsAuthenticated -from ...models import PresenteAta, Ata, MembroAssociacao +from ...models import Participante, Ata, MembroAssociacao from ..serializers.presentes_ata_serializer import PresentesAtaSerializer from rest_framework.decorators import action from rest_framework.response import Response @@ -23,7 +23,7 @@ class PresentesAtaViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, GenericViewSet): permission_classes = [IsAuthenticated & PermissaoApiUe] - queryset = PresenteAta.objects.all() + queryset = Participante.objects.all() serializer_class = PresentesAtaSerializer filter_fields = ('ata__uuid',) filter_backends = (filters.DjangoFilterBackend,) @@ -52,11 +52,11 @@ def membros_e_nao_membros(self, request): return Response(erro, status=status.HTTP_400_BAD_REQUEST) ata = Ata.objects.filter(uuid=ata_uuid).first() - presentes_ata_membros = PresenteAta.objects.filter(ata=ata).filter(membro=True).values() - presentes_ata_nao_membros = PresenteAta.objects.filter(ata=ata).filter(membro=False).order_by('nome').values() + presentes_ata_membros = Participante.objects.filter(ata=ata).filter(membro=True).values() + presentes_ata_nao_membros = Participante.objects.filter(ata=ata).filter(membro=False).order_by('nome').values() associacao = ata.associacao - # presentes_ata_conselho_fiscal = PresenteAta.objects.filter(ata=ata).filter(membro=True).filter(conselho_fiscal=True).values() + # presentes_ata_conselho_fiscal = Participante.objects.filter(ata=ata).filter(membro=True).filter(conselho_fiscal=True).values() presentes_ata_conselho_fiscal = retorna_membros_do_conselho_fiscal_por_associacao(associacao) result = { @@ -100,7 +100,8 @@ def padrao_presentes(self, request): "identificacao": membro.codigo_identificacao if membro.codigo_identificacao != "" else membro.cpf, "nome": membro.nome, "editavel": False, - "membro": True + "membro": True, + "presente": True } membros.append(dado) @@ -191,6 +192,6 @@ def get_nome_cargo_membro_associacao(self, request): "cargo": MembroEnum[membro.cargo_associacao].value } else: - result = PresenteAta.get_informacao_servidor(identificador) + result = Participante.get_informacao_servidor(identificador) return Response(result) diff --git a/sme_ptrf_apps/core/migrations/0333_presenteata_presente.py b/sme_ptrf_apps/core/migrations/0333_presenteata_presente.py new file mode 100644 index 000000000..1051dc271 --- /dev/null +++ b/sme_ptrf_apps/core/migrations/0333_presenteata_presente.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.14 on 2023-06-05 11:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0332_merge_20230517_1106'), + ] + + operations = [ + migrations.AddField( + model_name='presenteata', + name='presente', + field=models.BooleanField(default=True, verbose_name='Presente ?'), + ), + ] diff --git a/sme_ptrf_apps/core/migrations/0334_auto_20230611_2044.py b/sme_ptrf_apps/core/migrations/0334_auto_20230611_2044.py new file mode 100644 index 000000000..b77575b01 --- /dev/null +++ b/sme_ptrf_apps/core/migrations/0334_auto_20230611_2044.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.14 on 2023-06-11 20:44 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0333_presenteata_presente'), + ] + + operations = [ + migrations.RenameModel( + old_name='PresenteAta', + new_name='Participante', + ), + ] diff --git a/sme_ptrf_apps/core/models/__init__.py b/sme_ptrf_apps/core/models/__init__.py index 0e35169f8..042b3b644 100644 --- a/sme_ptrf_apps/core/models/__init__.py +++ b/sme_ptrf_apps/core/models/__init__.py @@ -64,7 +64,7 @@ from .tipo_acerto_documento import TipoAcertoDocumento from .analise_documento_prestacao_conta import AnaliseDocumentoPrestacaoConta from .solicitacao_acerto_documento import SolicitacaoAcertoDocumento -from .presentes_ata import PresenteAta +from .participante import Participante from .valores_reprogramados import ValoresReprogramados from .solicitacao_devolucao_ao_tesouro import SolicitacaoDevolucaoAoTesouro from .falha_geracao_pc import FalhaGeracaoPc diff --git a/sme_ptrf_apps/core/models/presentes_ata.py b/sme_ptrf_apps/core/models/participante.py similarity index 94% rename from sme_ptrf_apps/core/models/presentes_ata.py rename to sme_ptrf_apps/core/models/participante.py index a4e3094c7..c4b302e7e 100644 --- a/sme_ptrf_apps/core/models/presentes_ata.py +++ b/sme_ptrf_apps/core/models/participante.py @@ -5,7 +5,7 @@ from auditlog.registry import auditlog -class PresenteAta(ModeloBase): +class Participante(ModeloBase): history = AuditlogHistoryField() ata = models.ForeignKey('Ata', on_delete=models.CASCADE, related_name='presentes_na_ata') @@ -14,6 +14,7 @@ class PresenteAta(ModeloBase): cargo = models.CharField('Cargo', max_length=200, blank=True, default='') membro = models.BooleanField('Membro ?', default=False) conselho_fiscal = models.BooleanField('Pertence ao conselho fiscal ?', default=False) + presente = models.BooleanField('Presente ?', default=True) def eh_conselho_fiscal(self): if "Presidente do conselho fiscal" in self.cargo or "Conselheiro" in self.cargo: @@ -63,4 +64,4 @@ class Meta: verbose_name_plural = "17.0) Presentes das atas" -auditlog.register(PresenteAta) +auditlog.register(Participante) diff --git a/sme_ptrf_apps/core/services/ata_dados_service.py b/sme_ptrf_apps/core/services/ata_dados_service.py index 95262ae69..655725f93 100644 --- a/sme_ptrf_apps/core/services/ata_dados_service.py +++ b/sme_ptrf_apps/core/services/ata_dados_service.py @@ -1,7 +1,7 @@ import logging from datetime import datetime -from sme_ptrf_apps.core.models import PresenteAta, DevolucaoAoTesouro, Associacao, Periodo +from sme_ptrf_apps.core.models import Participante, DevolucaoAoTesouro, Associacao, Periodo from sme_ptrf_apps.core.services.prestacao_contas_services import informacoes_financeiras_para_atas from sme_ptrf_apps.core.services.associacoes_service import retorna_repasses_pendentes_periodos_ate_agora from sme_ptrf_apps.utils.numero_por_extenso import real @@ -82,8 +82,8 @@ def devolucoes_ao_tesouro_ata(ata, prestacao_de_contas): def presentes_ata(ata): from .membro_associacao_service import retorna_membros_do_conselho_fiscal_por_associacao - presentes_ata_membros = PresenteAta.objects.filter(ata=ata).filter(membro=True).values() - presentes_ata_nao_membros = PresenteAta.objects.filter(ata=ata).filter(membro=False).filter( + presentes_ata_membros = Participante.objects.filter(ata=ata).filter(membro=True).values() + presentes_ata_nao_membros = Participante.objects.filter(ata=ata).filter(membro=False).filter( conselho_fiscal=False).order_by('nome').values() presentes_ata_conselho_fiscal = retorna_membros_do_conselho_fiscal_por_associacao(ata.associacao) diff --git a/sme_ptrf_apps/core/tests/tests_api_presentes_ata/conftest.py b/sme_ptrf_apps/core/tests/tests_api_presentes_ata/conftest.py index 4a1152965..672f2d4e3 100644 --- a/sme_ptrf_apps/core/tests/tests_api_presentes_ata/conftest.py +++ b/sme_ptrf_apps/core/tests/tests_api_presentes_ata/conftest.py @@ -30,7 +30,7 @@ def ata_2020_1_teste(prestacao_conta_2020_1_conciliada): @pytest.fixture def presente_ata_membro_arnaldo(ata_2020_1_teste): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2020_1_teste, identificacao="0001", nome="Arnaldo", @@ -43,7 +43,7 @@ def presente_ata_membro_arnaldo(ata_2020_1_teste): @pytest.fixture def presente_ata_membro_e_conselho_fiscal_benedito(ata_2020_1_teste): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2020_1_teste, identificacao="0002", nome="Benedito", @@ -55,7 +55,7 @@ def presente_ata_membro_e_conselho_fiscal_benedito(ata_2020_1_teste): @pytest.fixture def presente_ata_nao_membro_carlos(ata_2020_1_teste): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2020_1_teste, identificacao="0003", nome="Carlos", diff --git a/sme_ptrf_apps/core/tests/tests_services/conftest.py b/sme_ptrf_apps/core/tests/tests_services/conftest.py index 35972180d..ba191bc87 100644 --- a/sme_ptrf_apps/core/tests/tests_services/conftest.py +++ b/sme_ptrf_apps/core/tests/tests_services/conftest.py @@ -488,7 +488,7 @@ def ata_2022_2_teste_valido(prestacao_conta_2020_1_conciliada): @pytest.fixture def presente_ata_membro_arnaldo(ata_2022_2_teste_valido): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2022_2_teste_valido, identificacao="0001", nome="Arnaldo", @@ -501,7 +501,7 @@ def presente_ata_membro_arnaldo(ata_2022_2_teste_valido): @pytest.fixture def presente_ata_membro_falcao(ata_2022_2_teste_valido): return baker.make( - 'PresenteAta', + 'Participante', ata=ata_2022_2_teste_valido, identificacao="0001", nome="Falcao", From 0e5cf65762cac0b27ea243948b2bf361466fc50d Mon Sep 17 00:00:00 2001 From: rayane maria dos santos Date: Mon, 12 Jun 2023 10:52:30 -0300 Subject: [PATCH 03/11] feat(95557): Implementa rota status-cadastro --- sme_ptrf_apps/conftest.py | 19 +- .../core/api/views/associacoes_viewset.py | 6 + .../tests/tests_api_associacoes/conftest.py | 342 ++++++++++++++++++ .../test_action_status_cadastro.py | 108 ++++++ .../test_action_status_periodo.py | 4 +- 5 files changed, 471 insertions(+), 8 deletions(-) create mode 100644 sme_ptrf_apps/core/tests/tests_api_associacoes/conftest.py create mode 100644 sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_cadastro.py diff --git a/sme_ptrf_apps/conftest.py b/sme_ptrf_apps/conftest.py index 7b3d59e12..8b22e110f 100644 --- a/sme_ptrf_apps/conftest.py +++ b/sme_ptrf_apps/conftest.py @@ -460,16 +460,16 @@ def associacao_com_presidente_ausente(unidade, periodo_anterior): ) @pytest.fixture -def associacao_sem_nome(unidade, periodo_anterior): +def associacao_cadastro_incompleto(unidade, periodo_anterior): return baker.make( 'Associacao', nome='', - cnpj='52.302.275/0001-83', + cnpj='52.302.275/0001-84', unidade=unidade, periodo_inicial=periodo_anterior, ccm='0.000.00-0', - email="ollyverottoboni@gmail.com", - processo_regularidade='123456', + email="associacaosemnome@gmail.com", + processo_regularidade='000000', status_presidente='AUSENTE', cargo_substituto_presidente_ausente=MembroEnum.VICE_PRESIDENTE_DIRETORIA_EXECUTIVA.name ) @@ -532,13 +532,20 @@ def conta_associacao_tipo_cheque(associacao, tipo_conta_cheque): ) @pytest.fixture -def conta_associacao_incompleta(associacao_sem_nome, tipo_conta_cartao): +def conta_associacao_incompleta(associacao_cadastro_incompleto, tipo_conta_cartao): return baker.make( 'ContaAssociacao', - associacao=associacao_sem_nome, + associacao=associacao_cadastro_incompleto, tipo_conta=tipo_conta_cartao, ) +@pytest.fixture +def conta_associacao_incompleta_002(associacao, tipo_conta_cartao): + return baker.make( + 'ContaAssociacao', + associacao=associacao, + tipo_conta=tipo_conta_cartao, + ) @pytest.fixture def conta_associacao_cheque(associacao, tipo_conta_cheque): diff --git a/sme_ptrf_apps/core/api/views/associacoes_viewset.py b/sme_ptrf_apps/core/api/views/associacoes_viewset.py index d7e21398f..8623269a3 100644 --- a/sme_ptrf_apps/core/api/views/associacoes_viewset.py +++ b/sme_ptrf_apps/core/api/views/associacoes_viewset.py @@ -727,3 +727,9 @@ def tags_informacoes_list(self, request): return Response(result) + @action(detail=True, url_path='status-cadastro', + permission_classes=[IsAuthenticated & PermissaoAPITodosComLeituraOuGravacao]) + def status_cadastro(self, request, uuid=None): + associacao = self.get_object() + response = associacao.pendencias_dados_da_associacao_para_geracao_de_documentos() + return Response(response) diff --git a/sme_ptrf_apps/core/tests/tests_api_associacoes/conftest.py b/sme_ptrf_apps/core/tests/tests_api_associacoes/conftest.py new file mode 100644 index 000000000..af0e9e6d4 --- /dev/null +++ b/sme_ptrf_apps/core/tests/tests_api_associacoes/conftest.py @@ -0,0 +1,342 @@ +import pytest +from model_bakery import baker +from sme_ptrf_apps.core.models.membro_associacao import MembroEnum, RepresentacaoCargo + +@pytest.fixture +def membro_associacao_001(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 001', + associacao=associacao, + cargo_associacao=MembroEnum.PRESIDENTE_DIRETORIA_EXECUTIVA.name, + cargo_educacao='Coordenador', + representacao=RepresentacaoCargo.SERVIDOR.name, + email='membroassociacao001@gmail.com', + codigo_identificacao='001' + ) + +@pytest.fixture +def membro_associacao_002(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 002', + associacao=associacao, + cargo_associacao=MembroEnum.VICE_PRESIDENTE_DIRETORIA_EXECUTIVA.name, + email='membroassociacao002@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='002' + ) + +@pytest.fixture +def membro_associacao_003(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 003', + associacao=associacao, + cargo_associacao=MembroEnum.SECRETARIO.name, + email='membroassociacao003@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='003' + ) + +@pytest.fixture +def membro_associacao_004(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 004', + associacao=associacao, + cargo_associacao=MembroEnum.TESOUREIRO.name, + email='membroassociacao004@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='004' + ) + +@pytest.fixture +def membro_associacao_005(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 005', + associacao=associacao, + cargo_associacao=MembroEnum.VOGAL_1.name, + email='membroassociacao005@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='005' + ) + +@pytest.fixture +def membro_associacao_006(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 006', + associacao=associacao, + cargo_associacao=MembroEnum.VOGAL_2.name, + email='membroassociacao006@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='006' + ) + +@pytest.fixture +def membro_associacao_007(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 007', + associacao=associacao, + cargo_associacao=MembroEnum.VOGAL_3.name, + email='membroassociacao007@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='007' + ) + +@pytest.fixture +def membro_associacao_008(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 008', + associacao=associacao, + cargo_associacao=MembroEnum.VOGAL_4.name, + email='membroassociacao008@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='008' + ) + +@pytest.fixture +def membro_associacao_009(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 009', + associacao=associacao, + cargo_associacao=MembroEnum.VOGAL_5.name, + email='membroassociacao009@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='009' + ) + +@pytest.fixture +def membro_associacao_010(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 010', + associacao=associacao, + cargo_associacao=MembroEnum.PRESIDENTE_CONSELHO_FISCAL.name, + email='membroassociacao010@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0010' + ) + +@pytest.fixture +def membro_associacao_011(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 011', + associacao=associacao, + cargo_associacao=MembroEnum.CONSELHEIRO_1.name, + email='membroassociacao011@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0011' + ) + +@pytest.fixture +def membro_associacao_012(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 012', + associacao=associacao, + cargo_associacao=MembroEnum.CONSELHEIRO_2.name, + email='membroassociacao012@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0012' + ) + +@pytest.fixture +def membro_associacao_013(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 013', + associacao=associacao, + cargo_associacao=MembroEnum.CONSELHEIRO_3.name, + email='membroassociacao013@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0013' + ) + +@pytest.fixture +def membro_associacao_014(associacao): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao 014', + associacao=associacao, + cargo_associacao=MembroEnum.CONSELHEIRO_4.name, + email='membroassociacao014@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0014' + ) + + +@pytest.fixture +def membro_associacao_cadastro_incompleto_001(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 001', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.PRESIDENTE_DIRETORIA_EXECUTIVA.name, + cargo_educacao='Coordenador', + representacao=RepresentacaoCargo.SERVIDOR.name, + email='membroassociacao001@gmail.com', + codigo_identificacao='001' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_002(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 002', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.VICE_PRESIDENTE_DIRETORIA_EXECUTIVA.name, + email='membroassociacao002@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='002' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_003(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 003', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.SECRETARIO.name, + email='membroassociacao003@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='003' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_004(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 004', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.TESOUREIRO.name, + email='membroassociacao004@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='004' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_005(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 005', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.VOGAL_1.name, + email='membroassociacao005@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='005' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_006(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 006', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.VOGAL_2.name, + email='membroassociacao006@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='006' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_007(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 007', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.VOGAL_3.name, + email='membroassociacao007@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='007' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_008(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 008', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.VOGAL_4.name, + email='membroassociacao008@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='008' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_009(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 009', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.VOGAL_5.name, + email='membroassociacao009@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='009' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_010(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 010', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.PRESIDENTE_CONSELHO_FISCAL.name, + email='membroassociacao010@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0010' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_011(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 011', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.CONSELHEIRO_1.name, + email='membroassociacao011@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0011' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_012(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 012', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.CONSELHEIRO_2.name, + email='membroassociacao012@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0012' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_013(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 013', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.CONSELHEIRO_3.name, + email='membroassociacao013@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0013' + ) + +@pytest.fixture +def membro_associacao_cadastro_incompleto_014(associacao_cadastro_incompleto): + return baker.make( + 'MembroAssociacao', + nome='Membro Associacao Cadastro Incompleto 014', + associacao=associacao_cadastro_incompleto, + cargo_associacao=MembroEnum.CONSELHEIRO_4.name, + email='membroassociacao014@gmail.com', + representacao=RepresentacaoCargo.SERVIDOR.name, + codigo_identificacao='0014' + ) diff --git a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_cadastro.py b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_cadastro.py new file mode 100644 index 000000000..dbe047971 --- /dev/null +++ b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_cadastro.py @@ -0,0 +1,108 @@ +import json +import pytest + +from freezegun import freeze_time +from rest_framework import status + +pytestmark = pytest.mark.django_db + +@freeze_time('2020-07-10 10:20:00') +def test_status_cadastro_somente_pendencia_cadastro( + jwt_authenticated_client_a, + associacao_cadastro_incompleto, + membro_associacao_cadastro_incompleto_001, + membro_associacao_cadastro_incompleto_002, + membro_associacao_cadastro_incompleto_003, + membro_associacao_cadastro_incompleto_004, + membro_associacao_cadastro_incompleto_005, + membro_associacao_cadastro_incompleto_006, + membro_associacao_cadastro_incompleto_007, + membro_associacao_cadastro_incompleto_008, + membro_associacao_cadastro_incompleto_009, + membro_associacao_cadastro_incompleto_010, + membro_associacao_cadastro_incompleto_011, + membro_associacao_cadastro_incompleto_012, + membro_associacao_cadastro_incompleto_013, + membro_associacao_cadastro_incompleto_014, +): + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao_cadastro_incompleto.uuid}/status-cadastro/', + content_type='application/json') + result = json.loads(response.content) + + status_cadastro_esperado = { + 'pendencia_cadastro': True, + 'pendencia_contas': False, + 'pendencia_membros': False + } + + assert response.status_code == status.HTTP_200_OK + assert result == status_cadastro_esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_cadastro_somente_pendencia_contas( + jwt_authenticated_client_a, + membro_associacao_001, + membro_associacao_002, + membro_associacao_003, + membro_associacao_004, + membro_associacao_005, + membro_associacao_006, + membro_associacao_007, + membro_associacao_008, + membro_associacao_009, + membro_associacao_010, + membro_associacao_011, + membro_associacao_012, + membro_associacao_013, + membro_associacao_014, + conta_associacao_incompleta_002, +): + response = jwt_authenticated_client_a.get(f'/api/associacoes/{conta_associacao_incompleta_002.associacao.uuid}/status-cadastro/', + content_type='application/json') + result = json.loads(response.content) + + status_cadastro_esperado = { + 'pendencia_cadastro': False, + 'pendencia_contas': True, + 'pendencia_membros': False + } + + assert response.status_code == status.HTTP_200_OK + assert result == status_cadastro_esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_cadastro_somente_pendencia_membros( + jwt_authenticated_client_a, + associacao, +): + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao.uuid}/status-cadastro/', + content_type='application/json') + result = json.loads(response.content) + + status_cadastro_esperado = { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + + assert response.status_code == status.HTTP_200_OK + assert result == status_cadastro_esperado + +@freeze_time('2020-07-10 10:20:00') +def test_status_cadastro_todas_as_pendencias( + jwt_authenticated_client_a, + conta_associacao_incompleta, +): + response = jwt_authenticated_client_a.get(f'/api/associacoes/{conta_associacao_incompleta.associacao.uuid}/status-cadastro/', + content_type='application/json') + result = json.loads(response.content) + + status_cadastro_esperado = { + 'pendencia_cadastro': True, + 'pendencia_contas': True, + 'pendencia_membros': True + } + + assert response.status_code == status.HTTP_200_OK + assert result == status_cadastro_esperado + diff --git a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py index 11e10130c..83fc444d3 100644 --- a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py +++ b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py @@ -282,11 +282,11 @@ def test_status_periodo_pendencias_cadastrais_sem_contas_pendentes( @freeze_time('2020-07-10 10:20:00') def test_status_periodo_pendencias_cadastrais_somente_dados_associacao_com_pendencia_cadastro_e_pendencia_membros( jwt_authenticated_client_a, - associacao_sem_nome, + associacao_cadastro_incompleto, periodo_2020_1, ): - response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao_sem_nome.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao_cadastro_incompleto.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', content_type='application/json') result = json.loads(response.content) From b5ecac06bb03522f1182c9dbc08afe7db5e2da0d Mon Sep 17 00:00:00 2001 From: rayane maria dos santos Date: Tue, 13 Jun 2023 14:45:57 -0300 Subject: [PATCH 04/11] feat(89001): Corrige validacao de cadastri contas bancarias --- sme_ptrf_apps/conftest.py | 12 +++++++++ sme_ptrf_apps/core/models/associacao.py | 3 +-- .../test_action_status_periodo.py | 26 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/sme_ptrf_apps/conftest.py b/sme_ptrf_apps/conftest.py index fc58708a8..90d4352c2 100644 --- a/sme_ptrf_apps/conftest.py +++ b/sme_ptrf_apps/conftest.py @@ -2076,6 +2076,18 @@ def observacao_conciliacao_campos_nao_preenchidos(periodo_2020_1, conta_associac texto="Observação com campos não preenchidos.", ) +@pytest.fixture +def observacao_conciliacao_com_saldo_zero(periodo_2020_1, conta_associacao): + return baker.make( + 'ObservacaoConciliacao', + periodo=periodo_2020_1, + associacao=conta_associacao.associacao, + conta_associacao=conta_associacao, + data_extrato = date(2020, 7, 1), + saldo_extrato = 0, + texto="Observação com saldo zero." + ) + @pytest.fixture def observacao_conciliacao_campos_nao_preenchidos_002(periodo_2020_1, conta_associacao_tipo_cheque): return baker.make( diff --git a/sme_ptrf_apps/core/models/associacao.py b/sme_ptrf_apps/core/models/associacao.py index 1dfe8156d..08e8353af 100644 --- a/sme_ptrf_apps/core/models/associacao.py +++ b/sme_ptrf_apps/core/models/associacao.py @@ -316,8 +316,7 @@ def pendencias_conciliacao_bancaria_por_periodo_para_geracao_de_documentos(self, for conta in contas: observacao = observacoes.filter(conta_associacao=conta).first() - - if observacao is None or not all([observacao.data_extrato, observacao.saldo_extrato, observacao.comprovante_extrato]): + if observacao is None or not (observacao.data_extrato and ((observacao.saldo_extrato > 0 and observacao.comprovante_extrato) or observacao.saldo_extrato == 0)): pendencias['contas_pendentes'].append(conta.uuid) if not pendencias['contas_pendentes']: diff --git a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py index 83fc444d3..1904b0d5f 100644 --- a/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py +++ b/sme_ptrf_apps/core/tests/tests_api_associacoes/test_action_status_periodo.py @@ -256,6 +256,32 @@ def test_status_periodo_pendencias_cadastrais_com_contas_pendentes( assert response.status_code == status.HTTP_200_OK assert result['pendencias_cadastrais'] == pendencias_cadastrais_esperado +@freeze_time('2020-07-10 10:20:00') +def test_status_periodo_pendencias_cadastrais_somente_uma_conta_pendente( + jwt_authenticated_client_a, associacao, + observacao_conciliacao_campos_nao_preenchidos_002, + observacao_conciliacao_com_saldo_zero, + periodo_2020_1 +): + + response = jwt_authenticated_client_a.get(f'/api/associacoes/{associacao.uuid}/status-periodo/?data={periodo_2020_1.data_inicio_realizacao_despesas}', + content_type='application/json') + result = json.loads(response.content) + + pendencias_cadastrais_esperado = { + 'conciliacao_bancaria': { + 'contas_pendentes': [f'{observacao_conciliacao_campos_nao_preenchidos_002.conta_associacao.uuid}',], + }, + 'dados_associacao': { + 'pendencia_cadastro': False, + 'pendencia_contas': False, + 'pendencia_membros': True + } + } + + assert response.status_code == status.HTTP_200_OK + assert result['pendencias_cadastrais'] == pendencias_cadastrais_esperado + @freeze_time('2020-07-10 10:20:00') def test_status_periodo_pendencias_cadastrais_sem_contas_pendentes( jwt_authenticated_client_a, From d25243ac7e62704d71a348ad1f189078aa08fd27 Mon Sep 17 00:00:00 2001 From: Matheus de Castro Diori <44413101+mdiori@users.noreply.github.com> Date: Wed, 14 Jun 2023 08:03:38 -0300 Subject: [PATCH 05/11] feat(95845): Adiciona membros ausentes pdf ata de pcs (#2104) Co-authored-by: Matheus --- sme_ptrf_apps/templates/pdf/ata/pdf.html | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sme_ptrf_apps/templates/pdf/ata/pdf.html b/sme_ptrf_apps/templates/pdf/ata/pdf.html index 9a98a1b3e..37725063a 100644 --- a/sme_ptrf_apps/templates/pdf/ata/pdf.html +++ b/sme_ptrf_apps/templates/pdf/ata/pdf.html @@ -384,7 +384,10 @@
Conta {{ conta.conta_associacao.nome }}
{{ dados.dados_texto_da_ata.comentarios }}

+ {% if dados.dados_texto_da_ata.comentarios %} +

Manifestações, comentários e justificativas

+

{{ dados.dados_texto_da_ata.comentarios }}

+ {% endif %} {% if not dados.dados_texto_da_ata.comentarios %}

Esgotados os assuntos o(a) senhor(a) presidente ofereceu a palavra a quem dela @@ -405,7 +408,7 @@

Conta {{ conta.conta_associacao.nome }}
{% endlanguage %} -

Presentes

+

Membros da Diretoria Executiva e do Conselho Fiscal

@@ -420,7 +423,11 @@
Conta {{ conta.conta_associacao.nome }}
{{ info.nome }}

{{ info.cargo }}

- + {% if info.presente %} + + {% else %} + + {% endif %} {% endfor %} From 2f29ad2998e2c86e7c9b0fe22df8b654046bb846 Mon Sep 17 00:00:00 2001 From: rayane maria dos santos Date: Wed, 14 Jun 2023 09:29:35 -0300 Subject: [PATCH 06/11] =?UTF-8?q?feat(95815):=20Adiciona=20valida=C3=A7?= =?UTF-8?q?=C3=A3o=20na=20carga=20de=20periodo=20inicial?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/services/periodo_inicial.py | 9 ++++++- .../tests/tests_carga_periodo/test_carga.py | 25 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/sme_ptrf_apps/core/services/periodo_inicial.py b/sme_ptrf_apps/core/services/periodo_inicial.py index 2f9e0f493..1e192f515 100644 --- a/sme_ptrf_apps/core/services/periodo_inicial.py +++ b/sme_ptrf_apps/core/services/periodo_inicial.py @@ -46,6 +46,13 @@ def processa_periodo_inicial(reader, arquivo): msg_erro = f'O período informado é anterior ao período inicial da associação. Linha ID:{index}' raise Exception(msg_erro) + if associacao.periodo_inicial: + response_pode_editar_periodo_inicial = associacao.pode_editar_periodo_inicial + if response_pode_editar_periodo_inicial['pode_editar_periodo_inicial'] == False: + msg_erro = ' '.join(response_pode_editar_periodo_inicial['mensagem_pode_editar_periodo_inicial']) + msg_erro = f"{msg_erro}. Linha ID:{index}" + raise Exception(msg_erro) + associacao.periodo_inicial = periodo associacao.save() logger.info("Periodo inicial da associação %s importado com sucesso.", associacao) @@ -67,7 +74,7 @@ def processa_periodo_inicial(reader, arquivo): logs = f"{logs}\nImportados {importados} períodos iniciais. Erro na importação de {erros} períodos iniciais." logger.info(f'Importados {importados} períodos iniciais. Erro na importação de {erros} períodos iniciais.') - + print(logs) arquivo.log = logs arquivo.save() diff --git a/sme_ptrf_apps/core/tests/tests_carga_periodo/test_carga.py b/sme_ptrf_apps/core/tests/tests_carga_periodo/test_carga.py index bbc1bb8d4..6aef3318b 100644 --- a/sme_ptrf_apps/core/tests/tests_carga_periodo/test_carga.py +++ b/sme_ptrf_apps/core/tests/tests_carga_periodo/test_carga.py @@ -77,8 +77,31 @@ def test_carga_com_erro(arquivo_carga_virgula): assert arquivo_carga_virgula.log == msg assert arquivo_carga_virgula.status == ERRO +def test_carga_com_erro_periodo_inicial_valores_reprogramados(arquivo_carga_virgula_processado, periodo, associacao): + carrega_periodo_inicial(arquivo_carga_virgula_processado) + msg = """Não é permitido alterar o período inicial da Associação. Há cadastros já realizados pela Associação no primeiro período de uso do sistema: - Valores Reprogramados.""" + assert msg in arquivo_carga_virgula_processado.log + assert arquivo_carga_virgula_processado.status == ERRO + +def test_carga_com_erro_periodo_inicial_despesas(arquivo_carga_virgula_processado, periodo, associacao, despesa_no_periodo): + carrega_periodo_inicial(arquivo_carga_virgula_processado) + msg = """Não é permitido alterar o período inicial da Associação. Há cadastros já realizados pela Associação no primeiro período de uso do sistema: - Valores Reprogramados - Despesa(s).""" + assert msg in arquivo_carga_virgula_processado.log + assert arquivo_carga_virgula_processado.status == ERRO + +def test_carga_com_erro_periodo_inicial_receitas(arquivo_carga_virgula_processado, periodo, associacao, despesa_no_periodo, receita_100_no_periodo_capital): + carrega_periodo_inicial(arquivo_carga_virgula_processado) + msg = """Não é permitido alterar o período inicial da Associação. Há cadastros já realizados pela Associação no primeiro período de uso do sistema: - Valores Reprogramados - Despesa(s) - Crédito(s).""" + assert msg in arquivo_carga_virgula_processado.log + assert arquivo_carga_virgula_processado.status == ERRO + +def test_carga_com_erro_periodo_inicial_prestacao_conta(arquivo_carga_virgula_processado, periodo, associacao, despesa_no_periodo, receita_100_no_periodo_capital, prestacao_conta): + carrega_periodo_inicial(arquivo_carga_virgula_processado) + msg = """Não é permitido alterar o período inicial da Associação. Há cadastros já realizados pela Associação no primeiro período de uso do sistema: - Valores Reprogramados - Despesa(s) - Crédito(s) - Prestação de Contas.""" + assert msg in arquivo_carga_virgula_processado.log + assert arquivo_carga_virgula_processado.status == ERRO -def test_carga_processado_com_erro(arquivo_carga_virgula_processado, periodo, associacao): +def test_carga_processado_com_erro(arquivo_carga_virgula_processado, periodo, associacao_status_nao_finalizado): carrega_periodo_inicial(arquivo_carga_virgula_processado) msg = """\nErro na linha 2: Associação (00094) não encontrado. Linha ID:2 Importados 1 períodos iniciais. Erro na importação de 1 períodos iniciais.""" From 6d0536c2627de20bd6cabbe25f9c3c12bdd3d393 Mon Sep 17 00:00:00 2001 From: Matheus de Castro Diori <44413101+mdiori@users.noreply.github.com> Date: Wed, 14 Jun 2023 13:45:26 -0300 Subject: [PATCH 07/11] feat(93657): Atualiza django para versao 3.1.14 (#2103) Co-authored-by: Matheus --- requirements/base.txt | 6 +++--- .../migrations/0004_auto_20230612_1636.py | 17 +++++++++++++++++ .../migrations/0023_auto_20230612_1636.py | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 sme_ptrf_apps/contrib/sites/migrations/0004_auto_20230612_1636.py create mode 100644 sme_ptrf_apps/users/migrations/0023_auto_20230612_1636.py diff --git a/requirements/base.txt b/requirements/base.txt index c32728efa..1868842b9 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -2,8 +2,8 @@ # Django # ------------------------------------------------------------------------------ -django==3.0.14 -django-auditlog==1.0.0 +django==3.1.14 +django-auditlog==2.0.0 # Dependências do Django Rest Framework # ------------------------------------------------------------------------------ @@ -44,7 +44,7 @@ djangorestframework==3.11.0 # https://github.com/encode/django-rest-framework # Para filtros no DRF # https://django-filter.readthedocs.io/en/master/# -django-filter==2.2.0 +django-filter==2.4.0 djangorestframework-jwt==1.11.0 # https://getblimp.github.io/django-rest-framework-jwt/ diff --git a/sme_ptrf_apps/contrib/sites/migrations/0004_auto_20230612_1636.py b/sme_ptrf_apps/contrib/sites/migrations/0004_auto_20230612_1636.py new file mode 100644 index 000000000..d34c4582e --- /dev/null +++ b/sme_ptrf_apps/contrib/sites/migrations/0004_auto_20230612_1636.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.14 on 2023-06-12 16:36 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('sites', '0003_set_site_domain_and_name'), + ] + + operations = [ + migrations.AlterModelOptions( + name='site', + options={'ordering': ['domain'], 'verbose_name': 'site', 'verbose_name_plural': 'sites'}, + ), + ] diff --git a/sme_ptrf_apps/users/migrations/0023_auto_20230612_1636.py b/sme_ptrf_apps/users/migrations/0023_auto_20230612_1636.py new file mode 100644 index 000000000..eab13d5f4 --- /dev/null +++ b/sme_ptrf_apps/users/migrations/0023_auto_20230612_1636.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.14 on 2023-06-12 16:36 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0022_unidadeemsuporte'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='first_name', + field=models.CharField(blank=True, max_length=150, verbose_name='first name'), + ), + ] From 7bd46b1b0a361be70cb9e5aacea8e860e05dfe77 Mon Sep 17 00:00:00 2001 From: Matheus de Castro Diori <44413101+mdiori@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:44:00 -0300 Subject: [PATCH 08/11] feat(95653): Adiciona indicativo de membros conselho fiscal ausentes na ata (#2108) Co-authored-by: Matheus --- .../core/api/views/presentes_ata_viewset.py | 24 +++++++++++++++++-- sme_ptrf_apps/templates/pdf/ata/pdf.html | 22 ++++++++++------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py b/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py index 06392eb11..9acf35e29 100644 --- a/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py +++ b/sme_ptrf_apps/core/api/views/presentes_ata_viewset.py @@ -56,8 +56,28 @@ def membros_e_nao_membros(self, request): presentes_ata_nao_membros = Participante.objects.filter(ata=ata).filter(membro=False).order_by('nome').values() associacao = ata.associacao - # presentes_ata_conselho_fiscal = Participante.objects.filter(ata=ata).filter(membro=True).filter(conselho_fiscal=True).values() - presentes_ata_conselho_fiscal = retorna_membros_do_conselho_fiscal_por_associacao(associacao) + + if not presentes_ata_membros: + membros_associacao = ata.associacao.membros_por_cargo() + presentes_ata_membros = [] + for membro in membros_associacao: + + dado = { + "ata": ata_uuid, + "cargo": remove_digitos(MembroEnum[membro.cargo_associacao].value), + "identificacao": membro.codigo_identificacao if membro.codigo_identificacao != "" else membro.cpf, + "nome": membro.nome, + "editavel": False, + "membro": True, + "presente": True + } + + presentes_ata_membros.append(dado) + + presentes_ata_conselho_fiscal = retorna_membros_do_conselho_fiscal_por_associacao(associacao) + else: + presentes_ata_conselho_fiscal = Participante.objects.filter(ata=ata).filter(membro=True, conselho_fiscal=True).values() + result = { 'presentes_membros': presentes_ata_membros, diff --git a/sme_ptrf_apps/templates/pdf/ata/pdf.html b/sme_ptrf_apps/templates/pdf/ata/pdf.html index 37725063a..97904a11a 100644 --- a/sme_ptrf_apps/templates/pdf/ata/pdf.html +++ b/sme_ptrf_apps/templates/pdf/ata/pdf.html @@ -475,16 +475,22 @@
Conta {{ conta.conta_associacao.nome }}
Assinatura
- {% for info in dados.presentes_na_ata.presentes_ata_conselho_fiscal %} + {% for info in dados.presentes_na_ata.presentes_ata_membros %} + {% if info.conselho_fiscal %} - - - - + + + {% if info.presente %} + + {% else %} + + {% endif %} + + {% endif %} {% endfor %}
Ausente
-

{{ info.nome }}

-

{{ info.cargo }}

-
+

{{ info.nome }}

+

{{ info.cargo }}

+
Ausente
From 630e088751a026c3205f58c41099558dc95d1e20 Mon Sep 17 00:00:00 2001 From: ollyvergithub Date: Thu, 15 Jun 2023 14:17:22 -0300 Subject: [PATCH 09/11] =?UTF-8?q?fix(91168):=20Resolve=20notifica=C3=A7?= =?UTF-8?q?=C3=A3o=20enviada=20apenas=20para=20um=20t=C3=A9cnico=20em=20Re?= =?UTF-8?q?lat=C3=B3rio=20Consolidado=20das=20DREs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...class_notificacao_comentario_de_analise_consolidado_dre.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sme_ptrf_apps/dre/services/notificacao_service/class_notificacao_comentario_de_analise_consolidado_dre.py b/sme_ptrf_apps/dre/services/notificacao_service/class_notificacao_comentario_de_analise_consolidado_dre.py index 69120dc2e..012f64b83 100644 --- a/sme_ptrf_apps/dre/services/notificacao_service/class_notificacao_comentario_de_analise_consolidado_dre.py +++ b/sme_ptrf_apps/dre/services/notificacao_service/class_notificacao_comentario_de_analise_consolidado_dre.py @@ -49,10 +49,10 @@ def notificar(self): comentario.set_comentario_notificado() logger.info("Notificações criadas com sucesso.") - return True + return True else: logger.info("Não existem usuários a serem notificados.") return False else: logger.info("Não existe comissão de exame de contas criada.") - return False \ No newline at end of file + return False From 39a1e6dcbaab5cf6337571f1f49a5ae39f0f3538 Mon Sep 17 00:00:00 2001 From: Matheus de Castro Diori <44413101+mdiori@users.noreply.github.com> Date: Mon, 19 Jun 2023 14:52:18 -0300 Subject: [PATCH 10/11] fix(96956): Corrige layout tag e adiciona info de tag conciliada backend (#2112) Co-authored-by: Matheus --- sme_ptrf_apps/core/models/associacao.py | 2 +- .../test_lancamentos_tags_informacoes.py | 5 +++-- sme_ptrf_apps/despesas/models/despesa.py | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/sme_ptrf_apps/core/models/associacao.py b/sme_ptrf_apps/core/models/associacao.py index 08e8353af..7a0164f7e 100644 --- a/sme_ptrf_apps/core/models/associacao.py +++ b/sme_ptrf_apps/core/models/associacao.py @@ -24,7 +24,7 @@ class Associacao(ModeloIdNome): history = AuditlogHistoryField() # Tags de informações - TAG_ENCERRADA = {"id": "7", "nome": "Associação encerrada", "descricao": "A associação foi encerrada."} + TAG_ENCERRADA = {"id": "1", "nome": "Associação encerrada", "descricao": "A associação foi encerrada."} # Status do Presidente STATUS_PRESIDENTE_PRESENTE = 'PRESENTE' diff --git a/sme_ptrf_apps/core/tests/tests_services/tests_prestacao_de_contas_services/tests_lancamento_da_prestacao_service/test_lancamentos_tags_informacoes.py b/sme_ptrf_apps/core/tests/tests_services/tests_prestacao_de_contas_services/tests_lancamento_da_prestacao_service/test_lancamentos_tags_informacoes.py index 8f14531f1..3ebf4fc8b 100644 --- a/sme_ptrf_apps/core/tests/tests_services/tests_prestacao_de_contas_services/tests_lancamento_da_prestacao_service/test_lancamentos_tags_informacoes.py +++ b/sme_ptrf_apps/core/tests/tests_services/tests_prestacao_de_contas_services/tests_lancamento_da_prestacao_service/test_lancamentos_tags_informacoes.py @@ -111,10 +111,11 @@ def test_get_lancamentos_da_analise_da_prestacao_com_tag_de_informacao_imposto_a 'tag_nome': 'Imposto', 'tag_hint': ['Essa despesa teve retenção de imposto:', 'R$ 10,00, pago em 10/03/2020.'] }, - {'tag_hint': 'Essa despesa não possui conciliação bancária.', + {'tag_hint': ['Essa despesa não possui conciliação bancária.', 'Não demonstrado por 39 meses.'], 'tag_id': '10', 'tag_nome': 'Não conciliada'} ] + def test_get_lancamentos_da_analise_da_prestacao_com_tag_de_informacao_imposto_apenas_dois_impostos_retidos( @@ -184,7 +185,7 @@ def test_get_lancamentos_da_analise_da_prestacao_com_tag_de_informacao_imposto_p 'tag_nome': 'Imposto Pago', 'tag_hint': 'Esse imposto está relacionado à despesa 123315 / Antônio José SA.', }, - {'tag_hint': 'Essa despesa não possui conciliação bancária.', + {'tag_hint': ['Essa despesa não possui conciliação bancária.', 'Não demonstrado por 39 meses.'], 'tag_id': '10', 'tag_nome': 'Não conciliada'} ] diff --git a/sme_ptrf_apps/despesas/models/despesa.py b/sme_ptrf_apps/despesas/models/despesa.py index abd323240..3a6897b9e 100644 --- a/sme_ptrf_apps/despesas/models/despesa.py +++ b/sme_ptrf_apps/despesas/models/despesa.py @@ -166,7 +166,7 @@ def tags_de_informacao(self): if not self.conferido: tags.append(tag_informacao( self.TAG_NAO_CONCILIADA, - f"Essa despesa não possui conciliação bancária." + self.__hint_nao_conciliada() )) return tags @@ -194,7 +194,18 @@ def mensagem_inativacao(self): def __str__(self): return f"{self.numero_documento} - {self.data_documento} - {self.valor_total:.2f}" - + + def __hint_nao_conciliada(self): + max_notificar_dias_nao_conferido = 0 + for rateio in self.rateios.filter(status=STATUS_COMPLETO): + if rateio.notificar_dias_nao_conferido > max_notificar_dias_nao_conferido: + max_notificar_dias_nao_conferido = rateio.notificar_dias_nao_conferido + + meses = max_notificar_dias_nao_conferido // 30 + msg = '1 mês.' if max_notificar_dias_nao_conferido <= 59 else f'{meses} meses.' + + return [f'Essa despesa não possui conciliação bancária.', f'Não demonstrado por {msg}'] + def __hint_impostos(self): if not self.despesas_impostos.exists(): return [] From f686b9aa7e1b65c508d24bd63c97497dc9f628fa Mon Sep 17 00:00:00 2001 From: Alessandro Fernandes Date: Mon, 19 Jun 2023 16:09:10 -0300 Subject: [PATCH 11/11] =?UTF-8?q?docs(8.3.0):=20Atualiza=20vers=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Entregas sprint 67 --- sme_ptrf_apps/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sme_ptrf_apps/__init__.py b/sme_ptrf_apps/__init__.py index 05e28415a..a0b65df29 100644 --- a/sme_ptrf_apps/__init__.py +++ b/sme_ptrf_apps/__init__.py @@ -1,4 +1,4 @@ -__version__ = "8.2.1" +__version__ = "8.3.0" __version_info__ = tuple( [