Files
plantillas-proyectos/backend/api/v1/modules/a76/invoice_settings/routes.py

145 lines
4.8 KiB
Python

from typing import List, Dict, Any
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from core.database import get_core_db
from core.security import get_current_user, validate_access_to_resource
from api.v1.modules.a76.invoice_settings import services
from api.v1.modules.a76.invoice_settings.dto import InvoiceSettingsRequest, InvoiceSettingsResponse, OperationType
from api.v1.modules.core.permissions.service import PermissionService
router = APIRouter(
prefix="/a76/invoice-settings",
tags=["a76/invoice-settings"]
)
def _invoice_perm_base_for_settings(operation_type: OperationType, invoice_type: str) -> str:
"""Alineado con get_invoice_permission_base en invoices/routes (defaults por tipo)."""
op = (
operation_type.value
if hasattr(operation_type, "value")
else str(operation_type).lower().split(".")[-1]
)
inv = (invoice_type or "").upper()
if op == "imp":
if inv == "TEM":
return "invoice.imp.tem"
if inv == "DEF":
return "invoice.imp.def"
if inv == "MEX":
return "invoice.imp.cm"
if inv == "CR":
return "invoice.imp.cr"
return "invoice.imp.tem"
if op == "exp":
if inv == "REPAR":
return "invoice.exp.rep"
return "invoice.exp"
return "invoice.imp.tem"
def _can_read_invoice_settings_row(
db: Session,
company_id: int,
current_user: Dict[str, Any],
invoice_type: str,
operation_type: OperationType,
) -> bool:
"""
Ver configuración por tipo/op: settings_general.view O ver facturas de ese mismo contexto
(para cargar defaults en alta/edición sin abrir la pantalla de parámetros).
"""
user_roles = current_user.get("realm_access", {}).get("roles", [])
if "admin" in user_roles:
return True
user_id = current_user.get("sub") or current_user.get("id")
if not user_id:
return False
ps = PermissionService(db)
if ps.has_permission(str(user_id), company_id, "settings_general.view"):
return True
base = _invoice_perm_base_for_settings(operation_type, invoice_type)
return ps.has_permission(str(user_id), company_id, f"{base}.view")
@router.get("/{invoice_type}", response_model=InvoiceSettingsResponse)
def get_invoice_settings(
invoice_type: str,
operation_type: OperationType = Query(...),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
"""Get settings for a specific invoice type and operation"""
tenant_id = validate_access_to_resource(db, company_id, current_user)
if not _can_read_invoice_settings_row(
db, company_id, current_user, invoice_type, operation_type
):
raise HTTPException(
status_code=403,
detail="Missing required permissions: settings_general.view "
f"(o permiso de vista del tipo de factura solicitado, p. ej. {_invoice_perm_base_for_settings(operation_type, invoice_type)}.view)",
)
settings = services.get_settings(
db,
tenant_id,
company_id,
invoice_type,
operation_type
)
if not settings:
# Return empty default if not found, to simplify frontend logic
return InvoiceSettingsResponse(
invoice_type=invoice_type,
operation_type=operation_type,
settings={},
id=0,
tenant_id=tenant_id,
company_id=company_id
)
return InvoiceSettingsResponse.model_validate(settings)
@router.get("/", response_model=List[InvoiceSettingsResponse])
def list_invoice_settings(
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
"""List all configured settings for validation or overview"""
tenant_id = validate_access_to_resource(
db,
company_id,
current_user,
required_permissions=["settings_general.view"],
)
return services.list_settings(
db,
tenant_id,
company_id
)
@router.put("/", response_model=InvoiceSettingsResponse)
def save_invoice_settings(
settings_data: InvoiceSettingsRequest,
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
"""Create or update invoice settings"""
tenant_id = validate_access_to_resource(
db,
company_id,
current_user,
required_permissions=["settings_general.edit"],
)
return services.upsert_settings(
db,
tenant_id,
company_id,
settings_data
)