Se agregaron los microservicios_v2

This commit is contained in:
2025-10-03 23:16:08 -06:00
parent 0ac9f06e51
commit 0b51024343
4 changed files with 353 additions and 1 deletions

View File

@@ -46,6 +46,60 @@ class PartidaSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Partida model = Partida
fields = '__all__' 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 TipoOperacionSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@@ -0,0 +1,269 @@
from celery import shared_task, group
from api.customs.models import *
from api.customs.serializers import PedimentoSerializer
from api.vucem.models import *
import requests
from config.settings import SERVICE_API_URL_V2
from datetime import datetime
import json
def credenciales_to_dict(credenciales):
if not credenciales:
return {}
return {
"id": str(credenciales.id),
"user": credenciales.usuario,
"password": credenciales.password,
"efirma": credenciales.efirma,
"key": credenciales.key.url if credenciales.key else None,
"cer": credenciales.cer.url if credenciales.cer else None,
"is_active": credenciales.is_active,
"organizacion": str(credenciales.organizacion.id) if credenciales.organizacion else None,
}
def pedimento_to_dict(pedimento):
return {
"id": str(pedimento.id),
"pedimento": str(pedimento.pedimento),
"pedimento_app": str(pedimento.pedimento_app),
"aduana": str(pedimento.aduana),
"patente": str(pedimento.patente),
"organizacion": str(pedimento.organizacion.id), # nunca None
"regimen": str(pedimento.regimen or ""),
"clave_pedimento": str(pedimento.clave_pedimento or ""),
"numero_operacion": str(pedimento.numero_operacion or "")
}
def cove_to_dict(cove):
return {
"id": cove.id,
"cove": str(cove.numero_cove),
}
def edoc_to_dict(edoc):
return {
"id": edoc.id,
"numero_edocument": str(edoc.numero_edocument),
}
def partida_to_dict(partida):
return {
"id": partida.id,
"numero": partida.numero_partida,
}
@shared_task
def procesar_pedimentos_completos(organizacion_id):
pedimentos = Pedimento.objects.filter(organizacion_id=organizacion_id)
respuestas = []
for pedimento in pedimentos[:10]:
if not pedimento.documents.filter(document_type=2).exists(): # Tipo 2: Pedimento Completo
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/pedimento_completo",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas
@shared_task
def procesar_remesas(organizacion_id):
pedimentos = Pedimento.objects.filter(organizacion_id=organizacion_id)
respuestas = []
for pedimento in pedimentos:
if not pedimento.documents.filter(document_type=3).exists(): # Tipo 3: Remesa
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/remesas",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas
@shared_task
def procesar_coves(organizacion_id):
pedimentos = Pedimento.objects.filter(
organizacion_id=organizacion_id,
coves__isnull=False
).distinct()
respuestas = []
for pedimento in pedimentos[:10]:
if pedimento.coves.filter(cove_descargado=False).exists(): # Tipo 3: Remesa
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"coves": [cove_to_dict(cove) for cove in pedimento.coves.filter(cove_descargado=False)],
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/all/coves",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas
@shared_task
def procesar_acuse_coves(organizacion_id):
pedimentos = Pedimento.objects.filter(
organizacion_id=organizacion_id,
coves__isnull=False
).distinct()
respuestas = []
for pedimento in pedimentos[10:20]:
if pedimento.coves.filter(acuse_cove_descargado=False).exists(): # Tipo 3: Remesa
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"coves": [cove_to_dict(cove) for cove in pedimento.coves.filter(acuse_cove_descargado=False)],
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/all/acuse/cove/",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas
@shared_task
def procesar_acuses(organizacion_id):
pedimentos = Pedimento.objects.filter(
organizacion_id=organizacion_id,
documentos__isnull=False
).distinct()
respuestas = []
for pedimento in pedimentos[:10]:
if pedimento.documentos.filter(acuse_descargado=False).exists(): # Tipo 3: Remesa
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"edocs": [edoc_to_dict(edoc) for edoc in pedimento.documentos.filter(acuse_descargado=False)],
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/all/acuse/pedimento/",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas
@shared_task
def procesar_edocs(organizacion_id):
pedimentos = Pedimento.objects.filter(
organizacion_id=organizacion_id,
documentos__isnull=False
).distinct()
respuestas = []
for pedimento in pedimentos[:10]:
if pedimento.documentos.filter(edocument_descargado=False).exists(): # Tipo 3: Remesa
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"edocs": [edoc_to_dict(edoc) for edoc in pedimento.documentos.filter(edocument_descargado=False)],
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/all/acuse/pedimento/",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas
@shared_task
def procesar_partidas(organizacion_id):
pedimentos = Pedimento.objects.filter(
organizacion_id=organizacion_id,
partidas__isnull=False
).distinct()
respuestas = []
for pedimento in pedimentos[:10]:
if pedimento.partidas.filter(descargado=False).exists(): # Tipo 4: Partidas
# Convertir el pedimento a JSON usando el serializer
pedimento_dict = pedimento_to_dict(pedimento)
credenciales = Vucem.objects.filter(id=CredencialesImportador.objects.filter(rfc=pedimento.contribuyente).first().vucem.id).first()
credenciales_dict = credenciales_to_dict(credenciales)
payload = {
"partidas": [partida_to_dict(partida) for partida in pedimento.partidas.filter(descargado=False)],
"pedimento": pedimento_dict,
"credencial": credenciales_dict
}
response = requests.post(
f"{SERVICE_API_URL_V2}/services/all/partidas/",
data=json.dumps(payload),
headers={"Content-Type": "application/json"}
)
# Aquí puedes continuar con el resto de tu lógica
respuestas.append(response.json())
return respuestas

View File

@@ -100,7 +100,7 @@ ALLOWED_HOSTS = [
SITE_URL = os.getenv('SITE_URL') SITE_URL = os.getenv('SITE_URL')
SERVICE_API_URL = os.getenv('SERVICE_API_URL') SERVICE_API_URL = os.getenv('SERVICE_API_URL')
SERVICE_API_URL_V2 = os.getenv('SERVICE_API_URL_V2')
# Application definition # Application definition
BASE_APPS = [ BASE_APPS = [
'django.contrib.admin', 'django.contrib.admin',

29
test.json Normal file
View File

@@ -0,0 +1,29 @@
{
"partidas": [
{
"id": 88,
"numero": 1
}
],
"pedimento": {
"id": "c192e4b3-68b7-49fb-b600-6e5f5ae463ee",
"pedimento": "0000451",
"pedimento_app": "20-24-3910-0000451",
"aduana": "240",
"patente": "3910",
"organizacion": "9d705e97-d3f2-4b6c-8d92-9f1af2b2d4b4",
"regimen": "IMD",
"clave_pedimento": "A1",
"numero_operacion": "21612122481"
},
"credencial": {
"id": "40d1d433-dba5-47a8-b00c-dce077c3c5cd",
"user": "TEC1406248Q2",
"password": "4Z+6Aulov0ohSWLda/INLyEm8p2xJSYK/iZnA+vjHZPDD4otHSBnr1p7GPugdwCh",
"efirma": "TXM241007",
"key": "/media/vucem_keys/TEC1406248Q2_clave_vJA0zau.key",
"cer": "/media/vucem_certs/TEC1406248Q2_certificado_Du8N2Q9.cer",
"is_active": true,
"organizacion": "9d705e97-d3f2-4b6c-8d92-9f1af2b2d4b4"
}
}