Merge branch 'development' into task/archivos_winsaai

This commit is contained in:
2026-03-05 08:19:07 -06:00
140 changed files with 25119 additions and 1400 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,
)
# Import models in correct order for SQLAlchemy relationship resolution
# CRITICAL: FaLineItem must be imported BEFORE LineItem
from api.v1.modules.a24.fa.fa_item_lines.models import FaLineItem # noqa: F401
@@ -26,6 +33,15 @@ celery_app.conf.update(
"api.v1.modules.a76.reports.movements.invoices.tasks",
"api.v1.modules.a76.reports.exportacion.descargo.task",
"api.v1.modules.a76.imports.tasks",
"api.v1.modules.a76.customs_brokers.imports.tasks",
"api.v1.modules.a76.clients_and_providers.imports.tasks",
"api.v1.modules.a76.pedmientos.imports.tasks",
"api.v1.modules.a76.general_catalogs.exchange_rate.imports.tasks",
"api.v1.modules.a76.general_catalogs.fractions.us_tariff_fractions.imports.tasks",
"api.v1.modules.a76.classes.imports.tasks",
"api.v1.modules.a76.parts.imports.tasks",
"api.v1.modules.a76.boms.imports.tasks",
"api.v1.modules.a76.transportation.vehicles.imports.tasks",
"api.v1.modules.a76.reports.exportacion.transmission.MAINX30.task",
"api.v1.modules.a76.reports.importacion.transmission.temporal.MAINX30.task",
"api.v1.modules.a76.reports.importacion.transmission.definitive.MAINX30.task",

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(
@@ -105,7 +123,7 @@ async def integrity_error_handler(
else:
error_message = "Error de integridad en la base de datos"
return JSONResponse(
response = JSONResponse(
status_code=status.HTTP_409_CONFLICT,
content={
"error": "DATABASE_INTEGRITY_ERROR",
@@ -113,6 +131,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(
@@ -131,7 +152,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",
@@ -139,6 +160,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 http_exception_handler(
@@ -174,7 +198,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",
@@ -182,6 +206,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: