feature/csv-for-envoices

This commit is contained in:
hreyes
2026-02-23 13:05:02 -06:00
parent bbe74906ec
commit 0683aaa801
21 changed files with 1232 additions and 255 deletions

View File

@@ -1,6 +1,13 @@
import os
from celery import Celery
# Orden: PedimentoCode y RegimenPedimento antes de CodePedimentoRegimen (mapper)
from api.v1.modules.public.reference_data.pedimento_codes.models import PedimentoCode
from api.v1.modules.public.reference_data.pedimento_regimens.models import RegimenPedimento
from api.v1.modules.public.reference_data.code_pedimento_regimens.models import (
CodePedimentoRegimen,
)
valkey_url = os.getenv("VALKEY_URL", "redis://valkey:6379/0")

View File

@@ -11,11 +11,23 @@ from fastapi.encoders import jsonable_encoder
from fastapi.exceptions import RequestValidationError
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
from .config import settings
from .exceptions import BaseAPIException
logger = logging.getLogger(__name__)
def _cors_headers(request: Request) -> Dict[str, str]:
"""CORS headers for error responses so browser does not block on 4xx/5xx."""
origin = request.headers.get("origin")
if not origin or origin not in settings.cors_origins_list:
return {}
return {
"Access-Control-Allow-Origin": origin,
"Access-Control-Allow-Credentials": "true",
}
async def base_exception_handler(
request: Request,
exc: BaseAPIException,
@@ -36,10 +48,13 @@ async def base_exception_handler(
if hasattr(exc, "errors") and exc.errors:
logger.warning(f"Validation errors details: {exc.errors}")
return JSONResponse(
response = JSONResponse(
status_code=exc.status_code,
content=jsonable_encoder(exc.to_dict()),
)
for k, v in _cors_headers(request).items():
response.headers[k] = v
return response
async def validation_exception_handler(
@@ -65,7 +80,7 @@ async def validation_exception_handler(
extra={"errors": errors},
)
return JSONResponse(
response = JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={
"error": "VALIDATION_ERROR",
@@ -74,6 +89,9 @@ async def validation_exception_handler(
"errors": errors,
},
)
for k, v in _cors_headers(request).items():
response.headers[k] = v
return response
async def integrity_error_handler(
@@ -102,7 +120,7 @@ async def integrity_error_handler(
elif "not null" in orig_msg:
error_message = "Falta un campo requerido."
return JSONResponse(
response = JSONResponse(
status_code=status.HTTP_409_CONFLICT,
content={
"error": "DATABASE_INTEGRITY_ERROR",
@@ -110,6 +128,9 @@ async def integrity_error_handler(
"status_code": status.HTTP_409_CONFLICT,
},
)
for k, v in _cors_headers(request).items():
response.headers[k] = v
return response
async def sqlalchemy_error_handler(
@@ -128,7 +149,7 @@ async def sqlalchemy_error_handler(
exc_info=True,
)
return JSONResponse(
response = JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={
"error": "DATABASE_ERROR",
@@ -136,6 +157,9 @@ async def sqlalchemy_error_handler(
"status_code": status.HTTP_500_INTERNAL_SERVER_ERROR,
},
)
for k, v in _cors_headers(request).items():
response.headers[k] = v
return response
async def general_exception_handler(
@@ -154,7 +178,7 @@ async def general_exception_handler(
exc_info=True,
)
return JSONResponse(
response = JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={
"error": "INTERNAL_SERVER_ERROR",
@@ -162,6 +186,9 @@ async def general_exception_handler(
"status_code": status.HTTP_500_INTERNAL_SERVER_ERROR,
},
)
for k, v in _cors_headers(request).items():
response.headers[k] = v
return response
def register_exception_handlers(app) -> None: