From b6cb92d2c1e63b03271d295aa31b4ec6584338f3 Mon Sep 17 00:00:00 2001 From: keven Date: Fri, 10 Oct 2025 18:05:28 -0300 Subject: [PATCH] =?UTF-8?q?[MVPTN-100]=20fix(CRUD):=20Ajustes=20diversos?= =?UTF-8?q?=20no=20CRUD=20de=20Im=C3=B3veis=20e=20Unidades=20dos=20Im?= =?UTF-8?q?=C3=B3veis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../t_imovel/t_imovel_index_repository.py | 5 +- .../t_imovel/t_imovel_update_repository.py | 81 ++++--------------- .../t_pessoa/t_pessoa_index_repository.py | 3 +- .../administrativo/schemas/t_imovel_schema.py | 51 ++++-------- 4 files changed, 38 insertions(+), 102 deletions(-) diff --git a/packages/v1/administrativo/repositories/t_imovel/t_imovel_index_repository.py b/packages/v1/administrativo/repositories/t_imovel/t_imovel_index_repository.py index d6a9a60..7e8dfec 100644 --- a/packages/v1/administrativo/repositories/t_imovel/t_imovel_index_repository.py +++ b/packages/v1/administrativo/repositories/t_imovel/t_imovel_index_repository.py @@ -18,8 +18,9 @@ class TImovelIndexRepository(BaseRepository): sql = """ SELECT TI.*, GTBB.DESCRICAO AS GTBB_DESCRICAO FROM T_IMOVEL TI - JOIN G_TB_BAIRRO GTBB ON TI.TB_BAIRRO_ID = GTBB.TB_BAIRRO_ID - WHERE TI.TIPO_CLASSE = :tipoClasse """ + LEFT JOIN G_TB_BAIRRO GTBB ON TI.TB_BAIRRO_ID = GTBB.TB_BAIRRO_ID + WHERE TI.TIPO_CLASSE = :tipoClasse + ORDER BY imovel_id DESC """ params = { "tipoClasse": t_imovel_index_schema.tipo_classe diff --git a/packages/v1/administrativo/repositories/t_imovel/t_imovel_update_repository.py b/packages/v1/administrativo/repositories/t_imovel/t_imovel_update_repository.py index 58acc26..675ee29 100644 --- a/packages/v1/administrativo/repositories/t_imovel/t_imovel_update_repository.py +++ b/packages/v1/administrativo/repositories/t_imovel/t_imovel_update_repository.py @@ -1,82 +1,33 @@ from abstracts.repository import BaseRepository +from api.actions.data.prepare_update_data import prepare_update_data from packages.v1.administrativo.schemas.t_imovel_schema import TImovelUpdateSchema from fastapi import HTTPException, status class TImovelUpdateRepository(BaseRepository): - """ - Repositório para atualização de registros na tabela T_IMOVEL. - """ - def execute(self, t_imovel_schema: TImovelUpdateSchema): - """ - Executa a atualização de um imóvel pelo ID. - """ + def execute(self, t_imovel_update_schema: TImovelUpdateSchema): try: - # ---------------------------------------------------- - # Mapeamento de atributos → colunas SQL - # ---------------------------------------------------- - field_map = { - "tipo_classe": "TIPO_CLASSE", - "tipo_registro": "TIPO_REGISTRO", - "data_registro": "DATA_REGISTRO", - "numero": "NUMERO", - "numero_letra": "NUMERO_LETRA", - "cidade": "CIDADE", - "cep": "CEP", - "uf": "UF", - "tb_bairro_id": "TB_BAIRRO_ID", - "cartorio": "CARTORIO", - "livro": "LIVRO", - "cns": "CNS", - } + + params, update_columns = prepare_update_data( + t_imovel_update_schema, + exclude_fields=["imovel_id"], + id_field="imovel_id" + ) - # ---------------------------------------------------- - # Montagem dinâmica dos campos - # ---------------------------------------------------- - updates = [] - params = {} - - for attr, column in field_map.items(): - value = getattr(t_imovel_schema, attr, None) - if value is not None: - updates.append(f"{column} = :{attr}") - params[attr] = value - - if not updates: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="Nenhum campo válido foi enviado para atualização." - ) - - params["imovel_id"] = t_imovel_schema.imovel_id - - # ---------------------------------------------------- - # Montagem do SQL dinâmico - # ---------------------------------------------------- sql = f""" - UPDATE T_IMOVEL - SET {', '.join(updates)} - WHERE IMOVEL_ID = :imovel_id - RETURNING *; - """ + UPDATE T_IMOVEL + SET {update_columns} + WHERE IMOVEL_ID = :imovel_id + RETURNING * + """ - # ---------------------------------------------------- - # Execução e retorno - # ---------------------------------------------------- - result = self.run_and_return(sql, params) + # Executa o update + response = self.run_and_return(sql, params) - if not result: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="Nenhum imóvel encontrado para o ID informado." - ) + return response - return result - - except HTTPException: - raise except Exception as e: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, diff --git a/packages/v1/administrativo/repositories/t_pessoa/t_pessoa_index_repository.py b/packages/v1/administrativo/repositories/t_pessoa/t_pessoa_index_repository.py index a26959f..d44d24e 100644 --- a/packages/v1/administrativo/repositories/t_pessoa/t_pessoa_index_repository.py +++ b/packages/v1/administrativo/repositories/t_pessoa/t_pessoa_index_repository.py @@ -35,7 +35,8 @@ class TPessoaIndexRepository(BaseRepository): TP.CEP FROM T_PESSOA TP WHERE TP.PESSOA_TIPO = :pessoa_tipo - ORDER BY TP.PESSOA_ID DESC""" + ORDER BY TP.PESSOA_ID DESC + """ params = { "pessoa_tipo": t_pessoa_tipo_schema.pessoa_tipo } diff --git a/packages/v1/administrativo/schemas/t_imovel_schema.py b/packages/v1/administrativo/schemas/t_imovel_schema.py index 7f34508..fcced8e 100644 --- a/packages/v1/administrativo/schemas/t_imovel_schema.py +++ b/packages/v1/administrativo/schemas/t_imovel_schema.py @@ -1,17 +1,13 @@ -from pydantic import BaseModel, field_validator, model_validator -from fastapi import HTTPException, status +from pydantic import BaseModel from typing import Optional from datetime import datetime -# Função de sanitização -from actions.validations.text import Text - # ---------------------------------------------------- # Schema base # ---------------------------------------------------- class TImovelSchema(BaseModel): imovel_id: Optional[int] = None - tipo_classe: Optional[str] = None + tipo_classe: Optional[int] = None tipo_registro: Optional[str] = None data_registro: Optional[datetime] = None numero: Optional[float] = None @@ -20,9 +16,10 @@ class TImovelSchema(BaseModel): cep: Optional[float] = None uf: Optional[str] = None tb_bairro_id: Optional[int] = None - cartorio: Optional[str] = None + cartorio: Optional[int] = None livro: Optional[str] = None cns: Optional[float] = None + class Config: from_attributes = True @@ -30,7 +27,8 @@ class TImovelSchema(BaseModel): # Schema base # ---------------------------------------------------- class TImovelIndexSchema(BaseModel): - tipo_classe: int = None + tipo_classe: int + class Config: from_attributes = True @@ -40,21 +38,24 @@ class TImovelIndexSchema(BaseModel): class TImovelIdSchema(BaseModel): imovel_id: int + class Config: + from_attributes = True + # ---------------------------------------------------- # Schema para criação de novo IMÓVEL (POST) # ---------------------------------------------------- class TImovelSaveSchema(BaseModel): imovel_id: Optional[int] = None - tipo_classe: Optional[str] = None + tipo_classe: Optional[int] = None tipo_registro: Optional[str] = None data_registro: Optional[datetime] = None - numero: float + numero: Optional[float] = None numero_letra: Optional[str] = None cidade: Optional[str] = None cep: Optional[float] = None uf: Optional[str] = None tb_bairro_id: Optional[int] = None - cartorio: Optional[str] = None + cartorio: Optional[int] = None livro: Optional[str] = None cns: Optional[float] = None @@ -65,8 +66,8 @@ class TImovelSaveSchema(BaseModel): # Schema para atualização de IMÓVEL (PUT) # ---------------------------------------------------- class TImovelUpdateSchema(BaseModel): - imovel_id: int = None - tipo_classe: Optional[str] = None + imovel_id: int + tipo_classe: Optional[int] = None tipo_registro: Optional[str] = None data_registro: Optional[datetime] = None numero: Optional[float] = None @@ -75,27 +76,9 @@ class TImovelUpdateSchema(BaseModel): cep: Optional[float] = None uf: Optional[str] = None tb_bairro_id: Optional[int] = None - cartorio: Optional[str] = None + cartorio: Optional[int] = None livro: Optional[str] = None cns: Optional[float] = None - # Sanitiza os campos textuais - @field_validator('tipo_classe', 'tipo_registro', 'numero_letra', 'cidade', 'uf', 'cartorio', 'livro') - def sanitize_fields(cls, v): - if v: - return Text.sanitize_input(v) - return v - - # Garante que ao menos um campo seja enviado - @model_validator(mode='after') - def validate_partial_update(self): - if not any([ - self.tipo_classe, self.tipo_registro, self.data_registro, self.numero, - self.numero_letra, self.cidade, self.cep, self.uf, self.tb_bairro_id, - self.cartorio, self.livro, self.cns - ]): - raise HTTPException( - status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, - detail="Pelo menos um campo deve ser fornecido para a atualização." - ) - return self + class Config: + from_attributes = True