From 8c1dd07d769d66167777f789a8733bf5112c2375 Mon Sep 17 00:00:00 2001
From: hreyes
Date: Wed, 22 Apr 2026 10:13:34 -0600
Subject: [PATCH] fix/catalogos-fijos
---
.../a76/general_catalogs/sectors/service.py | 9 ++
.../agency_tariff_codes/routes.py | 13 +++
.../carta_porte_codes/routes.py | 10 ++
.../code_pedimento_regimens/routes.py | 10 ++
.../reference_data/containers/routes.py | 11 ++
.../reference_data/currency_types/routes.py | 12 ++
.../reference_data/customs_sections/routes.py | 11 ++
.../customs_warehouses/routes.py | 12 ++
.../reference_data/identifiers/routes.py | 12 ++
.../public/reference_data/incoterms/routes.py | 12 ++
.../reference_data/invoice_types/routes.py | 14 +++
.../license_exceptions/routes.py | 10 ++
.../reference_data/material_types/routes.py | 12 ++
.../reference_data/payment_methods/routes.py | 11 ++
.../reference_data/pedimento_codes/routes.py | 11 ++
.../pedimento_regimens/routes.py | 11 ++
.../pedimento_transport_catalog/routes.py | 15 ++-
.../public/reference_data/states/routes.py | 11 ++
.../reference_data/trailer_types/routes.py | 3 +-
.../reference_data/trailer_types/services.py | 13 ++-
.../reference_data/transport_modes/routes.py | 11 ++
.../reference_data/transport_types/routes.py | 11 ++
.../valuation_methods/routes.py | 11 ++
.../api/dashboard/reference_data/sectors.ts | 2 +-
.../reference_data/sectors/columns.ts | 9 +-
.../sectors/data-table-actions.svelte | 50 ++++----
.../reference_data/sectors/+page.svelte | 110 ++++++++++++++++--
27 files changed, 387 insertions(+), 40 deletions(-)
diff --git a/backend/api/v1/modules/a76/general_catalogs/sectors/service.py b/backend/api/v1/modules/a76/general_catalogs/sectors/service.py
index 6d1ec4ee..fea918cd 100644
--- a/backend/api/v1/modules/a76/general_catalogs/sectors/service.py
+++ b/backend/api/v1/modules/a76/general_catalogs/sectors/service.py
@@ -8,6 +8,7 @@ from typing import Any, Dict, List, Optional, Tuple
from fastapi import HTTPException
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from . import dto, models
@@ -33,6 +34,14 @@ class SectorService:
)
if filters:
+ if filters.get("search"):
+ search_term = f"%{filters['search']}%"
+ query = query.filter(
+ or_(
+ models.Sector.key.ilike(search_term),
+ models.Sector.description.ilike(search_term)
+ )
+ )
if filters.get("key"):
query = query.filter(
models.Sector.key.ilike(f"%{filters['key']}%")
diff --git a/backend/api/v1/modules/public/reference_data/agency_tariff_codes/routes.py b/backend/api/v1/modules/public/reference_data/agency_tariff_codes/routes.py
index 40bb035f..89cb4220 100644
--- a/backend/api/v1/modules/public/reference_data/agency_tariff_codes/routes.py
+++ b/backend/api/v1/modules/public/reference_data/agency_tariff_codes/routes.py
@@ -18,12 +18,25 @@ async def list_agency_tariff_codes(
page_size: int = Query(50, ge=1, le=1000, description="Tamaño de página"),
agency: str = Query(None, description="Filtrar por código de agencia"),
q: str = Query(None, description="Búsqueda general"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(AgencyTariffCode)
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ AgencyTariffCode.tariff_flag_code.ilike(search_filter),
+ AgencyTariffCode.agency_code.ilike(search_filter),
+ AgencyTariffCode.requirement_level.ilike(search_filter),
+ AgencyTariffCode.program_code.ilike(search_filter),
+ AgencyTariffCode.definition.ilike(search_filter)
+ )
+ )
+
if agency:
query = query.filter(AgencyTariffCode.agency_code == agency)
diff --git a/backend/api/v1/modules/public/reference_data/carta_porte_codes/routes.py b/backend/api/v1/modules/public/reference_data/carta_porte_codes/routes.py
index 28429a4f..38a2f213 100644
--- a/backend/api/v1/modules/public/reference_data/carta_porte_codes/routes.py
+++ b/backend/api/v1/modules/public/reference_data/carta_porte_codes/routes.py
@@ -18,12 +18,22 @@ async def list_carta_porte(
page: int = Query(1, ge=1),
page_size: int = Query(50, ge=1, le=100),
q: str = Query(None, description="Buscar por código o descripción"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(CartaPorte)
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ CartaPorte.code.ilike(search_filter),
+ CartaPorte.description.ilike(search_filter)
+ )
+ )
+
if q:
search_filter = f"%{q}%"
query = query.filter(
diff --git a/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py b/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py
index 6d421350..03f5efd7 100644
--- a/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py
+++ b/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import CodePedimentoRegimenDTO
from .models import CodePedimentoRegimen
@@ -18,11 +19,20 @@ def list_code_pedimento_regimens(
code: str = Query(None, description="Filter by code"),
regime: str = Query(None, description="Filter by regime"),
type: str = Query(None, description="Filter by type"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(CodePedimentoRegimen)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ CodePedimentoRegimen.pedimento_code.ilike(search_filter)
+ )
+ )
if code is not None:
query = query.filter(CodePedimentoRegimen.pedimento_code == code)
diff --git a/backend/api/v1/modules/public/reference_data/containers/routes.py b/backend/api/v1/modules/public/reference_data/containers/routes.py
index ea0f18e1..7182f848 100644
--- a/backend/api/v1/modules/public/reference_data/containers/routes.py
+++ b/backend/api/v1/modules/public/reference_data/containers/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import ContainerDTO
from .models import Container
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/containers")
async def list_containers(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(Container)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ Container.key.ilike(search_filter),
+ Container.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/currency_types/routes.py b/backend/api/v1/modules/public/reference_data/currency_types/routes.py
index 988bf086..6d860ba3 100644
--- a/backend/api/v1/modules/public/reference_data/currency_types/routes.py
+++ b/backend/api/v1/modules/public/reference_data/currency_types/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import CurrencyTypeDTO
from .models import CurrencyType
@@ -15,11 +16,22 @@ router = APIRouter(prefix="/currency-types")
async def list_currency_types(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(CurrencyType)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ CurrencyType.code.ilike(search_filter),
+ CurrencyType.currency_name.ilike(search_filter),
+ CurrencyType.country_description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/customs_sections/routes.py b/backend/api/v1/modules/public/reference_data/customs_sections/routes.py
index 62ceac7c..767462d3 100644
--- a/backend/api/v1/modules/public/reference_data/customs_sections/routes.py
+++ b/backend/api/v1/modules/public/reference_data/customs_sections/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import CustomsSectionDTO
from .models import CustomsSection
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/customs-sections")
def list_customs_sections(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(CustomsSection)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ CustomsSection.code.ilike(search_filter),
+ CustomsSection.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py b/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py
index 802e1c9c..03947cd0 100644
--- a/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py
+++ b/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import CustomsWarehouseDTO
from .models import CustomsWarehouse
@@ -15,11 +16,22 @@ router = APIRouter(prefix="/customs-warehouses")
def list_customs_warehouses(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(CustomsWarehouse)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ CustomsWarehouse.key.ilike(search_filter),
+ CustomsWarehouse.customs.ilike(search_filter),
+ CustomsWarehouse.fiscalized_warehouse.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/identifiers/routes.py b/backend/api/v1/modules/public/reference_data/identifiers/routes.py
index 9f8c012c..b2263881 100644
--- a/backend/api/v1/modules/public/reference_data/identifiers/routes.py
+++ b/backend/api/v1/modules/public/reference_data/identifiers/routes.py
@@ -18,12 +18,24 @@ async def list_identifiers(
page_size: int = Query(50, ge=1, le=1000, description="Tamaño de página"),
level: str = Query(None, description="Filtrar por nivel (G o P)"),
q: str = Query(None, description="Búsqueda general"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(IdentifierCatalog)
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ IdentifierCatalog.key.ilike(search_filter),
+ IdentifierCatalog.description.ilike(search_filter),
+ IdentifierCatalog.level.ilike(search_filter),
+ IdentifierCatalog.complement.ilike(search_filter)
+ )
+ )
+
if level:
query = query.filter(IdentifierCatalog.nivel == level)
diff --git a/backend/api/v1/modules/public/reference_data/incoterms/routes.py b/backend/api/v1/modules/public/reference_data/incoterms/routes.py
index 261cfddc..6661e334 100644
--- a/backend/api/v1/modules/public/reference_data/incoterms/routes.py
+++ b/backend/api/v1/modules/public/reference_data/incoterms/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import IncotermDTO
from .models import Incoterm
@@ -17,12 +18,23 @@ async def list_incoterms(
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
code: str = Query(None, description="Filtrar por clave"),
description: str = Query(None, description="Filtrar por descripción"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(Incoterm)
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ Incoterm.code.ilike(search_filter),
+ Incoterm.description_es.ilike(search_filter),
+ Incoterm.description_en.ilike(search_filter)
+ )
+ )
+
if code:
query = query.filter(Incoterm.code.ilike(f"%{code}%"))
if description:
diff --git a/backend/api/v1/modules/public/reference_data/invoice_types/routes.py b/backend/api/v1/modules/public/reference_data/invoice_types/routes.py
index e0ce0866..c2b34297 100644
--- a/backend/api/v1/modules/public/reference_data/invoice_types/routes.py
+++ b/backend/api/v1/modules/public/reference_data/invoice_types/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import InvoiceTypeDTO
from .models import InvoiceType
@@ -17,9 +18,22 @@ def list_invoice_types(
page_size: int = Query(50, ge=1, le=100),
type: Optional[str] = Query(None, description="Filter by type"),
operation: Optional[str] = Query(None, description="Filter by operation type (imp, exp, both)"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
):
query = db.query(InvoiceType)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ InvoiceType.key.ilike(search_filter),
+ InvoiceType.description.ilike(search_filter),
+ InvoiceType.note.ilike(search_filter),
+ InvoiceType.type.ilike(search_filter),
+ InvoiceType.operation.ilike(search_filter)
+ )
+ )
# Filter by operation if provided
if operation:
diff --git a/backend/api/v1/modules/public/reference_data/license_exceptions/routes.py b/backend/api/v1/modules/public/reference_data/license_exceptions/routes.py
index 0c41fffa..c98a2eee 100644
--- a/backend/api/v1/modules/public/reference_data/license_exceptions/routes.py
+++ b/backend/api/v1/modules/public/reference_data/license_exceptions/routes.py
@@ -17,12 +17,22 @@ async def list_license_exceptions(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=1000, description="Tamaño de página"),
q: str = Query(None, description="Búsqueda general"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(LicenseException)
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ LicenseException.key.ilike(search_filter),
+ LicenseException.description.ilike(search_filter)
+ )
+ )
+
if q:
search_term = f"%{q}%"
query = query.filter(
diff --git a/backend/api/v1/modules/public/reference_data/material_types/routes.py b/backend/api/v1/modules/public/reference_data/material_types/routes.py
index 159778bf..b3982a93 100644
--- a/backend/api/v1/modules/public/reference_data/material_types/routes.py
+++ b/backend/api/v1/modules/public/reference_data/material_types/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import MaterialTypeDTO
from .models import MaterialType
@@ -16,12 +17,23 @@ async def list_material_types(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=1000, description="Tamaño de página"),
type: str = Query(None, description="Filtrar por tipo (ACTIVO FIJO, MATERIALES, PRODUCTOS)"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(MaterialType)
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ MaterialType.key.ilike(search_filter),
+ MaterialType.type.ilike(search_filter),
+ MaterialType.description.ilike(search_filter)
+ )
+ )
+
# Aplicar filtro por tipo si se proporciona
if type:
query = query.filter(MaterialType.type == type)
diff --git a/backend/api/v1/modules/public/reference_data/payment_methods/routes.py b/backend/api/v1/modules/public/reference_data/payment_methods/routes.py
index 465630fc..3e728f4b 100644
--- a/backend/api/v1/modules/public/reference_data/payment_methods/routes.py
+++ b/backend/api/v1/modules/public/reference_data/payment_methods/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import PaymentMethodDTO
from .models import PaymentMethod
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/payment-methods")
def list_payment_methods(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(PaymentMethod)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ PaymentMethod.key.ilike(search_filter),
+ PaymentMethod.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py b/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py
index 93b188f6..0d7aa39e 100644
--- a/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py
+++ b/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import PedimentoCodeDTO
from .models import PedimentoCode
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/pedimento-codes")
def list_pedimento_codes(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=1000, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(PedimentoCode)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ PedimentoCode.code.ilike(search_filter),
+ PedimentoCode.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py b/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py
index d788510d..678fa194 100644
--- a/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py
+++ b/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import RegimenPedimentoDTO
from .models import RegimenPedimento
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/pedimento-regimens")
def list_pedimento_regimens(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(RegimenPedimento)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ RegimenPedimento.code.ilike(search_filter),
+ RegimenPedimento.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/pedimento_transport_catalog/routes.py b/backend/api/v1/modules/public/reference_data/pedimento_transport_catalog/routes.py
index a8667238..e3a0db27 100644
--- a/backend/api/v1/modules/public/reference_data/pedimento_transport_catalog/routes.py
+++ b/backend/api/v1/modules/public/reference_data/pedimento_transport_catalog/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import PedimentoTransportCatalogDTO
from .models import PedimentoTransportCatalog
@@ -15,10 +16,22 @@ router = APIRouter(prefix="/pedimento-transport-catalog")
async def list_pedimento_transport_catalog(
page: int = Query(1, ge=1, description="Numero de pagina"),
page_size: int = Query(100, ge=1, le=200, description="Tamano de pagina"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
):
skip = (page - 1) * page_size
- query = db.query(PedimentoTransportCatalog).order_by(PedimentoTransportCatalog.code.asc())
+ query = db.query(PedimentoTransportCatalog)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ PedimentoTransportCatalog.code.ilike(search_filter),
+ PedimentoTransportCatalog.transport_en.ilike(search_filter),
+ PedimentoTransportCatalog.transport_es.ilike(search_filter),
+ PedimentoTransportCatalog.payment_date_code.ilike(search_filter)
+ )
+ ).order_by(PedimentoTransportCatalog.code.asc())
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/states/routes.py b/backend/api/v1/modules/public/reference_data/states/routes.py
index 151c1172..52d09f53 100644
--- a/backend/api/v1/modules/public/reference_data/states/routes.py
+++ b/backend/api/v1/modules/public/reference_data/states/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import StateDTO
from .models import State
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/states")
async def list_states(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(State)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ State.m3_key.ilike(search_filter),
+ State.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/trailer_types/routes.py b/backend/api/v1/modules/public/reference_data/trailer_types/routes.py
index 5e0ba35e..e74ab634 100644
--- a/backend/api/v1/modules/public/reference_data/trailer_types/routes.py
+++ b/backend/api/v1/modules/public/reference_data/trailer_types/routes.py
@@ -13,10 +13,11 @@ router = APIRouter()
def list_trailer_types(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
):
skip = (page - 1) * page_size
- items, total = services.TrailerTypeService.list_trailer_types(db, skip, page_size)
+ items, total = services.TrailerTypeService.list_trailer_types(db, skip, page_size, search)
return {
"items": [dto.TrailerTypeListItemDTO.model_validate(obj) for obj in items],
"total": total,
diff --git a/backend/api/v1/modules/public/reference_data/trailer_types/services.py b/backend/api/v1/modules/public/reference_data/trailer_types/services.py
index 577637e5..d36f3e3d 100644
--- a/backend/api/v1/modules/public/reference_data/trailer_types/services.py
+++ b/backend/api/v1/modules/public/reference_data/trailer_types/services.py
@@ -1,6 +1,7 @@
from typing import List, Tuple
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from . import dto, models
@@ -8,9 +9,19 @@ from . import dto, models
class TrailerTypeService:
@staticmethod
def list_trailer_types(
- db: Session, skip: int = 0, limit: int = 50
+ db: Session, skip: int = 0, limit: int = 50, search: str = None
) -> Tuple[List[models.TrailerType], int]:
q = db.query(models.TrailerType).order_by(models.TrailerType.trailer_type_key)
+
+ if search:
+ search_filter = f"%{search}%"
+ q = q.filter(
+ or_(
+ models.TrailerType.trailer_type_key.ilike(search_filter),
+ models.TrailerType.description.ilike(search_filter)
+ )
+ )
+
total = q.count()
items = q.offset(skip).limit(limit).all()
return items, total
diff --git a/backend/api/v1/modules/public/reference_data/transport_modes/routes.py b/backend/api/v1/modules/public/reference_data/transport_modes/routes.py
index 25a22036..cfe4405d 100644
--- a/backend/api/v1/modules/public/reference_data/transport_modes/routes.py
+++ b/backend/api/v1/modules/public/reference_data/transport_modes/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import TransportModeDTO
from .models import TransportMode
@@ -15,10 +16,20 @@ router = APIRouter(prefix="/transport-modes")
async def list_transport_modes(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
):
skip = (page - 1) * page_size
query = db.query(TransportMode)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ TransportMode.key.ilike(search_filter),
+ TransportMode.name.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/transport_types/routes.py b/backend/api/v1/modules/public/reference_data/transport_types/routes.py
index 69bf624e..563d5e0b 100644
--- a/backend/api/v1/modules/public/reference_data/transport_types/routes.py
+++ b/backend/api/v1/modules/public/reference_data/transport_types/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import TransportTypeDTO
from .models import TransportType
@@ -15,10 +16,20 @@ router = APIRouter(prefix="/transport-types")
def list_transport_types(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
):
skip = (page - 1) * page_size
query = db.query(TransportType)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ TransportType.transport_code.ilike(search_filter),
+ TransportType.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py b/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py
index 4742609d..e0f7c65d 100644
--- a/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py
+++ b/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py
@@ -4,6 +4,7 @@ from core.database import get_core_db
from core.security import get_current_user, has_role
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
+from sqlalchemy import or_
from .dto import ValuationMethodDTO
from .models import ValuationMethod
@@ -15,11 +16,21 @@ router = APIRouter(prefix="/valuation-methods")
async def list_valuation_methods(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
+ search: str = Query(None, description="Término de búsqueda"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(ValuationMethod)
+
+ if search:
+ search_filter = f"%{search}%"
+ query = query.filter(
+ or_(
+ ValuationMethod.key.ilike(search_filter),
+ ValuationMethod.description.ilike(search_filter)
+ )
+ )
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {
diff --git a/frontend/src/lib/api/dashboard/reference_data/sectors.ts b/frontend/src/lib/api/dashboard/reference_data/sectors.ts
index d36a26eb..43b9c72b 100644
--- a/frontend/src/lib/api/dashboard/reference_data/sectors.ts
+++ b/frontend/src/lib/api/dashboard/reference_data/sectors.ts
@@ -40,7 +40,7 @@ export const sectorsApi = {
page_size: pageSize.toString(),
company_id: companyId.toString()
});
- if (search) params.append('key', search);
+ if (search) params.append('search', search);
return api.get(`/v1/a76/sectors/?${params.toString()}`);
},
diff --git a/frontend/src/lib/components/dashboard/reference_data/sectors/columns.ts b/frontend/src/lib/components/dashboard/reference_data/sectors/columns.ts
index 9392d3aa..ba15fc57 100644
--- a/frontend/src/lib/components/dashboard/reference_data/sectors/columns.ts
+++ b/frontend/src/lib/components/dashboard/reference_data/sectors/columns.ts
@@ -1,7 +1,6 @@
import type { ColumnDef } from "@tanstack/table-core";
-import { renderComponent, renderSnippet } from "$lib/components/ui/data-table/index.js";
+import { renderSnippet } from "$lib/components/ui/data-table/index.js";
import { createRawSnippet } from "svelte";
-import DataTableActions from "./data-table-actions.svelte";
export type Sector = {
id: number;
@@ -56,12 +55,6 @@ export function createColumns(onSuccess?: () => void): ColumnDef[] {
});
return renderSnippet(authSnippet, { authorized: row.original.authorized });
}
- },
- {
- id: "actions",
- cell: ({ row }) => {
- return renderComponent(DataTableActions, { item: row.original, onSuccess });
- }
}
];
}
diff --git a/frontend/src/lib/components/dashboard/reference_data/sectors/data-table-actions.svelte b/frontend/src/lib/components/dashboard/reference_data/sectors/data-table-actions.svelte
index bf90e548..49013bc0 100644
--- a/frontend/src/lib/components/dashboard/reference_data/sectors/data-table-actions.svelte
+++ b/frontend/src/lib/components/dashboard/reference_data/sectors/data-table-actions.svelte
@@ -1,5 +1,6 @@
-
-
- {#snippet child({ props })}
-
- {/snippet}
-
-
-
- Acciones
-
- Copiar Clave
-
-
-
- Ver detalles
- Editar
-
-
+
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
+ Acciones
+
+ Copiar Clave
+
+
+
+ Ver detalles
+ Editar
+
+
+
diff --git a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte
index 8d722ad7..c155863d 100644
--- a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte
+++ b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte
@@ -2,14 +2,15 @@
import { onMount } from 'svelte';
import { sectorsApi, type Sector } from '$lib/api/dashboard/reference_data/sectors';
import { companyStore } from '$lib/stores/company.svelte';
- import DataTable from '$lib/components/dashboard/reference_data/sectors/data-table.svelte';
+ import InfiniteDataTable from '$lib/components/dashboard/common/infinite-data-table.svelte';
+ import CreateEditDialog from '$lib/components/dashboard/reference_data/sectors/create-edit-dialog.svelte';
import { createColumns } from '$lib/components/dashboard/reference_data/sectors/columns.js';
import * as Card from '$lib/components/ui/card';
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import { page } from '$app/stores';
import { browser } from '$app/environment';
- import { RefreshCw } from 'lucide-svelte';
+ import { RefreshCw, Plus, Pencil } from 'lucide-svelte';
import { useShortcuts } from '$lib/hooks/use-shortcuts';
import type { PageData } from './$types';
@@ -31,7 +32,7 @@
}
});
- // Estado para infinite scroll
+ // Estado para infinite scroll y seleccion
let allItems = $state(data.items || []);
let currentPage = $state(data.page || 1);
let pageSize = $state(50);
@@ -39,6 +40,13 @@
let loading = $state(false);
let hasMore = $derived(allItems.length < totalItems);
let error = $state(data.error || null);
+
+ let createDialogOpen = $state(false);
+ let editingItem = $state(null);
+ let selectedIds = $state<(string | number)[]>([]);
+ const selectedSector = $derived(
+ selectedIds.length === 1 ? allItems.find((s) => s.id === selectedIds[0]) : null
+ );
// Filtros
let searchQuery = $state($page.url.searchParams.get('search') || '');
@@ -123,11 +131,48 @@
}
function handleSuccess() {
+ createDialogOpen = false;
+ editingItem = null;
reloadData();
}
+ function handleRowDoubleClick(row: Sector) {
+ editingItem = row;
+ createDialogOpen = true;
+ }
+
+ function handleRowClick(row: Sector) {
+ const id = row.id;
+ if (selectedIds.includes(id)) {
+ selectedIds = selectedIds.filter((i) => i !== id);
+ } else {
+ selectedIds = [id]; // Selección única
+ }
+ }
+
+ function handleEditSelected() {
+ if (selectedSector) {
+ editingItem = selectedSector;
+ createDialogOpen = true;
+ }
+ }
+
+ $effect(() => {
+ if (!createDialogOpen) {
+ editingItem = null;
+ }
+ });
+
useShortcuts('Sectores', [
- { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData }
+ { key: 'Alt+Shift+R', description: 'Actualizar Lista', action: reloadData },
+ {
+ key: 'Ctrl+S',
+ description: 'Guardar',
+ action: () => {
+ if (!createDialogOpen) return;
+ document.dispatchEvent(new CustomEvent('save-form'));
+ }
+ }
]);
const columns = createColumns(handleSuccess);
@@ -144,6 +189,12 @@
Gestiona los sectores económicos del sistema
+
+
+
{#if error}
@@ -152,10 +203,55 @@
{/if}
-
-
-
+
+
+
+
Listado de Sectores
+
+
+
+
+
+
+
+ (selectedIds = ids)}
+ onRowClick={handleRowClick}
+ onRowDoubleClick={handleRowDoubleClick}
+ />
+
+
Mostrando {allItems.length} de {totalItems} registros
+
+
+
+
+
+
+