diff --git a/abstracts/repository.py b/abstracts/repository.py index 59d6507..2206381 100644 --- a/abstracts/repository.py +++ b/abstracts/repository.py @@ -1,50 +1,91 @@ -from typing import Literal, Optional +# Importa tipos utilitários para anotações estáticas e sobrecarga de assinaturas. +from typing import Any, Mapping, List, Optional, Literal, Union, overload +# Função `text` para construir SQL parametrizado de forma segura. from sqlalchemy import text +# Tipo de retorno de execução bruta de SQL (cursor/result set) do SQLAlchemy. +from sqlalchemy.engine import CursorResult +# Exceção base do SQLAlchemy para capturar erros de banco. from sqlalchemy.exc import SQLAlchemyError +# Provedor do engine de conexão com o Firebird, centralizado no projeto. from database.firebird import Firebird +# Define a classe base de repositórios, concentrando operações comuns de acesso a dados. class BaseRepository: - def query(self, sql: str, params: Optional[dict] = None): - """Executa uma consulta SQL e retorna o resultado como objeto ResultProxy""" - return self._execute(sql, params, fetch="result") - - def fetch_all(self, sql: str, params: Optional[dict] = None): - """Executa uma consulta SQL e retorna todos os registros com mapeamento de colunas""" - return self._execute(sql, params, fetch="all") - - def fetch_one(self, sql: str, params: Optional[dict] = None): - """Executa uma consulta SQL e retorna o primeiro registro com mapeamento de colunas""" - return self._execute(sql, params, fetch="one") - - def run(self, sql: str, params: Optional[dict] = None): - """Executa um SQL sem retorno de dados (ex: INSERT, UPDATE, DELETE)""" - return self._execute(sql, params, fetch="none") - - def run_and_return(self, sql: str, params: Optional[dict] = None): - """Executa SQL com RETURNING e retorna o primeiro registro como dict""" - return self._execute(sql, params, fetch="one") + # Sobrecarga 1: quando `fetch="all"`, o retorno é uma lista de mapeamentos (coluna->valor). + @overload + def _execute(self, sql: str, params: Optional[dict[str, Any]], fetch: Literal["all"]) -> List[Mapping[str, Any]]: ... + # Sobrecarga 2: quando `fetch="one"`, o retorno é um único mapeamento ou None. + @overload + def _execute(self, sql: str, params: Optional[dict[str, Any]], fetch: Literal["one"]) -> Optional[Mapping[str, Any]]: ... + # Sobrecarga 3: quando `fetch="none"`, não há retorno (operações DML sem leitura). + @overload + def _execute(self, sql: str, params: Optional[dict[str, Any]], fetch: Literal["none"]) -> None: ... + # Sobrecarga 4: quando `fetch="result"`, retorna o objeto `CursorResult` bruto do SQLAlchemy. + @overload + def _execute(self, sql: str, params: Optional[dict[str, Any]], fetch: Literal["result"]) -> CursorResult[Any]: ... + # Implementação concreta que atende às quatro sobrecargas por meio de um retorno em união. def _execute( self, - sql: str, - params: Optional[dict] = None, - fetch: Literal["all", "one", "result", "none"] = "result", - ): + sql: str, # Comando SQL (SELECT/INSERT/UPDATE/DELETE) em texto. + params: Optional[dict[str, Any]] = None, # Parâmetros nomeados para o SQL. + fetch: Literal["all", "one", "none", "result"] = "result", # Modo de leitura/retorno. + ) -> Union[ + List[Mapping[str, Any]], # Retorno quando `fetch="all"`. + Optional[Mapping[str, Any]], # Retorno quando `fetch="one"`. + None, # Retorno quando `fetch="none"`. + CursorResult[Any], # Retorno quando `fetch="result"`. + ]: + """Método interno que executa o SQL conforme o modo de fetch especificado.""" + # Obtém o engine de conexão com o Firebird a partir do provider central. engine = Firebird.get_engine() try: + # Inicia um contexto transacional; `begin()` garante commit/rollback automáticos. with engine.begin() as conn: + # Executa o SQL com parâmetros (usa dict vazio quando `params` é None). result = conn.execute(text(sql), params or {}) + # Quando for solicitado "all", converte o resultado em lista de mapeamentos (coluna->valor). if fetch == "all": - return result.mappings().all() + # retorna Sequence[RowMapping], compatível com List[Mapping[str, Any]] + return list(result.mappings().all()) + # Quando for solicitado "one", retorna apenas o primeiro registro (ou None). elif fetch == "one": return result.mappings().first() + # Quando for solicitado "none", não retorna dados (apenas executa o comando). elif fetch == "none": return None - return result # Result object + # Caso padrão: retorna o objeto Result bruto para manipulações específicas. + return result except SQLAlchemyError as e: + # Log simples para facilitar diagnóstico em ambiente de desenvolvimento/produção. print(f"[ERRO SQL]: {e}") + # Propaga a exceção para camadas superiores tratarem (ex.: FastAPI Exception Handler). raise - \ No newline at end of file + + # Executa uma consulta e retorna o objeto `CursorResult` bruto (uso avançado ou stream). + def query(self, sql: str, params: Optional[dict[str, Any]] = None) -> CursorResult[Any]: + """Executa uma consulta SQL e retorna o resultado como objeto ResultProxy.""" + return self._execute(sql, params, fetch="result") + + # Executa uma consulta e retorna todos os registros como lista de mapeamentos. + def fetch_all(self, sql: str, params: Optional[dict[str, Any]] = None) -> List[Mapping[str, Any]]: + """Executa uma consulta SQL e retorna todos os registros com mapeamento de colunas.""" + return self._execute(sql, params, fetch="all") + + # Executa uma consulta e retorna apenas o primeiro registro ou None. + def fetch_one(self, sql: str, params: Optional[dict[str, Any]] = None) -> Optional[Mapping[str, Any]]: + """Executa uma consulta SQL e retorna o primeiro registro com mapeamento de colunas.""" + return self._execute(sql, params, fetch="one") + + # Executa comandos DML (INSERT/UPDATE/DELETE) sem retorno de dados. + def run(self, sql: str, params: Optional[dict[str, Any]] = None) -> None: + """Executa um SQL sem retorno de dados (ex: INSERT, UPDATE, DELETE).""" + self._execute(sql, params, fetch="none") + + # Executa comandos com cláusula RETURNING e devolve o registro retornado (ou None). + def run_and_return(self, sql: str, params: Optional[dict[str, Any]] = None) -> Optional[Mapping[str, Any]]: + """Executa SQL com RETURNING e retorna o primeiro registro como dict.""" + return self._execute(sql, params, fetch="one") diff --git a/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_delete_action.py b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_delete_action.py new file mode 100644 index 0000000..5899b15 --- /dev/null +++ b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_delete_action.py @@ -0,0 +1,27 @@ +from abstracts.action import BaseAction +from api.packages.v1.administrativo.repositories.t_ato_partetipo.t_ato_partetipo_delete_repository import TAtoParteTipoDeleteRepository +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoIdSchema + +class TAtoParteTipoDeleteAction(BaseAction): + """ + Serviço responsável por encapsular a lógica de negócio para a operação + de exclusão de um registro na tabela t_t_ato_partetipo_id. + """ + + def execute(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + """ + Executa a operação de exclusão no banco de dados. + + Args: + t_ato_partetipo_id_schema (TAtoParteTipoSchema): O esquema com o ID a ser excluído. + + Returns: + O resultado da operação de exclusão. + """ + # Instanciamento do repositório + t_ato_partetipo_delete_repository = TAtoParteTipoDeleteRepository() + + # Execução do repositório + response = t_ato_partetipo_delete_repository.execute(t_ato_partetipo_id_schema) + + return response \ No newline at end of file diff --git a/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_index_action.py b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_index_action.py new file mode 100644 index 0000000..ce02c27 --- /dev/null +++ b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_index_action.py @@ -0,0 +1,24 @@ +from abstracts.action import BaseAction +from api.packages.v1.administrativo.repositories.t_ato_partetipo.t_ato_partetipo_index_repository import TAtoParteTipoIndexRepository + +class TAtoParteTipoIndexAction(BaseAction): + """ + Serviço responsável por encapsular a lógica de negócio para a operação + de listagem de todos os registros na tabela t_censec_qualidade. + """ + + def execute(self): + """ + Executa a operação de listagem no banco de dados. + + Returns: + A lista de todos os registros. + """ + # Instanciamento do repositório + t_ato_partetipo_index_repositoy = TAtoParteTipoIndexRepository() + + # Execução do repositório + response = t_ato_partetipo_index_repositoy.execute() + + # Retorno da informação + return response \ No newline at end of file diff --git a/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_save_action.py b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_save_action.py new file mode 100644 index 0000000..6b7738f --- /dev/null +++ b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_save_action.py @@ -0,0 +1,28 @@ +from abstracts.action import BaseAction +from api.packages.v1.administrativo.repositories.t_ato_partetipo.t_ato_partetipo_save_repository import TAtoParteTipoSaveRepository +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoSaveSchema + +class TAtoParteTipoSaveAction(BaseAction): + """ + Serviço responsável por encapsular a lógica de negócio para a operação + de salvar um novo registro na tabela t_censec_qualidade. + """ + + def execute(self, t_ato_partetipo_save_schema: TAtoParteTipoSaveSchema): + """ + Executa a operação de salvamento. + + Args: + t_ato_partetipo_schema (TCensecQualidadeSaveSchema): O esquema com os dados a serem salvos. + + Returns: + O resultado da operação de salvamento. + """ + # Instanciamento do repositório + t_ato_partetipo_save_repository = TAtoParteTipoSaveRepository() + + # Execução do repositório + response = t_ato_partetipo_save_repository.execute(t_ato_partetipo_save_schema) + + # Retorno da informação + return response \ No newline at end of file diff --git a/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_show_action.py b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_show_action.py new file mode 100644 index 0000000..0f4902a --- /dev/null +++ b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_show_action.py @@ -0,0 +1,28 @@ +from abstracts.action import BaseAction +from api.packages.v1.administrativo.repositories.t_ato_partetipo.t_ato_partetipo_show_repository import TAtoParteTipoShowRepository +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoIdSchema + +class TAtoParteTipoShowAction(BaseAction): + """ + Serviço responsável por encapsular a lógica de negócio para a exibição + de um registro na tabela t_censec_qualidade. + """ + + def execute(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + """ + Executa a operação de exibição. + + Args: + t_ato_partetipo_schema (TCensecQualidadeIdSchema): O esquema com o ID do registro a ser exibido. + + Returns: + O resultado da operação de exibição. + """ + # Instânciamento do repositório + t_ato_partetipo_show_repository = TAtoParteTipoShowRepository() + + # Execução do repositório + response = t_ato_partetipo_show_repository.execute(t_ato_partetipo_id_schema) + + # Retorno da informação + return response \ No newline at end of file diff --git a/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_update_action.py b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_update_action.py new file mode 100644 index 0000000..26edd3c --- /dev/null +++ b/packages/v1/administrativo/actions/t_ato_partetipo/t_ato_partetipo_update_action.py @@ -0,0 +1,27 @@ +from abstracts.action import BaseAction +from api.packages.v1.administrativo.repositories.t_ato_partetipo.t_ato_partetipo_update_repository import TAtoParteTipoUpdateRepository +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoUpdateSchema + + +class TAtoParteTipoUpdateAction(BaseAction): + """ + Serviço responsável por encapsular a lógica de negócio para a atualização + de um registro na tabela t_censec_qualidade. + """ + + def execute(self, t_ato_partetipo_update_schema: TAtoParteTipoUpdateSchema): + """ + Executa a operação de atualização. + + Args: + t_ato_partetipo_unidade_id (int): O ID do registro a ser atualizado. + t_ato_partetipo_update_schema (TCensecQualidadeUpdateSchema): O esquema com os dados a serem atualizados. + + Returns: + O resultado da operação de atualização. + """ + # Instância o repositório de atualização + t_ato_partetipo_update_repository = TAtoParteTipoUpdateRepository() + + # Chama o método de execução do repositório para realizar a atualização + return t_ato_partetipo_update_repository.execute(t_ato_partetipo_update_schema) \ No newline at end of file diff --git a/packages/v1/administrativo/controllers/t_ato_partetipo_controller.py b/packages/v1/administrativo/controllers/t_ato_partetipo_controller.py new file mode 100644 index 0000000..42e064e --- /dev/null +++ b/packages/v1/administrativo/controllers/t_ato_partetipo_controller.py @@ -0,0 +1,121 @@ +from actions.dynamic_import.dynamic_import import DynamicImport +from packages.v1.administrativo.schemas.t_ato_partetipo_schema import ( + TAtoParteTipoIndexSchema, + TAtoParteTipoSaveSchema, + TAtoParteTipoUpdateSchema, + TAtoParteTipoIdSchema +) + + +class TAtoParteTipoController: + """ + Controller responsável pelas operações de CRUD na tabela T_ATO_PARTETIPO. + Gerencia chamadas de listagem, busca, inserção, atualização e exclusão + de registros utilizando o sistema de importação dinâmica de services. + """ + + def __init__(self): + # Instancia o gerenciador dinâmico de imports + self.dynamic_import = DynamicImport() + + # Define o pacote ao qual o controller pertence + self.dynamic_import.set_package("administrativo") + + # Define a tabela alvo das operações + self.dynamic_import.set_table("t_ato_partetipo") + pass + + # ---------------------------------------------------- + # Lista todos os registros de T_ATO_PARTETIPO + # ---------------------------------------------------- + def index(self): + # Importa o service correspondente dinamicamente + index_service_class = self.dynamic_import.service( + "t_ato_partetipo_index_service", + "TAtoParteTipoIndexService" + ) + + # Instancia o service + self.index_service = index_service_class() + + # Executa a listagem e retorna o resultado + return { + "message": "Registros de T_ATO_PARTETIPO localizados com sucesso", + "data": self.index_service.execute(), + } + + # ---------------------------------------------------- + # Busca um registro de T_ATO_PARTETIPO pelo ID + # ---------------------------------------------------- + def show(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + # Importa o service correspondente dinamicamente + show_service_class = self.dynamic_import.service( + "t_ato_partetipo_show_service", + "TAtoParteTipoShowService" + ) + + # Instancia o service + self.show_service = show_service_class() + + # Executa a busca e retorna o resultado + return { + "message": "Registro de T_ATO_PARTETIPO localizado com sucesso", + "data": self.show_service.execute(t_ato_partetipo_id_schema), + } + + # ---------------------------------------------------- + # Cadastra um novo registro de T_ATO_PARTETIPO + # ---------------------------------------------------- + def save(self, t_ato_partetipo_save_schema: TAtoParteTipoSaveSchema): + # Importa o service correspondente dinamicamente + save_service_class = self.dynamic_import.service( + "t_ato_partetipo_save_service", + "TAtoParteTipoSaveService" + ) + + # Instancia o service + self.save_service = save_service_class() + + # Executa a inserção e retorna o resultado + return { + "message": "Registro de T_ATO_PARTETIPO salvo com sucesso", + "data": self.save_service.execute(t_ato_partetipo_save_schema), + } + + # ---------------------------------------------------- + # Atualiza os dados de um registro existente + # ---------------------------------------------------- + def update(self, t_ato_partetipo_update_schema: TAtoParteTipoUpdateSchema): + # Importa o service correspondente dinamicamente + update_service_class = self.dynamic_import.service( + "t_ato_partetipo_update_service", + "TAtoParteTipoUpdateService" + ) + + # Instancia o service + self.update_service = update_service_class() + + # Executa a atualização e retorna o resultado + return { + "message": "Registro de T_ATO_PARTETIPO atualizado com sucesso", + "data": self.update_service.execute(t_ato_partetipo_update_schema), + } + + # ---------------------------------------------------- + # Exclui um registro de T_ATO_PARTETIPO + # ---------------------------------------------------- + def delete(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + # Importa o service correspondente dinamicamente + delete_service_class = self.dynamic_import.service( + "t_ato_partetipo_delete_service", + "TAtoParteTipoDeleteService" + ) + + # Instancia o service + self.delete_service = delete_service_class() + + # Executa a exclusão e retorna o resultado + return { + "message": "Registro de T_ATO_PARTETIPO removido com sucesso", + "data": self.delete_service.execute(t_ato_partetipo_id_schema), + } diff --git a/packages/v1/administrativo/endpoints/t_ato_partetipo_endpoint.py b/packages/v1/administrativo/endpoints/t_ato_partetipo_endpoint.py new file mode 100644 index 0000000..610387a --- /dev/null +++ b/packages/v1/administrativo/endpoints/t_ato_partetipo_endpoint.py @@ -0,0 +1,143 @@ +# ---------------------------------------------------- +# Importação de bibliotecas e dependências +# ---------------------------------------------------- +from fastapi import APIRouter, Depends, status +from actions.jwt.get_current_user import get_current_user +from packages.v1.administrativo.controllers.t_ato_partetipo_controller import TAtoParteTipoController +from packages.v1.administrativo.schemas.t_ato_partetipo_schema import ( + TAtoParteTipoSaveSchema, + TAtoParteTipoUpdateSchema, + TAtoParteTipoIdSchema +) + +# ---------------------------------------------------- +# Inicialização do roteador da tabela T_ATO_PARTETIPO +# ---------------------------------------------------- +router = APIRouter() + +# Instancia o controller da tabela T_ATO_PARTETIPO +t_ato_partetipo_controller = TAtoParteTipoController() + +# ---------------------------------------------------- +# Lista todos os registros de T_ATO_PARTETIPO +# ---------------------------------------------------- +@router.get( + '/', + status_code=status.HTTP_200_OK, + summary='Lista todos os registros de T_ATO_PARTETIPO cadastrados', + response_description='Lista todos os registros de T_ATO_PARTETIPO cadastrados' +) +async def index( + current_user: dict = Depends(get_current_user) +): + """ + Lista todos os registros da tabela T_ATO_PARTETIPO de acordo com o ID de qualidade CENSEC. + """ + + # Executa a busca dos registros + response = t_ato_partetipo_controller.index() + + # Retorna os registros localizados + return response + + +# ---------------------------------------------------- +# Localiza um registro de T_ATO_PARTETIPO pelo ID +# ---------------------------------------------------- +@router.get( + '/{ato_partetipo_id}', + status_code=status.HTTP_200_OK, + summary='Busca um registro de T_ATO_PARTETIPO em específico pelo ID', + response_description='Busca um registro de T_ATO_PARTETIPO em específico' +) +async def show( + ato_partetipo_id: int, + current_user: dict = Depends(get_current_user) +): + """ + Localiza um registro específico de T_ATO_PARTETIPO pelo seu ID. + """ + # Cria o schema com o ID recebido + t_ato_partetipo_id_schema = TAtoParteTipoIdSchema(ato_partetipo_id=ato_partetipo_id) + + # Executa a busca do registro + response = t_ato_partetipo_controller.show(t_ato_partetipo_id_schema) + + # Retorna o resultado + return response + + +# ---------------------------------------------------- +# Cadastra um novo registro de T_ATO_PARTETIPO +# ---------------------------------------------------- +@router.post( + '/', + status_code=status.HTTP_201_CREATED, + summary='Cadastra um registro de T_ATO_PARTETIPO', + response_description='Cadastra um registro de T_ATO_PARTETIPO' +) +async def save( + t_ato_partetipo_schema: TAtoParteTipoSaveSchema, + current_user: dict = Depends(get_current_user) +): + """ + Realiza o cadastro de um novo registro na tabela T_ATO_PARTETIPO. + """ + # Executa a operação de salvamento + response = t_ato_partetipo_controller.save(t_ato_partetipo_schema) + + # Retorna o registro criado + return response + + +# ---------------------------------------------------- +# Atualiza os dados de um registro existente +# ---------------------------------------------------- +@router.put( + '/{ato_partetipo_id}', + status_code=status.HTTP_200_OK, + summary='Atualiza um registro de T_ATO_PARTETIPO', + response_description='Atualiza um registro de T_ATO_PARTETIPO' +) +async def update( + ato_partetipo_id: int, + t_ato_partetipo_update_schema: TAtoParteTipoUpdateSchema, + current_user: dict = Depends(get_current_user) +): + """ + Atualiza os dados de um registro existente na tabela T_ATO_PARTETIPO. + """ + # Define o ID no schema de atualização + t_ato_partetipo_update_schema.ato_partetipo_id = ato_partetipo_id + + # Executa a atualização + response = t_ato_partetipo_controller.update(t_ato_partetipo_update_schema) + + # Retorna o registro atualizado + return response + + +# ---------------------------------------------------- +# Exclui um registro de T_ATO_PARTETIPO +# ---------------------------------------------------- +@router.delete( + '/{ato_partetipo_id}', + status_code=status.HTTP_200_OK, + summary='Remove um registro de T_ATO_PARTETIPO', + response_description='Remove um registro de T_ATO_PARTETIPO' +) +async def delete( + ato_partetipo_id: int, + current_user: dict = Depends(get_current_user) +): + """ + Remove um registro da tabela T_ATO_PARTETIPO com base no ID informado. + """ + # Monta o schema de exclusão + t_ato_partetipo_schema = TAtoParteTipoIdSchema(ato_partetipo_id=ato_partetipo_id) + + # Executa a exclusão + response = t_ato_partetipo_controller.delete(t_ato_partetipo_schema) + + # Retorna o resultado da operação + return response diff --git a/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_delete_repository.py b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_delete_repository.py new file mode 100644 index 0000000..87761bf --- /dev/null +++ b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_delete_repository.py @@ -0,0 +1,42 @@ +from abstracts.repository import BaseRepository +from fastapi import HTTPException, status + +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoIdSchema + + +class TAtoParteTipoDeleteRepository(BaseRepository): + """ + Repositório responsável pela exclusão de registros da tabela T_IMOVEL. + """ + + def execute(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + """ + Executa a operação de exclusão de um registro com base no ID informado. + + Args: + t_ato_partetipo_id_schema (TAtoParteTipoIdSchema): Esquema contendo o identificador do registro a ser excluído. + + Returns: + dict: Resultado da operação de exclusão. + """ + try: + # Montagem do SQL + sql = """ + DELETE FROM T_ATO_PARTETIPO TAP + WHERE TAP.ATO_PARTETIPO_ID = :ato_partetipo_id + """ + + # Parâmetros da query + params = t_ato_partetipo_id_schema.model_dump(exclude_unset=True) + + # Execução da query + response = self.run(sql, params) + + # Retorno do resultado + return response + + except Exception as e: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail=f"Erro ao excluir registro de T_IMOVEL: {str(e)}", + ) diff --git a/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_index_repository.py b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_index_repository.py new file mode 100644 index 0000000..7688adc --- /dev/null +++ b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_index_repository.py @@ -0,0 +1,33 @@ +from abstracts.repository import BaseRepository + +class TAtoParteTipoIndexRepository(BaseRepository): + """ + Repositório para a operação de listagem de todos os registros + na tabela t_censec_qualidade. + """ + + def execute(self): + """ + Executa a consulta SQL para buscar todos os registros. + + Returns: + Uma lista de dicionários contendo os dados dos registros. + """ + # Montagem do SQL + sql = """ SELECT + TAP.ATO_PARTETIPO_ID, + TAP.DESCRICAO, + TAP.TIPO_PARTE, + TAP.AUTO_QUALIFICA, + TAP.DECLARA_DOI, + TAP.POSSUI_DOCUMENTO_EXT, + TAP.SITUACAO, + TAP.CENSEC_QUALIDADE_ID + FROM T_ATO_PARTETIPO TAP + """ + + # Execução do sql + response = self.fetch_all(sql) + + # Retorna os dados localizados + return response \ No newline at end of file diff --git a/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_save_repository.py b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_save_repository.py new file mode 100644 index 0000000..7445d47 --- /dev/null +++ b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_save_repository.py @@ -0,0 +1,75 @@ +from fastapi import HTTPException, status +from abstracts.repository import BaseRepository +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoSaveSchema + + +class TAtoParteTipoSaveRepository(BaseRepository): + """ + Repositório para a operação de salvamento de um novo registro na tabela t_t_ato_partetipo_unidade. + """ + + def execute(self, t_ato_partetipo_save_schema: TAtoParteTipoSaveSchema): + """ + Executa a operação de salvamento no banco de dados. + + Args: + t_ato_partetipo_schema (TAtoParteTipoSchema): O esquema com os dados a serem salvos. + + Returns: + O registro recém-criado. + + Raises: + HTTPException: Caso ocorra um erro na execução da query. + """ + try: + + # ---------------------------------------------------- + # Montagem do SQL + # ---------------------------------------------------- + sql = """ + INSERT INTO T_ATO_PARTETIPO ( + ATO_PARTETIPO_ID, + DESCRICAO, + TIPO_PARTE, + AUTO_QUALIFICA, + DECLARA_DOI, + POSSUI_DOCUMENTO_EXT, + SITUACAO, + CENSEC_QUALIDADE_ID + ) VALUES ( + :ato_partetipo_id, + :descricao, + :tipo_parte, + :auto_qualifica, + :declara_doi, + :possui_documento_ext, + :situacao, + :censec_qualidade_id + ) + RETURNING ATO_PARTETIPO_ID, + DESCRICAO, + TIPO_PARTE, + AUTO_QUALIFICA, + DECLARA_DOI, + POSSUI_DOCUMENTO_EXT, + SITUACAO, + CENSEC_QUALIDADE_ID + ; + """ + + # ---------------------------------------------------- + # Preenchimento dos parâmetros de acordo com o schema + # ---------------------------------------------------- + params = t_ato_partetipo_save_schema.model_dump(exclude_unset=True) + + + # Execução do sql + return self.run_and_return(sql, params) + + except Exception as e: + + # Informa que houve uma falha no salvamento do registro + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail=f"Erro ao salvar T_IMOVEL: {e}" + ) \ No newline at end of file diff --git a/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_show_repository.py b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_show_repository.py new file mode 100644 index 0000000..bfb55d2 --- /dev/null +++ b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_show_repository.py @@ -0,0 +1,47 @@ +from abstracts.repository import BaseRepository +from fastapi import HTTPException, status + +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoIdSchema + +class TAtoParteTipoShowRepository(BaseRepository): + """ + Repositório para a operação de exibição de um registro na tabela t_censec_qualidade. + """ + + def execute(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + """ + Busca um registro específico de CENSEC_QUALIDADE pelo ID. + + Args: + t_ato_partetipo_schema (TAtoParteTipoIdSchema): O esquema que contém o ID do registro. + + Returns: + O registro encontrado ou None se não existir. + + Raises: + HTTPException: Caso ocorra um erro na execução da query. + """ + try: + # Montagem do SQL + sql = "SELECT * FROM T_ATO_PARTETIPO TAP WHERE TAP.ATO_PARTETIPO_ID = :ato_partetipo_id" + + # ---------------------------------------------------- + # Preenchimento dos parâmetros de acordo com o schema + # ---------------------------------------------------- + params = t_ato_partetipo_id_schema.model_dump(exclude_unset=True) + + # Execução do SQL + result = self.fetch_one(sql, params) + + if not result: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Registro não encontrado" + ) + + return result + except Exception as e: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail=f"Erro ao buscar registro: {str(e)}" + ) \ No newline at end of file diff --git a/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_update_repository.py b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_update_repository.py new file mode 100644 index 0000000..b47c86e --- /dev/null +++ b/packages/v1/administrativo/repositories/t_ato_partetipo/t_ato_partetipo_update_repository.py @@ -0,0 +1,42 @@ +from abstracts.repository import BaseRepository +from api.actions.data.prepare_update_data import prepare_update_data +from packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoUpdateSchema +from fastapi import HTTPException, status + + +class TAtoParteTipoUpdateRepository(BaseRepository): + + def execute(self, t_ato_partetipo_update_schema: TAtoParteTipoUpdateSchema): + + try: + + params, update_columns = prepare_update_data( + t_ato_partetipo_update_schema, + exclude_fields=["ato_partipo_id"], + id_field="ato_partipo_id" + ) + + sql = f""" + UPDATE T_ATO_PARTETIPO + SET {update_columns} + WHERE ATO_PARTETIPO_ID = :ato_partetipo_id + RETURNING ATO_PARTETIPO_ID, + DESCRICAO, + TIPO_PARTE, + AUTO_QUALIFICA, + DECLARA_DOI, + POSSUI_DOCUMENTO_EXT, + SITUACAO, + CENSEC_QUALIDADE_ID + """ + + # Executa o update + response = self.run_and_return(sql, params) + + return response + + except Exception as e: + raise HTTPException( + status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, + detail=f"Erro ao atualizar o imóvel: {str(e)}" + ) diff --git a/packages/v1/administrativo/schemas/t_ato_partetipo_schema.py b/packages/v1/administrativo/schemas/t_ato_partetipo_schema.py new file mode 100644 index 0000000..aefe5eb --- /dev/null +++ b/packages/v1/administrativo/schemas/t_ato_partetipo_schema.py @@ -0,0 +1,77 @@ +from pydantic import BaseModel, Field +from decimal import Decimal +from typing import Optional + + +# ---------------------------------------------------- +# Schema base +# ---------------------------------------------------- +class TAtoParteTipoSchema(BaseModel): + ato_partetipo_id: Decimal = Field(..., description="Identificador único da parte do ato") + descricao: Optional[str] = Field(None, max_length=60) + tipo_parte: Optional[Decimal] = None + auto_qualifica: Optional[str] = Field(None, max_length=1) + declara_doi: Optional[str] = Field(None, max_length=1) + possui_documento_ext: Optional[str] = Field(None, max_length=1) + situacao: Optional[str] = Field(None, max_length=1) + texto: Optional[bytes] = None + censec_qualidade_id: Optional[Decimal] = None + + class Config: + from_attributes = True + + +# ---------------------------------------------------- +# Schema para indexação +# ---------------------------------------------------- +class TAtoParteTipoIndexSchema(BaseModel): + ato_partetipo_id: int + + class Config: + from_attributes = True + + +# ---------------------------------------------------- +# Schema para busca por ID (GET) +# ---------------------------------------------------- +class TAtoParteTipoIdSchema(BaseModel): + ato_partetipo_id: int + + class Config: + from_attributes = True + + +# ---------------------------------------------------- +# Schema para criação (POST) +# ---------------------------------------------------- +class TAtoParteTipoSaveSchema(BaseModel): + ato_partetipo_id: Optional[int] = None + descricao: Optional[str] = Field(None, max_length=60) + tipo_parte: Optional[Decimal] = None + auto_qualifica: Optional[str] = Field(None, max_length=1) + declara_doi: Optional[str] = Field(None, max_length=1) + possui_documento_ext: Optional[str] = Field(None, max_length=1) + situacao: Optional[str] = Field(None, max_length=1) + texto: Optional[bytes] = None + censec_qualidade_id: Optional[Decimal] = None + + class Config: + from_attributes = True + + +# ---------------------------------------------------- +# Schema para atualização (PUT) +# ---------------------------------------------------- +class TAtoParteTipoUpdateSchema(BaseModel): + ato_partetipo_id: Optional[int] = None + descricao: Optional[str] = Field(None, max_length=60) + tipo_parte: Optional[Decimal] = None + auto_qualifica: Optional[str] = Field(None, max_length=1) + declara_doi: Optional[str] = Field(None, max_length=1) + possui_documento_ext: Optional[str] = Field(None, max_length=1) + situacao: Optional[str] = Field(None, max_length=1) + texto: Optional[bytes] = None + censec_qualidade_id: Optional[Decimal] = None + + class Config: + from_attributes = True \ No newline at end of file diff --git a/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_delete_service.py b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_delete_service.py new file mode 100644 index 0000000..e3248e2 --- /dev/null +++ b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_delete_service.py @@ -0,0 +1,29 @@ + +from api.packages.v1.administrativo.actions.t_ato_partetipo.t_ato_partetipo_delete_action import TAtoParteTipoDeleteAction +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoIdSchema + + +class TAtoParteTipoDeleteService: + """ + Serviço responsável por encapsular a lógica de negócio para a operação + de exclusão de um registro na tabela t_censec_qualidade. + """ + + def execute(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + """ + Executa a operação de exclusão do registro no banco de dados. + + Args: + t_ato_partetipo_schema (TCensecQualidadeIdSchema): O esquema com o ID do registro a ser excluído. + + Returns: + O resultado da operação de exclusão. + """ + # Instanciamento da ação + t_ato_partetipo_delete_action = TAtoParteTipoDeleteAction() + + # Executa a ação em questão + data = t_ato_partetipo_delete_action.execute(t_ato_partetipo_id_schema) + + # Retorno da informação + return data \ No newline at end of file diff --git a/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_index_service.py b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_index_service.py new file mode 100644 index 0000000..1bcf70e --- /dev/null +++ b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_index_service.py @@ -0,0 +1,33 @@ +from fastapi import HTTPException, status + +from api.packages.v1.administrativo.actions.t_ato_partetipo.t_ato_partetipo_index_action import TAtoParteTipoIndexAction + +class TAtoParteTipoIndexService: + """ + Serviço responsável por encapsular a lógica de negócio para a operação + de listagem de registros na tabela t_censec_qualidade. + """ + + def execute(self): + """ + Executa a operação de busca de todos os registros no banco de dados. + + Returns: + A lista de registros encontrados. + """ + # Instanciamento da ação + t_ato_partetipo_index_action = TAtoParteTipoIndexAction() + + # Executa a busca de todas as ações + data = t_ato_partetipo_index_action.execute() + + # Verifica se foram localizados registros + if not data: + # Retorna uma exceção + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail='Não foi possível localizar os registros de T_IMOVEL_UNIDADE' + ) + + # Retorna as informações localizadas + return data \ No newline at end of file diff --git a/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_save_service.py b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_save_service.py new file mode 100644 index 0000000..e93a89e --- /dev/null +++ b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_save_service.py @@ -0,0 +1,35 @@ +from api.packages.v1.administrativo.actions.t_ato_partetipo.t_ato_partetipo_save_action import TAtoParteTipoSaveAction +from api.packages.v1.sequencia.schemas.g_sequencia import GSequenciaSchema +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoSaveSchema +from api.packages.v1.sequencia.services.g_sequencia.generate_service import GenerateService + +class TAtoParteTipoSaveService: + + # Cadastra o novo CENSEC_QUALIDADE + def execute(self, t_ato_partetipo_save_schema: TAtoParteTipoSaveSchema): + + # Verifica se precisa gerar o ID de sequência + # Coluna primária ajustadaA + if not t_ato_partetipo_save_schema.ato_partetipo_id: + + # Crio um objeto de sequencia + sequencia_schema = GSequenciaSchema() + + # Define os dados para atualizar a sequencia + sequencia_schema.tabela = 'T_ATO_PARTETIPO' + + # Busco a sequência atualizada + generate = GenerateService() + + # Busco a sequência atualizada + sequencia = generate.execute(sequencia_schema) + + # Atualiza os dados da chave primária + t_ato_partetipo_save_schema.ato_partetipo_id = sequencia.sequencia + + # Instanciamento de ações + # Ação já é importada como SaveAction + t_ato_partetipo_save_action = TAtoParteTipoSaveAction() + + # Retorna o resultado da operação + return t_ato_partetipo_save_action.execute(t_ato_partetipo_save_schema) # Nome do parâmetro ajustado \ No newline at end of file diff --git a/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_show_service.py b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_show_service.py new file mode 100644 index 0000000..805e660 --- /dev/null +++ b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_show_service.py @@ -0,0 +1,35 @@ +from api.packages.v1.administrativo.actions.t_ato_partetipo.t_ato_partetipo_show_action import TAtoParteTipoShowAction +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoIdSchema +from fastapi import HTTPException, status + +class TAtoParteTipoShowService: + """ + Serviço responsável por encapsular a lógica de negócio para a operação + de busca de um registro na tabela t_censec_qualidade. + """ + + def execute(self, t_ato_partetipo_id_schema: TAtoParteTipoIdSchema): + """ + Executa a operação de busca no banco de dados. + + Args: + t_ato_partetipo_schema (TCensecQualidadeIdSchema): O esquema com o ID a ser buscado. + + Returns: + O resultado da busca. + """ + # Instanciamento da ação + t_ato_partetipo_show_action = TAtoParteTipoShowAction() + + # Executa a ação em questão + data = t_ato_partetipo_show_action.execute(t_ato_partetipo_id_schema) + + if not data: + # Retorna uma exceção + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail='Não foi possível localizar o registro de T_IMOVEL_UNIDADE' + ) + + # Retorno da informação + return data \ No newline at end of file diff --git a/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_update_service.py b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_update_service.py new file mode 100644 index 0000000..6ebecae --- /dev/null +++ b/packages/v1/administrativo/services/t_ato_partetipo/go/t_ato_partetipo_update_service.py @@ -0,0 +1,25 @@ + +from api.packages.v1.administrativo.actions.t_ato_partetipo.t_ato_partetipo_update_action import TAtoParteTipoUpdateAction +from api.packages.v1.administrativo.schemas.t_ato_partetipo_schema import TAtoParteTipoUpdateSchema + + +class TAtoParteTipoUpdateService: + """ + Serviço para a operação de atualização de um registro na tabela + t_censec_qualidade. + """ + def execute(self, t_ato_partetipo_update_schema: TAtoParteTipoUpdateSchema): + """ + Executa a operação de atualização no banco de dados. + + Args: + t_ato_partetipo_schema (TCensecQualidadeUpdateSchema): O esquema com os dados a serem atualizados. + + Returns: + O resultado da operação de atualização. + """ + # Instanciamento de ações + t_ato_partetipo_update_action = TAtoParteTipoUpdateAction() + + # Retorna o resultado da operação + return t_ato_partetipo_update_action.execute(t_ato_partetipo_update_schema) \ No newline at end of file diff --git a/packages/v1/api.py b/packages/v1/api.py index b23dcad..6916529 100644 --- a/packages/v1/api.py +++ b/packages/v1/api.py @@ -2,6 +2,7 @@ from fastapi import APIRouter # Importa os módulos de rotas específicos +from api.packages.v1.administrativo.endpoints import t_ato_partetipo_endpoint from packages.v1.administrativo.endpoints import t_censec_tipoato_endpoint from packages.v1.administrativo.endpoints import t_censec_qualidadeato_endpoint from packages.v1.administrativo.endpoints import g_tb_txmodelogrupo_endpoint @@ -175,17 +176,22 @@ api_router.include_router( t_pessoa_endpoint.router, prefix="/administrativo/t_pessoa", tags=["Pessoas Fisicas e Jurídicas"] ) -# Inclui as rotas de t_imovel_unidade +# Inclui as rotas de t_pessoa_representante api_router.include_router( t_pessoa_representante_endpoint.router, prefix="/administrativo/t_pessoa_representante", tags=["Representante de pessoas jurídicas"] ) -# Inclui as rotas de t_imovel_unidade +# Inclui as rotas de t_censec_tipoato api_router.include_router( t_censec_tipoato_endpoint.router, prefix="/administrativo/t_censec_tipoato", tags=["CENSEC Tipo atos"] ) -# Inclui as rotas de t_imovel_unidade +# Inclui as rotas de t_censec_qualidadeato api_router.include_router( t_censec_qualidadeato_endpoint.router, prefix="/administrativo/t_censec_qualidadeato", tags=["CENSEC Qualidade Ato"] +) + +# Inclui as rotas de t_censec_qualidadeato +api_router.include_router( + t_ato_partetipo_endpoint.router, prefix="/administrativo/t_ato_partetipo", tags=["Tipo de Parte do Ato"] ) \ No newline at end of file