from rest_framework import serializers from api.customs.models import ( Pedimento, TipoOperacion, ProcesamientoPedimento, EDocument, Cove, Importador, Partida ) from django.db import models from api.record.models import Document # Asegúrate de importar el modelo Documento from api.record.serializers import DocumentSerializer from api.vucem.serializers import VucemSerializer class PedimentoSerializer(serializers.ModelSerializer): documentos_count = serializers.SerializerMethodField() documentos_peso_total = serializers.SerializerMethodField() def get_documentos_count(self, obj): # Si obj es un dict o no tiene 'documents', devuelve 0 if isinstance(obj, dict) or not hasattr(obj, 'documents'): return 0 return obj.documents.count() def get_documentos_peso_total(self, obj): # Si obj es un dict o no tiene 'documents', devuelve 0 if isinstance(obj, dict) or not hasattr(obj, 'documents'): return 0 return obj.documents.aggregate(total=models.Sum('size'))['total'] or 0 class Meta: model = Pedimento fields = '__all__' read_only_fields = ( 'created_at', 'updated_at', 'organizacion', 'pedimento_app', 'documentos_count', 'documentos_peso_total' ) def to_representation(self, instance): rep = super().to_representation(instance) rep['documentos_count'] = self.get_documentos_count(instance) rep['documentos_peso_total'] = self.get_documentos_peso_total(instance) return rep class PartidaSerializer(serializers.ModelSerializer): class Meta: model = Partida fields = '__all__' read_only_fields = ('created_at', 'updated_at', 'numero_partida') def validate_unique(self, attrs): """ Sobrescribe la validación de unicidad para manejar correctamente las actualizaciones de registros existentes. """ # Si estamos actualizando un registro existente, excluirlo de la validación if self.instance: # Para actualizaciones, crear una instancia temporal con los nuevos datos # pero sin guardarla, solo para validar unicidad excluyendo el registro actual exclude = {'id': self.instance.id} else: # Para creaciones nuevas, no excluir nada exclude = {} # Crear una instancia temporal con los datos combinados if self.instance: # Combinar datos existentes con los nuevos combined_attrs = {} for field in self.Meta.model._meta.fields: field_name = field.name if field_name in attrs: combined_attrs[field_name] = attrs[field_name] elif hasattr(self.instance, field_name): combined_attrs[field_name] = getattr(self.instance, field_name) else: combined_attrs = attrs # Verificar unique_together manualmente para pedimento + numero_partida if 'pedimento' in combined_attrs and 'numero_partida' in combined_attrs: queryset = self.Meta.model.objects.filter( pedimento=combined_attrs['pedimento'], numero_partida=combined_attrs['numero_partida'] ) # Si estamos actualizando, excluir el registro actual if self.instance: queryset = queryset.exclude(id=self.instance.id) if queryset.exists(): raise serializers.ValidationError({ 'non_field_errors': [ f'Ya existe una partida con el número {combined_attrs["numero_partida"]} para este pedimento.' ] }) def validate(self, data): """ Validación adicional personalizada. """ # Llamar a la validación de unicidad personalizada self.validate_unique(data) return data class TipoOperacionSerializer(serializers.ModelSerializer): class Meta: model = TipoOperacion fields = '__all__' class ProcesamientoPedimentoSerializer(serializers.ModelSerializer): organizacion = serializers.PrimaryKeyRelatedField(queryset=ProcesamientoPedimento._meta.get_field('organizacion').related_model.objects.all(), required=False) organizacion_name = serializers.CharField(source='organizacion.nombre', read_only=True) class Meta: model = ProcesamientoPedimento fields = '__all__' read_only_fields = ('created_at', 'updated_at') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) request = self.context.get('request') # Si no es superusuario, hacer organizacion read_only if request and hasattr(request, 'user') and not request.user.is_superuser: self.fields['organizacion'].read_only = True def to_representation(self, instance): representation = super().to_representation(instance) representation['pedimento'] = PedimentoSerializer(instance.pedimento).data return representation class EDocumentSerializer(serializers.ModelSerializer): class Meta: model = EDocument fields = '__all__' read_only_fields = ('created_at', 'updated_at') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Si no es superusuario, hacer organizacion read_only request = self.context.get('request') if request and hasattr(request, 'user') and not request.user.is_superuser: self.fields['organizacion'].read_only = True class CoveSerializer(serializers.ModelSerializer): class Meta: model = Cove fields = '__all__' read_only_fields = ('created_at', 'updated_at') class ImportadorSerializer(serializers.ModelSerializer): class Meta: model = Importador fields = '__all__' read_only_fields = ('created_at', 'updated_at')