import uuid from django.db import models from django.contrib.auth import get_user_model # Create your models here. class TipoOperacion(models.Model): tipo = models.CharField(max_length=100) descripcion = models.CharField(max_length=200) def __str__(self): return f"{self.tipo}" class Meta: verbose_name = "Tipo de Operacion" verbose_name_plural = "Tipos de Operacion" db_table = 'tipo_operacion' ordering = ['tipo'] class Pedimento(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) pedimento = models.CharField(max_length=20, unique=False, help_text="Número de pedimento aduanal") pedimento_app = models.CharField(max_length=25, unique=False, help_text="Número de pedimento en la aplicación") organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE, related_name='pedimentos', help_text="Organización a la que pertenece el pedimento") patente = models.CharField(max_length=20, blank=True, null=True, help_text="Número de patente aduanal") aduana = models.CharField(max_length=10, blank=True, null=True, help_text="Clave de la aduana según la clasificación aduanera") regimen = models.CharField(max_length=10, blank=True, null=True, help_text="Clave del régimen aduanero según la clasificación aduanera") tipo_operacion = models.ForeignKey('TipoOperacion', on_delete=models.SET_NULL, blank=True, null=True, help_text="Tipo de operación del pedimento", related_name='pedimentos') clave_pedimento = models.CharField(max_length=10, blank=True, null=True, help_text="Clave del pedimento según la clasificación aduanera") fecha_inicio = models.DateField(help_text="Fecha de inicio del pedimento", blank=True, null=True) fecha_fin = models.DateField(help_text="Fecha de fin del pedimento", blank=True, null=True) 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") 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") curp_apoderado = models.CharField(max_length=18, blank=True, null=True, help_text="CURP del apoderado aduanal") importe_total = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, help_text="Importe total del pedimento") saldo_disponible = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, help_text="Saldo disponible del pedimento") importe_pedimento = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, help_text="Importe del pedimento") existe_expediente = models.BooleanField(default=False) remesas = models.BooleanField(default=False, help_text="Indica si el pedimento tiene remesas asociadas") numero_partidas = models.PositiveIntegerField(default=0, help_text="Número de partidas asociadas al pedimento", blank=True, null=True) numero_operacion = models.CharField(max_length=20, blank=True, null=True, help_text="Número de operación del pedimento") created_at = models.DateTimeField(auto_now_add=True, help_text="Fecha de creación del registro") updated_at = models.DateTimeField(auto_now=True, help_text="Fecha de última actualización del registro") def __str__(self): return f"{self.pedimento}" class Meta: verbose_name = "Pedimento" verbose_name_plural = "Pedimentos" db_table = 'pedimento' ordering = ['pedimento'] unique_together = [ ['organizacion', 'pedimento'], ['organizacion', 'pedimento_app'] ] class Partida(models.Model): pedimento = models.ForeignKey(Pedimento, on_delete=models.CASCADE, related_name='partidas', help_text="Pedimento asociado a la partida") organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE, related_name='partidas', help_text="Organización a la que pertenece la partida") numero_partida = models.PositiveIntegerField(help_text="Número de la partida dentro del pedimento") descargado = models.BooleanField(default=False, help_text="Indica si la partida ha sido descargada") created_at = models.DateTimeField(auto_now_add=True, help_text="Fecha de creación del registro") updated_at = models.DateTimeField(auto_now=True, help_text="Fecha de última actualización del registro") def __str__(self): return f"Partida {self.numero_partida} del Pedimento {self.pedimento.pedimento}" class Meta: verbose_name = "Partida" verbose_name_plural = "Partidas" db_table = 'partida' ordering = ['pedimento', 'numero_partida'] unique_together = ['pedimento', 'numero_partida'] # No puede existir el mismo número de partida para un pedimento class EDocument(models.Model): pedimento = models.ForeignKey(Pedimento, on_delete=models.CASCADE, related_name='documentos', help_text="Pedimento asociado al documento") organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE, related_name='edocuments', help_text="Organización a la que pertenece el EDocument") numero_edocument = models.CharField(max_length=20, unique=True, help_text="Número único del e-documento") clave = models.CharField(max_length=10, blank=True, null=True, help_text="Clave del e-documento según la clasificación aduanera") cadena_original = models.TextField(blank=True, null=True, help_text="Cadena original del e-documento") sello_digital = models.TextField(blank=True, null=True, help_text="Firma digital del e-documento") descripcion = models.CharField(max_length=200, blank=True, null=True, help_text="Descripción del documento") created_at = models.DateTimeField(auto_now_add=True, help_text="Fecha de creación del documento") updated_at = models.DateTimeField(auto_now=True, help_text="Fecha de última actualización del documento") edocument_descargado = models.BooleanField(default=False, help_text="Indica si el e-documento ha sido descargado") acuse_descargado = models.BooleanField(default=False, help_text="Indica si el acuse del e-documento ha sido descargado") def __str__(self): return f"{self.descripcion} - {self.pedimento.pedimento}" class Meta: verbose_name = "EDocument" verbose_name_plural = "EDocuments" db_table = 'edocs' ordering = ['created_at'] class Cove(models.Model): pedimento = models.ForeignKey(Pedimento, on_delete=models.CASCADE, related_name='coves', help_text="Pedimento asociado a la cove") organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE, related_name='coves', help_text="Organización a la que pertenece la cove") numero_cove = models.CharField(max_length=20, unique=True, help_text="Número único de la cove") created_at = models.DateTimeField(auto_now_add=True, help_text="Fecha de creación de la cove") updated_at = models.DateTimeField(auto_now=True, help_text="Fecha de última actualización de la cove") cove_descargado = models.BooleanField(default=False, help_text="Indica si la cove ha sido descargada") acuse_cove_descargado = models.BooleanField(default=False, help_text="Indica si el acuse de la cove ha sido descargado") def __str__(self): return f"{self.numero_cove} - {self.pedimento.pedimento}" class Meta: verbose_name = "Cove" verbose_name_plural = "Coves" db_table = 'coves' ordering = ['created_at'] class EstadoDeProcesamiento(models.Model): estado = models.CharField(max_length=50) def __str__(self): return self.estado class Meta: verbose_name = "Estado de Procesamiento" verbose_name_plural = "Estados de Procesamiento" db_table = 'estado_de_procesamiento' ordering = ['estado'] class TipoDeProcesamiento(models.Model): tipo = models.CharField(max_length=50) def __str__(self): return self.tipo class Meta: verbose_name = "Tipo de Procesamiento" verbose_name_plural = "Tipos de Procesamiento" db_table = 'tipo_de_procesamiento' ordering = ['tipo'] class Servicio(models.Model): endpoint = models.CharField(max_length=100) descripcion = models.TextField(blank=True, null=True) hora_inicio = models.TimeField(max_length=50, blank=True, null=True) hora_fin = models.TimeField(max_length=50, blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.endpoint class Meta: verbose_name = "Servicio" verbose_name_plural = "Servicios" db_table = 'servicio' ordering = ['endpoint'] class ProcesamientoPedimento(models.Model): organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE, related_name='procesamientos') estado = models.ForeignKey(EstadoDeProcesamiento, on_delete=models.CASCADE, related_name='procesamientos') tipo_procesamiento = models.ForeignKey(TipoDeProcesamiento, on_delete=models.CASCADE, related_name='procesamientos', blank=True, null=True) pedimento = models.ForeignKey(Pedimento, on_delete=models.CASCADE, related_name='procesamientos') servicio = models.ForeignKey(Servicio, on_delete=models.CASCADE, related_name='procesamientos', blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.pedimento.pedimento} - {self.estado.estado}" class Meta: verbose_name = "Procesamiento de Pedimento" verbose_name_plural = "Procesamientos de Pedimento" db_table = 'procesamiento_pedimento' ordering = ['created_at'] class Regimen(models.Model): id = models.AutoField(primary_key=True) claveped = models.CharField(max_length=4) regimenped = models.CharField(max_length=4) tipo = models.IntegerField() class Meta: db_table = 'regimen' verbose_name = 'Regimen' verbose_name_plural = 'Regimenes' def __str__(self): return f"{self.claveped} - {self.regimenped} - {self.tipo}" class Importador(models.Model): rfc = models.CharField(primary_key=True, max_length=13, unique=True, help_text="RFC del importador") nombre = models.CharField(max_length=200, help_text="Nombre del importador") organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE, related_name='importadores', help_text="Organización a la que pertenece el importador") created_at = models.DateTimeField(auto_now_add=True, help_text="Fecha de creación del registro") updated_at = models.DateTimeField(auto_now=True, help_text="Fecha de última actualización del registro") class Meta: verbose_name = 'Importador' verbose_name_plural = 'Importadores' db_table = 'importador' ordering = ['rfc'] def __str__(self): return f"{self.rfc} - {self.nombre}" # bulk de datos class BulkUploadTask(models.Model): STATUS_CHOICES = [ ('pending', 'Pendiente'), ('processing', 'Procesando'), ('completed', 'Completado'), ('failed', 'Fallido'), ('partial', 'Parcialmente completado'), ] user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, related_name='bulk_upload_tasks') organizacion = models.ForeignKey('organization.Organizacion', on_delete=models.CASCADE) contribuyente = models.CharField(max_length=255, blank=True, null=True) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') task_type = models.CharField(max_length=50, default='bulk_create') total_files = models.IntegerField(default=0) processed_files = models.IntegerField(default=0) created_pedimentos = models.IntegerField(default=0) created_documents = models.IntegerField(default=0) result = models.JSONField(default=dict, blank=True) failed_files = models.JSONField(default=list, blank=True) error_message = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) started_at = models.DateTimeField(null=True, blank=True) finished_at = models.DateTimeField(null=True, blank=True) fecha_pago = models.DateField(null=True, blank=True) clave_pedimento = models.CharField(max_length=50, blank=True, null=True) tipo_operacion_id = models.IntegerField(null=True, blank=True) curp_apoderado = models.CharField(max_length=50, blank=True, null=True) partidas = models.IntegerField(default=0) celery_task_id = models.CharField(max_length=255, blank=True, null=True) def __str__(self): return f"BulkUpload {self.id} - {self.status}" class Meta: verbose_name = "Tarea de Carga Masiva" verbose_name_plural = "Tareas de Carga Masiva" db_table = 'bulk_upload_task' ordering = ['-created_at']