From 1e81082105dcc7ca514aa4822b0fc1e5819cb8ca Mon Sep 17 00:00:00 2001 From: Kenio de Souza Date: Fri, 19 Sep 2025 19:30:43 -0300 Subject: [PATCH] =?UTF-8?q?[DSAAS-6]=20fix(g=5Fsequencia):=20Feita=20a=20v?= =?UTF-8?q?alida=C3=A7=C3=A3o=20e=20cria=C3=A7=C3=A3o=20autom=C3=A1tica=20?= =?UTF-8?q?de=20sequ=C3=AAncia=20na=20tabela=20g=5Fsequencia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/g_sequencia/checkout_action.py | 14 ++++ .../repositories/g_sequencia/checkout.py | 67 +++++++++++++++++++ .../services/g_sequencia/checkout_service.py | 25 +++++++ .../services/g_sequencia/generate_service.py | 8 ++- 4 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 packages/v1/sequencia/actions/g_sequencia/checkout_action.py create mode 100644 packages/v1/sequencia/repositories/g_sequencia/checkout.py create mode 100644 packages/v1/sequencia/services/g_sequencia/checkout_service.py diff --git a/packages/v1/sequencia/actions/g_sequencia/checkout_action.py b/packages/v1/sequencia/actions/g_sequencia/checkout_action.py new file mode 100644 index 0000000..03e849b --- /dev/null +++ b/packages/v1/sequencia/actions/g_sequencia/checkout_action.py @@ -0,0 +1,14 @@ +from packages.v1.sequencia.repositories.g_sequencia.checkout import Checkout +from packages.v1.sequencia.schemas.g_sequencia import GSequenciaSchema +from abstracts.action import BaseAction + + +class CheckoutAction(BaseAction): + + def execute(self, sequencia_schema : GSequenciaSchema): + + # Instânciamento de repositório + checkout = Checkout() + + # Execução do repositório + return checkout.execute(sequencia_schema) \ No newline at end of file diff --git a/packages/v1/sequencia/repositories/g_sequencia/checkout.py b/packages/v1/sequencia/repositories/g_sequencia/checkout.py new file mode 100644 index 0000000..b288d8e --- /dev/null +++ b/packages/v1/sequencia/repositories/g_sequencia/checkout.py @@ -0,0 +1,67 @@ +from packages.v1.sequencia.schemas.g_sequencia import GSequenciaSchema +from abstracts.repository import BaseRepository +from fastapi import HTTPException, status + + +class Checkout(BaseRepository): + + def execute(self, sequencia_schema: GSequenciaSchema): + + # 1) Descobre o nome da PK a partir dos metadados + sql = """ + SELECT + sg.RDB$FIELD_NAME AS primary_key + FROM RDB$RELATION_CONSTRAINTS rc + JOIN RDB$INDEX_SEGMENTS sg + ON rc.RDB$INDEX_NAME = sg.RDB$INDEX_NAME + WHERE rc.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' + AND rc.RDB$RELATION_NAME = UPPER(:tabela) + ORDER BY sg.RDB$FIELD_POSITION + """ + params = {"tabela": sequencia_schema.tabela} + pk_result = self.fetch_one(sql, params) + + if not pk_result: + raise Exception(f"Tabela {sequencia_schema.tabela} não possui chave primária") + + pk_field = pk_result["primary_key"].strip() # Nome da coluna PK (ex: "ID") + + + # 2) Monta dinamicamente a query para buscar o último ID + sql = f"SELECT MAX({pk_field}) AS last_id FROM {sequencia_schema.tabela}" + + # Importante: aqui não dá para usar :param para nome de tabela/coluna + last_id = self.fetch_one(sql) + + # 3) Verifica se a tabela foi cadastrada no G_SEQUENCIA + sql = """ + SELECT * + FROM G_SEQUENCIA + WHERE TABELA = :tabela + + """ + params = {"tabela": sequencia_schema.tabela} + gSequenciaResult = self.fetch_one(sql, params) + + # 4) Se não houver registro no g_sequencia, cadastro um novo + if not gSequenciaResult: + # Insere o registro na tabela de controle de sequência + sql = """ + INSERT INTO G_SEQUENCIA (TABELA, SEQUENCIA) + VALUES (:tabela, :sequencia) + """ + params = { + "tabela": sequencia_schema.tabela, + "sequencia": last_id["last_id"] if last_id["last_id"] is not None else 0 + } + self.run(sql, params) + + # Verifico se a quantidade atual de sequencia é igual a quantidade da tabela + elif gSequenciaResult["sequencia"] != last_id["last_id"]: + + # Caso a sequencia seja diferente do ultimo ID da tabela, retorno uma exceção + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail=f"A sequência atual ({gSequenciaResult['sequencia']}) está divergente do último ID da tabela ({last_id['last_id']})" + ) + diff --git a/packages/v1/sequencia/services/g_sequencia/checkout_service.py b/packages/v1/sequencia/services/g_sequencia/checkout_service.py new file mode 100644 index 0000000..656a303 --- /dev/null +++ b/packages/v1/sequencia/services/g_sequencia/checkout_service.py @@ -0,0 +1,25 @@ +from packages.v1.sequencia.actions.g_sequencia.checkout_action import CheckoutAction +from packages.v1.sequencia.schemas.g_sequencia import GSequenciaSchema +from fastapi import HTTPException, status + + +class GenerateService: + + def execute(self, sequencia_schema : GSequenciaSchema): + + # Instânciamento de Action + checkoutAction = CheckoutAction() + + # Atualiza a sequência atual + data = checkoutAction.execute(sequencia_schema) + + # Verifica se foi localizado o registro + if not data: + # Retorna uma exceção + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail='Não foi possível localizar a tabela para verificação de sequência' + ) + + # Retorna a informação localizada + return data diff --git a/packages/v1/sequencia/services/g_sequencia/generate_service.py b/packages/v1/sequencia/services/g_sequencia/generate_service.py index ca9e549..90a077c 100644 --- a/packages/v1/sequencia/services/g_sequencia/generate_service.py +++ b/packages/v1/sequencia/services/g_sequencia/generate_service.py @@ -1,6 +1,6 @@ from packages.v1.sequencia.actions.g_sequencia.get_action import GetAction -from packages.v1.sequencia.actions.g_sequencia.save_action import \ - SaveAction +from packages.v1.sequencia.actions.g_sequencia.save_action import SaveAction +from packages.v1.sequencia.actions.g_sequencia.checkout_action import CheckoutAction from packages.v1.sequencia.schemas.g_sequencia import GSequenciaSchema @@ -11,6 +11,10 @@ class GenerateService: # Instânciamento de Action getAction = GetAction() saveAction = SaveAction() + checkoutAction = CheckoutAction() + + # Verifico se a tabela existe no G_SEQUENCIA e se a sequência está correta + checkoutAction.execute(sequencia_schema) # Busco a sequência atual sequencia_result = getAction.execute(sequencia_schema)