feature/funcionalidades-click-derecho-facturas

This commit is contained in:
2026-05-26 10:02:17 -06:00
parent 703bb68a04
commit e3205880d7
17 changed files with 2598 additions and 4 deletions

View File

@@ -1,5 +1,5 @@
import logging
from typing import Dict, Any, Optional
from typing import Dict, Any, Literal, Optional
from core.config import settings
from core.database import get_core_db
@@ -255,6 +255,252 @@ def delete_invoice(
success = services.InvoiceService.delete(db, invoice_id, tenant_id, company_id)
return {"success": success}
@router.post("/invoices/{invoice_id}/copy", response_model=schemas.InvoiceHeaderResponse)
def copy_invoice(
invoice_id: int = Path(..., description="ID de la factura a copiar"),
company_id: int = Query(..., description="Company ID"),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
original = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not original:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(original.operation_type, original.invoice_type)
validate_access_to_resource(
db, company_id, current_user, required_permissions=[f"{perm_base}.create"]
)
try:
return services.InvoiceService.copy(db, invoice_id, tenant_id, company_id)
except HTTPException:
raise
except Exception as e:
logger.exception("copy_invoice failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al copiar factura: {str(e)}")
@router.post("/invoices/{invoice_id}/copy-header", response_model=schemas.InvoiceHeaderResponse)
def copy_invoice_header(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(..., description="Company ID"),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
original = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not original:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(original.operation_type, original.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.create"])
try:
return services.InvoiceService.copy_header_only(db, invoice_id, tenant_id, company_id)
except HTTPException:
raise
except Exception as e:
logger.exception("copy_invoice_header failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al copiar encabezado: {str(e)}")
@router.get("/invoices/{invoice_id}/export")
def export_invoice(
invoice_id: int = Path(..., description="ID de la factura"),
format: Literal['csv', 'xlsx', 'txt'] = Query(..., description="Formato: csv | xlsx | txt"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_items(db, invoice, format)
except HTTPException:
raise
except Exception as e:
logger.exception("export_invoice failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al exportar factura: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/gm-transport")
def interface_gm_transport(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_gm_transport(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_gm_transport failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz GM Transport: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/carta-porte")
def interface_carta_porte(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_carta_porte(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_carta_porte failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz Carta Porte: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/tfc")
def interface_tfc(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_tfc(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_tfc failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz TFC: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/carta-porte-consolidada")
def interface_carta_porte_consolidada(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_carta_porte_consolidada(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_carta_porte_consolidada failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz Carta Porte Consolidada: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/aviso-cruce")
def interface_aviso_cruce(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_aviso_cruce(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_aviso_cruce failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz Aviso Cruce: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/aaduanal-rs")
def interface_aaduanal_rs(
invoice_id: int = Path(..., description="ID de la factura"),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_aaduanal_rs(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_aaduanal_rs failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz AAduanal_RS: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/caaarem")
def interface_caaarem(
invoice_id: int = Path(...),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_caaarem(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_caaarem failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz CAAAREM: {str(e)}")
@router.get("/invoices/{invoice_id}/interfaces/cp-genesis")
def interface_cp_genesis(
invoice_id: int = Path(...),
company_id: int = Query(...),
db: Session = Depends(get_core_db),
current_user: Dict[str, Any] = Depends(get_current_user),
):
tenant_id = validate_access_to_resource(db, company_id, current_user)
invoice = services.InvoiceService.get_by_id(db, invoice_id, tenant_id, company_id)
if not invoice:
raise HTTPException(status_code=404, detail="Factura no encontrada")
perm_base = get_invoice_permission_base(invoice.operation_type, invoice.invoice_type)
validate_access_to_resource(db, company_id, current_user, required_permissions=[f"{perm_base}.view"])
try:
return services.InvoiceService.export_cp_genesis(db, invoice)
except HTTPException:
raise
except Exception as e:
logger.exception("interface_cp_genesis failed: %s", e)
raise HTTPException(status_code=500, detail=f"Error al generar interfaz Carta Porte Genesis: {str(e)}")
# --- RUTA DE LISTADO (FILTROS) ---

File diff suppressed because it is too large Load Diff