feature/implementacion de gestor de informacion y archivos minIO
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user