Skip to main content

Overview

The Production API manages daily production reporting, monthly reports, GPU (Generadores de Precio Unitario) tracking, and estimations for subsea operations.

URL Patterns

From operaciones/urls.py:59-74:
# Production URLs
path('produccion/', produccion.lista_produccion, name='lista_produccion'),
path('produccion/obtener_sitios_con_ots_ejecutadas/', produccion.obtener_sitios_con_ots_ejecutadas),
path('produccion/ots_por_sitio_grid/', produccion.ots_por_sitio_grid),
path('produccion/obtener_partidas_produccion/', produccion.obtener_partidas_produccion),
path('produccion/guardar_produccion_masiva/', produccion.guardar_produccion_masiva),
path('produccion/buscar_productos_catalogo/', produccion.buscar_productos_catalogo),
path('produccion/vincular_partida_ot/', produccion.vincular_partida_ot),
path('produccion/guardar_reportes_diarios_masiva/', produccion.guardar_reportes_diarios_masiva),
path('produccion/guardar_archivo_mensual/', produccion.guardar_archivo_mensual),
path('produccion/obtener_supers_por_sitio/', produccion.obtener_supers_por_sitio),
path('produccion/configurar_ciclo_guardia/', produccion.configurar_ciclo_guardia),
path('produccion/obtener_guardias_mes/', produccion.obtener_guardias_mes),
path('produccion/obtener_grid_gpus/', produccion.obtener_grid_gpus),
path('produccion/guardar_estatus_gpu/', produccion.guardar_estatus_gpu),
path('produccion/obtener_arbol_mpp/', produccion.obtener_arbol_mpp),

Key Endpoints

Get Sites with Executed OTs

Retrieve all sites that have work orders in execution.
curl -X POST "https://api.sascop-bme-subtec.com/operaciones/produccion/obtener_sitios_con_ots_ejecutadas/" \
  -H "Cookie: sessionid=your_session_id" \
  -H "X-CSRFToken: your_csrf_token"
{
  "sitios": [
    {
      "id": 1,
      "descripcion": "Plataforma Alfa",
      "id_frente": 2,
      "frente_descripcion": "Golfo de México",
      "total_ots": 5
    },
    {
      "id": 2,
      "descripcion": "Embarcación Beta",
      "id_frente": 1,
      "frente_descripcion": "Costa Fuera",
      "total_ots": 3
    }
  ]
}

Save Massive Production

Submit multiple production records at once.
curl -X POST "https://api.sascop-bme-subtec.com/operaciones/produccion/guardar_produccion_masiva/" \
  -H "Cookie: sessionid=your_session_id" \
  -H "X-CSRFToken: your_csrf_token" \
  -H "Content-Type: application/json" \
  -d '{
    "id_ot": 1,
    "mes": 3,
    "anio": 2024,
    "registros": [
      {
        "id_partida_anexo": 1,
        "fecha_produccion": "2024-03-15",
        "volumen_produccion": 25.5,
        "tipo_tiempo": "TE",
        "id_estatus_cobro": 1,
        "id_sitio_produccion": 1
      },
      {
        "id_partida_anexo": 2,
        "fecha_produccion": "2024-03-15",
        "volumen_produccion": 10.0,
        "tipo_tiempo": "TE",
        "id_estatus_cobro": 1,
        "id_sitio_produccion": 1
      }
    ]
  }'
id_ot
integer
required
Work order identifier
mes
integer
required
Month (1-12)
anio
integer
required
Year (e.g., 2024)
registros
array
required
Array of production records

Save Daily Reports (Massive)

Submit multiple daily operational status reports.
curl -X POST "https://api.sascop-bme-subtec.com/operaciones/produccion/guardar_reportes_diarios_masiva/" \
  -H "Cookie: sessionid=your_session_id" \
  -H "X-CSRFToken: your_csrf_token" \
  -H "Content-Type: application/json" \
  -d '{
    "id_ot": 1,
    "mes": 3,
    "anio": 2024,
    "reportes": [
      {
        "fecha": "2024-03-15",
        "id_estatus": 1,
        "id_sitio": 1,
        "comentario": "Operación normal"
      },
      {
        "fecha": "2024-03-16",
        "id_estatus": 2,
        "id_sitio": 1,
        "comentario": "Clima adverso - operaciones suspendidas"
      }
    ]
  }'
id_ot
integer
required
Work order identifier
mes
integer
required
Month (1-12)
anio
integer
required
Year
reportes
array
required
Array of daily reports

Configure Guard Cycle

Set up superintendent rotation schedule for a site.
curl -X POST "https://api.sascop-bme-subtec.com/operaciones/produccion/configurar_ciclo_guardia/" \
  -H "Cookie: sessionid=your_session_id" \
  -H "X-CSRFToken: your_csrf_token" \
  -H "Content-Type: application/json" \
  -d '{
    "id_sitio": 1,
    "id_super_a": 1,
    "id_super_b": 2,
    "fecha_inicio_super_a": "2024-01-01"
  }'
id_sitio
integer
required
Site identifier
id_super_a
integer
required
First superintendent ID
id_super_b
integer
required
Second superintendent ID
fecha_inicio_super_a
string
required
Start date for superintendent A’s first shift (YYYY-MM-DD)

Get GPU Grid

Retrieve GPU (Unit Price Generators) tracking grid for a specific month.
curl -X POST "https://api.sascop-bme-subtec.com/operaciones/produccion/obtener_grid_gpus/" \
  -H "Cookie: sessionid=your_session_id" \
  -H "X-CSRFToken: your_csrf_token" \
  -H "Content-Type: application/json" \
  -d '{
    "id_ot": 1,
    "mes": 3,
    "anio": 2024
  }'
id_ot
integer
required
Work order identifier
mes
integer
required
Month (1-12)
anio
integer
required
Year

Production Models

From operaciones/models/produccion_models.py:63-88:

Produccion Model

class Produccion(models.Model):
    TIPO_TIEMPO_CHOICES = [
        ('TE', 'Tiempo Efectivo'),
        ('CMA', 'Costo Mínimo Aplicado'),
    ]
    
    id_partida_anexo = models.ForeignKey(PartidaAnexoImportada, on_delete=models.PROTECT)
    id_reporte_mensual = models.ForeignKey(ReporteMensual, on_delete=models.CASCADE)
    fecha_produccion = models.DateField()
    volumen_produccion = models.DecimalField(max_digits=15, decimal_places=6)
    tipo_tiempo = models.CharField(max_length=3, choices=TIPO_TIEMPO_CHOICES)
    es_excedente = models.BooleanField(default=False)
    id_estatus_cobro = models.ForeignKey(Estatus, on_delete=models.CASCADE)
    comentario = models.TextField(blank=True)
    id_sitio_produccion = models.ForeignKey(Sitio, on_delete=models.SET_NULL, null=True)
    
    class Meta:
        unique_together = ['id_partida_anexo', 'fecha_produccion', 'tipo_tiempo', 'id_sitio_produccion']

ReporteMensual Model

class ReporteMensual(models.Model):
    id_ot = models.ForeignKey(OTE, on_delete=models.CASCADE)
    mes = models.IntegerField(help_text="Mes numérico (1-12)")
    anio = models.IntegerField(help_text="Año (Ej. 2025)")
    archivo = models.URLField(blank=True, null=True, verbose_name="Link Evidencia (Drive)")
    id_estatus = models.ForeignKey(Estatus, on_delete=models.CASCADE)
    fecha_creacion = models.DateTimeField(auto_now_add=True)
    fecha_actualizacion = models.DateTimeField(auto_now=True)
    
    class Meta:
        unique_together = ['id_ot', 'mes', 'anio']

ReporteDiario Model

class ReporteDiario(models.Model):
    id_reporte_mensual = models.ForeignKey(ReporteMensual, on_delete=models.CASCADE)
    fecha = models.DateField()
    id_estatus = models.ForeignKey(Estatus, on_delete=models.CASCADE)
    comentario = models.CharField(max_length=255, blank=True, null=True)
    bloqueado = models.BooleanField(default=False)
    id_sitio = models.ForeignKey(Sitio, on_delete=models.CASCADE, null=True)
    
    class Meta:
        unique_together = ['id_reporte_mensual', 'fecha', 'id_sitio']

RegistroGPU Model

class RegistroGPU(models.Model):
    id_produccion = models.OneToOneField(Produccion, on_delete=models.CASCADE, related_name='gpu')
    id_estatus = models.ForeignKey(Estatus, on_delete=models.CASCADE)
    archivo = models.URLField(max_length=500, blank=True, null=True)
    nota_bloqueo = models.TextField(blank=True, null=True)
    id_estimacion_detalle = models.ForeignKey('EstimacionDetalle', on_delete=models.SET_NULL, null=True)
    fecha_actualizacion = models.DateTimeField(auto_now=True)

Cronograma (Schedule) Models

CronogramaVersion

class CronogramaVersion(models.Model):
    id_ot = models.ForeignKey(OTE, on_delete=models.CASCADE)
    nombre_version = models.CharField(max_length=150)
    archivo_mpp = models.FileField(upload_to='operaciones/mpps/')
    fecha_carga = models.DateTimeField(auto_now_add=True)
    es_activo = models.BooleanField(default=True)
    fecha_inicio_proyecto = models.DateField(null=True, blank=True)
    fecha_fin_proyecto = models.DateField(null=True, blank=True)

TareaCronograma

class TareaCronograma(models.Model):
    version = models.ForeignKey(CronogramaVersion, on_delete=models.CASCADE)
    uid_project = models.IntegerField()
    id_project = models.IntegerField()
    wbs = models.CharField(max_length=50)
    nombre = models.CharField(max_length=500)
    nivel_esquema = models.IntegerField(default=0)
    es_resumen = models.BooleanField(default=False)
    padre_uid = models.IntegerField(null=True, blank=True)
    fecha_inicio = models.DateField(null=True)
    fecha_fin = models.DateField(null=True)
    duracion_dias = models.DecimalField(max_digits=10, decimal_places=2, default=0)
    porcentaje_mpp = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    porcentaje_completado = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    recursos = models.TextField(blank=True, default='')

Superintendent Management

Superintendente Model

class Superintendente(models.Model):
    nombre = models.CharField(max_length=150)
    sitio_asignado = models.ForeignKey('Sitio', on_delete=models.SET_NULL, null=True)
    color = models.CharField(max_length=7, default="#3498db")
    activo = models.BooleanField(default=True)

CicloGuardia Model

class CicloGuardia(models.Model):
    sitio = models.OneToOneField('Sitio', on_delete=models.CASCADE)
    super_a = models.ForeignKey(Superintendente, on_delete=models.CASCADE, related_name='ciclos_a')
    super_b = models.ForeignKey(Superintendente, on_delete=models.CASCADE, related_name='ciclos_b')
    fecha_inicio_super_a = models.DateField()

Production Workflow

1

Create Monthly Report

Create or retrieve the monthly report container for the OT
2

Submit Daily Operational Status

Record daily operational status (working, suspended, standby, etc.)
3

Record Production Volumes

Submit production volumes for each partida (line item)
4

Track GPUs

For C-2 and C-3 items, track GPU status and photographic evidence
5

Close Monthly Report

Update monthly report status and attach evidence link
Production records have a unique constraint on:
  • id_partida_anexo
  • fecha_produccion
  • tipo_tiempo
  • id_sitio_produccion
Duplicate records will be rejected.

Build docs developers (and LLMs) love