Merge pull request 'feature/agregar eventos en las tareas de fondo, se modificaron modelos para capturar cuales si deben accionar tareas de fondo y cuales no necesariamente tienen que accionar tareas de fondo' (#29) from feature/background-tasks into main
Reviewed-on: #29
This commit is contained in:
@@ -34,6 +34,7 @@ class Pedimento(models.Model):
|
||||
fecha_pago = models.DateField(help_text="Fecha de pago del pedimento", blank=True, null=True)
|
||||
|
||||
alerta = models.BooleanField(default=False, help_text="Indica si el pedimento tiene una alerta asociada")
|
||||
consultar_vucem = models.BooleanField(default=False, help_text="Solo pedimentos originados desde datastage deben consultar VUCEM automáticamente")
|
||||
|
||||
contribuyente = models.ForeignKey('Importador', on_delete=models.CASCADE, related_name='pedimentos', help_text="Contribuyente asociado al pedimento", blank=True, null=True)
|
||||
agente_aduanal = models.CharField(max_length=100, blank=True, null=True, help_text="RFC del agente aduanal")
|
||||
|
||||
@@ -27,6 +27,9 @@ def trigger_celery_task_on_create(sender, instance, created, **kwargs):
|
||||
logger.info("NO es creación de pedimento, no se crea procesamiento.")
|
||||
return
|
||||
|
||||
if not instance.consultar_vucem:
|
||||
return
|
||||
|
||||
def crear_procesamiento():
|
||||
import logging
|
||||
logger = logging.getLogger('api.customs.async_operations')
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from celery import shared_task
|
||||
from django.core.files.base import ContentFile
|
||||
from django.utils import timezone
|
||||
import os
|
||||
import zipfile
|
||||
@@ -615,8 +614,6 @@ def bulk_upload_record_task(self, organizacion_id, parametros, archivo_paths):
|
||||
tiene_nomenclatura_especial = True
|
||||
info_extraida = procesar_archivo_m_con_nomenclatura(file_content, existing_pedimento)
|
||||
|
||||
django_file = ContentFile(file_content, name=file_name)
|
||||
|
||||
# Buscar documento existente
|
||||
existing_documents = Document.objects.filter(
|
||||
pedimento_id=existing_pedimento.id,
|
||||
@@ -630,51 +627,53 @@ def bulk_upload_record_task(self, organizacion_id, parametros, archivo_paths):
|
||||
break
|
||||
|
||||
if existing_document:
|
||||
# Actualizar documento existente
|
||||
# try:
|
||||
# if existing_document.archivo and os.path.exists(existing_document.archivo.path):
|
||||
# os.remove(existing_document.archivo.path)
|
||||
# except (ValueError, OSError):
|
||||
# pass
|
||||
|
||||
# existing_document.archivo = django_file
|
||||
# existing_document.size = len(file_content)
|
||||
# existing_document.extension = extension
|
||||
# existing_document.updated_at = timezone.now()
|
||||
# existing_document.save()
|
||||
|
||||
# doc = Document.objects.get(id=existing_document.id)
|
||||
# doc.archivo.delete(save=False) # Eliminar el archivo anterior
|
||||
# doc.delete() # Eliminar el registro para crear uno nuevo (evita problemas con archivos en Django)
|
||||
|
||||
updated_pedimentos.append({
|
||||
"id": str(existing_pedimento.id),
|
||||
"pedimento_app": existing_pedimento.pedimento_app,
|
||||
"accion": "Documento actualizado",
|
||||
"accion": "Documento ya existente, omitido",
|
||||
"documento": file_name
|
||||
})
|
||||
|
||||
documents_created += 1
|
||||
else:
|
||||
# Crear nuevo documento
|
||||
# Crear registro sin archivo primero
|
||||
document = Document.objects.create(
|
||||
organizacion=organizacion,
|
||||
pedimento_id=existing_pedimento.id,
|
||||
document_type=document_type,
|
||||
fuente_id=fuente.id,
|
||||
archivo=django_file,
|
||||
size=len(file_content),
|
||||
extension=os.path.splitext(file_name)[1].lower().lstrip('.')
|
||||
)
|
||||
|
||||
updated_pedimentos.append({
|
||||
"id": str(existing_pedimento.id),
|
||||
"pedimento_app": existing_pedimento.pedimento_app,
|
||||
"accion": "Documento creado",
|
||||
"documento": file_name
|
||||
})
|
||||
from api.utils.storage_service import storage_service
|
||||
ruta = storage_service.save_document_from_path(
|
||||
file_path=file_path,
|
||||
file_name=file_name,
|
||||
organizacion_id=organizacion.id,
|
||||
pedimento_app=existing_pedimento.pedimento_app,
|
||||
metadata={
|
||||
'pedimento_id': str(existing_pedimento.id),
|
||||
'document_id': str(document.id),
|
||||
'source': 'bulk_upload_async'
|
||||
}
|
||||
)
|
||||
|
||||
documents_created += 1
|
||||
if ruta:
|
||||
document.archivo = ruta
|
||||
document.save()
|
||||
documents_created += 1
|
||||
updated_pedimentos.append({
|
||||
"id": str(existing_pedimento.id),
|
||||
"pedimento_app": existing_pedimento.pedimento_app,
|
||||
"accion": "Documento creado",
|
||||
"documento": file_name
|
||||
})
|
||||
else:
|
||||
document.delete()
|
||||
failed_records.append({
|
||||
"file": relative_path,
|
||||
"archivo_original": folder_name + '.zip',
|
||||
"error": f"Error al guardar {file_name} en almacenamiento"
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
failed_records.append({
|
||||
|
||||
@@ -563,11 +563,14 @@ def process_all_organizations():
|
||||
"""
|
||||
Envía una tarea por organización activa a la cola org_processing.
|
||||
"""
|
||||
active_orgs = Organizacion.objects.filter(is_active=True, is_verified=True)
|
||||
|
||||
active_orgs = Organizacion.objects.filter(
|
||||
is_active=True,
|
||||
is_verified=True,
|
||||
apply_auto_download=True,
|
||||
)
|
||||
for org in active_orgs:
|
||||
process_organization_batch.apply_async(
|
||||
args=[org.id],
|
||||
args=[str(org.id)],
|
||||
queue='org_processing'
|
||||
)
|
||||
return f"Dispatched {active_orgs.count()} organizations"
|
||||
|
||||
@@ -297,6 +297,7 @@ def procesar_archivo_asc_task(datastage_id, user_organizacion_id, asc_name):
|
||||
"importe_pedimento": data.get('importe_pedimento', 0.0),
|
||||
"existe_expediente": data.get('existe_expediente', False),
|
||||
"remesas": data.get('remesas', False),
|
||||
"consultar_vucem": True,
|
||||
}
|
||||
try:
|
||||
Pedimento.objects.create(**pedimento_data)
|
||||
|
||||
@@ -42,6 +42,7 @@ class Organizacion(models.Model):
|
||||
|
||||
is_active = models.BooleanField(default=True)
|
||||
is_verified = models.BooleanField(default=False)
|
||||
apply_auto_download = models.BooleanField(default=False)
|
||||
|
||||
inicio = models.DateField(null=True, blank=True)
|
||||
vencimiento = models.DateField(null=True, blank=True)
|
||||
|
||||
@@ -1278,15 +1278,21 @@ class DocumentViewSet(viewsets.ModelViewSet, DocumentosFiltradosMixin):
|
||||
status=status.HTTP_403_FORBIDDEN
|
||||
)
|
||||
|
||||
# Usar tipo de documento por defecto siempre
|
||||
document_type, created = DocumentType.objects.get_or_create(
|
||||
nombre="Documento General",
|
||||
defaults={'descripcion': "Documento general sin tipo específico"}
|
||||
)
|
||||
if created:
|
||||
print(f"✅ DocumentType creado: {document_type.nombre} (ID: {document_type.id})")
|
||||
# Usar tipo de documento indicado o "Documento General" por defecto
|
||||
document_type_id_param = request.data.get('document_type_id')
|
||||
if document_type_id_param:
|
||||
try:
|
||||
document_type = DocumentType.objects.get(id=int(document_type_id_param))
|
||||
except (DocumentType.DoesNotExist, ValueError):
|
||||
return Response(
|
||||
{"error": f"Tipo de documento con ID '{document_type_id_param}' no encontrado"},
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
else:
|
||||
print(f"♻️ DocumentType existente: {document_type.nombre} (ID: {document_type.id})")
|
||||
document_type, _ = DocumentType.objects.get_or_create(
|
||||
nombre="Documento General",
|
||||
defaults={'descripcion': "Documento general sin tipo específico"}
|
||||
)
|
||||
|
||||
uploaded_documents = []
|
||||
failed_files = []
|
||||
@@ -1371,6 +1377,7 @@ class DocumentViewSet(viewsets.ModelViewSet, DocumentosFiltradosMixin):
|
||||
existing_doc.archivo = ruta
|
||||
existing_doc.size = file.size
|
||||
existing_doc.extension = extension
|
||||
existing_doc.document_type = document_type
|
||||
existing_doc.save()
|
||||
else:
|
||||
raise Exception(f"Error al guardar archivo: {file.name}")
|
||||
@@ -1406,7 +1413,7 @@ class DocumentViewSet(viewsets.ModelViewSet, DocumentosFiltradosMixin):
|
||||
"filename": file.name,
|
||||
"size": file.size,
|
||||
"extension": extension,
|
||||
"document_type": document_type.nombre
|
||||
"document_type": document.document_type.nombre if document.document_type else None
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
@@ -1750,6 +1757,265 @@ class DocumentViewSet(viewsets.ModelViewSet, DocumentosFiltradosMixin):
|
||||
|
||||
return Response(response_data, status=response_status)
|
||||
|
||||
@action(detail=False, methods=['post'], url_path='create-vu-record', parser_classes=[MultiPartParser])
|
||||
def create_vu_record(self, request):
|
||||
"""
|
||||
Crea un registro (Partida/Cove/EDocument) en su tabla correspondiente
|
||||
y sube sus archivos con la nomenclatura VU.
|
||||
|
||||
FormData:
|
||||
- pedimento_id : UUID del pedimento
|
||||
- tab_seccion : 'partida' | 'cove' | 'edoc'
|
||||
- numero : número del registro a crear
|
||||
- files : archivos (nombre con flag de sección: .xml.general, .pdf.acuse, etc.)
|
||||
"""
|
||||
pedimento_id = request.data.get('pedimento_id')
|
||||
tab_seccion = request.data.get('tab_seccion')
|
||||
numero = request.data.get('numero', '').strip()
|
||||
files = request.FILES.getlist('files')
|
||||
|
||||
if not pedimento_id:
|
||||
return Response({"error": "Se requiere 'pedimento_id'"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
if tab_seccion not in ('partida', 'cove', 'edoc'):
|
||||
return Response({"error": "tab_seccion debe ser 'partida', 'cove' o 'edoc'"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
if not numero:
|
||||
return Response({"error": "Se requiere 'numero'"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
if not files:
|
||||
return Response({"error": "Se requiere al menos un archivo"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
if not request.user.is_authenticated:
|
||||
return Response({"error": "Usuario no autenticado"}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
from api.customs.models import Pedimento as PedimentoModel, Partida, Cove, EDocument
|
||||
try:
|
||||
pedimento = PedimentoModel.objects.get(id=pedimento_id)
|
||||
except PedimentoModel.DoesNotExist:
|
||||
return Response({"error": "Pedimento no encontrado"}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
organizacion = pedimento.organizacion
|
||||
if not request.user.is_superuser:
|
||||
if not hasattr(request.user, 'organizacion') or request.user.organizacion != organizacion:
|
||||
return Response({"error": "Sin permisos para este pedimento"}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
# Validar número entero para partida
|
||||
numero_int = None
|
||||
if tab_seccion == 'partida':
|
||||
try:
|
||||
numero_int = int(numero)
|
||||
except ValueError:
|
||||
return Response({"error": "El número de partida debe ser un entero"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
uploaded_documents = []
|
||||
failed_files = []
|
||||
errors = []
|
||||
total_space_used = 0
|
||||
expediente_obj = None
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
uso = UsoAlmacenamiento.objects.select_for_update().get_or_create(
|
||||
organizacion=organizacion,
|
||||
defaults={'espacio_utilizado': 0}
|
||||
)[0]
|
||||
|
||||
max_bytes = organizacion.licencia.almacenamiento * 1024 ** 3
|
||||
total_files_size = sum(f.size for f in files)
|
||||
if uso.espacio_utilizado + total_files_size > max_bytes:
|
||||
espacio_faltante = (uso.espacio_utilizado + total_files_size) - max_bytes
|
||||
return Response({
|
||||
"error": "Espacio de almacenamiento insuficiente",
|
||||
"espacio_faltante_gb": round(espacio_faltante / (1024 ** 3), 2),
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
# Verificar unicidad y crear registro
|
||||
if tab_seccion == 'partida':
|
||||
if Partida.objects.filter(pedimento=pedimento, numero_partida=numero_int).exists():
|
||||
return Response(
|
||||
{"error": f"La partida {numero} ya existe para este pedimento"},
|
||||
status=status.HTTP_409_CONFLICT
|
||||
)
|
||||
expediente_obj = Partida.objects.create(
|
||||
pedimento=pedimento,
|
||||
organizacion=organizacion,
|
||||
numero_partida=numero_int
|
||||
)
|
||||
elif tab_seccion == 'cove':
|
||||
if Cove.objects.filter(pedimento=pedimento, numero_cove=numero).exists():
|
||||
return Response(
|
||||
{"error": f"El COVE {numero} ya existe para este pedimento"},
|
||||
status=status.HTTP_409_CONFLICT
|
||||
)
|
||||
expediente_obj = Cove.objects.create(
|
||||
pedimento=pedimento,
|
||||
organizacion=organizacion,
|
||||
numero_cove=numero
|
||||
)
|
||||
elif tab_seccion == 'edoc':
|
||||
if EDocument.objects.filter(pedimento=pedimento, numero_edocument=numero).exists():
|
||||
return Response(
|
||||
{"error": f"El EDocument {numero} ya existe para este pedimento"},
|
||||
status=status.HTTP_409_CONFLICT
|
||||
)
|
||||
expediente_obj = EDocument.objects.create(
|
||||
pedimento=pedimento,
|
||||
organizacion=organizacion,
|
||||
numero_edocument=numero
|
||||
)
|
||||
|
||||
espacio_usado_temp = uso.espacio_utilizado
|
||||
uploaded_secciones = set()
|
||||
|
||||
for file in files:
|
||||
try:
|
||||
if not file.name:
|
||||
failed_files.append("archivo_sin_nombre")
|
||||
errors.append("Archivo sin nombre detectado")
|
||||
continue
|
||||
|
||||
filename = file.name
|
||||
if '.' in filename:
|
||||
base = '.'.join(filename.split('.')[:-1])
|
||||
secciones = filename.split('.')[-1]
|
||||
else:
|
||||
base = filename
|
||||
secciones = ''
|
||||
|
||||
file.name = base
|
||||
extension = file.name.split('.')[-1].lower() if '.' in file.name else ''
|
||||
|
||||
if tab_seccion == 'partida':
|
||||
nuevo_nombre = f"vu_PT_{pedimento.pedimento_app}_{numero}.{extension}"
|
||||
document_type, _ = DocumentType.objects.get_or_create(
|
||||
nombre="Pedimento Partida",
|
||||
defaults={'descripcion': "Tag para saber que el archivo guarda una partida"}
|
||||
)
|
||||
elif tab_seccion == 'cove':
|
||||
if secciones == 'acuse':
|
||||
nuevo_nombre = f"vu_AC_COVE_{pedimento.pedimento_app}_{numero}.{extension}"
|
||||
document_type, _ = DocumentType.objects.get_or_create(
|
||||
nombre="Acuse Cove",
|
||||
defaults={'descripcion': "Tag para saber que el archivo guarda un acuse de cove"}
|
||||
)
|
||||
else:
|
||||
nuevo_nombre = f"vu_COVE_{pedimento.pedimento_app}_{numero}.{extension}"
|
||||
document_type, _ = DocumentType.objects.get_or_create(
|
||||
nombre="Cove",
|
||||
defaults={'descripcion': "Tag para saber que el archivo guarda un cove"}
|
||||
)
|
||||
elif tab_seccion == 'edoc':
|
||||
if secciones == 'acuse':
|
||||
nuevo_nombre = f"vu_AC_{pedimento.pedimento_app}_{numero}.{extension}"
|
||||
document_type, _ = DocumentType.objects.get_or_create(
|
||||
nombre="Pedimento Acuse",
|
||||
defaults={'descripcion': "Tag para saber que el documento es un Acuse"}
|
||||
)
|
||||
else:
|
||||
nuevo_nombre = f"vu_ED_{pedimento.pedimento_app}_{numero}.{extension}"
|
||||
document_type, _ = DocumentType.objects.get_or_create(
|
||||
nombre="Pedimento EDocument",
|
||||
defaults={'descripcion': "Tag para saber que el documento es un EDocument"}
|
||||
)
|
||||
|
||||
file.name = nuevo_nombre
|
||||
|
||||
document = Document.objects.create(
|
||||
organizacion=organizacion,
|
||||
pedimento_id=pedimento_id,
|
||||
document_type=document_type,
|
||||
size=file.size,
|
||||
extension=extension
|
||||
)
|
||||
|
||||
ruta = storage_service.save_document(
|
||||
file=file,
|
||||
organizacion_id=organizacion.id,
|
||||
pedimento_app=pedimento.pedimento_app,
|
||||
metadata={'source': 'create_vu_record'}
|
||||
)
|
||||
|
||||
if ruta:
|
||||
document.archivo = ruta
|
||||
document.save()
|
||||
else:
|
||||
document.delete()
|
||||
raise Exception(f"Error al guardar archivo: {file.name}")
|
||||
|
||||
espacio_usado_temp += file.size
|
||||
total_space_used += file.size
|
||||
uploaded_secciones.add(secciones)
|
||||
|
||||
uploaded_documents.append({
|
||||
"id": str(document.id),
|
||||
"filename": file.name,
|
||||
"size": file.size,
|
||||
"extension": extension,
|
||||
"document_type": document_type.nombre
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
failed_files.append(file.name)
|
||||
errors.append(f"Error al procesar {file.name}: {str(e)}")
|
||||
continue
|
||||
|
||||
# Actualizar flags de descarga según secciones subidas exitosamente
|
||||
if tab_seccion == 'partida':
|
||||
if uploaded_secciones:
|
||||
expediente_obj.descargado = True
|
||||
expediente_obj.save(update_fields=['descargado'])
|
||||
elif tab_seccion == 'cove':
|
||||
update_fields = []
|
||||
if 'general' in uploaded_secciones:
|
||||
expediente_obj.cove_descargado = True
|
||||
update_fields.append('cove_descargado')
|
||||
if 'acuse' in uploaded_secciones:
|
||||
expediente_obj.acuse_cove_descargado = True
|
||||
update_fields.append('acuse_cove_descargado')
|
||||
if update_fields:
|
||||
expediente_obj.save(update_fields=update_fields)
|
||||
elif tab_seccion == 'edoc':
|
||||
update_fields = []
|
||||
if 'general' in uploaded_secciones:
|
||||
expediente_obj.edocument_descargado = True
|
||||
update_fields.append('edocument_descargado')
|
||||
if 'acuse' in uploaded_secciones:
|
||||
expediente_obj.acuse_descargado = True
|
||||
update_fields.append('acuse_descargado')
|
||||
if update_fields:
|
||||
expediente_obj.save(update_fields=update_fields)
|
||||
|
||||
uso.espacio_utilizado = espacio_usado_temp
|
||||
uso.save()
|
||||
|
||||
except Exception as e:
|
||||
return Response(
|
||||
{"error": f"Error durante el procesamiento: {str(e)}"},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
space_used_mb = round(total_space_used / (1024 * 1024), 2)
|
||||
response_data = {
|
||||
"uploaded_count": len(uploaded_documents),
|
||||
"uploaded_documents": uploaded_documents,
|
||||
"space_used_mb": space_used_mb,
|
||||
"pedimento_id": str(pedimento_id),
|
||||
"expediente_id": str(expediente_obj.id),
|
||||
"tab_seccion": tab_seccion,
|
||||
"numero": numero,
|
||||
}
|
||||
|
||||
if failed_files:
|
||||
response_data.update({
|
||||
"message": f"Registro creado pero algunos archivos fallaron",
|
||||
"failed_files": failed_files,
|
||||
"errors": errors
|
||||
})
|
||||
response_status = status.HTTP_207_MULTI_STATUS
|
||||
else:
|
||||
response_data["message"] = f"{tab_seccion.capitalize()} {numero} creado exitosamente"
|
||||
response_status = status.HTTP_201_CREATED
|
||||
|
||||
return Response(response_data, status=response_status)
|
||||
|
||||
|
||||
class ProtectedDocumentDownloadView(APIView, DocumentosFiltradosMixin):
|
||||
permission_classes = [IsAuthenticated & (IsSameOrganization | IsSameOrganizationAndAdmin | IsSameOrganizationDeveloper | IsSuperUser)]
|
||||
serializer_class = DocumentSerializer
|
||||
|
||||
@@ -3,7 +3,6 @@ import tempfile
|
||||
from api.utils.storage_service import storage_service
|
||||
from celery import shared_task
|
||||
from api.organization.models import Organizacion
|
||||
from django.core.files.base import ContentFile
|
||||
from django.utils import timezone
|
||||
from api.reports.models import ReportDocument
|
||||
from api.customs.models import Pedimento, Cove, EDocument, Partida
|
||||
@@ -127,8 +126,8 @@ def generate_report_document(report_id):
|
||||
|
||||
@shared_task
|
||||
def generate_report_control_pedimento(report_id):
|
||||
report = None
|
||||
try:
|
||||
|
||||
report = ReportDocument.objects.get(id=report_id)
|
||||
report.status = 'processing'
|
||||
report.save(update_fields=['status'])
|
||||
@@ -222,8 +221,9 @@ def generate_report_control_pedimento(report_id):
|
||||
|
||||
# 4. GENERAR CSV CON DETALLES
|
||||
filename = f"report_{report.id}_{timezone.now().strftime('%Y%m%d%H%M%S')}.csv"
|
||||
file_path = os.path.join(settings.MEDIA_ROOT, 'reports', filename)
|
||||
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.csv', encoding='utf-8', newline='') as tmp:
|
||||
tmp_path = tmp.name
|
||||
|
||||
todas_las_filas = []
|
||||
|
||||
@@ -278,7 +278,7 @@ def generate_report_control_pedimento(report_id):
|
||||
todas_las_filas.append(fila)
|
||||
|
||||
# 5. ESCRIBIR ARCHIVO CSV
|
||||
with open(file_path, 'w', newline='', encoding='utf-8') as f:
|
||||
with open(tmp_path, 'w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.writer(f)
|
||||
|
||||
# SECCIÓN DE TOTALES
|
||||
@@ -308,15 +308,40 @@ def generate_report_control_pedimento(report_id):
|
||||
writer.writerow(fila)
|
||||
|
||||
|
||||
with open(file_path, 'rb') as f:
|
||||
report.file.save(filename, ContentFile(f.read()), save=True)
|
||||
with open(tmp_path, 'rb') as f:
|
||||
file_content = f.read()
|
||||
|
||||
uploaded_file = SimpleUploadedFile(
|
||||
name=filename,
|
||||
content=file_content,
|
||||
content_type='text/csv'
|
||||
)
|
||||
|
||||
ruta = storage_service.save_report(
|
||||
file=uploaded_file,
|
||||
organizacion_id=filters.get('organizacion_id'),
|
||||
metadata={
|
||||
'report_id': str(report.id),
|
||||
'report_type': 'control_pedimento',
|
||||
'user_id': str(report.user.id) if report.user else None
|
||||
}
|
||||
)
|
||||
|
||||
os.unlink(tmp_path)
|
||||
|
||||
if ruta:
|
||||
report.file = ruta
|
||||
report.status = 'ready'
|
||||
else:
|
||||
report.status = 'error'
|
||||
report.error_message = 'Error al guardar el archivo en storage'
|
||||
|
||||
report.status = 'ready'
|
||||
report.finished_at = timezone.now()
|
||||
report.save(update_fields=['status', 'file', 'finished_at'])
|
||||
report.save(update_fields=['status', 'file', 'finished_at', 'error_message'])
|
||||
|
||||
except Exception as e:
|
||||
report.status = 'error'
|
||||
report.error_message = str(e)
|
||||
report.finished_at = timezone.now()
|
||||
report.save(update_fields=['status', 'error_message', 'finished_at'])
|
||||
if report:
|
||||
report.status = 'error'
|
||||
report.error_message = str(e)
|
||||
report.finished_at = timezone.now()
|
||||
report.save(update_fields=['status', 'error_message', 'finished_at'])
|
||||
Reference in New Issue
Block a user