From 73b2eb222e58e7d1e322cef2966fccff20fbc30b Mon Sep 17 00:00:00 2001 From: hreyes Date: Wed, 6 May 2026 08:13:53 -0600 Subject: [PATCH] feature/permisos-reference-data --- .../v1/modules/a76/doc_types_dig/routes.py | 7 +- .../a76/general_catalogs/sectors/routes.py | 4 +- .../agency_tariff_codes/routes.py | 13 ++- .../carta_porte_codes/routes.py | 13 ++- .../code_pedimento_regimens/routes.py | 13 ++- .../reference_data/containers/routes.py | 13 ++- .../public/reference_data/countries/routes.py | 15 +++- .../reference_data/currency_types/routes.py | 13 ++- .../reference_data/customs_sections/routes.py | 13 ++- .../customs_warehouses/routes.py | 13 ++- .../reference_data/identifiers/routes.py | 13 ++- .../public/reference_data/incoterms/routes.py | 13 ++- .../reference_data/invoice_types/routes.py | 13 ++- .../license_exceptions/routes.py | 13 ++- .../reference_data/material_types/routes.py | 13 ++- .../reference_data/payment_methods/routes.py | 13 ++- .../reference_data/pedimento_codes/routes.py | 13 ++- .../pedimento_regimens/routes.py | 13 ++- .../pedimento_transport_catalog/routes.py | 13 ++- .../v1/modules/public/reference_data/rbac.py | 25 ++++++ .../public/reference_data/states/routes.py | 13 ++- .../reference_data/trailer_types/routes.py | 11 ++- .../reference_data/transport_modes/routes.py | 13 ++- .../reference_data/transport_types/routes.py | 13 ++- .../valuation_methods/routes.py | 13 ++- .../src/lib/components/sidebar/modules.ts | 25 +++++- .../code_pedimento_regimens/+page.svelte | 6 +- .../reference_data/containers/+page.svelte | 6 +- .../reference_data/countries/+page.svelte | 8 +- .../currency_types/+page.svelte | 8 +- .../customs_sections/+page.svelte | 6 +- .../customs_warehouses/+page.svelte | 8 +- .../+page.server.ts | 36 +++++--- .../document_types_digitization/+page.svelte | 85 +++++++++++-------- .../reference_data/incoterms/+page.svelte | 25 ++++-- .../reference_data/invoice_types/+page.svelte | 8 +- .../material_types/+page.svelte | 4 +- .../payment_methods/+page.svelte | 6 +- .../pedimento_codes/+page.svelte | 4 +- .../pedimento_regimens/+page.svelte | 6 +- .../reference_data/sectors/+page.svelte | 6 +- .../reference_data/states/+page.svelte | 4 +- .../transport_modes/+page.svelte | 6 +- .../transport_types/+page.svelte | 4 +- .../valuation_methods/+page.svelte | 8 +- 45 files changed, 437 insertions(+), 154 deletions(-) create mode 100644 backend/api/v1/modules/public/reference_data/rbac.py diff --git a/backend/api/v1/modules/a76/doc_types_dig/routes.py b/backend/api/v1/modules/a76/doc_types_dig/routes.py index ca229671..5dc43488 100644 --- a/backend/api/v1/modules/a76/doc_types_dig/routes.py +++ b/backend/api/v1/modules/a76/doc_types_dig/routes.py @@ -10,6 +10,7 @@ from .dto import DocumentTypeDigitizationResponse from .service import DocumentTypeDigitizationService router = APIRouter(prefix='/document-types-digitization', tags=['Document Types Digitization']) +VIEW_PERMISSION = ['ref_invoice_types.view'] @router.get('/', response_model=Dict[str, Any]) @@ -24,7 +25,7 @@ async def list_document_types( db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user), ): - tenant_id = validate_access_to_resource(db, company_id, current_user) + tenant_id = validate_access_to_resource(db, company_id, current_user, VIEW_PERMISSION) skip = (page - 1) * page_size filters: Dict[str, Any] = {} @@ -59,7 +60,7 @@ async def get_document_type( db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user), ): - tenant_id = validate_access_to_resource(db, company_id, current_user) + tenant_id = validate_access_to_resource(db, company_id, current_user, VIEW_PERMISSION) document_type = DocumentTypeDigitizationService.get_by_id( db, document_type_id, @@ -83,7 +84,7 @@ async def get_document_type_by_code( db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user), ): - tenant_id = validate_access_to_resource(db, company_id, current_user) + tenant_id = validate_access_to_resource(db, company_id, current_user, VIEW_PERMISSION) document_type = DocumentTypeDigitizationService.get_by_code( db, code, diff --git a/backend/api/v1/modules/a76/general_catalogs/sectors/routes.py b/backend/api/v1/modules/a76/general_catalogs/sectors/routes.py index 60398a89..331a7455 100644 --- a/backend/api/v1/modules/a76/general_catalogs/sectors/routes.py +++ b/backend/api/v1/modules/a76/general_catalogs/sectors/routes.py @@ -20,8 +20,8 @@ router = TenantCRUDRoutes( enable_filters=True, default_page_size=50, max_page_size=100, - list_permissions=["cat_sectors.view"], - get_permissions=["cat_sectors.view"], + list_permissions=["ref_sectors.view"], + get_permissions=["ref_sectors.view"], create_permissions=["cat_sectors.create"], update_permissions=["cat_sectors.edit"], delete_permissions=["cat_sectors.delete"], 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 89cb4220..a4300667 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 @@ -8,11 +8,16 @@ from sqlalchemy.orm import Session from .dto import AgencyTariffCodeDTO from .models import AgencyTariffCode +from ..rbac import require_ref_view router = APIRouter(prefix="/agency-tariff-codes") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_pedimento_codes.view"))], +) async def list_agency_tariff_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"), @@ -61,7 +66,11 @@ async def list_agency_tariff_codes( } -@router.get("/{id}", response_model=AgencyTariffCodeDTO) +@router.get( + "/{id}", + response_model=AgencyTariffCodeDTO, + dependencies=[Depends(require_ref_view("ref_pedimento_codes.view"))], +) async def get_agency_tariff_code( id: int, db: Session = Depends(get_core_db), 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 38a2f213..c95bb0cf 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 @@ -9,11 +9,16 @@ from sqlalchemy.orm import Session from .dto import CartaPorteDTO from .models import CartaPorte +from ..rbac import require_ref_view router = APIRouter(prefix="/carta-porte") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_transport_types.view"))], +) async def list_carta_porte( page: int = Query(1, ge=1), page_size: int = Query(50, ge=1, le=100), @@ -55,7 +60,11 @@ async def list_carta_porte( } -@router.get("/{id}", response_model=CartaPorteDTO) +@router.get( + "/{id}", + response_model=CartaPorteDTO, + dependencies=[Depends(require_ref_view("ref_transport_types.view"))], +) async def get_carta_porte( id: int, db: Session = Depends(get_core_db), 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 03f5efd7..c8ca4618 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import CodePedimentoRegimenDTO from .models import CodePedimentoRegimen +from ..rbac import require_ref_view router = APIRouter(prefix="/code-pedimento-regimens") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_pedimento_regimens.view"))], +) def list_code_pedimento_regimens( 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"), @@ -51,7 +56,11 @@ def list_code_pedimento_regimens( } -@router.get("/{id}", response_model=CodePedimentoRegimenDTO) +@router.get( + "/{id}", + response_model=CodePedimentoRegimenDTO, + dependencies=[Depends(require_ref_view("ref_pedimento_regimens.view"))], +) def get_code_pedimento_regimen( id: int, db: Session = Depends(get_core_db), 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 7182f848..be6659f0 100644 --- a/backend/api/v1/modules/public/reference_data/containers/routes.py +++ b/backend/api/v1/modules/public/reference_data/containers/routes.py @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import ContainerDTO from .models import Container +from ..rbac import require_ref_view router = APIRouter(prefix="/containers") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_containers.view"))], +) 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"), @@ -41,7 +46,11 @@ async def list_containers( } -@router.get("/{key}", response_model=ContainerDTO) +@router.get( + "/{key}", + response_model=ContainerDTO, + dependencies=[Depends(require_ref_view("ref_containers.view"))], +) async def get_container( key: str, db: Session = Depends(get_core_db), diff --git a/backend/api/v1/modules/public/reference_data/countries/routes.py b/backend/api/v1/modules/public/reference_data/countries/routes.py index 45d76eea..28550fa6 100644 --- a/backend/api/v1/modules/public/reference_data/countries/routes.py +++ b/backend/api/v1/modules/public/reference_data/countries/routes.py @@ -7,18 +7,23 @@ from sqlalchemy.orm import Session from .dto import CountryDTO from .models import Country +from ..rbac import require_ref_view router = APIRouter(prefix="/countries") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_countries.view"))], +) async def list_countries( 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), ): - """Endpoint público para obtener lista de países - no requiere autenticación""" + """Lista de países protegida por permiso ref_countries.view""" skip = (page - 1) * page_size query = db.query(Country) @@ -43,7 +48,11 @@ async def list_countries( } -@router.get("/{m3_key}", response_model=CountryDTO) +@router.get( + "/{m3_key}", + response_model=CountryDTO, + dependencies=[Depends(require_ref_view("ref_countries.view"))], +) async def get_country( m3_key: str, db: Session = Depends(get_core_db), 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 6d860ba3..bf658a36 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import CurrencyTypeDTO from .models import CurrencyType +from ..rbac import require_ref_view router = APIRouter(prefix="/currency-types") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_currency_types.view"))], +) 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"), @@ -42,7 +47,11 @@ async def list_currency_types( } -@router.get("/{code}", response_model=CurrencyTypeDTO) +@router.get( + "/{code}", + response_model=CurrencyTypeDTO, + dependencies=[Depends(require_ref_view("ref_currency_types.view"))], +) async def get_currency_type( code: str, db: Session = Depends(get_core_db), 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 767462d3..e6710d8f 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import CustomsSectionDTO from .models import CustomsSection +from ..rbac import require_ref_view router = APIRouter(prefix="/customs-sections") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_customs_sections.view"))], +) 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"), @@ -41,7 +46,11 @@ def list_customs_sections( } -@router.get("/{customs_code}", response_model=CustomsSectionDTO) +@router.get( + "/{customs_code}", + response_model=CustomsSectionDTO, + dependencies=[Depends(require_ref_view("ref_customs_sections.view"))], +) def get_customs_section( customs_code: str, db: Session = Depends(get_core_db), 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 03947cd0..3e7211e3 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import CustomsWarehouseDTO from .models import CustomsWarehouse +from ..rbac import require_ref_view router = APIRouter(prefix="/customs-warehouses") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_customs_warehouses.view"))], +) 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"), @@ -42,7 +47,11 @@ def list_customs_warehouses( } -@router.get("/{key}/{customs}", response_model=CustomsWarehouseDTO) +@router.get( + "/{key}/{customs}", + response_model=CustomsWarehouseDTO, + dependencies=[Depends(require_ref_view("ref_customs_warehouses.view"))], +) def get_customs_warehouse( key: str, customs: str, 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 b2263881..1b6594b7 100644 --- a/backend/api/v1/modules/public/reference_data/identifiers/routes.py +++ b/backend/api/v1/modules/public/reference_data/identifiers/routes.py @@ -8,11 +8,16 @@ from sqlalchemy.orm import Session from .dto import IdentifierDTO from .models import IdentifierCatalog +from ..rbac import require_ref_view router = APIRouter(prefix="/identifiers") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("cat_identifiers.view"))], +) async def list_identifiers( 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"), @@ -59,7 +64,11 @@ async def list_identifiers( } -@router.get("/{key}", response_model=IdentifierDTO) +@router.get( + "/{key}", + response_model=IdentifierDTO, + dependencies=[Depends(require_ref_view("cat_identifiers.view"))], +) async def get_identifier( key: str, db: Session = Depends(get_core_db), 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 6661e334..634ac861 100644 --- a/backend/api/v1/modules/public/reference_data/incoterms/routes.py +++ b/backend/api/v1/modules/public/reference_data/incoterms/routes.py @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import IncotermDTO from .models import Incoterm +from ..rbac import require_ref_view router = APIRouter(prefix="/incoterms") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_incoterms.view"))], +) async def list_incoterms( 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"), @@ -53,7 +58,11 @@ async def list_incoterms( } -@router.get("/{key}", response_model=IncotermDTO) +@router.get( + "/{key}", + response_model=IncotermDTO, + dependencies=[Depends(require_ref_view("ref_incoterms.view"))], +) async def get_incoterm( key: str, db: Session = Depends(get_core_db), 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 c2b34297..9fb47e3d 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import InvoiceTypeDTO from .models import InvoiceType +from ..rbac import require_ref_view router = APIRouter(prefix="/invoice-types") -@router.get("/", response_model=dict) +@router.get( + "/", + response_model=dict, + dependencies=[Depends(require_ref_view("ref_invoice_types.view"))], +) def list_invoice_types( page: int = Query(1, ge=1), page_size: int = Query(50, ge=1, le=100), @@ -55,7 +60,11 @@ def list_invoice_types( } -@router.get("/{key}", response_model=InvoiceTypeDTO) +@router.get( + "/{key}", + response_model=InvoiceTypeDTO, + dependencies=[Depends(require_ref_view("ref_invoice_types.view"))], +) def get_invoice_type( key: str, db: Session = Depends(get_core_db), 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 c98a2eee..c04dfbc0 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 @@ -8,11 +8,16 @@ from sqlalchemy.orm import Session from .dto import LicenseExceptionDTO from .models import LicenseException +from ..rbac import require_ref_view router = APIRouter(prefix="/license-exceptions") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_pedimento_regimens.view"))], +) 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"), @@ -52,7 +57,11 @@ async def list_license_exceptions( } -@router.get("/{key}", response_model=LicenseExceptionDTO) +@router.get( + "/{key}", + response_model=LicenseExceptionDTO, + dependencies=[Depends(require_ref_view("ref_pedimento_regimens.view"))], +) async def get_license_exception( key: str, db: Session = Depends(get_core_db), 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 b3982a93..94948c85 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import MaterialTypeDTO from .models import MaterialType +from ..rbac import require_ref_view router = APIRouter(prefix="/material-types") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_material_types.view"))], +) 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"), @@ -48,7 +53,11 @@ async def list_material_types( } -@router.get("/{key}", response_model=MaterialTypeDTO) +@router.get( + "/{key}", + response_model=MaterialTypeDTO, + dependencies=[Depends(require_ref_view("ref_material_types.view"))], +) async def get_material_type( key: str, db: Session = Depends(get_core_db), 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 3e728f4b..8731f4aa 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import PaymentMethodDTO from .models import PaymentMethod +from ..rbac import require_ref_view router = APIRouter(prefix="/payment-methods") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_payment_methods.view"))], +) 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"), @@ -41,7 +46,11 @@ def list_payment_methods( } -@router.get("/{key}", response_model=PaymentMethodDTO) +@router.get( + "/{key}", + response_model=PaymentMethodDTO, + dependencies=[Depends(require_ref_view("ref_payment_methods.view"))], +) def get_payment_method( key: str, db: Session = Depends(get_core_db), 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 0d7aa39e..9d1bead0 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import PedimentoCodeDTO from .models import PedimentoCode +from ..rbac import require_ref_view router = APIRouter(prefix="/pedimento-codes") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_pedimento_codes.view"))], +) 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"), @@ -41,7 +46,11 @@ def list_pedimento_codes( } -@router.get("/{code}", response_model=PedimentoCodeDTO) +@router.get( + "/{code}", + response_model=PedimentoCodeDTO, + dependencies=[Depends(require_ref_view("ref_pedimento_codes.view"))], +) def get_pedimento_code( code: str, db: Session = Depends(get_core_db), 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 678fa194..a9ca228b 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import RegimenPedimentoDTO from .models import RegimenPedimento +from ..rbac import require_ref_view router = APIRouter(prefix="/pedimento-regimens") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_pedimento_regimens.view"))], +) 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"), @@ -41,7 +46,11 @@ def list_pedimento_regimens( } -@router.get("/{key}", response_model=RegimenPedimentoDTO) +@router.get( + "/{key}", + response_model=RegimenPedimentoDTO, + dependencies=[Depends(require_ref_view("ref_pedimento_regimens.view"))], +) def get_pedimento_regimen( key: str, db: Session = Depends(get_core_db), 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 e3a0db27..18392d80 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import PedimentoTransportCatalogDTO from .models import PedimentoTransportCatalog +from ..rbac import require_ref_view router = APIRouter(prefix="/pedimento-transport-catalog") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_transport_types.view"))], +) 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"), @@ -42,7 +47,11 @@ async def list_pedimento_transport_catalog( } -@router.get("/{code}", response_model=PedimentoTransportCatalogDTO) +@router.get( + "/{code}", + response_model=PedimentoTransportCatalogDTO, + dependencies=[Depends(require_ref_view("ref_transport_types.view"))], +) async def get_pedimento_transport_catalog(code: str, db: Session = Depends(get_core_db)): obj = ( db.query(PedimentoTransportCatalog) diff --git a/backend/api/v1/modules/public/reference_data/rbac.py b/backend/api/v1/modules/public/reference_data/rbac.py new file mode 100644 index 00000000..baf920b7 --- /dev/null +++ b/backend/api/v1/modules/public/reference_data/rbac.py @@ -0,0 +1,25 @@ +from typing import Callable + +from core.database import get_core_db +from core.security import get_current_user, validate_access_to_resource +from fastapi import Depends, Query +from sqlalchemy.orm import Session + + +def require_ref_view(permission_code: str) -> Callable: + """ + Dependency factory to enforce reference-data view permissions per company. + + Endpoints using this dependency must receive `company_id` in query params. + """ + + async def _dep( + company_id: int = Query(..., description="Company ID"), + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user), + ) -> bool: + validate_access_to_resource(db, company_id, current_user, [permission_code]) + return True + + return _dep + 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 52d09f53..79595d33 100644 --- a/backend/api/v1/modules/public/reference_data/states/routes.py +++ b/backend/api/v1/modules/public/reference_data/states/routes.py @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import StateDTO from .models import State +from ..rbac import require_ref_view router = APIRouter(prefix="/states") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_states.view"))], +) 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"), @@ -41,7 +46,11 @@ async def list_states( } -@router.get("/{m3_key}", response_model=StateDTO) +@router.get( + "/{m3_key}", + response_model=StateDTO, + dependencies=[Depends(require_ref_view("ref_states.view"))], +) async def get_state( m3_key: str, db: Session = Depends(get_core_db), 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 e74ab634..9cdbbea5 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 @@ -5,11 +5,16 @@ from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from . import dto, services +from ..rbac import require_ref_view router = APIRouter() -@router.get("/trailer-types/", response_model=Dict[str, Any]) +@router.get( + "/trailer-types/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("trailers.view"))], +) 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"), @@ -27,7 +32,9 @@ def list_trailer_types( @router.get( - "/trailer-types/{trailer_type_key}", response_model=dto.TrailerTypeResponseDTO + "/trailer-types/{trailer_type_key}", + response_model=dto.TrailerTypeResponseDTO, + dependencies=[Depends(require_ref_view("trailers.view"))], ) def get_trailer_type(trailer_type_key: str, db: Session = Depends(get_core_db)): trailer_type = services.TrailerTypeService.get_trailer_type_by_key( 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 cfe4405d..0f480f64 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import TransportModeDTO from .models import TransportMode +from ..rbac import require_ref_view router = APIRouter(prefix="/transport-modes") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_transport_modes.view"))], +) 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"), @@ -40,7 +45,11 @@ async def list_transport_modes( } -@router.get("/{key}", response_model=TransportModeDTO) +@router.get( + "/{key}", + response_model=TransportModeDTO, + dependencies=[Depends(require_ref_view("ref_transport_modes.view"))], +) async def get_transport_mode(key: str, db: Session = Depends(get_core_db)): obj = db.query(TransportMode).filter(TransportMode.key == key).first() if not obj: 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 563d5e0b..fdfc47a9 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import TransportTypeDTO from .models import TransportType +from ..rbac import require_ref_view router = APIRouter(prefix="/transport-types") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_transport_types.view"))], +) 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"), @@ -40,7 +45,11 @@ def list_transport_types( } -@router.get("/{transport_code}", response_model=TransportTypeDTO) +@router.get( + "/{transport_code}", + response_model=TransportTypeDTO, + dependencies=[Depends(require_ref_view("ref_transport_types.view"))], +) def get_transport_type(transport_code: str, db: Session = Depends(get_core_db)): obj = ( db.query(TransportType) 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 e0f7c65d..899f80f3 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 @@ -8,11 +8,16 @@ from sqlalchemy import or_ from .dto import ValuationMethodDTO from .models import ValuationMethod +from ..rbac import require_ref_view router = APIRouter(prefix="/valuation-methods") -@router.get("/", response_model=Dict[str, Any]) +@router.get( + "/", + response_model=Dict[str, Any], + dependencies=[Depends(require_ref_view("ref_valuation_methods.view"))], +) 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"), @@ -41,7 +46,11 @@ async def list_valuation_methods( } -@router.get("/{key}", response_model=ValuationMethodDTO) +@router.get( + "/{key}", + response_model=ValuationMethodDTO, + dependencies=[Depends(require_ref_view("ref_valuation_methods.view"))], +) async def get_valuation_method( key: str, db: Session = Depends(get_core_db), diff --git a/frontend/src/lib/components/sidebar/modules.ts b/frontend/src/lib/components/sidebar/modules.ts index fb38105c..759b6873 100644 --- a/frontend/src/lib/components/sidebar/modules.ts +++ b/frontend/src/lib/components/sidebar/modules.ts @@ -100,14 +100,17 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.reference_data.codes_pedimento_regimen"](), url: "/dashboard/reference_data/code_pedimento_regimens", + permission: "ref_pedimento_regimens.view", }, { title: m["sidebar.reference_data.containers"](), url: "/dashboard/reference_data/containers", + permission: "ref_containers.view", }, { title: m["sidebar.reference_data.countries"](), url: "/dashboard/reference_data/countries", + permission: "ref_countries.view", }, { title: m["sidebar.reference_data.currency_types"](), @@ -117,58 +120,72 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.reference_data.customs_sections"](), url: "/dashboard/reference_data/customs_sections", + permission: "ref_customs_sections.view", }, { title: m["sidebar.reference_data.customs_warehouses"](), url: "/dashboard/reference_data/customs_warehouses", + permission: "ref_customs_warehouses.view", }, { title: m["sidebar.reference_data.incoterms"](), url: "/dashboard/reference_data/incoterms", + permission: "ref_incoterms.view", }, { title: m["sidebar.reference_data.document_types_digitization"](), url: "/dashboard/reference_data/document_types_digitization", + permission: "ref_invoice_types.view", }, { title: m["sidebar.reference_data.invoice_types"](), url: "/dashboard/reference_data/invoice_types", + permission: "ref_invoice_types.view", }, { title: m["sidebar.reference_data.material_types"](), url: "/dashboard/reference_data/material_types", + permission: "ref_material_types.view", }, { title: m["sidebar.reference_data.payment_methods"](), url: "/dashboard/reference_data/payment_methods", + permission: "ref_payment_methods.view", }, { title: m["sidebar.reference_data.pedimento_codes"](), url: "/dashboard/reference_data/pedimento_codes", + permission: "ref_pedimento_codes.view", }, { title: m["sidebar.reference_data.pedimento_regimes"](), url: "/dashboard/reference_data/pedimento_regimens", + permission: "ref_pedimento_regimens.view", }, { title: m["sidebar.reference_data.sectors"](), url: "/dashboard/reference_data/sectors", + permission: "ref_sectors.view", }, { title: m["sidebar.reference_data.states"](), url: "/dashboard/reference_data/states", + permission: "ref_states.view", }, { title: m["sidebar.reference_data.transportation_modes"](), url: "/dashboard/reference_data/transport_modes", + permission: "ref_transport_modes.view", }, { title: m["sidebar.reference_data.transportation_types"](), url: "/dashboard/reference_data/transport_types", + permission: "ref_transport_types.view", }, { title: m["sidebar.reference_data.valuation_methods"](), url: "/dashboard/reference_data/valuation_methods", + permission: "ref_valuation_methods.view", }, ], isActive: false, @@ -206,6 +223,7 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.general_catalogs.incoterms"](), url: "/dashboard/reference_data/incoterms", + permission: "ref_incoterms.view", }, { title: m["sidebar.general_catalogs.inpc"](), @@ -222,10 +240,12 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.general_catalogs.valuation_methods"](), url: "/dashboard/reference_data/valuation_methods", + permission: "ref_valuation_methods.view", }, { title: m["sidebar.general_catalogs.countries"](), url: "/dashboard/reference_data/countries", + permission: "ref_countries.view", }, { title: m["sidebar.general_catalogs.ports"](), @@ -269,6 +289,7 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.general_catalogs.currency_types"](), url: "/dashboard/reference_data/currency_types", + permission: "ref_currency_types.view", }, { title: m["sidebar.general_catalogs.multi_currency"](), @@ -278,6 +299,7 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.general_catalogs.invoice_types"](), url: "/dashboard/reference_data/invoice_types", + permission: "ref_invoice_types.view", }, { title: m["sidebar.general_catalogs.electronic_signatures"](), @@ -290,6 +312,7 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.general_catalogs.customs_warehouses"](), url: "/dashboard/reference_data/customs_warehouses", + permission: "ref_customs_warehouses.view", }, { title: m["sidebar.general_catalogs.prevalidators"](), @@ -413,7 +436,7 @@ export function getSidebarData(): SidebarData { { title: m["sidebar.pedimentos.payment_methods"](), url: "/dashboard/reference_data/payment_methods", - permission: 'pedimentos_payments.view', + permission: 'ref_payment_methods.view', }, { title: m["sidebar.pedimentos.customs_sections"](), diff --git a/frontend/src/routes/dashboard/reference_data/code_pedimento_regimens/+page.svelte b/frontend/src/routes/dashboard/reference_data/code_pedimento_regimens/+page.svelte index 7fd3ecf8..895ade27 100644 --- a/frontend/src/routes/dashboard/reference_data/code_pedimento_regimens/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/code_pedimento_regimens/+page.svelte @@ -41,8 +41,8 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.view')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.delete')); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); @@ -123,7 +123,7 @@ {#if isError} {:else} diff --git a/frontend/src/routes/dashboard/reference_data/containers/+page.svelte b/frontend/src/routes/dashboard/reference_data/containers/+page.svelte index c548628b..343d6b09 100644 --- a/frontend/src/routes/dashboard/reference_data/containers/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/containers/+page.svelte @@ -29,9 +29,9 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_containers.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_containers.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_containers.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_containers.delete')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/countries/+page.svelte b/frontend/src/routes/dashboard/reference_data/countries/+page.svelte index 5e1e7f5e..96520035 100644 --- a/frontend/src/routes/dashboard/reference_data/countries/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/countries/+page.svelte @@ -64,10 +64,10 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'ref_countries.view') || userHasPermission($currentUser, 'cat_countries.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_countries.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_countries.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_countries.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_countries.view')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte index 85aa166a..fcd5917f 100644 --- a/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/currency_types/+page.svelte @@ -62,10 +62,10 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'ref_currency_types.view') || userHasPermission($currentUser, 'cat_currency.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_currency_types.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_currency_types.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_currency_types.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_currency_types.view')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte b/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte index 6488bfc9..7035ad4e 100644 --- a/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/customs_sections/+page.svelte @@ -33,9 +33,9 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_customs_sections.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_customs_sections.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_customs_sections.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_customs_sections.delete')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte b/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte index 124dd7b4..c7740f53 100644 --- a/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/customs_warehouses/+page.svelte @@ -37,10 +37,10 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'ref_customs_warehouses.view') || userHasPermission($currentUser, 'cat_warehouses.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_customs_warehouses.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_customs_warehouses.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_customs_warehouses.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_customs_warehouses.view')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.server.ts b/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.server.ts index 4cb89742..23052018 100644 --- a/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.server.ts +++ b/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.server.ts @@ -11,7 +11,8 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { items: [], total: 0, page: 1, - page_size: 50 + page_size: 50, + status: 401 }; } @@ -28,7 +29,8 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { items: [], total: 0, page, - page_size: pageSize + page_size: pageSize, + status: 400 }; } @@ -50,19 +52,25 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { ); if (!response.ok) { - const errorText = await response.text(); - console.error('📊 [Document Types Digitization] API Error:', { - status: response.status, - statusText: response.statusText, - error: errorText - }); - + const message = + response.status === 403 + ? 'No tiene permiso para ver tipos de documento para digitalización' + : `Error ${response.status}: ${response.statusText}`; + if (response.status !== 403) { + const errorText = await response.text(); + console.error('📊 [Document Types Digitization] API Error:', { + status: response.status, + statusText: response.statusText, + error: errorText + }); + } return { - error: `Error ${response.status}: ${response.statusText}`, + error: message, items: [], total: 0, page, - page_size: pageSize + page_size: pageSize, + status: response.status }; } @@ -73,7 +81,8 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { total: data.total || 0, page: data.page || page, page_size: data.page_size || pageSize, - error: null + error: null, + status: 200 }; } catch (error) { console.error('📊 [Document Types Digitization] Load error:', error); @@ -82,7 +91,8 @@ export const load: PageServerLoad = async ({ cookies, fetch, url, parent }) => { items: [], total: 0, page: 1, - page_size: 50 + page_size: 50, + status: 500 }; } }; \ No newline at end of file diff --git a/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.svelte b/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.svelte index 5635d344..53321685 100644 --- a/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/document_types_digitization/+page.svelte @@ -16,6 +16,8 @@ import { createColumns } from '$lib/components/dashboard/reference_data/document_types_digitization/columns'; import { useShortcuts } from '$lib/hooks/use-shortcuts'; import type { PageData } from './$types'; + import { currentUser, userHasPermission } from '$lib/auth'; + import ErrorState from '$lib/components/dashboard/common/error-state.svelte'; let { data }: { data: PageData } = $props(); @@ -39,9 +41,12 @@ let totalItems = $state(data.total || 0); let loading = $state(false); let error = $state(data.error || null); + let status = $state(data.status || 200); let searchQuery = $state($page.url.searchParams.get('search') || ''); let timeout: ReturnType; let hasMore = $derived(allItems.length < totalItems); + const canView = $derived(userHasPermission($currentUser, 'ref_invoice_types.view')); + const isError = $derived(!canView || status >= 400 || error); function getActiveCompanyId(): number | null { const fromStore = companyStore.activeCompany?.id; @@ -137,42 +142,54 @@ const columns = createColumns(); -
-
-
-

Tipos de documento para digitalización

-

- Consulta el catálogo fijo de solo lectura utilizado por digitalización y pedimentos. -

-
+{#if isError} +
+
- - {#if error} -
- {error} +{:else} +
+
+
+

Tipos de documento para digitalización

+

+ Consulta el catálogo fijo de solo lectura utilizado por digitalización y pedimentos. +

+
- {/if} - - -
- Listado de tipos de documento -
- + {#if error} +
+ {error} +
+ {/if} + + + +
+ Listado de tipos de documento +
+ +
-
- - -
- -
-
- + + +
+ +
+
+ -
Mostrando {allItems.length} de {totalItems} registros
-
\ No newline at end of file +
Mostrando {allItems.length} de {totalItems} registros
+
+{/if} \ No newline at end of file diff --git a/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte b/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte index 0d417879..8bb8ae15 100644 --- a/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/incoterms/+page.svelte @@ -37,10 +37,10 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'ref_incoterms.view') || userHasPermission($currentUser, 'cat_incoterms.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_incoterms.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_incoterms.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_incoterms.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_incoterms.view')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); @@ -119,8 +119,18 @@ const columns = $derived(createColumns(handleSuccess, { canEdit, canDelete })); -
- +{#if isError} +
+ +
+{:else} +
{#if error}
{error} @@ -145,4 +155,5 @@
Mostrando {allItems.length} de {totalItems} registros
-
+
+{/if} diff --git a/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte index 961c00dd..70422d1f 100644 --- a/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/invoice_types/+page.svelte @@ -37,10 +37,10 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'ref_invoice_types.view') || userHasPermission($currentUser, 'cat_inv_types.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_invoice_types.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_invoice_types.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_invoice_types.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_invoice_types.view')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte index c6cef868..34ed23fc 100644 --- a/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/material_types/+page.svelte @@ -30,8 +30,8 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_material_types.view')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_material_types.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_material_types.delete')); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte b/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte index 15db5766..1700cf2c 100644 --- a/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/payment_methods/+page.svelte @@ -29,9 +29,9 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'pedimentos_payments.view')); - const canEdit = $derived(userHasPermission($currentUser, 'pedimentos_payments.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'pedimentos_payments.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_payment_methods.view')); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte b/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte index 744682b2..3ab5f81c 100644 --- a/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/pedimento_codes/+page.svelte @@ -32,8 +32,8 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_pedimento_codes.view')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_pedimento_codes.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_pedimento_codes.delete')); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte b/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte index 7ba93439..68c31820 100644 --- a/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/pedimento_regimens/+page.svelte @@ -42,9 +42,9 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_pedimento_regimens.delete')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte index a1140b47..edaeabdc 100644 --- a/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/sectors/+page.svelte @@ -38,9 +38,9 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_sectors.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_sectors.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_sectors.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_sectors.delete')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/states/+page.svelte b/frontend/src/routes/dashboard/reference_data/states/+page.svelte index 6fa06fdb..4d005ffc 100644 --- a/frontend/src/routes/dashboard/reference_data/states/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/states/+page.svelte @@ -32,8 +32,8 @@ // 🛡️ Permisos (Runas derivadas) const canView = $derived(userHasPermission($currentUser, 'ref_states.view')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_states.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_states.delete')); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte b/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte index 969e9a35..7f41241c 100644 --- a/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/transport_modes/+page.svelte @@ -33,9 +33,9 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_transport_modes.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_transport_modes.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_transport_modes.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_transport_modes.delete')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte b/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte index dc9d8fcf..a177a70b 100644 --- a/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/transport_types/+page.svelte @@ -30,8 +30,8 @@ // Permisos const canView = $derived(userHasPermission($currentUser, 'ref_transport_types.view')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_transport_types.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_transport_types.delete')); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error); diff --git a/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte b/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte index ce0203e1..077b3a27 100644 --- a/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte +++ b/frontend/src/routes/dashboard/reference_data/valuation_methods/+page.svelte @@ -38,10 +38,10 @@ let status = $state(data.status || 200); // Permisos - const canView = $derived(userHasPermission($currentUser, 'ref_valuation_methods.view') || userHasPermission($currentUser, 'cat_valuation.view')); - const canCreate = $derived(userHasPermission($currentUser, 'ref_valuation_methods.create')); - const canEdit = $derived(userHasPermission($currentUser, 'ref_valuation_methods.edit')); - const canDelete = $derived(userHasPermission($currentUser, 'ref_valuation_methods.delete')); + const canView = $derived(userHasPermission($currentUser, 'ref_valuation_methods.view')); + const canCreate = $derived(false); + const canEdit = $derived(false); + const canDelete = $derived(false); const isError = $derived(!canView || status >= 400 || error);