libretificacaotjcore 0.1.33__py3-none-any.whl → 0.1.49__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of libretificacaotjcore might be problematic. Click here for more details.

@@ -1,3 +1,4 @@
1
+
1
2
  from pymongo.errors import BulkWriteError
2
3
 
3
4
  class ArquivoRepository:
@@ -35,6 +35,21 @@ class ConfigDb:
35
35
  await self.__db.protocolos.create_index([("id", 1)], unique=True)
36
36
  await self.__db.protocolos.create_index([("solicitacaoId", 1), ("evento", 1)], unique=True)
37
37
  self.db_initialized = True
38
+
39
+ if "rubricas" not in (await self.__db.list_collection_names()):
40
+ await self.__db.create_collection("rubricas")
41
+
42
+ await self.__db.rubricas.create_index([("cnpj", 1)])
43
+ await self.__db.rubricas.create_index([("solicitacaoId", 1)], unique=True)
44
+ await self.__db.rubricas.create_index([("id", 1)], unique=True)
45
+ self.db_initialized = True
46
+
47
+ if "tempo_processos" not in (await self.__db.list_collection_names()):
48
+ await self.__db.create_collection("tempo_processos")
49
+
50
+ await self.__db.rubricas.create_index([("SolicitacaoId", 1)])
51
+ await self.__db.rubricas.create_index([("id", 1)], unique=True)
52
+ self.db_initialized = True
38
53
 
39
54
  async def get_db(self):
40
55
  await self.criar_schema()
@@ -0,0 +1,32 @@
1
+ from pymongo.errors import BulkWriteError
2
+
3
+ class RubricaRepository:
4
+ def __init__(self, db):
5
+ self.__db = db
6
+
7
+ async def inserir_rubrica(self, rubrica: dict) -> bool:
8
+
9
+ try:
10
+ rubricas_no_db = await self.__db.rubricas.find_one(
11
+ {"solicitacaoId": rubrica["solicitacaoId"]}
12
+ )
13
+
14
+ if rubricas_no_db is None:
15
+ await self.__db.rubricas.insert_one(rubrica)
16
+ return True
17
+
18
+ await self.__db.rubricas.delete_one(
19
+ {"solicitacaoId": rubrica["solicitacaoId"]}
20
+ )
21
+ await self.__db.rubricas.insert_one(rubrica)
22
+ return True
23
+ except Exception as e:
24
+ print(f"❌ Erro ao inserir o rubrica: {e}")
25
+ return False
26
+
27
+ async def buscar_por_solicitacao_id(self, solicitacaoId: int) -> dict:
28
+ try:
29
+ return await self.__db.rubricas.find_one({"solicitacaoId": solicitacaoId})
30
+ except Exception as e:
31
+ print(f"❌ Erro ao buscar rubricas por solicitacaoId: {e}")
32
+ return {}
@@ -0,0 +1,99 @@
1
+ from datetime import datetime
2
+ from pymongo.errors import BulkWriteError
3
+
4
+ from libretificacaotjcore.dtos.processo_dto import ProcessoDto
5
+ from libretificacaotjcore.enums.e_fase_retificacao import EFaseRetificacao
6
+
7
+ class TempoProcessoRepository:
8
+ def __init__(self, db):
9
+ self.__db = db
10
+
11
+ async def inserir_processo(self, *, processo: ProcessoDto) -> bool:
12
+ try:
13
+ processo_dict = processo.model_dump()
14
+ processo_dict["DataInicio"] = processo.DataInicio.strftime("%Y-%m-%d")
15
+ processo_dict["DataFim"] = processo.DataFim.strftime("%Y-%m-%d")
16
+ processo_dict["FaseDescricao"] = EFaseRetificacao(processo.Fase).name
17
+
18
+ processo_no_db = await self.__db.tempo_processos.find_one(
19
+ {
20
+ "SolicitacaoId": processo.SolicitacaoId,
21
+ "Fase": processo.Fase,
22
+ "DataInicio": processo_dict["DataInicio"],
23
+ "DataFim": processo_dict["DataFim"],
24
+ }
25
+ )
26
+
27
+
28
+
29
+ if processo_no_db is None:
30
+ processo_dict["InicioProcesso"] = datetime.now()
31
+ await self.__db.tempo_processos.insert_one(processo_dict)
32
+ return True
33
+
34
+ await self.__db.tempo_processos.delete_one(
35
+ {
36
+ "SolicitacaoId": processo.SolicitacaoId,
37
+ "Fase": processo.Fase,
38
+ "DataInicio": processo_dict["DataInicio"],
39
+ "DataFim": processo_dict["DataFim"],
40
+ }
41
+ )
42
+
43
+ processo_dict["InicioProcesso"] = datetime.now()
44
+ await self.__db.tempo_processos.insert_one(processo_dict)
45
+ return True
46
+
47
+ except Exception as e:
48
+ print(f"❌ Erro ao inserir o processo: {e}")
49
+ return False
50
+
51
+ async def atualizar_processo(self, *, processo: ProcessoDto) -> bool:
52
+ try:
53
+ processo_dict = processo.model_dump()
54
+ processo_dict["DataInicio"] = processo.DataInicio.strftime("%Y-%m-%d")
55
+ processo_dict["DataFim"] = processo.DataFim.strftime("%Y-%m-%d")
56
+
57
+ processo_no_db = await self.__db.tempo_processos.find_one(
58
+ {
59
+ "SolicitacaoId": processo.SolicitacaoId,
60
+ "Fase": processo.Fase,
61
+ "DataInicio": processo_dict["DataInicio"],
62
+ "DataFim": processo_dict["DataFim"],
63
+ }
64
+ )
65
+
66
+ if processo_no_db is None:
67
+ return False
68
+
69
+ processo_no_db['FimProcesso'] = datetime.now()
70
+ tempo_de_processo = self._tempo_de_processo(processo_no_db['InicioProcesso'], processo_no_db['FimProcesso'])
71
+ processo_no_db['TempoDeProcesso'] = tempo_de_processo
72
+
73
+ await self.__db.tempo_processos.replace_one(
74
+ {
75
+ "SolicitacaoId": processo.SolicitacaoId,
76
+ "Fase": processo.Fase,
77
+ "DataInicio": processo_dict["DataInicio"],
78
+ "DataFim": processo_dict["DataFim"],
79
+ },
80
+ processo_no_db
81
+ )
82
+ return True
83
+ except Exception as e:
84
+ print(f"❌ Erro ao atualizar o processo: {e}")
85
+ return False
86
+
87
+ def _tempo_de_processo(self, tempo_inicio: datetime, tempo_fim: datetime) -> str | None:
88
+ if tempo_inicio and tempo_fim:
89
+ delta = tempo_fim - tempo_inicio # <-- inverter a ordem
90
+ total_segundos = int(delta.total_seconds())
91
+
92
+ horas = total_segundos // 3600
93
+ minutos = (total_segundos % 3600) // 60
94
+ segundos = total_segundos % 60
95
+
96
+ tempo_formatado = f"{horas:02d}:{minutos:02d}:{segundos:02d}"
97
+ return tempo_formatado
98
+
99
+ return None
@@ -0,0 +1,78 @@
1
+ from datetime import date, datetime, timedelta
2
+ from pydantic import BaseModel, Field, field_validator
3
+ from libretificacaotjcore.enums.e_fase_retificacao import EFaseRetificacao
4
+
5
+
6
+ class ProcessoDto(BaseModel):
7
+ SolicitacaoId: int = Field(..., description="ID da solicitação")
8
+ DataInicio: date = Field(..., description="Data de início no formato YYYY-MM-DD")
9
+ DataFim: date = Field(..., description="Data de fim no formato YYYY-MM-DD")
10
+ Fase: int | None = Field(None, description="Fase de retificação")
11
+ InicioProcesso: datetime | None = Field(None, description="Data e hora de início do processo")
12
+ FimProcesso: datetime | None = Field(None, description="Data e hora de fim do processo")
13
+ TempoDeProcesso: str | None = Field(None, description="Tempo de processamento")
14
+ Observacoes: str | None = Field(None, description="Observações adicionais")
15
+
16
+ # --- Validadores ---
17
+
18
+ @field_validator("SolicitacaoId")
19
+ @classmethod
20
+ def validar_solicitacao_id(cls, v: int) -> int:
21
+ if v <= 0:
22
+ raise ValueError("O solicitacaoId deve ser um inteiro positivo.")
23
+ return v
24
+
25
+ @field_validator("DataInicio", mode="before")
26
+ @classmethod
27
+ def formatar_data_inicio(cls, value) -> date:
28
+ """
29
+ Aceita date, datetime ou string.
30
+ """
31
+ if isinstance(value, date):
32
+ return value
33
+ if isinstance(value, datetime):
34
+ return value.date()
35
+ if isinstance(value, str):
36
+ try:
37
+ return datetime.strptime(value, "%Y-%m-%d").date()
38
+ except ValueError as ve:
39
+ raise ValueError("A DataInicio deve estar no formato YYYY-MM-DD.") from ve
40
+ raise TypeError("Tipo inválido para DataInicio.")
41
+
42
+ @field_validator("DataFim", mode="before")
43
+ @classmethod
44
+ def ajustar_data_fim(cls, value) -> date:
45
+ """
46
+ Aceita date, datetime ou string.
47
+ Retorna o último dia do mês da data fornecida.
48
+ """
49
+ if isinstance(value, datetime):
50
+ value = value.date()
51
+ if isinstance(value, date):
52
+ ano, mes = value.year, value.month
53
+ elif isinstance(value, str):
54
+ try:
55
+ ano, mes = map(int, value.split("-")[:2])
56
+ except Exception:
57
+ raise ValueError("A DataFim deve estar no formato YYYY-MM-DD.")
58
+ else:
59
+ raise TypeError("Tipo inválido para DataFim.")
60
+
61
+ if mes < 1 or mes > 12:
62
+ raise ValueError("A DataFim deve conter um mês válido (1–12).")
63
+
64
+ # calcula o último dia do mês
65
+ if mes == 12:
66
+ proximo_mes = datetime(ano + 1, 1, 1)
67
+ else:
68
+ proximo_mes = datetime(ano, mes + 1, 1)
69
+ return (proximo_mes - timedelta(days=1)).date()
70
+
71
+ @field_validator("Fase")
72
+ @classmethod
73
+ def validar_fase(cls, v):
74
+ if v is None:
75
+ return v
76
+ if v not in EFaseRetificacao:
77
+ raise ValueError(f"Fase '{v}' não é válida.")
78
+ return v
@@ -2,6 +2,7 @@ from enum import Enum
2
2
 
3
3
 
4
4
  class EEventos(str, Enum):
5
+ S1010 = "S-1010"
5
6
  S1200 = "S-1200"
6
7
  S1210 = "S-1210"
7
8
  S1298 = "S-1298"
@@ -8,18 +8,25 @@ class EFaseRetificacao(Enum):
8
8
  DownloadXml = 3
9
9
  ExtraindoDadosDoXml = 4
10
10
  AguardandoRubrica = 5
11
- AberturaDeCompetencia = 6
12
- ConsultandoESocialAberturaCompetencia = 7
13
- InclusaoDasRubricas = 8
14
- ConsultandoESocialInclusaoRubricas = 9
15
- ExclusaoDePagamentos = 10
16
- ConsultandoESocialExclusaoPagamentos = 11
17
- RetificacaoDaRemuneracao = 12
18
- ConsultandoESocialRetificacaoRemuneracao = 13
19
- InclusaoDosPagamentos = 14
20
- ConsultandoESocialInclusaoPagamentos = 15
21
- Desligamento = 16
22
- ConsultandoESocialDesligamento = 17
23
- FechamentoDeCompetencia = 18
24
- ConsultandoESocialFechamentoCompetencia = 19
25
- Finalizado = 20
11
+ EstruturandoXmlAberturaCompetencia = 6
12
+ EstruturandoXmlInclusaoRubricas = 7
13
+ EstruturandoXmlExclusaoPagamentos = 8
14
+ EstruturandoXmlRetificacaoRemuneracao = 9
15
+ EstruturandoXmlInclusaoPagamentos = 10
16
+ EstruturandoXmlDesligamento = 11
17
+ EstruturandoXmlFechamentoCompetencia = 12
18
+ AberturaDeCompetencia = 13
19
+ ConsultandoESocialAberturaCompetencia = 14
20
+ InclusaoDasRubricas = 15
21
+ ConsultandoESocialInclusaoRubricas = 16
22
+ ExclusaoDePagamentos = 17
23
+ ConsultandoESocialExclusaoPagamentos = 18
24
+ RetificacaoDaRemuneracao = 19
25
+ ConsultandoESocialRetificacaoRemuneracao = 20
26
+ InclusaoDosPagamentos = 21
27
+ ConsultandoESocialInclusaoPagamentos = 22
28
+ Desligamento = 23
29
+ ConsultandoESocialDesligamento = 24
30
+ FechamentoDeCompetencia = 25
31
+ ConsultandoESocialFechamentoCompetencia = 26
32
+ Finalizado = 27
@@ -1,15 +1,16 @@
1
- import pika
1
+ import asyncio
2
+ import aio_pika
2
3
  import json
3
4
 
4
-
5
5
  class RabbitMQConsumer:
6
6
  def __init__(
7
7
  self,
8
+ *,
8
9
  host: str,
9
10
  queue: str,
10
11
  username: str,
11
12
  password: str,
12
- vhost: str ="/",
13
+ vhost: str = "/",
13
14
  ):
14
15
  self.host = host
15
16
  self.queue = queue
@@ -18,39 +19,41 @@ class RabbitMQConsumer:
18
19
  self.vhost = vhost
19
20
  self.connection = None
20
21
  self.channel = None
21
- self.connect()
22
-
23
- def connect(self):
24
- credentials = pika.PlainCredentials(self.username, self.password)
25
- parameters = pika.ConnectionParameters(
26
- host=self.host,
27
- credentials=credentials,
28
- virtual_host=self.vhost,
29
- heartbeat=60,
30
- blocked_connection_timeout=300,
22
+
23
+ async def connect(self):
24
+ self.connection = await aio_pika.connect_robust(
25
+ host=self.host,
26
+ login=self.username,
27
+ password=self.password,
28
+ virtualhost=self.vhost,
29
+ heartbeat=600,
31
30
  )
32
-
33
- self.connection = pika.BlockingConnection(parameters)
34
- self.channel = self.connection.channel()
35
- self.channel.queue_declare(queue=self.queue, durable=True)
36
-
37
- def start_consuming(self, callback):
38
- def on_message(ch, method, properties, body):
39
- mensagem = json.loads(body)
40
- callback(mensagem)
41
- ch.basic_ack(delivery_tag=method.delivery_tag)
42
- self.close()
43
-
31
+ self.channel = await self.connection.channel()
32
+ await self.channel.set_qos(prefetch_count=1)
33
+ await self.channel.declare_queue(self.queue, durable=True)
34
+
35
+ async def start_consuming(self, callback):
44
36
  if not self.channel:
45
37
  raise RuntimeError("❌ Canal RabbitMQ não conectado. Chame connect() antes.")
46
38
 
47
- self.channel.basic_qos(prefetch_count=1)
48
- self.channel.basic_consume(queue=self.queue, on_message_callback=on_message)
49
- print(
50
- f'[*] Aguardando mensagens na fila "{self.queue}". Para sair pressione CTRL+C'
51
- )
52
- self.channel.start_consuming()
39
+ queue = await self.channel.get_queue(self.queue)
40
+
41
+ async def on_message(message):
42
+ async with message.process():
43
+ try:
44
+ mensagem = json.loads(message.body.decode())
45
+ await callback(mensagem) # aqui sim passa o DTO
46
+ except Exception as e:
47
+ print(f"❌ Erro ao processar mensagem: {e}")
48
+
49
+ await queue.consume(on_message) # registra callback
50
+
51
+ print(f'[*] Aguardando mensagens na fila "{self.queue}". Para sair pressione CTRL+C')
52
+
53
+ # Mantém o consumer rodando
54
+ await asyncio.Future()
55
+
53
56
 
54
- def close(self):
57
+ async def close(self):
55
58
  if self.connection:
56
- self.connection.close()
59
+ await self.connection.close()
@@ -1,16 +1,20 @@
1
1
  import httpx
2
2
 
3
+
3
4
  class RequestServicoApi:
4
5
  def __init__(self, url, token):
5
6
  self.url = url
6
7
  self.token = token
8
+ self.client = httpx.AsyncClient(timeout=120, verify=False)
7
9
 
8
10
  async def handler(self, *, mensagem_atualizacao: dict):
9
- async with httpx.AsyncClient(timeout=120, verify=False) as client:
10
- print(self.token)
11
- response = await client.post(self.url, json=mensagem_atualizacao)
11
+ print(self.token)
12
+ response = await self.client.post(self.url, json=mensagem_atualizacao)
13
+
14
+ if response.status_code != 200:
15
+ raise Exception(f"Erro ao fazer request ao servico de API: {response.status_code}")
16
+
17
+ await self.close()
12
18
 
13
- if response.status_code != 200:
14
- raise Exception(f"Erro ao fazer request ao servico de API: {response.status_code}")
15
-
16
- return response.json()
19
+ async def close(self):
20
+ await self.client.aclose()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libretificacaotjcore
3
- Version: 0.1.33
3
+ Version: 0.1.49
4
4
  Summary: Biblioteca para centralizar conexao com filas no rabbit e banco de dados no mongodb para os servicos de retificacao da TJ
5
5
  Author-email: Jhonatan Azevedo <dev.azevedo@outlook.com>
6
6
  Project-URL: Homepage, https://github.com/seu-usuario/libretificacaotjcore
@@ -1,23 +1,26 @@
1
1
  libretificacaotjcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  libretificacaotjcore/database/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
3
- libretificacaotjcore/database/arquivo_repository.py,sha256=Wv42CWjddS8RPVR3aAOGwuFuLyGqmgq-TXOc-V0BTvE,2154
3
+ libretificacaotjcore/database/arquivo_repository.py,sha256=sWXdaHzS0xogZfa4VtdMcd7P7QOmStn12GrNVcGAuYo,2156
4
4
  libretificacaotjcore/database/certificado_repository.py,sha256=LF3rV1rQmRGZVB4wPh_vmDj81Gf_env_5hqtTbxXNFM,1396
5
- libretificacaotjcore/database/config_db.py,sha256=1SNpQV6GcrS0aZGX12wXmxhmLb8oc3uV4_H6HQ1z74w,1775
5
+ libretificacaotjcore/database/config_db.py,sha256=ZrOynusf7YIrkITEZQ-8KLMPJLBiHWIAg1EyFvHjVSE,2572
6
6
  libretificacaotjcore/database/protocolo_repository.py,sha256=kb-mXxiOYDPbrPbYMhOb9xDZHknUdVSfVlmQ_Cn0l1s,3788
7
+ libretificacaotjcore/database/rubrica_repository.py,sha256=BVZLukKVH1YKRgPkk18aqck90DdNGrqv4cYr1IRSbL4,1130
8
+ libretificacaotjcore/database/tempo_processo_repository.py,sha256=3pbeh69qI3I-Ucw-mGYrVLkyeh_wKTKAorq71ZHuc_k,3981
7
9
  libretificacaotjcore/dtos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
10
  libretificacaotjcore/dtos/arquivo_dto.py,sha256=D4LLJZf-Z0XhJmOvu7nAcBq0j70m9TFtbgxI9ikHXQ0,1045
11
+ libretificacaotjcore/dtos/processo_dto.py,sha256=KbG3TjcxHS4UTdflApChBrq6BpM8xS1Cd6PNba--hA0,3096
9
12
  libretificacaotjcore/dtos/solicitacao_dto.py,sha256=dmI-JGgE0wZ9zXqej6pqSIIaopkROnBQo2Hj3pEXcZ8,2576
10
13
  libretificacaotjcore/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- libretificacaotjcore/enums/e_eventos.py,sha256=EClyRpHtL21t_s1b_26bbBKpvd6QgOtIe87FmSzh34E,185
12
- libretificacaotjcore/enums/e_fase_retificacao.py,sha256=-MCqN3s3MHu2W-MlfLugGsI91CwoBUObqxJJGW9wGL8,766
14
+ libretificacaotjcore/enums/e_eventos.py,sha256=4NICIKFpxEvxMbHu_kcKqNXqylDETcr6qY1tK2bKmi4,207
15
+ libretificacaotjcore/enums/e_fase_retificacao.py,sha256=v7ERN6MuhdiuT2Yhzu5yzvR6rpKaxqoNMKrBlk4zhkY,1074
13
16
  libretificacaotjcore/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
17
  libretificacaotjcore/services/crypto_pass_service.py,sha256=9D0vyjan6f_8AfNxGkLpGdvyMpojsJq_AAySpv_zKMc,740
15
18
  libretificacaotjcore/services/file_service.py,sha256=14CJokBbrsryQGmL0_unH2QKZpnteEAfxf5CPFdv6cE,2075
16
- libretificacaotjcore/services/rabbitmq_consumer.py,sha256=XPbOvFR3HySfA1IROLPrsb4AmeHeq1Unthxt44vaqik,1760
19
+ libretificacaotjcore/services/rabbitmq_consumer.py,sha256=yRS3sAkaMIIn8Y06icwkO1bpddlLC7BmNSHJVhUalzY,1818
17
20
  libretificacaotjcore/services/rabbitmq_publisher.py,sha256=xsb9LmIuZizzq5lxnEEZKMK3U952KSQ2oqlTBZi2Lt8,1787
18
- libretificacaotjcore/services/request_servico_api.py,sha256=nv5DdFh12fLDUkQQSW4Q_tezASYFVAqMvrm7ZUaAZXw,576
21
+ libretificacaotjcore/services/request_servico_api.py,sha256=G7vnmvOfwrCGL-Jy_5tCKG-l5E00OCkJfkuoa5Y6sHo,613
19
22
  libretificacaotjcore/services/s3_service.py,sha256=HKR_jt2H3XdV1PCzo5R5bnhmoQ3I46Yn5IqAvVPhsjs,2946
20
- libretificacaotjcore-0.1.33.dist-info/METADATA,sha256=9kzSaYE2C99t-ap0SG7l3sc0hEd4PtqYbwV_qXR0xDU,2564
21
- libretificacaotjcore-0.1.33.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
22
- libretificacaotjcore-0.1.33.dist-info/top_level.txt,sha256=J9vnz_X9OUnxC-eXHiAzlc9xIrWBwZ5bgnIDQIIFY4c,21
23
- libretificacaotjcore-0.1.33.dist-info/RECORD,,
23
+ libretificacaotjcore-0.1.49.dist-info/METADATA,sha256=1x9RtwNRlGp8NrJLfPW8HE4s_16vE-th92cweckLYek,2564
24
+ libretificacaotjcore-0.1.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ libretificacaotjcore-0.1.49.dist-info/top_level.txt,sha256=J9vnz_X9OUnxC-eXHiAzlc9xIrWBwZ5bgnIDQIIFY4c,21
26
+ libretificacaotjcore-0.1.49.dist-info/RECORD,,