feature/implementacion de gestor de informacion y archivos minIO

This commit is contained in:
Dulce
2026-04-22 11:10:05 -06:00
parent 69d07f2713
commit 39504e196c
23 changed files with 2272 additions and 391 deletions

View File

@@ -20,8 +20,10 @@ class Vucem(models.Model):
password = models.CharField(max_length=100, help_text="Contraseña de VUCEM")
patente = models.CharField(max_length=100, unique=True, help_text="Patente de VUCEM")
efirma = models.CharField(max_length=100, blank=True, null=True,help_text="E-Firma de VUCEM")
key = models.FileField(upload_to='vucem_keys/', help_text="Llave privada de VUCEM")
cer = models.FileField(upload_to='vucem_certs/', help_text="Certificado de VUCEM")
# key = models.FileField(upload_to='vucem_keys/', help_text="Llave privada de VUCEM")
# cer = models.FileField(upload_to='vucem_certs/', help_text="Certificado de VUCEM")
key = models.CharField(max_length=500, blank=True, null=True, help_text="Llave privada de VUCEM")
cer = models.CharField(max_length=500, blank=True, null=True, help_text="Certificado de VUCEM")
is_importador = models.BooleanField(default=False, help_text="Indica si es importador")
acusecove = models.BooleanField(default=False, help_text="Indica si generara acusecove")

View File

@@ -1,5 +1,6 @@
from api.utils.storage_service import storage_service
from rest_framework import serializers
from .models import Vucem, CredencialesImportador
@@ -9,11 +10,91 @@ from .models import Vucem, CredencialesImportador
class VucemSerializer(serializers.ModelSerializer):
importadores = serializers.SerializerMethodField()
key = serializers.FileField(write_only=True, required=False, allow_null=True)
cer = serializers.FileField(write_only=True, required=False, allow_null=True)
key_download_url = serializers.SerializerMethodField(read_only=True)
cer_download_url = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Vucem
fields = '__all__'
read_only_fields = ('created_at', 'updated_at', 'organizacion', 'created_by', 'updated_by')
def get_key_download_url(self, obj):
if obj.key:
return storage_service.get_file_url(obj.key)
return None
def get_cer_download_url(self, obj):
if obj.cer:
return storage_service.get_file_url(obj.cer)
return None
def create(self, validated_data):
key_file = validated_data.pop('key', None)
cer_file = validated_data.pop('cer', None)
organizacion = validated_data.get('organizacion')
vucem = super().create(validated_data)
if key_file:
ruta = storage_service.save_vucem_key(
file=key_file,
organizacion_id=organizacion.id,
metadata={'vucem_id': str(vucem.id)}
)
if ruta:
vucem.key = ruta
else:
vucem.delete()
raise serializers.ValidationError({"key": "Error al guardar la llave"})
if cer_file:
ruta = storage_service.save_vucem_cert(
file=cer_file,
organizacion_id=organizacion.id,
metadata={'vucem_id': str(vucem.id)}
)
if ruta:
vucem.cer = ruta
else:
vucem.delete()
raise serializers.ValidationError({"cer_file": "Error al guardar el certificado"})
vucem.save()
return vucem
def update(self, instance, validated_data):
key_file = validated_data.pop('key', None)
cer_file = validated_data.pop('cer', None)
organizacion = validated_data.get('organizacion', instance.organizacion)
instance = super().update(instance, validated_data)
if key_file:
if instance.key:
storage_service.delete_file(str(instance.key))
ruta = storage_service.save_vucem_key(
file=key_file,
organizacion_id=organizacion.id
)
if ruta:
instance.key = ruta
if cer_file:
if instance.cer:
storage_service.delete_file(str(instance.cer))
ruta = storage_service.save_vucem_cert(
file=cer_file,
organizacion_id=organizacion.id
)
if ruta:
instance.cer = ruta
instance.save()
return instance
def get_importadores(self, obj):
# Importar aquí para evitar importación circular
from api.customs.serializers import ImportadorSerializer

View File

@@ -1,3 +1,7 @@
import atexit
import os
import tempfile
from django.shortcuts import render
from ..organization.models import Organizacion
from rest_framework import viewsets
@@ -8,6 +12,7 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action
from rest_framework.response import Response
from django.http import FileResponse, Http404
from api.utils.storage_service import storage_service
from .serializers import VucemSerializer, CredencialesImportadorSerializer, CredencialesImportadorSimpleSerializer
from rest_framework import serializers
@@ -140,25 +145,52 @@ class VucemView(viewsets.ModelViewSet):
@action(detail=True, methods=["get"], permission_classes=[IsAuthenticated])
def download_cer(self, request, pk=None):
"""
Descarga directa del archivo cer.
"""
vucem = self.get_object()
if not vucem.cer:
return Response({"detail": "No hay archivo cer disponible."}, status=404)
response = FileResponse(vucem.cer.open('rb'), as_attachment=True, filename=vucem.cer.name.split('/')[-1])
ruta = str(vucem.cer)
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp_path = tmp.name
success = storage_service.download_file(ruta, tmp_path)
if not success:
raise Http404("No se pudo descargar el archivo")
filename = os.path.basename(ruta)
response = FileResponse(open(tmp_path, 'rb'), as_attachment=True, filename=filename)
atexit.register(lambda: os.unlink(tmp_path) if os.path.exists(tmp_path) else None)
return response
@action(detail=True, methods=["get"], permission_classes=[IsAuthenticated])
def download_key(self, request, pk=None):
"""
Descarga directa del archivo key.
"""
vucem = self.get_object()
if not vucem.key:
return Response({"detail": "No hay archivo key disponible."}, status=404)
response = FileResponse(vucem.key.open('rb'), as_attachment=True, filename=vucem.key.name.split('/')[-1])
ruta = str(vucem.key)
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp_path = tmp.name
success = storage_service.download_file(ruta, tmp_path)
if not success:
raise Http404("No se pudo descargar el archivo")
filename = os.path.basename(ruta)
response = FileResponse(open(tmp_path, 'rb'), as_attachment=True, filename=filename)
atexit.register(lambda: os.unlink(tmp_path) if os.path.exists(tmp_path) else None)
return response
def perform_destroy(self, instance):
if instance.key:
storage_service.delete_file(str(instance.key))
if instance.cer:
storage_service.delete_file(str(instance.cer))
instance.delete()
class CredencialesImportadorViewSet(viewsets.ModelViewSet):