Se modifico el task de coves

This commit is contained in:
2025-09-01 15:55:09 -06:00
parent 879ce8d544
commit c572d4beed
39 changed files with 173 additions and 31 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@ __pycache__/
# C extensions # C extensions
*.so *.so
api/api_v2
main2.py main2.py
sample.xml sample.xml

0
api/api_v2/__init__.py Normal file
View File

18
api/api_v2/api.py Normal file
View File

@@ -0,0 +1,18 @@
from fastapi import APIRouter
# En Python, no se pueden usar llaves {} para importar múltiples módulos.
# Debes usar paréntesis () para hacer importaciones multilínea.
from api.api_v2.modules.acuses import router as acuses_router
from api.api_v2.modules.coves import router as coves_router
from api.api_v2.modules.edocs import router as edocs_router
from api.api_v2.modules.partidas import router as partidas_router
from api.api_v2.modules.pedimentos import router as pedimentos_router
api_router = APIRouter()
# Incluir routers de endpoints
api_router.include_router(acuses_router, tags=["acuses"])
api_router.include_router(coves_router, tags=["coves"])
api_router.include_router(edocs_router, tags=["edocs"])
api_router.include_router(partidas_router, tags=["partidas"])
api_router.include_router(pedimentos_router, tags=["pedimentos"])

View File

View File

@@ -0,0 +1,42 @@
from fastapi import APIRouter, HTTPException
from fastapi.responses import JSONResponse
from typing import Dict, Any, List, Optional
import asyncio
import logging
import traceback
from .schemas import AcuseSchema, AcuseMasivoSchema
from .services import *
router = APIRouter(prefix="/acuses", tags=["Acuses"])
@router.post("/service/acuse/individual", response_model=Dict[str, Any])
async def obtener_acuse(acuse_request: AcuseSchema):
"""
Endpoint para obtener el acuse de recibo de un documento específico.
"""
pass
@router.post("/service/acuse", response_model=Dict[str, Any])
async def obtener_acuses(acuse_request: AcuseMasivoSchema):
"""
Endpoint para obtener acuses de recibo de documentos asociados a un pedimento.
"""
pass
@router.post("/service/acuse_cove", response_model=Dict[str, Any])
async def obtener_acuses_cove(acuse_request: AcuseMasivoSchema):
"""
Endpoint para obtener acuses de recibo de COVEs asociados a un pedimento.
"""
pass
@router.post("/service/acuse_cove/individual", response_model=Dict[str, Any])
async def obtener_acuse_cove(acuse_request: AcuseSchema):
"""
Endpoint para obtener el acuse de recibo de un COVE específico.
"""
pass

View File

@@ -0,0 +1,22 @@
from fastapi import FastAPI
from pydantic import BaseModel
from uuid import UUID
# Aplica para Acuse, Acuse Cove y Edocuments
class AcuseSchema(BaseModel):
pedimento: str
organizacion: str
numero_documento: str
vu_user: str
password: str
class AcuseMasivoSchema(BaseModel):
pedimento: str
organizacion: str
numeros_documentos: list[str]
vu_user: str
password: str

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

@@ -202,7 +202,7 @@ class APIController:
return result return result
except Exception as e: except Exception as e:
print(f"Error al enviar documento: {e}") print(f"Error al enviar documento: {document_data}, Error: {e}")
# Limpiar archivo temporal en caso de error # Limpiar archivo temporal en caso de error
if 'temp_file_path' in locals() and os.path.exists(temp_file_path): if 'temp_file_path' in locals() and os.path.exists(temp_file_path):
os.unlink(temp_file_path) os.unlink(temp_file_path)

View File

@@ -1,8 +0,0 @@
from fastapi import FastAPI
from pydantic import BaseModel
from uuid import UUID
class AcuseSchema(BaseModel):
document_id: str

14
schemas/remesaSchema.py Normal file
View File

@@ -0,0 +1,14 @@
from fastapi import FastAPI
from pydantic import BaseModel
from uuid import UUID
# Aplica para Acuse y Acuse Cove
class Remesa(BaseModel):
numero_operacion: str
vu_user: str
password: str

View File

@@ -742,29 +742,81 @@ def coves_task(self, **kwargs):
if not coves_response: if not coves_response:
raise Exception("Error en la petición REST para coves") raise Exception("Error en la petición REST para coves")
logger.info("[TASK] Petición REST para coves completada exitosamente") logger.info("[TASK] Petición REST para coves completada exitosamente")
# Subir documento de coves si la petición fue exitosa # Procesar acuses de documentos digitalizados
try: documentos_procesados = []
upload_result = await _post_coves( documentos_exitosos = 0
response_service=service_data,
identificadores_cove=[coves_response[0].get('numero_cove')] if isinstance(coves_response, list) and coves_response else [] coves = coves_response if isinstance(coves_response, list) else []
) logger.info(f"Procesando COVE para {len(coves)} documentos...")
logger.info(f"Documento de coves subido exitosamente: {upload_result}")
except Exception as upload_err: # Obtener credenciales VUCEM para la firma
logger.error(f"Error al subir documento de coves: {upload_err}") credentials = await _get_vucem_credentials(service_data.get('pedimento', {}).get('contribuyente', ''), operation_name)
from controllers.SOAPController import soap_controller
self.update_state(state='PROGRESS', meta={'status': 'Finalizando proceso'})
for idx, cove in enumerate(coves):
documento_info = {
"numero_cove": cove.get('numero_cove', 'N/A'),
"procesado": False,
"error": None
}
if not cove.get('numero_cove'):
logger.warning(f"Documento {idx + 1} no tiene numero_cove, saltando...")
documento_info["error"] = "Sin número de cove"
documentos_procesados.append(documento_info)
continue
try:
logger.info(f"Procesando cove para documento {idx + 1}: {cove['numero_cove']}")
soap_response = await get_soap_cove(
credenciales=credentials,
response_service=service_data,
soap_controller=soap_controller,
cove=cove,
idx=idx + 1
)
if soap_response:
documento_info["procesado"] = True
documento_info["documento"] = soap_response.get('documento', {})
documentos_exitosos += 1
logger.info(f"cove del documento {idx + 1} procesado exitosamente")
else:
documento_info["error"] = "Error en petición SOAP"
logger.warning(f"No se pudo procesar el cove del documento {idx + 1}")
except Exception as e:
logger.error(f"Error al procesar cove del documento {idx + 1}: {e}")
documento_info["error"] = str(e)
documentos_procesados.append(documento_info)
if documentos_exitosos == 0:
logger.error("No se pudo procesar ningún cove de documento digitalizado")
await _update_service_status(service_data['id'], ESTADO_ERROR, service_data, operation_name)
raise Exception("No se pudo procesar ningún acuse cove de documento digitalizado")
await _update_service_status(service_data['id'], ESTADO_FINALIZADO, service_data, operation_name) await _update_service_status(service_data['id'], ESTADO_FINALIZADO, service_data, operation_name)
response_data = await _create_response( response_data = await _create_response(
service_data=service_data, service_data=service_data,
additional_data={ additional_data={
"coves": coves_response "covesDocs": documentos_procesados,
"total_documentos": len(coves),
"documentos_exitosos": documentos_exitosos,
"documentos_fallidos": len(coves) - documentos_exitosos
}, },
success_message="Coves obtenidos exitosamente" success_message=f"Se procesaron {documentos_exitosos}/{len(coves)} cove de documentos exitosamente"
) )
logger.info(f"[TASK] Consulta de coves completada exitosamente - Servicio: {service_data['id']}") if documentos_exitosos < len(coves):
response_data["warnings"] = [
f"Se procesaron solo {documentos_exitosos} de {len(coves)} coves"
]
logger.info(f"Procesamiento de acuses cove completado - Exitosos: {documentos_exitosos}/{len(coves)}")
return response_data return response_data
except Exception as e: except Exception as e:

View File

@@ -129,7 +129,6 @@ def extract_acuse_documento_from_soap(soap_response_text): # Testeado
logger.error(f"Error extrayendo acuseDocumento: {e}") logger.error(f"Error extrayendo acuseDocumento: {e}")
return None return None
def extract_pdf_bytes_from_xml(xml_path): def extract_pdf_bytes_from_xml(xml_path):
""" """
Igual que extract_pdf_bytes_from_xml_content pero recibe una ruta de archivo. Igual que extract_pdf_bytes_from_xml_content pero recibe una ruta de archivo.
@@ -309,13 +308,11 @@ async def get_soap_pedimento_completo(credenciales, response_service, soap_contr
organizacion=response_service['organizacion'], organizacion=response_service['organizacion'],
pedimento=response_service['pedimento']['id'], pedimento=response_service['pedimento']['id'],
file_name=_file_name, file_name=_file_name,
document_type=2, document_type=2,
) )
data['organizacion'] = response_service['organizacion'] data['organizacion'] = response_service['organizacion']
data['id'] = response_service['pedimento']['id'] data['id'] = response_service['pedimento']['id']
data['fuente'] = 2
return { return {
"servicio": response_service, "servicio": response_service,
@@ -970,6 +967,8 @@ async def get_soap_cove(credenciales, response_service, soap_controller, cove, i
cove=cove['numero_cove'] cove=cove['numero_cove']
) )
### >>> AQUÍ SE AÑADE EL LOGGER.DEBUG <<< ### ### >>> AQUÍ SE AÑADE EL LOGGER.DEBUG <<< ###
logger.debug(f"XML SOAP generado: {soap_xml}") # 👈 Registra el XML completo logger.debug(f"XML SOAP generado: {soap_xml}") # 👈 Registra el XML completo
@@ -989,6 +988,8 @@ async def get_soap_cove(credenciales, response_service, soap_controller, cove, i
headers=soap_headers headers=soap_headers
) )
if (soap_response) and (not soap_error(soap_response)): if (soap_response) and (not soap_error(soap_response)):
logger.info(f"Petición SOAP exitosa - Status: {soap_response.status_code}") logger.info(f"Petición SOAP exitosa - Status: {soap_response.status_code}")
@@ -999,14 +1000,14 @@ async def get_soap_cove(credenciales, response_service, soap_controller, cove, i
tipo_operacion = response_service['pedimento'].get('tipo_operacion', 'N/A') tipo_operacion = response_service['pedimento'].get('tipo_operacion', 'N/A')
pedimento = response_service['pedimento'].get('pedimento', 'N/A') pedimento = response_service['pedimento'].get('pedimento', 'N/A')
_file_name = f"vu_COVE_{remesas}{no_partidas}{tipo_operacion}_{aduana}_{patente}_{pedimento}_{idx}.xml" _file_name = f"vu_COVE_{remesas}{no_partidas}{tipo_operacion}_{aduana}_{patente}_{pedimento}_{cove['numero_cove']}.xml"
document_response = await rest_controller.post_document( document_response = await rest_controller.post_document(
soap_response=soap_response, soap_response=soap_response,
organizacion=response_service['organizacion'], organizacion=response_service['organizacion'],
pedimento=response_service['pedimento']['id'], pedimento=response_service['pedimento']['id'],
file_name=_file_name, file_name=_file_name,
document_type=8 document_type=8,
) )
return { return {